-
Notifications
You must be signed in to change notification settings - Fork 1
/
mitmproxy_sabrdump.py
127 lines (102 loc) · 5.47 KB
/
mitmproxy_sabrdump.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# usage: PYTHONPATH='.' mitmproxy -s utils/mitmproxy_sabrdump.py
import base64
import io
import protobug
from mitmproxy import http
from yt_dlp.networking import Response
from yt_dlp_plugins.extractor._ytse.downloader.sabr import UMPParser
from yt_dlp_plugins.extractor._ytse.protos import (
MediaHeader,
SabrRedirect,
NextRequestPolicy,
FormatInitializationMetadata,
StreamProtectionStatus,
VideoPlaybackAbrRequest,
PlaybackStartPolicy,
RequestCancellationPolicy,
SabrSeek,
LiveMetadata,
unknown_fields,
SelectableFormats,
PrewarmConnection,
AllowedCachedFormats
)
from yt_dlp_plugins.extractor._ytse.ump import UMPPartType
def write_unknown_fields(f, protobug_obj):
uf = list(unknown_fields(protobug_obj))
if uf:
f.write(f'Unknown Fields: {uf}\n')
class SABRParser:
def response(self, flow: http.HTTPFlow) -> None:
if "application/vnd.yt-ump" in flow.response.headers.get("Content-Type", ""):
res = Response(fp=io.BytesIO(flow.response.raw_content), url=flow.request.url, headers={})
parser = UMPParser(res)
rn = flow.request.query.get("rn")
n = flow.request.query.get("n")
with open(f'dumps/{rn}-{n}.dump', 'w') as f:
f.write(f'URL: {flow.request.url}\n')
f.write(f'request body base64: {base64.b64encode(flow.request.raw_content).decode("utf-8")}\n')
try:
vpar = protobug.loads(flow.request.raw_content, VideoPlaybackAbrRequest)
f.write(f'request body decoded: {vpar}\n')
except:
print('not a sabr request')
for part in parser.iter_parts():
print(f'Part type: {part.part_type}, Part size: {part.size}')
f.write(
f'Part type: {part.part_type} ({part.part_type.name}), Part size: {part.size}\n')
if part.part_type != UMPPartType.MEDIA:
f.write(f'Part data base64: {part.get_b64_str()}\n')
if part.part_type == UMPPartType.MEDIA_HEADER:
media_header = protobug.loads(part.data, MediaHeader)
f.write(f'Media Header: {media_header}\n')
write_unknown_fields(f, media_header)
elif part.part_type == UMPPartType.SABR_REDIRECT:
sabr_redirect = protobug.loads(part.data, SabrRedirect)
f.write(f'SABR Redirect: {sabr_redirect}\n')
write_unknown_fields(f, sabr_redirect)
elif part.part_type == UMPPartType.NEXT_REQUEST_POLICY:
nrp = protobug.loads(part.data, NextRequestPolicy)
f.write(f'Next Request Policy: {nrp}\n')
write_unknown_fields(f, nrp)
elif part.part_type == UMPPartType.FORMAT_INITIALIZATION_METADATA:
fim = protobug.loads(part.data, FormatInitializationMetadata)
f.write(f'Format Initialization Metadata {fim}\n')
write_unknown_fields(f, fim)
elif part.part_type == UMPPartType.STREAM_PROTECTION_STATUS:
sps = protobug.loads(part.data, StreamProtectionStatus)
f.write(f'Stream Protection Status: {sps}\n')
write_unknown_fields(f, sps)
elif part.part_type == UMPPartType.PLAYBACK_START_POLICY:
psp = protobug.loads(part.data, PlaybackStartPolicy)
f.write(f'Playback Start Policy: {psp}\n')
write_unknown_fields(f, psp)
elif part.part_type == UMPPartType.REQUEST_CANCELLATION_POLICY:
rcp = protobug.loads(part.data, RequestCancellationPolicy)
f.write(f'Request Cancellation Policy: {rcp}\n')
write_unknown_fields(f, rcp)
elif part.part_type == UMPPartType.SABR_SEEK:
sabr_seek = protobug.loads(part.data, SabrSeek)
f.write(f'Sabr Seek: {sabr_seek}\n')
write_unknown_fields(f, sabr_seek)
elif part.part_type == UMPPartType.LIVE_METADATA:
lm = protobug.loads(part.data, LiveMetadata)
f.write(f'Live Metadata: {lm}\n')
write_unknown_fields(f, lm)
elif part.part_type == UMPPartType.SELECTABLE_FORMATS:
sf = protobug.loads(part.data, SelectableFormats)
f.write(f'Selectable Formats: {sf}\n')
write_unknown_fields(f, sf)
elif part.part_type == UMPPartType.PREWARM_CONNECTION:
pc = protobug.loads(part.data, PrewarmConnection)
f.write(f'Prewarm Connection: {pc}\n')
write_unknown_fields(f, pc)
elif part.part_type == UMPPartType.ALLOWED_CACHED_FORMATS:
acf = protobug.loads(part.data, AllowedCachedFormats)
f.write(f'Allowed Cached Formats: {acf}\n')
write_unknown_fields(f, acf)
elif part.part_type == UMPPartType.MEDIA or part.part_type == UMPPartType.MEDIA_END:
f.write(f'Media Header Id: {part.data[0]}\n')
addons = [
SABRParser()
]