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