nx_galx_seek_test.nx source
↩ module page · 64 lines · 3966 B
1// nx_galx_seek_test.nx -- SOVEREIGN HTTP test client for the gallery daemon (replaces curl).
2// Connects to 127.0.0.1:18090, GETs argv[1], prints status+byte count, and writes the response
3// BODY (after the \r\n\r\n header terminator) to argv[2] if given (so a /vid seek stream can be
4// fed to nx_mp4_probe). Reuses nx_http_get_ua (the bits-up plain-TCP GET). license_tier: ORIGINAL
5import "nx_http_get_ua.nx"
6import "nx_connect.nx" // bounded connect: a raw sys_connect hangs ~127s on a black-holed host
7import "nx_syscalls.nx"
8
9func pr(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
10func prn(v: i64) -> i64 { var m: i64=v; if m<0 {m=0-m} let b: *u8=sys_mmap(32); var i: i64=32; if m==0 {i=i-1; b[i]=(48 as u8)} while m>0 { let q: i64=m/10; i=i-1; b[i]=((48+(m-q*10)) as u8); m=q } return sys_write(1, ((b as i64)+i) as *u8, 32-i) }
11// sockaddr_in for 127.0.0.1:port (16 bytes: family=2, port BE, 127.0.0.1, zero pad)
12func mkaddr(buf: *u8, port: i64) -> i64 {
13 buf[0]=(2 as u8); buf[1]=(0 as u8)
14 buf[2]=((port>>8)&0xff) as u8; buf[3]=(port&0xff) as u8
15 buf[4]=(127 as u8); buf[5]=(0 as u8); buf[6]=(0 as u8); buf[7]=(1 as u8)
16 var i: i64=8; while i<16 { buf[i]=(0 as u8); i=i+1 }
17 return 0
18}
19func body_off(b: *u8, n: i64) -> i64 { var i: i64=0; while i+3<n { if b[i]==(13 as u8) { if b[i+1]==(10 as u8) { if b[i+2]==(13 as u8) { if b[i+3]==(10 as u8) { return i+4 } } } } i=i+1 } return 0-1 }
20func wput(b: *u8, o: i64, s: *u8) -> i64 { var i: i64=0; while s[i]!=(0 as u8){ b[o]=s[i]; o=o+1; i=i+1 } return o }
21// GET with a Range header (nx_http_get_ua can't) -> verify the daemon answers 206 for native-container seeking.
22func range_get(addr: *u8, path: *u8, rng: *u8, out: *u8, cap: i64, stt: *i64) -> i64 {
23 stt[0]=0
24 let fd: i64 = sys_socket(2,1,0); if fd<0 { return 0-1 }
25 if nx_connect_bounded(fd, addr, 16, NX_CONN_DEFAULT_MS) < 0 { sys_close(fd); return 0-1 }
26 let req: *u8 = sys_mmap(4096); var o: i64=0
27 o=wput(req,o,"GET " as *u8); o=wput(req,o,path); o=wput(req,o," HTTP/1.1\r\nHost: 127.0.0.1\r\nUser-Agent: nx\r\nRange: bytes=" as *u8); o=wput(req,o,rng); o=wput(req,o,"\r\nConnection: close\r\n\r\n" as *u8)
28 sys_write(fd, req, o)
29 var off: i64=0; var keep: i64=1
30 while keep==1 { if off>=cap { keep=0 } else { let r: i64=sys_read(fd, ((out as i64)+off) as *u8, cap-off); if r<=0 { keep=0 } else { off=off+r } } }
31 sys_close(fd)
32 if off>12 { stt[0]=(out[9] as i64-0x30)*100+(out[10] as i64-0x30)*10+(out[11] as i64-0x30) }
33 return off
34}
35
36func main(argc: i64, argv: *i64) -> i64 {
37 if argc < 2 { pr("usage: nx_galx_seek_test <path> [outfile]\n" as *u8); return 2 }
38 let path: *u8 = argv[1] as *u8
39 var outf: *u8 = 0 as *u8
40 if argc >= 3 { outf = argv[2] as *u8 }
41 let addr: *u8 = sys_mmap(16); mkaddr(addr, 18090)
42 let host: *u8 = "127.0.0.1" as *u8
43 let ua: *u8 = "nx-seektest" as *u8
44 let cap: i64 = 8388608
45 let out: *u8 = sys_mmap(cap + 16)
46 let st: *i64 = sys_mmap(16) as *i64
47 let t0: i64 = sys_clock_now_us()
48 var n: i64 = 0
49 if argc >= 4 { n = range_get(addr, path, argv[3] as *u8, out, cap, st) } else { n = nx_http_get_ua(addr, path, nx_str_len(path), host, 9, ua, 11, out, cap, st) }
50 let dt: i64 = sys_clock_now_us() - t0
51 pr("GET " as *u8); pr(path); pr(" status=" as *u8); prn(st[0]); pr(" bytes=" as *u8); prn(n); pr(" us=" as *u8); prn(dt); pr("\n" as *u8)
52 let bo: i64 = body_off(out, n)
53 if argc >= 4 { if bo > 0 { pr("--- headers ---\n" as *u8); sys_write(1, out, bo) } }
54 if bo >= 0 {
55 if (outf as i64) != 0 {
56 let fd: i64 = sys_openat_wr(outf, 0x1a4)
57 if fd >= 0 { sys_write(fd, ((out as i64)+bo) as *u8, n-bo); sys_close(fd) }
58 pr(" body -> " as *u8); pr(outf); pr(" (" as *u8); prn(n-bo); pr(" bytes)\n" as *u8)
59 } else {
60 sys_write(1, ((out as i64)+bo) as *u8, n-bo); pr("\n" as *u8)
61 }
62 }
63 return 0
64}