mirror of
https://github.com/therealaleph/MasterHttpRelayVPN-RUST.git
synced 2026-05-18 07:34:36 +03:00
fix(exit_node): strip Content-Encoding + Content-Length on response (#964)
@mehdimalekidev reported `Content Encoding Error` when ChatGPT was routed through Apps Script + exit-node. Root cause: 1. Browser → Apps Script with `Accept-Encoding: gzip, br` (default). 2. Apps Script forwards header to exit-node. 3. exit-node calls `fetch(destination)` which **auto-decompresses** the response body (Deno / Bun / Node `fetch()` does this by default). 4. `resp.arrayBuffer()` returns **plain decompressed bytes** but `resp.headers` still has `Content-Encoding: gzip` from the destination. 5. exit-node forwards both — Apps Script + Rust client pass them through — browser sees `Content-Encoding: gzip` on plain bytes → "Content Encoding Error: invalid or unsupported form of compression". Fix: strip `Content-Encoding` and `Content-Length` from the response headers before returning to the relay. The Apps Script + Rust transport layer reframes the wire body anyway, so neither header is meaningful to forward end-to-end. Affects ChatGPT (gzip), Claude (br), Reddit (gzip), and any other compressed exit-node-routed destination — the fix makes them all work. No new test (this fixes a regression that would only show in a real fetch path; mocking auto-decompression behavior is fragile). Manual verification: tested ChatGPT through exit-node, response renders normally in Firefox. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -146,9 +146,20 @@ export default async function (req: Request): Promise<Response> {
|
||||
redirect: "manual",
|
||||
});
|
||||
|
||||
// `fetch()` (Deno / Bun / Node) auto-decompresses gzip / br / deflate
|
||||
// responses, so `resp.arrayBuffer()` returns plain bytes — but the
|
||||
// destination's `Content-Encoding` header is still on `resp.headers`.
|
||||
// Forwarding it would tell the client browser "this body is gzipped"
|
||||
// when it isn't, producing `Content Encoding Error` (#964). Same goes
|
||||
// for `Content-Length` — the post-decompression byte count is
|
||||
// different from what the destination announced. Strip both. The
|
||||
// Apps Script + Rust transport layer below us re-frames the wire body
|
||||
// anyway, so neither header is meaningful to forward.
|
||||
const data = new Uint8Array(await resp.arrayBuffer());
|
||||
const respHeaders: Record<string, string> = {};
|
||||
resp.headers.forEach((value, key) => {
|
||||
const lower = key.toLowerCase();
|
||||
if (lower === "content-encoding" || lower === "content-length") return;
|
||||
respHeaders[key] = value;
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user