diff --git a/src/Microsoft.AspNet.Server.WebListener/FeatureContext.cs b/src/Microsoft.AspNet.Server.WebListener/FeatureContext.cs index d27fb974da..af21159d7e 100644 --- a/src/Microsoft.AspNet.Server.WebListener/FeatureContext.cs +++ b/src/Microsoft.AspNet.Server.WebListener/FeatureContext.cs @@ -348,6 +348,11 @@ namespace Microsoft.AspNet.Server.WebListener set { _responseHeaders = value; } } + bool IHttpResponseFeature.HeadersSent + { + get { return Response.HeadersSent; } + } + void IHttpResponseFeature.OnSendingHeaders(Action callback, object state) { Response.OnSendingHeaders(callback, state); diff --git a/src/Microsoft.AspNet.Server.WebListener/MessagePump.cs b/src/Microsoft.AspNet.Server.WebListener/MessagePump.cs index a6089cb400..f376c034af 100644 --- a/src/Microsoft.AspNet.Server.WebListener/MessagePump.cs +++ b/src/Microsoft.AspNet.Server.WebListener/MessagePump.cs @@ -168,7 +168,7 @@ namespace Microsoft.AspNet.Server.WebListener catch (Exception ex) { LogHelper.LogException(_logger, "ProcessRequestAsync", ex); - if (requestContext.Response.SentHeaders) + if (requestContext.Response.HeadersSent) { requestContext.Abort(); } diff --git a/src/Microsoft.Net.Http.Server/RequestProcessing/RequestContext.cs b/src/Microsoft.Net.Http.Server/RequestProcessing/RequestContext.cs index 37102f41a2..37862cc392 100644 --- a/src/Microsoft.Net.Http.Server/RequestProcessing/RequestContext.cs +++ b/src/Microsoft.Net.Http.Server/RequestProcessing/RequestContext.cs @@ -145,7 +145,7 @@ namespace Microsoft.Net.Http.Server public Task UpgradeAsync() { - if (!IsUpgradableRequest || _response.SentHeaders) + if (!IsUpgradableRequest || _response.HeadersSent) { throw new InvalidOperationException(); } diff --git a/src/Microsoft.Net.Http.Server/RequestProcessing/Response.cs b/src/Microsoft.Net.Http.Server/RequestProcessing/Response.cs index 72aa46bd8c..21149425af 100644 --- a/src/Microsoft.Net.Http.Server/RequestProcessing/Response.cs +++ b/src/Microsoft.Net.Http.Server/RequestProcessing/Response.cs @@ -297,7 +297,7 @@ namespace Microsoft.Net.Http.Server } } - public bool SentHeaders + public bool HeadersSent { get { @@ -356,7 +356,7 @@ namespace Microsoft.Net.Http.Server UnsafeNclNativeMethods.HttpApi.HTTP_FLAGS flags, bool isOpaqueUpgrade) { - Debug.Assert(!SentHeaders, "HttpListenerResponse::SendHeaders()|SentHeaders is true."); + Debug.Assert(!HeadersSent, "HttpListenerResponse::SendHeaders()|SentHeaders is true."); // TODO: Verbose log headers _responseState = ResponseState.SentHeaders; diff --git a/src/Microsoft.Net.Http.Server/RequestProcessing/ResponseStream.cs b/src/Microsoft.Net.Http.Server/RequestProcessing/ResponseStream.cs index 5572e22e5a..cbe64f4330 100644 --- a/src/Microsoft.Net.Http.Server/RequestProcessing/ResponseStream.cs +++ b/src/Microsoft.Net.Http.Server/RequestProcessing/ResponseStream.cs @@ -94,7 +94,7 @@ namespace Microsoft.Net.Http.Server // Send headers public override void Flush() { - if (_closed || _requestContext.Response.SentHeaders) + if (_closed || _requestContext.Response.HeadersSent) { return; } @@ -127,7 +127,7 @@ namespace Microsoft.Net.Http.Server // Send headers public override Task FlushAsync(CancellationToken cancellationToken) { - if (_closed || _requestContext.Response.SentHeaders) + if (_closed || _requestContext.Response.HeadersSent) { return Helpers.CompletedTask(); } @@ -275,7 +275,7 @@ namespace Microsoft.Net.Http.Server uint dataToWrite = (uint)size; SafeLocalFree bufferAsIntPtr = null; IntPtr pBufferAsIntPtr = IntPtr.Zero; - bool sentHeaders = _requestContext.Response.SentHeaders; + bool sentHeaders = _requestContext.Response.HeadersSent; try { if (size == 0) @@ -398,7 +398,7 @@ namespace Microsoft.Net.Http.Server uint statusCode; uint bytesSent = 0; flags |= _leftToWrite == size ? UnsafeNclNativeMethods.HttpApi.HTTP_FLAGS.NONE : UnsafeNclNativeMethods.HttpApi.HTTP_FLAGS.HTTP_SEND_RESPONSE_FLAG_MORE_DATA; - bool sentHeaders = _requestContext.Response.SentHeaders; + bool sentHeaders = _requestContext.Response.HeadersSent; ResponseStreamAsyncResult asyncResult = new ResponseStreamAsyncResult(this, state, callback, buffer, offset, size, _requestContext.Response.BoundaryType == BoundaryType.Chunked, sentHeaders); // Update m_LeftToWrite now so we can queue up additional BeginWrite's without waiting for EndWrite. @@ -543,7 +543,7 @@ namespace Microsoft.Net.Http.Server uint statusCode; uint bytesSent = 0; flags |= _leftToWrite == size ? UnsafeNclNativeMethods.HttpApi.HTTP_FLAGS.NONE : UnsafeNclNativeMethods.HttpApi.HTTP_FLAGS.HTTP_SEND_RESPONSE_FLAG_MORE_DATA; - bool sentHeaders = _requestContext.Response.SentHeaders; + bool sentHeaders = _requestContext.Response.HeadersSent; ResponseStreamAsyncResult asyncResult = new ResponseStreamAsyncResult(this, null, null, buffer, offset, size, _requestContext.Response.BoundaryType == BoundaryType.Chunked, sentHeaders, cancellationRegistration); // Update m_LeftToWrite now so we can queue up additional BeginWrite's without waiting for EndWrite. @@ -649,7 +649,7 @@ namespace Microsoft.Net.Http.Server uint statusCode; uint bytesSent = 0; flags |= _leftToWrite == size ? UnsafeNclNativeMethods.HttpApi.HTTP_FLAGS.NONE : UnsafeNclNativeMethods.HttpApi.HTTP_FLAGS.HTTP_SEND_RESPONSE_FLAG_MORE_DATA; - bool sentHeaders = _requestContext.Response.SentHeaders; + bool sentHeaders = _requestContext.Response.HeadersSent; ResponseStreamAsyncResult asyncResult = new ResponseStreamAsyncResult(this, null, null, fileName, offset, size, _requestContext.Response.BoundaryType == BoundaryType.Chunked, sentHeaders, cancellationRegistration); @@ -768,7 +768,7 @@ namespace Microsoft.Net.Http.Server LogHelper.LogError(_requestContext.Logger, "ResponseStream::Dispose", "Fewer bytes were written than were specified in the Content-Length."); return; } - bool sentHeaders = _requestContext.Response.SentHeaders; + bool sentHeaders = _requestContext.Response.HeadersSent; if (sentHeaders && _leftToWrite == 0) { return; diff --git a/test/Microsoft.AspNet.Server.WebListener.FunctionalTests/ResponseHeaderTests.cs b/test/Microsoft.AspNet.Server.WebListener.FunctionalTests/ResponseHeaderTests.cs index 66b18b3364..12cf0daf8e 100644 --- a/test/Microsoft.AspNet.Server.WebListener.FunctionalTests/ResponseHeaderTests.cs +++ b/test/Microsoft.AspNet.Server.WebListener.FunctionalTests/ResponseHeaderTests.cs @@ -245,7 +245,9 @@ namespace Microsoft.AspNet.Server.WebListener responseHeaders.Add("Custom1", new string[] { "value1a", "value1b" }); responseHeaders.Add("Custom2", new string[] { "value2a, value2b" }); var body = responseInfo.Body; + Assert.False(responseInfo.HeadersSent); body.Flush(); + Assert.True(responseInfo.HeadersSent); Assert.Throws(() => responseInfo.StatusCode = 404); Assert.Throws(() => responseHeaders.Add("Custom3", new string[] { "value3a, value3b", "value3c" })); return Task.FromResult(0); @@ -275,7 +277,9 @@ namespace Microsoft.AspNet.Server.WebListener responseHeaders.Add("Custom1", new string[] { "value1a", "value1b" }); responseHeaders.Add("Custom2", new string[] { "value2a, value2b" }); var body = responseInfo.Body; + Assert.False(responseInfo.HeadersSent); await body.FlushAsync(); + Assert.True(responseInfo.HeadersSent); Assert.Throws(() => responseInfo.StatusCode = 404); Assert.Throws(() => responseHeaders.Add("Custom3", new string[] { "value3a, value3b", "value3c" })); })) diff --git a/test/Microsoft.AspNet.Server.WebListener.FunctionalTests/ResponseTests.cs b/test/Microsoft.AspNet.Server.WebListener.FunctionalTests/ResponseTests.cs index 6d7d13af0c..5505163782 100644 --- a/test/Microsoft.AspNet.Server.WebListener.FunctionalTests/ResponseTests.cs +++ b/test/Microsoft.AspNet.Server.WebListener.FunctionalTests/ResponseTests.cs @@ -36,6 +36,7 @@ namespace Microsoft.AspNet.Server.WebListener { var httpContext = new DefaultHttpContext((IFeatureCollection)env); Assert.Equal(200, httpContext.Response.StatusCode); + Assert.False(httpContext.Response.HeadersSent); return Task.FromResult(0); })) { diff --git a/test/Microsoft.Net.Http.Server.FunctionalTests/ResponseHeaderTests.cs b/test/Microsoft.Net.Http.Server.FunctionalTests/ResponseHeaderTests.cs index 3059532f5d..2fc83a613e 100644 --- a/test/Microsoft.Net.Http.Server.FunctionalTests/ResponseHeaderTests.cs +++ b/test/Microsoft.Net.Http.Server.FunctionalTests/ResponseHeaderTests.cs @@ -232,7 +232,9 @@ namespace Microsoft.Net.Http.Server responseHeaders.SetValues("Custom1", "value1a", "value1b"); responseHeaders.SetValues("Custom2", "value2a, value2b"); var body = context.Response.Body; + Assert.False(context.Response.HeadersSent); body.Flush(); + Assert.True(context.Response.HeadersSent); var ex = Assert.Throws(() => context.Response.StatusCode = 404); Assert.Equal("Headers already sent.", ex.Message); ex = Assert.Throws(() => responseHeaders.Add("Custom3", new string[] { "value3a, value3b", "value3c" })); @@ -266,7 +268,9 @@ namespace Microsoft.Net.Http.Server responseHeaders.SetValues("Custom1", "value1a", "value1b"); responseHeaders.SetValues("Custom2", "value2a, value2b"); var body = context.Response.Body; + Assert.False(context.Response.HeadersSent); await body.FlushAsync(); + Assert.True(context.Response.HeadersSent); var ex = Assert.Throws(() => context.Response.StatusCode = 404); Assert.Equal("Headers already sent.", ex.Message); ex = Assert.Throws(() => responseHeaders.Add("Custom3", new string[] { "value3a, value3b", "value3c" }));