code wiki / (root) / nx_galx_seek_test.nx

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}