code wiki / _hdl_build / nx_meet_http_gate.nx

nx_meet_http_gate.nx source

↩ module page · 76 lines · 5612 B

1// nx_meet_http_gate.nx -- liar-kill gate for P2's live-route brain. Feeds fixture HTTP requests through 2// meet_http_handle and asserts: a clean apply POST is parsed + url-decoded + SCREENED + persisted (200 + thanks), 3// a honeypot-filled POST and an AI-slop POST are FLAGGED, a /request-talent POST routes to hire + SCREENED, a GET 4// is refused (405), and a %0D%0A URL-encoded CRLF injection is stripped in the PERSISTED record. expect_exit: 0 5import "nx_syscalls.nx" 6import "nx_meet_lib.nx" 7import "nx_meet_curate.nx" 8import "nx_meet_http.nx" 9import "nx_meet_store.nx" 10import "nx_gate_verdict.nx" 11 12func has(hay: *u8, n: i64, needle: *u8) -> i64 { 13 let nl: i64 = mlen(needle); if nl == 0 { return 0 } 14 var i: i64 = 0 15 while i + nl <= n { var k: i64=0; var hit: i64=1; while k<nl { if hay[i+k]!=needle[k]{hit=0;k=nl}else{k=k+1} } if hit==1 {return 1} i=i+1 } 16 return 0 17} 18func slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n } 19// 1 if the persisted record for id contains needle. 20func stored_has(id: *u8, needle: *u8) -> i64 { 21 let pq: *i64 = sys_mmap(16) as *i64 22 let lq: *i64 = sys_mmap(16) as *i64 23 if meet_store_get(id, pq, lq) != 1 { return 0 } 24 return has(pq[0] as *u8, lq[0], needle) 25} 26 27func main() -> i64 { 28 mputs("=== nx_meet_http_gate: live-route handler (parse -> urldecode -> screen -> persist -> respond) ===\n" as *u8) 29 30 let clean: *u8 = "POST /apply HTTP/1.1\r\nHost: meet\r\nContent-Type: application/x-www-form-urlencoded\r\n\r\nname=Jane+Doe&email=jane%40example.com&role=Engineer&location=McKinney&resume=Built+payment+service+12000+reqs+jane%40example.com+github&website=&attest=on" as *u8 31 let bot: *u8 = "POST /apply HTTP/1.1\r\nHost: meet\r\n\r\nname=Spammer&email=s%40x.com&resume=Built+12000+jane%40example.com+github&website=http%3A%2F%2Fspam.example" as *u8 32 let slop: *u8 = "POST /apply HTTP/1.1\r\nHost: meet\r\n\r\nname=Bot&email=b%40x.com&resume=As+an+AI+language+model+results-driven+professional+synergy+proven+track+record+detail-oriented&website=" as *u8 33 let hire: *u8 = "POST /request-talent HTTP/1.1\r\nHost: meet\r\n\r\nname=HR&company=Acme+Inc&email=hr%40acme.com&role=Engineer&details=Senior+engineer+at+Acme+https%3A%2F%2Facme.com+salary+150000&website=" as *u8 34 let get: *u8 = "GET /apply HTTP/1.1\r\nHost: meet\r\n\r\n" as *u8 35 let inj: *u8 = "POST /apply HTTP/1.1\r\nHost: meet\r\n\r\nname=Eve%0D%0ABcc:+evil&email=eve%40x.com&resume=Built+12000+jane%40example.com+github&website=" as *u8 36 37 let resp: *u8 = sys_mmap(16384) 38 var pass: i64 = 0; var fail: i64 = 0 39 40 // 1) CLEAN apply 41 let v1: i64 = meet_http_handle(clean, slen(clean), "http-clean" as *u8, resp) 42 if v1 == ST_SCREENED { pass=pass+1 } else { fail=fail+1; mputs(" FAIL clean-not-screened\n" as *u8) } 43 if has(resp, slen(resp), "200 OK" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; mputs(" FAIL clean-no-200\n" as *u8) } 44 if has(resp, slen(resp), "Thanks" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; mputs(" FAIL clean-no-thanks\n" as *u8) } 45 if stored_has("http-clean" as *u8, "status: SCREENED" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; mputs(" FAIL clean-status-not-persisted\n" as *u8) } 46 // url-decode teeth: + -> space, %40 -> @ 47 if stored_has("http-clean" as *u8, "name: Jane Doe" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; mputs(" FAIL name-not-urldecoded\n" as *u8) } 48 if stored_has("http-clean" as *u8, "email: jane@example.com" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; mputs(" FAIL email-not-urldecoded\n" as *u8) } 49 50 // 2) GET -> 405 51 let vg: i64 = meet_http_handle(get, slen(get), "http-get" as *u8, resp) 52 if vg == 0 - 1 { pass=pass+1 } else { fail=fail+1; mputs(" FAIL get-not-refused\n" as *u8) } 53 if has(resp, slen(resp), "405" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; mputs(" FAIL get-no-405\n" as *u8) } 54 55 // 3) honeypot bot -> FLAGGED 56 if meet_http_handle(bot, slen(bot), "http-bot" as *u8, resp) == ST_FLAGGED { pass=pass+1 } else { fail=fail+1; mputs(" FAIL bot-not-flagged\n" as *u8) } 57 // 4) AI-slop -> FLAGGED 58 if meet_http_handle(slop, slen(slop), "http-slop" as *u8, resp) == ST_FLAGGED { pass=pass+1 } else { fail=fail+1; mputs(" FAIL slop-not-flagged\n" as *u8) } 59 // 5) hire route -> SCREENED + persisted kind:hire 60 if meet_http_handle(hire, slen(hire), "http-hire" as *u8, resp) == ST_SCREENED { pass=pass+1 } else { fail=fail+1; mputs(" FAIL hire-not-screened\n" as *u8) } 61 if stored_has("http-hire" as *u8, "kind: hire" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; mputs(" FAIL hire-kind-not-persisted\n" as *u8) } 62 // 6) URL-encoded CRLF injection -> stripped in the persisted record 63 meet_http_handle(inj, slen(inj), "http-inj" as *u8, resp) 64 if stored_has("http-inj" as *u8, "name: EveBcc: evil" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; mputs(" FAIL injection-not-stripped\n" as *u8) } 65 66 mputs("MEET-HTTP-GATE pass=" as *u8); mnum(pass); mputs(" fail=" as *u8); mnum(fail) 67 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check 68 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled 69 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify. 70 let ctr__dry: *i64 = gv_ctr() 71 ctr__dry[0] = pass 72 ctr__dry[1] = pass + fail 73 let rc__dry: i64 = gv_verdict("MEET-HTTP-GATE" as *u8, ctr__dry, "live-route handler: HTTP+form parse, url-decode, screen, persist, respond; injection-safe)" as *u8) 74 sys_exit(rc__dry) 75 return rc__dry 76}