feat(cronet_http): Add support for QUIC hints (#1873)
* feat(cronet_http): Add support for QUIC hints
* Fix comment
* Update version
* Update cronet_configuration_test.dart
* Update cronet_configuration_test.dart
* Update cronet_configuration_test.dart
* Fix tests
* Add wip
* Update pkgs/cronet_http/lib/src/cronet_client.dart
Co-authored-by: Michael Goderbauer <goderbauer@google.com>
---------
Co-authored-by: Michael Goderbauer <goderbauer@google.com>
diff --git a/pkgs/cronet_http/CHANGELOG.md b/pkgs/cronet_http/CHANGELOG.md
index 72a8ad0..aa525e7 100644
--- a/pkgs/cronet_http/CHANGELOG.md
+++ b/pkgs/cronet_http/CHANGELOG.md
@@ -1,8 +1,9 @@
-## 1.7.1-wip
+## 1.8.0-wip
* Made callbacks asynchronous to prevent background errors caused by the
unavailability of the Dart callback.
* Change the compile SDK version to 35 for compatibility with `package:jni`.
+* Add support for QUIC hints.
## 1.7.0
diff --git a/pkgs/cronet_http/example/integration_test/cronet_configuration_test.dart b/pkgs/cronet_http/example/integration_test/cronet_configuration_test.dart
index 63ce8eb..7b06862 100644
--- a/pkgs/cronet_http/example/integration_test/cronet_configuration_test.dart
+++ b/pkgs/cronet_http/example/integration_test/cronet_configuration_test.dart
@@ -121,6 +121,49 @@
});
}
+void testQuicHints() {
+ group('quicHints', () {
+ late HttpServer server;
+
+ setUp(() async {
+ server = (await HttpServer.bind('localhost', 0))
+ ..listen((request) async {
+ await request.drain<void>();
+ request.response.headers.set('Content-Type', 'text/plain');
+ request.response.write('Hello World');
+ await request.response.close();
+ });
+ });
+ tearDown(() {
+ server.close();
+ });
+
+ test('quic hints', () async {
+ final engine = CronetEngine.build(
+ cacheMode: CacheMode.diskNoHttp,
+ enableQuic: true,
+ enableHttp2: false,
+ quicHints: [
+ ('www.google.com', 443, 443),
+ ]);
+ final response = await CronetClient.fromCronetEngine(engine)
+ .send(Request('GET', Uri.parse('https://www.google.com/')));
+ expect(response.negotiatedProtocol, 'h3');
+ }, skip: 'requires internet access');
+
+ test('no quic hints', () async {
+ final engine = CronetEngine.build(
+ cacheMode: CacheMode.diskNoHttp,
+ enableQuic: true,
+ enableHttp2: false,
+ );
+ final response = await CronetClient.fromCronetEngine(engine)
+ .send(Request('GET', Uri.parse('https://www.google.com/')));
+ expect(response.negotiatedProtocol, 'http1.1');
+ }, skip: 'requires internet access');
+ });
+}
+
void testEngineClose() {
group('engine close', () {
test('multiple close', () {
@@ -155,5 +198,6 @@
testCache();
testInvalidConfigurations();
testUserAgent();
+ testQuicHints();
testEngineClose();
}
diff --git a/pkgs/cronet_http/lib/src/cronet_client.dart b/pkgs/cronet_http/lib/src/cronet_client.dart
index b3146ae..abf6bbf 100644
--- a/pkgs/cronet_http/lib/src/cronet_client.dart
+++ b/pkgs/cronet_http/lib/src/cronet_client.dart
@@ -119,6 +119,11 @@
/// should be used per [CronetEngine].
///
/// [userAgent] controls the `User-Agent` header.
+ ///
+ /// [quicHints] adds a list of hosts that support QUIC. Each hint is a tuple
+ /// of (host, port, alternativePort) that indicates that the host supports
+ /// QUIC. Note that [CacheMode.disk] or [CacheMode.diskNoHttp] is needed to
+ /// take advantage of 0-RTT connection establishment between sessions.
static CronetEngine build(
{CacheMode? cacheMode,
int? cacheMaxSize,
@@ -127,7 +132,8 @@
bool? enablePublicKeyPinningBypassForLocalTrustAnchors,
bool? enableQuic,
String? storagePath,
- String? userAgent}) {
+ String? userAgent,
+ List<(String, int, int)>? quicHints}) {
try {
return using((arena) {
final builder = jb.CronetEngine$Builder(
@@ -173,6 +179,13 @@
?.release();
}
+ if (quicHints != null) {
+ for (final (host, port, alternativePort) in quicHints) {
+ builder.addQuicHint(
+ host.toJString()..releasedBy(arena), port, alternativePort);
+ }
+ }
+
return CronetEngine._(builder.build()!);
});
} on JniException catch (e) {
diff --git a/pkgs/cronet_http/pubspec.yaml b/pkgs/cronet_http/pubspec.yaml
index d88b592..074d26b 100644
--- a/pkgs/cronet_http/pubspec.yaml
+++ b/pkgs/cronet_http/pubspec.yaml
@@ -1,5 +1,5 @@
name: cronet_http
-version: 1.7.1-wip
+version: 1.8.0-wip
description: >-
An Android Flutter plugin that provides access to the Cronet HTTP client.
repository: https://github.com/dart-lang/http/tree/master/pkgs/cronet_http