Skip to content

Commit

Permalink
Use Netty AttributeKey instead of mutable remoteChannelOpt
Browse files Browse the repository at this point in the history
  • Loading branch information
alikemalocalan committed Jan 19, 2025
1 parent a957c77 commit 49968ff
Showing 1 changed file with 15 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,14 @@ import io.netty.bootstrap.Bootstrap
import io.netty.buffer.ByteBuf
import io.netty.channel.*
import io.netty.channel.socket.nio.NioSocketChannel
import io.netty.util.AttributeKey
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import java.net.InetSocketAddress
import java.util.*


class ProxyClientHandler : ChannelInboundHandlerAdapter() {
private val logger: Logger = LoggerFactory.getLogger(this::class.java)
private var remoteChannelOpt: Optional<Channel> = Optional.empty()

private val bootstrap: Bootstrap = Bootstrap()
.channel(NioSocketChannel::class.java)
Expand All @@ -26,15 +25,20 @@ class ProxyClientHandler : ChannelInboundHandlerAdapter() {
.option(ChannelOption.SO_KEEPALIVE, true)
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10000)

companion object {
private val REMOTE_CHANNEL_KEY: AttributeKey<Channel> = AttributeKey.valueOf("remoteChannel")
}

override fun channelActive(ctx: ChannelHandlerContext) {
ctx.writeAndFlush(firstHttpsResponse()) // if https,return respond 200
}

override fun channelRead(ctx: ChannelHandlerContext, msg: Any) {
val buf: ByteBuf = msg as ByteBuf
val remoteChannel = ctx.channel().attr(REMOTE_CHANNEL_KEY).get()

if (remoteChannelOpt.isPresent) { // request take second time from the client
HttpServiceUtils.splitAndWriteByteBuf(buf, remoteChannelOpt.get())
if (remoteChannel != null) { // request take second time from the client
HttpServiceUtils.splitAndWriteByteBuf(buf, remoteChannel)
} else // request take first time from the client
HttpServiceUtils.httpRequestFromByteBuf(buf).ifPresent { request ->
val remoteAddressOpt = request.toInetSocketAddress()
Expand All @@ -43,7 +47,8 @@ class ProxyClientHandler : ChannelInboundHandlerAdapter() {
ctx.writeAndFlush(simple200Response()).addListener(ChannelFutureListener.CLOSE)
} else
if (request.isHttps) {
remoteChannelOpt = Optional.of(sendRequestToRemoteChannel(ctx, request, remoteAddressOpt.get()))
val remoteChannel: Channel = sendRequestToRemoteChannel(ctx, request, remoteAddressOpt.get())
ctx.channel().attr(REMOTE_CHANNEL_KEY).set(remoteChannel)
} else { //if http,force to https without any remote connection
val response = HttpServiceUtils.redirectHttpToHttps(request.host())
ctx.writeAndFlush(response)
Expand All @@ -69,19 +74,19 @@ class ProxyClientHandler : ChannelInboundHandlerAdapter() {
}

override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) {
remoteChannelOpt.ifPresent { remoteChannel ->
val remoteChannel = ctx.channel().attr(REMOTE_CHANNEL_KEY).get()
if (remoteChannel != null) {
logger.error("Proxy Client Connection lost for: ${remoteChannel.remoteAddress()} , error: ${cause.localizedMessage}")
remoteChannel.close()
}
if (remoteChannelOpt.isEmpty) {
} else {
logger.error("Proxy Client Connection lost: remote channel not present , error: ${cause.localizedMessage}")
}
ctx.close()
}

override fun channelInactive(ctx: ChannelHandlerContext?) {
if (remoteChannelOpt.isPresent)
remoteChannelOpt.get().close()
val remoteChannel = ctx?.channel()?.attr(REMOTE_CHANNEL_KEY)?.get()
remoteChannel?.close()
}

}

0 comments on commit 49968ff

Please sign in to comment.