示例#1
0
        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();
            }
        }
示例#2
0
        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));
        }
示例#3
0
        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
        }
示例#4
0
        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();
            }
        }
示例#5
0
        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();
            }
        }