1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.example.proxy;
17
18 import io.netty.bootstrap.Bootstrap;
19 import io.netty.buffer.Unpooled;
20 import io.netty.channel.Channel;
21 import io.netty.channel.ChannelFuture;
22 import io.netty.channel.ChannelFutureListener;
23 import io.netty.channel.ChannelHandlerContext;
24 import io.netty.channel.ChannelInboundHandlerAdapter;
25 import io.netty.channel.ChannelOption;
26
27 public class HexDumpProxyFrontendHandler extends ChannelInboundHandlerAdapter {
28
29 private final String remoteHost;
30 private final int remotePort;
31
32
33
34 private Channel outboundChannel;
35
36 public HexDumpProxyFrontendHandler(String remoteHost, int remotePort) {
37 this.remoteHost = remoteHost;
38 this.remotePort = remotePort;
39 }
40
41 @Override
42 public void channelActive(ChannelHandlerContext ctx) {
43 final Channel inboundChannel = ctx.channel();
44
45
46 Bootstrap b = new Bootstrap();
47 b.group(inboundChannel.eventLoop())
48 .channel(ctx.channel().getClass())
49 .handler(new HexDumpProxyBackendHandler(inboundChannel))
50 .option(ChannelOption.AUTO_READ, false);
51 ChannelFuture f = b.connect(remoteHost, remotePort);
52 outboundChannel = f.channel();
53 f.addListener(new ChannelFutureListener() {
54 @Override
55 public void operationComplete(ChannelFuture future) {
56 if (future.isSuccess()) {
57
58 inboundChannel.read();
59 } else {
60
61 inboundChannel.close();
62 }
63 }
64 });
65 }
66
67 @Override
68 public void channelRead(final ChannelHandlerContext ctx, Object msg) {
69 if (outboundChannel.isActive()) {
70 outboundChannel.writeAndFlush(msg).addListener(new ChannelFutureListener() {
71 @Override
72 public void operationComplete(ChannelFuture future) {
73 if (future.isSuccess()) {
74
75 ctx.channel().read();
76 } else {
77 future.channel().close();
78 }
79 }
80 });
81 }
82 }
83
84 @Override
85 public void channelInactive(ChannelHandlerContext ctx) {
86 if (outboundChannel != null) {
87 closeOnFlush(outboundChannel);
88 }
89 }
90
91 @Override
92 public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
93 cause.printStackTrace();
94 closeOnFlush(ctx.channel());
95 }
96
97
98
99
100 static void closeOnFlush(Channel ch) {
101 if (ch.isActive()) {
102 ch.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
103 }
104 }
105 }