code wiki / (root) / nx_page_get_test.nx

nx_page_get_test.nx source

↩ module page · 174 lines · 5417 B

1// nx_browser_loopback_test.nx -- fork-loopback fetch + render. 2// 3// Server: accepts ONE TCP connection on a high port, sends a canned 4// HTTP/1.1 response with a small HTML body, then exits. 5// Client: connects, reads the full response, parses it, renders to 6// plain text, writes to stdout. 7// 8// This proves the sovereign browser substrate composes over a real 9// kernel-mediated TCP socket -- only the TLS layer is omitted (the 10// already-passing nx_https_loopback_test proves that layer in 11// isolation). CAPABILITY_COMPLETENESS PARTIAL: combining 12// loopback + TLS into one binary is queued behind X.509 chain 13// validation arc. 14// 15// expect_exit: 0 16// license_tier: ORIGINAL 17 18import "nx_syscalls.nx" 19import "nx_connect.nx" // bounded connect: a raw sys_connect hangs ~127s on a black-holed host 20import "nx_http_response_parse.nx" 21import "nx_html_to_text.nx" 22 23const BLP_PORT: i64 = 17890 24 25// ===== LEAF: address + I/O ======================================= 26 27func blp_addr(out: *u8, port: i64) -> i64 { 28 out[0] = 2; out[1] = 0 29 out[2] = (port >> 8) & 0xff 30 out[3] = port & 0xff 31 out[4] = 127; out[5] = 0; out[6] = 0; out[7] = 1 32 var i: i64 = 8 33 while i < 16 { out[i] = 0; i = i + 1 } 34 return 16 35} 36 37func blp_recv_all(fd: i64, buf: *u8, cap: i64) -> i64 { 38 var got: i64 = 0 39 while got < cap { 40 let r: i64 = sys_read(fd, buf + got, cap - got) 41 if r <= 0 { return got } 42 got = got + r 43 } 44 return got 45} 46 47// ===== Canned response builder =================================== 48 49func blp_write(out: *u8, off: i64, s: *u8, n: i64) -> i64 { 50 var i: i64 = 0 51 while i < n { out[off + i] = s[i]; i = i + 1 } 52 return off + n 53} 54 55func blp_status(out: *u8) -> i64 { 56 let l: *u8 = sys_mmap(32) 57 l[0]=0x48; l[1]=0x54; l[2]=0x54; l[3]=0x50 58 l[4]=0x2f; l[5]=0x31; l[6]=0x2e; l[7]=0x31 59 l[8]=0x20; l[9]=0x32; l[10]=0x30; l[11]=0x30 60 l[12]=0x20; l[13]=0x4f; l[14]=0x4b 61 l[15]=0x0d; l[16]=0x0a 62 return blp_write(out, 0, l, 17) 63} 64 65func blp_ct(out: *u8, off: i64) -> i64 { 66 let l: *u8 = sys_mmap(32) 67 l[0]=0x43; l[1]=0x6f; l[2]=0x6e; l[3]=0x74 68 l[4]=0x65; l[5]=0x6e; l[6]=0x74; l[7]=0x2d 69 l[8]=0x54; l[9]=0x79; l[10]=0x70; l[11]=0x65 70 l[12]=0x3a; l[13]=0x20 71 l[14]=0x74; l[15]=0x65; l[16]=0x78; l[17]=0x74 72 l[18]=0x2f; l[19]=0x68; l[20]=0x74; l[21]=0x6d; l[22]=0x6c 73 l[23]=0x0d; l[24]=0x0a 74 return blp_write(out, off, l, 25) 75} 76 77func blp_cl(out: *u8, off: i64) -> i64 { 78 // "Content-Length: 20\r\n\r\n" body = 20 bytes 79 let l: *u8 = sys_mmap(32) 80 l[0]=0x43; l[1]=0x6f; l[2]=0x6e; l[3]=0x74 81 l[4]=0x65; l[5]=0x6e; l[6]=0x74; l[7]=0x2d 82 l[8]=0x4c; l[9]=0x65; l[10]=0x6e; l[11]=0x67 83 l[12]=0x74; l[13]=0x68; l[14]=0x3a; l[15]=0x20 84 l[16]=0x32; l[17]=0x30 85 l[18]=0x0d; l[19]=0x0a 86 l[20]=0x0d; l[21]=0x0a 87 return blp_write(out, off, l, 22) 88} 89 90func blp_body(out: *u8, off: i64) -> i64 { 91 // "<p>hello world</p>X1" (20 bytes total exactly) 92 let b: *u8 = sys_mmap(32) 93 b[0]=0x3c; b[1]=0x70; b[2]=0x3e 94 b[3]=0x68; b[4]=0x65; b[5]=0x6c; b[6]=0x6c; b[7]=0x6f 95 b[8]=0x20 96 b[9]=0x77; b[10]=0x6f; b[11]=0x72; b[12]=0x6c; b[13]=0x64 97 b[14]=0x3c; b[15]=0x2f; b[16]=0x70; b[17]=0x3e 98 b[18]=0x58; b[19]=0x31 99 return blp_write(out, off, b, 20) 100} 101 102func blp_build(out: *u8) -> i64 { 103 var p: i64 = 0 104 p = blp_status(out) 105 p = blp_ct(out, p) 106 p = blp_cl(out, p) 107 p = blp_body(out, p) 108 return p 109} 110 111// ===== Render helper ============================================= 112 113func blp_render(buf: *u8, n: i64, out: *u8, cap: i64) -> i64 { 114 let r: *i64 = nx_http_resp_alloc() 115 let v: i64 = nx_http_response_parse(buf, n, r) 116 if v != NX_HTTP_RESP_OK { return 0 - 200 - v } 117 if r[1] != 200 { return 0 - 300 - r[1] } 118 if r[7] <= 0 { return 0 - 400 - r[7] } 119 if r[6] < 0 { return 0 - 500 - r[6] } 120 return nx_html_to_text(buf + r[6], r[7], out, cap) 121} 122 123// ===== Endpoint runners ========================================== 124 125func blp_run_server(cfd: i64) -> i64 { 126 let buf: *u8 = sys_mmap(256) 127 let n: i64 = blp_build(buf) 128 sys_write(cfd, buf, n) 129 sys_close(cfd) 130 return 0 131} 132 133func blp_run_client(cfd: i64) -> i64 { 134 let buf: *u8 = sys_mmap(4096) 135 let n: i64 = blp_recv_all(cfd, buf, 4096) 136 if n <= 0 { return 10 } 137 if n > 250 { return 11 } 138 let rendered: *u8 = sys_mmap(512) 139 let m: i64 = blp_render(buf, n, rendered, 512) 140 if m < 0 { return 0 - m } 141 if m == 0 { return 99 } 142 sys_write(1, rendered, m) 143 if m != 14 { return 100 + m } 144 return 0 145} 146 147func main() -> i64 { 148 let addr: *u8 = sys_mmap(16) 149 blp_addr(addr, BLP_PORT) 150 let lfd: i64 = sys_socket(AF_INET, SOCK_STREAM, 0) 151 if lfd < 0 { return 1 } 152 if sys_bind(lfd, addr, 16) < 0 { return 2 } 153 if sys_listen(lfd, 4) < 0 { return 3 } 154 155 let pid: i64 = sys_fork() 156 if pid < 0 { return 4 } 157 if pid == 0 { 158 var spin: i64 = 0 159 while spin < 200000 { spin = spin + 1 } 160 let ccfd: i64 = sys_socket(AF_INET, SOCK_STREAM, 0) 161 if ccfd < 0 { return 5 } 162 if nx_connect_bounded(ccfd, addr, 16, NX_CONN_DEFAULT_MS) < 0 { return 6 } 163 return blp_run_client(ccfd) 164 } 165 166 let scfd: i64 = sys_accept(lfd) 167 if scfd < 0 { return 7 } 168 let sr: i64 = blp_run_server(scfd) 169 if sr != 0 { return sr } 170 171 let status: *i64 = sys_mmap(8) as *i64 172 sys_wait4(pid, status, 0) 173 return wait_exit_code(*status) 174}