in lib/src/http_impl.dart [1844:1909]
Future<_ConnectionInfo> connect(
String uriHost, int uriPort, _Proxy proxy, _HttpClient client) {
if (hasIdle) {
var connection = takeIdle();
client._connectionsChanged();
return Future.value(_ConnectionInfo(connection, proxy));
}
if (client.maxConnectionsPerHost != null &&
_active.length + _connecting >= client.maxConnectionsPerHost) {
var completer = Completer<_ConnectionInfo>();
_pending.add(() {
completer.complete(connect(uriHost, uriPort, proxy, client));
});
return completer.future;
}
var currentBadCertificateCallback = client._badCertificateCallback;
bool callback(X509Certificate certificate) {
if (currentBadCertificateCallback == null) return false;
return currentBadCertificateCallback(certificate, uriHost, uriPort);
}
Future<ConnectionTask> connectionTask = (isSecure && proxy.isDirect
? SecureSocket.startConnect(host, port,
context: context, onBadCertificate: callback)
: Socket.startConnect(host, port));
_connecting++;
return connectionTask.then((ConnectionTask task) {
_socketTasks.add(task);
Future socketFuture = task.socket;
if (client.connectionTimeout != null) {
socketFuture =
socketFuture.timeout(client.connectionTimeout, onTimeout: () {
_socketTasks.remove(task);
task.cancel();
});
}
return socketFuture.then((socket) {
_connecting--;
socket.setOption(SocketOption.tcpNoDelay, true);
var connection =
_HttpClientConnection(key, socket, client, false, context);
if (isSecure && !proxy.isDirect) {
connection._dispose = true;
return connection
.createProxyTunnel(uriHost, uriPort, proxy, callback)
.then((tunnel) {
client
._getConnectionTarget(uriHost, uriPort, true)
.addNewActive(tunnel);
_socketTasks.remove(task);
return _ConnectionInfo(tunnel, proxy);
});
} else {
addNewActive(connection);
_socketTasks.remove(task);
return _ConnectionInfo(connection, proxy);
}
}, onError: (error) {
_connecting--;
_socketTasks.remove(task);
_checkPending();
throw error;
});
});
}