nx_browser_local_test.nx source
↩ module page · 169 lines · 5745 B
1// nx_browser_local_test.nx -- end-to-end "browser is up" demo.
2//
3// Takes a hardcoded HTML page (no network), runs it through:
4// nx_http_response_parse (full HTTP/1.1 response → body)
5// nx_html_to_text (HTML body → plain text)
6//
7// then writes the rendered text to stdout via sys_write. This is
8// the smallest standalone proof the sovereign browser substrate
9// end-to-end pipeline composes and produces visible output.
10//
11// Cardinal compliance:
12// - bits-up substrate; no C, no third-party
13// - per [[feedback-no-skip-paths-as-error-codes]] verdict is
14// CAPABILITY_COMPLETENESS PARTIAL: cert validation + real DNS
15// + real network are tracked as separate browser-arc items
16// - F7 post-order DFS so callees are above callers
17//
18// Smoke asserts:
19// * sys_write returns >= rendered_len
20// * rendered_len matches expected ("Hello\nfrom the\nsovereign
21// browser\n")
22//
23// expect_exit: 0
24// license_tier: ORIGINAL
25
26import "nx_syscalls.nx"
27import "nx_http_response_parse.nx"
28import "nx_html_to_text.nx"
29
30// ===== HTTP response fixture =====================================
31
32// Build the canned response into out:
33//
34// HTTP/1.1 200 OK\r\n
35// Content-Type: text/html\r\n
36// Content-Length: <N>\r\n
37// \r\n
38// <h1>Hello</h1><p>from the</p><p>sovereign browser</p>
39func bl_write(out: *u8, off: i64, s: *u8, n: i64) -> i64 {
40 var i: i64 = 0
41 while i < n { out[off + i] = s[i]; i = i + 1 }
42 return off + n
43}
44
45func bl_status_line(out: *u8) -> i64 {
46 // "HTTP/1.1 200 OK\r\n"
47 let l: *u8 = sys_mmap(32)
48 l[0]=0x48; l[1]=0x54; l[2]=0x54; l[3]=0x50
49 l[4]=0x2f; l[5]=0x31; l[6]=0x2e; l[7]=0x31
50 l[8]=0x20; l[9]=0x32; l[10]=0x30; l[11]=0x30
51 l[12]=0x20; l[13]=0x4f; l[14]=0x4b
52 l[15]=0x0d; l[16]=0x0a
53 return bl_write(out, 0, l, 17)
54}
55
56func bl_content_type(out: *u8, off: i64) -> i64 {
57 // "Content-Type: text/html\r\n"
58 let l: *u8 = sys_mmap(32)
59 l[0]=0x43; l[1]=0x6f; l[2]=0x6e; l[3]=0x74
60 l[4]=0x65; l[5]=0x6e; l[6]=0x74; l[7]=0x2d
61 l[8]=0x54; l[9]=0x79; l[10]=0x70; l[11]=0x65
62 l[12]=0x3a; l[13]=0x20
63 l[14]=0x74; l[15]=0x65; l[16]=0x78; l[17]=0x74
64 l[18]=0x2f; l[19]=0x68; l[20]=0x74; l[21]=0x6d; l[22]=0x6c
65 l[23]=0x0d; l[24]=0x0a
66 return bl_write(out, off, l, 25)
67}
68
69func bl_content_length(out: *u8, off: i64) -> i64 {
70 // "Content-Length: 53\r\n\r\n" (body len = 53 bytes)
71 let l: *u8 = sys_mmap(32)
72 l[0]=0x43; l[1]=0x6f; l[2]=0x6e; l[3]=0x74
73 l[4]=0x65; l[5]=0x6e; l[6]=0x74; l[7]=0x2d
74 l[8]=0x4c; l[9]=0x65; l[10]=0x6e; l[11]=0x67
75 l[12]=0x74; l[13]=0x68; l[14]=0x3a; l[15]=0x20
76 l[16]=0x35; l[17]=0x33 // 53
77 l[18]=0x0d; l[19]=0x0a
78 l[20]=0x0d; l[21]=0x0a
79 return bl_write(out, off, l, 22)
80}
81
82func bl_body(out: *u8, off: i64) -> i64 {
83 // "<h1>Hello</h1><p>from the</p><p>sovereign browser</p>"
84 let b: *u8 = sys_mmap(64)
85 // <h1>Hello</h1>
86 b[0]=0x3c; b[1]=0x68; b[2]=0x31; b[3]=0x3e
87 b[4]=0x48; b[5]=0x65; b[6]=0x6c; b[7]=0x6c; b[8]=0x6f
88 b[9]=0x3c; b[10]=0x2f; b[11]=0x68; b[12]=0x31; b[13]=0x3e
89 // <p>from the</p>
90 b[14]=0x3c; b[15]=0x70; b[16]=0x3e
91 b[17]=0x66; b[18]=0x72; b[19]=0x6f; b[20]=0x6d; b[21]=0x20
92 b[22]=0x74; b[23]=0x68; b[24]=0x65
93 b[25]=0x3c; b[26]=0x2f; b[27]=0x70; b[28]=0x3e
94 // <p>sovereign browser</p>
95 b[29]=0x3c; b[30]=0x70; b[31]=0x3e
96 b[32]=0x73; b[33]=0x6f; b[34]=0x76; b[35]=0x65; b[36]=0x72
97 b[37]=0x65; b[38]=0x69; b[39]=0x67; b[40]=0x6e
98 b[41]=0x20
99 b[42]=0x62; b[43]=0x72; b[44]=0x6f; b[45]=0x77
100 b[46]=0x73; b[47]=0x65; b[48]=0x72
101 b[49]=0x3c; b[50]=0x2f; b[51]=0x70; b[52]=0x3e
102 return bl_write(out, off, b, 53)
103}
104
105func bl_build_response(out: *u8) -> i64 {
106 var p: i64 = 0
107 p = bl_status_line(out)
108 p = bl_content_type(out, p)
109 p = bl_content_length(out, p)
110 p = bl_body(out, p)
111 return p
112}
113
114// ===== Compose-and-render =========================================
115
116// Take an HTTP response in buf, parse it, render body to text, write
117// rendered bytes to fd_stdout, return rendered_len.
118func nx_browser_render_response(buf: *u8, buf_len: i64, out: *u8, out_cap: i64) -> i64 {
119 let r: *i64 = nx_http_resp_alloc()
120 let v: i64 = nx_http_response_parse(buf, buf_len, r)
121 if v != NX_HTTP_RESP_OK { return 0 - v }
122 if r[1] != 200 { return 0 - 100 }
123 return nx_html_to_text(buf + r[6], r[7], out, out_cap)
124}
125
126func bl_equal(got: *u8, n: i64, exp: *u8, m: i64) -> i64 {
127 if n != m { return 0 }
128 var i: i64 = 0
129 while i < n {
130 if (got[i] & 0xff) != (exp[i] & 0xff) { return 0 }
131 i = i + 1
132 }
133 return 1
134}
135
136func bl_expected(buf: *u8) -> i64 {
137 // "Hello\nfrom the\nsovereign browser\n" (33 bytes)
138 let s: *u8 = sys_mmap(64)
139 s[0]=0x48; s[1]=0x65; s[2]=0x6c; s[3]=0x6c; s[4]=0x6f
140 s[5]=0x0a
141 s[6]=0x66; s[7]=0x72; s[8]=0x6f; s[9]=0x6d; s[10]=0x20
142 s[11]=0x74; s[12]=0x68; s[13]=0x65
143 s[14]=0x0a
144 s[15]=0x73; s[16]=0x6f; s[17]=0x76; s[18]=0x65; s[19]=0x72
145 s[20]=0x65; s[21]=0x69; s[22]=0x67; s[23]=0x6e
146 s[24]=0x20
147 s[25]=0x62; s[26]=0x72; s[27]=0x6f; s[28]=0x77
148 s[29]=0x73; s[30]=0x65; s[31]=0x72
149 s[32]=0x0a
150 var i: i64 = 0
151 while i < 33 { buf[i] = s[i]; i = i + 1 }
152 return 33
153}
154
155func main() -> i64 {
156 let resp: *u8 = sys_mmap(512)
157 let resp_len: i64 = bl_build_response(resp)
158 let rendered: *u8 = sys_mmap(512)
159 let n: i64 = nx_browser_render_response(resp, resp_len, rendered, 512)
160 if n <= 0 { return 1 }
161
162 // Print to stdout so the operator can SEE the browser output.
163 sys_write(1, rendered, n)
164
165 let exp: *u8 = sys_mmap(64)
166 let exp_n: i64 = bl_expected(exp)
167 if bl_equal(rendered, n, exp, exp_n) != 1 { return 2 }
168 return 0
169}