code wiki / _hdl_build / nx_ad_banner_daemon.nx

nx_ad_banner_daemon.nx source

↩ module page · 85 lines · 4522 B

1// nx_ad_banner_daemon.nx -- a thin standalone HTTP daemon that serves the BANNER BUILDER live for testing. 2// GET any path -> the builder form; POST -> the form re-rendered with the generated banner preview + HTML. 3// Server-rendered, ZERO JavaScript. Composes nx_ad_banner_builder (abb_page). Plain HTTP (loopback/LAN); 4// TLS-fronting is a later rung. argv: [1]=port (default 8093). Sovereign, no gcc/.sh. license_tier: ORIGINAL 5import "nx_ad_banner_builder.nx" 6import "nx_syscalls.nx" 7const K_MAGIC_262144: i64 = 262144 8const K_MAGIC_8093: i64 = 8093 9const K_MAGIC_1000000: i64 = 1000000 10const K_MAGIC_65536: i64 = 65536 11const K_MAGIC_65535: i64 = 65535 12 13func bd_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 14func bd_atoi(s: *u8) -> i64 { var v: i64 = 0; var i: i64 = 0; while s[i] != (0 as u8) { let c: i64 = s[i] as i64; if c < 48 { return v } if c > 57 { return v } v = v * 10 + (c - 48); i = i + 1 } return v } 15func bd_cat(dst: *u8, off: i64, s: *u8) -> i64 { var o: i64 = off; var i: i64 = 0; while s[i] != (0 as u8) { dst[o] = s[i]; o = o + 1; i = i + 1 } return o } 16func bd_catb(dst: *u8, off: i64, src: *u8, n: i64) -> i64 { var o: i64 = off; var i: i64 = 0; while i < n { dst[o] = src[i]; o = o + 1; i = i + 1 } return o } 17func bd_itoa(dst: *u8, off: i64, v: i64) -> i64 { 18 let t: *u8 = sys_mmap(28); var m: i64 = v; var k: i64 = 0 19 if m == 0 { t[0] = 48 as u8; k = 1 } 20 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 21 var o: i64 = off; var q: i64 = k - 1 22 while q >= 0 { dst[o] = t[q]; o = o + 1; q = q - 1 } 23 return o 24} 25func bd_find(buf: *u8, n: i64, needle: *u8, nl: i64) -> i64 { 26 if nl == 0 { return 0 } 27 var i: i64 = 0 28 while i + nl <= n { var j: i64 = 0; var ok: i64 = 1; while j < nl { if buf[i + j] != needle[j] { ok = 0; j = nl } else { j = j + 1 } } if ok == 1 { return i } i = i + 1 } 29 return 0 - 1 30} 31func bd_starts(buf: *u8, n: i64, pre: *u8) -> i64 { var i: i64 = 0; while pre[i] != (0 as u8) { if i >= n { return 0 } if buf[i] != pre[i] { return 0 } i = i + 1 } return 1 } 32 33// send a full HTTP/1.1 response in one write. 34func bd_send(cfd: i64, status: *u8, body: *u8, blen: i64) -> i64 { 35 let buf: *u8 = sys_mmap(K_MAGIC_262144); var o: i64 = 0 36 o = bd_cat(buf, o, "HTTP/1.1 " as *u8); o = bd_cat(buf, o, status) 37 o = bd_cat(buf, o, "\r\nContent-Type: text/html; charset=utf-8\r\nContent-Length: " as *u8); o = bd_itoa(buf, o, blen) 38 o = bd_cat(buf, o, "\r\nConnection: close\r\nCache-Control: no-store\r\nReferrer-Policy: no-referrer\r\n\r\n" as *u8) 39 o = bd_catb(buf, o, body, blen) 40 sys_write(cfd, buf, o); return 0 41} 42 43func main(argc: i64, argv: *i64) -> i64 { 44 var port: i64 = K_MAGIC_8093 45 if argc >= 2 { port = bd_atoi(argv[1] as *u8) } 46 47 let addr: *u8 = sys_mmap(16) 48 addr[0] = 2 as u8; addr[1] = 0 as u8 49 addr[2] = ((port >> 8) & 0xff) as u8; addr[3] = (port & 0xff) as u8 50 var zi: i64 = 4; while zi < 16 { addr[zi] = 0 as u8; zi = zi + 1 } 51 let lfd: i64 = sys_socket(2, 1, 0) 52 if lfd < 0 { sys_write(1, "SOCKET-FAIL\n" as *u8, 12); sys_exit(1); return 1 } 53 let optv: *u8 = sys_mmap(4); optv[0] = 1 as u8 54 sys_setsockopt(lfd, 1, 2, optv, 4) 55 if sys_bind(lfd, addr, 16) < 0 { sys_write(1, "BIND-FAIL\n" as *u8, 10); sys_exit(1); return 1 } 56 if sys_listen(lfd, 16) < 0 { sys_write(1, "LISTEN-FAIL\n" as *u8, 12); sys_exit(1); return 1 } 57 sys_write(1, "BANNER-BUILDER-UP\n" as *u8, 18) 58 59 let empty: *u8 = sys_mmap(8); empty[0] = 0 as u8 60 var served: i64 = 0 61 while served < K_MAGIC_1000000 { 62 let cfd: i64 = sys_accept(lfd) 63 if cfd >= 0 { 64 sys_set_socket_timeout(cfd, 5) 65 let req: *u8 = sys_mmap(K_MAGIC_65536) 66 let rn: i64 = sys_read(cfd, req, K_MAGIC_65535) 67 if rn > 0 { 68 let he: i64 = bd_find(req, rn, "\r\n\r\n" as *u8, 4) 69 let out: *u8 = sys_mmap(K_MAGIC_262144) 70 var glen: i64 = 0 71 if bd_starts(req, rn, "POST" as *u8) == 1 { 72 var body: *u8 = empty; var bn: i64 = 0 73 if he >= 0 { body = ((req as i64) + he + 4) as *u8; bn = rn - he - 4 } 74 glen = abb_page(body, bn, out) 75 } else { 76 glen = abb_page(empty, 0, out) 77 } 78 bd_send(cfd, "200 OK" as *u8, out, glen) 79 } 80 sys_close(cfd) 81 } 82 served = served + 1 83 } 84 sys_close(lfd); sys_exit(0); return 0 85}