Skip to content

Add CRT HTTP/2 support#6702

Merged
zoewangg merged 2 commits intofeature/master/crtH2from
zoewang/crtHttp2
Feb 6, 2026
Merged

Add CRT HTTP/2 support#6702
zoewangg merged 2 commits intofeature/master/crtH2from
zoewang/crtHttp2

Conversation

@zoewangg
Copy link
Contributor

@zoewangg zoewangg commented Feb 2, 2026

Motivation and Context

Add HTTP/2 support to the AWS CRT HTTP client. This enables customers to use HTTP/2 with the CRT async HTTP client for improved performance with services
that support HTTP/2, such as Transcribe Streaming and Kinesis.

This PR targets the feature branch for initial review before merging to master.

Modifications

Core Changes

  • Migrated from HttpClientConnectionManager to HttpStreamManager API for both HTTP/1.1 and HTTP/2 support

    Key differences between HttpClientConnectionManager and HttpStreamManager

    • HttpClientConnectionManager (old API)
// Two-step process: acquire connection, then make request
CompletableFuture<HttpClientConnection> connFuture = connectionManager.acquireConnection();
connFuture.whenComplete((connection, error) -> {
    HttpStream stream = connection.makeRequest(request, responseHandler);
    stream.activate();
    // Must manage connection lifecycle (close, release back to pool)
});
  • HttpStreamManager (new API)
// Single-step: acquire stream directly (connection management is internal)
CompletableFuture<HttpStreamBase> streamFuture = streamManager.acquireStream(request, responseHandler);
streamFuture.whenComplete((stream, error) -> {
    // Stream is already activated, connection lifecycle managed internally
});
Aspect HttpClientConnectionManager HttpStreamManager
Abstraction level Connection-oriented Stream-oriented
HTTP/2 support No (HTTP/1.1 only) Yes (HTTP/1.1 and HTTP/2)
Connection lifecycle Manual (addRef/close) Automatic
Request activation Manual (stream.activate()) Automatic
Multiplexing N/A Supported for HTTP/2

The new HttpStreamManager API abstracts away connection management, making it protocol-agnostic. For HTTP/1.1, it's one stream per connection. For HTTP/2, multiple streams can share a single connection (multiplexing).

  • Added protocol(Protocol) builder method to AwsCrtAsyncHttpClient
  • HTTP/2 establishment:
    • ALPN negotiation with "h2" for HTTPS connections
    • Prior knowledge mode for HTTP (h2c) plaintext connections
  • HTTP/2 blocked in sync client (AwsCrtHttpClient) with UnsupportedOperationException

Request/Response Handling

  • Updated CrtRequestAdapter to conditionally add Connection header only for HTTP/1.1 (forbidden in HTTP/2 per RFC 7540)
  • Refactored response handlers to use HttpStreamBaseResponseHandler interface
  • Added ResponseHandlerHelper for shared stream management logic with thread-safe handling

Error Handling

  • Added try-catch wrapper in CrtAsyncRequestExecutor.execute() and CrtRequestExecutor.execute() to prevent unexpected exceptions from causing requests to
    hang

Test Updates

  • Updated test classes to use new HttpStreamManager API
  • Renamed tests to follow methodToTest_when_expectedBehavior convention
  • Added H2BehaviorTest for HTTP/2 functional tests
  • Added H2ErrorTest for RST_STREAM and GOAWAY error scenarios
  • Parameterized TranscribeStreamingIntegrationTest with Netty and CRT clients

Testing

  • All unit tests pass: mvn test -pl http-clients/aws-crt-client (175 tests)
  • Integration tests with Transcribe Streaming service
  • Manual testing with HTTP/2 enabled services

Types of changes

  • New feature (non-breaking change which adds functionality)

Checklist

  • I have read the CONTRIBUTING document
  • Local run of mvn install succeeds
  • My code follows the code style of this project
  • My change requires a change to the Javadoc documentation
  • I have updated the Javadoc documentation accordingly
  • I have added tests to cover my changes
  • All new and existing tests passed
  • I have added a changelog entry. Adding a new entry must be accomplished by running the scripts/new-change script and following the instructions.
    Commit the new file created by the script in .changes/next-release with your changes.
  • My change is to implement 1.11 parity feature and I have updated [LaunchChangelog](https://github.com/aws/aws-sdk-java-v2/blob/master/docs/
    LaunchChangelog.md)

License

  • I confirm that this pull request can be released under the Apache 2 license

@zoewangg zoewangg requested a review from a team as a code owner February 2, 2026 17:30
toThrow = new ConnectException(httpException.getMessage());
return new SSLHandshakeException(httpException.getMessage());
}
// TODO: check with CRT team, could CRT_SOCKET_TIMEOUT be thrown
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}

@Test
public void execute_AcquireConnectionFailure_shouldAlwaysWrapIOException() {
Copy link
Contributor Author

@zoewangg zoewangg Feb 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test was deleted because after the new stream manager change, there's no stream.activate() invocation anymore and the exception will only be surfaced through failed completable future, which is already covered in execute_retryableException_wrapsWithIOException

clientTlsContextOptions = clientTlsContextOptions.withAlpnList("h2");
}

try (ClientBootstrap clientBootstrap = new ClientBootstrap(null, null);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed try-catch because it's no longer needed and we removed subresource.addRef() to keep the logic simple

@zoewangg zoewangg merged commit 88811fd into feature/master/crtH2 Feb 6, 2026
9 of 30 checks passed
@zoewangg zoewangg deleted the zoewang/crtHttp2 branch February 6, 2026 19:25
@github-actions
Copy link

github-actions bot commented Feb 6, 2026

This pull request has been closed and the conversation has been locked. Comments on closed PRs are hard for our team to see. If you need more assistance, please open a new issue that references this one.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 6, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants