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