Skip to content

Custom SSLParameters break HTTP/2 over HTTPS #6

@laeubi

Description

@laeubi

Custom SSLParameters break HTTP/2 over HTTPS

Setting .sslParameters() overrides HttpClient's internal ALPN configuration, forcing HTTP/1.1 fallback even when explicitly setting application protocols:

// This does NOT work - still falls back to HTTP/1.1
SSLParameters params = new SSLParameters();
params.setApplicationProtocols(new String[] {"h2", "http/1.1"});

HttpClient client = HttpClient.newBuilder()
    .version(HttpClient.Version.HTTP_2)
    .sslParameters(params)  // Overrides ALPN, breaks HTTP/2
    .build();

// Workaround: only set sslContext
HttpClient client = HttpClient.newBuilder()
    .version(HttpClient.Version.HTTP_2)
    .sslContext(customSslContext)  // OK
    .build();

Demonstrated with this testcase:

@Test
@DisplayName("HTTP/2 with Custom SSLParameters (attempting ALPN)")
public void testHttp2WithCustomSSLParametersALPNAttempt() throws Exception {
logger.info("\n=== Testing HTTP/2 with Custom SSLParameters (attempting ALPN) ===");
// Create custom SSLParameters that attempt to preserve ALPN protocols
SSLParameters sslParameters = new SSLParameters();
// Disable hostname verification for testing with self-signed certificates
sslParameters.setEndpointIdentificationAlgorithm(null);
// Explicitly set ALPN protocols to support HTTP/2
// NOTE: This demonstrates a limitation - setting custom SSLParameters
// overrides HttpClient's internal ALPN configuration
sslParameters.setApplicationProtocols(new String[] {"h2", "http/1.1"});
HttpClient client = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_2)
.connectTimeout(Duration.ofSeconds(10))
.sslContext(createTrustAllSslContext())
.sslParameters(sslParameters)
.build();
HttpRequest request = HttpRequest.newBuilder()
.uri(getHttpsUrl())
.GET()
.build();
logger.info("Sending HTTPS request with custom SSLParameters to {}", getHttpsUrl());
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
logger.info("Response status: {}", response.statusCode());
logger.info("Response version: {}", response.version());
logger.info("Response body: {}", response.body());
assertEquals(200, response.statusCode(), "Expected 200 OK response");
// This currently documents a bug in the JDK see
// https://github.com/laeubi/java-http-client/issues/6
assertEquals(HttpClient.Version.HTTP_2, response.version(),
"Custom SSLParameters override HttpClient's ALPN configuration, " +
"causing fallback to HTTP/1.1 even when protocols are explicitly set");
assertNotNull(response.body(), "Response body should not be null");
logger.info("=== Custom SSLParameters test completed - demonstrates ALPN limitation ===\n");
}

the test fails with:

JAVA Version: 21.0.9+10-LTS
expected: <HTTP_2> but was: <HTTP_1_1>

Metadata

Metadata

Assignees

Labels

JDKbugSomething isn't working

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions