nx_fetch_status_boundary_gate_t252.nx source
↩ module page · 43 lines · 3100 B
1import "nx_fetch_any.nx"
2import "nx_gate_verdict.nx"
3func hs_case(c:*i64,label:*u8,s:*u8,want:i64)->i64{return gv_check(label,fa_status(s,fa_slen(s))==want,c)}
4func main()->i64{
5 let c:*i64=gv_ctr()
6 hs_case(c,"malformed-status-digits-must-not-become-200","HTTP/1.1 2/: malformed\r\n\r\n",0)
7 hs_case(c,"body-http-example-is-not-response-status","<html><pre>HTTP/1.1 200 OK</pre></html>",0)
8 hs_case(c,"valid-partial-content-status-preserved","HTTP/1.1 206 Partial Content\r\n\r\n",206)
9 hs_case(c,"empty-reason-with-required-space","HTTP/1.1 204 \r\n",204)
10 hs_case(c,"http10-supported","HTTP/1.0 200 OK\r\n",200)
11 hs_case(c,"missing-reason-separator","HTTP/1.1 200\r\n",0)
12 hs_case(c,"tab-instead-of-required-separator","HTTP/1.1 200\tOK\r\n",0)
13 hs_case(c,"extra-code-digit","HTTP/1.1 0200 OK\r\n",0)
14 hs_case(c,"short-code","HTTP/1.1 20 OK\r\n",0)
15 hs_case(c,"bad-code-suffix","HTTP/1.1 200x OK\r\n",0)
16 hs_case(c,"bare-lf-refused","HTTP/1.1 200 OK\n\n",0)
17 hs_case(c,"embedded-lf-before-later-crlf","HTTP/1.1 200 O\nK\r\n",0)
18 hs_case(c,"embedded-cr-before-later-crlf","HTTP/1.1 200 O\rK\r\n",0)
19 hs_case(c,"prefixed-status-refused","\r\nHTTP/1.1 200 OK\r\n",0)
20 hs_case(c,"unsupported-version","HTTP/2.0 200 OK\r\n",0)
21 hs_case(c,"first-status-not-later-body","HTTP/1.1 404 Missing\r\n\r\nHTTP/1.1 200 OK\r\n",404)
22 let line:*u8="HTTP/1.1 200 OK\r\n";var i:i64=0;var ok:i64=1
23 while i<fa_slen(line){if fa_status(line,i)!=0{ok=0};i=i+1}
24 gv_check("every-incomplete-status-prefix-refused",ok,c)
25 gv_check("null-input-refused",fa_status(0 as *u8,50)==0,c)
26 let buf:*u8=sys_mmap_try(16);if (buf as i64)==0{return 3}
27 let base:*u8="HTTP/1.1 200 X\r\n";i=0;while i<16{buf[i]=base[i];i=i+1}
28 var code:i64=0;ok=1
29 while code<1000{buf[9]=(48+code/100) as u8;buf[10]=(48+(code/10)%10) as u8;buf[11]=(48+code%10) as u8;var want:i64=0;if code>=100&&code<=599{want=code};if fa_status(buf,16)!=want{ok=0};code=code+1}
30 gv_check("all-three-digit-codes-class-range",ok,c)
31 buf[9]=50 as u8;buf[10]=48 as u8;buf[11]=48 as u8
32 i=0;ok=1;while i<256{buf[13]=i as u8;var want:i64=0;if i==9||i>=32&&i!=127{want=200};if fa_status(buf,16)!=want{ok=0};i=i+1}
33 gv_check("all-reason-octets-match-grammar",ok,c)
34 let slots:*i64=sys_mmap_try(32) as *i64;if (slots as i64)==0{sys_munmap_direct(buf,16);return 3}
35 let spaced:*u8="HTTP/1.1 200 \tOK\r\n"
36 let rc:i64=nx_http_resp_parse_status_line(spaced,fa_slen(spaced),slots,(slots as i64+8) as *i64,(slots as i64+16) as *i64,(slots as i64+24) as *i64)
37 gv_check("full-status-api-preserves-exact-reason-span",rc==0&&slots[0]==200&&slots[1]==13&&slots[2]==4&&slots[3]==19,c)
38 let invalid:*u8="HTTP/1.1 2/: bad\r\n"
39 let bad:i64=nx_http_resp_parse_status_line(invalid,fa_slen(invalid),slots,(slots as i64+8) as *i64,(slots as i64+16) as *i64,(slots as i64+24) as *i64)
40 gv_check("invalid-clears-stale-output-slots",bad!=0&&slots[0]==0&&slots[1]==0&&slots[2]==0&&slots[3]==0,c)
41 sys_munmap_direct(slots as *u8,32);sys_munmap_direct(buf,16)
42 return gv_verdict("nx_fetch_status_boundary_gate_t252",c,"Strict RFC9112 status grammar only; not full response framing conformance.")
43}