Skip to content

Require an absolute :path in HTTP/2 requests - #1484

Merged
quinnj merged 3 commits into
masterfrom
claude/h2-path-validation
Oct 22, 2026
Merged

quinnj merged 3 commits into
masterfrom
claude/h2-path-validation

Conversation

@quinnj

@quinnj quinnj commented Oct 22, 2026

Copy link
Copy Markdown
Member

RFC 9113 §8.3.1: :path carries the absolute path (and query) of the request target, or * for an OPTIONS request. The HTTP/2 server accepted any :path:

  • An empty :path reached the Request constructor, which threw ArgumentError("target must not be empty"). The client got RST_STREAM(INTERNAL_ERROR), and the server logged h2 server could not send the response at Error level. Any client could add an error record that way.
  • A :path such as abc or http://example.com/ was passed to the handler. HTTP/1 answers the same request target with 400.

Both are now malformed requests, rejected by _validate_h2_request_headers! like the other invalid pseudo-headers: GOAWAY(PROTOCOL_ERROR), nothing logged. * is accepted only with OPTIONS.

Verification

  • The pseudo-header validation testset checks that an empty :path, abc, an absolute URI, and * with GET are rejected, and that * with OPTIONS is accepted. On master the four rejections fail.
  • Real server: master answers an empty :path with RST_STREAM(2) plus one error log and serves abc with 200. Here both get GOAWAY(PROTOCOL_ERROR) and no log; /ok is still served.
  • The pseudo-header, CONNECT, edge-case, and invalid-header testsets of test/http2_server_tests.jl pass (39/39) on Julia 1.12.

Review

  • Clients: the HTTP.jl HTTP/2 client sends the request target as :path, which starts with / (or is * for OPTIONS *), and sends no :path for CONNECT, so its requests are unaffected.
  • CONNECT: the check sits in the :path branch, and CONNECT requests with a :path were already rejected.
  • Values: the value is checked after the same normalization and whitespace check as before.

🤖 Generated with Claude Code

quinnj added a commit that referenced this pull request Oct 22, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
quinnj and others added 2 commits October 22, 2026 03:01
RFC 9113 §8.3.1: :path is the absolute path (and query) of the target, or
`*` for an OPTIONS request. The server accepted any value. An empty :path
reached the Request constructor, which threw, so the client got
RST_STREAM(INTERNAL_ERROR) and the server logged "h2 server could not send
the response" for a malformed request. A :path such as "abc" was served,
though HTTP/1 answers the same target with 400. Both are now malformed
requests, rejected like the other invalid pseudo-headers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@quinnj
quinnj force-pushed the claude/h2-path-validation branch from dbea3da to bb40914 Compare October 22, 2026 09:01
@codecov

codecov Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.60%. Comparing base (2d7a024) to head (bb40914).
⚠️ Report is 32 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1484      +/-   ##
==========================================
+ Coverage   91.58%   91.60%   +0.01%     
==========================================
  Files          31       31              
  Lines       13051    13053       +2     
==========================================
+ Hits        11953    11957       +4     
+ Misses       1098     1096       -2     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@quinnj
quinnj merged commit e5c668a into master Oct 22, 2026
0 of 8 checks passed
@quinnj
quinnj deleted the claude/h2-path-validation branch October 22, 2026 12:35
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