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)); }
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)); }
internal async Task <TestHeadersSink> ReceiveTrailingHeadersAsync(Http1TestStream stream) { if (_responseIsChunked) { TestHeadersSink headers = await ReadHeadersAsync().ConfigureAwait(false); stream.ReleaseNextReader(); return(headers); } else { return(new TestHeadersSink()); } }
internal Stream ReceiveContentStream(Http1TestStream stream) => _responseIsChunked ? new Http1TestChunkedStream(this, _responseContentLength) : _responseContentLength != null ? new Http1TestContentLengthStream(this, _responseContentLength != 0 ? stream : null, _responseContentLength.Value) : new Http1TestLengthlessStream(this);