nx_browse_text_test.nx source
↩ module page · 126 lines · 4355 B
1// nx_browse_text_test.nx -- fork-loopback proof that nx_browse_text
2// composes correctly end-to-end.
3//
4// Server: accepts ONE TCP connection on a high port, replies with a
5// canned HTTP/1.1 response carrying small HTML, closes.
6// Client: invokes nx_browse_text(127.0.0.1:PORT, "/", "localhost",
7// out) and asserts the rendered text equals "Welcome\n" (8 bytes).
8//
9// expect_exit: 0
10// license_tier: ORIGINAL
11
12import "nx_syscalls.nx"
13import "nx_browse_text.nx"
14
15const BT_PORT: i64 = 17893
16
17// ===== fixture: canned HTTP response =============================
18
19func bt_addr(out: *u8, port: i64) -> i64 {
20 out[0]=2; out[1]=0
21 out[2]=(port >> 8) & 0xff; out[3]=port & 0xff
22 out[4]=127; out[5]=0; out[6]=0; out[7]=1
23 var i: i64 = 8
24 while i < 16 { out[i]=0; i = i + 1 }
25 return 16
26}
27
28func bt_write(out: *u8, off: i64, s: *u8, n: i64) -> i64 {
29 var i: i64 = 0
30 while i < n { out[off + i] = s[i]; i = i + 1 }
31 return off + n
32}
33
34func bt_make_response(out: *u8) -> i64 {
35 var p: i64 = 0
36 let l: *u8 = sys_mmap(64)
37 // "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nContent-Length: 18\r\n\r\n"
38 l[0]=0x48; l[1]=0x54; l[2]=0x54; l[3]=0x50
39 l[4]=0x2f; l[5]=0x31; l[6]=0x2e; l[7]=0x31
40 l[8]=0x20; l[9]=0x32; l[10]=0x30; l[11]=0x30
41 l[12]=0x20; l[13]=0x4f; l[14]=0x4b
42 l[15]=0x0d; l[16]=0x0a
43 p = bt_write(out, p, l, 17)
44 let ct: *u8 = sys_mmap(64)
45 ct[0]=0x43; ct[1]=0x6f; ct[2]=0x6e; ct[3]=0x74
46 ct[4]=0x65; ct[5]=0x6e; ct[6]=0x74; ct[7]=0x2d
47 ct[8]=0x54; ct[9]=0x79; ct[10]=0x70; ct[11]=0x65
48 ct[12]=0x3a; ct[13]=0x20
49 ct[14]=0x74; ct[15]=0x65; ct[16]=0x78; ct[17]=0x74
50 ct[18]=0x2f; ct[19]=0x68; ct[20]=0x74; ct[21]=0x6d; ct[22]=0x6c
51 ct[23]=0x0d; ct[24]=0x0a
52 p = bt_write(out, p, ct, 25)
53 let cl: *u8 = sys_mmap(64)
54 cl[0]=0x43; cl[1]=0x6f; cl[2]=0x6e; cl[3]=0x74
55 cl[4]=0x65; cl[5]=0x6e; cl[6]=0x74; cl[7]=0x2d
56 cl[8]=0x4c; cl[9]=0x65; cl[10]=0x6e; cl[11]=0x67
57 cl[12]=0x74; cl[13]=0x68; cl[14]=0x3a; cl[15]=0x20
58 cl[16]=0x31; cl[17]=0x38 // 18
59 cl[18]=0x0d; cl[19]=0x0a; cl[20]=0x0d; cl[21]=0x0a
60 p = bt_write(out, p, cl, 22)
61 let body: *u8 = sys_mmap(32)
62 // "<h1>Welcome</h1>WW" 18 bytes (4 + 7 + 5 = 16 for h1, +2 pad WW)
63 body[0]=0x3c; body[1]=0x68; body[2]=0x31; body[3]=0x3e
64 body[4]=0x57; body[5]=0x65; body[6]=0x6c; body[7]=0x63
65 body[8]=0x6f; body[9]=0x6d; body[10]=0x65
66 body[11]=0x3c; body[12]=0x2f; body[13]=0x68; body[14]=0x31; body[15]=0x3e
67 body[16]=0x57; body[17]=0x57
68 p = bt_write(out, p, body, 18)
69 return p
70}
71
72// ===== endpoint runners ==========================================
73
74func bt_run_server(cfd: i64) -> i64 {
75 let buf: *u8 = sys_mmap(512)
76 let n: i64 = bt_make_response(buf)
77 sys_write(cfd, buf, n)
78 sys_close(cfd)
79 return 0
80}
81
82func bt_run_client(cfd_unused: i64, addr: *u8) -> i64 {
83 let path: *u8 = sys_mmap(8); path[0]=0x2f // "/"
84 let host: *u8 = sys_mmap(16)
85 host[0]=0x6c; host[1]=0x6f; host[2]=0x63; host[3]=0x61
86 host[4]=0x6c; host[5]=0x68; host[6]=0x6f; host[7]=0x73; host[8]=0x74
87 let scratch: *u8 = sys_mmap(4096)
88 let out: *u8 = sys_mmap(512)
89 let status: *i64 = sys_mmap(8) as *i64
90 let verdict: *i64 = sys_mmap(8) as *i64
91 let m: i64 = nx_browse_text(addr, path, 1, host, 9,
92 scratch, 4096, out, 512, status, verdict)
93 if m < 0 { return 50 + verdict[0] }
94 if status[0] != 200 { return 60 }
95 if m == 0 { return 61 }
96 sys_write(1, out, m)
97 // Expected: "Welcome\nWW" = 10 bytes (Welcome + \n + trailing pad WW)
98 if m != 10 { return 100 + m }
99 return 0
100}
101
102func main() -> i64 {
103 let addr: *u8 = sys_mmap(16)
104 bt_addr(addr, BT_PORT)
105 let lfd: i64 = sys_socket(AF_INET, SOCK_STREAM, 0)
106 if lfd < 0 { return 1 }
107 if sys_bind(lfd, addr, 16) < 0 { return 2 }
108 if sys_listen(lfd, 4) < 0 { return 3 }
109
110 let pid: i64 = sys_fork()
111 if pid < 0 { return 4 }
112 if pid == 0 {
113 var spin: i64 = 0
114 while spin < 200000 { spin = spin + 1 }
115 return bt_run_client(0, addr)
116 }
117
118 let scfd: i64 = sys_accept(lfd)
119 if scfd < 0 { return 7 }
120 let sr: i64 = bt_run_server(scfd)
121 if sr != 0 { return sr }
122
123 let status: *i64 = sys_mmap(8) as *i64
124 sys_wait4(pid, status, 0)
125 return wait_exit_code(*status)
126}