public async Task ReadExitsGivenIncompleteChunkedExtension() { using (var input = new TestInput()) { var body = Http1MessageBody.For(HttpVersion.Http11, new HttpRequestHeaders { HeaderTransferEncoding = "chunked" }, input.Http1Connection); var stream = new HttpRequestStream(Mock.Of <IHttpBodyControlFeature>()); stream.StartAcceptingReads(body); input.Add("5;\r\0"); var buffer = new byte[1024]; var readTask = stream.ReadAsync(buffer, 0, buffer.Length); Assert.False(readTask.IsCompleted); input.Add("\r\r\r\nHello\r\n0\r\n\r\n"); Assert.Equal(5, await readTask.DefaultTimeout()); Assert.Equal(0, await stream.ReadAsync(buffer, 0, buffer.Length)); await body.StopAsync(); } }
public async Task CanReadAsyncFromContentLength(HttpVersion httpVersion) { using (var input = new TestInput()) { var body = Http1MessageBody.For(httpVersion, new HttpRequestHeaders { HeaderContentLength = "5" }, input.Http1Connection); var stream = new HttpRequestStream(Mock.Of <IHttpBodyControlFeature>()); stream.StartAcceptingReads(body); input.Add("Hello"); var buffer = new byte[1024]; var count = await stream.ReadAsync(buffer, 0, buffer.Length); Assert.Equal(5, count); AssertASCII("Hello", new ArraySegment <byte>(buffer, 0, count)); count = await stream.ReadAsync(buffer, 0, buffer.Length); Assert.Equal(0, count); await body.StopAsync(); } }
public async Task CanReadAsyncFromChunkedEncoding() { using (var input = new TestInput()) { var body = Http1MessageBody.For(HttpVersion.Http11, new HttpRequestHeaders { HeaderTransferEncoding = "chunked" }, input.Http1Connection); var stream = new HttpRequestStream(Mock.Of <IHttpBodyControlFeature>()); stream.StartAcceptingReads(body); input.Add("5\r\nHello\r\n"); var buffer = new byte[1024]; var count = await stream.ReadAsync(buffer, 0, buffer.Length); Assert.Equal(5, count); AssertASCII("Hello", new ArraySegment <byte>(buffer, 0, count)); input.Add("0\r\n\r\n"); count = await stream.ReadAsync(buffer, 0, buffer.Length); Assert.Equal(0, count); input.Http1Connection.RequestBodyPipe.Reader.Complete(); await body.StopAsync(); } }
internal async Task <MutableHttpServerRequest> ParseRequestStream(IInputStream requestStream) { var httpStream = new HttpRequestStream(requestStream); var request = new MutableHttpServerRequest(); try { var stream = await httpStream.ReadAsync(BUFFER_SIZE, InputStreamOptions.Partial); byte[] streamData = stream.Data; var requestPipeline = GetPipeline(); using (var pipeLineEnumerator = requestPipeline.GetEnumerator()) { pipeLineEnumerator.MoveNext(); bool requestComplete = false; while (!requestComplete) { pipeLineEnumerator.Current.HandleRequestPart(streamData, request); streamData = pipeLineEnumerator.Current.UnparsedData; if (pipeLineEnumerator.Current.IsFinished) { if (!pipeLineEnumerator.Current.IsSucceeded || !pipeLineEnumerator.MoveNext()) { break; } } else { var newStreamdata = await httpStream.ReadAsync(BUFFER_SIZE, InputStreamOptions.Partial); if (!newStreamdata.ReadSuccessful) { break; } streamData = streamData.ConcatArray(newStreamdata.Data); } } } request.IsComplete = requestPipeline.All(p => p.IsSucceeded); } catch (Exception ex) { Debug.WriteLine(ex.Message); } return(request); }
internal async Task<HttpRequest> ParseRequestStream(IInputStream requestStream) { var httpStream = new HttpRequestStream(requestStream); var request = new HttpRequest(); try { var stream = await httpStream.ReadAsync(BUFFER_SIZE, InputStreamOptions.Partial); byte[] streamData = stream.Data; var requestPipeline = GetPipeline(); using (var pipeLineEnumerator = requestPipeline.GetEnumerator()) { pipeLineEnumerator.MoveNext(); bool requestComplete = false; while (!requestComplete) { pipeLineEnumerator.Current.HandleRequestPart(streamData, request); streamData = pipeLineEnumerator.Current.UnparsedData; if (pipeLineEnumerator.Current.IsFinished) { if (!pipeLineEnumerator.Current.IsSucceeded || !pipeLineEnumerator.MoveNext()) { break; } } else { var newStreamdata = await httpStream.ReadAsync(BUFFER_SIZE, InputStreamOptions.Partial); if (!newStreamdata.ReadSuccessful) { break; } streamData = streamData.ConcatArray(newStreamdata.Data); } } } request.IsComplete = requestPipeline.All(p => p.IsSucceeded); } catch (Exception ex) { Debug.WriteLine(ex.Message); } return request; }
public async Task SynchronousReadsThrowIfDisallowedByIHttpBodyControlFeature() { var allowSynchronousIO = false; var mockBodyControl = new Mock <IHttpBodyControlFeature>(); mockBodyControl.Setup(m => m.AllowSynchronousIO).Returns(() => allowSynchronousIO); var mockMessageBody = new Mock <MessageBody>((HttpProtocol)null); mockMessageBody.Setup(m => m.ReadAsync(It.IsAny <ArraySegment <byte> >(), CancellationToken.None)).ReturnsAsync(0); var stream = new HttpRequestStream(mockBodyControl.Object); stream.StartAcceptingReads(mockMessageBody.Object); Assert.Equal(0, await stream.ReadAsync(new byte[1], 0, 1)); var ioEx = Assert.Throws <InvalidOperationException>(() => stream.Read(new byte[1], 0, 1)); Assert.Equal("Synchronous operations are disallowed. Call ReadAsync or set AllowSynchronousIO to true instead.", ioEx.Message); var ioEx2 = Assert.Throws <InvalidOperationException>(() => stream.CopyTo(Stream.Null)); Assert.Equal("Synchronous operations are disallowed. Call ReadAsync or set AllowSynchronousIO to true instead.", ioEx2.Message); allowSynchronousIO = true; Assert.Equal(0, stream.Read(new byte[1], 0, 1)); }
public async Task LogsWhenStopsReadingRequestBody() { using (var input = new TestInput()) { var logEvent = new ManualResetEventSlim(); var mockLogger = new Mock <IKestrelTrace>(); mockLogger .Setup(logger => logger.RequestBodyDone("ConnectionId", "RequestId")) .Callback(() => logEvent.Set()); input.Http1Connection.ServiceContext.Log = mockLogger.Object; input.Http1Connection.ConnectionIdFeature = "ConnectionId"; input.Http1Connection.TraceIdentifier = "RequestId"; var body = Http1MessageBody.For(HttpVersion.Http11, new HttpRequestHeaders { HeaderContentLength = "2" }, input.Http1Connection); var stream = new HttpRequestStream(Mock.Of <IHttpBodyControlFeature>()); stream.StartAcceptingReads(body); // Add some input and consume it to ensure PumpAsync is running input.Add("a"); Assert.Equal(1, await stream.ReadAsync(new byte[1], 0, 1)); input.Fin(); Assert.True(logEvent.Wait(TestConstants.DefaultTimeout)); await body.StopAsync(); } }
public async Task UpgradeConnectionAcceptsContentLengthZero() { // https://tools.ietf.org/html/rfc7230#section-3.3.2 // "A user agent SHOULD NOT send a Content-Length header field when the request message does not contain // a payload body and the method semantics do not anticipate such a body." // ==> it can actually send that header var headerConnection = "Upgrade, Keep-Alive"; using (var input = new TestInput()) { var body = Http1MessageBody.For(HttpVersion.Http11, new HttpRequestHeaders { HeaderConnection = headerConnection, ContentLength = 0 }, input.Http1Connection); var stream = new HttpRequestStream(Mock.Of <IHttpBodyControlFeature>()); stream.StartAcceptingReads(body); input.Add("Hello"); var buffer = new byte[1024]; Assert.Equal(5, await stream.ReadAsync(buffer, 0, buffer.Length)); AssertASCII("Hello", new ArraySegment <byte>(buffer, 0, 5)); input.Fin(); await body.StopAsync(); } }
public async Task LogsWhenStartsReadingRequestBody() { using (var input = new TestInput()) { var mockLogger = new Mock <IKestrelTrace>(); input.Http1Connection.ServiceContext.Log = mockLogger.Object; input.Http1Connection.ConnectionIdFeature = "ConnectionId"; input.Http1Connection.TraceIdentifier = "RequestId"; var body = Http1MessageBody.For(HttpVersion.Http11, new HttpRequestHeaders { HeaderContentLength = "2" }, input.Http1Connection); var stream = new HttpRequestStream(Mock.Of <IHttpBodyControlFeature>()); stream.StartAcceptingReads(body); // Add some input and consume it to ensure PumpAsync is running input.Add("a"); Assert.Equal(1, await stream.ReadAsync(new byte[1], 0, 1)); mockLogger.Verify(logger => logger.RequestBodyStart("ConnectionId", "RequestId")); input.Fin(); input.Http1Connection.RequestBodyPipe.Reader.Complete(); await body.StopAsync(); } }
public void StopAcceptingReadsCausesReadToThrowObjectDisposedException() { var stream = new HttpRequestStream(Mock.Of <IHttpBodyControlFeature>()); stream.StartAcceptingReads(null); stream.StopAcceptingReads(); Assert.Throws <ObjectDisposedException>(() => { stream.ReadAsync(new byte[1], 0, 1); }); }
public async Task AbortCausesReadToCancel() { var stream = new HttpRequestStream(Mock.Of <IHttpBodyControlFeature>()); stream.StartAcceptingReads(null); stream.Abort(); await Assert.ThrowsAsync <TaskCanceledException>(() => stream.ReadAsync(new byte[1], 0, 1)); }
public void AbortCausesReadToCancel() { var stream = new HttpRequestStream(Mock.Of <IHttpBodyControlFeature>()); stream.StartAcceptingReads(null); stream.Abort(); var task = stream.ReadAsync(new byte[1], 0, 1); Assert.True(task.IsCanceled); }
public async Task AbortWithErrorCausesReadToCancel() { var stream = new HttpRequestStream(Mock.Of <IHttpBodyControlFeature>()); stream.StartAcceptingReads(null); var error = new Exception(); stream.Abort(error); var exception = await Assert.ThrowsAsync <Exception>(() => stream.ReadAsync(new byte[1], 0, 1)); Assert.Same(error, exception); }
public void AbortWithErrorCausesReadToCancel() { var stream = new HttpRequestStream(Mock.Of <IHttpBodyControlFeature>()); stream.StartAcceptingReads(null); var error = new Exception(); stream.Abort(error); var task = stream.ReadAsync(new byte[1], 0, 1); Assert.True(task.IsFaulted); Assert.Same(error, task.Exception.InnerException); }
public async Task PumpAsyncDoesNotReturnAfterCancelingInput() { using (var input = new TestInput()) { var body = Http1MessageBody.For(HttpVersion.Http11, new HttpRequestHeaders { HeaderContentLength = "2" }, input.Http1Connection); var stream = new HttpRequestStream(Mock.Of <IHttpBodyControlFeature>()); stream.StartAcceptingReads(body); // Add some input and consume it to ensure PumpAsync is running input.Add("a"); Assert.Equal(1, await stream.ReadAsync(new byte[1], 0, 1)); input.Transport.Input.CancelPendingRead(); // Add more input and verify is read input.Add("b"); Assert.Equal(1, await stream.ReadAsync(new byte[1], 0, 1)); await body.StopAsync(); } }
public async Task StopAsyncPreventsFurtherDataConsumption() { using (var input = new TestInput()) { var body = Http1MessageBody.For(HttpVersion.Http11, new HttpRequestHeaders { HeaderContentLength = "2" }, input.Http1Connection); var stream = new HttpRequestStream(Mock.Of <IHttpBodyControlFeature>()); stream.StartAcceptingReads(body); // Add some input and consume it to ensure PumpAsync is running input.Add("a"); Assert.Equal(1, await stream.ReadAsync(new byte[1], 0, 1)); await body.StopAsync(); // Add some more data. Checking for cancelation and exiting the loop // should take priority over reading this data. input.Add("b"); // There shouldn't be any additional data available Assert.Equal(0, await stream.ReadAsync(new byte[1], 0, 1)); } }
public async Task ReadAsyncFromNoContentLengthReturnsZero(HttpVersion httpVersion) { using (var input = new TestInput()) { var body = Http1MessageBody.For(httpVersion, new HttpRequestHeaders(), input.Http1Connection); var stream = new HttpRequestStream(Mock.Of <IHttpBodyControlFeature>()); stream.StartAcceptingReads(body); input.Add("Hello"); var buffer = new byte[1024]; Assert.Equal(0, await stream.ReadAsync(buffer, 0, buffer.Length)); await body.StopAsync(); } }
public async Task ConnectionUpgradeKeepAlive(string headerConnection) { using (var input = new TestInput()) { var body = Http1MessageBody.For(HttpVersion.Http11, new HttpRequestHeaders { HeaderConnection = headerConnection }, input.Http1Connection); var stream = new HttpRequestStream(Mock.Of <IHttpBodyControlFeature>()); stream.StartAcceptingReads(body); input.Add("Hello"); var buffer = new byte[1024]; Assert.Equal(5, await stream.ReadAsync(buffer, 0, buffer.Length)); AssertASCII("Hello", new ArraySegment <byte>(buffer, 0, 5)); input.Fin(); await body.StopAsync(); } }
public async Task ReadThrowsGivenChunkPrefixGreaterThanMaxInt() { using (var input = new TestInput()) { var body = Http1MessageBody.For(HttpVersion.Http11, new HttpRequestHeaders { HeaderTransferEncoding = "chunked" }, input.Http1Connection); var stream = new HttpRequestStream(Mock.Of <IHttpBodyControlFeature>()); stream.StartAcceptingReads(body); input.Add("80000000\r\n"); var buffer = new byte[1024]; var ex = await Assert.ThrowsAsync <IOException>(async() => await stream.ReadAsync(buffer, 0, buffer.Length)); Assert.IsType <OverflowException>(ex.InnerException); Assert.Equal(CoreStrings.BadRequest_BadChunkSizeData, ex.Message); await body.StopAsync(); } }