Skip to content

Buffer HPACK parsing until the end of a header boundary#26700

Merged
ctiller merged 17 commits intogrpc:masterfrom
ctiller:hpack-buffering
Jul 28, 2021
Merged

Buffer HPACK parsing until the end of a header boundary#26700
ctiller merged 17 commits intogrpc:masterfrom
ctiller:hpack-buffering

Conversation

@ctiller
Copy link
Copy Markdown
Member

@ctiller ctiller commented Jul 15, 2021

HTTP2 headers are sent in (potentially) many frames, but all must be
sent sequentially with no traffic intervening.

This was not clear when I wrote the HPACK parser, and still indeed quite
contentious on the HTTP2 mailing lists.

Now that matter is well settled (years ago!) take advantage of the fact
by delaying parsing until all bytes are available.

A future change will leverage this to avoid having to store and verify
partial parse state, completely eliminating indirect calls within the
parser.

HTTP2 headers are sent in (potentially) many frames, but all must be
sent sequentially with no traffic intervening.

This was not clear when I wrote the HPACK parser, and still indeed quite
contentious on the HTTP2 mailing lists.

Now that matter is well settled (years ago!) take advantage of the fact
by delaying parsing until all bytes are available.

A future change will leverage this to avoid having to store and verify
partial parse state, completely eliminating indirect calls within the
parser.
@ctiller ctiller requested a review from yashykt July 15, 2021 22:36
@ctiller ctiller added the release notes: no Indicates if PR should not be in release notes label Jul 15, 2021
@ctiller
Copy link
Copy Markdown
Member Author

ctiller commented Jul 19, 2021

Test changes are usually ill advised to get a change through... so here are some notes on changes I made:

  • duplicate_headers wants to verify that we do not segfault on illegally duplicated headers, so verifying successful completion on some ops was over specifying the test.
  • large_metadata had previously sent a partial header fragment; under the new scheme such a partial header will not be parsed, and consequently not trigger the condition in question

@ctiller
Copy link
Copy Markdown
Member Author

ctiller commented Jul 19, 2021

@nicolasnoble @jtattermusch can you help me with why the tests don't seem to be running here?

@ctiller
Copy link
Copy Markdown
Member Author

ctiller commented Jul 20, 2021

Ok, looks like the tests are running again, fixed the last breakage I know of.

return {MakeSlice({0x40, 0x0b, 0x67, 0x72, 0x70, 0x63, 0x2d, 0x73,
0x74, 0x61, 0x74, 0x75, 0x73, 0x01, 0x30, 0x40,
0x0c, 0x67, 0x72, 0x70, 0x63, 0x2d, 0x6d, 0x65,
0x73, 0x73, 0x61, 0x67, 0x65, 0x00})};
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Side note: this has been broken for years and not doing a correct benchmark: grpc_slice_from_static_string totally stops at the trailing null byte, corrupting the stream.

@ctiller
Copy link
Copy Markdown
Member Author

ctiller commented Jul 21, 2021

Pinging on this for review

@ctiller ctiller mentioned this pull request Jul 26, 2021
"\x00\x00\x00\x04\x01\x00\x00\x00\x00" \
"\x00" \
"5{\x01\x05\x00\x00\x00\x01" \
"\x1aM\x01\x05\x00\x00\x00\x01" \
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

can you explain this change please?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The frame length was incorrect, meaning that this test would simply buffer and wait forever due to an incomplete request.

@ctiller
Copy link
Copy Markdown
Member Author

ctiller commented Jul 28, 2021

Known issues: #24375

@ctiller ctiller merged commit 8bab3e4 into grpc:master Jul 28, 2021
ctiller added a commit that referenced this pull request Jul 29, 2021
ctiller added a commit that referenced this pull request Jul 29, 2021
ctiller added a commit that referenced this pull request Aug 9, 2021
* Buffer HPACK parsing until the end of a header boundary

HTTP2 headers are sent in (potentially) many frames, but all must be
sent sequentially with no traffic intervening.

This was not clear when I wrote the HPACK parser, and still indeed quite
contentious on the HTTP2 mailing lists.

Now that matter is well settled (years ago!) take advantage of the fact
by delaying parsing until all bytes are available.

A future change will leverage this to avoid having to store and verify
partial parse state, completely eliminating indirect calls within the
parser.

* maybe fixes

* xx

* fix boundary detection

* clang-format

* Revert "xx"

This reverts commit 258d712.

* fix tests

* add missed check

* fixes

* fix

* update tests

* fix benchmark

* properly unref

* optimize final slice refcounting

* cleanup bm_chttp2_hpack

* start

* new parser progress

* refinement

* get it compiling

* bug-fix

* build files

* clang-tidy

* fixes

* fixes

* fixes

* fix-leaks

* clang-tidy

* comments

* fix merge error

* Revert "Buffer HPACK parsing until the end of a header boundary (#26700)"

This reverts commit 8bab3e4.

* streaming hpack parser start

* streaming parser

* clang-format

* Rework HPackTable into C++

* clang-tidy

* fix merge

* actually set the size of the entries array

* better
dennycd pushed a commit to dennycd/grpc that referenced this pull request Aug 10, 2021
* Buffer HPACK parsing until the end of a header boundary

HTTP2 headers are sent in (potentially) many frames, but all must be
sent sequentially with no traffic intervening.

This was not clear when I wrote the HPACK parser, and still indeed quite
contentious on the HTTP2 mailing lists.

Now that matter is well settled (years ago!) take advantage of the fact
by delaying parsing until all bytes are available.

A future change will leverage this to avoid having to store and verify
partial parse state, completely eliminating indirect calls within the
parser.

* maybe fixes

* xx

* fix boundary detection

* clang-format

* Revert "xx"

This reverts commit 258d712.

* fix tests

* add missed check

* fixes

* fix

* update tests

* fix benchmark

* properly unref

* optimize final slice refcounting

* cleanup bm_chttp2_hpack

* start

* new parser progress

* refinement

* get it compiling

* bug-fix

* build files

* clang-tidy

* fixes

* fixes

* fixes

* fix-leaks

* clang-tidy

* comments

* fix merge error

* Revert "Buffer HPACK parsing until the end of a header boundary (grpc#26700)"

This reverts commit 8bab3e4.

* streaming hpack parser start

* streaming parser

* clang-format

* Rework HPackTable into C++

* clang-tidy

* fix merge

* actually set the size of the entries array

* better
Vignesh2208 pushed a commit to Vignesh2208/grpc that referenced this pull request Aug 20, 2021
Vignesh2208 pushed a commit to Vignesh2208/grpc that referenced this pull request Aug 20, 2021
* Buffer HPACK parsing until the end of a header boundary

HTTP2 headers are sent in (potentially) many frames, but all must be
sent sequentially with no traffic intervening.

This was not clear when I wrote the HPACK parser, and still indeed quite
contentious on the HTTP2 mailing lists.

Now that matter is well settled (years ago!) take advantage of the fact
by delaying parsing until all bytes are available.

A future change will leverage this to avoid having to store and verify
partial parse state, completely eliminating indirect calls within the
parser.

* maybe fixes

* xx

* fix boundary detection

* clang-format

* Revert "xx"

This reverts commit 258d712.

* fix tests

* add missed check

* fixes

* fix

* update tests

* fix benchmark

* properly unref

* optimize final slice refcounting

* cleanup bm_chttp2_hpack

* start

* new parser progress

* refinement

* get it compiling

* bug-fix

* build files

* clang-tidy

* fixes

* fixes

* fixes

* fix-leaks

* clang-tidy

* comments

* fix merge error

* Revert "Buffer HPACK parsing until the end of a header boundary (grpc#26700)"

This reverts commit 8bab3e4.

* streaming hpack parser start

* streaming parser

* clang-format

* Rework HPackTable into C++

* clang-tidy

* fix merge

* actually set the size of the entries array

* better
lidizheng pushed a commit to lidizheng/grpc that referenced this pull request Sep 23, 2021
HTTP2 headers are sent in (potentially) many frames, but all must be
sent sequentially with no traffic intervening.

This was not clear when I wrote the HPACK parser, and still indeed quite
contentious on the HTTP2 mailing lists.

Now that matter is well settled (years ago!) take advantage of the fact
by delaying parsing until all bytes are available.

A future change will leverage this to avoid having to store and verify
partial parse state, completely eliminating indirect calls within the
parser.
lidizheng pushed a commit to lidizheng/grpc that referenced this pull request Sep 23, 2021
lidizheng pushed a commit to lidizheng/grpc that referenced this pull request Sep 23, 2021
* Buffer HPACK parsing until the end of a header boundary

HTTP2 headers are sent in (potentially) many frames, but all must be
sent sequentially with no traffic intervening.

This was not clear when I wrote the HPACK parser, and still indeed quite
contentious on the HTTP2 mailing lists.

Now that matter is well settled (years ago!) take advantage of the fact
by delaying parsing until all bytes are available.

A future change will leverage this to avoid having to store and verify
partial parse state, completely eliminating indirect calls within the
parser.

* maybe fixes

* xx

* fix boundary detection

* clang-format

* Revert "xx"

This reverts commit 258d712.

* fix tests

* add missed check

* fixes

* fix

* update tests

* fix benchmark

* properly unref

* optimize final slice refcounting

* cleanup bm_chttp2_hpack

* start

* new parser progress

* refinement

* get it compiling

* bug-fix

* build files

* clang-tidy

* fixes

* fixes

* fixes

* fix-leaks

* clang-tidy

* comments

* fix merge error

* Revert "Buffer HPACK parsing until the end of a header boundary (grpc#26700)"

This reverts commit 8bab3e4.

* streaming hpack parser start

* streaming parser

* clang-format

* Rework HPackTable into C++

* clang-tidy

* fix merge

* actually set the size of the entries array

* better
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release notes: no Indicates if PR should not be in release notes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants