-
Notifications
You must be signed in to change notification settings - Fork 802
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
Throw on wrong Content-Length #1462
Throw on wrong Content-Length #1462
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good overall, just left some minor comments
Co-authored-by: Miha Zupan <mihazupan.zupan1@gmail.com>
@@ -406,6 +406,7 @@ private static void RestoreUpgradeHeaders(HttpContext context, HttpRequestMessag | |||
// but for now, out of an abundance of caution, we only do it for requests that look like gRPC. | |||
return new StreamCopyHttpContent( | |||
source: request.Body, | |||
contentLength: request.Headers.ContentLength, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a scenario where we don't copy the Content-Length:
reverse-proxy/src/ReverseProxy/Forwarder/HttpTransformer.cs
Lines 61 to 73 in 6eba401
// https://datatracker.ietf.org/doc/html/rfc7230#section-3.3.3 | |
// If a message is received with both a Transfer-Encoding and a | |
// Content-Length header field, the Transfer-Encoding overrides the | |
// Content-Length. Such a message might indicate an attempt to | |
// perform request smuggling (Section 9.5) or response splitting | |
// (Section 9.4) and ought to be handled as an error. A sender MUST | |
// remove the received Content-Length field prior to forwarding such | |
// a message downstream. | |
if (httpContext.Request.Headers.ContainsKey(HeaderNames.TransferEncoding) | |
&& httpContext.Request.Headers.ContainsKey(HeaderNames.ContentLength)) | |
{ | |
proxyRequest.Content?.Headers.Remove(HeaderNames.ContentLength); | |
} |
Can StreamCopyHttpContent capture the ContentLength from its own headers on start?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I considered it but StreamCopyHttpContent
get it before transformation (step 2 vs step 3):
reverse-proxy/src/ReverseProxy/Forwarder/HttpForwarder.cs
Lines 287 to 293 in cde14a6
// :: Step 2: Setup copy of request body (background) Client --► Proxy --► Destination | |
// Note that we must do this before step (3) because step (3) may also add headers to the HttpContent that we set up here. | |
var requestContent = SetupRequestBodyCopy(context.Request, isStreamingRequest, activityToken); | |
destinationRequest.Content = requestContent; | |
// :: Step 3: Copy request headers Client --► Proxy --► Destination | |
await transformer.TransformRequestAsync(context, destinationRequest, destinationPrefix); |
Did I miss something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're correct on the ordering, but you can capture the header at the start of SerializeToStreamAsync, you don't need it in the constructor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it, I moved capturing out of the constructor.
Looks good overall. My comments are mostly style and flow. |
Co-authored-by: Chris Ross <Tratcher@Outlook.com>
Co-authored-by: Chris Ross <Tratcher@Outlook.com>
Co-authored-by: Chris Ross <Tratcher@Outlook.com>
Fixes #1412
Throwing an exception when
Content-Length
is set but doesn't match with actual length in request. This allows to avoid unclear hangings as described in the issue above.