nx_http_client_post_test.nx source
↩ module page · 102 lines · 3836 B
1// nx_http_client_post_test.nx -- KAT for nx_http_client_build_request_post.
2//
3// Asserts the wire-byte output for a representative ACME-style POST
4// matches an exact RFC 7230 ยง3 reference string. Body is a small
5// JSON-ish payload; content-type pinned to application/jose+json.
6//
7// Reference (header line endings shown as visible \r\n):
8//
9// POST /acme/new-account HTTP/1.1\r\n
10// Host: acme-staging-v02.api.letsencrypt.org\r\n
11// Content-Type: application/jose+json\r\n
12// Content-Length: 11\r\n
13// Connection: close\r\n
14// \r\n
15// {"hi":"x"}\n
16//
17// Total bytes (header up to "\r\n\r\n") + body 11 bytes.
18
19import "nx_syscalls.nx"
20import "nx_http_client.nx"
21
22func _assert_eq(buf: *u8, exp: *u8, n: i64) -> i64 {
23 var i: i64 = 0
24 while i < n {
25 if buf[i] != exp[i] { return i + 1 } // 1-based mismatch offset
26 i = i + 1
27 }
28 return 0
29}
30
31func main() -> i64 {
32 let path: *u8 = "/acme/new-account" as *u8
33 let host: *u8 = "acme-staging-v02.api.letsencrypt.org" as *u8
34 let ctype: *u8 = "application/jose+json" as *u8
35 let body: *u8 = "{\"hi\":\"x\"}\n" as *u8
36 let body_n: i64 = 11
37
38 let out: *u8 = sys_mmap(2048)
39 let n: i64 = nx_http_client_build_request_post(
40 path, 17,
41 host, 36,
42 ctype, 21,
43 body, body_n,
44 out
45 )
46
47 // Expected wire bytes -- exact. Header section is:
48 // "POST /acme/new-account HTTP/1.1\r\n" (33)
49 // "Host: acme-staging-v02.api.letsencrypt.org\r\n" (44)
50 // "Content-Type: application/jose+json\r\n" (37)
51 // "Content-Length: 11\r\n" (20)
52 // "Connection: close\r\n" (19)
53 // "\r\n" (2)
54 // sum header = 33+44+37+20+19+2 = 155
55 // + body 11 = 166 total
56 let exp: *u8 = "POST /acme/new-account HTTP/1.1\r\nHost: acme-staging-v02.api.letsencrypt.org\r\nContent-Type: application/jose+json\r\nContent-Length: 11\r\nConnection: close\r\n\r\n{\"hi\":\"x\"}\n" as *u8
57
58 if n != 166 { return 1 }
59 let m: i64 = _assert_eq(out, exp, 166)
60 if m != 0 { return 100 + m }
61
62 // Spot-checks at known offsets.
63 if out[0] != 80 as u8 { return 2 } // 'P'
64 if out[1] != 79 as u8 { return 3 } // 'O'
65 if out[2] != 83 as u8 { return 4 } // 'S'
66 if out[3] != 84 as u8 { return 5 } // 'T'
67 if out[4] != 32 as u8 { return 6 } // ' '
68 // last 11 bytes are body bytes
69 if out[155] != 123 as u8 { return 7 } // '{'
70 if out[165] != 10 as u8 { return 8 } // '\n'
71
72 // Second case: body_len = 1234 (multi-digit Content-Length).
73 let body2: *u8 = sys_mmap(2048)
74 var bi: i64 = 0
75 while bi < 1234 { body2[bi] = 65 as u8; bi = bi + 1 } // all 'A'
76 let out2: *u8 = sys_mmap(4096)
77 let n2: i64 = nx_http_client_build_request_post(
78 path, 17,
79 host, 36,
80 ctype, 21,
81 body2, 1234,
82 out2
83 )
84 // Header bytes count: 33+44+37 = 114; then "Content-Length: 1234\r\n" = 22;
85 // then "Connection: close\r\n" 19 + "\r\n" 2 = 21; sum header = 114+22+21 = 157
86 // + body 1234 = 1391 total
87 if n2 != 1391 { return 9 }
88 // Verify the Content-Length digits appear at expected offset (after 114-byte
89 // prefix + "Content-Length: " 16-byte string => offset 130).
90 if out2[130] != 49 as u8 { return 10 } // '1'
91 if out2[131] != 50 as u8 { return 11 } // '2'
92 if out2[132] != 51 as u8 { return 12 } // '3'
93 if out2[133] != 52 as u8 { return 13 } // '4'
94 if out2[134] != 13 as u8 { return 14 } // '\r'
95 if out2[135] != 10 as u8 { return 15 } // '\n'
96
97 // "PASS\n"
98 let ok: *u8 = sys_mmap(8)
99 ok[0]=80; ok[1]=65; ok[2]=83; ok[3]=83; ok[4]=10
100 sys_write(1, ok, 5)
101 return 0
102}