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