nx_pages_vhost_test.nx source
↩ module page · 98 lines · 4238 B
1// nx_pages_vhost_test.nx -- KAT for the D1.1 multi-vhost router.
2
3import "nx_pages_vhost.nx"
4import "nx_http.nx"
5
6func _vht_strlen(s: *u8) -> i64 {
7 var n: i64 = 0
8 while s[n] != 0 { n = n + 1 }
9 return n
10}
11
12// Build a minimal HttpRequest with one Host header at the given value.
13// Caller provides the raw byte buffer (must look like a real HTTP/1.1
14// request to satisfy the parser).
15// http_parse returns 0 on success; tests treat 0 as OK -> returns 1.
16func _vht_build_req(raw: *u8, req: *HttpRequest) -> i64 {
17 let n: i64 = _vht_strlen(raw)
18 let rc: i64 = http_parse(raw, n, req)
19 if rc == 0 { return 1 }
20 return 0
21}
22
23func main() -> i64 {
24 var fails: i64 = 0
25
26 // Allocate a 2KB arena + space for up to 4 vhost entries (32 bytes each).
27 let arena: *u8 = sys_mmap(2048)
28 let vhosts: *i64 = sys_mmap(4 * NX_VHOST_STRIDE * 8) as *i64
29 let table: *NxVHostTable = sys_mmap(40) as *NxVHostTable
30 let cursor: *i64 = sys_mmap(8) as *i64
31 cursor[0] = 0
32 nx_vhost_table_init(table, arena, 2048, vhosts)
33
34 // T1: empty table dispatch returns NO_MATCH when no fallback.
35 let req: *HttpRequest = sys_mmap(2048) as *HttpRequest
36 let raw1: *u8 = "GET / HTTP/1.1\r\nHost: nishifamily.com\r\n\r\n" as *u8
37 if _vht_build_req(raw1, req) != 1 { fails = fails + 1 }
38 let off_out: *i64 = sys_mmap(8) as *i64
39 let len_out: *i64 = sys_mmap(8) as *i64
40 let v1: i64 = nx_vhost_dispatch(raw1, req, table, off_out, len_out)
41 if v1 != NX_VHOST_NO_MATCH { fails = fails + 1 }
42
43 // T2: add nishifamily + andelinwest vhosts; basic dispatch.
44 let i_nf: i64 = nx_vhost_add(table, cursor,
45 "nishifamily.com" as *u8,
46 "/share/nishi-pages/dist" as *u8)
47 if i_nf != 0 { fails = fails + 1 }
48 let i_aw: i64 = nx_vhost_add(table, cursor,
49 "andelinwest.com" as *u8,
50 "/share/andelin-pages/dist" as *u8)
51 if i_aw != 1 { fails = fails + 1 }
52
53 let v2: i64 = nx_vhost_dispatch(raw1, req, table, off_out, len_out)
54 if v2 != NX_VHOST_OK { fails = fails + 1 }
55 // Verify the returned root is /share/nishi-pages/dist (23 chars).
56 if len_out[0] != 23 { fails = fails + 1 }
57
58 // T3: dispatch andelinwest.com -> matches its root.
59 let raw3: *u8 = "GET /index.html HTTP/1.1\r\nHost: andelinwest.com\r\n\r\n" as *u8
60 if _vht_build_req(raw3, req) != 1 { fails = fails + 1 }
61 let v3: i64 = nx_vhost_dispatch(raw3, req, table, off_out, len_out)
62 if v3 != NX_VHOST_OK { fails = fails + 1 }
63 if len_out[0] != 25 { fails = fails + 1 } // /share/andelin-pages/dist
64
65 // T4: port suffix -- "nishifamily.com:443" must match "nishifamily.com".
66 let raw4: *u8 = "GET / HTTP/1.1\r\nHost: nishifamily.com:443\r\n\r\n" as *u8
67 if _vht_build_req(raw4, req) != 1 { return 41 }
68 let v4: i64 = nx_vhost_dispatch(raw4, req, table, off_out, len_out)
69 if v4 != NX_VHOST_OK { return 42 }
70 if len_out[0] != 23 { return 43 }
71
72 // T5: case-insensitive -- "NISHIFAMILY.COM" must match.
73 let raw5: *u8 = "GET / HTTP/1.1\r\nHost: NISHIFAMILY.COM\r\n\r\n" as *u8
74 if _vht_build_req(raw5, req) != 1 { return 51 }
75 let v5: i64 = nx_vhost_dispatch(raw5, req, table, off_out, len_out)
76 if v5 != NX_VHOST_OK { return 52 }
77
78 // T6: unknown host -- no fallback -> NO_MATCH.
79 let raw6: *u8 = "GET / HTTP/1.1\r\nHost: unknown.example\r\n\r\n" as *u8
80 if _vht_build_req(raw6, req) != 1 { return 61 }
81 let v6: i64 = nx_vhost_dispatch(raw6, req, table, off_out, len_out)
82 if v6 != NX_VHOST_NO_MATCH { return 62 }
83
84 // T7: set fallback; unknown host now matches fallback root.
85 nx_vhost_set_fallback(table, 0 as i64)
86 let v7: i64 = nx_vhost_dispatch(raw6, req, table, off_out, len_out)
87 if v7 != NX_VHOST_FALLBACK { return 71 }
88 if len_out[0] != 23 { return 72 }
89
90 // T8: matched vhost takes precedence over fallback. Re-parse raw3
91 // because req was last populated from raw6 in T6.
92 if _vht_build_req(raw3, req) != 1 { return 80 }
93 let v8: i64 = nx_vhost_dispatch(raw3, req, table, off_out, len_out)
94 if v8 != NX_VHOST_OK { return 81 }
95 if len_out[0] != 25 { return 82 }
96
97 return fails
98}