Skip to content

Commit

Permalink
⚡️ Fallback to another adapter for H2
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexV525 committed Dec 22, 2023
1 parent f05b1d6 commit 755932c
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 12 deletions.
8 changes: 6 additions & 2 deletions plugins/http2_adapter/lib/src/connection_manager_imp.dart
Original file line number Diff line number Diff line change
Expand Up @@ -208,13 +208,14 @@ class _ConnectionManager implements ConnectionManager {
completerProxyInitialization.complete();
} else {
completerProxyInitialization.completeError(
SocketException('Proxy cannot be initialized'),
SocketException(
'Proxy cannot be initialized with status: $statusLine',
),
);
}
},
onError: completerProxyInitialization.completeError,
);

await completerProxyInitialization.future;

final socket = await SecureSocket.secure(
Expand All @@ -224,6 +225,9 @@ class _ConnectionManager implements ConnectionManager {
onBadCertificate: clientConfig.onBadCertificate,
supportedProtocols: ['h2'],
);
if (socket.selectedProtocol != 'h2') {
throw const H2NotSupportedSocketException();
}

proxySubscription.cancel();

Expand Down
33 changes: 23 additions & 10 deletions plugins/http2_adapter/lib/src/http2_adapter.dart
Original file line number Diff line number Diff line change
@@ -1,25 +1,34 @@
// ignore_for_file: void_checks
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';

import 'package:dio/dio.dart';
import 'package:dio/io.dart';
import 'package:http2/http2.dart';
import 'package:meta/meta.dart';

part 'client_setting.dart';

part 'connection_manager.dart';

part 'connection_manager_imp.dart';

@internal
class H2NotSupportedSocketException extends SocketException {
const H2NotSupportedSocketException() : super('h2 protocol not supported');
}

/// A Dio HttpAdapter which implements Http/2.0.
class Http2Adapter implements HttpClientAdapter {
Http2Adapter(
ConnectionManager? connectionManager,
) : _connectionMgr = connectionManager ?? ConnectionManager();
ConnectionManager? connectionManager, {
HttpClientAdapter? fallbackAdapter,
}) : _connectionMgr = connectionManager ?? ConnectionManager(),
_fallbackAdapter = fallbackAdapter ?? IOHttpClientAdapter();

final ConnectionManager _connectionMgr;
final HttpClientAdapter _fallbackAdapter;

@override
Future<ResponseBody> fetch(
Expand All @@ -28,12 +37,17 @@ class Http2Adapter implements HttpClientAdapter {
Future<void>? cancelFuture,
) async {
final redirects = <RedirectRecord>[];
return _fetch(
options,
requestStream,
cancelFuture,
redirects,
);
try {
return await _fetch(options, requestStream, cancelFuture, redirects);
} on H2NotSupportedSocketException {
// Fallback to use another adapter (typically IOHttpClientAdapter)
// since the request can have a better handle by it.
return await _fallbackAdapter.fetch(
options,
requestStream,
cancelFuture,
);
}
}

Future<ResponseBody> _fetch(
Expand Down Expand Up @@ -78,7 +92,6 @@ class Http2Adapter implements HttpClientAdapter {
// Creates a new outgoing stream.
final stream = transport.makeRequest(headers);

// ignore: unawaited_futures
cancelFuture?.whenComplete(() {
Future(() {
stream.terminate();
Expand Down
1 change: 1 addition & 0 deletions plugins/http2_adapter/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ environment:
dependencies:
http2: ^2.0.0
dio: ^5.2.0
meta: ^1.5.0

dev_dependencies:
crypto: ^3.0.2
Expand Down

0 comments on commit 755932c

Please sign in to comment.