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); } } ```
