code wiki / _hdl_build / nx_jq_realpage.nx
nx_jq_realpage.nx source
↩ module page · 132 lines · 7885 B
1// nx_jq_realpage.nx -- prove real minified jQuery 3.7.1 SELECTS + EXTRACTS over a REAL fetched page's DOM
2// (not the synthetic 2-element tree of nx_jq_tree). Fetch a live page over sovereign TLS -> STRIP its own
3// inline <script> blocks (so jQuery+extraction run cleanly; js_render_page_pending_begin concatenates all
4// inline scripts into ONE program where any top-level error aborts the rest) -> dt_parse the real HTML into
5// a DOM tree -> run preamble+jQuery+extraction as extrascripts in that tree's genv -> jQuery queries the
6// REAL parsed DOM. Proves Sizzle/getElementsByTagName over messy real HTML + attribute/text extraction =
7// exactly the capability clean-serve/archive need. Times dt_parse+jQuery+extract (real-page perf datapoint).
8import "nx_syscalls.nx"
9import "nx_x509_trust_store.nx"
10import "nx_trust_store_load_from_certdata.nx"
11import "nx_video_sniff.nx"
12import "nx_video_sniff_fetch.nx"
13import "nx_surrogate.nx"
14const K_MAGIC_4194304: i64 = 4194304
15const K_MAGIC_16384: i64 = 16384
16const K_MAGIC_2048: i64 = 2048
17const K_MAGIC_8388608: i64 = 8388608
18
19func cw(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
20func cwnum(n: i64) -> i64 {
21 if n == 0 { cw("0" as *u8); return 0 }
22 var m: i64 = n
23 if m < 0 { cw("-" as *u8); m = 0 - m }
24 let buf: *u8 = sys_mmap(32)
25 var k: i64 = 0
26 while m > 0 { buf[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
27 var i: i64 = k - 1
28 while i >= 0 { sys_write(1, ((buf as i64) + i) as *u8, 1); i = i - 1 }
29 return 0
30}
31func slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n }
32func app(dst: *u8, o: i64, s: *u8, n: i64) -> i64 { var i: i64=0; while i<n { dst[o]=s[i]; o=o+1; i=i+1 } return o }
33// case-insensitive match of lowercase `pat` at src[at..] (pat MUST be lowercase)
34func ci_eq(src: *u8, at: i64, n: i64, pat: *u8, pl: i64) -> i64 {
35 if at + pl > n { return 0 }
36 var k: i64 = 0
37 while k < pl {
38 var c: i64 = src[at + k] & 0xff
39 if c >= 65 { if c <= 90 { c = c + 32 } } // upper -> lower
40 if c != (pat[k] & 0xff) { return 0 }
41 k = k + 1
42 }
43 return 1
44}
45// copy src -> dst dropping every <script ...>...</script> block (isolate jQuery-over-real-DOM). Returns dst len.
46func strip_scripts(src: *u8, n: i64, dst: *u8) -> i64 {
47 var i: i64 = 0
48 var o: i64 = 0
49 while i < n {
50 if ci_eq(src, i, n, "<script" as *u8, 7) == 1 {
51 var j: i64 = i + 7
52 var close: i64 = 0 - 1
53 while j < n { if ci_eq(src, j, n, "</script" as *u8, 8) == 1 { close = j + 8; j = n } else { j = j + 1 } }
54 if close < 0 { i = n } else {
55 var g: i64 = close
56 var stop: i64 = 0
57 while stop == 0 {
58 if g >= n { stop = 1 } else { if (src[g] & 0xff) == 62 { g = g + 1; stop = 1 } else { g = g + 1 } }
59 }
60 i = g
61 }
62 } else { dst[o] = src[i]; o = o + 1; i = i + 1 }
63 }
64 return o
65}
66
67func main() -> i64 {
68 let r: i64 = nx_trust_store_load_from_certdata("data/mozilla_certdata.txt" as *u8, 512, K_MAGIC_4194304)
69 if r <= 0 { cw("certdata load failed\n" as *u8); return 1 }
70 let store: *TrustStore = r as *TrustStore
71 let status: *i64 = sys_mmap(8) as *i64
72 // jQuery
73 let jq: *u8 = sys_mmap(K_MAGIC_4194304)
74 let jn: i64 = nx_https_fetch_follow("https://code.jquery.com/jquery-3.7.1.min.js" as *u8, store, jq, K_MAGIC_4194304, 6, status)
75 if jn <= 0 { cw("(jquery fetch failed)\n" as *u8); return 1 }
76 // CONTROLLED synthetic parse (known counts) -- isolates tag-query/parse from real-page size/nesting.
77 let sgtC: *i64 = sg_new(); sg_seed(sgtC)
78 let exC: *u8 = sys_mmap(K_MAGIC_4194304)
79 var ec: i64 = 0
80 let plC: i64 = sg_build_preamble(sgtC, ((exC as i64) + ec) as *u8, K_MAGIC_16384)
81 ec = ec + plC
82 exC[ec] = 59 as u8; ec = ec + 1; exC[ec] = 10 as u8; ec = ec + 1
83 ec = app(exC, ec, jq, jn)
84 let exCt: *u8 = ";function Q(n,v){fetch('https://p/CTL-'+n+'-'+v+'.x')}try{Q('a',$('a').length)}catch(e){Q('a','THREW')}try{Q('div',$('div').length)}catch(e){Q('div','THREW')}try{Q('li',$('li').length)}catch(e){Q('li','THREW')}try{Q('p',$('p').length)}catch(e){Q('p','THREW')}try{Q('ul',$('ul').length)}catch(e){Q('ul','THREW')}" as *u8
85 ec = app(exC, ec, exCt, slen(exCt))
86 exC[ec] = 0 as u8
87 let ctlHtml: *u8 = "<html><head><title>c</title></head><body><div class='w'><a href='/1'>x</a><a href='/2'>y</a></div><ul><li>1</li><li>2</li><li>3</li></ul><p>P</p></body></html>" as *u8
88 let obC: *i64 = sys_mmap(16) as *i64
89 js_render_page_pending_begin(ctlHtml, slen(ctlHtml), exC, ec, obC)
90 let gC: *i64 = (obC[1]) as *i64
91 let ubC: *u8 = sys_mmap(K_MAGIC_2048)
92 let tC: i64 = js_pending_total(gC)
93 var pc: i64 = 0
94 while pc < tC { let ul: i64 = js_pending_url(gC, pc, ubC, K_MAGIC_2048); if ul > 0 { cw(" CTL " as *u8); cw(ubC); cw("\n" as *u8) } pc = pc + 1 }
95 // REAL target page (rich real HTML, server-rendered, no CF) -- proves Sizzle over messy real DOM
96 let page: *u8 = sys_mmap(K_MAGIC_8388608)
97 let tp0: i64 = sys_now_us()
98 let pn: i64 = nx_https_fetch_follow("https://en.wikipedia.org/wiki/JQuery" as *u8, store, page, K_MAGIC_8388608, 6, status)
99 let tp1: i64 = sys_now_us()
100 if pn <= 0 { cw("(page fetch failed status=" as *u8); cwnum(status[0]); cw(")\n" as *u8); return 1 }
101 cw("=== page bytes=" as *u8); cwnum(pn); cw(" fetch_us=" as *u8); cwnum(tp1 - tp0); cw(" ===\n" as *u8)
102 // strip the page's own inline scripts
103 let clean: *u8 = sys_mmap(K_MAGIC_8388608)
104 let cn: i64 = strip_scripts(page, pn, clean)
105 clean[cn] = 0 as u8
106 cw("=== stripped scripts: " as *u8); cwnum(pn); cw(" -> " as *u8); cwnum(cn); cw(" bytes ===\n" as *u8)
107 // extrascripts = preamble + jQuery + real-DOM extraction
108 let sgt: *i64 = sg_new(); sg_seed(sgt)
109 let extra: *u8 = sys_mmap(K_MAGIC_4194304)
110 var eo: i64 = 0
111 let pl: i64 = sg_build_preamble(sgt, ((extra as i64) + eo) as *u8, K_MAGIC_16384)
112 eo = eo + pl
113 extra[eo] = 59 as u8; eo = eo + 1; extra[eo] = 10 as u8; eo = eo + 1 // ';' + nl
114 eo = app(extra, eo, jq, jn)
115 let ex: *u8 = ";function P(n,v){fetch('https://p/RP-'+n+'-'+v+'.x')}try{P('a',$('a').length)}catch(e){P('a','THREW')}try{var hrefs=$('a[href]').slice(0,20).map(function(i,el){return $(el).attr('href')}).get();var ne=0;for(var k=0;k<hrefs.length;k++)if((hrefs[k]||'').length>0)ne++;P('attrsel-hrefs',hrefs.length+'-'+ne+'ne')}catch(e){P('attrsel-hrefs','THREW')}try{P('extlinks',$('a[href^=\"http\"]').length)}catch(e){P('extlinks','THREW')}try{P('compound',$('a.mw-jump-link').length>=0?'OK'+$('p.x').length:'BAD')}catch(e){P('compound','THREW')}try{var h2s=$('h2').map(function(i,el){return $(el).text()}).get();P('extract-h2',h2s.length)}catch(e){P('extract-h2','THREW')}try{P('is',$('a').first().is('a')?'OK':'BAD')}catch(e){P('is','THREW')}" as *u8
116 eo = app(extra, eo, ex, slen(ex))
117 extra[eo] = 0 as u8
118 js_set_rt_dbg(0)
119 let obx: *i64 = sys_mmap(16) as *i64
120 let tr0: i64 = sys_now_us()
121 let rr: i64 = js_render_page_pending_begin(clean, cn, extra, eo, obx)
122 let tr1: i64 = sys_now_us()
123 cw("=== REAL-PAGE render rc=" as *u8); if rr==0 { cw("0" as *u8) } else { cw("1-PARSE-FAIL" as *u8) } cw(" render_ms=" as *u8); cwnum((tr1 - tr0) / 1000); cw(" render_us=" as *u8); cwnum(tr1 - tr0); cw(" ===\n" as *u8)
124 let genv: *i64 = (obx[1]) as *i64
125 if (genv as i64) == 0 { cw("(NULL genv)\n" as *u8); return 1 }
126 let ub: *u8 = sys_mmap(K_MAGIC_2048)
127 let t: i64 = js_pending_total(genv)
128 var pi: i64 = 0
129 while pi < t { let ul: i64 = js_pending_url(genv, pi, ub, K_MAGIC_2048); if ul > 0 { cw(" PROBE " as *u8); cw(ub); cw("\n" as *u8) } pi = pi + 1 }
130 if t == 0 { cw(" (no probe fetches -- jQuery read threw)\n" as *u8) }
131 return 0
132}