Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to use Socks4/5 Proxy Handlers in Netty Client (4.1)

I need to configure socks proxy in Netty client (to request different sites via socks4 or 5 proxies). Tried a lot of proxies from free socks lists (like www.socks-proxy.net, http://sockslist.net/ etc) but with no luck:

@Test
public void testProxy() throws Exception {
    final String ua = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36";
    final String host = "www.main.de";
    final int port = 80;

    Bootstrap b = new Bootstrap();
    b.group(new NioEventLoopGroup())
            .channel(NioSocketChannel.class)
            .handler(new ChannelInitializer<SocketChannel>() {
                @Override
                protected void initChannel(SocketChannel ch) throws Exception {
                    ChannelPipeline p = ch.pipeline();

                    p.addLast(new HttpClientCodec());
                    p.addLast(new HttpContentDecompressor());
                    p.addLast(new HttpObjectAggregator(10_485_760));
                    p.addLast(new ChannelInboundHandlerAdapter() {
                        @Override
                        public void channelActive(final ChannelHandlerContext ctx) throws Exception {
                            HttpRequest request = new DefaultFullHttpRequest(HTTP_1_1, GET, "/");
                            request.headers().set(HOST, host + ":" + port);
                            request.headers().set(USER_AGENT, ua);
                            request.headers().set(CONNECTION, CLOSE);

                            ctx.writeAndFlush(request);

                            System.out.println("!sent");
                        }

                        @Override
                        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
                            System.out.println("!answer");
                            if (msg instanceof FullHttpResponse) {
                                FullHttpResponse httpResp = (FullHttpResponse) msg;


                                ByteBuf content = httpResp.content();
                                String strContent = content.toString(UTF_8);
                                System.out.println("body: " + strContent);

                                finish.countDown();
                                return;
                            }

                            super.channelRead(ctx, msg);
                        }

                        @Override
                        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
                            cause.printStackTrace(System.err);
                            ctx.close();
                            finish.countDown();
                        }
                    });

                    p.addLast(new Socks4ProxyHandler(new InetSocketAddress("149.202.68.167", 37678)));
                }
            });

    b.connect(host, port).awaitUninterruptibly();
    System.out.println("!connected");

    finish.await(1, MINUTES);
}

The connection hangs, resets or getting some strange exceptions. What's wrong? Proxy support added to Netty since 4.1 (now there is a 4.1CR, tried it and 4.1b7-8 before)

like image 325
yetanothercoder Avatar asked Jan 31 '16 20:01

yetanothercoder


1 Answers

The proxy instance should be the first in the pipeline, as you want it to handle the connection to the proxy first, before any http contents are handled.

To change this, change p.addLast(new Socks4ProxyHandler(new InetSocketAddress("149.202.68.167", 37678))); to:

p.addFirst(new Socks4ProxyHandler(new InetSocketAddress("149.202.68.167", 37678)));

As explained in the documentation for ChannelPipeline, the flow of the data is starting at the first handler, and ending at the last handler.

like image 126
Ferrybig Avatar answered Nov 07 '22 21:11

Ferrybig