mirror of
https://github.com/tursom/TursomServer.git
synced 2025-03-13 11:20:10 +08:00
添加日志记录
This commit is contained in:
parent
48ba8855bc
commit
560eddac2a
29
log/src/main/kotlin/cn/tursom/log/LogUtils.kt
Normal file
29
log/src/main/kotlin/cn/tursom/log/LogUtils.kt
Normal file
@ -0,0 +1,29 @@
|
||||
package cn.tursom.log
|
||||
|
||||
inline fun lazyLog(crossinline toString: () -> String) = object {
|
||||
override fun toString(): String = toString()
|
||||
}
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun lazyPrettyMap(map: Iterator<Map.Entry<CharSequence, Any>>) = lazyLog {
|
||||
val sb = StringBuilder("{\n")
|
||||
map.forEach { (k, v) ->
|
||||
sb.append(" $k: $v\n")
|
||||
}
|
||||
sb.append("}")
|
||||
sb.toString()
|
||||
}
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun lazyPrettyMap(map: Iterable<Map.Entry<CharSequence, Any>>) = if (map.iterator().hasNext()) {
|
||||
lazyPrettyMap(map.iterator())
|
||||
} else {
|
||||
"{}"
|
||||
}
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun lazyPrettyMap(map: Map<out CharSequence, Any>) = if (map.isNotEmpty()) {
|
||||
lazyPrettyMap(map.iterator())
|
||||
} else {
|
||||
"{}"
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
dependencies {
|
||||
implementation project(":")
|
||||
implementation project(":web")
|
||||
api project(":log")
|
||||
implementation group: "io.netty", name: "netty-all", version: "4.1.43.Final"
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import io.netty.buffer.ByteBufAllocator
|
||||
import io.netty.buffer.Unpooled
|
||||
import io.netty.channel.ChannelHandlerContext
|
||||
import io.netty.handler.stream.ChunkedInput
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
class NettyChunkedByteBuffer(private val bufList: List<ByteBuffer>) : ChunkedInput<ByteBuf> {
|
||||
constructor(vararg bufList: ByteBuffer) : this(bufList.asList())
|
||||
@ -29,6 +30,7 @@ class NettyChunkedByteBuffer(private val bufList: List<ByteBuffer>) : ChunkedInp
|
||||
override fun readChunk(allocator: ByteBufAllocator?): ByteBuf = readChunk()
|
||||
|
||||
private fun readChunk(): ByteBuf {
|
||||
log?.trace("readChunk")
|
||||
this.next?.close()
|
||||
val next = iterator.next()
|
||||
this.next = next
|
||||
@ -37,6 +39,16 @@ class NettyChunkedByteBuffer(private val bufList: List<ByteBuffer>) : ChunkedInp
|
||||
else Unpooled.wrappedBuffer(next.readBuffer())
|
||||
}
|
||||
|
||||
override fun close() {}
|
||||
override fun close() {
|
||||
log?.trace("close")
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val log = try {
|
||||
LoggerFactory.getLogger(NettyChunkedByteBuffer::class.java)
|
||||
} catch (e: Throwable) {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,23 +6,33 @@ import io.netty.buffer.ByteBufAllocator
|
||||
import io.netty.buffer.Unpooled
|
||||
import io.netty.channel.ChannelHandlerContext
|
||||
import io.netty.handler.stream.ChunkedInput
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
class NettyChunkedInput(val chunked: Chunked) : ChunkedInput<ByteBuf> {
|
||||
override fun progress(): Long = chunked.progress
|
||||
override fun length() = chunked.length
|
||||
override fun isEndOfInput(): Boolean = chunked.endOfInput
|
||||
class NettyChunkedInput(private val chunked: Chunked) : ChunkedInput<ByteBuf> {
|
||||
override fun progress(): Long = chunked.progress
|
||||
override fun length() = chunked.length
|
||||
override fun isEndOfInput(): Boolean = chunked.endOfInput
|
||||
|
||||
override fun readChunk(ctx: ChannelHandlerContext?): ByteBuf {
|
||||
val buf = chunked.readChunk()
|
||||
return if (buf is NettyByteBuffer) buf.byteBuf
|
||||
else Unpooled.wrappedBuffer(buf.readBuffer())
|
||||
}
|
||||
override fun readChunk(ctx: ChannelHandlerContext?): ByteBuf = readChunk()
|
||||
override fun readChunk(allocator: ByteBufAllocator?): ByteBuf = readChunk()
|
||||
@Suppress("MemberVisibilityCanBePrivate")
|
||||
fun readChunk(): ByteBuf {
|
||||
val buf = chunked.readChunk()
|
||||
log?.trace("readChunk {}", buf)
|
||||
return if (buf is NettyByteBuffer) buf.byteBuf
|
||||
else Unpooled.wrappedBuffer(buf.readBuffer())
|
||||
}
|
||||
|
||||
override fun readChunk(allocator: ByteBufAllocator?): ByteBuf {
|
||||
val buf = chunked.readChunk()
|
||||
return if (buf is NettyByteBuffer) buf.byteBuf
|
||||
else Unpooled.wrappedBuffer(buf.readBuffer())
|
||||
}
|
||||
override fun close() {
|
||||
log?.trace("close")
|
||||
chunked.close()
|
||||
}
|
||||
|
||||
override fun close() = chunked.close()
|
||||
companion object {
|
||||
private val log = try {
|
||||
LoggerFactory.getLogger(NettyChunkedInput::class.java)
|
||||
} catch (e: Throwable) {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
@ -9,6 +9,7 @@ import io.netty.buffer.Unpooled
|
||||
import io.netty.channel.ChannelHandlerContext
|
||||
import io.netty.handler.codec.http.*
|
||||
import io.netty.handler.stream.ChunkedFile
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.io.File
|
||||
import java.io.RandomAccessFile
|
||||
import kotlin.collections.set
|
||||
@ -31,7 +32,7 @@ open class NettyHttpContent(
|
||||
val httpMethod: HttpMethod get() = msg.method()
|
||||
val protocolVersion: HttpVersion get() = msg.protocolVersion()
|
||||
val headers: HttpHeaders get() = msg.headers()
|
||||
protected val paramMap by lazy { RequestParser.parse(msg) }
|
||||
protected val paramMap by lazy { ParamParser.parse(msg) }
|
||||
override val cookieMap by lazy { getHeader("Cookie")?.let { decodeCookie(it) } ?: mapOf() }
|
||||
override val body = msg.content()?.let { NettyByteBuffer(it) }
|
||||
|
||||
@ -48,26 +49,32 @@ open class NettyHttpContent(
|
||||
val responseBodyBuf: CompositeByteBuf = ctx.alloc().compositeBuffer()!!
|
||||
|
||||
override fun getHeader(header: String): String? {
|
||||
log?.trace("getHeader {}", header)
|
||||
return headers[header]
|
||||
}
|
||||
|
||||
override fun getHeaders(header: String): List<String> {
|
||||
log?.trace("getHeaders {}", header)
|
||||
return headers.getAll(header)
|
||||
}
|
||||
|
||||
override fun getHeaders(): Iterable<Map.Entry<String, String>> {
|
||||
log?.trace("getHeaders")
|
||||
return headers
|
||||
}
|
||||
|
||||
override fun getParams(): Map<String, List<String>> {
|
||||
log?.trace("getParams")
|
||||
return paramMap
|
||||
}
|
||||
|
||||
override fun getParams(param: String): List<String>? {
|
||||
log?.trace("getParams {}", param)
|
||||
return paramMap[param]
|
||||
}
|
||||
|
||||
override fun addParam(key: String, value: String) {
|
||||
log?.trace("addParam {}: {}", key, value)
|
||||
if (!paramMap.containsKey(key)) {
|
||||
paramMap[key] = ArrayList()
|
||||
}
|
||||
@ -75,23 +82,27 @@ open class NettyHttpContent(
|
||||
}
|
||||
|
||||
override fun write(message: String) {
|
||||
log?.trace("write {}", message)
|
||||
responseBodyBuf.addComponent(Unpooled.wrappedBuffer(message.toByteArray()))
|
||||
//responseBody.write(message.toByteArray())
|
||||
}
|
||||
|
||||
override fun write(byte: Byte) {
|
||||
log?.trace("write {}", byte)
|
||||
val buffer = ctx.alloc().buffer(1).writeByte(byte.toInt())
|
||||
responseBodyBuf.addComponent(buffer)
|
||||
//responseBody.write(byte.toInt())
|
||||
}
|
||||
|
||||
override fun write(bytes: ByteArray, offset: Int, size: Int) {
|
||||
log?.trace("write {}({}:{})", bytes, offset, size)
|
||||
responseBodyBuf.addComponent(Unpooled.wrappedBuffer(bytes, offset, size))
|
||||
//responseBody.write(bytes, offset, size)
|
||||
}
|
||||
|
||||
override fun write(buffer: ByteBuffer) {
|
||||
//buffer.writeTo(responseBody)
|
||||
log?.trace("write {}", buffer)
|
||||
responseBodyBuf.addComponent(if (buffer is NettyByteBuffer) {
|
||||
buffer.byteBuf
|
||||
} else {
|
||||
@ -102,18 +113,22 @@ open class NettyHttpContent(
|
||||
}
|
||||
|
||||
override fun reset() {
|
||||
log?.trace("reset")
|
||||
responseBodyBuf.clear()
|
||||
}
|
||||
|
||||
override fun finish() {
|
||||
log?.trace("finish")
|
||||
finish(responseBodyBuf)
|
||||
}
|
||||
|
||||
override fun finish(buffer: ByteArray, offset: Int, size: Int) {
|
||||
log?.trace("finish ByteArray[{}]({}:{})", buffer.size, offset, size)
|
||||
finish(Unpooled.wrappedBuffer(buffer, offset, size))
|
||||
}
|
||||
|
||||
override fun finish(buffer: ByteBuffer) {
|
||||
log?.trace("finish {}", buffer)
|
||||
if (buffer is NettyByteBuffer) {
|
||||
finish(buffer.byteBuf)
|
||||
} else {
|
||||
@ -123,11 +138,13 @@ open class NettyHttpContent(
|
||||
|
||||
fun finish(buf: ByteBuf) = finish(buf, responseStatus)
|
||||
fun finish(buf: ByteBuf, responseCode: HttpResponseStatus) {
|
||||
log?.trace("finish {}: {}", responseCode, buf)
|
||||
val response = DefaultFullHttpResponse(HttpVersion.HTTP_1_1, responseCode, buf)
|
||||
finish(response)
|
||||
}
|
||||
|
||||
fun finish(response: FullHttpResponse) {
|
||||
log?.trace("finish {}", response)
|
||||
finished = true
|
||||
val heads = response.headers()
|
||||
addHeaders(
|
||||
@ -142,6 +159,7 @@ open class NettyHttpContent(
|
||||
}
|
||||
|
||||
override fun writeChunkedHeader() {
|
||||
log?.trace("writeChunkedHeader")
|
||||
val response = DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK)
|
||||
response.status = if (responseMessage != null) HttpResponseStatus(responseCode, responseMessage)
|
||||
else responseStatus
|
||||
@ -157,10 +175,12 @@ open class NettyHttpContent(
|
||||
}
|
||||
|
||||
override fun addChunked(buffer: ByteBuffer) {
|
||||
log?.trace("addChunked {}", buffer)
|
||||
chunkedList.add(buffer)
|
||||
}
|
||||
|
||||
override fun finishChunked() {
|
||||
log?.trace("finishChunked {}", chunkedList)
|
||||
finished = true
|
||||
writeChunkedHeader()
|
||||
val httpChunkWriter = HttpChunkedInput(NettyChunkedByteBuffer(chunkedList))
|
||||
@ -168,6 +188,7 @@ open class NettyHttpContent(
|
||||
}
|
||||
|
||||
override fun finishChunked(chunked: Chunked) {
|
||||
log?.trace("finishChunked {}", chunked)
|
||||
finished = true
|
||||
writeChunkedHeader()
|
||||
val httpChunkWriter = HttpChunkedInput(NettyChunkedInput(chunked))
|
||||
@ -175,15 +196,25 @@ open class NettyHttpContent(
|
||||
}
|
||||
|
||||
override fun finishFile(file: File, chunkSize: Int) {
|
||||
log?.trace("finishFile {} chunkSize {}", file, chunkSize)
|
||||
finished = true
|
||||
writeChunkedHeader()
|
||||
ctx.writeAndFlush(HttpChunkedInput(ChunkedFile(file, chunkSize)))
|
||||
}
|
||||
|
||||
override fun finishFile(file: RandomAccessFile, offset: Long, length: Long, chunkSize: Int) {
|
||||
log?.trace("finishFile {}({}:{}) chunkSize {}", file, offset, length, chunkSize)
|
||||
finished = true
|
||||
writeChunkedHeader()
|
||||
ctx.writeAndFlush(HttpChunkedInput(ChunkedFile(file, offset, length, chunkSize)))
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val log = try {
|
||||
LoggerFactory.getLogger(NettyHttpContent::class.java)
|
||||
} catch (e: Throwable) {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@ import io.netty.channel.ChannelHandlerContext
|
||||
import io.netty.channel.SimpleChannelInboundHandler
|
||||
import io.netty.handler.codec.http.FullHttpRequest
|
||||
import io.netty.handler.codec.http.HttpResponseStatus
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
@ChannelHandler.Sharable
|
||||
class NettyHttpHandler(
|
||||
@ -14,6 +15,7 @@ class NettyHttpHandler(
|
||||
|
||||
override fun channelRead0(ctx: ChannelHandlerContext, msg: FullHttpRequest) {
|
||||
val handlerContext = NettyHttpContent(ctx, msg)
|
||||
log?.debug("{} {} {}", handlerContext.clientIp, handlerContext.method, handlerContext.uri)
|
||||
handler.handle(handlerContext)
|
||||
}
|
||||
|
||||
@ -23,6 +25,7 @@ class NettyHttpHandler(
|
||||
}
|
||||
|
||||
override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) {
|
||||
log?.error("exception cause on NettyHttpHandler", cause)
|
||||
val content = NettyExceptionContent(ctx, cause)
|
||||
handler.exceptionCause(content)
|
||||
if (!content.finished) {
|
||||
@ -31,4 +34,12 @@ class NettyHttpHandler(
|
||||
}
|
||||
ctx.close()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val log = try {
|
||||
LoggerFactory.getLogger(NettyHttpHandler::class.java)
|
||||
} catch (e: Throwable) {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
@ -15,7 +15,9 @@ import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler
|
||||
import io.netty.handler.stream.ChunkedWriteHandler
|
||||
import io.netty.handler.timeout.ReadTimeoutHandler
|
||||
import io.netty.handler.timeout.WriteTimeoutHandler
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
@Suppress("unused")
|
||||
class NettyHttpServer(
|
||||
override val port: Int,
|
||||
handler: HttpHandler<NettyHttpContent, NettyExceptionContent>,
|
||||
@ -47,14 +49,10 @@ class NettyHttpServer(
|
||||
override fun initChannel(ch: SocketChannel) {
|
||||
ch.pipeline()
|
||||
.apply {
|
||||
if (readTimeout != null) {
|
||||
addLast(ReadTimeoutHandler(readTimeout))
|
||||
}
|
||||
if (readTimeout != null) addLast(ReadTimeoutHandler(readTimeout))
|
||||
}
|
||||
.apply {
|
||||
if (writeTimeout != null) {
|
||||
addLast(WriteTimeoutHandler(writeTimeout))
|
||||
}
|
||||
if (writeTimeout != null) addLast(WriteTimeoutHandler(writeTimeout))
|
||||
}
|
||||
.addLast("codec", HttpServerCodec())
|
||||
.addLast("aggregator", HttpObjectAggregator(bodySize))
|
||||
@ -77,11 +75,22 @@ class NettyHttpServer(
|
||||
}
|
||||
|
||||
override fun run() {
|
||||
log?.warn("NettyHttpServer started on port {}", port)
|
||||
log?.info("try http://localhost:{}/", port)
|
||||
future.sync()
|
||||
}
|
||||
|
||||
override fun close() {
|
||||
log?.warn("NettyHttpServer({}) closed", port)
|
||||
future.cancel(false)
|
||||
future.channel().close()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val log = try {
|
||||
LoggerFactory.getLogger(NettyHttpServer::class.java)
|
||||
} catch (e: Throwable) {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
@ -1,8 +1,12 @@
|
||||
package cn.tursom.web.netty
|
||||
|
||||
import cn.tursom.log.lazyPrettyMap
|
||||
import cn.tursom.web.ResponseHeaderAdapter
|
||||
import io.netty.handler.codec.http.HttpHeaders
|
||||
import java.util.HashMap
|
||||
import org.slf4j.LoggerFactory
|
||||
import kotlin.collections.component1
|
||||
import kotlin.collections.component2
|
||||
import kotlin.collections.set
|
||||
|
||||
@Suppress("MemberVisibilityCanBePrivate")
|
||||
open class NettyResponseHeaderAdapter : ResponseHeaderAdapter {
|
||||
@ -10,11 +14,13 @@ open class NettyResponseHeaderAdapter : ResponseHeaderAdapter {
|
||||
val responseListMap = HashMap<String, ArrayList<Any>>()
|
||||
|
||||
override fun setResponseHeader(name: String, value: Any) {
|
||||
log?.trace("setResponseHeader {}: {}", name, value)
|
||||
responseMap[name] = value
|
||||
responseListMap.remove(name)
|
||||
}
|
||||
|
||||
override fun addResponseHeader(name: String, value: Any) {
|
||||
log?.trace("addResponseHeader {}: {}", name, value)
|
||||
val list = responseListMap[name] ?: run {
|
||||
val newList = ArrayList<Any>()
|
||||
responseListMap[name] = newList
|
||||
@ -28,6 +34,7 @@ open class NettyResponseHeaderAdapter : ResponseHeaderAdapter {
|
||||
}
|
||||
|
||||
protected fun addHeaders(heads: HttpHeaders, defaultHeaders: Map<out CharSequence, Any>) {
|
||||
log?.trace("addHeader\nheaders {}\ndefault {}", lazyPrettyMap(heads), lazyPrettyMap(defaultHeaders))
|
||||
responseListMap.forEach { (t, u) ->
|
||||
u.forEach {
|
||||
heads.add(t, it)
|
||||
@ -44,4 +51,12 @@ open class NettyResponseHeaderAdapter : ResponseHeaderAdapter {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val log = try {
|
||||
LoggerFactory.getLogger(NettyResponseHeaderAdapter::class.java)
|
||||
} catch (e: Throwable) {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
@ -5,12 +5,14 @@ import io.netty.handler.codec.http.HttpMethod
|
||||
import io.netty.handler.codec.http.QueryStringDecoder
|
||||
import io.netty.handler.codec.http.multipart.Attribute
|
||||
import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder
|
||||
import java.util.HashMap
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
import kotlin.collections.set
|
||||
|
||||
/**
|
||||
* HTTP请求参数解析器, 支持GET, POST
|
||||
*/
|
||||
object RequestParser {
|
||||
object ParamParser {
|
||||
fun parse(fullReq: FullHttpRequest): HashMap<String, List<String>> {
|
||||
val method = fullReq.method()
|
||||
|
@ -3,6 +3,7 @@ package cn.tursom.web
|
||||
import cn.tursom.core.buffer.ByteBuffer
|
||||
import cn.tursom.core.urlDecode
|
||||
import cn.tursom.web.utils.Chunked
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.io.File
|
||||
import java.io.RandomAccessFile
|
||||
import java.net.SocketAddress
|
||||
@ -36,6 +37,7 @@ interface HttpContent : ResponseHeaderAdapter, RequestHeaderAdapter {
|
||||
fun finish()
|
||||
fun finish(buffer: ByteArray, offset: Int = 0, size: Int = buffer.size - offset)
|
||||
fun finish(buffer: ByteBuffer) {
|
||||
log?.trace("buffer {}", buffer)
|
||||
if (buffer.hasArray) {
|
||||
finish(buffer.array, buffer.readOffset, buffer.readAllSize())
|
||||
} else {
|
||||
@ -48,54 +50,63 @@ interface HttpContent : ResponseHeaderAdapter, RequestHeaderAdapter {
|
||||
fun finish(code: Int) = finishHtml(code)
|
||||
|
||||
fun finishHtml(code: Int = responseCode) {
|
||||
log?.trace("finishHtml {}", code)
|
||||
responseHtml()
|
||||
responseCode = code
|
||||
finish()
|
||||
}
|
||||
|
||||
fun finishText(code: Int = responseCode) {
|
||||
log?.trace("finishText {}", code)
|
||||
responseText()
|
||||
responseCode = code
|
||||
finish()
|
||||
}
|
||||
|
||||
fun finishJson(code: Int = responseCode) {
|
||||
log?.trace("finishJson {}", code)
|
||||
responseJson()
|
||||
responseCode = code
|
||||
finish()
|
||||
}
|
||||
|
||||
fun finishHtml(response: ByteArray, code: Int = responseCode) {
|
||||
log?.trace("finishHtml {}: {}", code, response)
|
||||
responseHtml()
|
||||
responseCode = code
|
||||
finish(response)
|
||||
}
|
||||
|
||||
fun finishText(response: ByteArray, code: Int = responseCode) {
|
||||
log?.trace("finishText {}: {}", code, response)
|
||||
responseText()
|
||||
responseCode = code
|
||||
finish(response)
|
||||
}
|
||||
|
||||
fun finishJson(response: ByteArray, code: Int = responseCode) {
|
||||
log?.trace("finishJson {}: {}", code, response)
|
||||
responseJson()
|
||||
responseCode = code
|
||||
finish(response)
|
||||
}
|
||||
|
||||
fun finishHtml(response: ByteBuffer, code: Int = responseCode) {
|
||||
log?.trace("finishHtml {}: {}", code, response)
|
||||
responseHtml()
|
||||
responseCode = code
|
||||
finish(response)
|
||||
}
|
||||
|
||||
fun finishText(response: ByteBuffer, code: Int = responseCode) {
|
||||
log?.trace("finishText {}: {}", code, response)
|
||||
responseText()
|
||||
responseCode = code
|
||||
finish(response)
|
||||
}
|
||||
|
||||
fun finishJson(response: ByteBuffer, code: Int = responseCode) {
|
||||
log?.trace("finishJson {}: {}", code, response)
|
||||
responseJson()
|
||||
responseCode = code
|
||||
finish(response)
|
||||
@ -123,18 +134,29 @@ interface HttpContent : ResponseHeaderAdapter, RequestHeaderAdapter {
|
||||
fun moved(url: String) = permanentlyMoved(url)
|
||||
|
||||
fun permanentlyMoved(url: String) {
|
||||
log?.trace("permanentlyMoved {}", url)
|
||||
setResponseHeader("Location", url)
|
||||
finish(301)
|
||||
}
|
||||
|
||||
fun temporaryMoved(url: String) {
|
||||
log?.trace("temporaryMoved {}", url)
|
||||
noStore()
|
||||
setResponseHeader("Location", url)
|
||||
finish(302)
|
||||
}
|
||||
|
||||
fun finish(msg: String) {
|
||||
log?.trace("finish {}", msg)
|
||||
write(msg)
|
||||
finish()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val log = try {
|
||||
LoggerFactory.getLogger(HttpContent::class.java)
|
||||
} catch (e: Throwable) {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,9 @@
|
||||
package cn.tursom.web.mapping
|
||||
|
||||
import cn.tursom.web.utils.MethodEnum
|
||||
|
||||
annotation class Mapping(
|
||||
vararg val route: String,
|
||||
val method: String = ""
|
||||
val method: String = "",
|
||||
val methodEnum: MethodEnum = MethodEnum.NONE
|
||||
)
|
@ -8,13 +8,9 @@ import cn.tursom.web.HttpContent
|
||||
import cn.tursom.web.HttpHandler
|
||||
import cn.tursom.web.MutableHttpContent
|
||||
import cn.tursom.web.mapping.*
|
||||
import cn.tursom.web.result.Html
|
||||
import cn.tursom.web.result.Json
|
||||
import cn.tursom.web.result.Text
|
||||
import cn.tursom.web.result.*
|
||||
import cn.tursom.web.router.impl.SimpleRouter
|
||||
import cn.tursom.web.utils.Chunked
|
||||
import cn.tursom.web.result.ContextType
|
||||
import cn.tursom.web.result.NoReturnLog
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.io.File
|
||||
import java.io.RandomAccessFile
|
||||
@ -56,7 +52,6 @@ open class RoutedHttpHandler(
|
||||
}
|
||||
|
||||
override fun handle(content: HttpContent) {
|
||||
log?.debug("{} {} {}", content.clientIp, content.method, content.uri)
|
||||
if (content is MutableHttpContent) {
|
||||
handle(content, getHandler(content, content.method, content.uri))
|
||||
} else {
|
||||
@ -77,6 +72,7 @@ open class RoutedHttpHandler(
|
||||
}
|
||||
|
||||
open fun addRouter(handler: Any) {
|
||||
log?.info("add router {}", handler)
|
||||
@Suppress("LeakingThis")
|
||||
val clazz = handler.javaClass
|
||||
clazz.methods.forEach { method ->
|
||||
@ -180,6 +176,7 @@ open class RoutedHttpHandler(
|
||||
}
|
||||
|
||||
open fun deleteRouter(handler: Any) {
|
||||
log?.info("delete router {}", handler)
|
||||
@Suppress("LeakingThis")
|
||||
val clazz = handler.javaClass
|
||||
clazz.methods.forEach { method ->
|
||||
@ -217,7 +214,7 @@ open class RoutedHttpHandler(
|
||||
|
||||
protected fun getRoutes(annotation: Annotation) = when (annotation) {
|
||||
is Mapping -> {
|
||||
annotation.route to getRouter(annotation.method)
|
||||
annotation.route to getRouter(annotation.method.let { if (it.isEmpty()) annotation.methodEnum.method else it })
|
||||
}
|
||||
is GetMapping -> {
|
||||
annotation.route to getRouter("GET")
|
||||
@ -322,7 +319,7 @@ open class RoutedHttpHandler(
|
||||
}
|
||||
|
||||
fun finishHtml(result: Any?, content: HttpContent, doLog: Boolean = true) {
|
||||
if (doLog) log?.debug("{}: finishHtml: {}", content.clientIp, result)
|
||||
if (doLog) log?.debug("{} finishHtml {}", content.clientIp, result)
|
||||
result ?: return
|
||||
when (result) {
|
||||
is ByteBuffer -> content.finishHtml(result)
|
||||
@ -339,7 +336,7 @@ open class RoutedHttpHandler(
|
||||
}
|
||||
|
||||
fun finishText(result: Any?, content: HttpContent, doLog: Boolean = true) {
|
||||
if (doLog) log?.debug("{}: finishText: {}", content.clientIp, result)
|
||||
if (doLog) log?.debug("{} finishText {}", content.clientIp, result)
|
||||
result ?: return
|
||||
when (result) {
|
||||
is ByteBuffer -> content.finishText(result)
|
||||
@ -356,7 +353,7 @@ open class RoutedHttpHandler(
|
||||
}
|
||||
|
||||
fun finishJson(result: Any?, content: HttpContent, doLog: Boolean = true) {
|
||||
if (doLog) log?.debug("{}: finishJson: {}", content.clientIp, result)
|
||||
if (doLog) log?.debug("{} finishJson {}", content.clientIp, result)
|
||||
result ?: return
|
||||
when (result) {
|
||||
is ByteBuffer -> content.finishJson(result)
|
||||
@ -371,7 +368,7 @@ open class RoutedHttpHandler(
|
||||
}
|
||||
else -> {
|
||||
val json = json?.toJson(result)
|
||||
if (doLog) log?.debug("{}: finishJson: generate json: {}", content.clientIp, json)
|
||||
if (doLog) log?.debug("{} finishJson: generate json {}", content.clientIp, json)
|
||||
if (json != null) {
|
||||
content.finishJson(json.toByteArray())
|
||||
} else {
|
||||
|
7
web/src/main/kotlin/cn/tursom/web/utils/MethodEnum.kt
Normal file
7
web/src/main/kotlin/cn/tursom/web/utils/MethodEnum.kt
Normal file
@ -0,0 +1,7 @@
|
||||
package cn.tursom.web.utils
|
||||
|
||||
enum class MethodEnum(val method: String) {
|
||||
CONNECT("CONNECT"), DELETE("DELETE"), GET("GET"), HEAD("HEAD"),
|
||||
OPTIONS("OPTIONS"), PATCH("PATCH"), POST("POST"), PUT("PUT"),
|
||||
TRACE("TRACE"), NONE("")
|
||||
}
|
@ -3,12 +3,8 @@ package cn.tursom.web.router
|
||||
import cn.tursom.web.HttpContent
|
||||
import cn.tursom.web.MutableHttpContent
|
||||
import cn.tursom.web.mapping.*
|
||||
import cn.tursom.web.result.Html
|
||||
import cn.tursom.web.result.Json
|
||||
import cn.tursom.web.result.Text
|
||||
import cn.tursom.web.result.*
|
||||
import cn.tursom.web.router.impl.SimpleRouter
|
||||
import cn.tursom.web.result.ContextType
|
||||
import cn.tursom.web.result.NoReturnLog
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import org.slf4j.LoggerFactory
|
||||
@ -26,7 +22,6 @@ open class AsyncRoutedHttpHandler(
|
||||
protected val asyncRouterMap: HashMap<String, Router<Pair<Any?, suspend (HttpContent) -> Unit>>> = HashMap()
|
||||
|
||||
override fun handle(content: HttpContent) {
|
||||
log?.debug("{} {} {}", content.clientIp, content.method, content.uri)
|
||||
if (content is MutableHttpContent) {
|
||||
val handler = getAsyncHandler(content, content.method, content.uri)
|
||||
if (handler != null) GlobalScope.launch {
|
||||
@ -143,7 +138,7 @@ open class AsyncRoutedHttpHandler(
|
||||
|
||||
protected fun getAsyncRoutes(annotation: Annotation) = when (annotation) {
|
||||
is Mapping -> {
|
||||
annotation.route to getAsyncRouter(annotation.method)
|
||||
annotation.route to getAsyncRouter(annotation.method.let { if (it.isEmpty()) annotation.methodEnum.method else it })
|
||||
}
|
||||
is GetMapping -> {
|
||||
annotation.route to getAsyncRouter("GET")
|
||||
|
Loading…
Reference in New Issue
Block a user