code wiki / _hdl_build / nx_http_chunked_gate.nx

nx_http_chunked_gate.nx source

↩ module page · 68 lines · 4748 B

1// nx_http_chunked_gate.nx -- GATE for nx_http_chunked (M2 unblock: decode HF's chunked API responses). Proves 2// with hand-built fixtures (CRLF = bytes 13,10, no reliance on "\r" literal support): 3// T1 single chunk "5\r\nhello\r\n0\r\n\r\n" -> "hello" 4// T2 multi chunk "3\r\nabc\r\n3\r\ndef\r\n0\r\n\r\n" -> "abcdef" 5// T3 chunk extension "5;x=y\r\nhello\r\n0\r\n\r\n" -> "hello" (extension tolerated) 6// T4 header detect hc_is_chunked("Transfer-Encoding: chunked")==1 ; Content-Length header==0 7// T5 malformed size a body with no hex size -> -1 (never fabricates a decode) 8// GREEN iff T1-T5 pass. Sovereign nx_cc->nxasm. expect_exit: 0 license_tier: ORIGINAL 9import "nx_http_chunked.nx" 10import "nx_syscalls.nx" 11 12func w(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 13func wn(v: i64) -> i64 { var m: i64=v; if m<0{w("-" as *u8);m=0-m} let t:*u8=sys_mmap(24); var k:i64=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} var i:i64=0; let o:*u8=sys_mmap(24); while i<k{o[i]=t[k-1-i];i=i+1} sys_write(1,o,k); return 0 } 14func puts(dst: *u8, off: i64, s: *u8) -> i64 { var o: i64=off; var i: i64=0; while s[i]!=(0 as u8){dst[o]=s[i];o=o+1;i=i+1} return o } 15func crlf(dst: *u8, off: i64) -> i64 { dst[off]=13 as u8; dst[off+1]=10 as u8; return off+2 } 16func memeq(a: *u8, b: *u8, n: i64) -> i64 { var i: i64=0; while i<n { if a[i]!=b[i] { return 0 } i=i+1 } return 1 } 17 18func main() -> i64 { 19 w("=== nx_http_chunked_gate: chunked transfer-encoding decoder (M2 HF-API unblock) ===\n" as *u8) 20 var pass: i64=0; var total: i64=0 21 let out: *u8 = sys_mmap(4096) 22 23 // ---- T1: single chunk ---- 24 let f1: *u8 = sys_mmap(64); var p: i64=0 25 p=puts(f1,p,"5" as *u8); p=crlf(f1,p); p=puts(f1,p,"hello" as *u8); p=crlf(f1,p); p=puts(f1,p,"0" as *u8); p=crlf(f1,p); p=crlf(f1,p) 26 let d1: i64 = chunked_decode(f1, p, out) 27 var t1: i64=1; if d1 != 5 { t1=0 } else { if memeq(out,"hello" as *u8,5)!=1 { t1=0 } } 28 total=total+1; if t1==1 { pass=pass+1; w(" [PASS] " as *u8) } else { w(" [FAIL] " as *u8) } 29 w("T1 single chunk -> len=" as *u8); wn(d1); w(" (expect 5, \"hello\")\n" as *u8) 30 31 // ---- T2: multi chunk ---- 32 let f2: *u8 = sys_mmap(64); p=0 33 p=puts(f2,p,"3" as *u8); p=crlf(f2,p); p=puts(f2,p,"abc" as *u8); p=crlf(f2,p) 34 p=puts(f2,p,"3" as *u8); p=crlf(f2,p); p=puts(f2,p,"def" as *u8); p=crlf(f2,p) 35 p=puts(f2,p,"0" as *u8); p=crlf(f2,p); p=crlf(f2,p) 36 let d2: i64 = chunked_decode(f2, p, out) 37 var t2: i64=1; if d2 != 6 { t2=0 } else { if memeq(out,"abcdef" as *u8,6)!=1 { t2=0 } } 38 total=total+1; if t2==1 { pass=pass+1; w(" [PASS] " as *u8) } else { w(" [FAIL] " as *u8) } 39 w("T2 multi chunk -> len=" as *u8); wn(d2); w(" (expect 6, \"abcdef\")\n" as *u8) 40 41 // ---- T3: chunk extension tolerated ---- 42 let f3: *u8 = sys_mmap(64); p=0 43 p=puts(f3,p,"5;x=y" as *u8); p=crlf(f3,p); p=puts(f3,p,"hello" as *u8); p=crlf(f3,p); p=puts(f3,p,"0" as *u8); p=crlf(f3,p); p=crlf(f3,p) 44 let d3: i64 = chunked_decode(f3, p, out) 45 var t3: i64=1; if d3 != 5 { t3=0 } else { if memeq(out,"hello" as *u8,5)!=1 { t3=0 } } 46 total=total+1; if t3==1 { pass=pass+1; w(" [PASS] " as *u8) } else { w(" [FAIL] " as *u8) } 47 w("T3 chunk extension -> len=" as *u8); wn(d3); w(" (expect 5, \"hello\")\n" as *u8) 48 49 // ---- T4: header detection ---- 50 let h1: *u8 = "HTTP/1.1 200 OK\nTransfer-Encoding: chunked\nServer: x\n" as *u8 51 var h1n: i64=0; while h1[h1n]!=(0 as u8){h1n=h1n+1} 52 let h2: *u8 = "HTTP/1.1 200 OK\nContent-Length: 5\nServer: x\n" as *u8 53 var h2n: i64=0; while h2[h2n]!=(0 as u8){h2n=h2n+1} 54 var t4: i64=1; if hc_is_chunked(h1,h1n)!=1 { t4=0 } if hc_is_chunked(h2,h2n)!=0 { t4=0 } 55 total=total+1; if t4==1 { pass=pass+1; w(" [PASS] " as *u8) } else { w(" [FAIL] " as *u8) } 56 w("T4 header detect: chunked-hdr=" as *u8); wn(hc_is_chunked(h1,h1n)); w(" cl-hdr=" as *u8); wn(hc_is_chunked(h2,h2n)); w(" (expect 1,0)\n" as *u8) 57 58 // ---- T5: malformed size -> -1 ---- 59 let f5: *u8 = sys_mmap(16); f5[0]=(122 as u8); f5[1]=(122 as u8) // "zz" -- not hex 60 let d5: i64 = chunked_decode(f5, 2, out) 61 var t5: i64=1; if d5 != (0 - 1) { t5=0 } 62 total=total+1; if t5==1 { pass=pass+1; w(" [PASS] " as *u8) } else { w(" [FAIL] " as *u8) } 63 w("T5 malformed size -> " as *u8); wn(d5); w(" (expect -1, no fabrication)\n" as *u8) 64 65 w("\n=== nx_http_chunked_gate " as *u8); wn(pass); w("/" as *u8); wn(total) 66 if pass==total { w(" GREEN (chunked decoder: single/multi/extension/detect/malformed; HF dynamic-API enumerate unblocked)\n" as *u8); sys_exit(0); return 0 } 67 w(" RED\n" as *u8); sys_exit(1); return 1 68}