예제 #1
0
        internal async Task <HttpTestRequest> ReceiveRequestAsync(Http1TestStream stream)
        {
            string request = await ReadLineAsync().ConfigureAwait(false);

            Match match = Regex.Match(request, @"^([^ ]+) ([^ ]+) HTTP/(\d).(\d)$");

            if (!match.Success)
            {
                throw new Exception("Invalid request line.");
            }

            string method       = match.Groups[1].Value;
            string pathAndQuery = match.Groups[2].Value;
            int    versionMajor = int.Parse(match.Groups[3].Value, NumberStyles.None, CultureInfo.InvariantCulture);
            int    versionMinor = int.Parse(match.Groups[4].Value, NumberStyles.None, CultureInfo.InvariantCulture);
            var    version      = new Version(versionMajor, versionMinor);

            TestHeadersSink headers = await ReadHeadersAsync().ConfigureAwait(false);

            _responseContentLength = headers.TryGetSingleValue("content-length", out string?contentLength)
                ? int.Parse(contentLength, NumberStyles.None, CultureInfo.InvariantCulture)
                : method switch
            {
                "GET" or "HEAD" or "DELETE" or "TRACE" => 0,
                _ => (int?)null
            };
            _responseIsChunked = headers.TryGetSingleValue("transfer-encoding", out string?transferEncoding) && transferEncoding == "chunked";

            if (!_responseIsChunked && _responseContentLength == 0)
            {
                stream.ReleaseNextReader();
            }

            return(new HttpTestRequest(method, pathAndQuery, version, headers));
        }
예제 #2
0
        public override Task <HttpTestStream> AcceptStreamAsync()
        {
            Http1TestStream stream;
            bool            startRead, startWrite;

            lock (Sync)
            {
                startRead  = _activeReaders++ == 0;
                startWrite = _activeWriters++ == 0;

                stream = new Http1TestStream(this, ++_streamIdx);
                if (!startRead)
                {
                    _readQueue.Enqueue(stream);
                }
                if (!startWrite)
                {
                    _writeQueue.Enqueue(stream);
                }
            }

            if (startRead)
            {
                stream._readSemaphore.Release();
            }
            if (startWrite)
            {
                stream._writeSemaphore.Release();
            }

            return(Task.FromResult <HttpTestStream>(stream));
        }
예제 #3
0
        internal async Task <TestHeadersSink> ReceiveTrailingHeadersAsync(Http1TestStream stream)
        {
            if (_responseIsChunked)
            {
                TestHeadersSink headers = await ReadHeadersAsync().ConfigureAwait(false);

                stream.ReleaseNextReader();
                return(headers);
            }
            else
            {
                return(new TestHeadersSink());
            }
        }
예제 #4
0
 internal Stream ReceiveContentStream(Http1TestStream stream) =>
 _responseIsChunked ? new Http1TestChunkedStream(this, _responseContentLength) :
 _responseContentLength != null ? new Http1TestContentLengthStream(this, _responseContentLength != 0 ? stream : null, _responseContentLength.Value) :
 new Http1TestLengthlessStream(this);