code wiki / (root) / nx_lib_httpd.nx

nx_lib_httpd.nx source

↩ module page · 107 lines · 4500 B

1// nx_lib_httpd.nx -- sovereign HTTP DAEMON for the nishi-library read API. 2// Serves the READ PATH over the wire straight from nx_lib_store, RETIRING the 3// Python serve.py endpoints + its SQLite. No python, no 3rd-party HTTP stack, 4// no shell: raw sovereign sockets (nx_syscalls, pulled via nx_lib_serve -- so 5// we do NOT import nx_syscalls_x86_64.nx = no sys_* double-emit) + the pure 6// router nx_lib_http. 7// GET /api/works -> JSON array of work_hks 8// GET /api/work/<hk> -> JSON work record (200) or 404 9// license_tier: ORIGINAL | genealogy_id: nishi_library_sovereign_httpd_2026_06_30 10import "nx_lib_http.nx" 11 12const LHD_AF_INET: i64 = 2 13const LHD_SOCK_STREAM: i64 = 1 14const LHD_SOL_SOCKET: i64 = 1 15const LHD_SO_REUSEADDR: i64 = 2 16const LHD_PORT: i64 = 8095 17const LHD_BACKLOG: i64 = 128 18const LHD_BUDGET: i64 = 1000000 // JPL-rule-2 bounded accept loop 19 20func lhd_write_all(fd: i64, buf: *u8, n: i64) -> i64 { 21 var off: i64 = 0 22 while off < n { 23 let p: *u8 = ((buf as i64) + off) as *u8 24 let w: i64 = sys_write(fd, p, n - off) 25 if w <= 0 { return 0 } 26 off = off + w 27 } 28 return 0 29} 30 31// read one request off cfd, route via nx_lib_http, write the response. 32// GET -> read routes; POST /api/ingest -> write route. 33func lhd_handle(cfd: i64) -> i64 { 34 let req: *u8 = sys_mmap(131072) 35 let n: i64 = sys_read(cfd, req, 131072) 36 if n < 5 { return 0 } 37 let out: *u8 = sys_mmap(1200000) 38 let m0: i64 = req[0] as i64 39 if m0 == 71 { // 'G' GET ("GET " -> path at 4) 40 let path: *u8 = ((req as i64) + 4) as *u8 41 var pe: i64 = 4 42 var path_end: i64 = 0 - 1 43 while pe < n { if path_end < 0 { if (req[pe] as i64) == 32 { path_end = pe } } pe = pe + 1 } 44 if path_end < 0 { path_end = n } 45 let rn: i64 = lhd_response(path, path_end - 4, out) 46 lhd_write_all(cfd, out, rn) 47 } else { if m0 == 80 { // 'P' POST ("POST " -> path at 5) 48 let path: *u8 = ((req as i64) + 5) as *u8 49 var pe: i64 = 5 50 var path_end: i64 = 0 - 1 51 while pe < n { if path_end < 0 { if (req[pe] as i64) == 32 { path_end = pe } } pe = pe + 1 } 52 if path_end < 0 { path_end = n } 53 let path_n: i64 = path_end - 5 54 // body starts after CRLF CRLF 55 var bs: i64 = 0 - 1 56 var bi: i64 = 0 57 while bi + 3 < n { 58 if bs < 0 { if req[bi] == 13 as u8 { if req[bi+1] == 10 as u8 { if req[bi+2] == 13 as u8 { if req[bi+3] == 10 as u8 { bs = bi + 4 } } } } } 59 bi = bi + 1 60 } 61 if lhd_starts(path, path_n, "/api/ingest" as *u8) == 1 { 62 var bptr: *u8 = ("" as *u8) 63 var blen: i64 = 0 64 if bs >= 0 { bptr = ((req as i64) + bs) as *u8; blen = n - bs } 65 let rn: i64 = lhd_ingest_response(bptr, blen, out) 66 lhd_write_all(cfd, out, rn) 67 } else { 68 let rn: i64 = lhd_response("/nf" as *u8, 3, out) 69 lhd_write_all(cfd, out, rn) 70 } 71 } } 72 return 0 73} 74 75// sockaddr_in (16 bytes) for 0.0.0.0:<port>, port in network (big-endian) order. 76func lhd_sockaddr(addr: *u8, port: i64) -> i64 { 77 addr[0] = 2 as u8 // AF_INET family low byte 78 addr[1] = 0 as u8 79 addr[2] = ((port / 256) & 255) as u8 // port hi (network order) 80 addr[3] = (port & 255) as u8 // port lo 81 var i: i64 = 4 82 while i < 16 { addr[i] = 0 as u8; i = i + 1 } // INADDR_ANY + zero pad 83 return 0 84} 85 86func main() -> i64 { 87 let fd: i64 = sys_socket(LHD_AF_INET, LHD_SOCK_STREAM, 0) 88 if fd < 0 { return 10 } 89 let one: *u8 = sys_mmap(4) 90 one[0] = 1 as u8; one[1] = 0 as u8; one[2] = 0 as u8; one[3] = 0 as u8 91 sys_setsockopt(fd, LHD_SOL_SOCKET, LHD_SO_REUSEADDR, one, 4) 92 let addr: *u8 = sys_mmap(16) 93 lhd_sockaddr(addr, LHD_PORT) 94 if sys_bind(fd, addr, 16) < 0 { return 11 } 95 if sys_listen(fd, LHD_BACKLOG) < 0 { return 12 } 96 nx_lib_index_build() // build the persisted inverted index once at startup (O(1) /api/search) 97 let banner: *u8 = "nx_lib_httpd: sovereign library API on 0.0.0.0:8095 (reads nx_lib_store; no python/sqlite/3rd-party)\n" as *u8 98 sys_write(1, banner, ls_strlen(banner)) 99 var served: i64 = 0 100 while served < LHD_BUDGET { 101 let cfd: i64 = sys_accept(fd) 102 if cfd >= 0 { lhd_handle(cfd); sys_close(cfd) } 103 served = served + 1 104 } 105 sys_close(fd) 106 return 0 107}