🐛 QUIC Hijack() skips the status-written check that HTTP/2 enforces
まだ誰も着手していません。
評価
- 難易度
- 2/5
- 見積もり時間
- 1〜3時間
- 初心者へのやさしさ
- 78/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 活発
- 技術スタック
- go
- 領域
- backend, networking
調査の方向性
Compare http2RespWriter.Hijack in connection/http2.go with httpResponseAdapter.Hijack in connection/quic_connection.go, focusing on statusWritten and connectResponseSent. Reproduce the differing behavior with the described HTTP/2 and QUIC protocols, then verify that QUIC enforces the same precondition and no longer permits raw writes before a connect response is sent.
索引モデルが issue の本文から書いたものです。
説明
Describe the bug
Hijack() has different preconditions on the two transports.
HTTP/2, http2RespWriter.Hijack in connection/http2.go, refuses when no status was written yet:
if !rp.statusWritten {
return nil, nil, fmt.Errorf("status not yet written before attempting to hijack connection")
}
QUIC, httpResponseAdapter.Hijack in connection/quic_connection.go, has no such check. It always returns a localProxyConnection, even when connectResponseSent is still false, so the caller can write raw bytes to the stream before any connect response went out.
Same caller, different outcome depending on the transport: on HTTP/2 it gets an error, on QUIC it gets a conn.
To Reproduce
Stock cloudflared writes the status before it hijacks, so the built-in ingress path does not hit this. I hit it in a fork that replaces the OriginProxy, with code that hijacks first. net/http/httputil.ReverseProxy does exactly that on a 101: handleUpgradeResponse calls Hijack() and then writes the status line onto the conn itself.
ProxyHTTPserves the request throughhttputil.ReverseProxyto a backend that answers 101.- With
--protocol http2,Hijackfails and the client gets a 502. - With
--protocol quic,Hijacksucceeds and the caller can write to the stream before any connect response was sent.
Expected behavior
Both transports enforce the same precondition. The HTTP/2 check looks like the right one, so QUIC could refuse the same way while connectResponseSent is false.
Environment and versions
- OS: Linux
- Architecture: AMD64
- Version: 2026.9.1, and the
Hijackbodies are unchanged on master as of 2026.9.3
Logs and errors
HTTP/2: status not yet written before attempting to hijack connection. QUIC: no error.
Additional context
I worked around it on my side, so it does not block me. Filing it because the two transports disagree on the ResponseWriter contract, and that is easy to miss.
- 主要言語
- Go
- スター
- 15.8k
- フォーク
- 1.4k
- PR マージ指標
- 30日以内にマージされた PR はありません
環境構築
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
cloudflare/cloudflared のほかの issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
cloudflare/cloudflared#1715 ·
-
Priority: Normal Type: Feature Request
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
cloudflare/cloudflared#1645 · リアクション 3 件 ·
-
Priority: Normal Type: Bug
難易度 1/5 1時間未満 初心者へのやさしさ 68/100
cloudflare/cloudflared#1609 · リアクション 1 件 ·
-
Priority: Normal Type: Bug
難易度 1/5 1時間未満 初心者へのやさしさ 68/100
cloudflare/cloudflared#1348 · リアクション 6 件 ·
-
Priority: Normal Type: Bug
難易度 4/5 3〜5日 初心者へのやさしさ 35/100
cloudflare/cloudflared#1737 ·
cloudflare/cloudflared の issue をすべて見る
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
siderolabs/terraform-provider-talos#414 ·
メンテナーはふだん 1 日以内に返信
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
JuliaComputing/jh#63 · コメント 1 件 ·
-
area/proxy kind/bug priority/backlog triage/accepted
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
lexfrei/cloudflare-tunnel-gateway-controller#840 ·
メンテナーはふだん 1 日以内に返信
-
area:chat bug sev:papercut
難易度 2/5 1〜3時間 初心者へのやさしさ 86/100
Agent-Field/CodeAF#1592 ·
メンテナーはふだん 1 日以内に返信