Add new HeadersSent API.

This commit is contained in:
Chris Ross 2014-10-30 12:11:34 -07:00
parent ff0714fe6a
commit f6c1a559a0
8 changed files with 25 additions and 11 deletions

View File

@ -348,6 +348,11 @@ namespace Microsoft.AspNet.Server.WebListener
set { _responseHeaders = value; } set { _responseHeaders = value; }
} }
bool IHttpResponseFeature.HeadersSent
{
get { return Response.HeadersSent; }
}
void IHttpResponseFeature.OnSendingHeaders(Action<object> callback, object state) void IHttpResponseFeature.OnSendingHeaders(Action<object> callback, object state)
{ {
Response.OnSendingHeaders(callback, state); Response.OnSendingHeaders(callback, state);

View File

@ -168,7 +168,7 @@ namespace Microsoft.AspNet.Server.WebListener
catch (Exception ex) catch (Exception ex)
{ {
LogHelper.LogException(_logger, "ProcessRequestAsync", ex); LogHelper.LogException(_logger, "ProcessRequestAsync", ex);
if (requestContext.Response.SentHeaders) if (requestContext.Response.HeadersSent)
{ {
requestContext.Abort(); requestContext.Abort();
} }

View File

@ -145,7 +145,7 @@ namespace Microsoft.Net.Http.Server
public Task<Stream> UpgradeAsync() public Task<Stream> UpgradeAsync()
{ {
if (!IsUpgradableRequest || _response.SentHeaders) if (!IsUpgradableRequest || _response.HeadersSent)
{ {
throw new InvalidOperationException(); throw new InvalidOperationException();
} }

View File

@ -297,7 +297,7 @@ namespace Microsoft.Net.Http.Server
} }
} }
public bool SentHeaders public bool HeadersSent
{ {
get get
{ {
@ -356,7 +356,7 @@ namespace Microsoft.Net.Http.Server
UnsafeNclNativeMethods.HttpApi.HTTP_FLAGS flags, UnsafeNclNativeMethods.HttpApi.HTTP_FLAGS flags,
bool isOpaqueUpgrade) bool isOpaqueUpgrade)
{ {
Debug.Assert(!SentHeaders, "HttpListenerResponse::SendHeaders()|SentHeaders is true."); Debug.Assert(!HeadersSent, "HttpListenerResponse::SendHeaders()|SentHeaders is true.");
// TODO: Verbose log headers // TODO: Verbose log headers
_responseState = ResponseState.SentHeaders; _responseState = ResponseState.SentHeaders;

View File

@ -94,7 +94,7 @@ namespace Microsoft.Net.Http.Server
// Send headers // Send headers
public override void Flush() public override void Flush()
{ {
if (_closed || _requestContext.Response.SentHeaders) if (_closed || _requestContext.Response.HeadersSent)
{ {
return; return;
} }
@ -127,7 +127,7 @@ namespace Microsoft.Net.Http.Server
// Send headers // Send headers
public override Task FlushAsync(CancellationToken cancellationToken) public override Task FlushAsync(CancellationToken cancellationToken)
{ {
if (_closed || _requestContext.Response.SentHeaders) if (_closed || _requestContext.Response.HeadersSent)
{ {
return Helpers.CompletedTask(); return Helpers.CompletedTask();
} }
@ -275,7 +275,7 @@ namespace Microsoft.Net.Http.Server
uint dataToWrite = (uint)size; uint dataToWrite = (uint)size;
SafeLocalFree bufferAsIntPtr = null; SafeLocalFree bufferAsIntPtr = null;
IntPtr pBufferAsIntPtr = IntPtr.Zero; IntPtr pBufferAsIntPtr = IntPtr.Zero;
bool sentHeaders = _requestContext.Response.SentHeaders; bool sentHeaders = _requestContext.Response.HeadersSent;
try try
{ {
if (size == 0) if (size == 0)
@ -398,7 +398,7 @@ namespace Microsoft.Net.Http.Server
uint statusCode; uint statusCode;
uint bytesSent = 0; uint bytesSent = 0;
flags |= _leftToWrite == size ? UnsafeNclNativeMethods.HttpApi.HTTP_FLAGS.NONE : UnsafeNclNativeMethods.HttpApi.HTTP_FLAGS.HTTP_SEND_RESPONSE_FLAG_MORE_DATA; 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); 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. // 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 statusCode;
uint bytesSent = 0; uint bytesSent = 0;
flags |= _leftToWrite == size ? UnsafeNclNativeMethods.HttpApi.HTTP_FLAGS.NONE : UnsafeNclNativeMethods.HttpApi.HTTP_FLAGS.HTTP_SEND_RESPONSE_FLAG_MORE_DATA; 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); 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. // 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 statusCode;
uint bytesSent = 0; uint bytesSent = 0;
flags |= _leftToWrite == size ? UnsafeNclNativeMethods.HttpApi.HTTP_FLAGS.NONE : UnsafeNclNativeMethods.HttpApi.HTTP_FLAGS.HTTP_SEND_RESPONSE_FLAG_MORE_DATA; 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, ResponseStreamAsyncResult asyncResult = new ResponseStreamAsyncResult(this, null, null, fileName, offset, size,
_requestContext.Response.BoundaryType == BoundaryType.Chunked, sentHeaders, cancellationRegistration); _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."); LogHelper.LogError(_requestContext.Logger, "ResponseStream::Dispose", "Fewer bytes were written than were specified in the Content-Length.");
return; return;
} }
bool sentHeaders = _requestContext.Response.SentHeaders; bool sentHeaders = _requestContext.Response.HeadersSent;
if (sentHeaders && _leftToWrite == 0) if (sentHeaders && _leftToWrite == 0)
{ {
return; return;

View File

@ -245,7 +245,9 @@ namespace Microsoft.AspNet.Server.WebListener
responseHeaders.Add("Custom1", new string[] { "value1a", "value1b" }); responseHeaders.Add("Custom1", new string[] { "value1a", "value1b" });
responseHeaders.Add("Custom2", new string[] { "value2a, value2b" }); responseHeaders.Add("Custom2", new string[] { "value2a, value2b" });
var body = responseInfo.Body; var body = responseInfo.Body;
Assert.False(responseInfo.HeadersSent);
body.Flush(); body.Flush();
Assert.True(responseInfo.HeadersSent);
Assert.Throws<InvalidOperationException>(() => responseInfo.StatusCode = 404); Assert.Throws<InvalidOperationException>(() => responseInfo.StatusCode = 404);
Assert.Throws<InvalidOperationException>(() => responseHeaders.Add("Custom3", new string[] { "value3a, value3b", "value3c" })); Assert.Throws<InvalidOperationException>(() => responseHeaders.Add("Custom3", new string[] { "value3a, value3b", "value3c" }));
return Task.FromResult(0); return Task.FromResult(0);
@ -275,7 +277,9 @@ namespace Microsoft.AspNet.Server.WebListener
responseHeaders.Add("Custom1", new string[] { "value1a", "value1b" }); responseHeaders.Add("Custom1", new string[] { "value1a", "value1b" });
responseHeaders.Add("Custom2", new string[] { "value2a, value2b" }); responseHeaders.Add("Custom2", new string[] { "value2a, value2b" });
var body = responseInfo.Body; var body = responseInfo.Body;
Assert.False(responseInfo.HeadersSent);
await body.FlushAsync(); await body.FlushAsync();
Assert.True(responseInfo.HeadersSent);
Assert.Throws<InvalidOperationException>(() => responseInfo.StatusCode = 404); Assert.Throws<InvalidOperationException>(() => responseInfo.StatusCode = 404);
Assert.Throws<InvalidOperationException>(() => responseHeaders.Add("Custom3", new string[] { "value3a, value3b", "value3c" })); Assert.Throws<InvalidOperationException>(() => responseHeaders.Add("Custom3", new string[] { "value3a, value3b", "value3c" }));
})) }))

View File

@ -36,6 +36,7 @@ namespace Microsoft.AspNet.Server.WebListener
{ {
var httpContext = new DefaultHttpContext((IFeatureCollection)env); var httpContext = new DefaultHttpContext((IFeatureCollection)env);
Assert.Equal(200, httpContext.Response.StatusCode); Assert.Equal(200, httpContext.Response.StatusCode);
Assert.False(httpContext.Response.HeadersSent);
return Task.FromResult(0); return Task.FromResult(0);
})) }))
{ {

View File

@ -232,7 +232,9 @@ namespace Microsoft.Net.Http.Server
responseHeaders.SetValues("Custom1", "value1a", "value1b"); responseHeaders.SetValues("Custom1", "value1a", "value1b");
responseHeaders.SetValues("Custom2", "value2a, value2b"); responseHeaders.SetValues("Custom2", "value2a, value2b");
var body = context.Response.Body; var body = context.Response.Body;
Assert.False(context.Response.HeadersSent);
body.Flush(); body.Flush();
Assert.True(context.Response.HeadersSent);
var ex = Assert.Throws<InvalidOperationException>(() => context.Response.StatusCode = 404); var ex = Assert.Throws<InvalidOperationException>(() => context.Response.StatusCode = 404);
Assert.Equal("Headers already sent.", ex.Message); Assert.Equal("Headers already sent.", ex.Message);
ex = Assert.Throws<InvalidOperationException>(() => responseHeaders.Add("Custom3", new string[] { "value3a, value3b", "value3c" })); ex = Assert.Throws<InvalidOperationException>(() => responseHeaders.Add("Custom3", new string[] { "value3a, value3b", "value3c" }));
@ -266,7 +268,9 @@ namespace Microsoft.Net.Http.Server
responseHeaders.SetValues("Custom1", "value1a", "value1b"); responseHeaders.SetValues("Custom1", "value1a", "value1b");
responseHeaders.SetValues("Custom2", "value2a, value2b"); responseHeaders.SetValues("Custom2", "value2a, value2b");
var body = context.Response.Body; var body = context.Response.Body;
Assert.False(context.Response.HeadersSent);
await body.FlushAsync(); await body.FlushAsync();
Assert.True(context.Response.HeadersSent);
var ex = Assert.Throws<InvalidOperationException>(() => context.Response.StatusCode = 404); var ex = Assert.Throws<InvalidOperationException>(() => context.Response.StatusCode = 404);
Assert.Equal("Headers already sent.", ex.Message); Assert.Equal("Headers already sent.", ex.Message);
ex = Assert.Throws<InvalidOperationException>(() => responseHeaders.Add("Custom3", new string[] { "value3a, value3b", "value3c" })); ex = Assert.Throws<InvalidOperationException>(() => responseHeaders.Add("Custom3", new string[] { "value3a, value3b", "value3c" }));