Skip to content

fix(proxy): concatenate HTTP/2 Cookie headers when proxying to HTTP/1.1 (RFC 9113 §8.2.3)#901

Open
MyLittleLuckyDog wants to merge 2 commits into
cloudflare:mainfrom
MyLittleLuckyDog:fix/h2-cookie-concat-rfc9113
Open

fix(proxy): concatenate HTTP/2 Cookie headers when proxying to HTTP/1.1 (RFC 9113 §8.2.3)#901
MyLittleLuckyDog wants to merge 2 commits into
cloudflare:mainfrom
MyLittleLuckyDog:fix/h2-cookie-concat-rfc9113

Conversation

@MyLittleLuckyDog
Copy link
Copy Markdown

Summary

Implements Cookie header concatenation when proxying HTTP/2 requests to HTTP/1.1 upstreams, as required by RFC 9113 §8.2.3.

Fixes #892

Problem

When a browser sends cookies over HTTP/2, it may split them into separate Cookie header fields for better HPACK compression (permitted by RFC 9113 §8.2.3). Pingora currently forwards these as separate header lines to HTTP/1.1 upstreams. Many backends only read the first Cookie header, causing session cookies to be silently dropped — leading to failures such as CSRF token verification errors (HTTP 422 on GitLab, for example).

Changes

  • pingora-proxy/src/proxy_h1.rs: Add h2_to_h1_concat_cookie_headers() that merges multiple Cookie headers into one using "; " as delimiter, preserving insertion order. Called during H2→H1 conversion in proxy_1to1().
  • pingora-core/src/upstreams/peer.rs: Add PeerOptions.h2_to_h1_concat_cookies flag (default: true) to allow disabling the behavior if needed.

Test plan

  • test_concat_multiple_cookies — 3 cookies merged correctly
  • test_concat_preserves_order — GitLab CSRF scenario (order preserved)
  • test_concat_single_cookie_unchanged — single cookie untouched
  • test_concat_no_cookies_is_noop — no cookies, no changes
  • test_concat_two_cookies — 2 cookies merged, result is exactly 1 header
  • test_concat_cookies_with_semicolons — cookie values already containing ; handled correctly
  • cargo check -p pingora-proxy -p pingora-core passes
  • All 6 new tests pass

Jaeuk ryu and others added 2 commits June 2, 2026 15:19
RFC 9113 §8.2.3 requires that multiple Cookie header fields received
over HTTP/2 MUST be concatenated into a single octet string using the
"; " delimiter before being passed into a non-HTTP/2 context.

When a browser sends cookies over HTTP/2, it may split them into
separate header fields for better HPACK compression. If these are
forwarded as-is to an HTTP/1.1 upstream, many backends only read the
first Cookie header, silently dropping session cookies and causing
failures such as CSRF token verification errors (HTTP 422).

Changes:
- Add h2_to_h1_concat_cookie_headers() in proxy_h1.rs that merges
  multiple Cookie headers preserving insertion order
- Call it during H2→H1 conversion in proxy_1to1()
- Add PeerOptions.h2_to_h1_concat_cookies flag (default: true)
  to allow disabling if needed
- Add 6 unit tests covering normal, edge, and no-op cases

Fixes cloudflare#892

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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.

HTTP/2 multiple Cookie headers not concatenated when proxied to HTTP/1.1 upstream (RFC 9113 §8.2.3)

1 participant