Uploaded image for project: 'HttpComponents HttpClient'
  1. HttpComponents HttpClient
  2. HTTPCLIENT-2120

Support HTTP/2 (TLS) Tunneling over HTTP-Proxy

    XMLWordPrintableJSON

Details

    Description

      First of all:

      • Are there plans for supporting HTTP/2 (with TLS) connections via corporate HTTP-proxies?
        • If yes: is there a schedule?
      • Could you please add documentation to "https://hc.apache.org" that makes it clear that the HTTP/2 implementation does currently not support HTTP-proxies?
        • This alone could save people hours of programming something that has no chance to work and debugging afterwards
        • The only clear statement I found regarding that topic was at a migration guide ("https://ok2c.github.io/httpclient-migration-guide/migration-to-async-http2.html")

      Observations while trying to establish a HTTP/2 connection via proxy:

      The observations can be made using the following minimal example with [proxy_ip]:[proxy_port] replaced with host and port of an actual HTTP-Proxy:

      CloseableHttpAsyncClient client = HttpAsyncClients.custom()
          .setVersionPolicy(HttpVersionPolicy.FORCE_HTTP_2)
          .setProxy(HttpHost.create("[proxy_ip]:[proxy_port]")).build();
      client.start();
      // throws org.apache.hc.core5.http.ConnectionClosedException
      client.execute(SimpleHttpRequests.get("https://http2.pro/client"), null).get();
      

      The above code throws the following Exception:

      Exception in thread "main" java.util.concurrent.ExecutionException: org.apache.hc.core5.http.ConnectionClosedException: Connection is closed
      	at org.apache.hc.core5.concurrent.BasicFuture.getResult(BasicFuture.java:72)
      	at org.apache.hc.core5.concurrent.BasicFuture.get(BasicFuture.java:85)
      	at com.test.MinimalProxyTest.basicTest(MinimalProxyTest.java:41)
      	at com.test.MinimalProxyTest.main(MinimalProxyTest.java:23)
      Caused by: org.apache.hc.core5.http.ConnectionClosedException: Connection is closed
      	at org.apache.hc.core5.http2.impl.nio.AbstractH2StreamMultiplexer.onException(AbstractH2StreamMultiplexer.java:661)
      	at org.apache.hc.core5.http2.impl.nio.AbstractH2IOEventHandler.exception(AbstractH2IOEventHandler.java:91)
      	at org.apache.hc.core5.http2.impl.nio.ClientH2IOEventHandler.exception(ClientH2IOEventHandler.java:39)
      	at org.apache.hc.core5.reactor.InternalDataChannel.onException(InternalDataChannel.java:162)
      	at org.apache.hc.core5.reactor.InternalChannel.handleIOEvent(InternalChannel.java:55)
      	at org.apache.hc.core5.reactor.SingleCoreIOReactor.processEvents(SingleCoreIOReactor.java:179)
      	at org.apache.hc.core5.reactor.SingleCoreIOReactor.doExecute(SingleCoreIOReactor.java:128)
      	at org.apache.hc.core5.reactor.AbstractSingleCoreIOReactor.execute(AbstractSingleCoreIOReactor.java:85)
      	at org.apache.hc.core5.reactor.IOReactorWorker.run(IOReactorWorker.java:44)
      	at java.base/java.lang.Thread.run(Thread.java:832)
      
      • There is no exception thrown that makes clear that this constellation (HTTP/2 + Proxy) is not supported
        • Even though I found org.apache.hc.client5.http.impl.async.InternalHttpAsyncClient.determineRoute(HttpHost, HttpClientContext) with throw new HttpException("HTTP/2 tunneling not supported") which is not triggered because HttpClientContext.getProtocolVersion() returns HTTP-1.1
      • Looking at the Logs I see that the HTTP/2 request was tried to be performed unencrypted and the Proxy sends HTTP/1.0 400 Bad Request and closes the connection
      • Also in the logs I can see Code FRAME_SIZE_ERROR and Frame size exceeds maximum which might be caused by trying to consume the HTTP-1.1 proxy response as HTTP/2
        • The associated Exception (H2ConnectionException: Frame size exceeds maximum) is omitted in org.apache.hc.core5.http2.impl.nio.AbstractH2StreamMultiplexer.onException(Exception) where ((ExecutableCommand) command).failed(new ConnectionClosedException()) is called

      What can be done?

      If I wanted to support you in implementing the HTTP/2 via proxy support where would I have to start?

      • When I understand the situation right then we are almost there and the only problem is that the HTTP/2 request is tried to be performed without encryption

      Attachments

        1. hc5_session.log
          11 kB
          synth3

        Activity

          People

            Unassigned Unassigned
            synth3 synth3
            Votes:
            1 Vote for this issue
            Watchers:
            6 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: