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}