Skip to content

Commit 2d5bd34

Browse files
yyoyoian-pixelweb-flowclaude
authored
fix: skip H2 for tunnel_request (single ops) — completes #1040 (#1041)
Completes [#1040](#1040) (v1.9.21). #1040 skipped H2 for `tunnel_batch_request_to` but missed `tunnel_request` — the single-op path used for plain `connect` ops. The 16-17s long-poll stalls persisted on full-tunnel sessions that go through the single-op path; this PR closes that gap. Same fix shape: remove the H2 try/fallback/NonRetryable block from `tunnel_request`, go straight to H1 pool `acquire()`. H2 remains active for relay-mode paths (`do_relay_once_with`, exit-node `relay()`). ## All h2_relay_request call sites audited | Call site | Function | Mode | H2 skipped? | |---|---|---|---| | `do_relay_once_with` | relay | Relay | No (correct — relay benefits from H2) | | `relay()` exit-node | relay | Relay | No (correct) | | `tunnel_request` | tunnel single op | Full tunnel | **YES — this PR** | | `tunnel_batch_request_to` | tunnel batch | Full tunnel | Yes (PR #1040) | | `tunnel_batch_request_with_timeout` | tunnel batch | Full tunnel | Yes (PR #1040) | No other full-tunnel paths use H2 after this fix. ## Verified locally on top of v1.9.21 - `cargo test --lib --release`: 209/209 ✅ - `cargo build --release --features ui --bin mhrv-rs-ui`: clean ✅ Reviewed via Anthropic Claude. Co-Authored-By: yyoyoian-pixel <noreply@github.com> Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent b259dd0 commit 2d5bd34

1 file changed

Lines changed: 3 additions & 44 deletions

File tree

src/domain_fronter.rs

Lines changed: 3 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -2653,50 +2653,9 @@ impl DomainFronter {
26532653
let script_id = self.next_script_id();
26542654
let path = format!("/macros/s/{}/exec", script_id);
26552655

2656-
// h2 fast path. Tunnel ops are stateful — a `connect` may
2657-
// have opened an upstream socket; a `data` op may have
2658-
// forwarded bytes. Replaying on h1 after the op reached
2659-
// Apps Script can corrupt the tunnel session. Only fall back
2660-
// when h2 definitely never sent.
2661-
// Use the user-configured batch_timeout so Full-mode tuning
2662-
// (`request_timeout_secs`) is honored — a fixed cap would let
2663-
// legitimately slow batches incorrectly trip strike counters
2664-
// on healthy deployments at tunnel_client::fire_batch.
2665-
match self
2666-
.h2_relay_request(&path, payload.clone(), self.batch_timeout)
2667-
.await
2668-
{
2669-
Ok((status, _hdrs, _resp_body)) if is_h2_fronting_refusal_status(status) => {
2670-
// Edge rejected the fronted h2 request. Safe to fall
2671-
// back to h1 — the tunnel op never executed because
2672-
// Apps Script never received the request.
2673-
self.sticky_disable_h2_for_fronting_refusal(
2674-
status,
2675-
&format!("tunnel op {}", op),
2676-
)
2677-
.await;
2678-
// fall through to h1
2679-
}
2680-
Ok((status, _hdrs, resp_body)) => {
2681-
return self.finalize_tunnel_response(&script_id, status, resp_body);
2682-
}
2683-
Err((e, RequestSent::No)) => {
2684-
tracing::debug!(
2685-
"h2 tunnel request pre-send failure: {} — falling back to h1",
2686-
e
2687-
);
2688-
}
2689-
Err((e, RequestSent::Maybe)) => {
2690-
tracing::warn!(
2691-
"h2 tunnel request post-send failure (op={}): {} — \
2692-
not replaying on h1 to avoid corrupting the tunnel session",
2693-
op,
2694-
e
2695-
);
2696-
return Err(e);
2697-
}
2698-
}
2699-
2656+
// Skip h2 for tunnel ops — same rationale as tunnel_batch_request_to
2657+
// (PR #1040): tunnel ops are already single HTTP requests, h2
2658+
// multiplexing adds no benefit and causes 16-17s long-poll stalls.
27002659
let mut entry = self.acquire().await?;
27012660

27022661
let req_head = format!(

0 commit comments

Comments
 (0)