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 DoesNotEnforceRequestBodyTimeoutOnUpgradeRequests() { using (var input = new TestInput()) { var mockTimeoutControl = new Mock <ITimeoutControl>(); input.Http1ConnectionContext.TimeoutControl = mockTimeoutControl.Object; var body = Http1MessageBody.For(HttpVersion.Http11, new HttpRequestHeaders { HeaderConnection = "upgrade" }, input.Http1Connection); // Add some input and read it to start PumpAsync input.Add("a"); Assert.Equal(1, await body.ReadAsync(new ArraySegment <byte>(new byte[1]))); input.Fin(); Assert.Equal(0, await body.ReadAsync(new ArraySegment <byte>(new byte[1]))); mockTimeoutControl.Verify(timeoutControl => timeoutControl.StartTimingReads(), Times.Never); mockTimeoutControl.Verify(timeoutControl => timeoutControl.StopTimingReads(), Times.Never); // Due to the limits set on HttpProtocol.RequestBodyPipe, backpressure should be triggered on every // write to that pipe. Verify that read timing pause and resume are not called on upgrade // requests. mockTimeoutControl.Verify(timeoutControl => timeoutControl.PauseTimingReads(), Times.Never); mockTimeoutControl.Verify(timeoutControl => timeoutControl.ResumeTimingReads(), Times.Never); 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 CanReadFromRemainingData(HttpVersion httpVersion) { using (var input = new TestInput()) { var body = Http1MessageBody.For(httpVersion, new HttpRequestHeaders { HeaderConnection = "upgrade" }, input.Http1Connection); var mockBodyControl = new Mock <IHttpBodyControlFeature>(); mockBodyControl.Setup(m => m.AllowSynchronousIO).Returns(true); var stream = new HttpRequestStream(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 LogsWhenStartsReadingRequestBody() { using (var input = new TestInput()) { var mockLogger = new Mock <IKestrelTrace>(); 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)); mockLogger.Verify(logger => logger.RequestBodyStart("ConnectionId", "RequestId")); input.Fin(); await body.StopAsync(); } }
public async Task CanReadAsyncFromRemainingData(HttpVersion httpVersion) { using (var input = new TestInput()) { var body = Http1MessageBody.For(httpVersion, new HttpRequestHeaders { HeaderConnection = "upgrade" }, 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)); input.Fin(); input.Http1Connection.RequestBodyPipe.Reader.Complete(); 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(); } }