-
Bug
-
Resolution: Won't Fix
-
P4
-
None
-
11, 17, 18, 19
-
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
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