fix: enhance SABR protobuf handling by conditionally stripping quality-track entries

This commit is contained in:
Abolfazl
2026-05-07 18:09:59 +03:30
parent 9b6d03e070
commit 33db28a7ea
+50 -15
View File
@@ -1988,24 +1988,45 @@ class DomainFronter:
@staticmethod @staticmethod
def _strip_sabr_quality_tracks(body: bytes) -> bytes: def _strip_sabr_quality_tracks(body: bytes) -> bytes:
"""Strip field-3 (quality-track selection) entries from a SABR protobuf. """Strip field-3 (quality-track selection) entries from a SABR
segment-fetch protobuf.
SABR videoplayback POST bodies may contain field-3 (tag byte 0x1a, SABR videoplayback POSTs come in two distinct message types:
wire-type 2) entries that select multiple simultaneous quality tracks.
The combined multi-track response easily exceeds Apps Script • Segment-fetch — contains field-2 (0x12) top-level entries that
UrlFetchApp's ~10 MB response buffer. Removing these top-level carry byte-range requests for video/audio segments. Field-3
field-3 entries forces a single-track response within the limit. (0x1a) entries in these messages are quality-track selectors that
ask googlevideo to bundle multiple simultaneous quality tracks into
one response, easily exceeding Apps Script UrlFetchApp's ~10 MB
buffer → 502. We strip them to force a single-track response.
• Session-init — contains field-5 (0x2a) entries and NO field-2
entries. Field-3 entries in this message type carry essential
session metadata (language, viewer state, etc.). Stripping them
corrupts the init handshake → CDN returns 403.
We therefore only strip field-3 entries when at least one field-2
entry is found at the top level (segment-fetch body). For any other
body type the original bytes are returned unchanged.
Only top-level fields are inspected; nested messages are left intact. Only top-level fields are inspected; nested messages are left intact.
If any unrecognised wire type is encountered the remainder of the If any unrecognised wire type is encountered the remainder of the
buffer is copied verbatim so a malformed body is never silently lost. buffer is copied verbatim so a malformed body is never silently lost.
""" """
out = bytearray() # ── phase 1: single pass — collect all top-level fields ────
# We need to know whether field 2 exists before deciding to strip.
# Rather than walking the buffer twice, we accumulate (field_number,
# seg_start, seg_end) tuples in one pass, then decide what to keep.
segments: list[tuple[int, int, int]] = [] # (field_number, start, end)
has_field2 = False
has_field3 = False
i = 0 i = 0
n = len(body) n = len(body)
tail_start = n # if we bail early, copy from here
while i < n: while i < n:
seg_start = i seg_start = i
# ── decode varint tag ─────────────────────────────────── # decode varint tag
tag = 0 tag = 0
shift = 0 shift = 0
while i < n: while i < n:
@@ -2015,14 +2036,13 @@ class DomainFronter:
if not (b & 0x80): if not (b & 0x80):
break break
else: else:
# truncated tag byte — copy remainder verbatim tail_start = seg_start
out.extend(body[seg_start:])
break break
field_number = tag >> 3 field_number = tag >> 3
wire_type = tag & 0x07 wire_type = tag & 0x07
# ── advance i past the field value ───────────────────── # advance i past the field value
if wire_type == 0: # varint if wire_type == 0: # varint
while i < n and (body[i] & 0x80): while i < n and (body[i] & 0x80):
i += 1 i += 1
@@ -2043,13 +2063,28 @@ class DomainFronter:
elif wire_type == 5: # 32-bit fixed elif wire_type == 5: # 32-bit fixed
i = min(i + 4, n) i = min(i + 4, n)
else: else:
# unknown wire type — cannot safely skip; copy rest verbatim # unknown wire type — bail, copy rest verbatim from seg_start
out.extend(body[seg_start:]) tail_start = seg_start
break break
if field_number != 3: if field_number == 2:
out.extend(body[seg_start:i]) has_field2 = True
elif field_number == 3:
has_field3 = True
segments.append((field_number, seg_start, i))
# ── phase 2: decide ────────────────────────────────────────
# Only strip when this is a segment-fetch body (has field 2).
# Initialization bodies lack field 2 — field 3 is essential there.
if not has_field2 or not has_field3:
return body # nothing to do — return original unchanged
out = bytearray()
for field_number, seg_start, seg_end in segments:
if field_number != 3:
out.extend(body[seg_start:seg_end])
# append any tail bytes that were copied verbatim on early bail
out.extend(body[tail_start:])
return bytes(out) return bytes(out)
def _build_payload(self, method, url, headers, body): def _build_payload(self, method, url, headers, body):