nx_pages_static_test.nx source
↩ module page · 117 lines · 5640 B
1// nx_pages_static_test.nx -- structural smoke for nx_pages_static.
2//
3// Exercises MIME table + suffix predicates + response builders +
4// the serve entry's BAD_ARG / NOT_FOUND / METHOD_NOT_ALLOWED paths.
5// Real file-read + 200 path is exercised by the loopback bench
6// (bench/nx_pages_static_loopback.sh, queued).
7//
8// expect_exit: 0
9//
10// license_tier: ORIGINAL
11
12import "nx_syscalls_x86_64.nx"
13import "nx_pages_static.nx"
14
15func bytes_eq(a: *u8, b: *u8, n: i64) -> i64 {
16 var i: i64 = 0
17 while i < n {
18 if a[i] != b[i] { return 0 }
19 i = i + 1
20 }
21 return 1
22}
23
24func main() -> i64 {
25 // ---- Verdict enum gate ----
26 if nxpg_verdict_is_valid(NXPG_OK) != 1 { return 1 }
27 if nxpg_verdict_is_valid(NXPG_NOT_FOUND) != 1 { return 2 }
28 if nxpg_verdict_is_valid(NXPG_FORBIDDEN) != 1 { return 3 }
29 if nxpg_verdict_is_valid(NXPG_METHOD_NOT_ALLOWED) != 1 { return 4 }
30 if nxpg_verdict_is_valid(NXPG_VERDICT_N) != 0 { return 5 }
31 if nxpg_verdict_is_valid(-1) != 0 { return 6 }
32
33 if bytes_eq(nxpg_verdict_name(NXPG_NOT_FOUND), "NOT_FOUND" as *u8, 9) != 1 { return 10 }
34 if bytes_eq(nxpg_verdict_name(NXPG_FORBIDDEN), "FORBIDDEN" as *u8, 9) != 1 { return 11 }
35 if bytes_eq(nxpg_verdict_name(NXPG_METHOD_NOT_ALLOWED), "METHOD_NOT_ALLOWED" as *u8, 18) != 1 { return 12 }
36
37 // ---- MIME-type detection ----
38 if nx_pages_mime_from_path("index.html" as *u8, 10) != NXMIME_HTML { return 20 }
39 if nx_pages_mime_from_path("snapshot.json" as *u8, 13) != NXMIME_JSON { return 21 }
40 if nx_pages_mime_from_path("style.css" as *u8, 9) != NXMIME_CSS { return 22 }
41 if nx_pages_mime_from_path("app.js" as *u8, 6) != NXMIME_JS { return 23 }
42 if nx_pages_mime_from_path("img.png" as *u8, 7) != NXMIME_PNG { return 24 }
43 if nx_pages_mime_from_path("photo.jpg" as *u8, 9) != NXMIME_JPG { return 25 }
44 if nx_pages_mime_from_path("icon.svg" as *u8, 8) != NXMIME_SVG { return 26 }
45 if nx_pages_mime_from_path("readme.txt" as *u8, 10) != NXMIME_TXT { return 27 }
46 if nx_pages_mime_from_path("favicon.ico" as *u8, 11) != NXMIME_ICO { return 28 }
47 if nx_pages_mime_from_path("data.bin" as *u8, 8) != NXMIME_OCTET { return 29 }
48 if nx_pages_mime_from_path("noext" as *u8, 5) != NXMIME_OCTET { return 30 }
49
50 // ---- MIME-type strings ----
51 if bytes_eq(nx_pages_mime_type(NXMIME_HTML),
52 "text/html; charset=utf-8" as *u8, 24) != 1 { return 40 }
53 if bytes_eq(nx_pages_mime_type(NXMIME_JSON),
54 "application/json" as *u8, 16) != 1 { return 41 }
55 if bytes_eq(nx_pages_mime_type(NXMIME_OCTET),
56 "application/octet-stream" as *u8, 24) != 1 { return 42 }
57
58 // ---- BAD_ARG path on serve ----
59 let buf: *u8 = sys_mmap(4096)
60 let nn: *i64 = sys_mmap(8) as *i64
61 if nx_pages_serve_file(0 as *u8, 5, "x" as *u8, 1, 1, buf, 4096, nn) != NXPG_BAD_ARG { return 50 }
62 if nx_pages_serve_file("x" as *u8, 1, 0 as *u8, 1, 1, buf, 4096, nn) != NXPG_BAD_ARG { return 51 }
63 if nx_pages_serve_file("x" as *u8, 0, "x" as *u8, 1, 1, buf, 4096, nn) != NXPG_BAD_ARG { return 52 }
64 if nx_pages_serve_file("x" as *u8, 1, "x" as *u8, 0, 1, buf, 4096, nn) != NXPG_BAD_ARG { return 53 }
65 if nx_pages_serve_file("x" as *u8, 1, "x" as *u8, 1, 1, 0 as *u8, 4096, nn) != NXPG_BAD_ARG { return 54 }
66 if nx_pages_serve_file("x" as *u8, 1, "x" as *u8, 1, 1, buf, 0, nn) != NXPG_BAD_ARG { return 55 }
67
68 // ---- METHOD_NOT_ALLOWED (POST = method_kind=2) ----
69 let r1: i64 = nx_pages_serve_file("/index.html" as *u8, 11,
70 "/var/www" as *u8, 8,
71 2, buf, 4096, nn)
72 if r1 != NXPG_METHOD_NOT_ALLOWED { return 60 }
73 // Verify response contains "405"
74 if buf[9] != 0x34 as u8 { return 61 } // '4'
75 if buf[10] != 0x30 as u8 { return 62 } // '0'
76 if buf[11] != 0x35 as u8 { return 63 } // '5'
77
78 // ---- NOT_FOUND on URL not starting with / ----
79 let r2: i64 = nx_pages_serve_file("foo" as *u8, 3,
80 "/var/www" as *u8, 8,
81 1, buf, 4096, nn)
82 if r2 != NXPG_NOT_FOUND { return 70 }
83
84 // ---- NOT_FOUND on bare / (no implicit index) ----
85 let r3: i64 = nx_pages_serve_file("/" as *u8, 1,
86 "/var/www" as *u8, 8,
87 1, buf, 4096, nn)
88 if r3 != NXPG_NOT_FOUND { return 80 }
89
90 // ---- FORBIDDEN on path-traversal attempt ----
91 let r4: i64 = nx_pages_serve_file("/../etc/passwd" as *u8, 14,
92 "/var/www" as *u8, 8,
93 1, buf, 4096, nn)
94 if r4 != NXPG_FORBIDDEN { return 90 }
95 // Verify response contains "403"
96 if buf[9] != 0x34 as u8 { return 91 } // '4'
97 if buf[10] != 0x30 as u8 { return 92 } // '0'
98 if buf[11] != 0x33 as u8 { return 93 } // '3'
99
100 // ---- FORBIDDEN on backslash ----
101 let r5: i64 = nx_pages_serve_file("/dir\\file.html" as *u8, 14,
102 "/var/www" as *u8, 8,
103 1, buf, 4096, nn)
104 if r5 != NXPG_FORBIDDEN { return 100 }
105
106 // ---- NOT_FOUND on file that doesn't exist ----
107 let r6: i64 = nx_pages_serve_file("/nope/notthere.html" as *u8, 19,
108 "/tmp" as *u8, 4,
109 1, buf, 4096, nn)
110 if r6 != NXPG_NOT_FOUND { return 110 }
111 // Verify response contains "404"
112 if buf[9] != 0x34 as u8 { return 111 }
113 if buf[10] != 0x30 as u8 { return 112 }
114 if buf[11] != 0x34 as u8 { return 113 }
115
116 return 0
117}