Allow Content-Length 0 for Websocket-Connection (#2217)
This commit is contained in:
parent
7fde08d6fb
commit
9a8dd6ef12
|
|
@ -230,6 +230,16 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
keepAlive = (connectionOptions & ConnectionOptions.KeepAlive) == ConnectionOptions.KeepAlive;
|
keepAlive = (connectionOptions & ConnectionOptions.KeepAlive) == ConnectionOptions.KeepAlive;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (upgrade)
|
||||||
|
{
|
||||||
|
if (headers.HeaderTransferEncoding.Count > 0 || (headers.ContentLength.HasValue && headers.ContentLength.Value != 0))
|
||||||
|
{
|
||||||
|
context.ThrowRequestRejected(RequestRejectionReason.UpgradeRequestCannotHavePayload);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ForUpgrade(context);
|
||||||
|
}
|
||||||
|
|
||||||
var transferEncoding = headers.HeaderTransferEncoding;
|
var transferEncoding = headers.HeaderTransferEncoding;
|
||||||
if (transferEncoding.Count > 0)
|
if (transferEncoding.Count > 0)
|
||||||
{
|
{
|
||||||
|
|
@ -246,11 +256,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
context.ThrowRequestRejected(RequestRejectionReason.FinalTransferCodingNotChunked, transferEncoding.ToString());
|
context.ThrowRequestRejected(RequestRejectionReason.FinalTransferCodingNotChunked, transferEncoding.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (upgrade)
|
|
||||||
{
|
|
||||||
context.ThrowRequestRejected(RequestRejectionReason.UpgradeRequestCannotHavePayload);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new ForChunkedEncoding(keepAlive, context);
|
return new ForChunkedEncoding(keepAlive, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -262,10 +267,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
{
|
{
|
||||||
return keepAlive ? MessageBody.ZeroContentLengthKeepAlive : MessageBody.ZeroContentLengthClose;
|
return keepAlive ? MessageBody.ZeroContentLengthKeepAlive : MessageBody.ZeroContentLengthClose;
|
||||||
}
|
}
|
||||||
else if (upgrade)
|
|
||||||
{
|
|
||||||
context.ThrowRequestRejected(RequestRejectionReason.UpgradeRequestCannotHavePayload);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new ForContentLength(keepAlive, contentLength, context);
|
return new ForContentLength(keepAlive, contentLength, context);
|
||||||
}
|
}
|
||||||
|
|
@ -282,11 +283,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (upgrade)
|
|
||||||
{
|
|
||||||
return new ForUpgrade(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
return keepAlive ? MessageBody.ZeroContentLengthKeepAlive : MessageBody.ZeroContentLengthClose;
|
return keepAlive ? MessageBody.ZeroContentLengthKeepAlive : MessageBody.ZeroContentLengthClose;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -503,6 +503,32 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task PumpAsyncDoesNotReturnAfterCancelingInput()
|
public async Task PumpAsyncDoesNotReturnAfterCancelingInput()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue