public HttpConnectionKey(HttpConnectionKind kind, string host, int port, string sslHostName, Uri proxyUri)
 {
     Kind        = kind;
     Host        = host;
     Port        = port;
     SslHostName = sslHostName;
     ProxyUri    = proxyUri;
 }
 public HttpConnectionKey(HttpConnectionKind kind, string?host, int port, string?sslHostName, Uri?proxyUri, string identity)
 {
     Kind        = kind;
     Host        = host;
     Port        = port;
     SslHostName = sslHostName;
     ProxyUri    = proxyUri;
     Identity    = identity;
 }
Example #3
0
 // Same options that are provided to the HttpConnectionPool.
 public HttpEndPoint(HttpConnectionKind kind, string host, int port, string sslHostName, Uri proxyUri, int maxConnections)
     : base(IPAddress.Parse(host), port)
 {
     Kind           = kind;
     Host           = host;
     SslHostName    = sslHostName;
     ProxyUri       = proxyUri;
     MaxConnections = maxConnections;
 }
 public HttpConnectionPool(HttpConnectionKind kind, string host, string sslHost, int port, Uri proxyUri, HttpConnectionPoolManager poolManager)
 {
     _kind            = kind;
     _host            = host;
     _sslHost         = sslHost;
     _port            = port;
     _proxyUri        = proxyUri;
     _poolManager     = poolManager;
     _idleConnections = new List <CachedConnection>();
 }
        private async ValueTask <(Socket, Stream, HttpResponseMessage)> ConnectAsync(HttpConnectionKind kind, HttpRequestMessage request, CancellationToken cancellationToken)
        {
            Stream stream = null;

            switch (_kind)
            {
            case HttpConnectionKind.Http:
            case HttpConnectionKind.Https:
            case HttpConnectionKind.ProxyConnect:
                stream = await ConnectAsync(request, cancellationToken).ConfigureAwait(false);

                break;

            case HttpConnectionKind.ProxyTunnel:
            case HttpConnectionKind.SslProxyTunnel:
                HttpResponseMessage response;
                (stream, response) = await EstablishProxyTunnel(request.Headers.Any()?request.Headers : null, cancellationToken).ConfigureAwait(false);

                if (response != null)
                {
                    // Return non-success response from proxy.
                    response.RequestMessage = request;
                    return(null, null, response);
                }
                break;
            }

            Socket socket = (stream as ExposedSocketNetworkStream)?.Socket;

            if (kind == HttpConnectionKind.Https || kind == HttpConnectionKind.SslProxyTunnel)
            {
                var sslOptions = new SslClientAuthenticationOptions();
                sslOptions.TargetHost          = _poolManager.settings.EndPointProvider.GetHost(_sslHost);
                sslOptions.EnabledSslProtocols = SslProtocols.Tls11;
                if (_poolManager.settings.RemoteCertificateValidationCallback != null)
                {
                    sslOptions.RemoteCertificateValidationCallback = _poolManager.settings.RemoteCertificateValidationCallback;
                }
                else
                {
                    sslOptions.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) =>
                    {
                        return(true);
                    };
                }
                sslOptions.ClientCertificates = _poolManager.settings.ClientCertificates;
                SslStream sslStream = await EstablishSslConnectionAsync(sslOptions, request, stream, cancellationToken).ConfigureAwait(false);

                stream = sslStream;
            }

            return(socket, stream, null);
        }
        GetConnectionAsync(HttpConnectionKind kind, HttpRequestMessage request, CancellationToken cancellationToken)
        {
            var connection = await GetOrReserveHttpConnectionAsync(cancellationToken);

            if (connection != null)
            {
                return(connection, false, null);
            }

            var(sokect, stream, failureResponse) = await ConnectAsync(kind, request, cancellationToken);

            connection = ConstructHttpConnection(sokect, stream);

            return(connection, true, null);
        }
Example #7
0
        /// <summary>Initializes the pool.</summary>
        /// <param name="maxConnections">The maximum number of connections allowed to be associated with the pool at any given time.</param>
        ///
        public HttpConnectionPool(HttpConnectionPoolManager poolManager, HttpConnectionKind kind, string host, int port, string sslHostName, Uri proxyUri, int maxConnections)
        {
            _poolManager    = poolManager;
            _kind           = kind;
            _host           = host;
            _port           = port;
            _proxyUri       = proxyUri;
            _maxConnections = maxConnections;

            switch (kind)
            {
            case HttpConnectionKind.Http:
                Debug.Assert(host != null);
                Debug.Assert(port != 0);
                Debug.Assert(sslHostName == null);
                Debug.Assert(proxyUri == null);
                break;

            case HttpConnectionKind.Https:
                Debug.Assert(host != null);
                Debug.Assert(port != 0);
                Debug.Assert(sslHostName != null);
                Debug.Assert(proxyUri == null);

                _sslOptions = ConstructSslOptions(poolManager, sslHostName);
                break;

            case HttpConnectionKind.Proxy:
                Debug.Assert(host == null);
                Debug.Assert(port == 0);
                Debug.Assert(sslHostName == null);
                Debug.Assert(proxyUri != null);
                break;

            case HttpConnectionKind.ProxyTunnel:
                Debug.Assert(host != null);
                Debug.Assert(port != 0);
                Debug.Assert(sslHostName == null);
                Debug.Assert(proxyUri != null);
                break;

            case HttpConnectionKind.SslProxyTunnel:
                Debug.Assert(host != null);
                Debug.Assert(port != 0);
                Debug.Assert(sslHostName != null);
                Debug.Assert(proxyUri != null);

                _sslOptions = ConstructSslOptions(poolManager, sslHostName);
                break;

            case HttpConnectionKind.ProxyConnect:
                Debug.Assert(host != null);
                Debug.Assert(port != 0);
                Debug.Assert(sslHostName == null);
                Debug.Assert(proxyUri != null);
                Debug.Assert(proxyUri.IdnHost == host && proxyUri.Port == port);
                break;

            default:
                Debug.Fail("Unkown HttpConnectionKind in HttpConnectionPool.ctor");
                break;
            }

            if (_host != null)
            {
                // Precalculate ASCII bytes for Host header
                // Note that if _host is null, this is a (non-tunneled) proxy connection, and we can't cache the hostname.
                string hostHeader =
                    (_port != (_sslOptions == null ? DefaultHttpPort : DefaultHttpsPort)) ?
                    $"{_host}:{_port}" :
                    _host;

                // Note the IDN hostname should always be ASCII, since it's already been IDNA encoded.
                _hostHeaderValueBytes = Encoding.ASCII.GetBytes(hostHeader);
                Debug.Assert(Encoding.ASCII.GetString(_hostHeaderValueBytes) == hostHeader);
            }

            // Set up for PreAuthenticate.  Access to this cache is guarded by a lock on the cache itself.
            if (_poolManager.Settings._preAuthenticate)
            {
                PreAuthCredentials = new CredentialCache();
            }
        }
Example #8
0
        /// <summary>Initializes the pool.</summary>
        /// <param name="maxConnections">The maximum number of connections allowed to be associated with the pool at any given time.</param>
        ///
        public HttpConnectionPool(HttpConnectionPoolManager poolManager, HttpConnectionKind kind, string host, int port, string sslHostName, Uri proxyUri, int maxConnections)
        {
            _poolManager    = poolManager;
            _kind           = kind;
            _host           = host;
            _port           = port;
            _proxyUri       = proxyUri;
            _maxConnections = maxConnections;

            switch (kind)
            {
            case HttpConnectionKind.Http:
                Debug.Assert(host != null);
                Debug.Assert(port != 0);
                Debug.Assert(sslHostName == null);
                Debug.Assert(proxyUri == null);
                break;

            case HttpConnectionKind.Https:
                Debug.Assert(host != null);
                Debug.Assert(port != 0);
                Debug.Assert(sslHostName != null);
                Debug.Assert(proxyUri == null);

                _sslOptions = ConstructSslOptions(poolManager, sslHostName);
                break;

            case HttpConnectionKind.Proxy:
                Debug.Assert(host == null);
                Debug.Assert(port == 0);
                Debug.Assert(sslHostName == null);
                Debug.Assert(proxyUri != null);
                break;

            case HttpConnectionKind.SslProxyTunnel:
                Debug.Assert(host != null);
                Debug.Assert(port != 0);
                Debug.Assert(sslHostName != null);
                Debug.Assert(proxyUri != null);

                _sslOptions = ConstructSslOptions(poolManager, sslHostName);
                break;

            case HttpConnectionKind.ProxyConnect:
                Debug.Assert(host != null);
                Debug.Assert(port != 0);
                Debug.Assert(sslHostName == null);
                Debug.Assert(proxyUri != null);
                Debug.Assert(proxyUri.IdnHost == host && proxyUri.Port == port);
                break;

            default:
                Debug.Fail("Unkown HttpConnectionKind in HttpConnectionPool.ctor");
                break;
            }

            if (_host != null)
            {
                // Precalculate ASCII bytes for header name
                // Note that if _host is null, this is a (non-tunneled) proxy connection, and we can't cache the hostname.
                // CONSIDER: Cache more than just host name -- port, header name, etc

                // Note the IDN hostname should always be ASCII, since it's already been IDNA encoded.
                _idnHostAsciiBytes = Encoding.ASCII.GetBytes(_host);
                Debug.Assert(Encoding.ASCII.GetString(_idnHostAsciiBytes) == _host);
            }
        }