code wiki / _hdl_build / nx_http_head_probe.nx

nx_http_head_probe.nx source

↩ module page · 81 lines · 3836 B

1// nx_http_head_probe.nx -- diagnostic: fetch a URL and print the HTTP 2// status line + transfer model + key headers (Location, Content-Type). 3// The measure-first tool for "what does this URL actually return?" -- 4// distinguishes a 3xx redirect (needs redirect-following) from a 200 5// with empty/JS body. Composes the SAME sovereign stack as nish 6// (nx_https_get + nx_http_response_parse), no new capability. 7// nx_http_head_probe <https-url> 8// (B)-tutor diagnostic; reusable basis for nish redirect-following. 9import "nx_syscalls.nx" 10import "nx_x509_trust_store.nx" 11import "nx_trust_store_load_from_certdata.nx" 12import "nx_https_get.nx" 13import "nx_http_response_parse.nx" 14const K_MAGIC_4194304: i64 = 4194304 15const K_MAGIC_524288: i64 = 524288 16 17func _p(fd: i64, s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(fd,s,n); return 0 } 18func _pn(fd: i64, v: i64) -> i64 { 19 let bb: *u8 = sys_mmap(28); var m: i64=v; if m<0{m=0-m}; let t: *u8 = sys_mmap(28); var k: i64=0 20 if m==0 { t[0]=48 as u8; k=1 } 21 while m>0 { t[k]=(48+(m%10)) as u8; m=m/10; k=k+1 } 22 var i: i64=0; while i<k { bb[i]=t[k-1-i]; i=i+1 } 23 sys_write(fd,bb,k); return 0 24} 25 26// Print the raw header value at (buf+off, len) to fd. 27func _pv(fd: i64, buf: *u8, off: i64, len: i64) -> i64 { 28 let base: i64 = buf as i64 29 sys_write(fd, (base + off) as *u8, len) 30 return 0 31} 32 33func main(argc: i64, argv: *i64) -> i64 { 34 if argc < 2 { _p(2, "usage: nx_http_head_probe <https-url>\n" as *u8); sys_exit(2); return 2 } 35 let url: *u8 = argv[1] as *u8 36 37 var rr: i64 = nx_trust_store_load_from_certdata("data/mozilla_certdata.txt" as *u8, 300, K_MAGIC_4194304) 38 if rr <= 0 { rr = nx_trust_store_load_from_certdata("/tmp/mozilla_certdata.txt" as *u8, 300, K_MAGIC_4194304) } 39 if rr <= 0 { _p(2, "CA-load-fail\n" as *u8); sys_exit(3); return 3 } 40 let store: *TrustStore = rr as *TrustStore 41 42 let cr: *u8 = sys_mmap(32) 43 let priv: *u8 = sys_mmap(32) 44 let ufd: i64 = sys_openat_rd("/dev/urandom" as *u8) 45 if ufd >= 0 { sys_read(ufd, cr, 32); sys_read(ufd, priv, 32); sys_close(ufd) } 46 47 let now: i64 = sys_now_realtime_sec() 48 let cap: i64 = K_MAGIC_524288 49 let buf: *u8 = sys_mmap(cap) 50 let n: i64 = nx_https_get(url, cr, priv, store, now, buf, cap) 51 if n < 0 { _p(1, "FETCH_VERDICT=" as *u8); _pn(1, 0 - n); _p(1, "\n" as *u8); sys_exit(0); return 0 } 52 53 _p(1, "RAWLEN=" as *u8); _pn(1, n); _p(1, "\n" as *u8) 54 55 let r: *i64 = nx_http_resp_alloc() 56 let pv: i64 = nx_http_response_parse(buf, n, r) 57 _p(1, "PARSE=" as *u8); _pn(1, pv); _p(1, "\n" as *u8) 58 if pv == NX_HTTP_RESP_OK { 59 _p(1, "STATUS=" as *u8); _pn(1, r[1]); _p(1, "\n" as *u8) 60 _p(1, "KIND=" as *u8); _pn(1, r[8]); _p(1, " (1=clen 2=chunked 3=until-close)\n" as *u8) 61 _p(1, "CLEN=" as *u8); _pn(1, r[9]); _p(1, "\n" as *u8) 62 _p(1, "BODYLEN=" as *u8); _pn(1, n - r[6]); _p(1, "\n" as *u8) 63 64 let vo: *i64 = sys_mmap(8) as *i64 65 let vl: *i64 = sys_mmap(8) as *i64 66 let loc: *u8 = sys_mmap(16) 67 loc[0]=76 as u8; loc[1]=111 as u8; loc[2]=99 as u8; loc[3]=97 as u8 68 loc[4]=116 as u8; loc[5]=105 as u8; loc[6]=111 as u8; loc[7]=110 as u8 69 if nx_http_response_header(buf, n, r, loc, 8, vo, vl) == 1 { 70 _p(1, "LOCATION=" as *u8); _pv(1, buf, vo[0], vl[0]); _p(1, "\n" as *u8) 71 } 72 let ct: *u8 = sys_mmap(16) 73 ct[0]=67 as u8; ct[1]=111 as u8; ct[2]=110 as u8; ct[3]=116 as u8 74 ct[4]=101 as u8; ct[5]=110 as u8; ct[6]=116 as u8; ct[7]=45 as u8 75 ct[8]=84 as u8; ct[9]=121 as u8; ct[10]=112 as u8; ct[11]=101 as u8 76 if nx_http_response_header(buf, n, r, ct, 12, vo, vl) == 1 { 77 _p(1, "CONTENT-TYPE=" as *u8); _pv(1, buf, vo[0], vl[0]); _p(1, "\n" as *u8) 78 } 79 } 80 sys_exit(0); return 0 81}