Example #1
0
 protected override void Dispose(bool disposing)
 {
     _disposed = true;
     if (disposing)
     {
         _inner.Dispose();
     }
 }
Example #2
0
        private async Task TunnelThroughProxyAsync(HttpRequestMessage request, ApmStream transport, CancellationToken cancellationToken)
        {
            // Send a Connect request:
            // CONNECT server.example.com:80 HTTP / 1.1
            // Host: server.example.com:80
            var connectReqeuest = new HttpRequestMessage();

            connectReqeuest.Headers.ProxyAuthorization = request.Headers.ProxyAuthorization;
            connectReqeuest.Method = new HttpMethod("CONNECT");
            // TODO: IPv6 hosts
            string authority = request.GetHostProperty() + ":" + request.GetPortProperty().Value;

            connectReqeuest.SetAddressLineProperty(authority);
            connectReqeuest.Headers.Host = authority;

            HttpConnection      connection = new HttpConnection(new BufferedReadStream(transport));
            HttpResponseMessage connectResponse;

            try
            {
                connectResponse = await connection.SendAsync(connectReqeuest, cancellationToken);

                // TODO:? await connectResponse.Content.LoadIntoBufferAsync(); // Drain any body
                // There's no danger of accidently consuming real response data because the real request hasn't been sent yet.
            }
            catch (Exception ex)
            {
                transport.Dispose();
                throw new HttpRequestException("SSL Tunnel failed to initialize", ex);
            }

            // Listen for a response. Any 2XX is considered success, anything else is considered a failure.
            if ((int)connectResponse.StatusCode < 200 || 300 <= (int)connectResponse.StatusCode)
            {
                transport.Dispose();
                throw new HttpRequestException("Failed to negotiate the proxy tunnel: " + connectResponse.ToString());
            }
        }