code wiki / _hdl_build / nx_meet_http.nx
nx_meet_http.nx source
↩ module page · 134 lines · 6226 B
1// nx_meet_http.nx -- P2 (live-route brain, LIBRARY): turn a real HTTP form POST into the gated submission chain.
2// Parses the request (method/path/body) + the url-encoded form body, routes POST /apply | /request-talent,
3// SCREENS (R6 anti-fake + R7 curation), builds a sanitized record, PERSISTS it (P4 seg-store), and returns an
4// HTTP response. The only thing left after this is the socket accept-loop (operator infra: accept -> read ->
5// meet_http_handle -> write -> close). 100% sovereign. license_tier: ORIGINAL
6import "nx_syscalls.nx"
7import "nx_meet_lib.nx"
8import "nx_meet_curate.nx"
9import "nx_meet_intake_process.nx"
10import "nx_meet_store.nx"
11const K_MAGIC_1024: i64 = 1024
12const K_MAGIC_8192: i64 = 8192
13const K_MAGIC_16384: i64 = 16384
14
15func hx(c: i64) -> i64 {
16 if c >= 48 { if c <= 57 { return c - 48 } } // 0-9
17 if c >= 97 { if c <= 102 { return c - 87 } } // a-f
18 if c >= 65 { if c <= 70 { return c - 55 } } // A-F
19 return 0 - 1
20}
21// url-decode src[0..slen) into dst (%XX -> byte, '+' -> space). nul-terminated. returns length.
22func url_decode(src: *u8, slen: i64, dst: *u8) -> i64 {
23 var o: i64 = 0; var i: i64 = 0
24 while i < slen {
25 let c: i64 = src[i] as i64
26 if c == 37 { // '%'
27 var done: i64 = 0
28 if i + 2 < slen {
29 let h1: i64 = hx(src[i+1] as i64); let h2: i64 = hx(src[i+2] as i64)
30 if h1 >= 0 { if h2 >= 0 { dst[o] = ((h1 * 16) + h2) as u8; o = o + 1; i = i + 3; done = 1 } }
31 }
32 if done == 0 { dst[o] = src[i]; o = o + 1; i = i + 1 }
33 } else {
34 if c == 43 { dst[o] = 32 as u8; o = o + 1; i = i + 1 } // '+' -> space
35 else { dst[o] = src[i]; o = o + 1; i = i + 1 }
36 }
37 }
38 dst[o] = 0 as u8
39 return o
40}
41// extract url-encoded field `key` from body[0..blen) -> url-decoded into out. returns len, or -1 if absent.
42func form_get(body: *u8, blen: i64, key: *u8, out: *u8, cap: i64) -> i64 {
43 let kl: i64 = mlen(key)
44 var i: i64 = 0
45 while i < blen {
46 var le: i64 = i
47 while le < blen { if body[le] == (38 as u8) { break } le = le + 1 } // '&'
48 var eq: i64 = i
49 while eq < le { if body[eq] == (61 as u8) { break } eq = eq + 1 } // '='
50 if eq < le {
51 if (eq - i) == kl {
52 var k: i64 = 0; var mok: i64 = 1
53 while k < kl { if body[i+k] != key[k] { mok = 0; k = kl } else { k = k + 1 } }
54 if mok == 1 {
55 let vs: i64 = eq + 1
56 return url_decode((body as i64 + vs) as *u8, le - vs, out)
57 }
58 }
59 }
60 i = le + 1
61 }
62 out[0] = 0 as u8
63 return 0 - 1
64}
65func http_is_post(req: *u8, n: i64) -> i64 {
66 if n < 4 { return 0 }
67 if req[0] == (80 as u8) { if req[1] == (79 as u8) { if req[2] == (83 as u8) { if req[3] == (84 as u8) { return 1 } } } }
68 return 0
69}
70func http_path_is(req: *u8, n: i64, path: *u8) -> i64 {
71 var i: i64 = 0
72 while i < n { if req[i] == (32 as u8) { break } i = i + 1 }
73 i = i + 1
74 let s: i64 = i
75 while i < n { if req[i] == (32 as u8) { break } i = i + 1 }
76 let pl: i64 = mlen(path)
77 if (i - s) != pl { return 0 }
78 var k: i64 = 0
79 while k < pl { if req[s+k] != path[k] { return 0 } k = k + 1 }
80 return 1
81}
82func http_body_off(req: *u8, n: i64) -> i64 {
83 var i: i64 = 0
84 while i + 3 < n {
85 if req[i] == (13 as u8) { if req[i+1] == (10 as u8) { if req[i+2] == (13 as u8) { if req[i+3] == (10 as u8) { return i + 4 } } } }
86 i = i + 1
87 }
88 return 0 - 1
89}
90
91// THE LIVE-ROUTE BRAIN: handle one HTTP request -> screen + sanitize + persist + HTTP response. returns the
92// curation verdict (ST_SCREENED / ST_FLAGGED), or -1 if not a POST to a known route.
93func meet_http_handle(req: *u8, n: i64, id: *u8, resp: *u8) -> i64 {
94 if http_is_post(req, n) == 0 {
95 mcat(resp, 0, "HTTP/1.1 405 Method Not Allowed\r\nContent-Type: text/plain\r\n\r\nUse POST.\n" as *u8)
96 return 0 - 1
97 }
98 var ishire: i64 = 0
99 if http_path_is(req, n, "/request-talent" as *u8) == 1 { ishire = 1 }
100 var kindname: *u8 = "apply" as *u8
101 if ishire == 1 { kindname = "hire" as *u8 }
102
103 let bo: i64 = http_body_off(req, n)
104 var body: *u8 = req; var blen: i64 = 0
105 if bo >= 0 { body = (req as i64 + bo) as *u8; blen = n - bo }
106
107 let nm: *u8 = sys_mmap(K_MAGIC_1024); form_get(body, blen, "name" as *u8, nm, K_MAGIC_1024)
108 let em: *u8 = sys_mmap(K_MAGIC_1024); form_get(body, blen, "email" as *u8, em, K_MAGIC_1024)
109 let ro: *u8 = sys_mmap(K_MAGIC_1024); form_get(body, blen, "role" as *u8, ro, K_MAGIC_1024)
110 let lo: *u8 = sys_mmap(K_MAGIC_1024); form_get(body, blen, "location" as *u8, lo, K_MAGIC_1024)
111 let hp: *u8 = sys_mmap(K_MAGIC_1024); form_get(body, blen, "website" as *u8, hp, K_MAGIC_1024)
112 let scr: *u8 = sys_mmap(K_MAGIC_8192)
113 if ishire == 1 { form_get(body, blen, "details" as *u8, scr, K_MAGIC_8192) } else { form_get(body, blen, "resume" as *u8, scr, K_MAGIC_8192) }
114
115 var verdict: i64 = 0
116 if ishire == 1 { verdict = curate_screen_posting(scr, hp) } else { verdict = curate_screen_resume(scr, hp) }
117
118 // sanitized, persisted application record
119 let rec: *u8 = sys_mmap(K_MAGIC_16384)
120 var o: i64 = rec_field(rec, 0, "kind" as *u8, kindname)
121 o = rec_field(rec, o, "name" as *u8, nm)
122 o = rec_field(rec, o, "email" as *u8, em)
123 o = rec_field(rec, o, "role" as *u8, ro)
124 o = rec_field(rec, o, "location" as *u8, lo)
125 o = rec_field(rec, o, "status" as *u8, curate_state_name(verdict))
126 meet_store_put(id, rec)
127
128 // HTTP response (sovereign 0-JS thank-you)
129 var r: i64 = mcat(resp, 0, "HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n" as *u8)
130 r = mcat(resp, r, "<!doctype html><meta charset=\"utf-8\"><title>Request received</title><h1>Thanks -- your request was received.</h1>" as *u8)
131 if verdict == ST_SCREENED { r = mcat(resp, r, "<p>You passed our checks. Every member is verified before you meet anyone; we will be in touch.</p>" as *u8) }
132 else { r = mcat(resp, r, "<p>Your submission is under review.</p>" as *u8) }
133 return verdict
134}