-
Notifications
You must be signed in to change notification settings - Fork 10.4k
Don't send body in HEAD response when using PipeWriter.Advance before headers flushed #59725
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1426,12 +1426,15 @@ await connection.Receive( | |
$"Date: {server.Context.DateHeaderValue}", | ||
"", | ||
""); | ||
|
||
connection.ShutdownSend(); | ||
await connection.ReceiveEnd(); | ||
} | ||
} | ||
} | ||
|
||
[Fact] | ||
public async Task HeadResponseBodyNotWrittenWithAsyncWrite() | ||
public async Task HeadResponseHeadersWrittenWithAsyncWriteBeforeAppCompletes() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. aspnet/KestrelHttpServer#1204 changed some of the HEAD response tests to only check the response headers are flushed and doesn't fully check that the body doesn't exist. So split the test into two for the flushed headers check, and the lack of body check. |
||
{ | ||
var flushed = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); | ||
|
||
|
@@ -1461,8 +1464,68 @@ await connection.Receive( | |
} | ||
} | ||
|
||
[Fact] | ||
public async Task HeadResponseBodyNotWrittenWithAsyncWrite() | ||
{ | ||
await using (var server = new TestServer(async httpContext => | ||
{ | ||
httpContext.Response.ContentLength = 12; | ||
await httpContext.Response.WriteAsync("hello, world"); | ||
}, new TestServiceContext(LoggerFactory))) | ||
{ | ||
using (var connection = server.CreateConnection()) | ||
{ | ||
await connection.Send( | ||
"HEAD / HTTP/1.1", | ||
"Host:", | ||
"", | ||
""); | ||
await connection.Receive( | ||
"HTTP/1.1 200 OK", | ||
"Content-Length: 12", | ||
$"Date: {server.Context.DateHeaderValue}", | ||
"", | ||
""); | ||
|
||
connection.ShutdownSend(); | ||
await connection.ReceiveEnd(); | ||
} | ||
} | ||
} | ||
|
||
[Fact] | ||
public async Task HeadResponseBodyNotWrittenWithSyncWrite() | ||
{ | ||
var serviceContext = new TestServiceContext(LoggerFactory) { ServerOptions = { AllowSynchronousIO = true } }; | ||
|
||
await using (var server = new TestServer(httpContext => | ||
{ | ||
httpContext.Response.ContentLength = 12; | ||
httpContext.Response.Body.Write(Encoding.ASCII.GetBytes("hello, world"), 0, 12); | ||
return Task.CompletedTask; | ||
}, serviceContext)) | ||
{ | ||
using (var connection = server.CreateConnection()) | ||
{ | ||
await connection.Send( | ||
"HEAD / HTTP/1.1", | ||
"Host:", | ||
"", | ||
""); | ||
await connection.Receive( | ||
"HTTP/1.1 200 OK", | ||
"Content-Length: 12", | ||
$"Date: {server.Context.DateHeaderValue}", | ||
"", | ||
""); | ||
connection.ShutdownSend(); | ||
await connection.ReceiveEnd(); | ||
} | ||
} | ||
} | ||
|
||
[Fact] | ||
public async Task HeadResponseHeadersWrittenWithSyncWriteBeforeAppCompletes() | ||
{ | ||
var flushed = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); | ||
|
||
|
@@ -1471,7 +1534,7 @@ public async Task HeadResponseBodyNotWrittenWithSyncWrite() | |
await using (var server = new TestServer(async httpContext => | ||
{ | ||
httpContext.Response.ContentLength = 12; | ||
await httpContext.Response.BodyWriter.WriteAsync(new Memory<byte>(Encoding.ASCII.GetBytes("hello, world"), 0, 12)); | ||
httpContext.Response.Body.Write(Encoding.ASCII.GetBytes("hello, world"), 0, 12); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. #7110 removed the sync write which this test and |
||
await flushed.Task; | ||
}, serviceContext)) | ||
{ | ||
|
@@ -1494,6 +1557,88 @@ await connection.Receive( | |
} | ||
} | ||
|
||
[Fact] | ||
public async Task HeadResponseBodyNotWrittenWithAdvanceBeforeFlush() | ||
{ | ||
var serviceContext = new TestServiceContext(LoggerFactory) { ServerOptions = { AllowSynchronousIO = true } }; | ||
|
||
await using (var server = new TestServer(async httpContext => | ||
{ | ||
var span = httpContext.Response.BodyWriter.GetSpan(5); | ||
for (var i = 0; i < span.Length; i++) | ||
{ | ||
span[i] = (byte)'h'; | ||
} | ||
httpContext.Response.BodyWriter.Advance(span.Length); | ||
await httpContext.Response.BodyWriter.FlushAsync(); | ||
}, serviceContext)) | ||
{ | ||
using (var connection = server.CreateConnection()) | ||
{ | ||
await connection.Send( | ||
"HEAD / HTTP/1.1", | ||
"Host:", | ||
"", | ||
""); | ||
await connection.Receive( | ||
"HTTP/1.1 200 OK", | ||
$"Date: {server.Context.DateHeaderValue}", | ||
"Transfer-Encoding: chunked", | ||
"", | ||
""); | ||
|
||
connection.ShutdownSend(); | ||
await connection.ReceiveEnd(); | ||
} | ||
} | ||
} | ||
|
||
[Fact] | ||
public async Task HeadResponseBodyNotWrittenWithAdvanceBeforeAndAfterFlush() | ||
{ | ||
var serviceContext = new TestServiceContext(LoggerFactory) { ServerOptions = { AllowSynchronousIO = true } }; | ||
|
||
await using (var server = new TestServer(async httpContext => | ||
{ | ||
// Make response chunked | ||
var span = httpContext.Response.BodyWriter.GetSpan(5); | ||
for (var i = 0; i < span.Length; i++) | ||
{ | ||
span[i] = (byte)'h'; | ||
} | ||
httpContext.Response.BodyWriter.Advance(span.Length); | ||
await httpContext.Response.BodyWriter.FlushAsync(); | ||
|
||
// Send after headers flushed | ||
span = httpContext.Response.BodyWriter.GetSpan(5); | ||
for (var i = 0; i < span.Length; i++) | ||
{ | ||
span[i] = (byte)'h'; | ||
} | ||
httpContext.Response.BodyWriter.Advance(span.Length); | ||
await httpContext.Response.BodyWriter.FlushAsync(); | ||
}, serviceContext)) | ||
{ | ||
using (var connection = server.CreateConnection()) | ||
{ | ||
await connection.Send( | ||
"HEAD / HTTP/1.1", | ||
"Host:", | ||
"", | ||
""); | ||
await connection.Receive( | ||
"HTTP/1.1 200 OK", | ||
$"Date: {server.Context.DateHeaderValue}", | ||
"Transfer-Encoding: chunked", | ||
"", | ||
""); | ||
|
||
connection.ShutdownSend(); | ||
await connection.ReceiveEnd(); | ||
} | ||
} | ||
} | ||
|
||
[Fact] | ||
public async Task ZeroLengthWritesFlushHeaders() | ||
{ | ||
|
Uh oh!
There was an error while loading. Please reload this page.