code wiki / _hdl_build / nx_lib_research_alias_gate.nx
nx_lib_research_alias_gate.nx source
↩ module page · 75 lines · 3867 B
1// nx_lib_research_alias_gate.nx -- gate for the /research edge-prefix alias in nx_lib_http.
2// The sites edge conf-routes `nishifamily.com /research 8095 stream`; STREAM mode passes the
3// RAW request through (no prefix strip), so lhd_response now accepts the /research prefix by
4// delegating to the identical stripped route. This gate PROVES the alias byte-identical:
5// T1 /research/ == / (home)
6// T2 /research/api/works == /api/works (JSON API)
7// T3 /research?q=cat == /?q=cat (re-rooted query form)
8// T4 /research == / (bare prefix -> home)
9// NEG T5 /researchfoo -> 404 (prefix must be followed by / or ? -- no greedy match)
10// NEG T6 /bogus -> 404 (untouched routes still 404)
11// license_tier: ORIGINAL
12import "nx_lib_http.nx"
13import "nx_gate_verdict.nx"
14
15func ga_eq(a: *u8, an: i64, b: *u8, bn: i64) -> i64 {
16 if an != bn { return 0 }
17 var i: i64 = 0
18 while i < an { if a[i] != b[i] { return 0 } i = i + 1 }
19 return 1
20}
21
22func ga_has404(a: *u8, an: i64) -> i64 {
23 // look for "404" in the status line
24 var i: i64 = 0
25 while i + 2 < an {
26 if a[i] == 52 as u8 { if a[i+1] == 48 as u8 { if a[i+2] == 52 as u8 { return 1 } } }
27 i = i + 1
28 }
29 return 0
30}
31
32func ga_len(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
33func ga_puts(s: *u8) -> i64 { sys_write(1, s, ga_len(s)); return 0 }
34
35// run one equality case: alias path vs canonical path must be byte-identical and non-empty.
36func ga_case(name: *u8, ap: *u8, cp: *u8, oa: *u8, ob: *u8) -> i64 {
37 let an: i64 = lhd_response(ap, ga_len(ap), oa)
38 let bn: i64 = lhd_response(cp, ga_len(cp), ob)
39 if an <= 0 { ga_puts(" [FAIL] " as *u8); ga_puts(name); ga_puts(" (empty alias response)\n" as *u8); return 0 }
40 if ga_eq(oa, an, ob, bn) == 0 { ga_puts(" [FAIL] " as *u8); ga_puts(name); ga_puts(" (alias != canonical)\n" as *u8); return 0 }
41 ga_puts(" [OK] " as *u8); ga_puts(name); ga_puts("\n" as *u8)
42 return 1
43}
44
45func main() -> i64 {
46 ga_puts("=== nx_lib_research_alias_gate: /research prefix alias byte-identical ===\n" as *u8)
47 let oa: *u8 = sys_mmap(1300000)
48 let ob: *u8 = sys_mmap(1300000)
49 var pass: i64 = 0
50
51 pass = pass + ga_case("T1 /research/ == /" as *u8, "/research/" as *u8, "/" as *u8, oa, ob)
52 pass = pass + ga_case("T2 /research/api/works == /api/works" as *u8, "/research/api/works" as *u8, "/api/works" as *u8, oa, ob)
53 pass = pass + ga_case("T3 /research?q=cat == /?q=cat" as *u8, "/research?q=cat" as *u8, "/?q=cat" as *u8, oa, ob)
54 pass = pass + ga_case("T4 /research == /" as *u8, "/research" as *u8, "/" as *u8, oa, ob)
55
56 // NEG T5: /researchfoo must NOT alias (no greedy prefix) -> 404
57 let n5: i64 = lhd_response("/researchfoo" as *u8, 12, oa)
58 if ga_has404(oa, n5) == 1 { ga_puts(" [OK] NEG T5 /researchfoo -> 404\n" as *u8); pass = pass + 1 }
59 else { ga_puts(" [FAIL] NEG T5 /researchfoo did not 404\n" as *u8) }
60
61 // NEG T6: unrelated path still 404s
62 let n6: i64 = lhd_response("/bogus" as *u8, 6, oa)
63 if ga_has404(oa, n6) == 1 { ga_puts(" [OK] NEG T6 /bogus -> 404\n" as *u8); pass = pass + 1 }
64 else { ga_puts(" [FAIL] NEG T6 /bogus did not 404\n" as *u8) }
65
66 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check
67 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled
68 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify.
69 let ctr__dry: *i64 = gv_ctr()
70 ctr__dry[0] = pass
71 ctr__dry[1] = 6
72 let rc__dry: i64 = gv_verdict("LIB-RESEARCH-ALIAS-GATE" as *u8, ctr__dry, "teeth unchanged; verdict emission migrated onto the shared base class" as *u8)
73 sys_exit(rc__dry)
74 return rc__dry
75}