code wiki / _hdl_build / nx_host_router_gate.nx

nx_host_router_gate.nx source

↩ module page · 98 lines · 5916 B

1// nx_host_router_gate.nx -- proves hr_serve3 (S-class routing) end-to-end against a REAL temp docroot. 2// Routing is a property of the HOST: ONE resolver gives clean URLs (dir AND flat layouts) + real 301s to 3// ONE canonical URL, while (a) keeping dir-index PRECEDENCE so an existing hub is never shadowed, and 4// (b) never 301-ing into a 404. This is the live-daemon counterpart of nx_route_gate (pure logic, 5/5). 5// license_tier: ORIGINAL expect_exit: 0 6import "nx_host_router.nx" 7import "nx_syscalls.nx" 8 9func w(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 10func 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 } 11func slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n } 12 13func mkfile(p: *u8, c: *u8) -> i64 { 14 let fd: i64 = sys_openat_wr(p, 420) 15 if fd < 0 { w(" CANNOT CREATE "); w(p); w("\n" as *u8); return 1 } 16 sys_write(fd, c, slen(c)); sys_close(fd); return 0 17} 18func mkreq(buf: *u8, path: *u8) -> i64 { 19 var j: i64=0; var k: i64=0 20 let a: *u8="GET " as *u8; while a[k]!=(0 as u8){buf[j]=a[k];j=j+1;k=k+1} 21 k=0; while path[k]!=(0 as u8){buf[j]=path[k];j=j+1;k=k+1} 22 let b: *u8=" HTTP/1.1\r\nHost: nishifamily.com\r\n\r\n" as *u8 23 k=0; while b[k]!=(0 as u8){buf[j]=b[k];j=j+1;k=k+1} 24 return j 25} 26// substring search in h[0..n) 27func hsearch(h: *u8, n: i64, ndl: *u8) -> i64 { 28 let nl: i64 = slen(ndl); if nl==0 { return 0 } 29 var i: i64=0 30 while i+nl<=n { var j: i64=0; var ok: i64=1; while j<nl{ if h[i+j]!=ndl[j]{ok=0;j=nl} else {j=j+1} } if ok==1{return 1} i=i+1 } 31 return 0 32} 33 34// run one request; check verdict + (optional) marker substring present in the response bytes. 35func chk(cfg: *u8, cfgn: i64, path: *u8, expv: i64, marker: *u8) -> i64 { 36 let req: *u8 = sys_mmap(4096); let reqn: i64 = mkreq(req, path) 37 let out: *u8 = sys_mmap(65536); let out_n: *i64 = (sys_mmap(8)) as *i64 38 let v: i64 = hr_serve3(cfg, cfgn, req, reqn, out, 65536, out_n) 39 var ok: i64 = 1 40 if v != expv { ok = 0 } 41 if (marker as i64) != 0 { if hsearch(out, out_n[0], marker) == 0 { ok = 0 } } 42 w(" "); w(path); w(" -> v="); wn(v); w(" n="); wn(out_n[0]) 43 if ok==1 { w(" ok\n" as *u8) } else { w(" FAIL(exp v="); wn(expv); w(")\n" as *u8) } 44 return ok 45} 46 47func main(argc: i64, argv: *i64) -> i64 { 48 w("=== nx_host_router_gate -- hr_serve3 S-class routing on a live docroot ===\n" as *u8) 49 sys_mkdir("/tmp/hrt" as *u8, 0x1ed); sys_mkdir("/tmp/hrt/blog" as *u8, 0x1ed); sys_mkdir("/tmp/hrt/games" as *u8, 0x1ed) 50 mkfile("/tmp/hrt/index.html" as *u8, "<!doctype html><h1>HOMEPAGE-ROOT</h1>" as *u8) 51 mkfile("/tmp/hrt/style.css" as *u8, "body{color:red}" as *u8) 52 mkfile("/tmp/hrt/blog/index.html" as *u8, "<!doctype html><h1>BLOG-INDEX</h1>" as *u8) 53 mkfile("/tmp/hrt/vn.html" as *u8, "<!doctype html><h1>VN-FLATFILE</h1>" as *u8) 54 mkfile("/tmp/hrt/games/index.html" as *u8, "<!doctype html><h1>GAMES-HUB-DIR</h1>" as *u8) 55 mkfile("/tmp/hrt/games.html" as *u8, "<!doctype html><h1>GAMES-STALE-FLAT</h1>" as *u8) 56 let cfg: *u8 = "* /tmp/hrt\n" as *u8 57 let cfgn: i64 = slen(cfg) 58 var pass: i64 = 0; var tot: i64 = 0 59 60 w(" T1 clean URLs serve (dir + flat + root):\n" as *u8) 61 var a: i64 = 1 62 if chk(cfg,cfgn,"/blog" as *u8, HR_S2_OK, "BLOG-INDEX" as *u8)==0 { a=0 } 63 if chk(cfg,cfgn,"/vn" as *u8, HR_S2_OK, "VN-FLATFILE" as *u8)==0 { a=0 } 64 if chk(cfg,cfgn,"/" as *u8, HR_S2_OK, "HOMEPAGE-ROOT" as *u8)==0 { a=0 } 65 tot=tot+1; if a==1 { pass=pass+1; w(" PASS T1\n" as *u8) } else { w(" FAIL T1\n" as *u8) } 66 67 w(" T2 ONE canonical URL via REAL 301 (.html / trailing-slash / index.html):\n" as *u8) 68 var b: i64 = 1 69 if chk(cfg,cfgn,"/vn.html" as *u8, HR_S2_REDIR, "Location: /vn\r" as *u8)==0 { b=0 } 70 if chk(cfg,cfgn,"/blog/" as *u8, HR_S2_REDIR, "Location: /blog\r" as *u8)==0 { b=0 } 71 if chk(cfg,cfgn,"/index.html" as *u8, HR_S2_REDIR, "Location: /\r" as *u8)==0 { b=0 } 72 if chk(cfg,cfgn,"/blog/index.html" as *u8, HR_S2_REDIR, "Location: /blog\r" as *u8)==0 { b=0 } 73 if chk(cfg,cfgn,"/vn.html" as *u8, HR_S2_REDIR, "301 Moved" as *u8)==0 { b=0 } 74 tot=tot+1; if b==1 { pass=pass+1; w(" PASS T2\n" as *u8) } else { w(" FAIL T2\n" as *u8) } 75 76 w(" T3 assets served exact (MIME + bytes):\n" as *u8) 77 var c: i64 = 1 78 if chk(cfg,cfgn,"/style.css" as *u8, HR_S2_OK, "body{color:red}" as *u8)==0 { c=0 } 79 if chk(cfg,cfgn,"/style.css" as *u8, HR_S2_OK, "text/css" as *u8)==0 { c=0 } 80 tot=tot+1; if c==1 { pass=pass+1; w(" PASS T3\n" as *u8) } else { w(" FAIL T3\n" as *u8) } 81 82 w(" T4 safe: traversal 400, miss falls through, NO 301-to-404 (neg-controls):\n" as *u8) 83 var d: i64 = 1 84 if chk(cfg,cfgn,"/a/../b" as *u8, HR_S2_BAD, "400" as *u8)==0 { d=0 } 85 if chk(cfg,cfgn,"/nope" as *u8, HR_S2_MISS, 0 as *u8)==0 { d=0 } 86 if chk(cfg,cfgn,"/ghost.html" as *u8, HR_S2_MISS, 0 as *u8)==0 { d=0 } 87 tot=tot+1; if d==1 { pass=pass+1; w(" PASS T4\n" as *u8) } else { w(" FAIL T4\n" as *u8) } 88 89 w(" T5 NO REGRESSION: dir-index keeps precedence (hub not shadowed by stale flat) + flat 301s to it:\n" as *u8) 90 var e: i64 = 1 91 if chk(cfg,cfgn,"/games" as *u8, HR_S2_OK, "GAMES-HUB-DIR" as *u8)==0 { e=0 } 92 if chk(cfg,cfgn,"/games.html" as *u8, HR_S2_REDIR, "Location: /games\r" as *u8)==0 { e=0 } 93 tot=tot+1; if e==1 { pass=pass+1; w(" PASS T5\n" as *u8) } else { w(" FAIL T5\n" as *u8) } 94 95 w("nx_host_router_gate pass="); wn(pass); w("/"); wn(tot) 96 if pass==tot { w(" verdict=GREEN (S-class routing LIVE-handler: clean + canonical-301 + safe + no-regression)\n" as *u8); sys_exit(0); return 0 } 97 w(" verdict=RED\n" as *u8); sys_exit(1); return 1 98}