Note: This bug is displayed in read-only format because
the product is no longer active in Red Hat Bugzilla.
RHEL Engineering is moving the tracking of its product development work on RHEL 6 through RHEL 9 to Red Hat Jira (issues.redhat.com). If you're a Red Hat customer, please continue to file support cases via the Red Hat customer portal. If you're not, please head to the "RHEL project" in Red Hat Jira and file new tickets here. Individual Bugzilla bugs in the statuses "NEW", "ASSIGNED", and "POST" are being migrated throughout September 2023. Bugs of Red Hat partners with an assigned Engineering Partner Manager (EPM) are migrated in late September as per pre-agreed dates. Bugs against components "kernel", "kernel-rt", and "kpatch" are only migrated if still in "NEW" or "ASSIGNED". If you cannot log in to RH Jira, please consult article #7032570. That failing, please send an e-mail to the RH Jira admins at rh-issues@redhat.com to troubleshoot your issue as a user management inquiry. The email creates a ServiceNow ticket with Red Hat. Individual Bugzilla bugs that are migrated will be moved to status "CLOSED", resolution "MIGRATED", and set with "MigratedToJIRA" in "Keywords". The link to the successor Jira issue will be found under "Links", have a little "two-footprint" icon next to it, and direct you to the "RHEL project" in Red Hat Jira (issue links are of type "https://issues.redhat.com/browse/RHEL-XXXX", where "X" is a digit). This same link will be available in a blue banner at the top of the page informing you that that bug has been migrated.
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
Comment 4RHEL Program Management
2023-07-08 07:27:58 UTC
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.
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