• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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