示例#1
0
        protected override async Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            var endpoint = new UnixDomainSocketEndPoint(this.providerUri.LocalPath);

            using (Socket socket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.Unspecified))
            {
                Events.Connecting(this.providerUri.LocalPath);
                await socket.ConnectAsync(endpoint);

                Events.Connected(this.providerUri.LocalPath);

                using (var stream = new HttpBufferedStream(new NetworkStream(socket, true)))
                {
                    var    serializer   = new HttpRequestResponseSerializer();
                    byte[] requestBytes = serializer.SerializeRequest(request);

                    Events.SendRequest(request.RequestUri);
                    await stream.WriteAsync(requestBytes, 0, requestBytes.Length, cancellationToken);

                    if (request.Content != null)
                    {
                        await request.Content.CopyToAsync(stream);
                    }

                    HttpResponseMessage response = await serializer.DeserializeResponse(stream, cancellationToken);

                    Events.ResponseReceived(response.StatusCode);

                    return(response);
                }
            }
        }
        async Task SetResponseStatusLine(HttpResponseMessage httpResponse, HttpBufferedStream bufferedStream, CancellationToken cancellationToken)
        {
            string statusLine = await bufferedStream.ReadLineAsync(cancellationToken).ConfigureAwait(false);

            if (string.IsNullOrWhiteSpace(statusLine))
            {
                throw new HttpRequestException("Response is empty.");
            }

            string[] statusLineParts = statusLine.Split(new[] { SP }, 3);
            if (statusLineParts.Length < 3)
            {
                throw new HttpRequestException("Status line is not valid.");
            }

            string[] httpVersion = statusLineParts[0].Split(new[] { ProtocolVersionSeparator }, 2);
            if (httpVersion.Length < 2 || !Version.TryParse(httpVersion[1], out Version versionNumber))
            {
                throw new HttpRequestException($"Version is not valid {statusLineParts[0]}.");
            }

            httpResponse.Version = versionNumber;

            if (!Enum.TryParse(statusLineParts[1], out HttpStatusCode statusCode))
            {
                throw new HttpRequestException($"StatusCode is not valid {statusLineParts[1]}.");
            }

            httpResponse.StatusCode   = statusCode;
            httpResponse.ReasonPhrase = statusLineParts[2];
        }
示例#3
0
        protected override async Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            var endpoint = new UnixDomainSocketEndPoint(this.providerUri.LocalPath);

            Events.Connecting(this.providerUri.LocalPath);
            // do not dispose `Socket` or `HttpBufferedStream` here, b/c it will be used later
            // by the consumer of HttpResponseMessage (HttpResponseMessage.Content.ReadAsStringAsync()).
            // When HttpResponseMessage is disposed - the stream and socket is disposed as well.
            Socket socket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.Unspecified);
            await socket.ConnectAsync(endpoint);

            Events.Connected(this.providerUri.LocalPath);

            var stream     = new HttpBufferedStream(new NetworkStream(socket, true));
            var serializer = new HttpRequestResponseSerializer();

            byte[] requestBytes = serializer.SerializeRequest(request);

            Events.SendRequest(request.RequestUri);
            await stream.WriteAsync(requestBytes, 0, requestBytes.Length, cancellationToken);

            if (request.Content != null)
            {
                await request.Content.CopyToAsync(stream);
            }

            HttpResponseMessage response = await serializer.DeserializeResponse(stream, cancellationToken);

            Events.ResponseReceived(response.StatusCode);

            return(response);
        }
        async Task SetHeadersAndContent(HttpResponseMessage httpResponse, HttpBufferedStream bufferedStream, CancellationToken cancellationToken)
        {
            IList <string> headers = new List <string>();
            string         line    = await bufferedStream.ReadLineAsync(cancellationToken);

            while (!string.IsNullOrWhiteSpace(line))
            {
                headers.Add(line);
                line = await bufferedStream.ReadLineAsync(cancellationToken);
            }

            httpResponse.Content = new StreamContent(bufferedStream);
            var contentHeaders = new Dictionary <string, string>();

            foreach (string header in headers)
            {
                if (string.IsNullOrWhiteSpace(header))
                {
                    // headers end
                    break;
                }

                int headerSeparatorPosition = header.IndexOf(HeaderSeparator);
                if (headerSeparatorPosition <= 0)
                {
                    throw new HttpRequestException($"Header is invalid {header}.");
                }

                string headerName  = header.Substring(0, headerSeparatorPosition).Trim();
                string headerValue = header.Substring(headerSeparatorPosition + 1).Trim();

                bool headerAdded = httpResponse.Headers.TryAddWithoutValidation(headerName, headerValue);
                if (!headerAdded)
                {
                    contentHeaders.Add(headerName, headerValue);
                }
            }

            bool isChunked = httpResponse.Headers.TransferEncodingChunked.HasValue &&
                             httpResponse.Headers.TransferEncodingChunked.Value;

            httpResponse.Content = isChunked
                    ? new StreamContent(new HttpChunkedStreamReader(bufferedStream))
                    : new StreamContent(bufferedStream);

            foreach (KeyValuePair <string, string> contentHeader in contentHeaders)
            {
                httpResponse.Content.Headers.TryAddWithoutValidation(contentHeader.Key, contentHeader.Value);
                if (string.Equals(contentHeader.Key, ContentLengthHeaderName, StringComparison.InvariantCultureIgnoreCase))
                {
                    if (!long.TryParse(contentHeader.Value, out long contentLength))
                    {
                        throw new HttpRequestException($"Header value {contentHeader.Value} is invalid for {ContentLengthHeaderName}.");
                    }

                    await httpResponse.Content.LoadIntoBufferAsync(contentLength);
                }
            }
        }
        public async Task <HttpResponseMessage> DeserializeResponse(HttpBufferedStream bufferedStream, CancellationToken cancellationToken)
        {
            var httpResponse = new HttpResponseMessage();

            await SetResponseStatusLine(httpResponse, bufferedStream, cancellationToken).ConfigureAwait(false);
            await SetHeadersAndContent(httpResponse, bufferedStream, cancellationToken).ConfigureAwait(false);

            return(httpResponse);
        }
示例#6
0
        public HttpChunkedStreamReader(HttpBufferedStream stream)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            this.stream = stream;
        }
        async Task SetHeadersAndContent(HttpResponseMessage httpResponse, HttpBufferedStream bufferedStream, CancellationToken cancellationToken)
        {
            IList <string> headers = new List <string>();
            string         line    = await bufferedStream.ReadLineAsync(cancellationToken).ConfigureAwait(false);

            while (!string.IsNullOrWhiteSpace(line))
            {
                headers.Add(line);
                line = await bufferedStream.ReadLineAsync(cancellationToken).ConfigureAwait(false);
            }

            httpResponse.Content = new StreamContent(bufferedStream);
            foreach (string header in headers)
            {
                if (string.IsNullOrWhiteSpace(header))
                {
                    // headers end
                    break;
                }

                int headerSeparatorPosition = header.IndexOf(HeaderSeparator);
                if (headerSeparatorPosition <= 0)
                {
                    throw new HttpRequestException($"Header is invalid {header}.");
                }

                string headerName  = header.Substring(0, headerSeparatorPosition).Trim();
                string headerValue = header.Substring(headerSeparatorPosition + 1).Trim();

                bool headerAdded = httpResponse.Headers.TryAddWithoutValidation(headerName, headerValue);
                if (!headerAdded)
                {
                    if (string.Equals(headerName, ContentLengthHeaderName, StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (!long.TryParse(headerValue, out long contentLength))
                        {
                            throw new HttpRequestException($"Header value is invalid for {headerName}.");
                        }

                        await httpResponse.Content.LoadIntoBufferAsync(contentLength).ConfigureAwait(false);
                    }

                    httpResponse.Content.Headers.TryAddWithoutValidation(headerName, headerValue);
                }
            }
        }
示例#8
0
        protected override async Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            Socket socket = await this.GetConnectedSocketAsync();

            var stream = new HttpBufferedStream(new NetworkStream(socket, true));

            var serializer = new HttpRequestResponseSerializer();

            byte[] requestBytes = serializer.SerializeRequest(request);

            await stream.WriteAsync(requestBytes, 0, requestBytes.Length, cancellationToken);

            if (request.Content != null)
            {
                await request.Content.CopyToAsync(stream);
            }

            HttpResponseMessage response = await serializer.DeserializeResponse(stream, cancellationToken);

            return(response);
        }
示例#9
0
 public HttpChunkedStreamReader(HttpBufferedStream stream)
 {
     this.stream = Preconditions.CheckNotNull(stream, nameof(stream));
 }
 public HttpChunkedStreamReader(HttpBufferedStream stream)
 {
     this.stream = stream;
 }