亚洲欧美日韩综合系列在线_91精品人妻一区二区_欧美大肥婆一级特大AA片_九色91视频免费观看_亚洲综合国产精品_av中文字幕在线不卡_久久精品色综合网_看黄色视频的软件_无卡无码高清中文字幕码2024_亚洲欧美日韩天堂网

java通過netty實現(xiàn)代理服務器

來源: libraryhu 發(fā)布時間:2018-11-21 15:52:32 閱讀量:1222

思路

netty有內置的http編解碼器,那就可以輕易做到不只是轉發(fā)原始數(shù)據(jù),而是可以修改響應內容,當然僅限http代理,因為https代理的話私鑰都存在客戶端和目標服務器上,代理服務器只能捕獲到雙方的公鑰,無法解密成明文,除非代理服務器制作證書,并實現(xiàn)SSL/TLS握手。

image.png

實現(xiàn)

EventLoopGroup bossGroup = new NioEventLoopGroup();EventLoopGroup workerGroup = new NioEventLoopGroup(2);try {ServerBootstrap b = new ServerBootstrap();b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).option(ChannelOption.SO_BACKLOG, 100).option(ChannelOption.TCP_NODELAY, true).handler(new LoggingHandler(LogLevel.INFO)).childHandler(new ChannelInitializer<Channel>() {@Overrideprotected void initChannel(Channel ch) throws Exception {ch.pipeline().addLast("httpCodec",new HttpServerCodec());ch.pipeline().addLast("httpObject",new HttpObjectAggregator(65536));ch.pipeline().addLast("serverHandle",new HttpProxyServerHandle());}});ChannelFuture f = b.bind(port).sync();f.channel().closeFuture().sync();} catch (Exception e) {e.printStackTrace();} finally {bossGroup.shutdownGracefully();workerGroup.shutdownGracefully();}

public class HttpProxyServerHandle extends ChannelInboundHandlerAdapter {private ChannelFuture cf;private String host;private int port;@Overridepublic void channelRead(final ChannelHandlerContext ctx, final Object msg) throws Exception {if (msg instanceof FullHttpRequest) {FullHttpRequest request = (FullHttpRequest) msg;String host = request.headers().get("host");String[] temp = host.split(":");int port = 80;if (temp.length > 1) {port = Integer.parseInt(temp[1]);} else {if (request.uri().indexOf("https") == 0) {port = 443;}}this.host = temp[0];this.port = port;if ("CONNECT".equalsIgnoreCase(request.method().name())) {//HTTPS建立代理握手HttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, NettyHttpProxyServer.SUCCESS);ctx.writeAndFlush(response);ctx.pipeline().remove("httpCodec");ctx.pipeline().remove("httpObject");return;}//連接至目標服務器Bootstrap bootstrap = new Bootstrap();bootstrap.group(ctx.channel().eventLoop()) // 注冊線程池.channel(ctx.channel().getClass()) // 使用NioSocketChannel來作為連接用的channel類.handler(new HttpProxyInitializer(ctx.channel()));ChannelFuture cf = bootstrap.connect(temp[0], port);cf.addListener(new ChannelFutureListener() {public void operationComplete(ChannelFuture future) throws Exception {if (future.isSuccess()) {future.channel().writeAndFlush(msg);} else {ctx.channel().close();}}});//            ChannelFuture cf = bootstrap.connect(temp[0], port).sync();//            cf.channel().writeAndFlush(request);} else { // https 只轉發(fā)數(shù)據(jù),不做處理if (cf == null) {//連接至目標服務器Bootstrap bootstrap = new Bootstrap();bootstrap.group(ctx.channel().eventLoop()) // 復用客戶端連接線程池.channel(ctx.channel().getClass()) // 使用NioSocketChannel來作為連接用的channel類.handler(new ChannelInitializer() {@Overrideprotected void initChannel(Channel ch) throws Exception {ch.pipeline().addLast(new ChannelInboundHandlerAdapter() {@Overridepublic void channelRead(ChannelHandlerContext ctx0, Object msg) throws Exception {ctx.channel().writeAndFlush(msg);}});}});cf = bootstrap.connect(host, port);cf.addListener(new ChannelFutureListener() {public void operationComplete(ChannelFuture future) throws Exception {if (future.isSuccess()) {future.channel().writeAndFlush(msg);} else {ctx.channel().close();}}});} else {cf.channel().writeAndFlush(msg);}}}}
public class HttpProxyInitializer extends ChannelInitializer{private Channel clientChannel;public HttpProxyInitializer(Channel clientChannel) {this.clientChannel = clientChannel;}@Overrideprotected void initChannel(Channel ch) throws Exception {ch.pipeline().addLast(new HttpClientCodec());ch.pipeline().addLast(new HttpObjectAggregator(6553600));ch.pipeline().addLast(new HttpProxyClientHandle(clientChannel));}}

public class HttpProxyClientHandle extends ChannelInboundHandlerAdapter {private Channel clientChannel;public HttpProxyClientHandle(Channel clientChannel) {this.clientChannel = clientChannel;}@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {FullHttpResponse response = (FullHttpResponse) msg;//修改http響應體返回至客戶端response.headers().add("test","from proxy");clientChannel.writeAndFlush(msg);}}


    標簽: 服務器搭建
    分享:
    評論:
    你還沒有登錄,請先