public BufferedReadStream(ApmStream inner) { if (inner == null) { throw new ArgumentNullException("inner"); } _inner = inner; _buffer = new byte[1024]; }
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()); } }
private async Task <HttpResponseMessage> ProcessRequestAsync(HttpRequestMessage request, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); ProcessUrl(request); ProcessHostHeader(request); request.Headers.ConnectionClose = true; // TODO: Connection re-use is not supported. if (request.Method != HttpMethod.Get) { throw new NotImplementedException(request.Method.Method); // TODO: POST } ProxyMode proxyMode = DetermineProxyModeAndAddressLine(request); ApmStream transport = await ConnectAsync(request, cancellationToken); if (proxyMode == ProxyMode.Tunnel) { await TunnelThroughProxyAsync(request, transport, cancellationToken); } System.Diagnostics.Debug.Assert(!(proxyMode == ProxyMode.Http && request.IsHttps())); if (request.IsHttps()) { SslStream sslStream = new SslStream(transport); await sslStream.AuthenticateAsClientAsync(request.GetHostProperty()); transport = new ApmStreamWrapper(sslStream); } var bufferedReadStream = new BufferedReadStream(transport); var connection = new HttpConnection(bufferedReadStream); return(await connection.SendAsync(request, cancellationToken)); }
public ContentLengthReadStream(ApmStream inner, long contentLength) { _inner = inner; _bytesRemaining = contentLength; }