Repository navigation
[Bug]: Decode content-coded responses on the pinned direct provider transport #5111
Description
Client or integration
Direct HTTP/API client
Area
Proxy and routing
Summary
SOCKS responses now decode gzip/deflate, but pinnedHttpRequest returns raw encoded success bytes. Provider outbound chooses between these transports, so the same gzip JSON response is readable on one route and still compressed on the pinned direct route.
Reproduction
Static source trace at 7864869c31c41cca9830d93540238f17df8faafb; the following fake-upstream regression is the proposed executable reproduction, not a claimed local test result.
- Fake upstream returns gzip or deflate JSON with matching Content-Encoding and coded Content-Length.
- Read the response through pinned direct and SOCKS routes.
- Compare logical JSON, coding/length headers, decoder errors and cleanup. Current pinned direct code forwards raw bytes into a Response.
Version
Operating system
Source review on macOS 27.0; the transport logic is cross-platform. Runtime reproduction has not been executed in this analysis.
Provider and model
Not provider- or model-specific. Use a local fake upstream and no real credentials.
Logs or error output
No live traffic or runtime logs collected. Evidence is the exact source path below.
Screenshots and supporting files
src/lib/pinned-http.ts:153; src/lib/pinned-http.ts:194; src/lib/provider-outbound.ts:209; src/lib/socks5-fetch.ts:530. This is the pinned direct residual after #5070, not a duplicate request to decode SOCKS gzip.
Redacted configuration
Use a test-owned loopback upstream and SOCKS tunnel or the pinned direct helper as specified above. No user home, provider credentials or running proxy is needed.
Implementation path
- MODIFY
src/lib/pinned-http.ts: apply an explicit content-coding policy to success bodies; default identity requests can reduce unnecessary coding but are not the complete fix. - EXTRACT only the narrow shared gzip/deflate decoding policy from
src/lib/socks5-fetch.tsif useful; leave injected executors under their existing contract. - Remove stale coded length/encoding after decoding and preserve byte ceilings, cancellation, deadlines and connection cleanup. Define encoded/decoded accounting explicitly for the bounded pinned consumer.
- Do not reject an entire Accept-Encoding preference list merely because it mentions an unsupported alternative; validate the actual response coding. Brotli and multiple-coding support are separate policy decisions.
- ADD
tests/lib/pinned-http-content-coding.test.tsand route-parity fixtures.
Acceptance criteria and verification
- Identity/gzip/deflate produce identical logical JSON across owned raw transports.
- Corrupt/unsupported coding returns a named error and closes the socket.
- Decoded body size remains bounded when
maxBytesis configured; existing encoded-byte behavior is explicitly preserved or versioned. - Abort/bodyless behavior remains intact; no direct-network fallback around operator egress policy.
New test files must be registered in scripts/test-layout/layout.json and tests/fixtures/test-layout-expected.json; split tests rather than raise file-size caps. Update structure/transports/inventory.md and any other owner declared by the manifest. Run focused regressions and exact-head hosted CI in the implementation PR; no passing runtime result is claimed here.
Checks
- I searched existing issues and documentation.
- I removed secrets, tokens, account details, request credentials, and personal data.
Activity
lidge-jun commentedon Sep 19, 2026
Resolved by #5126, merged into
devasaf4f744c75e4dd0348b4e497e67db4ac80208e07.Acceptance verified at reviewed head
c10958672e51c50b0966b93f7917d2981553913b: identity/gzip/deflate route parity; stale coding/length removal; named unsupported/corrupt failures; encoded and decoded byte bounds; retained bodyless, abort and source-error behavior; actual transport-error classification. Independent source review passed, all review threads were resolved, and hosted run 35434708658 passed all applicable checks plus aggregate CI. Linux and macOS logs show the new regressions executed successfully.The merge was reread as MERGED and its ancestry in dev verified. Local suites/tests/typecheck/build were NOT RUN per campaign restrictions. Cumulative post-merge dev CI is tracked separately.