feat: support Miruro provider tracks, proxies, and native embeds
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
"""Local-only resolved HLS/VTT + native model smoke; no live requests."""
|
||||
import base64
|
||||
import http.server
|
||||
import json
|
||||
from pathlib import Path
|
||||
@@ -6,7 +7,7 @@ import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import threading
|
||||
from urllib.parse import urlsplit
|
||||
from urllib.parse import parse_qs, urlsplit
|
||||
|
||||
binary = str(Path(sys.argv[1]).resolve())
|
||||
fixtures = Path(sys.argv[2]).resolve()
|
||||
@@ -17,7 +18,51 @@ class Handler(http.server.BaseHTTPRequestHandler):
|
||||
def log_message(self, *_):
|
||||
pass
|
||||
|
||||
def transport(self):
|
||||
path = urlsplit(self.path).path
|
||||
try:
|
||||
encoded, suffix = path.lstrip("/").split("/", 1)
|
||||
target, referer = encoded.split("~")
|
||||
def decode(value):
|
||||
raw = base64.urlsafe_b64decode(value + "=" * (-len(value) % 4))
|
||||
return bytes(byte ^ [1, 2, 3][index % 3] for index, byte in enumerate(raw)).decode()
|
||||
upstream = urlsplit(decode(target))
|
||||
if not upstream.path.startswith("/transport-"):
|
||||
return False
|
||||
assert decode(referer) == "https://transport.example/"
|
||||
assert self.headers.get("X-Secret") is None and self.headers.get("Referer") is None, "private headers leaked to proxy"
|
||||
except (ValueError, UnicodeError):
|
||||
return False
|
||||
query = parse_qs(upstream.query)
|
||||
if upstream.path.endswith(".m3u8"):
|
||||
assert query == {"skip": ["fixture"]}, "provider query or token-removal rule lost"
|
||||
port = self.server.server_port
|
||||
if upstream.path == "/transport-master.m3u8":
|
||||
def encode(value):
|
||||
raw = value.encode()
|
||||
return base64.urlsafe_b64encode(bytes(byte ^ [1, 2, 3][index % 3] for index, byte in enumerate(raw))).decode().rstrip("=")
|
||||
nested = (f"http://localhost:{port}/" + encode(f"http://127.0.0.1:{port}/transport-variant.m3u8?token=private") +
|
||||
"~" + encode("https://transport.example/") + "/pl.m3u8")
|
||||
data = f"#EXTM3U\n#EXT-X-STREAM-INF:BANDWIDTH=1\n{nested}\n".encode()
|
||||
elif upstream.path == "/transport-variant.m3u8":
|
||||
data = (f'#EXTM3U\n#EXT-X-KEY:METHOD=AES-128,URI="http://2130706433:{port}/transport-private"\n'
|
||||
'#EXTINF:1,\nhttps://foreign.invalid/transport-segment.bin\n#EXT-X-ENDLIST\n').encode()
|
||||
elif upstream.path == "/transport-segment.bin":
|
||||
assert upstream.hostname == "127.0.0.1", "segment origin rewrite lost"
|
||||
data = bytes(range(256))
|
||||
else:
|
||||
errors.append("unexpected transport request")
|
||||
self.send_error(403)
|
||||
return True
|
||||
self.send_response(200)
|
||||
self.send_header("Content-Length", str(len(data)))
|
||||
self.end_headers()
|
||||
self.wfile.write(data)
|
||||
return True
|
||||
|
||||
def do_GET(self):
|
||||
if self.transport():
|
||||
return
|
||||
path = urlsplit(self.path).path
|
||||
seen.append(path)
|
||||
alternate = path.startswith("/alternate/")
|
||||
@@ -30,13 +75,17 @@ class Handler(http.server.BaseHTTPRequestHandler):
|
||||
self.send_error(403)
|
||||
return
|
||||
if path == "/master.m3u8":
|
||||
if urlsplit(self.path).query != "token=fixture":
|
||||
errors.append("master token lost")
|
||||
query = parse_qs(urlsplit(self.path).query)
|
||||
if query.get("token") != ["fixture"] or (alternate and query.get("rewrite") != ["1"]):
|
||||
errors.append("master token or provider query lost")
|
||||
data = b'#EXTM3U\n#EXT-X-STREAM-INF:BANDWIDTH=500000\nvariant.m3u8?token=variant\n'
|
||||
elif path == "/variant.m3u8":
|
||||
if urlsplit(self.path).query != "token=variant":
|
||||
errors.append("variant token lost")
|
||||
query = parse_qs(urlsplit(self.path).query)
|
||||
if query.get("token") != ["variant"] or (alternate and query.get("rewrite") != ["1"]):
|
||||
errors.append("variant token or provider query lost")
|
||||
data = (fixtures / "resolved-vod.m3u8").read_bytes()
|
||||
if alternate:
|
||||
data = data.replace(b"resolved-vod-", b"https://invalid.example/alternate/resolved-vod-")
|
||||
elif path == "/english.jpeg":
|
||||
data = (b'WEBVTT\n\n00:00.000 --> 00:10.000\nAlternate English cue\n' if alternate else
|
||||
b'WEBVTT\n\n00:00.000 --> 00:02.000\nFirst English cue\n\n00:02.000 --> 00:04.000\nSecond English cue\n')
|
||||
|
||||
Reference in New Issue
Block a user