code wiki / _hdl_build / nx_loop_http.nx

nx_loop_http.nx source

↩ module page · 50 lines · 3791 B

1// nx_loop_http.nx -- sovereign plain-HTTP loopback probe (NO shell curl): connect 127.0.0.1:<port>, GET <path>, 2// print "status=<code> ct=<content-type> bytes=<n>" + the first 200 body bytes. For verifying the reader daemon's 3// routes ON THE NAS via nx_reader_diag (the reader terminates plain HTTP on :8791; TLS is at the proxy). Reusable. 4// nx_loop_http <port> <path> 5import "nx_syscalls.nx" 6import "nx_connect.nx" // bounded connect: a raw sys_connect hangs ~127s on a black-holed host 7const K_MAGIC_4096: i64 = 4096 8const K_MAGIC_2097152: i64 = 2097152 9 10func lw(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 11func ln(v: i64) -> i64 { let b: *u8=sys_mmap(24); var m: i64=v; if m<0{lw("-" as *u8);m=0-m} let t: *u8=sys_mmap(24); var k: i64=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} var i: i64=0; while i<k{b[i]=t[k-1-i];i=i+1} sys_write(1,b,k); return 0 } 12func lslen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n } 13func latoi(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 { if c<=57 { v=v*10+(c-48) } } i=i+1 } return v } 14 15func main(argc: i64, argv: *i64) -> i64 { 16 if argc < 3 { lw("usage: nx_loop_http <port> <path>\n" as *u8); return 2 } 17 let port: i64 = latoi(argv[1] as *u8) 18 let path: *u8 = argv[2] as *u8 19 let fd: i64 = sys_socket(2, 1, 0) // AF_INET, SOCK_STREAM 20 if fd < 0 { lw("socket-fail rc=" as *u8); ln(fd); lw("\n" as *u8); return 1 } 21 let sa: *u8 = sys_mmap(16) 22 sa[0] = 2 as u8; sa[1] = 0 as u8 // AF_INET 23 sa[2] = ((port>>8)&0xff) as u8; sa[3] = (port&0xff) as u8 // port BE 24 sa[4] = 127 as u8; sa[5] = 0 as u8; sa[6] = 0 as u8; sa[7] = 1 as u8 // 127.0.0.1 25 var z: i64 = 8; while z < 16 { sa[z] = 0 as u8; z = z + 1 } 26 if nx_connect_bounded(fd, sa, 16, NX_CONN_DEFAULT_MS) < 0 { lw("connect-fail (daemon down?)\n" as *u8); sys_close(fd); return 1 } 27 // request 28 let req: *u8 = sys_mmap(K_MAGIC_4096); var o: i64 = 0 29 let g: *u8 = "GET " as *u8; var i: i64=0; while g[i]!=(0 as u8){req[o]=g[i];o=o+1;i=i+1} 30 i=0; while path[i]!=(0 as u8){req[o]=path[i];o=o+1;i=i+1} 31 let h: *u8 = " HTTP/1.1\r\nHost: 127.0.0.1\r\nConnection: close\r\n\r\n" as *u8; i=0; while h[i]!=(0 as u8){req[o]=h[i];o=o+1;i=i+1} 32 sys_write(fd, req, o) 33 // read all 34 let buf: *u8 = sys_mmap(K_MAGIC_2097152); var tot: i64 = 0; var run: i64 = 1 35 while run == 1 { let r: i64 = sys_read(fd, (buf as i64 + tot) as *u8, K_MAGIC_2097152 - tot); if r <= 0 { run = 0 } else { tot = tot + r } } 36 sys_close(fd) 37 // parse status (after "HTTP/1.1 ") 38 var code: i64 = 0 39 if tot > 12 { code = ((buf[9] as i64 - 48)*100) + ((buf[10] as i64 - 48)*10) + (buf[11] as i64 - 48) } 40 lw("status=" as *u8); ln(code); lw(" bytes=" as *u8); ln(tot); lw("\n" as *u8) 41 // content-type: find "Content-Type:" (case varies; try both) 42 var ci: i64 = 0; var ctat: i64 = 0-1 43 while ci + 13 < tot { if (buf[ci] as i64)==67 { if (buf[ci+8] as i64)==84 { ctat = ci; ci = tot } } ci = ci + 1 } 44 if ctat >= 0 { lw(" " as *u8); var e: i64 = ctat; while e < tot { if (buf[e] as i64)==13 { e = tot } else { let o2: *u8=sys_mmap(1); o2[0]=buf[e]; sys_write(1,o2,1); e=e+1 } } lw("\n" as *u8) } 45 // find body (after \r\n\r\n) and dump first 200 bytes 46 var bi: i64 = 0; var bat: i64 = 0-1 47 while bi + 4 <= tot { if (buf[bi] as i64)==13 { if (buf[bi+1] as i64)==10 { if (buf[bi+2] as i64)==13 { if (buf[bi+3] as i64)==10 { bat = bi+4; bi = tot } } } } bi = bi + 1 } 48 if bat >= 0 { var d: i64 = 200; if bat + d > tot { d = tot - bat } lw(" body[0..200]: " as *u8); sys_write(1, (buf as i64 + bat) as *u8, d); lw("\n" as *u8) } 49 return 0 50}