Skip to content

Account for promised stream ID when fragmenting PUSH_PROMISE - #1338

Open
AryanRG wants to merge 1 commit into
python-hyper:masterfrom
AryanRG:fix/push-promise-frame-size
Open

AryanRG wants to merge 1 commit into
python-hyper:masterfrom
AryanRG:fix/push-promise-frame-size

Conversation

@AryanRG

@AryanRG AryanRG commented Oct 16, 2026 •

Copy link
Copy Markdown

Large pushed request headers can make H2Connection.push_stream() raise AssertionError even when the header list is below the peer's limit. _build_headers_frames() gives the first PUSH_PROMISE a full frame's worth of HPACK data, then serialization adds the four-byte promised stream ID, exceeding SETTINGS_MAX_FRAME_SIZE. With assertions disabled, the oversized frame reaches the peer and is rejected instead.

Reserve those four bytes in the first fragment, while allowing each CONTINUATION to use the full frame payload. This follows RFC 9113 sections 4.2 and 6.6.

The regression uses two h2 peers with the default 16,384-byte limit. Six cases cover small headers, the first-fragment boundary, a one-byte overflow, the full-frame boundary, and multiple continuations. It checks serialized frame sizes, stream IDs, END_HEADERS placement, HPACK byte preservation, and the receiving client's PushedStreamReceived event.

Validation on macOS, CPython 3.13.12:

  • Baseline: 1,662 passed, 100% line and branch coverage.
  • New regression before the fix: 4 failed, 2 passed; failures are the outbound size assertion.
  • New regression plus adjacent complex-logic, priority, and header-indexing tests after the fix: 380 passed.
  • Full suite after the fix: 1,668 passed, 100% line and branch coverage (python -bb -m pytest --cov=h2 --cov-report=term --cov-report=xml).
  • ruff check src/ tests/test_push_promise_fragmentation.py and mypy --strict-bytes src/ tests/typing/strict_bytes.py pass.
  • The full multi-Python tox matrix and h2spec were not run locally.

AI assistance was used to prepare the implementation and regression tests.

Reserve four bytes in the initial frame and keep full-size CONTINUATION fragments. Add boundary and peer round-trip regressions.

AI disclosure: discovered, implemented, tested, and independently AI-reviewed by Codex AI agents at the account owner request.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant