code wiki / (root) / nx_http_cache_test.nx

nx_http_cache_test.nx source

↩ module page · 141 lines · 5708 B

1// nx_http_cache_test.nx -- smoke for HTTP cache primitive. 2// 3// expect_exit: 0 4// 5// license_tier: ORIGINAL 6 7import "nx_syscalls_x86_64.nx" 8import "nx_http_cache.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 gates ---- 31 if nxc_verdict_is_valid(NXC_OK_FRESH) != 1 { return 1 } 32 if nxc_verdict_is_valid(NXC_OK_NOT_MODIFIED) != 1 { return 2 } 33 if nxc_verdict_is_valid(NXC_VERDICT_N) != 0 { return 3 } 34 if bytes_eq(nxc_verdict_name(NXC_OK_FRESH), "OK_FRESH" as *u8, 8) != 1 { return 4 } 35 if bytes_eq(nxc_verdict_name(NXC_OK_NOT_MODIFIED), "OK_NOT_MODIFIED" as *u8, 15) != 1 { return 5 } 36 37 // ---- FNV-1a 64-bit determinism ---- 38 let h1: i64 = nxc_fnv1a_64("hello" as *u8, 5) 39 let h2: i64 = nxc_fnv1a_64("hello" as *u8, 5) 40 if h1 != h2 { return 10 } 41 // Different inputs produce different hashes. 42 let h3: i64 = nxc_fnv1a_64("hellp" as *u8, 5) 43 if h1 == h3 { return 11 } 44 let h4: i64 = nxc_fnv1a_64("" as *u8, 0) 45 // Init constant for FNV-1a-64 = -3750763034362895579 46 if h4 != -3750763034362895579 { return 12 } 47 48 // ---- Hex emission of a known value ---- 49 let hex_buf: *u8 = sys_mmap(32) 50 let hex_off: *i64 = sys_mmap(8) as *i64 51 hex_off[0] = 0 52 let known_val: i64 = 0x0123456789abcdef 53 nxc_put_hex_64(hex_buf, hex_off, 32, known_val) 54 if hex_off[0] != 16 { return 20 } 55 if bytes_eq(hex_buf, "0123456789abcdef" as *u8, 16) != 1 { return 21 } 56 57 // ---- ETag compute: write 16-char hex ---- 58 let etag_buf: *u8 = sys_mmap(32) 59 let etag_off: *i64 = sys_mmap(8) as *i64 60 etag_off[0] = 0 61 let body: *u8 = "Hello, World!" as *u8 62 let rc1: i64 = nx_http_etag_compute(body, 13, etag_buf, etag_off, 32) 63 if rc1 != NXC_OK_FRESH { return 30 } 64 if etag_off[0] != 16 { return 31 } 65 // Same body should produce same hash. 66 let etag_buf2: *u8 = sys_mmap(32) 67 let etag_off2: *i64 = sys_mmap(8) as *i64 68 etag_off2[0] = 0 69 nx_http_etag_compute(body, 13, etag_buf2, etag_off2, 32) 70 if bytes_eq(etag_buf, etag_buf2, 16) != 1 { return 32 } 71 72 // ---- If-None-Match: exact match ---- 73 let etag: *u8 = "abc123def4567890" as *u8 74 if nx_http_if_none_match_matches( 75 "\"abc123def4567890\"" as *u8, 18, 76 etag, 16) != 1 { return 40 } 77 // Mismatch 78 if nx_http_if_none_match_matches( 79 "\"xyz789def4567890\"" as *u8, 18, 80 etag, 16) != 0 { return 41 } 81 // Wildcard 82 if nx_http_if_none_match_matches( 83 "*" as *u8, 1, etag, 16) != 1 { return 42 } 84 // Multiple values, one matches 85 if nx_http_if_none_match_matches( 86 "\"first\", \"abc123def4567890\"" as *u8, 27, 87 etag, 16) != 1 { return 43 } 88 89 // ---- Cache decide: no If-None-Match -> FRESH ---- 90 if nx_http_cache_decide(0 as *u8, 0, etag, 16) != NXC_OK_FRESH { return 50 } 91 // Empty If-None-Match -> FRESH 92 if nx_http_cache_decide(0 as *u8, 0, etag, 16) != NXC_OK_FRESH { return 51 } 93 // Matching If-None-Match -> NOT_MODIFIED 94 if nx_http_cache_decide("\"abc123def4567890\"" as *u8, 18, 95 etag, 16) != NXC_OK_NOT_MODIFIED { return 52 } 96 // Non-matching If-None-Match -> FRESH 97 if nx_http_cache_decide("\"zzzzzzzzzzzzzzz\"" as *u8, 17, 98 etag, 16) != NXC_OK_FRESH { return 53 } 99 100 // ---- 304 emit ---- 101 let resp_buf: *u8 = sys_mmap(512) 102 let resp_off: *i64 = sys_mmap(8) as *i64 103 resp_off[0] = 0 104 let rc_304: i64 = nx_http_emit_304(resp_buf, resp_off, 512, 105 etag, 16, 300) 106 if rc_304 != NXC_OK_FRESH { return 60 } 107 if resp_off[0] <= 0 { return 61 } 108 // Verify shape 109 if bytes_contains(resp_buf, resp_off[0], 110 "HTTP/1.1 304 Not Modified" as *u8, 25) != 1 { return 62 } 111 if bytes_contains(resp_buf, resp_off[0], 112 "ETag: \"abc123def4567890\"" as *u8, 24) != 1 { return 63 } 113 if bytes_contains(resp_buf, resp_off[0], 114 "Cache-Control: public, max-age=300" as *u8, 33) != 1 { return 64 } 115 if bytes_contains(resp_buf, resp_off[0], 116 "Content-Length: 0" as *u8, 17) != 1 { return 65 } 117 118 // ---- Cache-Control header injection ---- 119 let cc_buf: *u8 = sys_mmap(128) 120 let cc_off: *i64 = sys_mmap(8) as *i64 121 cc_off[0] = 0 122 let rc_cc: i64 = nx_http_emit_cache_control_header(cc_buf, cc_off, 128, 60) 123 if rc_cc != NXC_OK_FRESH { return 70 } 124 if bytes_contains(cc_buf, cc_off[0], 125 "Cache-Control: public, max-age=60\r\n" as *u8, 35) != 1 { return 71 } 126 127 // Max-age=0 128 cc_off[0] = 0 129 nx_http_emit_cache_control_header(cc_buf, cc_off, 128, 0) 130 if bytes_contains(cc_buf, cc_off[0], 131 "max-age=0\r\n" as *u8, 11) != 1 { return 72 } 132 133 // ---- BAD_ARG paths ---- 134 if nx_http_etag_compute(0 as *u8, 5, etag_buf, etag_off, 32) != NXC_BAD_ARG { return 80 } 135 if nx_http_etag_compute(body, 13, 0 as *u8, etag_off, 32) != NXC_BAD_ARG { return 81 } 136 if nx_http_etag_compute(body, 13, etag_buf, 0 as *i64, 32) != NXC_BAD_ARG { return 82 } 137 if nx_http_emit_304(0 as *u8, resp_off, 512, etag, 16, 0) != NXC_BAD_ARG { return 83 } 138 if nx_http_emit_304(resp_buf, resp_off, 512, etag, 16, -1) != NXC_BAD_ARG { return 84 } 139 140 return 0 141}