NettyHttpServer add SSL support

This commit is contained in:
tursom 2021-05-14 10:54:18 +08:00
parent 993de664d9
commit c0be3e52a2
2 changed files with 45 additions and 17 deletions

View File

@ -5,10 +5,7 @@ import cn.tursom.core.buffer.impl.NettyByteBuffer
import io.netty.bootstrap.Bootstrap
import io.netty.buffer.ByteBuf
import io.netty.buffer.Unpooled
import io.netty.channel.Channel
import io.netty.channel.ChannelFuture
import io.netty.channel.ChannelInitializer
import io.netty.channel.EventLoopGroup
import io.netty.channel.*
import io.netty.channel.nio.NioEventLoopGroup
import io.netty.channel.socket.SocketChannel
import io.netty.channel.socket.nio.NioSocketChannel
@ -37,7 +34,8 @@ class WebSocketClient(
var initChannel: ((ch: SocketChannel) -> Unit)? = null
) {
private val uri: URI = URI.create(url)
internal var ch: Channel? = null
var ch: Channel? = null
internal set
fun open() {
close()
@ -111,10 +109,8 @@ class WebSocketClient(
ch?.writeAndFlush(CloseWebSocketFrame())
} else {
ch?.writeAndFlush(CloseWebSocketFrame(WebSocketCloseStatus.NORMAL_CLOSURE, reasonText))
}
ch?.close()
}?.addListener(ChannelFutureListener.CLOSE)
return ch?.closeFuture()
//ch?.closeFuture()?.sync()
}
fun write(text: String): ChannelFuture {
@ -194,6 +190,6 @@ class WebSocketClient(
}
companion object {
private val group: EventLoopGroup = NioEventLoopGroup()
val group: EventLoopGroup = NioEventLoopGroup()
}
}

View File

@ -5,6 +5,7 @@ import cn.tursom.web.HttpHandler
import cn.tursom.web.HttpServer
import cn.tursom.web.WebSocketHandler
import io.netty.bootstrap.ServerBootstrap
import io.netty.buffer.ByteBufAllocator
import io.netty.channel.ChannelFuture
import io.netty.channel.ChannelInitializer
import io.netty.channel.ChannelOption
@ -16,6 +17,7 @@ import io.netty.handler.codec.http.HttpObject
import io.netty.handler.codec.http.HttpObjectAggregator
import io.netty.handler.codec.http.HttpServerCodec
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler
import io.netty.handler.ssl.SslHandler
import io.netty.handler.stream.ChunkedWriteHandler
import io.netty.handler.timeout.ReadTimeoutHandler
import io.netty.handler.timeout.WriteTimeoutHandler
@ -30,9 +32,12 @@ class NettyHttpServer(
var webSocketPath: Iterable<Pair<String, WebSocketHandler<NettyWebSocketContent>>> = listOf(),
var readTimeout: Int? = 60,
var writeTimeout: Int? = null,
decodeType: NettyHttpDecodeType = if (webSocketPath.iterator().hasNext()) NettyHttpDecodeType.FULL_HTTP else NettyHttpDecodeType.MULTI_PART,
decodeType: NettyHttpDecodeType = if (webSocketPath.iterator()
.hasNext()
) NettyHttpDecodeType.FULL_HTTP else NettyHttpDecodeType.MULTI_PART,
backlog: Int = 1024,
val wrapWebSocketFrame: Boolean = false,
val sslHandlerBuilder: ((allocator: ByteBufAllocator) -> SslHandler)? = null,
) : HttpServer {
constructor(
port: Int,
@ -41,16 +46,27 @@ class NettyHttpServer(
webSocketPath: Iterable<Pair<String, WebSocketHandler<NettyWebSocketContent>>> = listOf(),
readTimeout: Int? = 60,
writeTimeout: Int? = null,
decodeType: NettyHttpDecodeType = if (webSocketPath.iterator().hasNext()) NettyHttpDecodeType.FULL_HTTP else NettyHttpDecodeType.MULTI_PART,
decodeType: NettyHttpDecodeType = if (webSocketPath.iterator()
.hasNext()
) NettyHttpDecodeType.FULL_HTTP else NettyHttpDecodeType.MULTI_PART,
backlog: Int = 1024,
wrapWebSocketFrame: Boolean = false,
sslHandlerBuilder: ((allocator: ByteBufAllocator) -> SslHandler)? = null,
handler: (content: NettyHttpContent) -> Unit,
) : this(
port,
object : HttpHandler<NettyHttpContent, NettyExceptionContent> {
override fun handle(content: NettyHttpContent) = handler(content)
},
bodySize, autoRun, webSocketPath, readTimeout, writeTimeout, decodeType, backlog, wrapWebSocketFrame
bodySize,
autoRun,
webSocketPath,
readTimeout,
writeTimeout,
decodeType,
backlog,
wrapWebSocketFrame,
sslHandlerBuilder
)
var decodeType: NettyHttpDecodeType = decodeType
@ -73,6 +89,12 @@ class NettyHttpServer(
.childHandler(object : ChannelInitializer<SocketChannel>() {
override fun initChannel(ch: SocketChannel) {
val pipeline = ch.pipeline()
val sslHandler = sslHandlerBuilder?.invoke(ch.alloc())
if (sslHandler != null) {
pipeline.addLast(sslHandler)
}
readTimeout?.let {
pipeline.addLast(ReadTimeoutHandler(it))
}
@ -97,22 +119,32 @@ class NettyHttpServer(
.option(ChannelOption.SO_BACKLOG, backlog) // determining the number of connections queued
.option(ChannelOption.SO_REUSEADDR, true)
.childOption(ChannelOption.SO_KEEPALIVE, java.lang.Boolean.TRUE)
private val future: ChannelFuture = b.bind(port)
private var future: ChannelFuture? = null
init {
if (autoRun) run()
}
override fun run() {
if (future != null) return
future = b.bind(port)
log?.warn("NettyHttpServer started on port {}", port)
log?.info("try http://localhost:{}/", port)
future.sync()
log?.info(
"try http{}://localhost:{}/",
if (sslHandlerBuilder == null) "" else "s",
when {
sslHandlerBuilder == null && port == 80 -> ""
sslHandlerBuilder != null && port == 443 -> ""
else -> port
}
)
future!!.sync()
}
override fun close() {
log?.warn("NettyHttpServer({}) closed", port)
future.cancel(false)
future.channel().close()
future?.cancel(false)
future?.channel()?.close()
}
private fun updateHandler(): SimpleChannelInboundHandler<out HttpObject> {