private async ValueTask <HttpConnection> CreateConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken) { // If a non-infinite connect timeout has been set, create and use a new CancellationToken that'll be canceled // when either the original token is canceled or a connect timeout occurs. CancellationTokenSource cancellationWithConnectTimeout = null; if (Settings._connectTimeout != Timeout.InfiniteTimeSpan) { cancellationWithConnectTimeout = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, default); cancellationWithConnectTimeout.CancelAfter(Settings._connectTimeout); cancellationToken = cancellationWithConnectTimeout.Token; } try { Stream stream = await (_proxyUri == null ? ConnectHelper.ConnectAsync(_host, _port, cancellationToken) : (_sslOptions == null ? ConnectHelper.ConnectAsync(_proxyUri.IdnHost, _proxyUri.Port, cancellationToken) : EstablishProxyTunnel(cancellationToken))).ConfigureAwait(false); TransportContext transportContext = null; if (_sslOptions != null) { // TODO #25206 and #24430: Register/IsCancellationRequested should be removable once SslStream auth and sockets respect cancellation. CancellationTokenRegistration ctr = cancellationToken.Register(s => ((Stream)s).Dispose(), stream); try { SslStream sslStream = await ConnectHelper.EstablishSslConnectionAsync(_sslOptions, request, stream, cancellationToken).ConfigureAwait(false); stream = sslStream; transportContext = sslStream.TransportContext; cancellationToken.ThrowIfCancellationRequested(); // to handle race condition where stream is dispose of by cancellation after auth } catch (Exception exc) { stream.Dispose(); // in case cancellation occurs after successful SSL auth if (HttpConnection.ShouldWrapInOperationCanceledException(exc, cancellationToken)) { throw HttpConnection.CreateOperationCanceledException(exc, cancellationToken); } throw; } finally { ctr.Dispose(); } } return(_maxConnections == int.MaxValue ? new HttpConnection(this, stream, transportContext) : new HttpConnectionWithFinalizer(this, stream, transportContext)); // finalizer needed to signal the pool when a connection is dropped } finally { cancellationWithConnectTimeout?.Dispose(); } }
private async ValueTask <HttpConnection> CreateConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken) { Stream stream = await ConnectHelper.ConnectAsync(_key, cancellationToken).ConfigureAwait(false); TransportContext transportContext = null; if (_key.IsSecure) { SslStream sslStream = await ConnectHelper.EstablishSslConnectionAsync(_pools.Settings, _key.SslHostName, request, stream, cancellationToken).ConfigureAwait(false); stream = sslStream; transportContext = sslStream.TransportContext; } return(new HttpConnection(this, stream, transportContext)); }
private async ValueTask <HttpConnection> CreateConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken) { Stream stream = await ConnectHelper.ConnectAsync(_key, cancellationToken).ConfigureAwait(false); TransportContext transportContext = null; if (_key.IsSecure) { SslStream sslStream = await ConnectHelper.EstablishSslConnectionAsync(_sslOptions, request, stream, cancellationToken).ConfigureAwait(false); stream = sslStream; transportContext = sslStream.TransportContext; } return(_maxConnections == int.MaxValue ? new HttpConnection(this, stream, transportContext) : new HttpConnectionWithFinalizer(this, stream, transportContext)); // finalizer needed to signal the pool when a connection is dropped }
private async ValueTask <HttpConnection> CreateConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken) { // If a non-infinite connect timeout has been set, create and use a new CancellationToken that'll be canceled // when either the original token is canceled or a connect timeout occurs. CancellationTokenSource cancellationWithConnectTimeout = null; if (Settings._connectTimeout != Timeout.InfiniteTimeSpan) { cancellationWithConnectTimeout = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, default); cancellationWithConnectTimeout.CancelAfter(Settings._connectTimeout); cancellationToken = cancellationWithConnectTimeout.Token; } try { Stream stream = await (_proxyUri == null ? ConnectHelper.ConnectAsync(_host, _port, cancellationToken) : (_sslOptions == null ? ConnectHelper.ConnectAsync(_proxyUri.IdnHost, _proxyUri.Port, cancellationToken) : EstablishProxyTunnel(cancellationToken))).ConfigureAwait(false); TransportContext transportContext = null; if (_sslOptions != null) { SslStream sslStream = await ConnectHelper.EstablishSslConnectionAsync(_sslOptions, request, stream, cancellationToken).ConfigureAwait(false); stream = sslStream; transportContext = sslStream.TransportContext; } return(_maxConnections == int.MaxValue ? new HttpConnection(this, stream, transportContext) : new HttpConnectionWithFinalizer(this, stream, transportContext)); // finalizer needed to signal the pool when a connection is dropped } finally { cancellationWithConnectTimeout?.Dispose(); } }
private async ValueTask <(HttpConnection, HttpResponseMessage)> CreateConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken) { // If a non-infinite connect timeout has been set, create and use a new CancellationToken that'll be canceled // when either the original token is canceled or a connect timeout occurs. CancellationTokenSource cancellationWithConnectTimeout = null; if (Settings._connectTimeout != Timeout.InfiniteTimeSpan) { cancellationWithConnectTimeout = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, default); cancellationWithConnectTimeout.CancelAfter(Settings._connectTimeout); cancellationToken = cancellationWithConnectTimeout.Token; } try { Socket socket = null; Stream stream = null; switch (_kind) { case HttpConnectionKind.Http: case HttpConnectionKind.Https: case HttpConnectionKind.ProxyConnect: (socket, stream) = await ConnectHelper.ConnectAsync(_host, _port, cancellationToken).ConfigureAwait(false); break; case HttpConnectionKind.Proxy: (socket, stream) = await ConnectHelper.ConnectAsync(_proxyUri.IdnHost, _proxyUri.Port, cancellationToken).ConfigureAwait(false); break; case HttpConnectionKind.ProxyTunnel: case HttpConnectionKind.SslProxyTunnel: HttpResponseMessage response; (stream, response) = await EstablishProxyTunnel(cancellationToken).ConfigureAwait(false); if (response != null) { // Return non-success response from proxy. response.RequestMessage = request; return(null, response); } break; } TransportContext transportContext = null; if (_sslOptions != null) { SslStream sslStream = await ConnectHelper.EstablishSslConnectionAsync(_sslOptions, request, stream, cancellationToken).ConfigureAwait(false); stream = sslStream; transportContext = sslStream.TransportContext; } HttpConnection connection = _maxConnections == int.MaxValue ? new HttpConnection(this, socket, stream, transportContext) : new HttpConnectionWithFinalizer(this, socket, stream, transportContext); // finalizer needed to signal the pool when a connection is dropped return(connection, null); } finally { cancellationWithConnectTimeout?.Dispose(); } }