1 /*
2 * nghttp2 - HTTP/2 C Library
3 *
4 * Copyright (c) 2012 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 #ifndef UTIL_H
26 #define UTIL_H
27
28 #include "nghttp2_config.h"
29
30 #ifdef HAVE_UNISTD_H
31 # include <unistd.h>
32 #endif // HAVE_UNISTD_H
33 #include <getopt.h>
34 #ifdef HAVE_NETDB_H
35 # include <netdb.h>
36 #endif // HAVE_NETDB_H
37
38 #include <cmath>
39 #include <cstring>
40 #include <cassert>
41 #include <vector>
42 #include <string>
43 #include <algorithm>
44 #include <sstream>
45 #include <memory>
46 #include <chrono>
47 #include <map>
48 #include <random>
49 #include <optional>
50
51 #ifdef HAVE_LIBEV
52 # include <ev.h>
53 #endif // HAVE_LIBEV
54
55 #include "url-parser/url_parser.h"
56
57 #include "template.h"
58 #include "network.h"
59 #include "allocator.h"
60
61 namespace nghttp2 {
62
63 constexpr auto NGHTTP2_H2_ALPN = "\x2h2"_sr;
64 constexpr auto NGHTTP2_H2 = "h2"_sr;
65
66 // The additional HTTP/2 protocol ALPN protocol identifier we also
67 // supports for our applications to make smooth migration into final
68 // h2 ALPN ID.
69 constexpr auto NGHTTP2_H2_16_ALPN = "\x5h2-16"_sr;
70 constexpr auto NGHTTP2_H2_16 = "h2-16"_sr;
71
72 constexpr auto NGHTTP2_H2_14_ALPN = "\x5h2-14"_sr;
73 constexpr auto NGHTTP2_H2_14 = "h2-14"_sr;
74
75 constexpr auto NGHTTP2_H1_1_ALPN = "\x8http/1.1"_sr;
76 constexpr auto NGHTTP2_H1_1 = "http/1.1"_sr;
77
78 constexpr size_t NGHTTP2_MAX_UINT64_DIGITS = str_size("18446744073709551615");
79
80 namespace util {
81
82 extern const char UPPER_XDIGITS[];
83
is_alpha(const char c)84 inline bool is_alpha(const char c) {
85 return ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z');
86 }
87
is_digit(const char c)88 inline bool is_digit(const char c) { return '0' <= c && c <= '9'; }
89
is_hex_digit(const char c)90 inline bool is_hex_digit(const char c) {
91 return is_digit(c) || ('A' <= c && c <= 'F') || ('a' <= c && c <= 'f');
92 }
93
94 // Returns true if |s| is hex string.
95 bool is_hex_string(const StringRef &s);
96
97 bool in_rfc3986_unreserved_chars(const char c);
98
99 bool in_rfc3986_sub_delims(const char c);
100
101 // Returns true if |c| is in token (HTTP-p1, Section 3.2.6)
102 bool in_token(char c);
103
104 bool in_attr_char(char c);
105
106 // Returns integer corresponding to hex notation |c|. If
107 // is_hex_digit(c) is false, it returns 256.
108 uint32_t hex_to_uint(char c);
109
110 std::string percent_encode(const unsigned char *target, size_t len);
111
112 std::string percent_encode(const std::string &target);
113
114 template <typename InputIt>
percent_decode(InputIt first,InputIt last)115 std::string percent_decode(InputIt first, InputIt last) {
116 std::string result;
117 result.resize(last - first);
118 auto p = std::begin(result);
119 for (; first != last; ++first) {
120 if (*first != '%') {
121 *p++ = *first;
122 continue;
123 }
124
125 if (first + 1 != last && first + 2 != last && is_hex_digit(*(first + 1)) &&
126 is_hex_digit(*(first + 2))) {
127 *p++ = (hex_to_uint(*(first + 1)) << 4) + hex_to_uint(*(first + 2));
128 first += 2;
129 continue;
130 }
131
132 *p++ = *first;
133 }
134 result.resize(p - std::begin(result));
135 return result;
136 }
137
138 StringRef percent_decode(BlockAllocator &balloc, const StringRef &src);
139
140 // Percent encode |target| if character is not in token or '%'.
141 StringRef percent_encode_token(BlockAllocator &balloc, const StringRef &target);
142
143 template <typename OutputIt>
percent_encode_token(OutputIt it,const StringRef & target)144 OutputIt percent_encode_token(OutputIt it, const StringRef &target) {
145 for (auto first = std::begin(target); first != std::end(target); ++first) {
146 uint8_t c = *first;
147
148 if (c != '%' && in_token(c)) {
149 *it++ = c;
150 continue;
151 }
152
153 *it++ = '%';
154 *it++ = UPPER_XDIGITS[c >> 4];
155 *it++ = UPPER_XDIGITS[(c & 0x0f)];
156 }
157
158 return it;
159 }
160
161 // Returns the number of bytes written by percent_encode_token with
162 // the same |target| parameter. The return value does not include a
163 // terminal NUL byte.
164 size_t percent_encode_tokenlen(const StringRef &target);
165
166 // Returns quotedString version of |target|. Currently, this function
167 // just replace '"' with '\"'.
168 StringRef quote_string(BlockAllocator &balloc, const StringRef &target);
169
170 template <typename OutputIt>
quote_string(OutputIt it,const StringRef & target)171 OutputIt quote_string(OutputIt it, const StringRef &target) {
172 for (auto c : target) {
173 if (c == '"') {
174 *it++ = '\\';
175 *it++ = '"';
176 } else {
177 *it++ = c;
178 }
179 }
180
181 return it;
182 }
183
184 // Returns the number of bytes written by quote_string with the same
185 // |target| parameter. The return value does not include a terminal
186 // NUL byte.
187 size_t quote_stringlen(const StringRef &target);
188
189 static constexpr char LOWER_XDIGITS[] = "0123456789abcdef";
190
191 template <std::weakly_incrementable OutputIt>
format_hex(OutputIt it,std::span<const uint8_t> s)192 OutputIt format_hex(OutputIt it, std::span<const uint8_t> s) {
193 for (auto c : s) {
194 *it++ = LOWER_XDIGITS[c >> 4];
195 *it++ = LOWER_XDIGITS[c & 0xf];
196 }
197
198 return it;
199 }
200
201 template <typename T, size_t N = std::dynamic_extent,
202 std::weakly_incrementable OutputIt>
format_hex(OutputIt it,std::span<T,N> s)203 OutputIt format_hex(OutputIt it, std::span<T, N> s) {
204 return format_hex(it, std::span<const uint8_t>{as_uint8_span(s)});
205 }
206
207 std::string format_hex(std::span<const uint8_t> s);
208
209 template <typename T, size_t N = std::dynamic_extent>
format_hex(std::span<T,N> s)210 std::string format_hex(std::span<T, N> s) {
211 return format_hex(std::span<const uint8_t>{as_uint8_span(s)});
212 }
213
214 StringRef format_hex(BlockAllocator &balloc, std::span<const uint8_t> s);
215
216 template <typename T, size_t N = std::dynamic_extent>
format_hex(BlockAllocator & balloc,std::span<T,N> s)217 StringRef format_hex(BlockAllocator &balloc, std::span<T, N> s) {
218 return format_hex(balloc, std::span<const uint8_t>{as_uint8_span(s)});
219 }
220
221 // decode_hex decodes hex string |s|, returns the decoded byte string.
222 // This function assumes |s| is hex string, that is is_hex_string(s)
223 // == true.
224 std::span<const uint8_t> decode_hex(BlockAllocator &balloc, const StringRef &s);
225
226 template <typename OutputIt>
decode_hex(OutputIt d_first,const StringRef & s)227 OutputIt decode_hex(OutputIt d_first, const StringRef &s) {
228 for (auto it = std::begin(s); it != std::end(s); it += 2) {
229 *d_first++ = (hex_to_uint(*it) << 4) | hex_to_uint(*(it + 1));
230 }
231
232 return d_first;
233 }
234
235 // Returns given time |t| from epoch in HTTP Date format (e.g., Mon,
236 // 10 Oct 2016 10:25:58 GMT).
237 std::string http_date(time_t t);
238 // Writes given time |t| from epoch in HTTP Date format into the
239 // buffer pointed by |res|. The buffer must be at least 29 bytes
240 // long. This function returns the one beyond the last position.
241 char *http_date(char *res, time_t t);
242
243 // Returns given time |t| from epoch in Common Log format (e.g.,
244 // 03/Jul/2014:00:19:38 +0900)
245 std::string common_log_date(time_t t);
246 // Writes given time |t| from epoch in Common Log format into the
247 // buffer pointed by |res|. The buffer must be at least 26 bytes
248 // long. This function returns the one beyond the last position.
249 char *common_log_date(char *res, time_t t);
250
251 // Returns given millisecond |ms| from epoch in ISO 8601 format (e.g.,
252 // 2014-11-15T12:58:24.741Z or 2014-11-15T12:58:24.741+09:00)
253 std::string iso8601_date(int64_t ms);
254 // Writes given time |t| from epoch in ISO 8601 format into the buffer
255 // pointed by |res|. The buffer must be at least 29 bytes long. This
256 // function returns the one beyond the last position.
257 char *iso8601_date(char *res, int64_t ms);
258
259 // Writes given time |t| from epoch in ISO 8601 basic format into the
260 // buffer pointed by |res|. The buffer must be at least 24 bytes
261 // long. This function returns the one beyond the last position.
262 char *iso8601_basic_date(char *res, int64_t ms);
263
264 time_t parse_http_date(const StringRef &s);
265
266 // Parses time formatted as "MMM DD HH:MM:SS YYYY [GMT]" (e.g., Feb 3
267 // 00:55:52 2015 GMT), which is specifically used by OpenSSL
268 // ASN1_TIME_print().
269 time_t parse_openssl_asn1_time_print(const StringRef &s);
270
271 char upcase(char c);
272
lowcase(char c)273 inline char lowcase(char c) {
274 constexpr static unsigned char tbl[] = {
275 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
276 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
277 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
278 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
279 60, 61, 62, 63, 64, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
280 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y',
281 'z', 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
282 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
283 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134,
284 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
285 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,
286 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179,
287 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194,
288 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209,
289 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224,
290 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
291 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254,
292 255,
293 };
294 return tbl[static_cast<unsigned char>(c)];
295 }
296
297 template <typename InputIterator1, typename InputIterator2>
starts_with(InputIterator1 first1,InputIterator1 last1,InputIterator2 first2,InputIterator2 last2)298 bool starts_with(InputIterator1 first1, InputIterator1 last1,
299 InputIterator2 first2, InputIterator2 last2) {
300 return std::distance(first1, last1) >= std::distance(first2, last2) &&
301 std::equal(first2, last2, first1);
302 }
303
starts_with(const S & a,const T & b)304 template <typename S, typename T> bool starts_with(const S &a, const T &b) {
305 return starts_with(std::begin(a), std::end(a), std::begin(b), std::end(b));
306 }
307
308 struct CaseCmp {
operatorCaseCmp309 bool operator()(char lhs, char rhs) const {
310 return lowcase(lhs) == lowcase(rhs);
311 }
312 };
313
314 template <typename InputIterator1, typename InputIterator2>
istarts_with(InputIterator1 first1,InputIterator1 last1,InputIterator2 first2,InputIterator2 last2)315 bool istarts_with(InputIterator1 first1, InputIterator1 last1,
316 InputIterator2 first2, InputIterator2 last2) {
317 return std::distance(first1, last1) >= std::distance(first2, last2) &&
318 std::equal(first2, last2, first1, CaseCmp());
319 }
320
istarts_with(const S & a,const T & b)321 template <typename S, typename T> bool istarts_with(const S &a, const T &b) {
322 return istarts_with(std::begin(a), std::end(a), std::begin(b), std::end(b));
323 }
324
325 template <typename InputIterator1, typename InputIterator2>
ends_with(InputIterator1 first1,InputIterator1 last1,InputIterator2 first2,InputIterator2 last2)326 bool ends_with(InputIterator1 first1, InputIterator1 last1,
327 InputIterator2 first2, InputIterator2 last2) {
328 auto len1 = std::distance(first1, last1);
329 auto len2 = std::distance(first2, last2);
330
331 return len1 >= len2 && std::equal(first2, last2, first1 + (len1 - len2));
332 }
333
ends_with(const T & a,const S & b)334 template <typename T, typename S> bool ends_with(const T &a, const S &b) {
335 return ends_with(std::begin(a), std::end(a), std::begin(b), std::end(b));
336 }
337
338 template <typename InputIterator1, typename InputIterator2>
iends_with(InputIterator1 first1,InputIterator1 last1,InputIterator2 first2,InputIterator2 last2)339 bool iends_with(InputIterator1 first1, InputIterator1 last1,
340 InputIterator2 first2, InputIterator2 last2) {
341 auto len1 = std::distance(first1, last1);
342 auto len2 = std::distance(first2, last2);
343
344 return len1 >= len2 &&
345 std::equal(first2, last2, first1 + (len1 - len2), CaseCmp());
346 }
347
iends_with(const T & a,const S & b)348 template <typename T, typename S> bool iends_with(const T &a, const S &b) {
349 return iends_with(std::begin(a), std::end(a), std::begin(b), std::end(b));
350 }
351
352 template <typename InputIt1, typename InputIt2>
strieq(InputIt1 first1,InputIt1 last1,InputIt2 first2,InputIt2 last2)353 bool strieq(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2) {
354 return std::equal(first1, last1, first2, last2, CaseCmp());
355 }
356
strieq(const T & a,const S & b)357 template <typename T, typename S> bool strieq(const T &a, const S &b) {
358 return strieq(std::begin(a), std::end(a), std::begin(b), std::end(b));
359 }
360
361 template <typename T, typename S>
strieq(const T & a,const S & b,size_t blen)362 bool strieq(const T &a, const S &b, size_t blen) {
363 return std::equal(std::begin(a), std::end(a), std::begin(b),
364 std::next(std::begin(b), blen), CaseCmp());
365 }
366
367 template <typename T, typename S>
streq(const T & a,const S & b,size_t blen)368 bool streq(const T &a, const S &b, size_t blen) {
369 return std::equal(std::begin(a), std::end(a), std::begin(b),
370 std::next(std::begin(b), blen));
371 }
372
inp_strlower(InputIt first,InputIt last)373 template <typename InputIt> void inp_strlower(InputIt first, InputIt last) {
374 std::transform(first, last, first, lowcase);
375 }
376
377 // Lowercase |s| in place.
inp_strlower(std::string & s)378 inline void inp_strlower(std::string &s) {
379 inp_strlower(std::begin(s), std::end(s));
380 }
381
382 // Returns string representation of |n| with 2 fractional digits.
383 std::string dtos(double n);
384
utos(T n)385 template <typename T> std::string utos(T n) {
386 std::string res;
387 if (n == 0) {
388 res = "0";
389 return res;
390 }
391 size_t nlen = 0;
392 for (auto t = n; t; t /= 10, ++nlen)
393 ;
394 res.resize(nlen);
395 for (; n; n /= 10) {
396 res[--nlen] = (n % 10) + '0';
397 }
398 return res;
399 }
400
utos(OutputIt dst,T n)401 template <typename T, typename OutputIt> OutputIt utos(OutputIt dst, T n) {
402 if (n == 0) {
403 *dst++ = '0';
404 return dst;
405 }
406 size_t nlen = 0;
407 for (auto t = n; t; t /= 10, ++nlen)
408 ;
409 auto p = dst + nlen;
410 auto res = p;
411 for (; n; n /= 10) {
412 *--p = (n % 10) + '0';
413 }
414 return res;
415 }
416
417 template <typename T>
make_string_ref_uint(BlockAllocator & balloc,T n)418 StringRef make_string_ref_uint(BlockAllocator &balloc, T n) {
419 auto iov = make_byte_ref(balloc, NGHTTP2_MAX_UINT64_DIGITS + 1);
420 auto p = std::begin(iov);
421 p = util::utos(p, n);
422 *p = '\0';
423 return StringRef{std::span{std::begin(iov), p}};
424 }
425
utos_unit(T n)426 template <typename T> std::string utos_unit(T n) {
427 char u = 0;
428 if (n >= (1 << 30)) {
429 u = 'G';
430 n /= (1 << 30);
431 } else if (n >= (1 << 20)) {
432 u = 'M';
433 n /= (1 << 20);
434 } else if (n >= (1 << 10)) {
435 u = 'K';
436 n /= (1 << 10);
437 }
438 if (u == 0) {
439 return utos(n);
440 }
441 return utos(n) + u;
442 }
443
444 // Like utos_unit(), but 2 digits fraction part is followed.
utos_funit(T n)445 template <typename T> std::string utos_funit(T n) {
446 char u = 0;
447 int b = 0;
448 if (n >= (1 << 30)) {
449 u = 'G';
450 b = 30;
451 } else if (n >= (1 << 20)) {
452 u = 'M';
453 b = 20;
454 } else if (n >= (1 << 10)) {
455 u = 'K';
456 b = 10;
457 }
458 if (b == 0) {
459 return utos(n);
460 }
461 return dtos(static_cast<double>(n) / (1 << b)) + u;
462 }
463
utox(T n)464 template <typename T> std::string utox(T n) {
465 std::string res;
466 if (n == 0) {
467 res = "0";
468 return res;
469 }
470 int i = 0;
471 T t = n;
472 for (; t; t /= 16, ++i)
473 ;
474 res.resize(i);
475 --i;
476 for (; n; --i, n /= 16) {
477 res[i] = UPPER_XDIGITS[(n & 0x0f)];
478 }
479 return res;
480 }
481
482 void to_token68(std::string &base64str);
483
484 StringRef to_base64(BlockAllocator &balloc, const StringRef &token68str);
485
486 void show_candidates(const char *unkopt, const option *options);
487
488 bool has_uri_field(const http_parser_url &u, http_parser_url_fields field);
489
490 bool fieldeq(const char *uri1, const http_parser_url &u1, const char *uri2,
491 const http_parser_url &u2, http_parser_url_fields field);
492
493 bool fieldeq(const char *uri, const http_parser_url &u,
494 http_parser_url_fields field, const char *t);
495
496 bool fieldeq(const char *uri, const http_parser_url &u,
497 http_parser_url_fields field, const StringRef &t);
498
499 StringRef get_uri_field(const char *uri, const http_parser_url &u,
500 http_parser_url_fields field);
501
502 uint16_t get_default_port(const char *uri, const http_parser_url &u);
503
504 bool porteq(const char *uri1, const http_parser_url &u1, const char *uri2,
505 const http_parser_url &u2);
506
507 void write_uri_field(std::ostream &o, const char *uri, const http_parser_url &u,
508 http_parser_url_fields field);
509
510 bool numeric_host(const char *hostname);
511
512 bool numeric_host(const char *hostname, int family);
513
514 // Returns numeric address string of |addr|. If getnameinfo() is
515 // failed, "unknown" is returned.
516 std::string numeric_name(const struct sockaddr *sa, socklen_t salen);
517
518 // Returns string representation of numeric address and port of
519 // |addr|. If address family is AF_UNIX, this return path to UNIX
520 // domain socket. Otherwise, the format is like <HOST>:<PORT>. For
521 // IPv6 address, address is enclosed by square brackets ([]).
522 std::string to_numeric_addr(const Address *addr);
523
524 std::string to_numeric_addr(const struct sockaddr *sa, socklen_t salen);
525
526 // Sets |port| to |addr|.
527 void set_port(Address &addr, uint16_t port);
528
529 // Get port from |su|.
530 uint16_t get_port(const sockaddr_union *su);
531
532 // Returns true if |port| is prohibited as a QUIC client port.
533 bool quic_prohibited_port(uint16_t port);
534
535 // Returns ASCII dump of |data| of length |len|. Only ASCII printable
536 // characters are preserved. Other characters are replaced with ".".
537 std::string ascii_dump(const uint8_t *data, size_t len);
538
539 // Returns absolute path of executable path. If argc == 0 or |cwd| is
540 // nullptr, this function returns nullptr. If argv[0] starts with
541 // '/', this function returns argv[0]. Otherwise return cwd + "/" +
542 // argv[0]. If non-null is returned, it is NULL-terminated string and
543 // dynamically allocated by malloc. The caller is responsible to free
544 // it.
545 char *get_exec_path(int argc, char **const argv, const char *cwd);
546
547 // Validates path so that it does not contain directory traversal
548 // vector. Returns true if path is safe. The |path| must start with
549 // "/" otherwise returns false. This function should be called after
550 // percent-decode was performed.
551 bool check_path(const std::string &path);
552
553 // Returns the |tv| value as 64 bit integer using a microsecond as an
554 // unit.
555 int64_t to_time64(const timeval &tv);
556
557 // Returns true if ALPN ID |proto| is supported HTTP/2 protocol
558 // identifier.
559 bool check_h2_is_selected(const StringRef &proto);
560
561 // Selects h2 protocol ALPN ID if one of supported h2 versions are
562 // present in |in| of length inlen. Returns true if h2 version is
563 // selected.
564 bool select_h2(const unsigned char **out, unsigned char *outlen,
565 const unsigned char *in, unsigned int inlen);
566
567 // Selects protocol ALPN ID if one of identifiers contained in |protolist| is
568 // present in |in| of length inlen. Returns true if identifier is
569 // selected.
570 bool select_protocol(const unsigned char **out, unsigned char *outlen,
571 const unsigned char *in, unsigned int inlen,
572 std::vector<std::string> proto_list);
573
574 // Returns default ALPN protocol list, which only contains supported
575 // HTTP/2 protocol identifier.
576 std::vector<unsigned char> get_default_alpn();
577
578 // Parses delimited strings in |s| and returns the array of substring,
579 // delimited by |delim|. The any white spaces around substring are
580 // treated as a part of substring.
581 std::vector<std::string> parse_config_str_list(const StringRef &s,
582 char delim = ',');
583
584 // Parses delimited strings in |s| and returns Substrings in |s|
585 // delimited by |delim|. The any white spaces around substring are
586 // treated as a part of substring.
587 std::vector<StringRef> split_str(const StringRef &s, char delim);
588
589 // Behaves like split_str, but this variant splits at most |n| - 1
590 // times and returns at most |n| sub-strings. If |n| is zero, it
591 // falls back to split_str.
592 std::vector<StringRef> split_str(const StringRef &s, char delim, size_t n);
593
594 // Writes given time |tp| in Common Log format (e.g.,
595 // 03/Jul/2014:00:19:38 +0900) in buffer pointed by |out|. The buffer
596 // must be at least 27 bytes, including terminal NULL byte. Expected
597 // type of |tp| is std::chrono::time_point. This function returns
598 // StringRef wrapping the buffer pointed by |out|, and this string is
599 // terminated by NULL.
format_common_log(char * out,const T & tp)600 template <typename T> StringRef format_common_log(char *out, const T &tp) {
601 auto t =
602 std::chrono::duration_cast<std::chrono::seconds>(tp.time_since_epoch());
603 auto p = common_log_date(out, t.count());
604 *p = '\0';
605 return StringRef{out, p};
606 }
607
608 // Returns given time |tp| in ISO 8601 format (e.g.,
609 // 2014-11-15T12:58:24.741Z or 2014-11-15T12:58:24.741+09:00).
610 // Expected type of |tp| is std::chrono::time_point
format_iso8601(const T & tp)611 template <typename T> std::string format_iso8601(const T &tp) {
612 auto t = std::chrono::duration_cast<std::chrono::milliseconds>(
613 tp.time_since_epoch());
614 return iso8601_date(t.count());
615 }
616
617 // Writes given time |tp| in ISO 8601 format (e.g.,
618 // 2014-11-15T12:58:24.741Z or 2014-11-15T12:58:24.741+09:00) in
619 // buffer pointed by |out|. The buffer must be at least 30 bytes,
620 // including terminal NULL byte. Expected type of |tp| is
621 // std::chrono::time_point. This function returns StringRef wrapping
622 // the buffer pointed by |out|, and this string is terminated by NULL.
format_iso8601(char * out,const T & tp)623 template <typename T> StringRef format_iso8601(char *out, const T &tp) {
624 auto t = std::chrono::duration_cast<std::chrono::milliseconds>(
625 tp.time_since_epoch());
626 auto p = iso8601_date(out, t.count());
627 *p = '\0';
628 return StringRef{out, p};
629 }
630
631 // Writes given time |tp| in ISO 8601 basic format (e.g.,
632 // 20141115T125824.741Z or 20141115T125824.741+0900) in buffer pointed
633 // by |out|. The buffer must be at least 25 bytes, including terminal
634 // NULL byte. Expected type of |tp| is std::chrono::time_point. This
635 // function returns StringRef wrapping the buffer pointed by |out|,
636 // and this string is terminated by NULL.
format_iso8601_basic(char * out,const T & tp)637 template <typename T> StringRef format_iso8601_basic(char *out, const T &tp) {
638 auto t = std::chrono::duration_cast<std::chrono::milliseconds>(
639 tp.time_since_epoch());
640 auto p = iso8601_basic_date(out, t.count());
641 *p = '\0';
642 return StringRef{out, p};
643 }
644
645 // Writes given time |tp| in HTTP Date format (e.g., Mon, 10 Oct 2016
646 // 10:25:58 GMT) in buffer pointed by |out|. The buffer must be at
647 // least 30 bytes, including terminal NULL byte. Expected type of
648 // |tp| is std::chrono::time_point. This function returns StringRef
649 // wrapping the buffer pointed by |out|, and this string is terminated
650 // by NULL.
format_http_date(char * out,const T & tp)651 template <typename T> StringRef format_http_date(char *out, const T &tp) {
652 auto t =
653 std::chrono::duration_cast<std::chrono::seconds>(tp.time_since_epoch());
654 auto p = http_date(out, t.count());
655 *p = '\0';
656 return StringRef{out, p};
657 }
658
659 // Return the system precision of the template parameter |Clock| as
660 // a nanosecond value of type |Rep|
clock_precision()661 template <typename Clock, typename Rep> Rep clock_precision() {
662 std::chrono::duration<Rep, std::nano> duration = typename Clock::duration(1);
663
664 return duration.count();
665 }
666
667 #ifdef HAVE_LIBEV
668 template <typename Duration = std::chrono::steady_clock::duration>
duration_from(ev_tstamp d)669 Duration duration_from(ev_tstamp d) {
670 return std::chrono::duration_cast<Duration>(std::chrono::duration<double>(d));
671 }
672
ev_tstamp_from(const Duration & d)673 template <typename Duration> ev_tstamp ev_tstamp_from(const Duration &d) {
674 return std::chrono::duration<double>(d).count();
675 }
676 #endif // HAVE_LIBEV
677
678 int make_socket_closeonexec(int fd);
679 int make_socket_nonblocking(int fd);
680 int make_socket_nodelay(int fd);
681
682 int create_nonblock_socket(int family);
683 int create_nonblock_udp_socket(int family);
684
685 int bind_any_addr_udp(int fd, int family);
686
687 bool check_socket_connected(int fd);
688
689 // Returns the error code (errno) by inspecting SO_ERROR of given
690 // |fd|. This function returns the error code if it succeeds, or -1.
691 // Returning 0 means no error.
692 int get_socket_error(int fd);
693
694 // Returns true if |host| is IPv6 numeric address (e.g., ::1)
695 bool ipv6_numeric_addr(const char *host);
696
697 // Parses |s| as unsigned integer and returns the parsed integer.
698 // Additionally, if |s| ends with 'k', 'm', 'g' and its upper case
699 // characters, multiply the integer by 1024, 1024 * 1024 and 1024 *
700 // 1024 respectively. If there is an error, returns no value.
701 std::optional<int64_t> parse_uint_with_unit(const StringRef &s);
702
703 // Parses |s| as unsigned integer and returns the parsed integer..
704 std::optional<int64_t> parse_uint(const StringRef &s);
705
706 // Parses |s| as unsigned integer and returns the parsed integer
707 // casted to double. If |s| ends with "s", the parsed value's unit is
708 // a second. If |s| ends with "ms", the unit is millisecond.
709 // Similarly, it also supports 'm' and 'h' for minutes and hours
710 // respectively. If none of them are given, the unit is second. This
711 // function returns no value if error occurs.
712 std::optional<double> parse_duration_with_unit(const StringRef &s);
713
714 // Returns string representation of time duration |t|. If t has
715 // fractional part (at least more than or equal to 1e-3), |t| is
716 // multiplied by 1000 and the unit "ms" is appended. Otherwise, |t|
717 // is left as is and "s" is appended.
718 std::string duration_str(double t);
719
720 // Returns string representation of time duration |t|. It appends
721 // unit after the formatting. The available units are s, ms and us.
722 // The unit which is equal to or less than |t| is used and 2
723 // fractional digits follow.
724 std::string format_duration(const std::chrono::microseconds &u);
725
726 // Just like above, but this takes |t| as seconds.
727 std::string format_duration(double t);
728
729 // The maximum buffer size including terminal NULL to store the result
730 // of make_hostport.
731 constexpr size_t max_hostport = NI_MAXHOST + /* [] for IPv6 */ 2 + /* : */ 1 +
732 /* port */ 5 + /* terminal NULL */ 1;
733
734 // Just like make_http_hostport(), but doesn't treat 80 and 443
735 // specially.
736 StringRef make_hostport(BlockAllocator &balloc, const StringRef &host,
737 uint16_t port);
738
739 template <typename OutputIt>
make_hostport(OutputIt first,const StringRef & host,uint16_t port)740 StringRef make_hostport(OutputIt first, const StringRef &host, uint16_t port) {
741 auto ipv6 = ipv6_numeric_addr(host.data());
742 auto serv = utos(port);
743 auto p = first;
744
745 if (ipv6) {
746 *p++ = '[';
747 }
748
749 p = std::copy(std::begin(host), std::end(host), p);
750
751 if (ipv6) {
752 *p++ = ']';
753 }
754
755 *p++ = ':';
756
757 p = std::copy(std::begin(serv), std::end(serv), p);
758
759 *p = '\0';
760
761 return StringRef{std::span{first, p}};
762 }
763
764 // Creates "host:port" string using given |host| and |port|. If
765 // |host| is numeric IPv6 address (e.g., ::1), it is enclosed by "["
766 // and "]". If |port| is 80 or 443, port part is omitted.
767 StringRef make_http_hostport(BlockAllocator &balloc, const StringRef &host,
768 uint16_t port);
769
770 template <typename OutputIt>
make_http_hostport(OutputIt first,const StringRef & host,uint16_t port)771 StringRef make_http_hostport(OutputIt first, const StringRef &host,
772 uint16_t port) {
773 if (port != 80 && port != 443) {
774 return make_hostport(first, host, port);
775 }
776
777 auto ipv6 = ipv6_numeric_addr(host.data());
778 auto p = first;
779
780 if (ipv6) {
781 *p++ = '[';
782 }
783
784 p = std::copy(std::begin(host), std::end(host), p);
785
786 if (ipv6) {
787 *p++ = ']';
788 }
789
790 *p = '\0';
791
792 return StringRef{std::span{first, p}};
793 }
794
795 // hexdump dumps |data| of length |datalen| in the format similar to
796 // hexdump(1) with -C option. This function returns 0 if it succeeds,
797 // or -1.
798 int hexdump(FILE *out, const void *data, size_t datalen);
799
800 // Copies 2 byte unsigned integer |n| in host byte order to |buf| in
801 // network byte order.
802 void put_uint16be(uint8_t *buf, uint16_t n);
803
804 // Copies 4 byte unsigned integer |n| in host byte order to |buf| in
805 // network byte order.
806 void put_uint32be(uint8_t *buf, uint32_t n);
807
808 // Retrieves 2 byte unsigned integer stored in |data| in network byte
809 // order and returns it in host byte order.
810 uint16_t get_uint16(const uint8_t *data);
811
812 // Retrieves 4 byte unsigned integer stored in |data| in network byte
813 // order and returns it in host byte order.
814 uint32_t get_uint32(const uint8_t *data);
815
816 // Retrieves 8 byte unsigned integer stored in |data| in network byte
817 // order and returns it in host byte order.
818 uint64_t get_uint64(const uint8_t *data);
819
820 // Reads mime types file (see /etc/mime.types), and stores extension
821 // -> MIME type map in |res|. This function returns 0 if it succeeds,
822 // or -1.
823 int read_mime_types(std::map<std::string, std::string> &res,
824 const char *filename);
825
826 // Fills random alpha and digit byte to the range [|first|, |last|).
827 // Returns the one beyond the |last|.
828 template <typename OutputIt, typename Generator>
random_alpha_digit(OutputIt first,OutputIt last,Generator & gen)829 OutputIt random_alpha_digit(OutputIt first, OutputIt last, Generator &gen) {
830 // If we use uint8_t instead char, gcc 6.2.0 complains by shouting
831 // char-array initialized from wide string.
832 static constexpr char s[] =
833 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
834 std::uniform_int_distribution<> dis(0, 26 * 2 + 10 - 1);
835 for (; first != last; ++first) {
836 *first = s[dis(gen)];
837 }
838 return first;
839 }
840
841 // Fills random bytes to the range [|first|, |last|).
842 template <typename OutputIt, typename Generator>
random_bytes(OutputIt first,OutputIt last,Generator & gen)843 void random_bytes(OutputIt first, OutputIt last, Generator &gen) {
844 std::uniform_int_distribution<uint8_t> dis;
845 std::generate(first, last, [&dis, &gen]() { return dis(gen); });
846 }
847
848 // Shuffles the range [|first|, |last|] by calling swap function |fun|
849 // for each pair. |fun| takes 2 RandomIt iterators. If |fun| is
850 // noop, no modification is made.
851 template <typename RandomIt, typename Generator, typename SwapFun>
shuffle(RandomIt first,RandomIt last,Generator && gen,SwapFun fun)852 void shuffle(RandomIt first, RandomIt last, Generator &&gen, SwapFun fun) {
853 auto len = std::distance(first, last);
854 if (len < 2) {
855 return;
856 }
857
858 using dist_type = std::uniform_int_distribution<size_t>;
859 using param_type = dist_type::param_type;
860
861 dist_type d;
862
863 for (decltype(len) i = 0; i < len - 1; ++i) {
864 fun(first + i, first + d(gen, param_type(i, len - 1)));
865 }
866 }
867
868 template <typename OutputIterator, typename CharT, size_t N>
copy_lit(OutputIterator it,CharT (& s)[N])869 OutputIterator copy_lit(OutputIterator it, CharT (&s)[N]) {
870 return std::copy_n(s, N - 1, it);
871 }
872
873 // Returns x**y
874 double int_pow(double x, size_t y);
875
876 uint32_t hash32(const StringRef &s);
877
878 // Computes SHA-256 of |s|, and stores it in |buf|. This function
879 // returns 0 if it succeeds, or -1.
880 int sha256(uint8_t *buf, const StringRef &s);
881
882 // Computes SHA-1 of |s|, and stores it in |buf|. This function
883 // returns 0 if it succeeds, or -1.
884 int sha1(uint8_t *buf, const StringRef &s);
885
886 // Returns host from |hostport|. If host cannot be found in
887 // |hostport|, returns empty string. The returned string might not be
888 // NULL-terminated.
889 StringRef extract_host(const StringRef &hostport);
890
891 // split_hostport splits host and port in |hostport|. Unlike
892 // extract_host, square brackets enclosing host name is stripped. If
893 // port is not available, it returns empty string in the second
894 // string. The returned string might not be NULL-terminated. On any
895 // error, it returns a pair which has empty strings.
896 std::pair<StringRef, StringRef> split_hostport(const StringRef &hostport);
897
898 // Returns new std::mt19937 object.
899 std::mt19937 make_mt19937();
900
901 // daemonize calls daemon(3). If __APPLE__ is defined, it implements
902 // daemon() using fork().
903 int daemonize(int nochdir, int noclose);
904
905 // Returns |s| from which trailing white spaces (SPC or HTAB) are
906 // removed. If any white spaces are removed, new string is allocated
907 // by |balloc| and returned. Otherwise, the copy of |s| is returned
908 // without allocation.
909 StringRef rstrip(BlockAllocator &balloc, const StringRef &s);
910
911 #ifdef ENABLE_HTTP3
912 int msghdr_get_local_addr(Address &dest, msghdr *msg, int family);
913
914 uint8_t msghdr_get_ecn(msghdr *msg, int family);
915
916 // msghdr_get_udp_gro returns UDP_GRO value from |msg|. If UDP_GRO is
917 // not found, or UDP_GRO is not supported, this function returns 0.
918 size_t msghdr_get_udp_gro(msghdr *msg);
919 #endif // ENABLE_HTTP3
920
921 } // namespace util
922
923 } // namespace nghttp2
924
925 #endif // UTIL_H
926