public async Task CanReadAsyncFromContentLength(HttpVersion httpVersion) { using (var input = new TestInput()) { var body = MessageBody.For(httpVersion, new FrameRequestHeaders { HeaderContentLength = "5" }, input.Frame); var stream = new FrameRequestStream(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 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.Frame.ServiceContext.Log = mockLogger.Object; input.Frame.ConnectionIdFeature = "ConnectionId"; input.Frame.TraceIdentifier = "RequestId"; var body = MessageBody.For(HttpVersion.Http11, new FrameRequestHeaders { HeaderContentLength = "2" }, input.Frame); var stream = new FrameRequestStream(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(TimeSpan.FromSeconds(10))); await body.StopAsync(); } }
public void PositionThrows() { var stream = new FrameRequestStream(); Assert.Throws <NotSupportedException>(() => stream.Position); Assert.Throws <NotSupportedException>(() => stream.Position = 0); }
public async Task CanHandleLargeBlocks() { using (var input = new TestInput()) { var body = MessageBody.For("HTTP/1.0", new FrameRequestHeaders(), input.FrameContext); var stream = new FrameRequestStream(); stream.StartAcceptingReads(body); // Input needs to be greater than 4032 bytes to allocate a block not backed by a slab. var largeInput = new string('a', 8192); input.Add(largeInput, true); // Add a smaller block to the end so that SocketInput attempts to return the large // block to the memory pool. input.Add("Hello", true); var readBuffer = new byte[8192]; var count1 = await stream.ReadAsync(readBuffer, 0, 8192); Assert.Equal(8192, count1); AssertASCII(largeInput, new ArraySegment <byte>(readBuffer, 0, 8192)); var count2 = await stream.ReadAsync(readBuffer, 0, 8192); Assert.Equal(5, count2); AssertASCII("Hello", new ArraySegment <byte>(readBuffer, 0, 5)); var count3 = await stream.ReadAsync(readBuffer, 0, 8192); Assert.Equal(0, count3); } }
public async Task ReadExitsGivenIncompleteChunkedExtension() { using (var input = new TestInput()) { var body = MessageBody.For(HttpVersion.Http11, new FrameRequestHeaders { HeaderTransferEncoding = "chunked" }, input.Frame); var stream = new FrameRequestStream(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.TimeoutAfter(TimeSpan.FromSeconds(10))); Assert.Equal(0, await stream.ReadAsync(buffer, 0, buffer.Length)); await body.StopAsync(); } }
public void PositionThrows() { var stream = new FrameRequestStream(Mock.Of <IHttpBodyControlFeature>()); Assert.Throws <NotSupportedException>(() => stream.Position); Assert.Throws <NotSupportedException>(() => stream.Position = 0); }
public async Task CanHandleLargeBlocks() { using (var input = new TestInput()) { var body = MessageBody.For(HttpVersion.Http10, new FrameRequestHeaders { HeaderContentLength = "8197" }, input.Frame); var stream = new FrameRequestStream(Mock.Of <IHttpBodyControlFeature>()); stream.StartAcceptingReads(body); // Input needs to be greater than 4032 bytes to allocate a block not backed by a slab. var largeInput = new string('a', 8192); input.Add(largeInput); // Add a smaller block to the end so that SocketInput attempts to return the large // block to the memory pool. input.Add("Hello"); var ms = new MemoryStream(); await stream.CopyToAsync(ms); var requestArray = ms.ToArray(); Assert.Equal(8197, requestArray.Length); AssertASCII(largeInput + "Hello", new ArraySegment <byte>(requestArray, 0, requestArray.Length)); await body.StopAsync(); } }
public void NullDestinationCausesCopyToAsyncToThrowArgumentNullException() { var stream = new FrameRequestStream(Mock.Of <IHttpBodyControlFeature>()); stream.StartAcceptingReads(null); Assert.Throws <ArgumentNullException>(() => { stream.CopyToAsync(null); }); }
public void ZeroBufferSizeCausesCopyToAsyncToThrowArgumentException() { var stream = new FrameRequestStream(Mock.Of <IHttpBodyControlFeature>()); stream.StartAcceptingReads(null); Assert.Throws <ArgumentException>(() => { stream.CopyToAsync(Mock.Of <Stream>(), 0); }); }
public async Task CanReadFromRemainingData(HttpVersion httpVersion) { using (var input = new TestInput()) { var body = MessageBody.For(httpVersion, new FrameRequestHeaders { HeaderConnection = "upgrade" }, input.Frame); var mockBodyControl = new Mock <IHttpBodyControlFeature>(); mockBodyControl.Setup(m => m.AllowSynchronousIO).Returns(true); var stream = new FrameRequestStream(mockBodyControl.Object); stream.StartAcceptingReads(body); input.Add("Hello"); var buffer = new byte[1024]; var count = stream.Read(buffer, 0, buffer.Length); Assert.Equal(5, count); AssertASCII("Hello", new ArraySegment <byte>(buffer, 0, count)); input.Fin(); await body.StopAsync(); } }
public async Task SynchronousReadsThrowIfDisallowedByIHttpBodyControlFeature() { var allowSynchronousIO = false; var mockBodyControl = new Mock <IHttpBodyControlFeature>(); mockBodyControl.Setup(m => m.AllowSynchronousIO).Returns(() => allowSynchronousIO); var mockMessageBody = new Mock <MessageBody>((Frame)null); mockMessageBody.Setup(m => m.ReadAsync(It.IsAny <ArraySegment <byte> >(), CancellationToken.None)).ReturnsAsync(0); var stream = new FrameRequestStream(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 CanReadFromChunkedEncoding() { using (var input = new TestInput()) { var body = MessageBody.For(HttpVersion.Http11, new FrameRequestHeaders { HeaderTransferEncoding = "chunked" }, input.Frame); var mockBodyControl = new Mock <IHttpBodyControlFeature>(); mockBodyControl.Setup(m => m.AllowSynchronousIO).Returns(true); var stream = new FrameRequestStream(mockBodyControl.Object); stream.StartAcceptingReads(body); input.Add("5\r\nHello\r\n"); var buffer = new byte[1024]; var count = stream.Read(buffer, 0, buffer.Length); Assert.Equal(5, count); AssertASCII("Hello", new ArraySegment <byte>(buffer, 0, count)); input.Add("0\r\n\r\n"); count = stream.Read(buffer, 0, buffer.Length); Assert.Equal(0, count); await body.StopAsync(); } }
public Streams(IHttpBodyControlFeature bodyControl, IFrameControl frameControl) { _request = new FrameRequestStream(bodyControl); _emptyRequest = new FrameRequestStream(bodyControl); _response = new FrameResponseStream(bodyControl, frameControl); _upgradeableResponse = new WrappingStream(_response); _upgradeStream = new FrameDuplexStream(_request, _response); }
public void StopAcceptingReadsCausesCopyToAsyncToThrowObjectDisposedException() { var stream = new FrameRequestStream(Mock.Of <IHttpBodyControlFeature>()); stream.StartAcceptingReads(null); stream.StopAcceptingReads(); Assert.Throws <ObjectDisposedException>(() => { stream.CopyToAsync(Mock.Of <Stream>()); }); }
public void AbortCausesCopyToAsyncToCancel() { var stream = new FrameRequestStream(Mock.Of <IHttpBodyControlFeature>()); stream.StartAcceptingReads(null); stream.Abort(); var task = stream.CopyToAsync(Mock.Of <Stream>()); Assert.True(task.IsCanceled); }
public void AbortCausesReadToCancel() { var stream = new FrameRequestStream(); stream.StartAcceptingReads(null); stream.Abort(); var task = stream.ReadAsync(new byte[1], 0, 1); Assert.True(task.IsCanceled); }
public void AbortWithErrorCausesCopyToAsyncToCancel() { var stream = new FrameRequestStream(Mock.Of <IHttpBodyControlFeature>()); stream.StartAcceptingReads(null); var error = new Exception(); stream.Abort(error); var task = stream.CopyToAsync(Mock.Of <Stream>()); Assert.True(task.IsFaulted); Assert.Same(error, task.Exception.InnerException); }
public async Task ReadAsyncFromNoContentLengthReturnsZero(HttpVersion httpVersion) { using (var input = new TestInput()) { var body = MessageBody.For(httpVersion, new FrameRequestHeaders(), input.Frame); var stream = new FrameRequestStream(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 ReadFromNoContentLengthReturnsZero(HttpVersion httpVersion) { using (var input = new TestInput()) { var body = MessageBody.For(httpVersion, new FrameRequestHeaders(), input.Frame); var mockBodyControl = new Mock <IHttpBodyControlFeature>(); mockBodyControl.Setup(m => m.AllowSynchronousIO).Returns(true); var stream = new FrameRequestStream(mockBodyControl.Object); stream.StartAcceptingReads(body); input.Add("Hello"); var buffer = new byte[1024]; Assert.Equal(0, stream.Read(buffer, 0, buffer.Length)); await body.StopAsync(); } }
public async Task Http10ConnectionCloseAsync() { var input = new TestInput(); var body = MessageBody.For("HTTP/1.0", new FrameRequestHeaders(), input.FrameContext); var stream = new FrameRequestStream().StartAcceptingReads(body); input.Add("Hello", true); var buffer1 = new byte[1024]; var count1 = await stream.ReadAsync(buffer1, 0, 1024); AssertASCII("Hello", new ArraySegment <byte>(buffer1, 0, 5)); var buffer2 = new byte[1024]; var count2 = await stream.ReadAsync(buffer2, 0, 1024); Assert.Equal(0, count2); }
public void Http10ConnectionClose() { var input = new TestInput(); var body = MessageBody.For("HTTP/1.0", new Dictionary <string, StringValues>(), input.FrameContext); var stream = new FrameRequestStream(body); input.Add("Hello", true); var buffer1 = new byte[1024]; var count1 = stream.Read(buffer1, 0, 1024); AssertASCII("Hello", new ArraySegment <byte>(buffer1, 0, 5)); var buffer2 = new byte[1024]; var count2 = stream.Read(buffer2, 0, 1024); Assert.Equal(0, count2); }
public async Task ConnectionUpgradeKeepAlive(string headerConnection) { using (var input = new TestInput()) { var body = MessageBody.For(HttpVersion.Http11, new FrameRequestHeaders { HeaderConnection = headerConnection }, input.Frame); var stream = new FrameRequestStream(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 ReadThrowsGivenChunkPrefixGreaterThan8Bytes() { using (var input = new TestInput()) { var body = MessageBody.For(HttpVersion.Http11, new FrameRequestHeaders { HeaderTransferEncoding = "chunked" }, input.Frame); var stream = new FrameRequestStream(Mock.Of <IHttpBodyControlFeature>()); stream.StartAcceptingReads(body); input.Add("012345678\r"); var buffer = new byte[1024]; var ex = await Assert.ThrowsAsync <BadHttpRequestException>(async() => await stream.ReadAsync(buffer, 0, buffer.Length)); Assert.Equal(CoreStrings.BadRequest_BadChunkSizeData, ex.Message); await body.StopAsync(); } }
public async Task PumpAsyncDoesNotReturnAfterCancelingInput() { using (var input = new TestInput()) { var body = MessageBody.For(HttpVersion.Http11, new FrameRequestHeaders { HeaderContentLength = "2" }, input.Frame); var stream = new FrameRequestStream(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.Pipe.Reader.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 = MessageBody.For(HttpVersion.Http11, new FrameRequestHeaders { HeaderContentLength = "2" }, input.Frame); var stream = new FrameRequestStream(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 WriteAsyncThrows() { var stream = new FrameRequestStream(); await Assert.ThrowsAsync <NotSupportedException>(() => stream.WriteAsync(new byte[1], 0, 1)); }
public void SetLengthThrows() { var stream = new FrameRequestStream(); Assert.Throws <NotSupportedException>(() => stream.SetLength(0)); }
public void WriteByteThrows() { var stream = new FrameRequestStream(); Assert.Throws <NotSupportedException>(() => stream.WriteByte(0)); }
public Streams(IFrameControl frameControl) { RequestBody = new FrameRequestStream(); ResponseBody = new FrameResponseStream(frameControl); DuplexStream = new FrameDuplexStream(RequestBody, ResponseBody); }
public void BeginWriteThrows() { var stream = new FrameRequestStream(); Assert.Throws <NotSupportedException>(() => stream.BeginWrite(new byte[1], 0, 1, null, null)); }