startConnect static method
Future<ConnectionTask<SecureSocket> >
startConnect(
- Object host,
- int port, {
- SecurityContext? context,
- bool onBadCertificate(
- X509Certificate certificate
- void keyLog(
- String line
- List<
String> ? supportedProtocols,
Connects to host:port over TLS, as SecureSocket.startConnect does.
Hand it to HttpClient.connectionFactory for an https or wss uri
with no proxy. A cancelled task completes ConnectionTask.socket with a
SocketException at once and closes the socket.
Implementation
static Future<ConnectionTask<SecureSocket>> startConnect(
Object host,
int port, {
SecurityContext? context,
bool Function(X509Certificate certificate)? onBadCertificate,
void Function(String line)? keyLog,
List<String>? supportedProtocols,
}) async {
final tcp = await RawSocket.startConnect(host, port);
final cancelled = Completer<void>();
RawSocket? raw;
Future<SecureSocket> open() async {
final socket = await tcp.socket;
raw = socket;
if (cancelled.isCompleted) {
unawaited(socket.close());
throw const SocketException('Connection attempt cancelled');
}
final handshake = RawSecureSocket.secure(
socket,
host: host,
context: context,
onBadCertificate: onBadCertificate,
keyLog: keyLog,
supportedProtocols: supportedProtocols,
);
// Closing the socket does not end a pending handshake future, so the
// cancel is raced; a handshake that still completes is closed.
unawaited(
handshake.then((secure) {
if (cancelled.isCompleted) secure.close();
}, onError: (Object _) {}),
);
final secure = await Future.any([
handshake,
cancelled.future.then<RawSecureSocket>(
(_) => throw const SocketException('Connection attempt cancelled'),
),
]);
return _RawSecureSocketAdapter(secure);
}
return ConnectionTask.fromSocket(open(), () {
if (cancelled.isCompleted) return;
cancelled.complete();
tcp.cancel();
final socket = raw;
if (socket != null) unawaited(socket.close());
});
}