-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
Improve HTTP/1 response header parsing #74393
Conversation
Tagging subscribers to this area: @dotnet/ncl Issue DetailsBased on the "portable" implementation from @scalablecory's PR #63295. Sending in-memory (no I/O) requests and parsing the response:
|
/azp run runtime-libraries-coreclr outerloop |
Azure Pipelines successfully started running 1 pipeline(s). |
6e51403
to
7804b82
Compare
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.
LGTM!
Test failure is #74795 |
@stephentoub could you please take a look at this one if you get a chance, given there was quite a bit of discussion on the original PR introducing these sorts of changes (#63295). |
src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnection.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnection.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnection.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnection.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnection.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnection.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnection.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnection.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnection.cs
Outdated
Show resolved
Hide resolved
@dotnet/ncl can someone please take a look at this one? |
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.
LGTM, but it will be better if @stephentoub could take another look...
int pos = 0; | ||
while (line[pos] != (byte)':' && line[pos] != (byte)' ') | ||
int bytesScanned = finished ? bytesConsumed : buffer.Length; | ||
if (_allowedReadLineBytes < bytesScanned) |
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.
Why is this check <
but the one at https://github.com/dotnet/runtime/pull/74393/files#diff-595f700a4c83b735d856fe14b5ebe8c7f7c18ae6e586adc8b398a997a0678274R997 which may also be comparing against buffer.Length uses <=
?
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.
When we check <=
above, it's after we've determined that we must read more data in order to make progress. If we're already equal to the limit, there's no point in trying to read again as we'll definitely go over the limit.
Here we check <
because we may already be done with reading. If the response headers happened to consume exactly _allowedReadLineBytes
, we don't throw as we technically didn't go over the limit.
More accurately, this check could be
if (finished ? (_allowedReadLineBytes < bytesConsumed) : (_allowedReadLineBytes <= buffer.Length))
though I don't think it matters either way. Both of the checks could be <
or <=
and we'd just be playing with +/- 1 on the limit (which is controlled in KB anyway).
else | ||
{ | ||
ThrowForEmptyHeaderName(); | ||
} | ||
} |
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.
This looks like a really slow way to trim ending whitespace. Do we not expect any?
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.
(Also it's only looking for ' '... other whitespace doesn't matter?)
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.
The expected hot path is that there are no trailing spaces.
(Also it's only looking for ' '... other whitespace doesn't matter?)
This matches the existing behavior.
According to the spec, the name shouldn't have trailing whitespace at all
field-line = field-name ":" OWS field-value OWS
We also trim the whitespace around the value. We trim leading SP and HTAB, but only trailing SP.
I think it's fine that we're more accepting on the name, but it's odd that we differ for leading/trailing OWS on the value.
Opened #77001
b62e86b
to
7be0a23
Compare
Based on the "portable" implementation from @scalablecory's PR #63295.
This PR does not include the Avx2-vectorized parsing code.
Sending in-memory (no I/O) requests and parsing the response: