xref: /third_party/nghttp2/src/util.h (revision 2c593315)
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
60namespace nghttp2 {
61
62constexpr auto NGHTTP2_H2_ALPN = StringRef::from_lit("\x2h2");
63constexpr 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.
68constexpr auto NGHTTP2_H2_16_ALPN = StringRef::from_lit("\x5h2-16");
69constexpr auto NGHTTP2_H2_16 = StringRef::from_lit("h2-16");
70
71constexpr auto NGHTTP2_H2_14_ALPN = StringRef::from_lit("\x5h2-14");
72constexpr auto NGHTTP2_H2_14 = StringRef::from_lit("h2-14");
73
74constexpr auto NGHTTP2_H1_1_ALPN = StringRef::from_lit("\x8http/1.1");
75constexpr auto NGHTTP2_H1_1 = StringRef::from_lit("http/1.1");
76
77constexpr size_t NGHTTP2_MAX_UINT64_DIGITS = str_size("18446744073709551615");
78
79namespace util {
80
81extern const char UPPER_XDIGITS[];
82
83inline bool is_alpha(const char c) {
84  return ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z');
85}
86
87inline bool is_digit(const char c) { return '0' <= c && c <= '9'; }
88
89inline 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.
94bool is_hex_string(const StringRef &s);
95
96bool in_rfc3986_unreserved_chars(const char c);
97
98bool in_rfc3986_sub_delims(const char c);
99
100// Returns true if |c| is in token (HTTP-p1, Section 3.2.6)
101bool in_token(char c);
102
103bool 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.
107uint32_t hex_to_uint(char c);
108
109std::string percent_encode(const unsigned char *target, size_t len);
110
111std::string percent_encode(const std::string &target);
112
113template <typename InputIt>
114std::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
137StringRef percent_decode(BlockAllocator &balloc, const StringRef &src);
138
139// Percent encode |target| if character is not in token or '%'.
140StringRef percent_encode_token(BlockAllocator &balloc, const StringRef &target);
141
142template <typename OutputIt>
143OutputIt 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.
163size_t percent_encode_tokenlen(const StringRef &target);
164
165// Returns quotedString version of |target|.  Currently, this function
166// just replace '"' with '\"'.
167StringRef quote_string(BlockAllocator &balloc, const StringRef &target);
168
169template <typename OutputIt>
170OutputIt 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.
186size_t quote_stringlen(const StringRef &target);
187
188std::string format_hex(const unsigned char *s, size_t len);
189
190template <size_t N> std::string format_hex(const unsigned char (&s)[N]) {
191  return format_hex(s, N);
192}
193
194template <size_t N> std::string format_hex(const std::array<uint8_t, N> &s) {
195  return format_hex(s.data(), s.size());
196}
197
198StringRef format_hex(BlockAllocator &balloc, const StringRef &s);
199
200static constexpr char LOWER_XDIGITS[] = "0123456789abcdef";
201
202template <typename OutputIt>
203OutputIt 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.
216StringRef decode_hex(BlockAllocator &balloc, const StringRef &s);
217
218template <typename OutputIt>
219OutputIt 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).
229std::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.
233char *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)
237std::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.
241char *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)
245std::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.
249char *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.
254char *iso8601_basic_date(char *res, int64_t ms);
255
256time_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().
261time_t parse_openssl_asn1_time_print(const StringRef &s);
262
263char upcase(char c);
264
265inline 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
289template <typename InputIterator1, typename InputIterator2>
290bool 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
298template <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
302struct CaseCmp {
303  bool operator()(char lhs, char rhs) const {
304    return lowcase(lhs) == lowcase(rhs);
305  }
306};
307
308template <typename InputIterator1, typename InputIterator2>
309bool 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
317template <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
321template <typename T, typename CharT, size_t N>
322bool istarts_with_l(const T &a, const CharT (&b)[N]) {
323  return istarts_with(a.begin(), a.end(), b, b + N - 1);
324}
325
326template <typename InputIterator1, typename InputIterator2>
327bool 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
335template <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
339template <typename T, typename CharT, size_t N>
340bool ends_with_l(const T &a, const CharT (&b)[N]) {
341  return ends_with(a.begin(), a.end(), b, b + N - 1);
342}
343
344template <typename InputIterator1, typename InputIterator2>
345bool 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
353template <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
357template <typename T, typename CharT, size_t N>
358bool iends_with_l(const T &a, const CharT (&b)[N]) {
359  return iends_with(a.begin(), a.end(), b, b + N - 1);
360}
361
362template <typename InputIt1, typename InputIt2>
363bool 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
371template <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
375template <typename CharT, typename InputIt, size_t N>
376bool strieq_l(const CharT (&a)[N], InputIt b, size_t blen) {
377  return strieq(a, a + (N - 1), b, b + blen);
378}
379
380template <typename CharT, size_t N, typename T>
381bool strieq_l(const CharT (&a)[N], const T &b) {
382  return strieq(a, a + (N - 1), b.begin(), b.end());
383}
384
385template <typename InputIt1, typename InputIt2>
386bool 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
393template <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
397template <typename CharT, typename InputIt, size_t N>
398bool streq_l(const CharT (&a)[N], InputIt b, size_t blen) {
399  return streq(a, a + (N - 1), b, b + blen);
400}
401
402template <typename CharT, size_t N, typename T>
403bool 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.
409template <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
414template <typename InputIt> void inp_strlower(InputIt first, InputIt last) {
415  std::transform(first, last, first, lowcase);
416}
417
418// Lowercase |s| in place.
419inline 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.
424std::string dtos(double n);
425
426template <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
442template <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
458template <typename T>
459StringRef 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
467template <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.
486template <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
505template <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
523void to_token68(std::string &base64str);
524
525StringRef to_base64(BlockAllocator &balloc, const StringRef &token68str);
526
527void show_candidates(const char *unkopt, const option *options);
528
529bool has_uri_field(const http_parser_url &u, http_parser_url_fields field);
530
531bool fieldeq(const char *uri1, const http_parser_url &u1, const char *uri2,
532             const http_parser_url &u2, http_parser_url_fields field);
533
534bool fieldeq(const char *uri, const http_parser_url &u,
535             http_parser_url_fields field, const char *t);
536
537bool fieldeq(const char *uri, const http_parser_url &u,
538             http_parser_url_fields field, const StringRef &t);
539
540StringRef get_uri_field(const char *uri, const http_parser_url &u,
541                        http_parser_url_fields field);
542
543uint16_t get_default_port(const char *uri, const http_parser_url &u);
544
545bool porteq(const char *uri1, const http_parser_url &u1, const char *uri2,
546            const http_parser_url &u2);
547
548void write_uri_field(std::ostream &o, const char *uri, const http_parser_url &u,
549                     http_parser_url_fields field);
550
551bool numeric_host(const char *hostname);
552
553bool numeric_host(const char *hostname, int family);
554
555// Returns numeric address string of |addr|.  If getnameinfo() is
556// failed, "unknown" is returned.
557std::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 ([]).
563std::string to_numeric_addr(const Address *addr);
564
565std::string to_numeric_addr(const struct sockaddr *sa, socklen_t salen);
566
567// Sets |port| to |addr|.
568void 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 ".".
572std::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.
580char *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.
586bool check_path(const std::string &path);
587
588// Returns the |tv| value as 64 bit integer using a microsecond as an
589// unit.
590int64_t to_time64(const timeval &tv);
591
592// Returns true if ALPN ID |proto| is supported HTTP/2 protocol
593// identifier.
594bool 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.
599bool 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.
605bool 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.
611std::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.
616std::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.
622std::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.
627std::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.
635template <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
646template <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.
658template <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.
672template <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.
686template <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|
696template <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
703template <typename Duration = std::chrono::steady_clock::duration>
704Duration duration_from(ev_tstamp d) {
705  return std::chrono::duration_cast<Duration>(std::chrono::duration<double>(d));
706}
707
708template <typename Duration> ev_tstamp ev_tstamp_from(const Duration &d) {
709  return std::chrono::duration<double>(d).count();
710}
711#endif // HAVE_LIBEV
712
713int make_socket_closeonexec(int fd);
714int make_socket_nonblocking(int fd);
715int make_socket_nodelay(int fd);
716
717int create_nonblock_socket(int family);
718int create_nonblock_udp_socket(int family);
719
720int bind_any_addr_udp(int fd, int family);
721
722bool 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.
727int get_socket_error(int fd);
728
729// Returns true if |host| is IPv6 numeric address (e.g., ::1)
730bool 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.
737int64_t parse_uint_with_unit(const char *s);
738// The following overload does not require |s| is NULL terminated.
739int64_t parse_uint_with_unit(const uint8_t *s, size_t len);
740int64_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.
744int64_t parse_uint(const char *s);
745// The following overload does not require |s| is NULL terminated.
746int64_t parse_uint(const uint8_t *s, size_t len);
747int64_t parse_uint(const std::string &s);
748int64_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.
757double parse_duration_with_unit(const char *s);
758// The following overload does not require |s| is NULL terminated.
759double parse_duration_with_unit(const uint8_t *s, size_t len);
760double 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.
766std::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.
772std::string format_duration(const std::chrono::microseconds &u);
773
774// Just like above, but this takes |t| as seconds.
775std::string format_duration(double t);
776
777// The maximum buffer size including terminal NULL to store the result
778// of make_hostport.
779constexpr 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.
784StringRef make_hostport(BlockAllocator &balloc, const StringRef &host,
785                        uint16_t port);
786
787template <typename OutputIt>
788StringRef 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.
815StringRef make_http_hostport(BlockAllocator &balloc, const StringRef &host,
816                             uint16_t port);
817
818template <typename OutputIt>
819StringRef 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`.
844void 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.
848void 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.
852void 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.
856uint16_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.
860uint32_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.
864uint64_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.
869int 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|.
874template <typename OutputIt, typename Generator>
875OutputIt 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|).
888template <typename OutputIt, typename Generator>
889void 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.
897template <typename RandomIt, typename Generator, typename SwapFun>
898void 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
914template <typename OutputIterator, typename CharT, size_t N>
915OutputIterator copy_lit(OutputIterator it, CharT (&s)[N]) {
916  return std::copy_n(s, N - 1, it);
917}
918
919// Returns x**y
920double int_pow(double x, size_t y);
921
922uint32_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.
926int 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.
930int 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.
935StringRef 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.
942std::pair<StringRef, StringRef> split_hostport(const StringRef &hostport);
943
944// Returns new std::mt19937 object.
945std::mt19937 make_mt19937();
946
947// daemonize calls daemon(3).  If __APPLE__ is defined, it implements
948// daemon() using fork().
949int 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.
955StringRef rstrip(BlockAllocator &balloc, const StringRef &s);
956
957#ifdef ENABLE_HTTP3
958int msghdr_get_local_addr(Address &dest, msghdr *msg, int family);
959
960uint8_t 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.
964size_t msghdr_get_udp_gro(msghdr *msg);
965#endif // ENABLE_HTTP3
966
967} // namespace util
968
969} // namespace nghttp2
970
971#endif // UTIL_H
972