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; }
// 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); }
/// <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(); } }
/// <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); } }