Here is my complete workable Java code that supports HTTP and HTTPS requests using SOCKS proxy with synchronous HttpClient.
import java.io.IOException; import java.net.InetSocketAddress; import java.net.Proxy; import java.net.Socket; import java.nio.charset.StandardCharsets; import org.apache.http.HttpHost; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.config.Registry; import org.apache.http.config.RegistryBuilder; import org.apache.http.conn.socket.ConnectionSocketFactory; import org.apache.http.conn.socket.PlainConnectionSocketFactory; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.protocol.HttpContext; import org.apache.http.ssl.SSLContexts; import org.apache.http.util.EntityUtils; import javax.net.ssl.SSLContext; /** * How to send a HTTP or HTTPS request via SOCKS proxy. */ public class HttpClientWithSocksProxy { public static void main(String[] args) throws Exception { Registry<ConnectionSocketFactory> reg = RegistryBuilder.<ConnectionSocketFactory>create() .register("http", new MyHTTPConnectionSocketFactory()) .register("https", new MyHTTPSConnectionSocketFactory(SSLContexts.createSystemDefault ())) .build(); PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(reg); try (CloseableHttpClient httpclient = HttpClients.custom() .setConnectionManager(cm) .build()) { InetSocketAddress socksaddr = new InetSocketAddress("mysockshost", 1234); HttpClientContext context = HttpClientContext.create(); context.setAttribute("socks.address", socksaddr); HttpHost target = new HttpHost("www.example.com/", 80, "http"); HttpGet request = new HttpGet("/"); System.out.println("Executing request " + request + " to " + target + " via SOCKS " + "proxy " + socksaddr); try (CloseableHttpResponse response = httpclient.execute(target, request, context)) { System.out.println("----------------------------------------"); System.out.println(response.getStatusLine()); System.out.println(EntityUtils.toString(response.getEntity(), StandardCharsets .UTF_8)); } } } static class MyHTTPConnectionSocketFactory extends PlainConnectionSocketFactory { @Override public Socket createSocket(final HttpContext context) throws IOException { InetSocketAddress socksaddr = (InetSocketAddress) context.getAttribute("socks.address"); Proxy proxy = new Proxy(Proxy.Type.SOCKS, socksaddr); return new Socket(proxy); } } static class MyHTTPSConnectionSocketFactory extends SSLConnectionSocketFactory { public MyHTTPSConnectionSocketFactory(final SSLContext sslContext) { super(sslContext); } @Override public Socket createSocket(final HttpContext context) throws IOException { InetSocketAddress socksaddr = (InetSocketAddress) context.getAttribute("socks.address"); Proxy proxy = new Proxy(Proxy.Type.SOCKS, socksaddr); return new Socket(proxy); } } } When it comes to HttpAsyncClient, how can I use socks proxy with HttpAsyncClient? Here is my incomplete Java code which is not workable yet: import java.io.IOException; import java.net.InetSocketAddress; import java.net.Proxy; import java.net.Socket; import java.nio.charset.StandardCharsets; import java.util.concurrent.CountDownLatch; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.concurrent.FutureCallback; import org.apache.http.config.Registry; import org.apache.http.config.RegistryBuilder; import org.apache.http.conn.socket.ConnectionSocketFactory; import org.apache.http.conn.socket.PlainConnectionSocketFactory; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.impl.nio.client.CloseableHttpAsyncClient; import org.apache.http.impl.nio.client.HttpAsyncClients; import org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager; import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor; import org.apache.http.protocol.HttpContext; import org.apache.http.ssl.SSLContexts; import org.apache.http.util.EntityUtils; import javax.net.ssl.SSLContext; public class HttpAsyncClientWithSocksProxy { public static void main(String[] args) throws Exception { Registry<ConnectionSocketFactory> reg = RegistryBuilder.<ConnectionSocketFactory>create() .register("http", new MyHTTPConnectionSocketFactory()) .register("https", new MyHTTPSConnectionSocketFactory( SSLContexts.createSystemDefault())) .build(); PoolingNHttpClientConnectionManager cm = new PoolingNHttpClientConnectionManager( new DefaultConnectingIOReactor()); try (CloseableHttpAsyncClient httpclient = HttpAsyncClients.custom() .setConnectionManager(cm) .build()) { InetSocketAddress socksaddr = new InetSocketAddress("mysockshost", 1234); HttpClientContext context = HttpClientContext.create(); context.setAttribute("socks.address", socksaddr); HttpGet request = new HttpGet("http://www.example.com/"); System.out.println("Executing request " + request + " via SOCKS " + "proxy " + socksaddr); final CountDownLatch latch = new CountDownLatch(1); httpclient.execute(request, new FutureCallback<HttpResponse>() { public void completed(final HttpResponse response) { latch.countDown(); System.out.println(request.getRequestLine() + "->" + response.getStatusLine()); try { System.out.println(EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8)); } catch (IOException e) { e.printStackTrace(); } } public void failed(final Exception ex) { latch.countDown(); System.out.println(request.getRequestLine() + "->" + ex); } public void cancelled() { latch.countDown(); System.out.println(request.getRequestLine() + " cancelled"); } }); latch.wait(); } } static class MyHTTPConnectionSocketFactory extends PlainConnectionSocketFactory { @Override public Socket createSocket(final HttpContext context) throws IOException { InetSocketAddress socksaddr = (InetSocketAddress) context.getAttribute("socks.address"); Proxy proxy = new Proxy(Proxy.Type.SOCKS, socksaddr); return new Socket(proxy); } } static class MyHTTPSConnectionSocketFactory extends SSLConnectionSocketFactory { public MyHTTPSConnectionSocketFactory(final SSLContext sslContext) { super(sslContext); } @Override public Socket createSocket(final HttpContext context) throws IOException { InetSocketAddress socksaddr = (InetSocketAddress) context.getAttribute("socks.address"); Proxy proxy = new Proxy(Proxy.Type.SOCKS, socksaddr); return new Socket(proxy); } } } Any ideas? Thanks in advance! -- My tech blog: http://www.soulmachine.me My GitHub: https://github.com/soulmachine My LinkedIn: http://www.linkedin.com/in/soulmachine/ My Sina Weibo: http://weibo.com/soulmachine