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}