Ejemplo n.º 1
0
        async Task <HttpRequestFeature> CreateRequestAsync(Stream stream, CancellationToken cancellationToken)
        {
            var firstLine = await stream.ReadLineAsync(cancellationToken).ConfigureAwait(false);

            var parts  = firstLine.Split(' ');
            var result = new HttpRequestFeature();

            result.Method = parts[0];
            var uri = new Uri(parts[1], UriKind.RelativeOrAbsolute);

            if (!uri.IsAbsoluteUri)
            {
                uri = new Uri(_localhostUri, uri);
            }
            result.Protocol = parts[2];
            for (; ;)
            {
                var line = await stream.ReadLineAsync(cancellationToken).ConfigureAwait(false);

                if (line.Length == 0)
                {
                    break;
                }
                (var name, var values) = HttpParser.ParseHeaderNameValues(line);
                result.Headers.Add(name, new Microsoft.Extensions.Primitives.StringValues(values.ToArray()));
            }
            result.Scheme      = uri.Scheme;
            result.Path        = PathString.FromUriComponent(uri);
            result.QueryString = QueryString.FromUriComponent(uri).Value;
            result.Body        = new BodyStream(stream, result.Headers.ContentLength);
            return(result);
        }
Ejemplo n.º 2
0
        private async Task PopulateRequestAsync(Stream stream, IOwinRequest request, CancellationToken cancellationToken)
        {
            var firstLine = await stream.ReadLineAsync(cancellationToken).ConfigureAwait(false);

            var parts = firstLine.Split(' ');

            if (parts.Length < 3)
            {
                throw new FormatException($"{firstLine} is not a valid request status");
            }

            _logger.WriteVerbose("Incoming request:" + firstLine);
            request.Method   = parts[0];
            request.Protocol = parts[2];
            var uri = new Uri(parts[1], UriKind.RelativeOrAbsolute);

            if (!uri.IsAbsoluteUri)
            {
                uri = new Uri(_localhostUri, uri);
            }
            for (; ;)
            {
                var line = await stream.ReadLineAsync(cancellationToken).ConfigureAwait(false);

                if (line.Length == 0)
                {
                    break;
                }
                _logger.WriteVerbose("Incoming header:" + line);
                (var name, var values) = HttpParser.ParseHeaderNameValues(line);
                request.Headers.Add(name, values.ToArray());
            }
            request.Scheme      = uri.Scheme;
            request.Path        = PathString.FromUriComponent(uri);
            request.QueryString = QueryString.FromUriComponent(uri);

            long?length = null;

            var contentLengthValues = request.Headers.GetValues("Content-Length");

            if (contentLengthValues != null && contentLengthValues.Count > 0)
            {
                length = long.Parse(contentLengthValues[0]);
            }
            request.Body = new BodyStream(stream, length);
        }
Ejemplo n.º 3
0
        protected override async Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            ValidateAndNormalizeRequest(request);
            Stream stream = null;

            try
            {
                _logger.LogVerbose("HttpOS Client: Trying to connect..");
                stream = await _dial.DialAsync(request, cancellationToken).ConfigureAwait(false);

                _logger.LogVerbose("HttpOS Client: Connected.");
                request.Properties.Add(UnderlyingStreamProperty, stream);

                _logger.LogVerbose("HttpOS Client: Writing request");
                await stream.WriteClientMethodAndHeadersAsync(request, cancellationToken).ConfigureAwait(false);

                // as soon as headers are sent, we should begin reading the response, and send the request body concurrently
                // This is because if the server 404s nothing will ever read the response and it'll hang waiting
                // for someone to read it
                var writeContentTask = Task.Run(async() =>  // Cancel this task if server response detected
                {
                    if (request.Content != null)
                    {
                        _logger.LogVerbose("HttpOS Client: Writing request request.Content.CopyToAsync");
                        await request.Content.CopyToAsync(stream).ConfigureAwait(false);
                    }

                    _logger.LogVerbose("HttpOS Client:  stream.FlushAsync");
                    await stream.FlushAsync(cancellationToken).ConfigureAwait(false);
                    _logger.LogVerbose("HttpOS Client: Finished writing request");
                }, cancellationToken);

                var responseContent = new DialResponseContent();
                var response        = new HttpResponseMessage {
                    RequestMessage = request, Content = responseContent
                };

                _logger.LogVerbose("HttpOS Client: Waiting for response");
                string statusLine = await stream.ReadLineAsync(cancellationToken).ConfigureAwait(false);

                _logger.LogVerbose("HttpOS Client: Read 1st response line");
                ParseStatusLine(response, statusLine);
                _logger.LogVerbose("HttpOS Client: ParseStatusLine");
                for (;;)
                {
                    var line = await stream.ReadLineAsync(cancellationToken).ConfigureAwait(false);

                    if (line.Length == 0)
                    {
                        _logger.LogVerbose("HttpOS Client: Found empty line, end of response headers");
                        break;
                    }

                    try
                    {
                        _logger.LogVerbose("HttpOS Client: Parsing line:" + line);
                        (var name, var value) = HttpParser.ParseHeaderNameValues(line);
                        if (!response.Headers.TryAddWithoutValidation(name, value))
                        {
                            response.Content.Headers.TryAddWithoutValidation(name, value);
                        }
                    }
                    catch (FormatException ex)
                    {
                        throw new HttpRequestException("Error parsing header", ex);
                    }
                }

                _logger.LogVerbose("HttpOS Client: Finished reading response header lines");
                responseContent.SetContent(
                    new BodyStream(stream, response.Content.Headers.ContentLength, closeOnReachEnd: true),
                    response.Content.Headers.ContentLength);
                return(response);
            }
            catch (TimeoutException)
            {
                _logger.LogWarning("HttpOS Client: connection timed out.");
                stream?.Dispose();
                throw;
            }
            catch (Exception e)
            {
                _logger.LogError("HttpOS Client: Exception:" + e.Message);
                stream?.Dispose();
                throw;
            }
        }