code wiki / _hdl_build / nx_route.nx

nx_route.nx source

↩ module page · 51 lines · 4056 B

1// nx_route.nx -- the SOVEREIGN S-CLASS ROUTING ENGINE: one declarative pure function every delivery flows through, 2// replacing per-path if-chains. URL path + a resource manifest -> a routing DECISION. S-class properties, uniform 3// for ALL resources (qualitative: clean+canonical+safe; quantitative: one engine, every path handled the same): 4// * CLEAN extensionless URLs: /vn -> serves vn.html ; /foo -> foo/index.html ; exact assets (/x.png,/x.css) served 5// * ONE CANONICAL url: /vn.html -> 301 /vn ; /vn/ -> 301 /vn (trailing slash) -> no more "/vn vs /vn.html" mess 6// * TRAVERSAL-SAFE: any ".." -> 400 (never serves outside the docroot) 7// * deterministic + pure (path+manifest in, decision out) -> fully gateable with zero live-daemon risk. 8// codes: 0=SERVE(out=file) 1=REDIRECT-301(out=location) 2=NOT-FOUND 3=BAD-REQUEST(traversal). license_tier: ORIGINAL 9import "nx_syscalls.nx" 10const K_MAGIC_1024: i64 = 1024 11 12func r_len(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 13func r_cpy(dst: *u8, s: *u8) -> i64 { var i: i64 = 0; while s[i] != (0 as u8) { dst[i] = s[i]; i = i + 1 } dst[i] = 0 as u8; return i } 14func r_cpyn(dst: *u8, s: *u8, n: i64) -> i64 { var i: i64 = 0; while i < n { dst[i] = s[i]; i = i + 1 } dst[i] = 0 as u8; return i } 15func r_ends(s: *u8, suf: *u8) -> i64 { let ls: i64 = r_len(s); let lf: i64 = r_len(suf); if lf > ls { return 0 } var i: i64 = 0; while i < lf { if s[ls-lf+i] != suf[i] { return 0 } i = i + 1 } return 1 } 16func r_dotdot(s: *u8) -> i64 { var i: i64 = 0; while s[i] != (0 as u8) { if s[i] == (46 as u8) { if s[i+1] == (46 as u8) { return 1 } } i = i + 1 } return 0 } 17// substring search 18func r_find(hay: *u8, needle: *u8) -> i64 { 19 let nl: i64 = r_len(needle); if nl == 0 { return 1 } 20 var i: i64 = 0 21 while hay[i] != (0 as u8) { var j: i64 = 0; var ok: i64 = 1; while j < nl { if hay[i+j] != needle[j] { ok = 0; j = nl } else { j = j + 1 } } if ok == 1 { return 1 } i = i + 1 } 22 return 0 23} 24// is `entry` a whole line in manifest? (manifest is newline-bounded: starts+ends with '\n') 25func r_mem(manifest: *u8, entry: *u8) -> i64 { 26 let nd: *u8 = sys_mmap(K_MAGIC_1024); var o: i64 = 0; nd[o] = 10 as u8; o = o + 1 27 var i: i64 = 0; while entry[i] != (0 as u8) { nd[o] = entry[i]; o = o + 1; i = i + 1 } nd[o] = 10 as u8; o = o + 1; nd[o] = 0 as u8 28 return r_find(manifest, nd) 29} 30 31// THE ENGINE. path = request path (no query). manifest = "\n/a.html\n/b/index.html\n..." . out = result string. 32func route(path: *u8, manifest: *u8, out: *u8) -> i64 { 33 if r_dotdot(path) == 1 { r_cpy(out, "/" as *u8); return 3 } // traversal -> bad request 34 let n: i64 = r_len(path) 35 if n == 0 { r_cpy(out, "/" as *u8); return 1 } // empty -> / 36 // canonical: strip trailing slash (except root) 37 if n > 1 { if path[n-1] == (47 as u8) { r_cpyn(out, path, n-1); return 1 } } 38 // canonical: .html -> extensionless 39 if r_ends(path, ".html" as *u8) == 1 { r_cpyn(out, path, n-5); return 1 } 40 // resolve to a served file 41 if n == 1 { // "/" 42 if r_mem(manifest, "/index.html" as *u8) == 1 { r_cpy(out, "/index.html" as *u8); return 0 } 43 return 2 44 } 45 let c1: *u8 = sys_mmap(K_MAGIC_1024); let l1: i64 = r_cpy(c1, path); c1[l1] = 46 as u8; c1[l1+1]=104 as u8; c1[l1+2]=116 as u8; c1[l1+3]=109 as u8; c1[l1+4]=108 as u8; c1[l1+5]=0 as u8 // path + ".html" 46 if r_mem(manifest, c1) == 1 { r_cpy(out, c1); return 0 } 47 let c2: *u8 = sys_mmap(K_MAGIC_1024); var l2: i64 = r_cpy(c2, path); c2[l2]=47 as u8; l2 = l2 + 1; var k: i64 = 0; let idx: *u8 = "index.html" as *u8; while idx[k] != (0 as u8) { c2[l2]=idx[k]; l2=l2+1; k=k+1 } c2[l2]=0 as u8 // path + "/index.html" 48 if r_mem(manifest, c2) == 1 { r_cpy(out, c2); return 0 } 49 if r_mem(manifest, path) == 1 { r_cpy(out, path); return 0 } // exact asset (.png/.css/...) 50 return 2 // not found 51}