code wiki / _hdl_build / nx_media_multiround_gate.nx
nx_media_multiround_gate.nx source
↩ module page · 131 lines · 6740 B
1import "nx_gate_gn.nx"
2import "nx_gate_base.nx"
3// nx_media_multiround_gate.nx -- proves MULTI-ROUND real-network capture: a page fetches a config/api URL,
4// and the RESPONSE drives the NEXT fetch (the signed manifest). Single-round pending-capture MISSES it (it
5// only sees the config URL). Multi-round SERVICES the config fetch (canned bytes here; real TLS in the CLI),
6// drains the promise chain, and the manifest fetch appears in the NEXT round -> captured. This is exactly
7// the signed-URL / round-2-module shape. Hermetic (a canned responder plays the server). license_tier: ORIGINAL expect_exit: 0
8import "nx_syscalls.nx"
9import "nx_js_eval.nx"
10import "nx_media_jsexec.nx"
11
12func grow(name: *u8, ok: i64) -> i64 { if ok==1 { gw(" PASS " as *u8) } else { gw(" FAIL " as *u8) } gw(name); gw("
13" as *u8); return ok }
14func gsl(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n }
15
16// canned "server": maps a config/api URL to a JSON body whose fields drive the next fetch. (In the live CLI
17// this is nx_https_fetch_follow of the real URL.) Returns body length (0 = no canned response -> resolve empty).
18func canned(url: *u8, ul: i64, out: *u8, ocap: i64) -> i64 {
19 var body: *u8 = "" as *u8
20 if mjx_contains(url, ul, "cfg" as *u8, 3) == 1 { body = "{\"host\":\"https://cdn/signed\"}" as *u8 }
21 if mjx_contains(url, ul, "step1" as *u8, 5) == 1 { body = "{\"next\":\"https://api/step2\"}" as *u8 }
22 if mjx_contains(url, ul, "step2" as *u8, 5) == 1 { body = "{\"stream\":\"https://cdn/deep/master.m3u8\"}" as *u8 }
23 let bl: i64 = gsl(body)
24 var i: i64 = 0
25 while i < bl { if i < (ocap - 1) { out[i] = body[i] } i = i + 1 }
26 out[bl] = 0 as u8
27 return bl
28}
29// append url to the seen buffer if new; state[0]=len, state[1]=count.
30func seen_add(seen: *u8, state: *i64, url: *u8, ul: i64, cap: i64) -> i64 {
31 let sl: i64 = state[0]
32 if mjx_contains(seen, sl, url, ul) == 1 { return 0 }
33 if (sl + ul + 1) < cap {
34 var nl: i64 = sl
35 var k: i64 = 0
36 while k < ul { seen[nl] = url[k]; nl = nl + 1; k = k + 1 }
37 seen[nl] = 10 as u8; nl = nl + 1
38 seen[nl] = 0 as u8
39 state[0] = nl; state[1] = state[1] + 1
40 }
41 return 1
42}
43
44// SINGLE-ROUND: run the page, capture the media it fetches in round 1 ONLY (no servicing). Returns media count.
45func single_round_media(page: *u8, plen: i64, seen: *u8, cap: i64) -> i64 {
46 let ob: *i64 = sys_mmap(16) as *i64
47 js_run_source_keep(page, plen, ob)
48 let genv: *i64 = (ob[1]) as *i64
49 if (genv as i64) == 0 { return 0 }
50 let state: *i64 = sys_mmap(16) as *i64; state[0] = 0; state[1] = 0
51 let ubuf: *u8 = sys_mmap(2048)
52 let total: i64 = js_pending_total(genv)
53 var i: i64 = 0
54 while i < total { let ul: i64 = js_pending_url(genv, i, ubuf, 2048); if mjx_is_media_url(ubuf, ul) == 1 { seen_add(seen, state, ubuf, ul, cap) } i = i + 1 }
55 return state[1]
56}
57
58// MULTI-ROUND: run the page, then SERVICE each unserviced pending (media -> collect + resolve empty; config ->
59// serve canned body) and DRAIN, up to maxrounds, until no new work. Captures media discovered across rounds.
60func multiround_media(page: *u8, plen: i64, seen: *u8, cap: i64, maxrounds: i64) -> i64 {
61 let ob: *i64 = sys_mmap(16) as *i64
62 js_run_source_keep(page, plen, ob)
63 let ctx: *i64 = (ob[0]) as *i64
64 let genv: *i64 = (ob[1]) as *i64
65 if (genv as i64) == 0 { return 0 }
66 let state: *i64 = sys_mmap(16) as *i64; state[0] = 0; state[1] = 0
67 let ubuf: *u8 = sys_mmap(2048)
68 let body: *u8 = sys_mmap(4096)
69 var round: i64 = 0
70 var go: i64 = 1
71 while go == 1 {
72 if round >= maxrounds { go = 0 }
73 else {
74 let total: i64 = js_pending_total(genv)
75 var did: i64 = 0
76 var i: i64 = 0
77 while i < total {
78 if js_pending_serviced(genv, i) == 0 {
79 let ul: i64 = js_pending_url(genv, i, ubuf, 2048)
80 if mjx_is_media_url(ubuf, ul) == 1 {
81 seen_add(seen, state, ubuf, ul, cap)
82 js_pending_service(ctx, genv, i, 200, "" as *u8, 0) // resolve empty (don't recurse into media)
83 } else {
84 let bl: i64 = canned(ubuf, ul, body, 4096)
85 js_pending_service(ctx, genv, i, 200, body, bl)
86 }
87 did = 1
88 }
89 i = i + 1
90 }
91 if did == 0 { go = 0 } else { el_drain(ctx, genv); round = round + 1 }
92 }
93 }
94 return state[1]
95}
96func seen_has(seen: *u8, want: *u8) -> i64 { return mjx_contains(seen, gsl(seen), want, gsl(want)) }
97
98func main() -> i64 {
99 gw("media-multiround SOVEREIGN gate (service config fetch -> drain -> capture the round-2 manifest)\n" as *u8)
100 var pass: i64 = 0
101 var ttl: i64 = 0
102
103 // A page whose CONFIG response drives the manifest fetch (the signed-URL shape).
104 let page2: *u8 = "fetch('https://api/cfg').then(function(r){return r.json();}).then(function(c){ fetch(c.host+'/master.m3u8'); });" as *u8
105
106 // T1: SINGLE-ROUND misses it -> 0 media (only the non-media config URL is pending in round 1).
107 let s1: *u8 = sys_mmap(4096)
108 let c1: i64 = single_round_media(page2, gsl(page2), s1, 4096)
109 ttl=ttl+1; pass=pass+grow("T1 single-round captures 0 media (the gap)\x00" as *u8, (c1 == 0) as i64)
110
111 // T2: MULTI-ROUND services the config, drains, captures the round-2 manifest.
112 let s2: *u8 = sys_mmap(4096)
113 let c2: i64 = multiround_media(page2, gsl(page2), s2, 4096, 4)
114 var t2: i64 = 1
115 if c2 != 1 { t2 = 0 }
116 if seen_has(s2, "https://cdn/signed/master.m3u8\x00" as *u8) == 0 { t2 = 0 }
117 ttl=ttl+1; pass=pass+grow("T2 multi-round captures https://cdn/signed/master.m3u8\x00" as *u8, t2)
118
119 // T3: DEEP CHAIN (config -> api2 -> manifest) needs 3 rounds; multi-round follows it.
120 let page3: *u8 = "fetch('https://api/step1').then(function(r){return r.json();}).then(function(c){ return fetch(c.next); }).then(function(r){return r.json();}).then(function(d){ fetch(d.stream); });" as *u8
121 let s3: *u8 = sys_mmap(4096)
122 let c3: i64 = multiround_media(page3, gsl(page3), s3, 4096, 5)
123 var t3: i64 = 1
124 if c3 != 1 { t3 = 0 }
125 if seen_has(s3, "https://cdn/deep/master.m3u8\x00" as *u8) == 0 { t3 = 0 }
126 ttl=ttl+1; pass=pass+grow("T3 deep chain (3 rounds) captures https://cdn/deep/master.m3u8\x00" as *u8, t3)
127
128 gw("pass=" as *u8); gn(pass); gw("/" as *u8); gn(ttl); gw("\n" as *u8)
129 if pass == ttl { gw("verdict=GREEN (multi-round: service config -> drain -> capture the manifest a single round misses)\n" as *u8); sys_exit(0); return 0 }
130 gw("verdict=RED\n" as *u8); sys_exit(1); return 1
131}