1 /*
2 * nghttp2 - HTTP/2 C Library
3 *
4 * Copyright (c) 2013 Tatsuhiro Tsujikawa
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sublicense, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be
15 * included in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25 #include "util_test.h"
26
27 #include <cstring>
28 #include <iostream>
29 #include <random>
30
31 #include <CUnit/CUnit.h>
32
33 #include <nghttp2/nghttp2.h>
34
35 #include "util.h"
36 #include "template.h"
37
38 using namespace nghttp2;
39
40 namespace shrpx {
41
test_util_streq(void)42 void test_util_streq(void) {
43 CU_ASSERT(
44 util::streq(StringRef::from_lit("alpha"), StringRef::from_lit("alpha")));
45 CU_ASSERT(!util::streq(StringRef::from_lit("alpha"),
46 StringRef::from_lit("alphabravo")));
47 CU_ASSERT(!util::streq(StringRef::from_lit("alphabravo"),
48 StringRef::from_lit("alpha")));
49 CU_ASSERT(
50 !util::streq(StringRef::from_lit("alpha"), StringRef::from_lit("alphA")));
51 CU_ASSERT(!util::streq(StringRef{}, StringRef::from_lit("a")));
52 CU_ASSERT(util::streq(StringRef{}, StringRef{}));
53 CU_ASSERT(!util::streq(StringRef::from_lit("alpha"), StringRef{}));
54
55 CU_ASSERT(
56 !util::streq(StringRef::from_lit("alph"), StringRef::from_lit("alpha")));
57 CU_ASSERT(
58 !util::streq(StringRef::from_lit("alpha"), StringRef::from_lit("alph")));
59 CU_ASSERT(
60 !util::streq(StringRef::from_lit("alpha"), StringRef::from_lit("alphA")));
61
62 CU_ASSERT(util::streq_l("alpha", "alpha", 5));
63 CU_ASSERT(util::streq_l("alpha", "alphabravo", 5));
64 CU_ASSERT(!util::streq_l("alpha", "alphabravo", 6));
65 CU_ASSERT(!util::streq_l("alphabravo", "alpha", 5));
66 CU_ASSERT(!util::streq_l("alpha", "alphA", 5));
67 CU_ASSERT(!util::streq_l("", "a", 1));
68 CU_ASSERT(util::streq_l("", "", 0));
69 CU_ASSERT(!util::streq_l("alpha", "", 0));
70 }
71
test_util_strieq(void)72 void test_util_strieq(void) {
73 CU_ASSERT(util::strieq(std::string("alpha"), std::string("alpha")));
74 CU_ASSERT(util::strieq(std::string("alpha"), std::string("AlPhA")));
75 CU_ASSERT(util::strieq(std::string(), std::string()));
76 CU_ASSERT(!util::strieq(std::string("alpha"), std::string("AlPhA ")));
77 CU_ASSERT(!util::strieq(std::string(), std::string("AlPhA ")));
78
79 CU_ASSERT(
80 util::strieq(StringRef::from_lit("alpha"), StringRef::from_lit("alpha")));
81 CU_ASSERT(
82 util::strieq(StringRef::from_lit("alpha"), StringRef::from_lit("AlPhA")));
83 CU_ASSERT(util::strieq(StringRef{}, StringRef{}));
84 CU_ASSERT(!util::strieq(StringRef::from_lit("alpha"),
85 StringRef::from_lit("AlPhA ")));
86 CU_ASSERT(
87 !util::strieq(StringRef::from_lit(""), StringRef::from_lit("AlPhA ")));
88
89 CU_ASSERT(util::strieq_l("alpha", "alpha", 5));
90 CU_ASSERT(util::strieq_l("alpha", "AlPhA", 5));
91 CU_ASSERT(util::strieq_l("", static_cast<const char *>(nullptr), 0));
92 CU_ASSERT(!util::strieq_l("alpha", "AlPhA ", 6));
93 CU_ASSERT(!util::strieq_l("", "AlPhA ", 6));
94
95 CU_ASSERT(util::strieq_l("alpha", StringRef::from_lit("alpha")));
96 CU_ASSERT(util::strieq_l("alpha", StringRef::from_lit("AlPhA")));
97 CU_ASSERT(util::strieq_l("", StringRef{}));
98 CU_ASSERT(!util::strieq_l("alpha", StringRef::from_lit("AlPhA ")));
99 CU_ASSERT(!util::strieq_l("", StringRef::from_lit("AlPhA ")));
100 }
101
test_util_inp_strlower(void)102 void test_util_inp_strlower(void) {
103 std::string a("alPha");
104 util::inp_strlower(a);
105 CU_ASSERT("alpha" == a);
106
107 a = "ALPHA123BRAVO";
108 util::inp_strlower(a);
109 CU_ASSERT("alpha123bravo" == a);
110
111 a = "";
112 util::inp_strlower(a);
113 CU_ASSERT("" == a);
114 }
115
test_util_to_base64(void)116 void test_util_to_base64(void) {
117 BlockAllocator balloc(4096, 4096);
118
119 CU_ASSERT("AAA++B/=" ==
120 util::to_base64(balloc, StringRef::from_lit("AAA--B_")));
121 CU_ASSERT("AAA++B/B" ==
122 util::to_base64(balloc, StringRef::from_lit("AAA--B_B")));
123 }
124
test_util_to_token68(void)125 void test_util_to_token68(void) {
126 std::string x = "AAA++B/=";
127 util::to_token68(x);
128 CU_ASSERT("AAA--B_" == x);
129
130 x = "AAA++B/B";
131 util::to_token68(x);
132 CU_ASSERT("AAA--B_B" == x);
133 }
134
test_util_percent_encode_token(void)135 void test_util_percent_encode_token(void) {
136 BlockAllocator balloc(4096, 4096);
137 CU_ASSERT("h2" ==
138 util::percent_encode_token(balloc, StringRef::from_lit("h2")));
139 CU_ASSERT("h3~" ==
140 util::percent_encode_token(balloc, StringRef::from_lit("h3~")));
141 CU_ASSERT("100%25" ==
142 util::percent_encode_token(balloc, StringRef::from_lit("100%")));
143 CU_ASSERT("http%202" ==
144 util::percent_encode_token(balloc, StringRef::from_lit("http 2")));
145 }
146
test_util_percent_encode_path(void)147 void test_util_percent_encode_path(void) {
148 CU_ASSERT("/foo1/bar%3F&/%0A" == util::percent_encode_path("/foo1/bar?&/"
149 "\x0a"));
150 }
151
test_util_percent_decode(void)152 void test_util_percent_decode(void) {
153 {
154 std::string s = "%66%6F%6f%62%61%72";
155 CU_ASSERT("foobar" == util::percent_decode(std::begin(s), std::end(s)));
156 }
157 {
158 std::string s = "%66%6";
159 CU_ASSERT("f%6" == util::percent_decode(std::begin(s), std::end(s)));
160 }
161 {
162 std::string s = "%66%";
163 CU_ASSERT("f%" == util::percent_decode(std::begin(s), std::end(s)));
164 }
165 BlockAllocator balloc(1024, 1024);
166
167 CU_ASSERT("foobar" == util::percent_decode(
168 balloc, StringRef::from_lit("%66%6F%6f%62%61%72")));
169
170 CU_ASSERT("f%6" ==
171 util::percent_decode(balloc, StringRef::from_lit("%66%6")));
172
173 CU_ASSERT("f%" == util::percent_decode(balloc, StringRef::from_lit("%66%")));
174 }
175
test_util_quote_string(void)176 void test_util_quote_string(void) {
177 BlockAllocator balloc(4096, 4096);
178 CU_ASSERT("alpha" ==
179 util::quote_string(balloc, StringRef::from_lit("alpha")));
180 CU_ASSERT("" == util::quote_string(balloc, StringRef::from_lit("")));
181 CU_ASSERT("\\\"alpha\\\"" ==
182 util::quote_string(balloc, StringRef::from_lit("\"alpha\"")));
183 }
184
test_util_utox(void)185 void test_util_utox(void) {
186 CU_ASSERT("0" == util::utox(0));
187 CU_ASSERT("1" == util::utox(1));
188 CU_ASSERT("F" == util::utox(15));
189 CU_ASSERT("10" == util::utox(16));
190 CU_ASSERT("3B9ACA07" == util::utox(1000000007));
191 CU_ASSERT("100000000" == util::utox(1LL << 32));
192 }
193
test_util_http_date(void)194 void test_util_http_date(void) {
195 CU_ASSERT("Thu, 01 Jan 1970 00:00:00 GMT" == util::http_date(0));
196 CU_ASSERT("Wed, 29 Feb 2012 09:15:16 GMT" == util::http_date(1330506916));
197
198 std::array<char, 30> http_buf;
199
200 CU_ASSERT("Thu, 01 Jan 1970 00:00:00 GMT" ==
201 util::format_http_date(http_buf.data(),
202 std::chrono::system_clock::time_point()));
203 CU_ASSERT("Wed, 29 Feb 2012 09:15:16 GMT" ==
204 util::format_http_date(http_buf.data(),
205 std::chrono::system_clock::time_point(
206 std::chrono::seconds(1330506916))));
207 }
208
test_util_select_h2(void)209 void test_util_select_h2(void) {
210 const unsigned char *out = NULL;
211 unsigned char outlen = 0;
212
213 // Check single entry and select it.
214 const unsigned char t1[] = "\x2h2";
215 CU_ASSERT(util::select_h2(&out, &outlen, t1, sizeof(t1) - 1));
216 CU_ASSERT(
217 memcmp(NGHTTP2_PROTO_VERSION_ID, out, NGHTTP2_PROTO_VERSION_ID_LEN) == 0);
218 CU_ASSERT(NGHTTP2_PROTO_VERSION_ID_LEN == outlen);
219
220 out = NULL;
221 outlen = 0;
222
223 // Check the case where id is correct but length is invalid and too
224 // long.
225 const unsigned char t2[] = "\x6h2-14";
226 CU_ASSERT(!util::select_h2(&out, &outlen, t2, sizeof(t2) - 1));
227
228 // Check the case where h2 is located after bogus ID.
229 const unsigned char t3[] = "\x2h3\x2h2";
230 CU_ASSERT(util::select_h2(&out, &outlen, t3, sizeof(t3) - 1));
231
232 CU_ASSERT(
233 memcmp(NGHTTP2_PROTO_VERSION_ID, out, NGHTTP2_PROTO_VERSION_ID_LEN) == 0);
234 CU_ASSERT(NGHTTP2_PROTO_VERSION_ID_LEN == outlen);
235
236 out = NULL;
237 outlen = 0;
238
239 // Check the case that last entry's length is invalid and too long.
240 const unsigned char t4[] = "\x2h3\x6h2-14";
241 CU_ASSERT(!util::select_h2(&out, &outlen, t4, sizeof(t4) - 1));
242
243 // Check the case that all entries are not supported.
244 const unsigned char t5[] = "\x2h3\x2h4";
245 CU_ASSERT(!util::select_h2(&out, &outlen, t5, sizeof(t5) - 1));
246
247 // Check the case where 2 values are eligible, but last one is
248 // picked up because it has precedence over the other.
249 const unsigned char t6[] = "\x5h2-14\x5h2-16";
250 CU_ASSERT(util::select_h2(&out, &outlen, t6, sizeof(t6) - 1));
251 CU_ASSERT(util::streq(NGHTTP2_H2_16, StringRef{out, outlen}));
252 }
253
test_util_ipv6_numeric_addr(void)254 void test_util_ipv6_numeric_addr(void) {
255 CU_ASSERT(util::ipv6_numeric_addr("::1"));
256 CU_ASSERT(util::ipv6_numeric_addr("2001:0db8:85a3:0042:1000:8a2e:0370:7334"));
257 // IPv4
258 CU_ASSERT(!util::ipv6_numeric_addr("127.0.0.1"));
259 // not numeric address
260 CU_ASSERT(!util::ipv6_numeric_addr("localhost"));
261 }
262
test_util_utos(void)263 void test_util_utos(void) {
264 uint8_t buf[32];
265
266 CU_ASSERT(("0" == StringRef{buf, util::utos(buf, 0)}));
267 CU_ASSERT(("123" == StringRef{buf, util::utos(buf, 123)}));
268 CU_ASSERT(("18446744073709551615" ==
269 StringRef{buf, util::utos(buf, 18446744073709551615ULL)}));
270 }
271
test_util_make_string_ref_uint(void)272 void test_util_make_string_ref_uint(void) {
273 BlockAllocator balloc(1024, 1024);
274
275 CU_ASSERT("0" == util::make_string_ref_uint(balloc, 0));
276 CU_ASSERT("123" == util::make_string_ref_uint(balloc, 123));
277 CU_ASSERT("18446744073709551615" ==
278 util::make_string_ref_uint(balloc, 18446744073709551615ULL));
279 }
280
test_util_utos_unit(void)281 void test_util_utos_unit(void) {
282 CU_ASSERT("0" == util::utos_unit(0));
283 CU_ASSERT("1023" == util::utos_unit(1023));
284 CU_ASSERT("1K" == util::utos_unit(1024));
285 CU_ASSERT("1K" == util::utos_unit(1025));
286 CU_ASSERT("1M" == util::utos_unit(1 << 20));
287 CU_ASSERT("1G" == util::utos_unit(1 << 30));
288 CU_ASSERT("1024G" == util::utos_unit(1LL << 40));
289 }
290
test_util_utos_funit(void)291 void test_util_utos_funit(void) {
292 CU_ASSERT("0" == util::utos_funit(0));
293 CU_ASSERT("1023" == util::utos_funit(1023));
294 CU_ASSERT("1.00K" == util::utos_funit(1024));
295 CU_ASSERT("1.00K" == util::utos_funit(1025));
296 CU_ASSERT("1.09K" == util::utos_funit(1119));
297 CU_ASSERT("1.27K" == util::utos_funit(1300));
298 CU_ASSERT("1.00M" == util::utos_funit(1 << 20));
299 CU_ASSERT("1.18M" == util::utos_funit(1234567));
300 CU_ASSERT("1.00G" == util::utos_funit(1 << 30));
301 CU_ASSERT("4492450797.23G" == util::utos_funit(4823732313248234343LL));
302 CU_ASSERT("1024.00G" == util::utos_funit(1LL << 40));
303 }
304
test_util_parse_uint_with_unit(void)305 void test_util_parse_uint_with_unit(void) {
306 CU_ASSERT(0 == util::parse_uint_with_unit("0"));
307 CU_ASSERT(1023 == util::parse_uint_with_unit("1023"));
308 CU_ASSERT(1024 == util::parse_uint_with_unit("1k"));
309 CU_ASSERT(2048 == util::parse_uint_with_unit("2K"));
310 CU_ASSERT(1 << 20 == util::parse_uint_with_unit("1m"));
311 CU_ASSERT(1 << 21 == util::parse_uint_with_unit("2M"));
312 CU_ASSERT(1 << 30 == util::parse_uint_with_unit("1g"));
313 CU_ASSERT(1LL << 31 == util::parse_uint_with_unit("2G"));
314 CU_ASSERT(9223372036854775807LL ==
315 util::parse_uint_with_unit("9223372036854775807"));
316 // check overflow case
317 CU_ASSERT(-1 == util::parse_uint_with_unit("9223372036854775808"));
318 CU_ASSERT(-1 == util::parse_uint_with_unit("10000000000000000000"));
319 CU_ASSERT(-1 == util::parse_uint_with_unit("9223372036854775807G"));
320 // bad characters
321 CU_ASSERT(-1 == util::parse_uint_with_unit("1.1"));
322 CU_ASSERT(-1 == util::parse_uint_with_unit("1a"));
323 CU_ASSERT(-1 == util::parse_uint_with_unit("a1"));
324 CU_ASSERT(-1 == util::parse_uint_with_unit("1T"));
325 CU_ASSERT(-1 == util::parse_uint_with_unit(""));
326 }
327
test_util_parse_uint(void)328 void test_util_parse_uint(void) {
329 CU_ASSERT(0 == util::parse_uint("0"));
330 CU_ASSERT(1023 == util::parse_uint("1023"));
331 CU_ASSERT(-1 == util::parse_uint("1k"));
332 CU_ASSERT(9223372036854775807LL == util::parse_uint("9223372036854775807"));
333 // check overflow case
334 CU_ASSERT(-1 == util::parse_uint("9223372036854775808"));
335 CU_ASSERT(-1 == util::parse_uint("10000000000000000000"));
336 // bad characters
337 CU_ASSERT(-1 == util::parse_uint("1.1"));
338 CU_ASSERT(-1 == util::parse_uint("1a"));
339 CU_ASSERT(-1 == util::parse_uint("a1"));
340 CU_ASSERT(-1 == util::parse_uint("1T"));
341 CU_ASSERT(-1 == util::parse_uint(""));
342 }
343
test_util_parse_duration_with_unit(void)344 void test_util_parse_duration_with_unit(void) {
345 CU_ASSERT(0. == util::parse_duration_with_unit("0"));
346 CU_ASSERT(123. == util::parse_duration_with_unit("123"));
347 CU_ASSERT(123. == util::parse_duration_with_unit("123s"));
348 CU_ASSERT(0.500 == util::parse_duration_with_unit("500ms"));
349 CU_ASSERT(123. == util::parse_duration_with_unit("123S"));
350 CU_ASSERT(0.500 == util::parse_duration_with_unit("500MS"));
351 CU_ASSERT(180 == util::parse_duration_with_unit("3m"));
352 CU_ASSERT(3600 * 5 == util::parse_duration_with_unit("5h"));
353
354 auto err = std::numeric_limits<double>::infinity();
355 // check overflow case
356 CU_ASSERT(err == util::parse_duration_with_unit("9223372036854775808"));
357 // bad characters
358 CU_ASSERT(err == util::parse_duration_with_unit("0u"));
359 CU_ASSERT(err == util::parse_duration_with_unit("0xs"));
360 CU_ASSERT(err == util::parse_duration_with_unit("0mt"));
361 CU_ASSERT(err == util::parse_duration_with_unit("0mss"));
362 CU_ASSERT(err == util::parse_duration_with_unit("s"));
363 CU_ASSERT(err == util::parse_duration_with_unit("ms"));
364 }
365
test_util_duration_str(void)366 void test_util_duration_str(void) {
367 CU_ASSERT("0" == util::duration_str(0.));
368 CU_ASSERT("1s" == util::duration_str(1.));
369 CU_ASSERT("500ms" == util::duration_str(0.5));
370 CU_ASSERT("1500ms" == util::duration_str(1.5));
371 CU_ASSERT("2m" == util::duration_str(120.));
372 CU_ASSERT("121s" == util::duration_str(121.));
373 CU_ASSERT("1h" == util::duration_str(3600.));
374 }
375
test_util_format_duration(void)376 void test_util_format_duration(void) {
377 CU_ASSERT("0us" == util::format_duration(std::chrono::microseconds(0)));
378 CU_ASSERT("999us" == util::format_duration(std::chrono::microseconds(999)));
379 CU_ASSERT("1.00ms" == util::format_duration(std::chrono::microseconds(1000)));
380 CU_ASSERT("1.09ms" == util::format_duration(std::chrono::microseconds(1090)));
381 CU_ASSERT("1.01ms" == util::format_duration(std::chrono::microseconds(1009)));
382 CU_ASSERT("999.99ms" ==
383 util::format_duration(std::chrono::microseconds(999990)));
384 CU_ASSERT("1.00s" ==
385 util::format_duration(std::chrono::microseconds(1000000)));
386 CU_ASSERT("1.05s" ==
387 util::format_duration(std::chrono::microseconds(1050000)));
388
389 CU_ASSERT("0us" == util::format_duration(0.));
390 CU_ASSERT("999us" == util::format_duration(0.000999));
391 CU_ASSERT("1.00ms" == util::format_duration(0.001));
392 CU_ASSERT("1.09ms" == util::format_duration(0.00109));
393 CU_ASSERT("1.01ms" == util::format_duration(0.001009));
394 CU_ASSERT("999.99ms" == util::format_duration(0.99999));
395 CU_ASSERT("1.00s" == util::format_duration(1.));
396 CU_ASSERT("1.05s" == util::format_duration(1.05));
397 }
398
test_util_starts_with(void)399 void test_util_starts_with(void) {
400 CU_ASSERT(util::starts_with(StringRef::from_lit("foo"),
401 StringRef::from_lit("foo")));
402 CU_ASSERT(util::starts_with(StringRef::from_lit("fooo"),
403 StringRef::from_lit("foo")));
404 CU_ASSERT(util::starts_with(StringRef::from_lit("ofoo"), StringRef{}));
405 CU_ASSERT(!util::starts_with(StringRef::from_lit("ofoo"),
406 StringRef::from_lit("foo")));
407
408 CU_ASSERT(util::istarts_with(StringRef::from_lit("FOO"),
409 StringRef::from_lit("fOO")));
410 CU_ASSERT(util::istarts_with(StringRef::from_lit("ofoo"), StringRef{}));
411 CU_ASSERT(util::istarts_with(StringRef::from_lit("fOOo"),
412 StringRef::from_lit("Foo")));
413 CU_ASSERT(!util::istarts_with(StringRef::from_lit("ofoo"),
414 StringRef::from_lit("foo")));
415
416 CU_ASSERT(util::istarts_with_l(StringRef::from_lit("fOOo"), "Foo"));
417 CU_ASSERT(!util::istarts_with_l(StringRef::from_lit("ofoo"), "foo"));
418 }
419
test_util_ends_with(void)420 void test_util_ends_with(void) {
421 CU_ASSERT(
422 util::ends_with(StringRef::from_lit("foo"), StringRef::from_lit("foo")));
423 CU_ASSERT(util::ends_with(StringRef::from_lit("foo"), StringRef{}));
424 CU_ASSERT(
425 util::ends_with(StringRef::from_lit("ofoo"), StringRef::from_lit("foo")));
426 CU_ASSERT(
427 !util::ends_with(StringRef::from_lit("ofoo"), StringRef::from_lit("fo")));
428
429 CU_ASSERT(
430 util::iends_with(StringRef::from_lit("fOo"), StringRef::from_lit("Foo")));
431 CU_ASSERT(util::iends_with(StringRef::from_lit("foo"), StringRef{}));
432 CU_ASSERT(util::iends_with(StringRef::from_lit("oFoo"),
433 StringRef::from_lit("fOO")));
434 CU_ASSERT(!util::iends_with(StringRef::from_lit("ofoo"),
435 StringRef::from_lit("fo")));
436
437 CU_ASSERT(util::iends_with_l(StringRef::from_lit("oFoo"), "fOO"));
438 CU_ASSERT(!util::iends_with_l(StringRef::from_lit("ofoo"), "fo"));
439 }
440
test_util_parse_http_date(void)441 void test_util_parse_http_date(void) {
442 CU_ASSERT(1001939696 == util::parse_http_date(StringRef::from_lit(
443 "Mon, 1 Oct 2001 12:34:56 GMT")));
444 }
445
test_util_localtime_date(void)446 void test_util_localtime_date(void) {
447 auto tz = getenv("TZ");
448 if (tz) {
449 tz = strdup(tz);
450 }
451 setenv("TZ", ":Pacific/Auckland", 1);
452 tzset();
453
454 CU_ASSERT_STRING_EQUAL("02/Oct/2001:00:34:56 +1200",
455 util::common_log_date(1001939696).c_str());
456 CU_ASSERT_STRING_EQUAL("2001-10-02T00:34:56.123+12:00",
457 util::iso8601_date(1001939696000LL + 123).c_str());
458
459 std::array<char, 27> common_buf;
460
461 CU_ASSERT("02/Oct/2001:00:34:56 +1200" ==
462 util::format_common_log(common_buf.data(),
463 std::chrono::system_clock::time_point(
464 std::chrono::seconds(1001939696))));
465
466 std::array<char, 30> iso8601_buf;
467
468 CU_ASSERT(
469 "2001-10-02T00:34:56.123+12:00" ==
470 util::format_iso8601(iso8601_buf.data(),
471 std::chrono::system_clock::time_point(
472 std::chrono::milliseconds(1001939696123LL))));
473
474 if (tz) {
475 setenv("TZ", tz, 1);
476 free(tz);
477 } else {
478 unsetenv("TZ");
479 }
480 tzset();
481 }
482
test_util_get_uint64(void)483 void test_util_get_uint64(void) {
484 {
485 auto v = std::array<unsigned char, 8>{
486 {0x01, 0x12, 0x34, 0x56, 0xff, 0x9a, 0xab, 0xbc}};
487
488 auto n = util::get_uint64(v.data());
489
490 CU_ASSERT(0x01123456ff9aabbcULL == n);
491 }
492 {
493 auto v = std::array<unsigned char, 8>{
494 {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
495
496 auto n = util::get_uint64(v.data());
497
498 CU_ASSERT(0xffffffffffffffffULL == n);
499 }
500 }
501
test_util_parse_config_str_list(void)502 void test_util_parse_config_str_list(void) {
503 auto res = util::parse_config_str_list(StringRef::from_lit("a"));
504 CU_ASSERT(1 == res.size());
505 CU_ASSERT("a" == res[0]);
506
507 res = util::parse_config_str_list(StringRef::from_lit("a,"));
508 CU_ASSERT(2 == res.size());
509 CU_ASSERT("a" == res[0]);
510 CU_ASSERT("" == res[1]);
511
512 res = util::parse_config_str_list(StringRef::from_lit(":a::"), ':');
513 CU_ASSERT(4 == res.size());
514 CU_ASSERT("" == res[0]);
515 CU_ASSERT("a" == res[1]);
516 CU_ASSERT("" == res[2]);
517 CU_ASSERT("" == res[3]);
518
519 res = util::parse_config_str_list(StringRef{});
520 CU_ASSERT(1 == res.size());
521 CU_ASSERT("" == res[0]);
522
523 res = util::parse_config_str_list(StringRef::from_lit("alpha,bravo,charlie"));
524 CU_ASSERT(3 == res.size());
525 CU_ASSERT("alpha" == res[0]);
526 CU_ASSERT("bravo" == res[1]);
527 CU_ASSERT("charlie" == res[2]);
528 }
529
test_util_make_http_hostport(void)530 void test_util_make_http_hostport(void) {
531 BlockAllocator balloc(4096, 4096);
532
533 CU_ASSERT("localhost" == util::make_http_hostport(
534 balloc, StringRef::from_lit("localhost"), 80));
535 CU_ASSERT("[::1]" ==
536 util::make_http_hostport(balloc, StringRef::from_lit("::1"), 443));
537 CU_ASSERT(
538 "localhost:3000" ==
539 util::make_http_hostport(balloc, StringRef::from_lit("localhost"), 3000));
540 }
541
test_util_make_hostport(void)542 void test_util_make_hostport(void) {
543 std::array<char, util::max_hostport> hostport_buf;
544 CU_ASSERT("localhost:80" ==
545 util::make_hostport(std::begin(hostport_buf),
546 StringRef::from_lit("localhost"), 80));
547 CU_ASSERT("[::1]:443" == util::make_hostport(std::begin(hostport_buf),
548 StringRef::from_lit("::1"),
549 443));
550
551 BlockAllocator balloc(4096, 4096);
552 CU_ASSERT("localhost:80" ==
553 util::make_hostport(balloc, StringRef::from_lit("localhost"), 80));
554 CU_ASSERT("[::1]:443" ==
555 util::make_hostport(balloc, StringRef::from_lit("::1"), 443));
556 }
557
test_util_strifind(void)558 void test_util_strifind(void) {
559 CU_ASSERT(util::strifind(StringRef::from_lit("gzip, deflate, bzip2"),
560 StringRef::from_lit("gzip")));
561
562 CU_ASSERT(util::strifind(StringRef::from_lit("gzip, deflate, bzip2"),
563 StringRef::from_lit("dEflate")));
564
565 CU_ASSERT(util::strifind(StringRef::from_lit("gzip, deflate, bzip2"),
566 StringRef::from_lit("BZIP2")));
567
568 CU_ASSERT(util::strifind(StringRef::from_lit("nghttp2"), StringRef{}));
569
570 // Be aware this fact
571 CU_ASSERT(!util::strifind(StringRef{}, StringRef{}));
572
573 CU_ASSERT(!util::strifind(StringRef::from_lit("nghttp2"),
574 StringRef::from_lit("http1")));
575 }
576
test_util_random_alpha_digit(void)577 void test_util_random_alpha_digit(void) {
578 std::random_device rd;
579 std::mt19937 gen(rd());
580 std::array<uint8_t, 19> data;
581
582 auto p = util::random_alpha_digit(std::begin(data), std::end(data), gen);
583
584 CU_ASSERT(std::end(data) == p);
585
586 for (auto b : data) {
587 CU_ASSERT(('A' <= b && b <= 'Z') || ('a' <= b && b <= 'z') ||
588 ('0' <= b && b <= '9'));
589 }
590 }
591
test_util_format_hex(void)592 void test_util_format_hex(void) {
593 BlockAllocator balloc(4096, 4096);
594
595 CU_ASSERT("0ff0" ==
596 util::format_hex(balloc, StringRef::from_lit("\x0f\xf0")));
597 CU_ASSERT("" == util::format_hex(balloc, StringRef::from_lit("")));
598 }
599
test_util_is_hex_string(void)600 void test_util_is_hex_string(void) {
601 CU_ASSERT(util::is_hex_string(StringRef{}));
602 CU_ASSERT(util::is_hex_string(StringRef::from_lit("0123456789abcdef")));
603 CU_ASSERT(util::is_hex_string(StringRef::from_lit("0123456789ABCDEF")));
604 CU_ASSERT(!util::is_hex_string(StringRef::from_lit("000")));
605 CU_ASSERT(!util::is_hex_string(StringRef::from_lit("XX")));
606 }
607
test_util_decode_hex(void)608 void test_util_decode_hex(void) {
609 BlockAllocator balloc(4096, 4096);
610
611 CU_ASSERT("\x0f\xf0" ==
612 util::decode_hex(balloc, StringRef::from_lit("0ff0")));
613 CU_ASSERT("" == util::decode_hex(balloc, StringRef{}));
614 }
615
test_util_extract_host(void)616 void test_util_extract_host(void) {
617 CU_ASSERT(StringRef::from_lit("foo") ==
618 util::extract_host(StringRef::from_lit("foo")));
619 CU_ASSERT(StringRef::from_lit("foo") ==
620 util::extract_host(StringRef::from_lit("foo:")));
621 CU_ASSERT(StringRef::from_lit("foo") ==
622 util::extract_host(StringRef::from_lit("foo:0")));
623 CU_ASSERT(StringRef::from_lit("[::1]") ==
624 util::extract_host(StringRef::from_lit("[::1]")));
625 CU_ASSERT(StringRef::from_lit("[::1]") ==
626 util::extract_host(StringRef::from_lit("[::1]:")));
627
628 CU_ASSERT(util::extract_host(StringRef::from_lit(":foo")).empty());
629 CU_ASSERT(util::extract_host(StringRef::from_lit("[::1")).empty());
630 CU_ASSERT(util::extract_host(StringRef::from_lit("[::1]0")).empty());
631 CU_ASSERT(util::extract_host(StringRef{}).empty());
632 }
633
test_util_split_hostport(void)634 void test_util_split_hostport(void) {
635 CU_ASSERT(std::make_pair(StringRef::from_lit("foo"), StringRef{}) ==
636 util::split_hostport(StringRef::from_lit("foo")));
637 CU_ASSERT(
638 std::make_pair(StringRef::from_lit("foo"), StringRef::from_lit("80")) ==
639 util::split_hostport(StringRef::from_lit("foo:80")));
640 CU_ASSERT(
641 std::make_pair(StringRef::from_lit("::1"), StringRef::from_lit("80")) ==
642 util::split_hostport(StringRef::from_lit("[::1]:80")));
643 CU_ASSERT(std::make_pair(StringRef::from_lit("::1"), StringRef{}) ==
644 util::split_hostport(StringRef::from_lit("[::1]")));
645
646 CU_ASSERT(std::make_pair(StringRef{}, StringRef{}) ==
647 util::split_hostport(StringRef{}));
648 CU_ASSERT(std::make_pair(StringRef{}, StringRef{}) ==
649 util::split_hostport(StringRef::from_lit("[::1]:")));
650 CU_ASSERT(std::make_pair(StringRef{}, StringRef{}) ==
651 util::split_hostport(StringRef::from_lit("foo:")));
652 CU_ASSERT(std::make_pair(StringRef{}, StringRef{}) ==
653 util::split_hostport(StringRef::from_lit("[::1:")));
654 CU_ASSERT(std::make_pair(StringRef{}, StringRef{}) ==
655 util::split_hostport(StringRef::from_lit("[::1]80")));
656 }
657
test_util_split_str(void)658 void test_util_split_str(void) {
659 CU_ASSERT(std::vector<StringRef>{StringRef::from_lit("")} ==
660 util::split_str(StringRef::from_lit(""), ','));
661 CU_ASSERT(std::vector<StringRef>{StringRef::from_lit("alpha")} ==
662 util::split_str(StringRef::from_lit("alpha"), ','));
663 CU_ASSERT((std::vector<StringRef>{StringRef::from_lit("alpha"),
664 StringRef::from_lit("")}) ==
665 util::split_str(StringRef::from_lit("alpha,"), ','));
666 CU_ASSERT((std::vector<StringRef>{StringRef::from_lit("alpha"),
667 StringRef::from_lit("bravo")}) ==
668 util::split_str(StringRef::from_lit("alpha,bravo"), ','));
669 CU_ASSERT((std::vector<StringRef>{StringRef::from_lit("alpha"),
670 StringRef::from_lit("bravo"),
671 StringRef::from_lit("charlie")}) ==
672 util::split_str(StringRef::from_lit("alpha,bravo,charlie"), ','));
673 CU_ASSERT(
674 (std::vector<StringRef>{StringRef::from_lit("alpha"),
675 StringRef::from_lit("bravo"),
676 StringRef::from_lit("charlie")}) ==
677 util::split_str(StringRef::from_lit("alpha,bravo,charlie"), ',', 0));
678 CU_ASSERT(std::vector<StringRef>{StringRef::from_lit("")} ==
679 util::split_str(StringRef::from_lit(""), ',', 1));
680 CU_ASSERT(std::vector<StringRef>{StringRef::from_lit("")} ==
681 util::split_str(StringRef::from_lit(""), ',', 2));
682 CU_ASSERT(
683 (std::vector<StringRef>{StringRef::from_lit("alpha"),
684 StringRef::from_lit("bravo,charlie")}) ==
685 util::split_str(StringRef::from_lit("alpha,bravo,charlie"), ',', 2));
686 CU_ASSERT(std::vector<StringRef>{StringRef::from_lit("alpha")} ==
687 util::split_str(StringRef::from_lit("alpha"), ',', 2));
688 CU_ASSERT((std::vector<StringRef>{StringRef::from_lit("alpha"),
689 StringRef::from_lit("")}) ==
690 util::split_str(StringRef::from_lit("alpha,"), ',', 2));
691 CU_ASSERT(std::vector<StringRef>{StringRef::from_lit("alpha")} ==
692 util::split_str(StringRef::from_lit("alpha"), ',', 0));
693 CU_ASSERT(
694 std::vector<StringRef>{StringRef::from_lit("alpha,bravo,charlie")} ==
695 util::split_str(StringRef::from_lit("alpha,bravo,charlie"), ',', 1));
696 }
697
698 } // namespace shrpx
699