nx_http_session_test.nx source
↩ module page · 166 lines · 7409 B
1// nx_http_session_test.nx -- smoke for session token + cookie I/O.
2//
3// expect_exit: 0
4//
5// license_tier: ORIGINAL
6
7import "nx_syscalls_x86_64.nx"
8import "nx_http_session.nx"
9
10func bytes_eq(a: *u8, b: *u8, n: i64) -> i64 {
11 var i: i64 = 0
12 while i < n {
13 if a[i] != b[i] { return 0 }
14 i = i + 1
15 }
16 return 1
17}
18
19func bytes_contains(haystack: *u8, h_n: i64, needle: *u8, n_n: i64) -> i64 {
20 if n_n > h_n { return 0 }
21 var i: i64 = 0
22 while i <= h_n - n_n {
23 if bytes_eq(((haystack as i64) + i) as *u8, needle, n_n) == 1 { return 1 }
24 i = i + 1
25 }
26 return 0
27}
28
29func main() -> i64 {
30 // ---- Verdict enum ----
31 if nxss_verdict_is_valid(NXSS_OK) != 1 { return 1 }
32 if nxss_verdict_is_valid(NXSS_NOT_FOUND) != 1 { return 2 }
33 if nxss_verdict_is_valid(NXSS_VERDICT_N) != 0 { return 3 }
34 if bytes_eq(nxss_verdict_name(NXSS_OK), "OK" as *u8, 2) != 1 { return 4 }
35 if bytes_eq(nxss_verdict_name(NXSS_NOT_FOUND), "NOT_FOUND" as *u8, 9) != 1 { return 5 }
36
37 // ---- Constants ----
38 if NXSS_TOKEN_BYTES != 16 { return 10 }
39 if NXSS_TOKEN_HEX_LEN != 32 { return 11 }
40 if NXSS_DEFAULT_MAX_AGE_S != 1800 { return 12 }
41
42 // ---- Hex validate ----
43 if nxss_is_hex_lower(0x30) != 1 { return 20 } // '0'
44 if nxss_is_hex_lower(0x39) != 1 { return 21 } // '9'
45 if nxss_is_hex_lower(0x61) != 1 { return 22 } // 'a'
46 if nxss_is_hex_lower(0x66) != 1 { return 23 } // 'f'
47 if nxss_is_hex_lower(0x67) != 0 { return 24 } // 'g' invalid
48 if nxss_is_hex_lower(0x41) != 0 { return 25 } // 'A' (uppercase invalid)
49
50 // ---- Token validate ----
51 if nxss_validate_token_hex("0123456789abcdef0123456789abcdef" as *u8, 32) != 1 { return 30 }
52 if nxss_validate_token_hex("0123456789abcdef0123456789abcde" as *u8, 31) != 0 { return 31 }
53 if nxss_validate_token_hex("0123456789ABCDEF0123456789ABCDEF" as *u8, 32) != 0 { return 32 } // uppercase rejected
54 if nxss_validate_token_hex("0123456789abcdef0123456789abcdez" as *u8, 32) != 0 { return 33 } // 'z'
55 if nxss_validate_token_hex(0 as *u8, 32) != 0 { return 34 }
56
57 // ---- Token build from bytes ----
58 let rand16: *u8 = sys_mmap(16)
59 var i: i64 = 0
60 while i < 16 { rand16[i] = (i * 17) as u8; i = i + 1 }
61 let tok_buf: *u8 = sys_mmap(64)
62 let tok_off: *i64 = sys_mmap(8) as *i64
63 tok_off[0] = 0
64 if nx_http_session_token_from_bytes(rand16, tok_buf, tok_off, 64) != NXSS_OK { return 40 }
65 if tok_off[0] != 32 { return 41 }
66 if nxss_validate_token_hex(tok_buf, 32) != 1 { return 42 }
67
68 // Known input: bytes 0x00..0x0f stepped by 17 are 0, 17, 34, ...
69 // First byte 0 -> "00". Second byte 17 = 0x11 -> "11".
70 if tok_buf[0] != 0x30 as u8 { return 43 }
71 if tok_buf[1] != 0x30 as u8 { return 44 }
72 if tok_buf[2] != 0x31 as u8 { return 45 }
73 if tok_buf[3] != 0x31 as u8 { return 46 }
74
75 // ---- Set-Cookie emit ----
76 let cb: *u8 = sys_mmap(256)
77 let co: *i64 = sys_mmap(8) as *i64
78 co[0] = 0
79 let known_token: *u8 = "abcdef0123456789abcdef0123456789" as *u8
80 let rc1: i64 = nx_http_session_emit_set_cookie(cb, co, 256,
81 "nishi_sess" as *u8, 10,
82 known_token, 32,
83 1800)
84 if rc1 != NXSS_OK { return 50 }
85 if bytes_contains(cb, co[0],
86 "Set-Cookie: nishi_sess=" as *u8, 23) != 1 { return 51 }
87 if bytes_contains(cb, co[0],
88 "abcdef0123456789abcdef0123456789" as *u8, 32) != 1 { return 52 }
89 if bytes_contains(cb, co[0],
90 "; Path=/" as *u8, 8) != 1 { return 53 }
91 if bytes_contains(cb, co[0],
92 "; Max-Age=1800" as *u8, 14) != 1 { return 54 }
93 if bytes_contains(cb, co[0],
94 "; HttpOnly" as *u8, 10) != 1 { return 55 }
95 if bytes_contains(cb, co[0],
96 "; Secure" as *u8, 8) != 1 { return 56 }
97 if bytes_contains(cb, co[0],
98 "; SameSite=Strict" as *u8, 17) != 1 { return 57 }
99
100 // ---- Set-Cookie default convenience ----
101 co[0] = 0
102 if nx_http_session_emit_set_cookie_default(cb, co, 256, known_token, 32) != NXSS_OK { return 60 }
103 if bytes_contains(cb, co[0],
104 "nishi_sess=abcdef0123456789abcdef0123456789" as *u8, 43) != 1 { return 61 }
105
106 // ---- Bad token in Set-Cookie ----
107 co[0] = 0
108 let bad_token: *u8 = "TOO-SHORT" as *u8
109 if nx_http_session_emit_set_cookie(cb, co, 256,
110 "n" as *u8, 1, bad_token, 9, 60) != NXSS_BAD_TOKEN { return 70 }
111 co[0] = 0
112 let bad_hex: *u8 = "0123456789ABCDEF0123456789abcdef" as *u8 // upper
113 if nx_http_session_emit_set_cookie(cb, co, 256,
114 "n" as *u8, 1, bad_hex, 32, 60) != NXSS_BAD_TOKEN { return 71 }
115
116 // ---- Cookie parser: single cookie ----
117 let voff: *i64 = sys_mmap(8) as *i64
118 let vlen: *i64 = sys_mmap(8) as *i64
119 let cookie_hdr: *u8 = "nishi_sess=abc123def456" as *u8
120 let pv1: i64 = nx_http_session_parse_cookie(cookie_hdr, 23,
121 "nishi_sess" as *u8, 10,
122 voff, vlen)
123 if pv1 != NXSS_OK { return 80 }
124 if vlen[0] != 12 { return 81 }
125 let val_ptr: *u8 = ((cookie_hdr as i64) + voff[0]) as *u8
126 if bytes_eq(val_ptr, "abc123def456" as *u8, 12) != 1 { return 82 }
127
128 // ---- Cookie parser: multiple cookies ----
129 let multi_hdr: *u8 = "lang=en; nishi_sess=tokvalue; theme=dark" as *u8
130 let pv2: i64 = nx_http_session_parse_cookie(multi_hdr, 40,
131 "nishi_sess" as *u8, 10,
132 voff, vlen)
133 if pv2 != NXSS_OK { return 90 }
134 if vlen[0] != 8 { return 91 }
135 let val2_ptr: *u8 = ((multi_hdr as i64) + voff[0]) as *u8
136 if bytes_eq(val2_ptr, "tokvalue" as *u8, 8) != 1 { return 92 }
137
138 // theme should also be findable
139 let pv3: i64 = nx_http_session_parse_cookie(multi_hdr, 40,
140 "theme" as *u8, 5,
141 voff, vlen)
142 if pv3 != NXSS_OK { return 100 }
143 if vlen[0] != 4 { return 101 }
144 let val3_ptr: *u8 = ((multi_hdr as i64) + voff[0]) as *u8
145 if bytes_eq(val3_ptr, "dark" as *u8, 4) != 1 { return 102 }
146
147 // first cookie (lang) also findable
148 let pv4: i64 = nx_http_session_parse_cookie(multi_hdr, 40,
149 "lang" as *u8, 4,
150 voff, vlen)
151 if pv4 != NXSS_OK { return 110 }
152 if vlen[0] != 2 { return 111 }
153
154 // ---- NOT_FOUND ----
155 let pv5: i64 = nx_http_session_parse_cookie(multi_hdr, 40,
156 "missing" as *u8, 7,
157 voff, vlen)
158 if pv5 != NXSS_NOT_FOUND { return 120 }
159
160 // ---- BAD_ARG ----
161 if nx_http_session_parse_cookie(0 as *u8, 10, "x" as *u8, 1, voff, vlen) != NXSS_BAD_ARG { return 130 }
162 if nx_http_session_parse_cookie(cookie_hdr, 0, "x" as *u8, 1, voff, vlen) != NXSS_BAD_ARG { return 131 }
163 if nx_http_session_parse_cookie(cookie_hdr, 10, 0 as *u8, 1, voff, vlen) != NXSS_BAD_ARG { return 132 }
164
165 return 0
166}