Skip to content
This repository was archived by the owner on Dec 18, 2018. It is now read-only.

Reject POST and PUT requests with no Content-Length or Transfer-Encoding (#1130) #1193

Merged
merged 1 commit into from
Nov 5, 2016

Conversation

cesarblum
Copy link
Contributor

{
long contentLength;
if (!long.TryParse(unparsedContentLength, out contentLength) || contentLength < 0)
if (!long.TryParse(unparsedContentLength.ToString(), out contentLength) || contentLength < 0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought we were going to change this to use your new FrameHeaders.UseContentLength method.

@@ -280,6 +281,13 @@ protected virtual void OnConsumedBytes(int count)
}
}

// If we got here, request contains no Content-Length or Transfer-Encoding header.
// Reject with 411 Length Required.
if (HttpMethods.IsPost(context.Method) || HttpMethods.IsPut(context.Method))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No user code has run at this point. Do a strict reference equals.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Were there any other methods you considered requiring a content length for?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope. IIS and nginx seem to require a length only for POST and PUT, so I'm doing the same here.

@@ -196,13 +196,29 @@ public void ForThrowsWhenFinalTransferCodingIsNotChunked()
using (var input = new TestInput())
{
var ex = Assert.Throws<BadHttpRequestException>(() =>
MessageBody.For(HttpVersion.Http10, new FrameRequestHeaders { HeaderTransferEncoding = "chunked, not-chunked" }, input.FrameContext));
MessageBody.For(HttpVersion.Http11, new FrameRequestHeaders { HeaderTransferEncoding = "chunked, not-chunked" }, input.FrameContext));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did this change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically an HTTP/1.0 request shouldn't be chunked. Not sure we want to change this to reject such requests - we can an open an issue for it though.

{
input.FrameContext.Method = method;
var ex = Assert.Throws<BadHttpRequestException>(() =>
MessageBody.For(HttpVersion.Http11, new FrameRequestHeaders(), input.FrameContext));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we test this for HTTP/1.0 too?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. I've checked the HTTP/1.0 spec and we have to respond with a 400 in case it's HTTP/1.0 - there's no 411 status code in HTTP/1.0.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a request
contains an entity body and Content-Length is not specified, and the
server does not recognize or cannot calculate the length from other
fields, then the server should send a 400 (bad request) response.

https://tools.ietf.org/html/rfc1945#section-7.2.2

@cesarblum
Copy link
Contributor Author

@halter73 Updated with early check for != GET.

@halter73
Copy link
Member

halter73 commented Nov 4, 2016

Both travis builds are failing with "Block being garbage collected instead of returned to pool: IncomingStart, /Users/travis/build/aspnet/KestrelHttpServer/src/Microsoft.AspNetCore.Server.Kestrel/Internal/Http/SocketInput.cs, 66"

https://travis-ci.org/aspnet/KestrelHttpServer/builds/173249429

[Theory]
[InlineData("POST")]
[InlineData("PUT")]
public void ForThrowsWhenMethodRequiresLengthButNoContentLengthSetHttp10(string method)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My guess is that this test is throwing causing the block to be leaked.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Never mind this issue repros in the dev branch. I found your issue #1195.

@cesarblum
Copy link
Contributor Author

Opened https://github.com/dotnet/corefx/issues/13369 to track test failures caused by hang on 0-byte async write to SslStream.

@cesarblum cesarblum force-pushed the cesarbs/reject-requests-no-length branch from 6a40315 to 7f1ffa0 Compare November 4, 2016 23:00
@cesarblum
Copy link
Contributor Author

Rebased with b3aca04.

@cesarblum cesarblum force-pushed the cesarbs/reject-requests-no-length branch from 7f1ffa0 to a1c5987 Compare November 5, 2016 01:05
@cesarblum cesarblum merged commit a1c5987 into dev Nov 5, 2016
@cesarblum cesarblum deleted the cesarbs/reject-requests-no-length branch November 5, 2016 01:27
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants