Description of problem: RFC 7321#4.3.6 states that: A client sending a CONNECT request MUST send the authority form of request-target (Section 5.3 of [RFC7230]); i.e., the request-target consists of only the host name and port number of the tunnel destination, separated by a colon. For example, CONNECT server.example.com:80 HTTP/1.1 Host: server.example.com:80 The HttpURLConnection API in OpenJDK 8 implements CONNECT support as: /** * send a CONNECT request for establishing a tunnel to proxy server */ private void sendCONNECTRequest() throws IOException { int port = url.getPort(); requests.set(0, HTTP_CONNECT + " " + connectRequestURI(url) + " " + httpVersion, null); requests.setIfNotSet("User-Agent", userAgent); String host = url.getHost(); if (port != -1 && port != url.getDefaultPort()) { host += ":" + String.valueOf(port); } requests.setIfNotSet("Host", host); The logic for deciding when to append ":" and the port number will not append them when it is the default port for the given protocol (80 for http, 443 for https), and thus will generate requests in these formats: CONNECT example.com:443 HTTP/1.1 User-Agent: Java/1.8.0_232 Host: example.com CONNECT example.com:80 HTTP/1.1 User-Agent: Java/1.8.0_232 Host: example.com Note that neither of these request includes the port number in the Host header per the RFC example, causing the the request-target and host header to not match. Starting in version 2.2, HAproxy implemented strict RFC compliance checking that will reject these requests with BADREQ: https://github.com/haproxy/haproxy/commit/531b83e039bbe369e4fe6e775e9bfa310d780da1 The only current work-around for this non-compliant behavior by Java is to use the "accept-invalid-http-request" option, which is sub-optimal. Version-Release number of selected component (if applicable): Tested under 1.8.0.232.b09-0.el7_7, but this issue exists in all current OpenJDK releases How reproducible: 100% Steps to Reproduce: 1. Setup a HAproxy 2.4 http frontend that will accept CONNECT requests 2. Use HttpURLConnection to generate a CONNECT request 3. Observe the rejection of the CONNECT request by HAproxy Actual results: A <BADREQ> is logged by HAproxy due to the mismatch between the authority and the Host header in the request generated by Java: 127.0.0.1:35039 127.0.0.1:80 [28/Dec/2021:04:19:12 +0000] tcp-80 tcp-80/<NOSRV> -1/-1/-1/-1/0 400 0 - - PR-- 1/1/0/0/0 0/0 "<BADREQ>" and the CONNECT request is rejected by HAproxy with a 400 error: HTTP/1.1 400 Bad request Content-length: 90 Cache-Control: no-cache Connection: close Content-Type: text/html <html><body><h1>400 Bad request</h1> Your browser sent an invalid request. </body></html> Expected results: A properly formatted RFC compliant CONNECT request being generated by Java that can be serviced by HAproxy without requiring enabling the "accept-invalid-http-request" option. Additional info: RFC compliant behavior should be able to be achieved by removing the port logic and simplifying the sendCONNECTRequest() method: /** * send a CONNECT request for establishing a tunnel to proxy server */ private void sendCONNECTRequest() throws IOException { requests.set(0, HTTP_CONNECT + " " + connectRequestURI(url) + " " + httpVersion, null); requests.setIfNotSet("User-Agent", userAgent); requests.setIfNotSet("Host", connectRequestURI(url)); Unfortunately there is not a good public conduit to report Java bugs directly to the OpenJDK project for resolution, so hopefully Red Hat can help facilitate this, as this issue has not been fixed in any newer JDK version either, making this a generic JDK issue across multiple supported JDK long-term releases and RHEL versions. JDK 11: https://github.com/openjdk/jdk11/blob/37115c8ea4aff13a8148ee2b8832b20888a5d880/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java#L2197 JDK 17: https://github.com/openjdk/jdk17u/blob/master/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java#L2301
After evaluating this issue, there are no plans to address it further or fix it in an upcoming release. Therefore, it is being closed. If plans change such that this issue will be fixed in an upcoming release, then the bug can be reopened.