mirror of
https://github.com/tursom/TursomServer.git
synced 2025-03-07 16:20:08 +08:00
进一步优化结构
This commit is contained in:
parent
2629b93c23
commit
696f35a254
web
netty-web/src/main/kotlin/cn/tursom/web/netty
src/main/kotlin/cn/tursom/web
@ -1,20 +1,20 @@
|
||||
@file:Suppress("unused")
|
||||
|
||||
package cn.tursom.web.netty
|
||||
|
||||
import cn.tursom.web.HttpContent
|
||||
import cn.tursom.web.utils.Cookie
|
||||
import io.netty.handler.codec.DateFormatter
|
||||
import io.netty.handler.codec.http.cookie.ServerCookieDecoder
|
||||
import java.util.*
|
||||
import kotlin.collections.HashMap
|
||||
|
||||
|
||||
fun HttpContent.parseHttpDate(date: CharSequence, start: Int = 0, end: Int = date.length): Date = DateFormatter.parseHttpDate(date, start, end)
|
||||
fun HttpContent.format(date: Date): String = DateFormatter.format(date)
|
||||
fun HttpContent.append(date: Date, sb: StringBuilder): StringBuilder = DateFormatter.append(date, sb)
|
||||
fun HttpContent.decodeCookie(cookie: String): Map<String, Cookie> {
|
||||
val cookieMap = HashMap<String, Cookie>()
|
||||
ServerCookieDecoder.STRICT.decode(cookie).forEach {
|
||||
cookieMap[it.name()] = Cookie(it.name(), it.value(), it.domain(), it.path(), it.maxAge())
|
||||
}
|
||||
return cookieMap
|
||||
fun parseHttpDate(date: CharSequence, start: Int = 0, end: Int = date.length): Date = DateFormatter.parseHttpDate(date, start, end)
|
||||
fun format(date: Date): String = DateFormatter.format(date)
|
||||
fun append(date: Date, sb: StringBuilder): StringBuilder = DateFormatter.append(date, sb)
|
||||
fun decodeCookie(cookie: String): Map<String, String> {
|
||||
val cookieMap = HashMap<String, String>()
|
||||
ServerCookieDecoder.STRICT.decode(cookie).forEach {
|
||||
cookieMap[it.name()] = it.value()
|
||||
}
|
||||
return cookieMap
|
||||
}
|
@ -54,10 +54,6 @@ open class NettyHttpContent(
|
||||
return headers.toList()
|
||||
}
|
||||
|
||||
override fun getParam(param: String): String? {
|
||||
return paramMap[param]?.get(0)
|
||||
}
|
||||
|
||||
override fun getParams(): Map<String, List<String>> {
|
||||
return paramMap
|
||||
}
|
||||
|
@ -2,10 +2,7 @@ package cn.tursom.web
|
||||
|
||||
import cn.tursom.core.buffer.ByteBuffer
|
||||
import cn.tursom.core.urlDecode
|
||||
import cn.tursom.web.utils.CacheControl
|
||||
import cn.tursom.web.utils.Chunked
|
||||
import cn.tursom.web.utils.Cookie
|
||||
import cn.tursom.web.utils.SameSite
|
||||
import java.io.File
|
||||
import java.io.RandomAccessFile
|
||||
import java.net.SocketAddress
|
||||
@ -17,19 +14,16 @@ interface HttpContent : ResponseHeaderAdapter, RequestHeaderAdapter {
|
||||
val body: ByteBuffer?
|
||||
val clientIp: SocketAddress
|
||||
val method: String
|
||||
//val responseBody: ByteArrayOutputStream
|
||||
val cookieMap: Map<String, Cookie>
|
||||
val realIp
|
||||
get() = getHeader("X-Forwarded-For") ?: clientIp.toString().let { str ->
|
||||
str.substring(1, str.indexOf(':').let { if (it < 1) str.length else it - 1 })
|
||||
}
|
||||
|
||||
fun getParam(param: String): String?
|
||||
fun getParam(param: String): String? = getParams(param)?.firstOrNull()
|
||||
fun getParams(): Map<String, List<String>>
|
||||
fun getParams(param: String): List<String>?
|
||||
|
||||
operator fun get(name: String) = (getHeader(name) ?: getParam(name))?.urlDecode
|
||||
|
||||
operator fun set(name: String, value: Any) = setResponseHeader(name, value)
|
||||
|
||||
fun write(message: String)
|
||||
@ -38,8 +32,6 @@ interface HttpContent : ResponseHeaderAdapter, RequestHeaderAdapter {
|
||||
fun write(buffer: ByteBuffer)
|
||||
fun reset()
|
||||
|
||||
//fun finish() = finish(responseBody.buf, 0, responseBody.count)
|
||||
|
||||
fun finish()
|
||||
fun finish(buffer: ByteArray, offset: Int = 0, size: Int = buffer.size - offset)
|
||||
fun finish(buffer: ByteBuffer) {
|
||||
@ -55,82 +47,67 @@ interface HttpContent : ResponseHeaderAdapter, RequestHeaderAdapter {
|
||||
fun finish(code: Int) = finishHtml(code)
|
||||
|
||||
fun finishHtml(code: Int = responseCode) {
|
||||
responseHtml()
|
||||
responseCode = code
|
||||
setResponseHeader("content-type", "text/html; charset=UTF-8")
|
||||
finish()
|
||||
}
|
||||
|
||||
fun finishText(code: Int = responseCode) {
|
||||
responseText()
|
||||
responseCode = code
|
||||
setResponseHeader("content-type", "text/plain; charset=UTF-8")
|
||||
finish()
|
||||
}
|
||||
|
||||
fun finishJson(code: Int = responseCode) {
|
||||
responseJson()
|
||||
responseCode = code
|
||||
setResponseHeader("content-type", "application/json; charset=UTF-8")
|
||||
finish()
|
||||
}
|
||||
|
||||
fun finishHtml(response: ByteArray, code: Int = responseCode) {
|
||||
responseHtml()
|
||||
responseCode = code
|
||||
setResponseHeader("content-type", "text/html; charset=UTF-8")
|
||||
finish(response)
|
||||
}
|
||||
|
||||
fun finishText(response: ByteArray, code: Int = responseCode) {
|
||||
responseText()
|
||||
responseCode = code
|
||||
setResponseHeader("content-type", "text/plain; charset=UTF-8")
|
||||
finish(response)
|
||||
}
|
||||
|
||||
fun finishJson(response: ByteArray, code: Int = responseCode) {
|
||||
responseJson()
|
||||
responseCode = code
|
||||
setResponseHeader("content-type", "application/json; charset=UTF-8")
|
||||
finish(response)
|
||||
}
|
||||
|
||||
fun finishHtml(response: ByteBuffer, code: Int = responseCode) {
|
||||
responseHtml()
|
||||
responseCode = code
|
||||
setResponseHeader("content-type", "text/html; charset=UTF-8")
|
||||
finish(response)
|
||||
}
|
||||
|
||||
fun finishText(response: ByteBuffer, code: Int = responseCode) {
|
||||
responseText()
|
||||
responseCode = code
|
||||
setResponseHeader("content-type", "text/plain; charset=UTF-8")
|
||||
finish(response)
|
||||
}
|
||||
|
||||
fun finishJson(response: ByteBuffer, code: Int = responseCode) {
|
||||
responseJson()
|
||||
responseCode = code
|
||||
setResponseHeader("content-type", "application/json; charset=UTF-8")
|
||||
finish(response)
|
||||
}
|
||||
|
||||
fun usingCache() = finish(304)
|
||||
|
||||
fun getCookie(name: String): Cookie? = cookieMap[name]
|
||||
|
||||
fun setCookie(
|
||||
name: String,
|
||||
value: Any,
|
||||
maxAge: Int = 0,
|
||||
domain: String? = null,
|
||||
path: String? = null,
|
||||
sameSite: SameSite? = null
|
||||
) {
|
||||
deleteCookie(name, path ?: "/")
|
||||
addCookie(name, value, maxAge, domain, path, sameSite)
|
||||
}
|
||||
|
||||
fun deleteCookie(name: String, path: String = "/") =
|
||||
addCookie(name, "deleted; expires=Thu, 01 Jan 1970 00:00:00 GMT", path = path)
|
||||
|
||||
fun writeChunkedHeader()
|
||||
fun addChunked(buffer: ByteBuffer)
|
||||
fun finishChunked()
|
||||
|
||||
fun finishChunked(chunked: Chunked)
|
||||
|
||||
fun finishFile(file: File, chunkSize: Int = 8192)
|
||||
@ -157,9 +134,6 @@ interface HttpContent : ResponseHeaderAdapter, RequestHeaderAdapter {
|
||||
finish(302)
|
||||
}
|
||||
|
||||
fun noCache() = cacheControl(CacheControl.NoCache)
|
||||
fun noStore() = cacheControl(CacheControl.NoStore)
|
||||
|
||||
fun finish(msg: String) {
|
||||
write(msg)
|
||||
finish()
|
||||
|
@ -1,9 +1,18 @@
|
||||
package cn.tursom.web
|
||||
|
||||
import cn.tursom.web.utils.parseRange
|
||||
|
||||
interface RequestHeaderAdapter {
|
||||
val cookieMap: Map<String, String>
|
||||
val requestHost: String? get() = getHeader("Host")
|
||||
fun getHeader(header: String): String?
|
||||
fun getHeaders(): List<Map.Entry<String, String>>
|
||||
|
||||
fun getCookie(name: String): String? = cookieMap[name]
|
||||
|
||||
fun getCacheTag(): String? = getHeader("If-None-Match")
|
||||
fun getRequestRange(): List<Pair<Int, Int>>? {
|
||||
val range = getHeader("Range") ?: return null
|
||||
return parseRange(range)
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package cn.tursom.web
|
||||
|
||||
import cn.tursom.web.utils.CacheControl
|
||||
import cn.tursom.web.utils.Cookie
|
||||
import cn.tursom.web.utils.SameSite
|
||||
|
||||
interface ResponseHeaderAdapter {
|
||||
@ -9,6 +10,8 @@ interface ResponseHeaderAdapter {
|
||||
|
||||
fun setCacheTag(tag: Any) = setResponseHeader("Etag", tag)
|
||||
|
||||
fun noCache() = cacheControl(CacheControl.NoCache)
|
||||
fun noStore() = cacheControl(CacheControl.NoStore)
|
||||
fun cacheControl(
|
||||
cacheControl: CacheControl,
|
||||
maxAge: Int? = null,
|
||||
@ -20,10 +23,11 @@ interface ResponseHeaderAdapter {
|
||||
}"
|
||||
)
|
||||
|
||||
fun addCookie(cookie: Cookie) = addCookie(cookie.name, cookie.value, cookie.maxAge, cookie.domain, cookie.path, cookie.sameSite)
|
||||
fun addCookie(
|
||||
name: String,
|
||||
value: Any,
|
||||
maxAge: Int = 0,
|
||||
maxAge: Long = 0,
|
||||
domain: String? = null,
|
||||
path: String? = null,
|
||||
sameSite: SameSite? = null
|
||||
@ -40,4 +44,16 @@ interface ResponseHeaderAdapter {
|
||||
fun setLanguage(language: String) {
|
||||
setResponseHeader("Content-Language", language)
|
||||
}
|
||||
|
||||
fun acceptRanges(unit: String) = setResponseHeader("Accept-Ranges", unit)
|
||||
fun acceptBytesRanges() = acceptRanges("bytes")
|
||||
fun notAcceptRanges() = acceptRanges("none")
|
||||
|
||||
fun range(start: Int, end: Int) = setResponseHeader("Content-Range", "$start-$end/*")
|
||||
fun range(start: Int, end: Int, resourceSize: Int) = setResponseHeader("Content-Range", "$start-$end/$resourceSize")
|
||||
fun range(resourceSize: Int) = setResponseHeader("Content-Range", "*/$resourceSize")
|
||||
|
||||
fun responseHtml() = setResponseHeader("content-type", "text/html; charset=UTF-8")
|
||||
fun responseText() = setResponseHeader("content-type", "text/plain; charset=UTF-8")
|
||||
fun responseJson() = setResponseHeader("content-type", "application/json; charset=UTF-8")
|
||||
}
|
@ -15,8 +15,7 @@ class EmptyHttpContent(
|
||||
override val body: ByteBuffer? = null,
|
||||
override val clientIp: SocketAddress = InetSocketAddress(0),
|
||||
override val method: String = "GET",
|
||||
//override val responseBody: ByteArrayOutputStream = ByteArrayOutputStream(0),
|
||||
override val cookieMap: Map<String, Cookie> = mapOf()
|
||||
override val cookieMap: Map<String, String> = mapOf()
|
||||
) : HttpContent {
|
||||
override fun getHeader(header: String): String? = null
|
||||
override fun getHeaders(): List<Map.Entry<String, String>> = listOf()
|
||||
|
53
web/src/main/kotlin/cn/tursom/web/utils/HttpUtil.kt
Normal file
53
web/src/main/kotlin/cn/tursom/web/utils/HttpUtil.kt
Normal file
@ -0,0 +1,53 @@
|
||||
package cn.tursom.web.utils
|
||||
|
||||
fun parseRange(range: String): ArrayList<Pair<Int, Int>> {
|
||||
var index = 6
|
||||
val rangeList = ArrayList<Pair<Int, Int>>()
|
||||
var start = index
|
||||
var first = -1
|
||||
while (index < range.length) {
|
||||
when (range[index]) {
|
||||
'-' -> {
|
||||
first = range.substring(start, index).toInt()
|
||||
start = ++index
|
||||
}
|
||||
',' -> {
|
||||
rangeList.add(first to range.substring(start, index).toInt())
|
||||
index += 2
|
||||
start = index
|
||||
}
|
||||
else -> index++
|
||||
}
|
||||
}
|
||||
if (range.last() != '-') {
|
||||
rangeList.add(first to range.substring(start, index).toInt())
|
||||
} else {
|
||||
rangeList.add(first to -1)
|
||||
}
|
||||
return rangeList
|
||||
}
|
||||
|
||||
fun parseCookie(cookies: List<String>): Map<String, String> {
|
||||
var index = 6
|
||||
val cookiesMap = HashMap<String, String>()
|
||||
var start = index
|
||||
var key = ""
|
||||
cookies.forEach { cookie ->
|
||||
while (index < cookie.length) {
|
||||
when (cookie[index]) {
|
||||
'-' -> {
|
||||
key = cookie.substring(start, index)
|
||||
start = ++index
|
||||
}
|
||||
';' -> {
|
||||
cookiesMap[key] = cookie.substring(start, index)
|
||||
index += 2
|
||||
start = index
|
||||
}
|
||||
else -> index++
|
||||
}
|
||||
}
|
||||
cookiesMap[key] = cookie.substring(start, index)
|
||||
}
|
||||
return cookiesMap
|
||||
}
|
Loading…
Reference in New Issue
Block a user