#167 Prevent duplicate Content-Length headers

This commit is contained in:
Chris R 2016-08-31 14:09:17 -07:00
Родитель 6522926c22
Коммит 88114568b9
3 изменённых файлов: 15 добавлений и 20 удалений

Просмотреть файл

@ -338,11 +338,6 @@ namespace Microsoft.Net.Http.Server
_responseState = ResponseState.Started;
var reasonPhrase = GetReasonPhrase(StatusCode);
/*
if (m_BoundaryType==BoundaryType.Raw) {
use HTTP_SEND_RESPONSE_FLAG_RAW_HEADER;
}
*/
uint statusCode;
uint bytesSent;
List<GCHandle> pinnedHeaders = SerializeHeaders(isOpaqueUpgrade);
@ -414,7 +409,7 @@ namespace Microsoft.Net.Http.Server
return statusCode;
}
internal HttpApi.HTTP_FLAGS ComputeHeaders(bool endOfRequest = false)
internal HttpApi.HTTP_FLAGS ComputeHeaders(long writeCount, bool endOfRequest = false)
{
// 401
if (StatusCode == (ushort)HttpStatusCode.Unauthorized)
@ -456,6 +451,13 @@ namespace Microsoft.Net.Http.Server
_boundaryType = BoundaryType.ContentLength;
// ComputeLeftToWrite checks for HEAD requests when setting _leftToWrite
_expectedBodyLength = responseContentLength.Value;
if (responseContentLength.Value == writeCount && !isHeadRequest)
{
// A single write with the whole content-length. Http.Sys will set the content-length for us in this scenario.
// If we don't remove it then range requests served from cache will have two.
// https://github.com/aspnet/WebListener/issues/167
ContentLength = null;
}
}
else if (responseChunkedSet)
{
@ -495,7 +497,6 @@ namespace Microsoft.Net.Http.Server
flags = HttpApi.HTTP_FLAGS.HTTP_SEND_RESPONSE_FLAG_DISCONNECT;
}
Headers.IsReadOnly = true; // Prohibit further modifications.
return flags;
}
@ -511,12 +512,7 @@ namespace Microsoft.Net.Http.Server
HttpApi.HTTP_RESPONSE_INFO[] knownHeaderInfo = null;
List<GCHandle> pinnedHeaders;
GCHandle gcHandle;
/*
// here we would check for BoundaryType.Raw, in this case we wouldn't need to do anything
if (m_BoundaryType==BoundaryType.Raw) {
return null;
}
*/
if (Headers.Count == 0)
{
return null;

Просмотреть файл

@ -137,7 +137,7 @@ namespace Microsoft.Net.Http.Server
}
// Make sure all validation is performed before this computes the headers
var flags = ComputeLeftToWrite(endOfRequest);
var flags = ComputeLeftToWrite(data.Count, endOfRequest);
if (!_inOpaqueMode && endOfRequest && _leftToWrite > 0)
{
_requestContext.Abort();
@ -315,7 +315,7 @@ namespace Microsoft.Net.Http.Server
}
// Make sure all validation is performed before this computes the headers
var flags = ComputeLeftToWrite();
var flags = ComputeLeftToWrite(data.Count);
if (_leftToWrite != data.Count)
{
flags |= HttpApi.HTTP_FLAGS.HTTP_SEND_RESPONSE_FLAG_MORE_DATA;
@ -438,12 +438,12 @@ namespace Microsoft.Net.Http.Server
_requestContext.Abort();
}
private HttpApi.HTTP_FLAGS ComputeLeftToWrite(bool endOfRequest = false)
private HttpApi.HTTP_FLAGS ComputeLeftToWrite(long writeCount, bool endOfRequest = false)
{
var flags = HttpApi.HTTP_FLAGS.NONE;
if (!_requestContext.Response.HasComputedHeaders)
{
flags = _requestContext.Response.ComputeHeaders(endOfRequest);
flags = _requestContext.Response.ComputeHeaders(writeCount, endOfRequest);
}
if (_leftToWrite == long.MinValue)
{
@ -591,7 +591,7 @@ namespace Microsoft.Net.Http.Server
}
// Make sure all validation is performed before this computes the headers
var flags = ComputeLeftToWrite();
var flags = ComputeLeftToWrite(count.Value);
uint statusCode;
uint bytesSent = 0;
var chunked = _requestContext.Response.BoundaryType == BoundaryType.Chunked;

Просмотреть файл

@ -1000,8 +1000,7 @@ namespace Microsoft.Net.Http.Server
}
}
[ConditionalFact]
[FrameworkSkipCondition(RuntimeFrameworks.CoreCLR, SkipReason = "Cached response contains duplicate Content-Length headers (#167).")]
[Fact]
public async Task Caching_RequestRangeFromCachedFile_ServedFromCache()
{
string address;