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}