package com.virjar.dungproxy.server.proxyservice.handler; import com.google.common.base.Charsets; import com.virjar.dungproxy.server.proxyservice.client.NettyHttpClient; import com.virjar.dungproxy.server.proxyservice.common.AttributeKeys; import com.virjar.dungproxy.server.proxyservice.common.ProxyResponse; import com.virjar.dungproxy.server.proxyservice.common.util.NetworkUtil; import com.virjar.dungproxy.server.proxyservice.handler.checker.ConnectMethodValidator; import com.virjar.dungproxy.server.proxyservice.handler.checker.RequestValidator; import com.virjar.dungproxy.server.proxyservice.server.ProxySelector; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelPipeline; import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpResponseEncoder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Description: DispatchHandler * * @author lingtong.fu * @version 2016-10-18 16:16 */ @ChannelHandler.Sharable public class DispatchHandler extends ClientProcessHandler { private static final Logger log = LoggerFactory.getLogger(DispatchHandler.class); private ProxySelector proxySelector; private NettyHttpClient nettyHttpClient; public DispatchHandler(ProxySelector proxySelector, NettyHttpClient nettyHttpClient) { this.proxySelector = proxySelector; this.nettyHttpClient = nettyHttpClient; } @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { try { ChannelPipeline pipeline = ctx.pipeline(); NetworkUtil.setAttr(ctx.channel(), AttributeKeys.PROXY_SELECTOR_HOLDER, proxySelector); NetworkUtil.setAttr(ctx.channel(), AttributeKeys.SIMPLE_HTTP_CLIENT, nettyHttpClient); if (msg instanceof FullHttpRequest) { FullHttpRequest request = (FullHttpRequest) msg; if (request.decoderResult().isFailure()) { log.info("[{}] Bad Request [{}] Cause [{}]", ctx.channel(), request.uri(), request.decoderResult().cause().getMessage()); NetworkUtil.resetHandler(pipeline, BadRequestHandler.instance); } else { NetworkUtil.removeHandler(pipeline, HttpResponseEncoder.class); NetworkUtil.addHandlerIfAbsent(pipeline, ConnectMethodValidator.instance); NetworkUtil.addHandlerIfAbsent(pipeline, RequestValidator.instance); } } else { ByteBuf bb = (ByteBuf) msg; log.info("[{}] Bad Request Content:\n {}", ctx.channel(), bb.toString(Charsets.UTF_8)); NetworkUtil.resetHandler(pipeline, BadRequestHandler.instance); } super.channelRead(ctx, msg); } catch (Exception e) { String log; if (msg instanceof FullHttpRequest) { FullHttpRequest request = (FullHttpRequest) msg; log = String.format("Channel 发生异常 [%s] [%s] MTD [%s] URL [%s] Headers [%s]", ctx.channel(), request.protocolVersion().toString(), request.method(), request.uri(), request.headers().entries()); } else { log = String.format("Channel 发生异常 [%s]", ctx.channel()); } NetworkUtil.releaseMsgCompletely(msg); DispatchHandler.log.error(log, e); NetworkUtil.writeAndFlushAndClose(ctx.channel(), ProxyResponse.proxyError(0, e.getClass().getName(), Long.toHexString(ctx.channel().hashCode()))); } } }