title: Java HttpClient with TLS/SSLContext through proxy
body: <p>I want to make a HTTP call to server that uses TLS to authenticate. Moreover server needs my IP to be whitelisted, so with AWS Lambda I need to use proxy. What I want to achieve is HTTP POST request with TLS that goes through proxy.</p>
  <p>To achieve TLS protocol I use <code>KeyStore</code> with loaded certs and private key.
  Making a call without proxy (locally from whitelisted IP) works, so I assume <code>keyStore</code> is configured correctly.</p>
  <p>Here is how I build <code>httpClient</code> (it's <code>java.net.http.HttpClient</code>):</p>
  <pre><code>var keyManagerFactory = KeyManagerFactory.getInstance(&quot;PKIX&quot;);
  keyManagerFactory.init(keyStore, null);
  
  var trustManagerFactory = TrustManagerFactory.getInstance(&quot;PKIX&quot;);
  trustManagerFactory.init(keyStore, null);
  
  SSLContext sslContext = SSLContext.getInstance(&quot;TLS&quot;);
  sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);
  
  URI proxyUri = config.getProxyUri(); // this is injected object with preloaded config parameters
  
  HttpClient httpClient = HttpClient.newBuilder()
      .sslContext(sslContext)
      .proxy(
        ProxySelector.of(
          InetSocketAddress.createUnresolved(proxyUri.getHost(), proxyUri.getPort())))
      .build();
  </code></pre>
  <p>Now making a request:</p>
  <pre><code>String body = createRequestBody(); // creates string with JSON
  
  HttpRequest request = HttpRequest.newBuilder()
      .uri(config.getServiceUri()) // same config as in example above
      .header(&quot;Content-Type&quot;, &quot;application/json&quot;)
      .POST(BodyPublishers.ofString(body))
      .build();
  
  HttpResponse&lt;String&gt; response = httpClient.send(request, BodyHandlers.ofString());
  </code></pre>
  <p>Calling <code>.send(...)</code> causes</p>
  <pre><code>java.io.IOException: Tunnel failed, got: 403
  # java.net.http/jdk.internal.net.http.HttpClientImpl.send(Unknown Source)
  # java.net.http/jdk.internal.net.http.HttpClientFacade.send(Unknown Source)
  # (method we are in above example)
  </code></pre>
  <p>Proxy doesn't need any authentication and in other AWS Lambda I've seen this proxy working with builder using only <code>.proxy(...)</code> method just like in the example above. So the only thing that is different is this <code>.sslContext(...)</code>.</p>
  <p>Do I need some more <code>sslContext</code> configuration? I've been searching for some examples with TLS through proxy, but I've not managed to find anything.
  <a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/net/http/HttpClient.Builder.html" rel="nofollow noreferrer">HttpClient.Builder Docs</a> doesn't say anything about proxy with sslContext either.</p>
  <p>Thanks for help!</p>