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