Imported Upstream version 1.46.0
[platform/upstream/nghttp2.git] / src / util.cc
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 #include "util.h"
26
27 #ifdef HAVE_TIME_H
28 #  include <time.h>
29 #endif // HAVE_TIME_H
30 #include <sys/types.h>
31 #ifdef HAVE_SYS_SOCKET_H
32 #  include <sys/socket.h>
33 #endif // HAVE_SYS_SOCKET_H
34 #ifdef HAVE_NETDB_H
35 #  include <netdb.h>
36 #endif // HAVE_NETDB_H
37 #include <sys/stat.h>
38 #ifdef HAVE_FCNTL_H
39 #  include <fcntl.h>
40 #endif // HAVE_FCNTL_H
41 #ifdef HAVE_NETINET_IN_H
42 #  include <netinet/in.h>
43 #endif // HAVE_NETINET_IN_H
44 #ifdef _WIN32
45 #  include <ws2tcpip.h>
46 #  include <boost/date_time/posix_time/posix_time.hpp>
47 #else // !_WIN32
48 #  include <netinet/tcp.h>
49 #endif // !_WIN32
50 #ifdef HAVE_ARPA_INET_H
51 #  include <arpa/inet.h>
52 #endif // HAVE_ARPA_INET_H
53
54 #include <cmath>
55 #include <cerrno>
56 #include <cassert>
57 #include <cstdio>
58 #include <cstring>
59 #include <iostream>
60 #include <fstream>
61
62 #include <openssl/evp.h>
63
64 #include <nghttp2/nghttp2.h>
65
66 #include "ssl_compat.h"
67 #include "timegm.h"
68
69 namespace nghttp2 {
70
71 namespace util {
72
73 #ifndef _WIN32
74 namespace {
75 int nghttp2_inet_pton(int af, const char *src, void *dst) {
76   return inet_pton(af, src, dst);
77 }
78 } // namespace
79 #else // _WIN32
80 namespace {
81 // inet_pton-wrapper for Windows
82 int nghttp2_inet_pton(int af, const char *src, void *dst) {
83 #  if _WIN32_WINNT >= 0x0600
84   return InetPtonA(af, src, dst);
85 #  else
86   // the function takes a 'char*', so we need to make a copy
87   char addr[INET6_ADDRSTRLEN + 1];
88   strncpy(addr, src, sizeof(addr));
89   addr[sizeof(addr) - 1] = 0;
90
91   int size = sizeof(struct in6_addr);
92
93   if (WSAStringToAddress(addr, af, NULL, (LPSOCKADDR)dst, &size) == 0)
94     return 1;
95   return 0;
96 #  endif
97 }
98 } // namespace
99 #endif // _WIN32
100
101 const char UPPER_XDIGITS[] = "0123456789ABCDEF";
102
103 bool in_rfc3986_unreserved_chars(const char c) {
104   static constexpr char unreserved[] = {'-', '.', '_', '~'};
105   return is_alpha(c) || is_digit(c) ||
106          std::find(std::begin(unreserved), std::end(unreserved), c) !=
107              std::end(unreserved);
108 }
109
110 bool in_rfc3986_sub_delims(const char c) {
111   static constexpr char sub_delims[] = {'!', '$', '&', '\'', '(', ')',
112                                         '*', '+', ',', ';',  '='};
113   return std::find(std::begin(sub_delims), std::end(sub_delims), c) !=
114          std::end(sub_delims);
115 }
116
117 std::string percent_encode(const unsigned char *target, size_t len) {
118   std::string dest;
119   for (size_t i = 0; i < len; ++i) {
120     unsigned char c = target[i];
121
122     if (in_rfc3986_unreserved_chars(c)) {
123       dest += c;
124     } else {
125       dest += '%';
126       dest += UPPER_XDIGITS[c >> 4];
127       dest += UPPER_XDIGITS[(c & 0x0f)];
128     }
129   }
130   return dest;
131 }
132
133 std::string percent_encode(const std::string &target) {
134   return percent_encode(reinterpret_cast<const unsigned char *>(target.c_str()),
135                         target.size());
136 }
137
138 std::string percent_encode_path(const std::string &s) {
139   std::string dest;
140   for (auto c : s) {
141     if (in_rfc3986_unreserved_chars(c) || in_rfc3986_sub_delims(c) ||
142         c == '/') {
143       dest += c;
144       continue;
145     }
146
147     dest += '%';
148     dest += UPPER_XDIGITS[(c >> 4) & 0x0f];
149     dest += UPPER_XDIGITS[(c & 0x0f)];
150   }
151   return dest;
152 }
153
154 bool in_token(char c) {
155   static constexpr char extra[] = {'!', '#', '$', '%', '&', '\'', '*', '+',
156                                    '-', '.', '^', '_', '`', '|',  '~'};
157   return is_alpha(c) || is_digit(c) ||
158          std::find(std::begin(extra), std::end(extra), c) != std::end(extra);
159 }
160
161 bool in_attr_char(char c) {
162   static constexpr char bad[] = {'*', '\'', '%'};
163   return util::in_token(c) &&
164          std::find(std::begin(bad), std::end(bad), c) == std::end(bad);
165 }
166
167 StringRef percent_encode_token(BlockAllocator &balloc,
168                                const StringRef &target) {
169   auto iov = make_byte_ref(balloc, target.size() * 3 + 1);
170   auto p = percent_encode_token(iov.base, target);
171
172   *p = '\0';
173
174   return StringRef{iov.base, p};
175 }
176
177 size_t percent_encode_tokenlen(const StringRef &target) {
178   size_t n = 0;
179
180   for (auto first = std::begin(target); first != std::end(target); ++first) {
181     uint8_t c = *first;
182
183     if (c != '%' && in_token(c)) {
184       ++n;
185       continue;
186     }
187
188     // percent-encoded character '%ff'
189     n += 3;
190   }
191
192   return n;
193 }
194
195 uint32_t hex_to_uint(char c) {
196   if (c <= '9') {
197     return c - '0';
198   }
199   if (c <= 'Z') {
200     return c - 'A' + 10;
201   }
202   if (c <= 'z') {
203     return c - 'a' + 10;
204   }
205   return 256;
206 }
207
208 StringRef quote_string(BlockAllocator &balloc, const StringRef &target) {
209   auto cnt = std::count(std::begin(target), std::end(target), '"');
210
211   if (cnt == 0) {
212     return make_string_ref(balloc, target);
213   }
214
215   auto iov = make_byte_ref(balloc, target.size() + cnt + 1);
216   auto p = quote_string(iov.base, target);
217
218   *p = '\0';
219
220   return StringRef{iov.base, p};
221 }
222
223 size_t quote_stringlen(const StringRef &target) {
224   size_t n = 0;
225
226   for (auto c : target) {
227     if (c == '"') {
228       n += 2;
229     } else {
230       ++n;
231     }
232   }
233
234   return n;
235 }
236
237 namespace {
238 template <typename Iterator>
239 Iterator cpydig(Iterator d, uint32_t n, size_t len) {
240   auto p = d + len - 1;
241
242   do {
243     *p-- = (n % 10) + '0';
244     n /= 10;
245   } while (p >= d);
246
247   return d + len;
248 }
249 } // namespace
250
251 namespace {
252 constexpr const char *MONTH[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
253                                  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
254 constexpr const char *DAY_OF_WEEK[] = {"Sun", "Mon", "Tue", "Wed",
255                                        "Thu", "Fri", "Sat"};
256 } // namespace
257
258 std::string http_date(time_t t) {
259   /* Sat, 27 Sep 2014 06:31:15 GMT */
260   std::string res(29, 0);
261   http_date(&res[0], t);
262   return res;
263 }
264
265 char *http_date(char *res, time_t t) {
266   struct tm tms;
267
268   if (gmtime_r(&t, &tms) == nullptr) {
269     return res;
270   }
271
272   auto p = res;
273
274   auto s = DAY_OF_WEEK[tms.tm_wday];
275   p = std::copy_n(s, 3, p);
276   *p++ = ',';
277   *p++ = ' ';
278   p = cpydig(p, tms.tm_mday, 2);
279   *p++ = ' ';
280   s = MONTH[tms.tm_mon];
281   p = std::copy_n(s, 3, p);
282   *p++ = ' ';
283   p = cpydig(p, tms.tm_year + 1900, 4);
284   *p++ = ' ';
285   p = cpydig(p, tms.tm_hour, 2);
286   *p++ = ':';
287   p = cpydig(p, tms.tm_min, 2);
288   *p++ = ':';
289   p = cpydig(p, tms.tm_sec, 2);
290   s = " GMT";
291   p = std::copy_n(s, 4, p);
292
293   return p;
294 }
295
296 std::string common_log_date(time_t t) {
297   // 03/Jul/2014:00:19:38 +0900
298   std::string res(26, 0);
299   common_log_date(&res[0], t);
300   return res;
301 }
302
303 char *common_log_date(char *res, time_t t) {
304   struct tm tms;
305
306   if (localtime_r(&t, &tms) == nullptr) {
307     return res;
308   }
309
310   auto p = res;
311
312   p = cpydig(p, tms.tm_mday, 2);
313   *p++ = '/';
314   auto s = MONTH[tms.tm_mon];
315   p = std::copy_n(s, 3, p);
316   *p++ = '/';
317   p = cpydig(p, tms.tm_year + 1900, 4);
318   *p++ = ':';
319   p = cpydig(p, tms.tm_hour, 2);
320   *p++ = ':';
321   p = cpydig(p, tms.tm_min, 2);
322   *p++ = ':';
323   p = cpydig(p, tms.tm_sec, 2);
324   *p++ = ' ';
325
326 #ifdef HAVE_STRUCT_TM_TM_GMTOFF
327   auto gmtoff = tms.tm_gmtoff;
328 #else  // !HAVE_STRUCT_TM_TM_GMTOFF
329   auto gmtoff = nghttp2_timegm(&tms) - t;
330 #endif // !HAVE_STRUCT_TM_TM_GMTOFF
331   if (gmtoff >= 0) {
332     *p++ = '+';
333   } else {
334     *p++ = '-';
335     gmtoff = -gmtoff;
336   }
337
338   p = cpydig(p, gmtoff / 3600, 2);
339   p = cpydig(p, (gmtoff % 3600) / 60, 2);
340
341   return p;
342 }
343
344 std::string iso8601_date(int64_t ms) {
345   // 2014-11-15T12:58:24.741Z
346   // 2014-11-15T12:58:24.741+09:00
347   std::string res(29, 0);
348   auto p = iso8601_date(&res[0], ms);
349   res.resize(p - &res[0]);
350   return res;
351 }
352
353 char *iso8601_date(char *res, int64_t ms) {
354   time_t sec = ms / 1000;
355
356   tm tms;
357   if (localtime_r(&sec, &tms) == nullptr) {
358     return res;
359   }
360
361   auto p = res;
362
363   p = cpydig(p, tms.tm_year + 1900, 4);
364   *p++ = '-';
365   p = cpydig(p, tms.tm_mon + 1, 2);
366   *p++ = '-';
367   p = cpydig(p, tms.tm_mday, 2);
368   *p++ = 'T';
369   p = cpydig(p, tms.tm_hour, 2);
370   *p++ = ':';
371   p = cpydig(p, tms.tm_min, 2);
372   *p++ = ':';
373   p = cpydig(p, tms.tm_sec, 2);
374   *p++ = '.';
375   p = cpydig(p, ms % 1000, 3);
376
377 #ifdef HAVE_STRUCT_TM_TM_GMTOFF
378   auto gmtoff = tms.tm_gmtoff;
379 #else  // !HAVE_STRUCT_TM_TM_GMTOFF
380   auto gmtoff = nghttp2_timegm(&tms) - sec;
381 #endif // !HAVE_STRUCT_TM_TM_GMTOFF
382   if (gmtoff == 0) {
383     *p++ = 'Z';
384   } else {
385     if (gmtoff > 0) {
386       *p++ = '+';
387     } else {
388       *p++ = '-';
389       gmtoff = -gmtoff;
390     }
391     p = cpydig(p, gmtoff / 3600, 2);
392     *p++ = ':';
393     p = cpydig(p, (gmtoff % 3600) / 60, 2);
394   }
395
396   return p;
397 }
398
399 char *iso8601_basic_date(char *res, int64_t ms) {
400   time_t sec = ms / 1000;
401
402   tm tms;
403   if (localtime_r(&sec, &tms) == nullptr) {
404     return res;
405   }
406
407   auto p = res;
408
409   p = cpydig(p, tms.tm_year + 1900, 4);
410   p = cpydig(p, tms.tm_mon + 1, 2);
411   p = cpydig(p, tms.tm_mday, 2);
412   *p++ = 'T';
413   p = cpydig(p, tms.tm_hour, 2);
414   p = cpydig(p, tms.tm_min, 2);
415   p = cpydig(p, tms.tm_sec, 2);
416   *p++ = '.';
417   p = cpydig(p, ms % 1000, 3);
418
419 #ifdef HAVE_STRUCT_TM_TM_GMTOFF
420   auto gmtoff = tms.tm_gmtoff;
421 #else  // !HAVE_STRUCT_TM_TM_GMTOFF
422   auto gmtoff = nghttp2_timegm(&tms) - sec;
423 #endif // !HAVE_STRUCT_TM_TM_GMTOFF
424   if (gmtoff == 0) {
425     *p++ = 'Z';
426   } else {
427     if (gmtoff > 0) {
428       *p++ = '+';
429     } else {
430       *p++ = '-';
431       gmtoff = -gmtoff;
432     }
433     p = cpydig(p, gmtoff / 3600, 2);
434     p = cpydig(p, (gmtoff % 3600) / 60, 2);
435   }
436
437   return p;
438 }
439
440 #ifdef _WIN32
441 namespace bt = boost::posix_time;
442 // one-time definition of the locale that is used to parse UTC strings
443 // (note that the time_input_facet is ref-counted and deleted automatically)
444 static const std::locale
445     ptime_locale(std::locale::classic(),
446                  new bt::time_input_facet("%a, %d %b %Y %H:%M:%S GMT"));
447 #endif //_WIN32
448
449 time_t parse_http_date(const StringRef &s) {
450 #ifdef _WIN32
451   // there is no strptime - use boost
452   std::stringstream sstr(s.str());
453   sstr.imbue(ptime_locale);
454   bt::ptime ltime;
455   sstr >> ltime;
456   if (!sstr)
457     return 0;
458
459   return boost::posix_time::to_time_t(ltime);
460 #else  // !_WIN32
461   tm tm{};
462   char *r = strptime(s.c_str(), "%a, %d %b %Y %H:%M:%S GMT", &tm);
463   if (r == 0) {
464     return 0;
465   }
466   return nghttp2_timegm_without_yday(&tm);
467 #endif // !_WIN32
468 }
469
470 time_t parse_openssl_asn1_time_print(const StringRef &s) {
471   tm tm{};
472   auto r = strptime(s.c_str(), "%b %d %H:%M:%S %Y GMT", &tm);
473   if (r == nullptr) {
474     return 0;
475   }
476   return nghttp2_timegm_without_yday(&tm);
477 }
478
479 char upcase(char c) {
480   if ('a' <= c && c <= 'z') {
481     return c - 'a' + 'A';
482   } else {
483     return c;
484   }
485 }
486
487 std::string format_hex(const unsigned char *s, size_t len) {
488   std::string res;
489   res.resize(len * 2);
490
491   for (size_t i = 0; i < len; ++i) {
492     unsigned char c = s[i];
493
494     res[i * 2] = LOWER_XDIGITS[c >> 4];
495     res[i * 2 + 1] = LOWER_XDIGITS[c & 0x0f];
496   }
497   return res;
498 }
499
500 StringRef format_hex(BlockAllocator &balloc, const StringRef &s) {
501   auto iov = make_byte_ref(balloc, s.size() * 2 + 1);
502   auto p = iov.base;
503
504   for (auto cc : s) {
505     uint8_t c = cc;
506     *p++ = LOWER_XDIGITS[c >> 4];
507     *p++ = LOWER_XDIGITS[c & 0xf];
508   }
509
510   *p = '\0';
511
512   return StringRef{iov.base, p};
513 }
514
515 void to_token68(std::string &base64str) {
516   std::transform(std::begin(base64str), std::end(base64str),
517                  std::begin(base64str), [](char c) {
518                    switch (c) {
519                    case '+':
520                      return '-';
521                    case '/':
522                      return '_';
523                    default:
524                      return c;
525                    }
526                  });
527   base64str.erase(std::find(std::begin(base64str), std::end(base64str), '='),
528                   std::end(base64str));
529 }
530
531 StringRef to_base64(BlockAllocator &balloc, const StringRef &token68str) {
532   // At most 3 padding '='
533   auto len = token68str.size() + 3;
534   auto iov = make_byte_ref(balloc, len + 1);
535   auto p = iov.base;
536
537   p = std::transform(std::begin(token68str), std::end(token68str), p,
538                      [](char c) {
539                        switch (c) {
540                        case '-':
541                          return '+';
542                        case '_':
543                          return '/';
544                        default:
545                          return c;
546                        }
547                      });
548
549   auto rem = token68str.size() & 0x3;
550   if (rem) {
551     p = std::fill_n(p, 4 - rem, '=');
552   }
553
554   *p = '\0';
555
556   return StringRef{iov.base, p};
557 }
558
559 namespace {
560 // Calculates Damerau–Levenshtein distance between c-string a and b
561 // with given costs.  swapcost, subcost, addcost and delcost are cost
562 // to swap 2 adjacent characters, substitute characters, add character
563 // and delete character respectively.
564 int levenshtein(const char *a, int alen, const char *b, int blen, int swapcost,
565                 int subcost, int addcost, int delcost) {
566   auto dp = std::vector<std::vector<int>>(3, std::vector<int>(blen + 1));
567   for (int i = 0; i <= blen; ++i) {
568     dp[1][i] = i;
569   }
570   for (int i = 1; i <= alen; ++i) {
571     dp[0][0] = i;
572     for (int j = 1; j <= blen; ++j) {
573       dp[0][j] = dp[1][j - 1] + (a[i - 1] == b[j - 1] ? 0 : subcost);
574       if (i >= 2 && j >= 2 && a[i - 1] != b[j - 1] && a[i - 2] == b[j - 1] &&
575           a[i - 1] == b[j - 2]) {
576         dp[0][j] = std::min(dp[0][j], dp[2][j - 2] + swapcost);
577       }
578       dp[0][j] = std::min(dp[0][j],
579                           std::min(dp[1][j] + delcost, dp[0][j - 1] + addcost));
580     }
581     std::rotate(std::begin(dp), std::begin(dp) + 2, std::end(dp));
582   }
583   return dp[1][blen];
584 }
585 } // namespace
586
587 void show_candidates(const char *unkopt, const option *options) {
588   for (; *unkopt == '-'; ++unkopt)
589     ;
590   if (*unkopt == '\0') {
591     return;
592   }
593   auto unkoptend = unkopt;
594   for (; *unkoptend && *unkoptend != '='; ++unkoptend)
595     ;
596   auto unkoptlen = unkoptend - unkopt;
597   if (unkoptlen == 0) {
598     return;
599   }
600   int prefix_match = 0;
601   auto cands = std::vector<std::pair<int, const char *>>();
602   for (size_t i = 0; options[i].name != nullptr; ++i) {
603     auto optnamelen = strlen(options[i].name);
604     // Use cost 0 for prefix match
605     if (istarts_with(options[i].name, options[i].name + optnamelen, unkopt,
606                      unkopt + unkoptlen)) {
607       if (optnamelen == static_cast<size_t>(unkoptlen)) {
608         // Exact match, then we don't show any condidates.
609         return;
610       }
611       ++prefix_match;
612       cands.emplace_back(0, options[i].name);
613       continue;
614     }
615     // Use cost 0 for suffix match, but match at least 3 characters
616     if (unkoptlen >= 3 &&
617         iends_with(options[i].name, options[i].name + optnamelen, unkopt,
618                    unkopt + unkoptlen)) {
619       cands.emplace_back(0, options[i].name);
620       continue;
621     }
622     // cost values are borrowed from git, help.c.
623     int sim =
624         levenshtein(unkopt, unkoptlen, options[i].name, optnamelen, 0, 2, 1, 3);
625     cands.emplace_back(sim, options[i].name);
626   }
627   if (prefix_match == 1 || cands.empty()) {
628     return;
629   }
630   std::sort(std::begin(cands), std::end(cands));
631   int threshold = cands[0].first;
632   // threshold value is a magic value.
633   if (threshold > 6) {
634     return;
635   }
636   std::cerr << "\nDid you mean:\n";
637   for (auto &item : cands) {
638     if (item.first > threshold) {
639       break;
640     }
641     std::cerr << "\t--" << item.second << "\n";
642   }
643 }
644
645 bool has_uri_field(const http_parser_url &u, http_parser_url_fields field) {
646   return u.field_set & (1 << field);
647 }
648
649 bool fieldeq(const char *uri1, const http_parser_url &u1, const char *uri2,
650              const http_parser_url &u2, http_parser_url_fields field) {
651   if (!has_uri_field(u1, field)) {
652     if (!has_uri_field(u2, field)) {
653       return true;
654     } else {
655       return false;
656     }
657   } else if (!has_uri_field(u2, field)) {
658     return false;
659   }
660   if (u1.field_data[field].len != u2.field_data[field].len) {
661     return false;
662   }
663   return memcmp(uri1 + u1.field_data[field].off,
664                 uri2 + u2.field_data[field].off, u1.field_data[field].len) == 0;
665 }
666
667 bool fieldeq(const char *uri, const http_parser_url &u,
668              http_parser_url_fields field, const char *t) {
669   return fieldeq(uri, u, field, StringRef{t});
670 }
671
672 bool fieldeq(const char *uri, const http_parser_url &u,
673              http_parser_url_fields field, const StringRef &t) {
674   if (!has_uri_field(u, field)) {
675     return t.empty();
676   }
677   auto &f = u.field_data[field];
678   return StringRef{uri + f.off, f.len} == t;
679 }
680
681 StringRef get_uri_field(const char *uri, const http_parser_url &u,
682                         http_parser_url_fields field) {
683   if (!util::has_uri_field(u, field)) {
684     return StringRef{};
685   }
686
687   return StringRef{uri + u.field_data[field].off, u.field_data[field].len};
688 }
689
690 uint16_t get_default_port(const char *uri, const http_parser_url &u) {
691   if (util::fieldeq(uri, u, UF_SCHEMA, "https")) {
692     return 443;
693   } else if (util::fieldeq(uri, u, UF_SCHEMA, "http")) {
694     return 80;
695   } else {
696     return 443;
697   }
698 }
699
700 bool porteq(const char *uri1, const http_parser_url &u1, const char *uri2,
701             const http_parser_url &u2) {
702   uint16_t port1, port2;
703   port1 =
704       util::has_uri_field(u1, UF_PORT) ? u1.port : get_default_port(uri1, u1);
705   port2 =
706       util::has_uri_field(u2, UF_PORT) ? u2.port : get_default_port(uri2, u2);
707   return port1 == port2;
708 }
709
710 void write_uri_field(std::ostream &o, const char *uri, const http_parser_url &u,
711                      http_parser_url_fields field) {
712   if (util::has_uri_field(u, field)) {
713     o.write(uri + u.field_data[field].off, u.field_data[field].len);
714   }
715 }
716
717 bool numeric_host(const char *hostname) {
718   return numeric_host(hostname, AF_INET) || numeric_host(hostname, AF_INET6);
719 }
720
721 bool numeric_host(const char *hostname, int family) {
722   int rv;
723   std::array<uint8_t, sizeof(struct in6_addr)> dst;
724
725   rv = nghttp2_inet_pton(family, hostname, dst.data());
726
727   return rv == 1;
728 }
729
730 std::string numeric_name(const struct sockaddr *sa, socklen_t salen) {
731   std::array<char, NI_MAXHOST> host;
732   auto rv = getnameinfo(sa, salen, host.data(), host.size(), nullptr, 0,
733                         NI_NUMERICHOST);
734   if (rv != 0) {
735     return "unknown";
736   }
737   return host.data();
738 }
739
740 std::string to_numeric_addr(const Address *addr) {
741   return to_numeric_addr(&addr->su.sa, addr->len);
742 }
743
744 std::string to_numeric_addr(const struct sockaddr *sa, socklen_t salen) {
745   auto family = sa->sa_family;
746 #ifndef _WIN32
747   if (family == AF_UNIX) {
748     return reinterpret_cast<const sockaddr_un *>(sa)->sun_path;
749   }
750 #endif // !_WIN32
751
752   std::array<char, NI_MAXHOST> host;
753   std::array<char, NI_MAXSERV> serv;
754   auto rv = getnameinfo(sa, salen, host.data(), host.size(), serv.data(),
755                         serv.size(), NI_NUMERICHOST | NI_NUMERICSERV);
756   if (rv != 0) {
757     return "unknown";
758   }
759
760   auto hostlen = strlen(host.data());
761   auto servlen = strlen(serv.data());
762
763   std::string s;
764   char *p;
765   if (family == AF_INET6) {
766     s.resize(hostlen + servlen + 2 + 1);
767     p = &s[0];
768     *p++ = '[';
769     p = std::copy_n(host.data(), hostlen, p);
770     *p++ = ']';
771   } else {
772     s.resize(hostlen + servlen + 1);
773     p = &s[0];
774     p = std::copy_n(host.data(), hostlen, p);
775   }
776   *p++ = ':';
777   std::copy_n(serv.data(), servlen, p);
778
779   return s;
780 }
781
782 void set_port(Address &addr, uint16_t port) {
783   switch (addr.su.storage.ss_family) {
784   case AF_INET:
785     addr.su.in.sin_port = htons(port);
786     break;
787   case AF_INET6:
788     addr.su.in6.sin6_port = htons(port);
789     break;
790   }
791 }
792
793 std::string ascii_dump(const uint8_t *data, size_t len) {
794   std::string res;
795
796   for (size_t i = 0; i < len; ++i) {
797     auto c = data[i];
798
799     if (c >= 0x20 && c < 0x7f) {
800       res += c;
801     } else {
802       res += '.';
803     }
804   }
805
806   return res;
807 }
808
809 char *get_exec_path(int argc, char **const argv, const char *cwd) {
810   if (argc == 0 || cwd == nullptr) {
811     return nullptr;
812   }
813
814   auto argv0 = argv[0];
815   auto len = strlen(argv0);
816
817   char *path;
818
819   if (argv0[0] == '/') {
820     path = static_cast<char *>(malloc(len + 1));
821     if (path == nullptr) {
822       return nullptr;
823     }
824     memcpy(path, argv0, len + 1);
825   } else {
826     auto cwdlen = strlen(cwd);
827     path = static_cast<char *>(malloc(len + 1 + cwdlen + 1));
828     if (path == nullptr) {
829       return nullptr;
830     }
831     memcpy(path, cwd, cwdlen);
832     path[cwdlen] = '/';
833     memcpy(path + cwdlen + 1, argv0, len + 1);
834   }
835
836   return path;
837 }
838
839 bool check_path(const std::string &path) {
840   // We don't like '\' in path.
841   return !path.empty() && path[0] == '/' &&
842          path.find('\\') == std::string::npos &&
843          path.find("/../") == std::string::npos &&
844          path.find("/./") == std::string::npos &&
845          !util::ends_with_l(path, "/..") && !util::ends_with_l(path, "/.");
846 }
847
848 int64_t to_time64(const timeval &tv) {
849   return tv.tv_sec * 1000000 + tv.tv_usec;
850 }
851
852 bool check_h2_is_selected(const StringRef &proto) {
853   return streq(NGHTTP2_H2, proto) || streq(NGHTTP2_H2_16, proto) ||
854          streq(NGHTTP2_H2_14, proto);
855 }
856
857 namespace {
858 bool select_proto(const unsigned char **out, unsigned char *outlen,
859                   const unsigned char *in, unsigned int inlen,
860                   const StringRef &key) {
861   for (auto p = in, end = in + inlen; p + key.size() <= end; p += *p + 1) {
862     if (std::equal(std::begin(key), std::end(key), p)) {
863       *out = p + 1;
864       *outlen = *p;
865       return true;
866     }
867   }
868   return false;
869 }
870 } // namespace
871
872 bool select_h2(const unsigned char **out, unsigned char *outlen,
873                const unsigned char *in, unsigned int inlen) {
874   return select_proto(out, outlen, in, inlen, NGHTTP2_H2_ALPN) ||
875          select_proto(out, outlen, in, inlen, NGHTTP2_H2_16_ALPN) ||
876          select_proto(out, outlen, in, inlen, NGHTTP2_H2_14_ALPN);
877 }
878
879 bool select_protocol(const unsigned char **out, unsigned char *outlen,
880                      const unsigned char *in, unsigned int inlen,
881                      std::vector<std::string> proto_list) {
882   for (const auto &proto : proto_list) {
883     if (select_proto(out, outlen, in, inlen, StringRef{proto})) {
884       return true;
885     }
886   }
887
888   return false;
889 }
890
891 std::vector<unsigned char> get_default_alpn() {
892   auto res = std::vector<unsigned char>(NGHTTP2_H2_ALPN.size() +
893                                         NGHTTP2_H2_16_ALPN.size() +
894                                         NGHTTP2_H2_14_ALPN.size());
895   auto p = std::begin(res);
896
897   p = std::copy_n(std::begin(NGHTTP2_H2_ALPN), NGHTTP2_H2_ALPN.size(), p);
898   p = std::copy_n(std::begin(NGHTTP2_H2_16_ALPN), NGHTTP2_H2_16_ALPN.size(), p);
899   p = std::copy_n(std::begin(NGHTTP2_H2_14_ALPN), NGHTTP2_H2_14_ALPN.size(), p);
900
901   return res;
902 }
903
904 std::vector<StringRef> split_str(const StringRef &s, char delim) {
905   size_t len = 1;
906   auto last = std::end(s);
907   StringRef::const_iterator d;
908   for (auto first = std::begin(s); (d = std::find(first, last, delim)) != last;
909        ++len, first = d + 1)
910     ;
911
912   auto list = std::vector<StringRef>(len);
913
914   len = 0;
915   for (auto first = std::begin(s);; ++len) {
916     auto stop = std::find(first, last, delim);
917     list[len] = StringRef{first, stop};
918     if (stop == last) {
919       break;
920     }
921     first = stop + 1;
922   }
923   return list;
924 }
925
926 std::vector<StringRef> split_str(const StringRef &s, char delim, size_t n) {
927   if (n == 0) {
928     return split_str(s, delim);
929   }
930
931   if (n == 1) {
932     return {s};
933   }
934
935   size_t len = 1;
936   auto last = std::end(s);
937   StringRef::const_iterator d;
938   for (auto first = std::begin(s);
939        len < n && (d = std::find(first, last, delim)) != last;
940        ++len, first = d + 1)
941     ;
942
943   auto list = std::vector<StringRef>(len);
944
945   len = 0;
946   for (auto first = std::begin(s);; ++len) {
947     if (len == n - 1) {
948       list[len] = StringRef{first, last};
949       break;
950     }
951
952     auto stop = std::find(first, last, delim);
953     list[len] = StringRef{first, stop};
954     if (stop == last) {
955       break;
956     }
957     first = stop + 1;
958   }
959   return list;
960 }
961
962 std::vector<std::string> parse_config_str_list(const StringRef &s, char delim) {
963   auto sublist = split_str(s, delim);
964   auto res = std::vector<std::string>();
965   res.reserve(sublist.size());
966   for (const auto &s : sublist) {
967     res.emplace_back(std::begin(s), std::end(s));
968   }
969   return res;
970 }
971
972 int make_socket_closeonexec(int fd) {
973 #ifdef _WIN32
974   (void)fd;
975   return 0;
976 #else  // !_WIN32
977   int flags;
978   int rv;
979   while ((flags = fcntl(fd, F_GETFD)) == -1 && errno == EINTR)
980     ;
981   while ((rv = fcntl(fd, F_SETFD, flags | FD_CLOEXEC)) == -1 && errno == EINTR)
982     ;
983   return rv;
984 #endif // !_WIN32
985 }
986
987 int make_socket_nonblocking(int fd) {
988   int rv;
989
990 #ifdef _WIN32
991   u_long mode = 1;
992
993   rv = ioctlsocket(fd, FIONBIO, &mode);
994 #else  // !_WIN32
995   int flags;
996   while ((flags = fcntl(fd, F_GETFL, 0)) == -1 && errno == EINTR)
997     ;
998   while ((rv = fcntl(fd, F_SETFL, flags | O_NONBLOCK)) == -1 && errno == EINTR)
999     ;
1000 #endif // !_WIN32
1001
1002   return rv;
1003 }
1004
1005 int make_socket_nodelay(int fd) {
1006   int val = 1;
1007   if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast<char *>(&val),
1008                  sizeof(val)) == -1) {
1009     return -1;
1010   }
1011   return 0;
1012 }
1013
1014 int create_nonblock_socket(int family) {
1015 #ifdef SOCK_NONBLOCK
1016   auto fd = socket(family, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
1017
1018   if (fd == -1) {
1019     return -1;
1020   }
1021 #else  // !SOCK_NONBLOCK
1022   auto fd = socket(family, SOCK_STREAM, 0);
1023
1024   if (fd == -1) {
1025     return -1;
1026   }
1027
1028   make_socket_nonblocking(fd);
1029   make_socket_closeonexec(fd);
1030 #endif // !SOCK_NONBLOCK
1031
1032   if (family == AF_INET || family == AF_INET6) {
1033     make_socket_nodelay(fd);
1034   }
1035
1036   return fd;
1037 }
1038
1039 int create_nonblock_udp_socket(int family) {
1040 #ifdef SOCK_NONBLOCK
1041   auto fd = socket(family, SOCK_DGRAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
1042
1043   if (fd == -1) {
1044     return -1;
1045   }
1046 #else  // !SOCK_NONBLOCK
1047   auto fd = socket(family, SOCK_DGRAM, 0);
1048
1049   if (fd == -1) {
1050     return -1;
1051   }
1052
1053   make_socket_nonblocking(fd);
1054   make_socket_closeonexec(fd);
1055 #endif // !SOCK_NONBLOCK
1056
1057   return fd;
1058 }
1059
1060 int bind_any_addr_udp(int fd, int family) {
1061   addrinfo hints{};
1062   addrinfo *res, *rp;
1063   int rv;
1064
1065   hints.ai_family = family;
1066   hints.ai_socktype = SOCK_DGRAM;
1067   hints.ai_flags = AI_PASSIVE;
1068
1069   rv = getaddrinfo(nullptr, "0", &hints, &res);
1070   if (rv != 0) {
1071     return -1;
1072   }
1073
1074   for (rp = res; rp; rp = rp->ai_next) {
1075     if (bind(fd, rp->ai_addr, rp->ai_addrlen) != -1) {
1076       break;
1077     }
1078   }
1079
1080   freeaddrinfo(res);
1081
1082   if (!rp) {
1083     return -1;
1084   }
1085
1086   return 0;
1087 }
1088
1089 bool check_socket_connected(int fd) {
1090   int error;
1091   socklen_t len = sizeof(error);
1092   if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (char *)&error, &len) != 0) {
1093     return false;
1094   }
1095
1096   return error == 0;
1097 }
1098
1099 int get_socket_error(int fd) {
1100   int error;
1101   socklen_t len = sizeof(error);
1102   if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (char *)&error, &len) != 0) {
1103     return -1;
1104   }
1105
1106   return error;
1107 }
1108
1109 bool ipv6_numeric_addr(const char *host) {
1110   uint8_t dst[16];
1111   return nghttp2_inet_pton(AF_INET6, host, dst) == 1;
1112 }
1113
1114 namespace {
1115 std::pair<int64_t, size_t> parse_uint_digits(const void *ss, size_t len) {
1116   const uint8_t *s = static_cast<const uint8_t *>(ss);
1117   int64_t n = 0;
1118   size_t i;
1119   if (len == 0) {
1120     return {-1, 0};
1121   }
1122   constexpr int64_t max = std::numeric_limits<int64_t>::max();
1123   for (i = 0; i < len; ++i) {
1124     if ('0' <= s[i] && s[i] <= '9') {
1125       if (n > max / 10) {
1126         return {-1, 0};
1127       }
1128       n *= 10;
1129       if (n > max - (s[i] - '0')) {
1130         return {-1, 0};
1131       }
1132       n += s[i] - '0';
1133       continue;
1134     }
1135     break;
1136   }
1137   if (i == 0) {
1138     return {-1, 0};
1139   }
1140   return {n, i};
1141 }
1142 } // namespace
1143
1144 int64_t parse_uint_with_unit(const char *s) {
1145   return parse_uint_with_unit(reinterpret_cast<const uint8_t *>(s), strlen(s));
1146 }
1147
1148 int64_t parse_uint_with_unit(const StringRef &s) {
1149   return parse_uint_with_unit(s.byte(), s.size());
1150 }
1151
1152 int64_t parse_uint_with_unit(const uint8_t *s, size_t len) {
1153   int64_t n;
1154   size_t i;
1155   std::tie(n, i) = parse_uint_digits(s, len);
1156   if (n == -1) {
1157     return -1;
1158   }
1159   if (i == len) {
1160     return n;
1161   }
1162   if (i + 1 != len) {
1163     return -1;
1164   }
1165   int mul = 1;
1166   switch (s[i]) {
1167   case 'K':
1168   case 'k':
1169     mul = 1 << 10;
1170     break;
1171   case 'M':
1172   case 'm':
1173     mul = 1 << 20;
1174     break;
1175   case 'G':
1176   case 'g':
1177     mul = 1 << 30;
1178     break;
1179   default:
1180     return -1;
1181   }
1182   constexpr int64_t max = std::numeric_limits<int64_t>::max();
1183   if (n > max / mul) {
1184     return -1;
1185   }
1186   return n * mul;
1187 }
1188
1189 int64_t parse_uint(const char *s) {
1190   return parse_uint(reinterpret_cast<const uint8_t *>(s), strlen(s));
1191 }
1192
1193 int64_t parse_uint(const std::string &s) {
1194   return parse_uint(reinterpret_cast<const uint8_t *>(s.c_str()), s.size());
1195 }
1196
1197 int64_t parse_uint(const StringRef &s) {
1198   return parse_uint(s.byte(), s.size());
1199 }
1200
1201 int64_t parse_uint(const uint8_t *s, size_t len) {
1202   int64_t n;
1203   size_t i;
1204   std::tie(n, i) = parse_uint_digits(s, len);
1205   if (n == -1 || i != len) {
1206     return -1;
1207   }
1208   return n;
1209 }
1210
1211 double parse_duration_with_unit(const char *s) {
1212   return parse_duration_with_unit(reinterpret_cast<const uint8_t *>(s),
1213                                   strlen(s));
1214 }
1215
1216 double parse_duration_with_unit(const StringRef &s) {
1217   return parse_duration_with_unit(s.byte(), s.size());
1218 }
1219
1220 double parse_duration_with_unit(const uint8_t *s, size_t len) {
1221   constexpr auto max = std::numeric_limits<int64_t>::max();
1222   int64_t n;
1223   size_t i;
1224
1225   std::tie(n, i) = parse_uint_digits(s, len);
1226   if (n == -1) {
1227     goto fail;
1228   }
1229   if (i == len) {
1230     return static_cast<double>(n);
1231   }
1232   switch (s[i]) {
1233   case 'S':
1234   case 's':
1235     // seconds
1236     if (i + 1 != len) {
1237       goto fail;
1238     }
1239     return static_cast<double>(n);
1240   case 'M':
1241   case 'm':
1242     if (i + 1 == len) {
1243       // minutes
1244       if (n > max / 60) {
1245         goto fail;
1246       }
1247       return static_cast<double>(n) * 60;
1248     }
1249
1250     if (i + 2 != len || (s[i + 1] != 's' && s[i + 1] != 'S')) {
1251       goto fail;
1252     }
1253     // milliseconds
1254     return static_cast<double>(n) / 1000.;
1255   case 'H':
1256   case 'h':
1257     // hours
1258     if (i + 1 != len) {
1259       goto fail;
1260     }
1261     if (n > max / 3600) {
1262       goto fail;
1263     }
1264     return static_cast<double>(n) * 3600;
1265   }
1266 fail:
1267   return std::numeric_limits<double>::infinity();
1268 }
1269
1270 std::string duration_str(double t) {
1271   if (t == 0.) {
1272     return "0";
1273   }
1274   auto frac = static_cast<int64_t>(t * 1000) % 1000;
1275   if (frac > 0) {
1276     return utos(static_cast<int64_t>(t * 1000)) + "ms";
1277   }
1278   auto v = static_cast<int64_t>(t);
1279   if (v % 60) {
1280     return utos(v) + "s";
1281   }
1282   v /= 60;
1283   if (v % 60) {
1284     return utos(v) + "m";
1285   }
1286   v /= 60;
1287   return utos(v) + "h";
1288 }
1289
1290 std::string format_duration(const std::chrono::microseconds &u) {
1291   const char *unit = "us";
1292   int d = 0;
1293   auto t = u.count();
1294   if (t >= 1000000) {
1295     d = 1000000;
1296     unit = "s";
1297   } else if (t >= 1000) {
1298     d = 1000;
1299     unit = "ms";
1300   } else {
1301     return utos(t) + unit;
1302   }
1303   return dtos(static_cast<double>(t) / d) + unit;
1304 }
1305
1306 std::string format_duration(double t) {
1307   const char *unit = "us";
1308   if (t >= 1.) {
1309     unit = "s";
1310   } else if (t >= 0.001) {
1311     t *= 1000.;
1312     unit = "ms";
1313   } else {
1314     t *= 1000000.;
1315     return utos(static_cast<int64_t>(t)) + unit;
1316   }
1317   return dtos(t) + unit;
1318 }
1319
1320 std::string dtos(double n) {
1321   auto m = llround(100. * n);
1322   auto f = utos(m % 100);
1323   return utos(m / 100) + "." + (f.size() == 1 ? "0" : "") + f;
1324 }
1325
1326 StringRef make_http_hostport(BlockAllocator &balloc, const StringRef &host,
1327                              uint16_t port) {
1328   auto iov = make_byte_ref(balloc, host.size() + 2 + 1 + 5 + 1);
1329   return make_http_hostport(iov.base, host, port);
1330 }
1331
1332 StringRef make_hostport(BlockAllocator &balloc, const StringRef &host,
1333                         uint16_t port) {
1334   auto iov = make_byte_ref(balloc, host.size() + 2 + 1 + 5 + 1);
1335   return make_hostport(iov.base, host, port);
1336 }
1337
1338 namespace {
1339 void hexdump8(FILE *out, const uint8_t *first, const uint8_t *last) {
1340   auto stop = std::min(first + 8, last);
1341   for (auto k = first; k != stop; ++k) {
1342     fprintf(out, "%02x ", *k);
1343   }
1344   // each byte needs 3 spaces (2 hex value and space)
1345   for (; stop != first + 8; ++stop) {
1346     fputs("   ", out);
1347   }
1348   // we have extra space after 8 bytes
1349   fputc(' ', out);
1350 }
1351 } // namespace
1352
1353 void hexdump(FILE *out, const uint8_t *src, size_t len) {
1354   if (len == 0) {
1355     return;
1356   }
1357   size_t buflen = 0;
1358   auto repeated = false;
1359   std::array<uint8_t, 16> buf{};
1360   auto end = src + len;
1361   auto i = src;
1362   for (;;) {
1363     auto nextlen =
1364         std::min(static_cast<size_t>(16), static_cast<size_t>(end - i));
1365     if (nextlen == buflen &&
1366         std::equal(std::begin(buf), std::begin(buf) + buflen, i)) {
1367       // as long as adjacent 16 bytes block are the same, we just
1368       // print single '*'.
1369       if (!repeated) {
1370         repeated = true;
1371         fputs("*\n", out);
1372       }
1373       i += nextlen;
1374       continue;
1375     }
1376     repeated = false;
1377     fprintf(out, "%08lx", static_cast<unsigned long>(i - src));
1378     if (i == end) {
1379       fputc('\n', out);
1380       break;
1381     }
1382     fputs("  ", out);
1383     hexdump8(out, i, end);
1384     hexdump8(out, i + 8, std::max(i + 8, end));
1385     fputc('|', out);
1386     auto stop = std::min(i + 16, end);
1387     buflen = stop - i;
1388     auto p = buf.data();
1389     for (; i != stop; ++i) {
1390       *p++ = *i;
1391       if (0x20 <= *i && *i <= 0x7e) {
1392         fputc(*i, out);
1393       } else {
1394         fputc('.', out);
1395       }
1396     }
1397     fputs("|\n", out);
1398   }
1399 }
1400
1401 void put_uint16be(uint8_t *buf, uint16_t n) {
1402   uint16_t x = htons(n);
1403   memcpy(buf, &x, sizeof(uint16_t));
1404 }
1405
1406 void put_uint32be(uint8_t *buf, uint32_t n) {
1407   uint32_t x = htonl(n);
1408   memcpy(buf, &x, sizeof(uint32_t));
1409 }
1410
1411 uint16_t get_uint16(const uint8_t *data) {
1412   uint16_t n;
1413   memcpy(&n, data, sizeof(uint16_t));
1414   return ntohs(n);
1415 }
1416
1417 uint32_t get_uint32(const uint8_t *data) {
1418   uint32_t n;
1419   memcpy(&n, data, sizeof(uint32_t));
1420   return ntohl(n);
1421 }
1422
1423 uint64_t get_uint64(const uint8_t *data) {
1424   uint64_t n = 0;
1425   n += static_cast<uint64_t>(data[0]) << 56;
1426   n += static_cast<uint64_t>(data[1]) << 48;
1427   n += static_cast<uint64_t>(data[2]) << 40;
1428   n += static_cast<uint64_t>(data[3]) << 32;
1429   n += static_cast<uint64_t>(data[4]) << 24;
1430   n += data[5] << 16;
1431   n += data[6] << 8;
1432   n += data[7];
1433   return n;
1434 }
1435
1436 int read_mime_types(std::map<std::string, std::string> &res,
1437                     const char *filename) {
1438   std::ifstream infile(filename);
1439   if (!infile) {
1440     return -1;
1441   }
1442
1443   auto delim_pred = [](char c) { return c == ' ' || c == '\t'; };
1444
1445   std::string line;
1446   while (std::getline(infile, line)) {
1447     if (line.empty() || line[0] == '#') {
1448       continue;
1449     }
1450
1451     auto type_end = std::find_if(std::begin(line), std::end(line), delim_pred);
1452     if (type_end == std::begin(line)) {
1453       continue;
1454     }
1455
1456     auto ext_end = type_end;
1457     for (;;) {
1458       auto ext_start = std::find_if_not(ext_end, std::end(line), delim_pred);
1459       if (ext_start == std::end(line)) {
1460         break;
1461       }
1462       ext_end = std::find_if(ext_start, std::end(line), delim_pred);
1463 #ifdef HAVE_STD_MAP_EMPLACE
1464       res.emplace(std::string(ext_start, ext_end),
1465                   std::string(std::begin(line), type_end));
1466 #else  // !HAVE_STD_MAP_EMPLACE
1467       res.insert(std::make_pair(std::string(ext_start, ext_end),
1468                                 std::string(std::begin(line), type_end)));
1469 #endif // !HAVE_STD_MAP_EMPLACE
1470     }
1471   }
1472
1473   return 0;
1474 }
1475
1476 StringRef percent_decode(BlockAllocator &balloc, const StringRef &src) {
1477   auto iov = make_byte_ref(balloc, src.size() * 3 + 1);
1478   auto p = iov.base;
1479   for (auto first = std::begin(src); first != std::end(src); ++first) {
1480     if (*first != '%') {
1481       *p++ = *first;
1482       continue;
1483     }
1484
1485     if (first + 1 != std::end(src) && first + 2 != std::end(src) &&
1486         is_hex_digit(*(first + 1)) && is_hex_digit(*(first + 2))) {
1487       *p++ = (hex_to_uint(*(first + 1)) << 4) + hex_to_uint(*(first + 2));
1488       first += 2;
1489       continue;
1490     }
1491
1492     *p++ = *first;
1493   }
1494   *p = '\0';
1495   return StringRef{iov.base, p};
1496 }
1497
1498 // Returns x**y
1499 double int_pow(double x, size_t y) {
1500   auto res = 1.;
1501   for (; y; --y) {
1502     res *= x;
1503   }
1504   return res;
1505 }
1506
1507 uint32_t hash32(const StringRef &s) {
1508   /* 32 bit FNV-1a: http://isthe.com/chongo/tech/comp/fnv/ */
1509   uint32_t h = 2166136261u;
1510   size_t i;
1511
1512   for (i = 0; i < s.size(); ++i) {
1513     h ^= s[i];
1514     h += (h << 1) + (h << 4) + (h << 7) + (h << 8) + (h << 24);
1515   }
1516
1517   return h;
1518 }
1519
1520 #if !OPENSSL_1_1_API
1521 namespace {
1522 EVP_MD_CTX *EVP_MD_CTX_new(void) { return EVP_MD_CTX_create(); }
1523 } // namespace
1524
1525 namespace {
1526 void EVP_MD_CTX_free(EVP_MD_CTX *ctx) { EVP_MD_CTX_destroy(ctx); }
1527 } // namespace
1528 #endif // !OPENSSL_1_1_API
1529
1530 namespace {
1531 int message_digest(uint8_t *res, const EVP_MD *meth, const StringRef &s) {
1532   int rv;
1533
1534   auto ctx = EVP_MD_CTX_new();
1535   if (ctx == nullptr) {
1536     return -1;
1537   }
1538
1539   auto ctx_deleter = defer(EVP_MD_CTX_free, ctx);
1540
1541   rv = EVP_DigestInit_ex(ctx, meth, nullptr);
1542   if (rv != 1) {
1543     return -1;
1544   }
1545
1546   rv = EVP_DigestUpdate(ctx, s.c_str(), s.size());
1547   if (rv != 1) {
1548     return -1;
1549   }
1550
1551   unsigned int mdlen = EVP_MD_size(meth);
1552
1553   rv = EVP_DigestFinal_ex(ctx, res, &mdlen);
1554   if (rv != 1) {
1555     return -1;
1556   }
1557
1558   return 0;
1559 }
1560 } // namespace
1561
1562 int sha256(uint8_t *res, const StringRef &s) {
1563   return message_digest(res, EVP_sha256(), s);
1564 }
1565
1566 int sha1(uint8_t *res, const StringRef &s) {
1567   return message_digest(res, EVP_sha1(), s);
1568 }
1569
1570 bool is_hex_string(const StringRef &s) {
1571   if (s.size() % 2) {
1572     return false;
1573   }
1574
1575   for (auto c : s) {
1576     if (!is_hex_digit(c)) {
1577       return false;
1578     }
1579   }
1580
1581   return true;
1582 }
1583
1584 StringRef decode_hex(BlockAllocator &balloc, const StringRef &s) {
1585   auto iov = make_byte_ref(balloc, s.size() + 1);
1586   auto p = decode_hex(iov.base, s);
1587   *p = '\0';
1588   return StringRef{iov.base, p};
1589 }
1590
1591 StringRef extract_host(const StringRef &hostport) {
1592   if (hostport[0] == '[') {
1593     // assume this is IPv6 numeric address
1594     auto p = std::find(std::begin(hostport), std::end(hostport), ']');
1595     if (p == std::end(hostport)) {
1596       return StringRef{};
1597     }
1598     if (p + 1 < std::end(hostport) && *(p + 1) != ':') {
1599       return StringRef{};
1600     }
1601     return StringRef{std::begin(hostport), p + 1};
1602   }
1603
1604   auto p = std::find(std::begin(hostport), std::end(hostport), ':');
1605   if (p == std::begin(hostport)) {
1606     return StringRef{};
1607   }
1608   return StringRef{std::begin(hostport), p};
1609 }
1610
1611 std::pair<StringRef, StringRef> split_hostport(const StringRef &hostport) {
1612   if (hostport.empty()) {
1613     return {};
1614   }
1615   if (hostport[0] == '[') {
1616     // assume this is IPv6 numeric address
1617     auto p = std::find(std::begin(hostport), std::end(hostport), ']');
1618     if (p == std::end(hostport)) {
1619       return {};
1620     }
1621     if (p + 1 == std::end(hostport)) {
1622       return {StringRef{std::begin(hostport) + 1, p}, {}};
1623     }
1624     if (*(p + 1) != ':' || p + 2 == std::end(hostport)) {
1625       return {};
1626     }
1627     return {StringRef{std::begin(hostport) + 1, p},
1628             StringRef{p + 2, std::end(hostport)}};
1629   }
1630
1631   auto p = std::find(std::begin(hostport), std::end(hostport), ':');
1632   if (p == std::begin(hostport)) {
1633     return {};
1634   }
1635   if (p == std::end(hostport)) {
1636     return {StringRef{std::begin(hostport), p}, {}};
1637   }
1638   if (p + 1 == std::end(hostport)) {
1639     return {};
1640   }
1641
1642   return {StringRef{std::begin(hostport), p},
1643           StringRef{p + 1, std::end(hostport)}};
1644 }
1645
1646 std::mt19937 make_mt19937() {
1647   std::random_device rd;
1648   return std::mt19937(rd());
1649 }
1650
1651 int daemonize(int nochdir, int noclose) {
1652 #ifdef __APPLE__
1653   pid_t pid;
1654   pid = fork();
1655   if (pid == -1) {
1656     return -1;
1657   } else if (pid > 0) {
1658     _exit(EXIT_SUCCESS);
1659   }
1660   if (setsid() == -1) {
1661     return -1;
1662   }
1663   pid = fork();
1664   if (pid == -1) {
1665     return -1;
1666   } else if (pid > 0) {
1667     _exit(EXIT_SUCCESS);
1668   }
1669   if (nochdir == 0) {
1670     if (chdir("/") == -1) {
1671       return -1;
1672     }
1673   }
1674   if (noclose == 0) {
1675     if (freopen("/dev/null", "r", stdin) == nullptr) {
1676       return -1;
1677     }
1678     if (freopen("/dev/null", "w", stdout) == nullptr) {
1679       return -1;
1680     }
1681     if (freopen("/dev/null", "w", stderr) == nullptr) {
1682       return -1;
1683     }
1684   }
1685   return 0;
1686 #else  // !__APPLE__
1687   return daemon(nochdir, noclose);
1688 #endif // !__APPLE__
1689 }
1690
1691 #ifdef ENABLE_HTTP3
1692 int msghdr_get_local_addr(Address &dest, msghdr *msg, int family) {
1693   switch (family) {
1694   case AF_INET:
1695     for (auto cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) {
1696       if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) {
1697         auto pktinfo = reinterpret_cast<in_pktinfo *>(CMSG_DATA(cmsg));
1698         dest.len = sizeof(dest.su.in);
1699         auto &sa = dest.su.in;
1700         sa.sin_family = AF_INET;
1701         sa.sin_addr = pktinfo->ipi_addr;
1702
1703         return 0;
1704       }
1705     }
1706
1707     return -1;
1708   case AF_INET6:
1709     for (auto cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) {
1710       if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) {
1711         auto pktinfo = reinterpret_cast<in6_pktinfo *>(CMSG_DATA(cmsg));
1712         dest.len = sizeof(dest.su.in6);
1713         auto &sa = dest.su.in6;
1714         sa.sin6_family = AF_INET6;
1715         sa.sin6_addr = pktinfo->ipi6_addr;
1716         return 0;
1717       }
1718     }
1719
1720     return -1;
1721   }
1722
1723   return -1;
1724 }
1725 #endif // ENABLE_HTTP3
1726
1727 } // namespace util
1728
1729 } // namespace nghttp2