protected override void Dispose(bool disposing) { _disposed = true; if (disposing) { _inner.Dispose(); } }
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()); } }