Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8285972

HttpClient does not send upgrade headers over h2c when using proxy

XMLWordPrintable

    • generic
    • generic

      ADDITIONAL SYSTEM INFORMATION :
      Windows 10
      Java 17

      A DESCRIPTION OF THE PROBLEM :
      when sending an request using [HttpClient](https://docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/net/http/HttpClient.html) over clear text proxy connection[h2c No TLS] using version [HTTP 2](https://docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/net/http/HttpClient.Version.html#HTTP_2) request gets formated as an normal HTTP 1.1 request with no upgrade headers. Therefore an HTTP 2 Client is expecting response in HTTP 1.1 format for all requests

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1) Create an simple TCP server to simply display the bytes read

      2) Create an HttpClient with proxy

      3) Simply observe the results on the server side and you will see how the request is an protocol error

      In this test case
      Proxy=>runs on port 1000
      Destination=>runs on port 2000

      Output is displayed on the proxy server running on port 1000

      Since this is first request using h2c i expect to see upgrade headers indicating to upgrade the connection first to http2 and then send http 2 frames to the destination server

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      GET http://192.168.1.2:2000/Test.txt HTTP/1.1
      Connection: Upgrade, HTTP2-Settings
      Content-Length: 0
      Host: 192.168.1.2:2000
      HTTP2-Settings: AAEAAEAAAAIAAAABAAMAAABkAAQBAAAAAAUAAEAA
      Upgrade: h2c
      ACTUAL -
      All upgrade headers missing

      GET http://192.168.1.2:2000/Test.txt HTTP/1.1
      Content-Length: 0
      Host: 192.168.1.2:2000
      User-Agent: Java-http-client/17.0.2

      ---------- BEGIN SOURCE ----------
      Create an server to simply print the bytes received and close the connection

      public static void main(String[] args)throws Exception
       {
        try(ServerSocket server=new ServerSocket(1000))
        {
         try(Socket client=server.accept())
         {
          try(InputStream input=client.getInputStream())
          {
           byte[] data=new byte[8196];
           int length=input.read(data);
           System.out.println(new String(data,0,length));
          }
         }
        }
       }

      We dont need to run the server again on port 2000 as the request stops at the proxy running on port 1000

      Create an HttpClient using protocol version 2

       public static void main(String[] args)throws Exception
       {
        HttpClient client=HttpClient.newBuilder()
                                    .proxy(ProxySelector.of(new InetSocketAddress("192.168.1.2",1000)))
                                    .version(HttpClient.Version.HTTP_2)
                                    .build();
        
        HttpRequest request=HttpRequest.newBuilder(URI.create("http://192.168.1.2:2000/Test.txt"))
                                        .build();
        
        HttpResponse response=client.send(request,BodyHandlers.ofString());
        System.out.println("Status code: " + response.statusCode());
        System.out.println("Headers: " + response.headers().map());
        System.out.println("Body: " + response.body());
        
        System.out.println("========");
        
        response=client.send(request,BodyHandlers.ofString());
        System.out.println("Status code: " + response.statusCode());
        System.out.println("Headers: " + response.headers().map());
        System.out.println("Body: " + response.body());
       }

      Simply see the output on the server side
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      No work around available.

      FREQUENCY : always


            michaelm Michael McMahon
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved: