Files
MasterHttpRelayVPN-RUST/docs/changelog/v1.9.17.md
T
therealaleph 141cd6c7a8 feat: v1.9.17 — CORS response header injection (#561 / YouTube comments)
mhrv-rs already short-circuits CORS preflight (OPTIONS → 204 with permissive ACL headers, no relay round-trip). What was missing: the actual cross-origin fetch that follows the preflight also needs CORS-compliant headers on the response, or the browser drops the response and the JS layer sees a CORS failure even though the relay succeeded.

Apps Script's UrlFetchApp.fetch() preserves the destination's response headers inconsistently — sometimes the origin returns `Access-Control-Allow-Origin: *` (which is incompatible with `Allow-Credentials: true`), sometimes drops ACL headers entirely. The visible symptom is YouTube comments not loading + the "restricted mode" error surfacing on responses the browser silently rejected before the JS handler could read them.

Fix: after the relay returns, if the original request had an `Origin` header, we strip any `Access-Control-*` headers the destination emitted and inject a fresh permissive set echoing the request's origin (required for credentialed fetches; `*` is invalid alongside Allow-Credentials).

The body is preserved byte-for-byte; only the header block before the first \r\n\r\n is rewritten. Malformed responses (no header/body separator) round-trip unchanged so we never corrupt non-HTTP/1.x bytes.

Idea credit: ThisIsDara/mhr-cfw-go — Go rewrite of upstream Python's CFW variant added the same fix; reviewing their code surfaced the gap in mhrv-rs. Their other claimed improvements (HTTP/2, connection pooling, request coalescing, response caching, range-parallel) are already in mhrv-rs.

Tests: 200 lib (was 197, +3 covering wildcard-origin replacement, non-ACL header preservation, malformed-response passthrough) + 36 tunnel-node green.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 20:56:48 +03:00

2.6 KiB
Raw Blame History

• Inject CORS response headers after relay — اضافه شد به‌جای فقط preflight short-circuit. مرورگرها در درخواست‌های cross-origin (مثل YouTubes youtubei/v1/next / youtubei/v1/comments که از script context fire می‌شه) responseـی نیاز دارن با Access-Control-Allow-Origin که با origin درخواست match کنه + Allow-Credentials: true. Apps Script's UrlFetchApp.fetch() گاهی header‌های ACL مقصد رو preserve نمی‌کنه، یا destination با Allow-Origin: * پاسخ می‌ده که با credentialed request ناسازگاره. mhrv-rs حالا header‌های Access-Control-* پاسخ relay رو strip می‌کنه + permissive set تزریق می‌کنه که با origin درخواست echo می‌شه. علت ریشه‌ای: YouTube comments نمی‌اومدن load بشن + گاهی restricted-mode error به همین دلیل ظاهر می‌شد. ایده credit: ThisIsDara/mhr-cfw-go (Go rewrite of upstream Python). فقط برای درخواست‌هایی با Origin header اعمال می‌شه — non-CORS traffic (curl، apps native) دست‌نخورده می‌مونه. ۱۹۷ → ۲۰۰ lib test (+۳ regression test for CORS injection edge cases).

• Inject CORS response headers after relay (in addition to the existing preflight short-circuit). When browsers issue cross-origin fetches from script contexts — e.g. YouTube's youtubei/v1/next / youtubei/v1/comments calls, which fire from the player JS — they require the response to carry Access-Control-Allow-Origin matching the request's origin AND Allow-Credentials: true. Apps Script's UrlFetchApp.fetch() sometimes doesn't preserve the destination's ACL headers, or the destination returns Allow-Origin: * which is incompatible with credentialed requests. mhrv-rs now strips any Access-Control-* headers from the relay response and injects a permissive set keyed on the request's Origin. Root cause: YouTube comments not loading + the "restricted mode" error sometimes surfacing on cross-origin XHR responses the browser silently dropped. Idea credit: ThisIsDara/mhr-cfw-go (Go rewrite of upstream Python's CFW variant). Only applies when the original request had an Origin header — non-CORS traffic (curl, app-level HTTP clients) passes through byte-for-byte unchanged. 197 → 200 lib tests (+3 regression tests for CORS injection edge cases: wildcard-origin replacement, non-ACL header preservation, malformed-response passthrough).