code wiki / _hdl_build / _eg_httpd_ref.nx
_eg_httpd_ref.nx source
↩ module page · 80 lines · 2956 B
1// _eg_httpd_ref.nx -- HAND REFERENCE (written ONCE, scratch) for the PROOF-2 daemon-class target.
2// This is the byte-identical TARGET the generalized walker (nx_eg) must reproduce from a STRUCTURAL
3// spec. It is NOT a constant-variant of nx_eoe's nested-counting-loop shape: its control flow is a real
4// socket->bind->listen->`while accept`->`if cfd<0 continue`->fork->flat-if route dispatch->send, modeled
5// on the live daemons nx_http_server.nx (listen/accept) + nx_sites_daemon.nx (accept/fork/flat-if).
6// Plain NishiLang nx_cc compiles today; loopback bind on a chosen port; GET /health -> 200, default 404.
7// Dialect rails honored: flat-ifs only (LM-002, no else-if chaining), no &&/|| (LM-001), mask-after-shift
8// for the port bytes (LM-005). license_tier: ORIGINAL
9import "nx_syscalls.nx"
10func eh_find(buf: *u8, n: i64, pat: *u8, plen: i64) -> i64 {
11 var i: i64 = 0
12 while i + plen <= n {
13 var j: i64 = 0
14 var ok: i64 = 1
15 while j < plen {
16 if buf[i+j] != pat[j] { ok = 0 }
17 j = j + 1
18 }
19 if ok == 1 { return 1 }
20 i = i + 1
21 }
22 return 0
23}
24func main() -> i64 {
25 let port: i64 = 18080
26 let addr: *u8 = sys_mmap(16)
27 addr[0] = 2 as u8
28 addr[1] = 0 as u8
29 addr[2] = ((port >> 8) & 0xff) as u8
30 addr[3] = (port & 0xff) as u8
31 addr[4] = 127 as u8
32 addr[5] = 0 as u8
33 addr[6] = 0 as u8
34 addr[7] = 1 as u8
35 addr[8] = 0 as u8
36 addr[9] = 0 as u8
37 addr[10] = 0 as u8
38 addr[11] = 0 as u8
39 addr[12] = 0 as u8
40 addr[13] = 0 as u8
41 addr[14] = 0 as u8
42 addr[15] = 0 as u8
43 let lfd: i64 = sys_socket(2, 1, 0)
44 if lfd < 0 { return 10 }
45 let optval: *u8 = sys_mmap(4)
46 optval[0] = 1 as u8
47 optval[1] = 0 as u8
48 optval[2] = 0 as u8
49 optval[3] = 0 as u8
50 sys_setsockopt(lfd, 1, 2, optval, 4)
51 let brc: i64 = sys_bind(lfd, addr, 16)
52 if brc < 0 { return 20 }
53 let lrc: i64 = sys_listen(lfd, 16)
54 if lrc < 0 { return 30 }
55 let req: *u8 = sys_mmap(4096)
56 let ok200: *u8 = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: 2\r\nConnection: close\r\n\r\nok" as *u8
57 let nf404: *u8 = "HTTP/1.1 404 Not Found\r\nContent-Type: text/plain\r\nContent-Length: 9\r\nConnection: close\r\n\r\nnot found" as *u8
58 var served: i64 = 0
59 while served < 64 {
60 let cfd: i64 = sys_accept(lfd)
61 if cfd < 0 { continue }
62 let pid: i64 = sys_fork()
63 if pid == 0 {
64 sys_close(lfd)
65 let rn: i64 = sys_read(cfd, req, 4096)
66 var resp: *u8 = nf404
67 var rlen: i64 = 99
68 let is_health: i64 = eh_find(req, rn, "GET /health" as *u8, 11)
69 if is_health == 1 { resp = ok200 }
70 if is_health == 1 { rlen = 85 }
71 sys_write(cfd, resp, rlen)
72 sys_close(cfd)
73 sys_exit(0)
74 }
75 sys_close(cfd)
76 served = served + 1
77 }
78 sys_close(lfd)
79 return 0
80}