Search code examples
javahttpsproxyjava-http-client

Can the core Java HttpClient proxy through a TLS Proxy?


I am trying to setup a HttpClient to proxy requests through a HTTPS authenticated proxy.

It seems the Java HttpClient can only proxy over http and therefore the proxy credentials are sent in plaintext to the proxy.

I have opened the proxy on port 8443 to accept http and this works fine:

System.setProperty("jdk.http.auth.tunneling.disabledSchemes", "");
String user = "username";
String password = "password";

Authenticator authenticator = new ProxyAuthenticator(user, password);
Authenticator.setDefault(authenticator);

HttpClient httpClient = HttpClient.newBuilder()
    .sslContext(getSSLContextTrustAny())
    .version(HttpClient.Version.HTTP_1_1)
    .proxy(ProxySelector.of(new InetSocketAddress("my.proxy", 8443)))
    .authenticator(Authenticator.getDefault())
    .build();

String uri = "https://ensc1aqsjv0asda.x.pipedream.net/";
String msg = "test-msg";

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create(uri))
    .POST(HttpRequest.BodyPublishers.ofString(msg))
    .build();

HttpResponse<?> response = httpClient.send(request, HttpResponse.BodyHandlers.discarding());

System.out.println(response);
System.out.println(response.headers());

(Note: getSSLContextTrustAny() returns an SSLContext that trusts any cert as the proxy is using a self signed CA)

However, when I set the port to 443 (which is open), the request just times out. I suspect the client is trying to proxy to http://my.proxy:443 instead of over TLS to https://my.proxy:443

Is it possible to make the client use https for proxying?


Solution

  • No - this is not supported. It is possible to tunnel an HTTPS connection to a server through a clear connection to a proxy, but it is not possible to proxy a clear HTTP connection to a server through an encrypted connection to a proxy.