code wiki / _hdl_build / nx_media_multiround_gate.nx

nx_media_multiround_gate.nx source

↩ module page · 139 lines · 7127 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" 11import "nx_gate_verdict.nx" 12 13func grow(name: *u8, ok: i64) -> i64 { if ok==1 { gw(" PASS " as *u8) } else { gw(" FAIL " as *u8) } gw(name); gw(" 14" as *u8); return ok } 15func gsl(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n } 16 17// canned "server": maps a config/api URL to a JSON body whose fields drive the next fetch. (In the live CLI 18// this is nx_https_fetch_follow of the real URL.) Returns body length (0 = no canned response -> resolve empty). 19func canned(url: *u8, ul: i64, out: *u8, ocap: i64) -> i64 { 20 var body: *u8 = "" as *u8 21 if mjx_contains(url, ul, "cfg" as *u8, 3) == 1 { body = "{\"host\":\"https://cdn/signed\"}" as *u8 } 22 if mjx_contains(url, ul, "step1" as *u8, 5) == 1 { body = "{\"next\":\"https://api/step2\"}" as *u8 } 23 if mjx_contains(url, ul, "step2" as *u8, 5) == 1 { body = "{\"stream\":\"https://cdn/deep/master.m3u8\"}" as *u8 } 24 let bl: i64 = gsl(body) 25 var i: i64 = 0 26 while i < bl { if i < (ocap - 1) { out[i] = body[i] } i = i + 1 } 27 out[bl] = 0 as u8 28 return bl 29} 30// append url to the seen buffer if new; state[0]=len, state[1]=count. 31func seen_add(seen: *u8, state: *i64, url: *u8, ul: i64, cap: i64) -> i64 { 32 let sl: i64 = state[0] 33 if mjx_contains(seen, sl, url, ul) == 1 { return 0 } 34 if (sl + ul + 1) < cap { 35 var nl: i64 = sl 36 var k: i64 = 0 37 while k < ul { seen[nl] = url[k]; nl = nl + 1; k = k + 1 } 38 seen[nl] = 10 as u8; nl = nl + 1 39 seen[nl] = 0 as u8 40 state[0] = nl; state[1] = state[1] + 1 41 } 42 return 1 43} 44 45// SINGLE-ROUND: run the page, capture the media it fetches in round 1 ONLY (no servicing). Returns media count. 46func single_round_media(page: *u8, plen: i64, seen: *u8, cap: i64) -> i64 { 47 let ob: *i64 = sys_mmap(16) as *i64 48 js_run_source_keep(page, plen, ob) 49 let genv: *i64 = (ob[1]) as *i64 50 if (genv as i64) == 0 { return 0 } 51 let state: *i64 = sys_mmap(16) as *i64; state[0] = 0; state[1] = 0 52 let ubuf: *u8 = sys_mmap(2048) 53 let total: i64 = js_pending_total(genv) 54 var i: i64 = 0 55 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 } 56 return state[1] 57} 58 59// MULTI-ROUND: run the page, then SERVICE each unserviced pending (media -> collect + resolve empty; config -> 60// serve canned body) and DRAIN, up to maxrounds, until no new work. Captures media discovered across rounds. 61func multiround_media(page: *u8, plen: i64, seen: *u8, cap: i64, maxrounds: i64) -> i64 { 62 let ob: *i64 = sys_mmap(16) as *i64 63 js_run_source_keep(page, plen, ob) 64 let ctx: *i64 = (ob[0]) as *i64 65 let genv: *i64 = (ob[1]) as *i64 66 if (genv as i64) == 0 { return 0 } 67 let state: *i64 = sys_mmap(16) as *i64; state[0] = 0; state[1] = 0 68 let ubuf: *u8 = sys_mmap(2048) 69 let body: *u8 = sys_mmap(4096) 70 var round: i64 = 0 71 var go: i64 = 1 72 while go == 1 { 73 if round >= maxrounds { go = 0 } 74 else { 75 let total: i64 = js_pending_total(genv) 76 var did: i64 = 0 77 var i: i64 = 0 78 while i < total { 79 if js_pending_serviced(genv, i) == 0 { 80 let ul: i64 = js_pending_url(genv, i, ubuf, 2048) 81 if mjx_is_media_url(ubuf, ul) == 1 { 82 seen_add(seen, state, ubuf, ul, cap) 83 js_pending_service(ctx, genv, i, 200, "" as *u8, 0) // resolve empty (don't recurse into media) 84 } else { 85 let bl: i64 = canned(ubuf, ul, body, 4096) 86 js_pending_service(ctx, genv, i, 200, body, bl) 87 } 88 did = 1 89 } 90 i = i + 1 91 } 92 if did == 0 { go = 0 } else { el_drain(ctx, genv); round = round + 1 } 93 } 94 } 95 return state[1] 96} 97func seen_has(seen: *u8, want: *u8) -> i64 { return mjx_contains(seen, gsl(seen), want, gsl(want)) } 98 99func main() -> i64 { 100 gw("media-multiround SOVEREIGN gate (service config fetch -> drain -> capture the round-2 manifest)\n" as *u8) 101 var pass: i64 = 0 102 var ttl: i64 = 0 103 104 // A page whose CONFIG response drives the manifest fetch (the signed-URL shape). 105 let page2: *u8 = "fetch('https://api/cfg').then(function(r){return r.json();}).then(function(c){ fetch(c.host+'/master.m3u8'); });" as *u8 106 107 // T1: SINGLE-ROUND misses it -> 0 media (only the non-media config URL is pending in round 1). 108 let s1: *u8 = sys_mmap(4096) 109 let c1: i64 = single_round_media(page2, gsl(page2), s1, 4096) 110 ttl=ttl+1; pass=pass+grow("T1 single-round captures 0 media (the gap)\x00" as *u8, (c1 == 0) as i64) 111 112 // T2: MULTI-ROUND services the config, drains, captures the round-2 manifest. 113 let s2: *u8 = sys_mmap(4096) 114 let c2: i64 = multiround_media(page2, gsl(page2), s2, 4096, 4) 115 var t2: i64 = 1 116 if c2 != 1 { t2 = 0 } 117 if seen_has(s2, "https://cdn/signed/master.m3u8\x00" as *u8) == 0 { t2 = 0 } 118 ttl=ttl+1; pass=pass+grow("T2 multi-round captures https://cdn/signed/master.m3u8\x00" as *u8, t2) 119 120 // T3: DEEP CHAIN (config -> api2 -> manifest) needs 3 rounds; multi-round follows it. 121 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 122 let s3: *u8 = sys_mmap(4096) 123 let c3: i64 = multiround_media(page3, gsl(page3), s3, 4096, 5) 124 var t3: i64 = 1 125 if c3 != 1 { t3 = 0 } 126 if seen_has(s3, "https://cdn/deep/master.m3u8\x00" as *u8) == 0 { t3 = 0 } 127 ttl=ttl+1; pass=pass+grow("T3 deep chain (3 rounds) captures https://cdn/deep/master.m3u8\x00" as *u8, t3) 128 129 gw("pass=" as *u8); gn(pass); gw("/" as *u8); gn(ttl); gw("\n" as *u8) 130 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check 131 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled 132 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify. 133 let ctr__dry: *i64 = gv_ctr() 134 ctr__dry[0] = pass 135 ctr__dry[1] = ttl 136 let rc__dry: i64 = gv_verdict("MEDIA-MULTIROUND-GATE" as *u8, ctr__dry, "multi-round: service config -> drain -> capture the manifest a single round misses)" as *u8) 137 sys_exit(rc__dry) 138 return rc__dry 139}