0
0
mirror of https://github.com/tursom/TursomServer.git synced 2025-03-07 16:20:08 +08:00

进一步优化结构

This commit is contained in:
tursom 2019-11-22 10:34:53 +08:00
parent 2629b93c23
commit 696f35a254
7 changed files with 101 additions and 54 deletions

View File

@ -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
}

View File

@ -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
}

View File

@ -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()

View File

@ -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)
}
}

View File

@ -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")
}

View File

@ -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()

View 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
}