4

I'd like to use the JDK 11 HttpClient to perform a request through an HTTPS proxy. I've tried this code to create the client:

HttpClient client = HttpClient
    .newBuilder()
    .proxy(ProxySelector.of(new InetSocketAddress("my.proxy.host",8443)))
    .version(Version.HTTP_1_1)
    .build();

and this code to generate the request:

String auth = new String(Base64.getEncoder().encode("username:password".getBytes()));
var request =
HttpRequest
    .newBuilder(new URI("http://my.internal.host/path"))
    .POST(BodyPublishers.ofString("{\"foo\":\"bar\"}"))
    .header("Proxy-Authorization", "Basic " + auth)
    .header("Content-Type", "application/json")
    .build();

But it fails with java.io.IOException: HTTP/1.1 header parser received no bytes.

The equivalent curl I'd like to perform would be:

curl -XPOST --proxy 'https://username:password@http://my.proxy.host:8443/path' \
  -d '{"foo":"bar"}' \
  -h 'Content-Type: application/json' \
  http://my.internal.host/path

And that works. Any suggestions?

Naman
  • 27,789
  • 26
  • 218
  • 353
Yonatan
  • 2,543
  • 2
  • 19
  • 20
  • Basic authentication with proxy is disabled by default - see [https://stackoverflow.com/questions/53333556/proxy-authentication-with-jdk-11-httpclient](https://stackoverflow.com/questions/53333556/proxy-authentication-with-jdk-11-httpclient) – daniel Sep 03 '20 at 10:31
  • @daniel the problem is not with the authentication - I'm not getting to the proxy at all, because it uses http and not https to use it. If it was an authentication issue, I'd get a 403 error, and not "header parser received no bytes". – Yonatan Sep 03 '20 at 16:04
  • The `HttpClient` doesn't use SSL when connecting to the proxy. – daniel Sep 04 '20 at 11:09
  • I am not 100% sure whether that's what you are trying to do. If that's not the problem then I might suggest trying with JDK 14 or with an early access build of JDK 15. – daniel Sep 04 '20 at 11:17
  • We have an http proxy over https, but the connection itself is http. You can see it in the curl example - `curl -XPOST --proxy 'https://username:password@http://my.proxy.host:8443/path' -d '{"foo":"bar"}' -h 'Content-Type: application/json' http://my.internal.host/path` - I'm trying to access to http://my.internal.host though https://my.proxy.host:8443 . In nodejs, for instance, this is a trivial task (you just need to provide the https schema with the proxy host). – Yonatan Sep 04 '20 at 18:50
  • 1
    This was not supported by the old `HttpURLConnection` andis not supported by the new `java.net.HttpClient` either. – daniel Sep 07 '20 at 13:14
  • Are you sure that that curl command did a successful HTTP request using the proxy? Or did it also result in an error? – Devabc Nov 17 '21 at 19:24
  • This was possible to achieve with the old HttpURLConnection by providing a custom sslsocketfactory. Unfortunately the new HttpClient doesn't provide a way to specify this, the option exists to provide the SSLContext, from which it calls the getSocketFactory() method. I've not yet found a way to achieve overriding the socket factory it uses as SSLContext can't superclasses, it's all final. See https://github.com/alanwhite/tpclient for working code for the old client. – Hamish258 Jan 15 '23 at 21:11

0 Answers0