nx_browser_page_demo_test.nx source
↩ module page · 155 lines · 6756 B
1// nx_browser_page_demo_test.nx -- the browser renders a REAL webpage.
2//
3// Fetches http://example.com/ with the bits-up stack (DNS + sockets +
4// HTTP/1.1), then renders the HTML to readable text via nx_html_to_text
5// (tag strip + entity decode + script/style removal). This is a
6// sovereign text-mode browser -- Lynx/w3m class -- rendering a real
7// page off the live internet, every byte NishiLang.
8//
9// PROOF (not a claim): the rendered text MUST contain the real page's
10// own words ("Example Domain" + "illustrative examples"). The rendered
11// text is also written to nishi-browser-proofs/rendered_example_com.txt
12// so it can be read + diffed against the live page.
13//
14// expect_exit: 0
15// license_tier: ORIGINAL
16
17import "nx_syscalls.nx"
18import "nx_connect.nx" // bounded connect: a raw sys_connect hangs ~127s on a black-holed host
19import "nx_dns_resolve_a_record.nx"
20import "nx_https_url_connect.nx"
21import "nx_http_client.nx"
22import "nx_http_response_parse.nx"
23import "nx_html_to_text.nx"
24import "nx_https_fetch_lib.nx" // hf_decode_transport: the fleet's ONE transport decoder (chunked + gzip + deflate)
25
26func _contains(hay: *u8, hlen: i64, needle: *u8, nlen: i64) -> i64 {
27 if nlen == 0 { return 1 }
28 if hlen < nlen { return 0 }
29 let last: i64 = hlen - nlen
30 var i: i64 = 0
31 while i <= last {
32 var j: i64 = 0
33 var ok: i64 = 1
34 while j < nlen {
35 if hay[i + j] != needle[j] { ok = 0; j = nlen }
36 j = j + 1
37 }
38 if ok == 1 { return 1 }
39 i = i + 1
40 }
41 return 0
42}
43
44func _slen(s: *u8) -> i64 {
45 var n: i64 = 0
46 while s[n] != 0 { n = n + 1 }
47 return n
48}
49
50func main() -> i64 {
51 let host: *u8 = "example.com\x00"
52 // DERIVED from the literal, never hand-counted beside it: a counted length is a second copy
53 // of the literal's shape and the two drift silently.
54 let host_len: i64 = _slen(host)
55 let path: *u8 = "/\x00"
56
57 // ---- DNS + TCP:80 ----
58 let dns: *DnsResolveResult = nx_dns_resolve_default(host, host_len, 1779284141)
59 if dns.verdict != NX_DNS_R_OK { return 30 }
60 if dns.ipv4_packed == 0 { return 31 }
61 let fd: i64 = sys_socket(NX_HTTPS_AF_INET, NX_HTTPS_SOCK_STREAM, 0)
62 if fd < 0 { return 32 }
63 let sa: *u8 = sys_mmap(16)
64 nx_https_build_sockaddr(sa, dns.ipv4_packed, 80)
65 if nx_connect_bounded(fd, sa, 16, NX_CONN_DEFAULT_MS) < 0 { sys_close(fd); return 33 }
66
67 // ---- GET / ----
68 // THE REQUEST BUFFER IS DERIVED FROM THE BUILDER'S OWN BOUND (2026-08-27). This line used to
69 // read sys_mmap(256): the day the identity + derived-caps headers outgrew 256 bytes the request
70 // overran its arena (crash guard: ARENA-OVERRUN prev_alloc_size=256, the Accept header spilling
71 // into the next cell), the response buffer was corrupted, and this test convicted the browser
72 // (exit 80) for a cap it had guessed itself. The owner of the bound is nx_http_client.
73 let path_len: i64 = _slen(path)
74 let req: *u8 = sys_mmap(nx_http_client_request_cap(path_len, host_len, 0, 0))
75 let req_len: i64 = nx_http_client_build_request(path, path_len, host, host_len, req)
76 if sys_write(fd, req, req_len) < 0 { sys_close(fd); return 34 }
77
78 // ---- recv to EOF (Connection: close) ----
79 let cap: i64 = 131072
80 let buf: *u8 = sys_mmap(cap)
81 var total: i64 = 0
82 var budget: i64 = 100000
83 var reading: i64 = 1
84 while reading == 1 {
85 if total >= cap { reading = 0 }
86 if budget <= 0 { reading = 0 }
87 if reading == 1 {
88 let got: i64 = sys_read(fd, buf + total, cap - total)
89 if got <= 0 { reading = 0 }
90 if got > 0 { total = total + got }
91 budget = budget - 1
92 }
93 }
94 sys_close(fd)
95 if total < 16 { return 35 }
96
97 // ---- TRANSPORT DECODE AT THE FLEET CHOKEPOINT (2026-08-27) -------------------------
98 // example.com has been fronted by Cloudflare since 2026-08-26 and answers our request --
99 // which since 2026-08-25 advertises the codecs we can actually decode -- with
100 // Content-Encoding: gzip. This row dechunked by hand and then read the gzip stream as HTML:
101 // the "rendered page" it judged began 1f 8b 08 and the row convicted the browser (exit 80)
102 // for a transport coding the fetch path already strips. hf_decode_transport is the ONE
103 // decoder every fetch consumer inherits (chunked + gzip + deflate; status line and headers
104 // preserved, the wire headers renamed X-Was-*), so composing it here means this row and the
105 // browser's own fetch path can never disagree about what the document is. Its refusals are
106 // carried as distinct exits: a coding we do not advertise is a server fault, not a render
107 // fault, and must read differently from "the page lacks its own words".
108 let dec: *u8 = sys_mmap(cap)
109 let dn: i64 = hf_decode_transport(buf, total, dec, cap)
110 if dn == HF_DEC_ECODING { return 56 }
111 if dn == HF_DEC_CHUNK { return 57 }
112 if dn == HF_DEC_INFLATE { return 58 }
113 if dn < 0 { if dn != HF_DEC_IDENTITY { return 59 } }
114 var doc: *u8 = buf
115 var doc_len: i64 = total
116 if dn >= 0 { doc = dec; doc_len = dn }
117
118 // ---- parse HTTP, locate HTML body ----
119 let resp: *i64 = sys_mmap(128) as *i64
120 if nx_http_response_parse(doc, doc_len, resp) != 0 { return 50 }
121 let status: i64 = resp[1]
122 if status != 200 { return 50 + status }
123 let body_off: i64 = resp[6]
124 let html: *u8 = doc + body_off
125 let html_len: i64 = doc_len - body_off
126 if html_len <= 0 { return 55 }
127
128 // ---- render HTML -> readable text ----
129 let text: *u8 = sys_mmap(32768)
130 let text_len: i64 = nx_html_to_text(html, html_len, text, 32768)
131 if text_len <= 0 { return 60 }
132
133 // ---- emit rendered page to stdout + proof file ----
134 let banner: *u8 = "\n=== example.com rendered by the Nishi browser (bits-up, text mode) ===\n\x00"
135 sys_write(1, banner, _slen(banner))
136 sys_write(1, text, text_len)
137 sys_write(1, banner, 1)
138
139 let outp: *u8 = "/mnt/c/Users/elder/nishi-browser-proofs/rendered_example_com.txt\x00"
140 let ofd: i64 = sys_openat_wr(outp, 0x1A4)
141 if ofd > 0 { sys_write(ofd, text, text_len); sys_close(ofd) }
142
143 // ---- PROOF: rendered text contains the real page's own words ----
144 let n1: *u8 = "Example Domain\x00"
145 let n2: *u8 = "documentation examples\x00"
146 let n3: *u8 = "without needing permission\x00"
147 if _contains(text, text_len, n1, _slen(n1)) != 1 { return 80 }
148 if _contains(text, text_len, n2, _slen(n2)) != 1 { return 81 }
149 if _contains(text, text_len, n3, _slen(n3)) != 1 { return 82 }
150
151 let pass: *u8 = sys_mmap(16)
152 pass[0]=0x50; pass[1]=0x41; pass[2]=0x53; pass[3]=0x53; pass[4]=0x0A
153 sys_write(2, pass, 5)
154 return 0
155}