コード例 #1
0
 public BufferedReadStream(ApmStream inner)
 {
     if (inner == null)
     {
         throw new ArgumentNullException("inner");
     }
     _inner  = inner;
     _buffer = new byte[1024];
 }
コード例 #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());
            }
        }
コード例 #3
0
        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));
        }
コード例 #4
0
 public ContentLengthReadStream(ApmStream inner, long contentLength)
 {
     _inner          = inner;
     _bytesRemaining = contentLength;
 }