Hi,

I am recently working on a challenging problem related to  socks proxy.
Basically, I am given a server, which can act as a socks proxy through ssh.
Specifically, if you establish a port forwarding via command:
```
ssh -N -p 22 <remote_host> -D 1080
```
then you can use `localhost:1080` as a socks proxy. For example, the
following command will work:
```
curl -v -x socks5h://localhost:1080 http://www.wikipedia.org/  -I
```

The challenge to me is how I can achieve such proxy handling via Mina. I
tried to follow example code in
https://github.com/apache/mina/blob/2.0/mina-example/src/test/java/org/apache/mina/example/proxy/ProxyTestClient.java.
However, I can't make it work. In fact, now I tend to think that example is
not exactly applicable to my case as it doesn't address the `ssh -D` port
forwarding.

So, can anyone share some pointers how to solve this problem? Greatly
appreciate it.

P.S., for what it's worth, I am pasting my sample code here:
```
    private static final Logger log =
LoggerFactory.getLogger(MinaSocksProxyTest.class);

    @Test
    public void test() throws InterruptedException {
        NioSocketConnector socketConnector = new NioSocketConnector();
        ProxyConnector connector = new ProxyConnector(socketConnector);

        // Set connect timeout.
        connector.setConnectTimeoutMillis(60000);

        InetSocketAddress proxyAddr = new
InetSocketAddress("remote.proxy.server", 22);
        String user = "username";
        String password = "password";
        SocksProxyRequest proxyRequest = new SocksProxyRequest(
                SocksProxyConstants.SOCKS_VERSION_4,
                SocksProxyConstants.ESTABLISH_TCPIP_STREAM,
                proxyAddr, user);
        proxyRequest.setPassword( password );

        ProxyIoSession proxyIoSession = new ProxyIoSession( proxyAddr,
proxyRequest);

        connector.setProxyIoSession(proxyIoSession);

        connector.getFilterChain().addLast("logger", new LoggingFilter());
        connector.getFilterChain().addLast("http-codec", new
HttpClientCodec());

        connector.setHandler(new DummyHandler());

        String host = "www.wikipedia.org";

        ConnectFuture future = connector.connect(new InetSocketAddress(
host, 80));
        future.awaitUninterruptibly();

        IoSession session = future.getSession();

        Map<String, String> headers = new HashMap<>();
        headers.put("Accept", "*/*");
        headers.put("Connection", "keep-alive");
        headers.put("Host",  host);
        headers.put("User-Agent", "CT workflow agent");

        HttpRequest req = new HttpRequestImpl(HttpVersion.HTTP_1_1,
HttpMethod.GET, "/", "", headers);

        log.info("sending request: " + req);
        session.write(req);
        Thread.sleep(3000);
    }

    class DummyHandler extends AbstractProxyIoHandler {
        @Override
        public void messageReceived(IoSession session, Object message)
throws Exception {
            if (message instanceof HttpResponse) {
                log.info("check class:" + message.getClass().getName());
                DefaultHttpResponse response = (DefaultHttpResponse)
message;
                log.info(response.toString());
                log.info("status code: " + response.getStatus().code());
            }
        }


        @Override
        public void sessionCreated(IoSession session) throws Exception {
            log.debug("CLIENT - Session created: " + session);
        }

        @Override
        public void proxySessionOpened(IoSession session) throws Exception {
            log.debug("CLIENT - Session opened: " + session);
            ProxyIoSession proxyIoSession = (ProxyIoSession) session
                    .getAttribute(ProxyIoSession.PROXY_SESSION);
            if (proxyIoSession != null) {
                ProxyRequest req = proxyIoSession.getRequest();

                byte[] c = null;
                if (req instanceof SocksProxyRequest ) {
                    log.debug("Sending request to a SOCKS SESSION ...");
                } else if (req instanceof HttpProxyRequest
                        && ((HttpProxyRequest) req).getHttpVerb() ==
HttpProxyConstants.CONNECT) {
                    log.debug("Sending request to a HTTP CONNECTED SESSION
...");
                    c = (((HttpProxyRequest) req).toHttpString())
                            .getBytes(proxyIoSession.getCharsetName());
                }

                if (c != null) {
                    IoBuffer buf = IoBuffer.allocate(c.length);
                    buf.put(c);
                    buf.flip();
                }
            }
        }

        @Override
        public void exceptionCaught(IoSession session, Throwable cause) {
            log.debug("CLIENT - Exception caught");
            session.close(true);
        }
    }
```

Reply via email to