test(server): guard dp-manager REST clients against h2 ALPN (#535, #536)#539
test(server): guard dp-manager REST clients against h2 ALPN (#535, #536)#539moonming wants to merge 1 commit into
Conversation
#536 fixed #535 by pinning the dp-manager REST mTLS clients to HTTP/1.1 (`.http1_only()`) but shipped no test — the same blind spot that let the regression reach production. dp-manager multiplexes kine/etcd gRPC and the /dp/* REST API on one cmux TLS port, routing by negotiated ALPN; if these clients ever advertise `h2` again (another dep unifies reqwest's `http2` feature back on, or `.http1_only()` is dropped), every budget_check / heartbeat / telemetry call fails at the transport layer. Add `cp_rest_client_advertises_only_http1_alpn` for both build_client copies: capture the raw TLS ClientHello and assert ALPN advertises http/1.1 and not h2. Verified to fail if `.http1_only()` is removed.
ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Free Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThis PR adds two regression tests to validate HTTP/1.1-only ALPN advertisement behavior: one for the heartbeat/REST client in ChangesALPN Validation Across Clients
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Note 🎁 Summarized by CodeRabbit FreeYour organization has reached its limit of developer seats under the Pro Plan. For new users, CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please add seats to your subscription by visiting https://app.coderabbit.ai/login.If you believe this is a mistake and have available seats, please assign one to the pull request author through the subscription management page using the link above. Comment |
What
Adds a regression guard for #535 — the dp-manager REST clients negotiating ALPN
h2and getting misrouted by dp-manager's single-port cmux. The fix already landed in #536 (.http1_only()on bothbuild_clientcopies); this PR adds the test #536 didn't include.Scope: this guards the REST client only — the gRPC/etcd h2 path is intentional and untouched
The DP talks to dp-manager over two protocols on the same
:7944TLS port, handled by two different client libraries:etcd_client(tonic) —crates/aisix-etcd/src/etcd_provider.rsreqwest—heartbeat.rs/telemetry.rsdp-manager advertises ALPN
["h2","http/1.1"]on the one port to accept both clients (h2 for the tonic gRPC client, http/1.1 for the reqwest REST client); cmux then splits them by protocol. That h2 belongs to etcd-client, not reqwest —reqwesthas never carried thehttp2feature in this repo's history. #535 wasobject_storeaccidentally unifyingreqwest/http2onto the shared client, so the REST client also started advertising h2. This guard (and #536's.http1_only()) only pins the reqwest REST client back to its intended h1; the etcd-client gRPC watch is a separate connection and is not affected.What it asserts
cp_rest_client_advertises_only_http1_alpn(heartbeat + telemetry): builds the real CP-REST mTLS client viabuild_client, fires one request at a bare TCP listener, captures the raw TLS ClientHello (sent in the clear, pre-handshake), and asserts the ALPN list advertiseshttp/1.1and noth2. No TLS server / cert needed, so it can't flake on handshake details — a short/failed capture makes.position()returnNone→ loud panic, never a silent green.Verified: fails if
.http1_only()is removed frombuild_client(reproduces #535), passes with it.Test plan
cargo test -p aisix-server(52 + 2 new pass)cargo clippy -p aisix-server --testsclean.http1_only()locally → test goes RED; restored → GREENTests only — no production code change. Guards #535 / #536.