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(future -> {
54 if (future.isSuccess()) {
55
56 inboundChannel.read();
57 } else {
58
59 inboundChannel.close();
60 }
61 });
62 }
63
64 @Override
65 public void channelRead(final ChannelHandlerContext ctx, Object msg) {
66 if (outboundChannel.isActive()) {
67 outboundChannel.writeAndFlush(msg).addListener(future -> {
68 if (future.isSuccess()) {
69
70 ctx.read();
71 } else {
72 ctx.close();
73 }
74 });
75 }
76 }
77
78 @Override
79 public void channelInactive(ChannelHandlerContext ctx) {
80 if (outboundChannel != null) {
81 closeOnFlush(outboundChannel);
82 }
83 }
84
85 @Override
86 public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
87 cause.printStackTrace();
88 closeOnFlush(ctx.channel());
89 }
90
91
92
93
94 static void closeOnFlush(Channel ch) {
95 if (ch.isActive()) {
96 ch.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
97 }
98 }
99 }