_ZN7httplib6detail17gzip_decompressorD2Ev:
 7649|    138|inline gzip_decompressor::~gzip_decompressor() { inflateEnd(&strm_); }
_ZN7httplib10ClientImplD2Ev:
14511|  3.08k|inline ClientImpl::~ClientImpl() {
14512|       |  // Wait until all the requests in flight are handled.
14513|  3.08k|  size_t retry_count = 10;
14514|  3.08k|  while (retry_count-- > 0) {
  ------------------
  |  Branch (14514:10): [True: 3.08k, False: 0]
  ------------------
14515|  3.08k|    {
14516|  3.08k|      std::lock_guard<std::mutex> guard(socket_mutex_);
14517|  3.08k|      if (socket_requests_in_flight_ == 0) { break; }
  ------------------
  |  Branch (14517:11): [True: 3.08k, False: 0]
  ------------------
14518|  3.08k|    }
14519|      0|    std::this_thread::sleep_for(std::chrono::milliseconds{1});
14520|      0|  }
14521|       |
14522|  3.08k|  std::lock_guard<std::mutex> guard(socket_mutex_);
14523|  3.08k|  shutdown_socket(socket_);
14524|  3.08k|  close_socket(socket_);
14525|  3.08k|}
_ZN7httplib6detail12decompressorD2Ev:
 3701|    138|  virtual ~decompressor() = default;
_ZN7httplib6StreamD2Ev:
 1875|  6.16k|  virtual ~Stream() = default;
_ZNK7httplib10ClientImpl15shutdown_socketERNS0_6SocketE:
14640|  3.08k|inline void ClientImpl::shutdown_socket(Socket &socket) const {
14641|  3.08k|  if (socket.sock == INVALID_SOCKET) { return; }
  ------------------
  |  |  322|  3.08k|#define INVALID_SOCKET (-1)
  ------------------
  |  Branch (14641:7): [True: 3.08k, False: 0]
  ------------------
14642|      0|  detail::shutdown_socket(socket.sock);
14643|      0|}
_ZN7httplib10ClientImpl12close_socketERNS0_6SocketE:
14645|  3.08k|inline void ClientImpl::close_socket(Socket &socket) {
14646|       |  // If there are requests in flight in another thread, usually closing
14647|       |  // the socket will be fine and they will simply receive an error when
14648|       |  // using the closed socket, but it is still a bug since rarely the OS
14649|       |  // may reassign the socket id to be used for a new socket, and then
14650|       |  // suddenly they will be operating on a live socket that is different
14651|       |  // than the one they intended!
14652|  3.08k|  assert(socket_requests_in_flight_ == 0 ||
  ------------------
  |  Branch (14652:3): [True: 3.08k, False: 0]
  |  Branch (14652:3): [True: 0, False: 0]
  |  Branch (14652:3): [True: 3.08k, False: 0]
  ------------------
14653|  3.08k|         socket_requests_are_from_thread_ == std::this_thread::get_id());
14654|       |
14655|       |  // It is also a bug if this happens while SSL is still active
14656|       |#ifdef CPPHTTPLIB_SSL_ENABLED
14657|       |  assert(socket.ssl == nullptr);
14658|       |#endif
14659|       |
14660|  3.08k|  if (socket.sock == INVALID_SOCKET) { return; }
  ------------------
  |  |  322|  3.08k|#define INVALID_SOCKET (-1)
  ------------------
  |  Branch (14660:7): [True: 3.08k, False: 0]
  ------------------
14661|      0|  detail::close_socket(socket.sock);
14662|      0|  socket.sock = INVALID_SOCKET;
  ------------------
  |  |  322|      0|#define INVALID_SOCKET (-1)
  ------------------
14663|      0|}
_ZN7httplib10ClientImplC2ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEi:
14503|  3.08k|    : ClientImpl(host, port, std::string(), std::string()) {}
_ZN7httplib10ClientImplC2ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEiS9_S9_:
14508|  3.08k|    : host_(detail::escape_abstract_namespace_unix_domain(host)), port_(port),
14509|  3.08k|      client_cert_path_(client_cert_path), client_key_path_(client_key_path) {}
_ZN7httplib6detail37escape_abstract_namespace_unix_domainERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
 6545|  3.08k|inline std::string escape_abstract_namespace_unix_domain(const std::string &s) {
 6546|  3.08k|  if (s.size() > 1 && s[0] == '\0') {
  ------------------
  |  Branch (6546:7): [True: 3.08k, False: 0]
  |  Branch (6546:23): [True: 0, False: 3.08k]
  ------------------
 6547|      0|    auto ret = s;
 6548|      0|    ret[0] = '@';
 6549|      0|    return ret;
 6550|      0|  }
 6551|  3.08k|  return s;
 6552|  3.08k|}
_ZN7httplib6detail26insertion_ordered_multimapINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS0_11case_ignore8equal_toEEC2Ev:
 1132|  15.4k|  insertion_ordered_multimap() = default;
_ZN7httplib6detail13write_headersERNS_6StreamERKNS0_26insertion_ordered_multimapINSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEENS0_11case_ignore8equal_toEEE:
 8414|  3.08k|inline ssize_t write_headers(Stream &strm, const Headers &headers) {
 8415|  3.08k|  ssize_t write_len = 0;
 8416|  14.2k|  for (const auto &x : headers) {
  ------------------
  |  Branch (8416:22): [True: 14.2k, False: 3.08k]
  ------------------
 8417|       |    // Skip fields with invalid names or values to prevent response splitting
 8418|       |    // via CR/LF injection, matching set_header(). The client validates request
 8419|       |    // headers up front in check_and_write_headers, but the server passes
 8420|       |    // res.headers straight to this writer, and res.headers is a public field
 8421|       |    // an application can populate directly with request-derived values.
 8422|  14.2k|    if (!fields::is_field_valid(x.first, x.second)) { continue; }
  ------------------
  |  Branch (8422:9): [True: 0, False: 14.2k]
  ------------------
 8423|       |
 8424|  14.2k|    std::string s;
 8425|  14.2k|    s = x.first;
 8426|  14.2k|    s += ": ";
 8427|  14.2k|    s += x.second;
 8428|  14.2k|    s += "\r\n";
 8429|       |
 8430|  14.2k|    auto len = strm.write(s.data(), s.size());
 8431|  14.2k|    if (len < 0) { return len; }
  ------------------
  |  Branch (8431:9): [True: 0, False: 14.2k]
  ------------------
 8432|  14.2k|    write_len += len;
 8433|  14.2k|  }
 8434|  3.08k|  auto len = strm.write("\r\n");
 8435|  3.08k|  if (len < 0) { return len; }
  ------------------
  |  Branch (8435:7): [True: 0, False: 3.08k]
  ------------------
 8436|  3.08k|  write_len += len;
 8437|  3.08k|  return write_len;
 8438|  3.08k|}
_ZNK7httplib6detail26insertion_ordered_multimapINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS0_11case_ignore8equal_toEE5beginEv:
 1141|  3.08k|  const_iterator begin() const { return make_citer(0, npos()); }
_ZNK7httplib6detail26insertion_ordered_multimapINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS0_11case_ignore8equal_toEE10make_citerEmm:
 1274|  64.4k|  const_iterator make_citer(size_type idx, size_type key_idx) const {
 1275|  64.4k|    return const_iterator(entries_.data(), idx, entries_.size(), key_idx);
 1276|  64.4k|  }
_ZN7httplib6detail26insertion_ordered_multimapINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS0_11case_ignore8equal_toEE10iterator_tIKNS2_4pairIS8_S8_EEEC2EPSF_mmm:
 1116|  64.4k|        : data_(data), idx_(idx), size_(size), key_idx_(key_idx) {}
_ZN7httplib6detail26insertion_ordered_multimapINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS0_11case_ignore8equal_toEE4nposEv:
 1035|   191k|  static size_type npos() { return static_cast<size_type>(-1); }
_ZNK7httplib6detail26insertion_ordered_multimapINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS0_11case_ignore8equal_toEE3endEv:
 1142|  57.9k|  const_iterator end() const { return make_citer(entries_.size(), npos()); }
_ZNK7httplib6detail26insertion_ordered_multimapINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS0_11case_ignore8equal_toEE10iterator_tIKNS2_4pairIS8_S8_EEEneISF_EEbRKNSC_IT_EE:
 1107|  48.0k|    template <typename U> bool operator!=(const iterator_t<U> &rhs) const {
 1108|  48.0k|      return idx_ != rhs.idx_;
 1109|  48.0k|    }
_ZNK7httplib6detail26insertion_ordered_multimapINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS0_11case_ignore8equal_toEE10iterator_tIKNS2_4pairIS8_S8_EEEdeEv:
 1063|  14.2k|    reference operator*() const { return data_[idx_]; }
_ZN7httplib6detail6fields14is_field_validERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEESA_:
10035|  36.4k|inline bool is_field_valid(const std::string &name, const std::string &value) {
10036|  36.4k|  return is_field_name(name) && is_field_value(value);
  ------------------
  |  Branch (10036:10): [True: 36.4k, False: 0]
  |  Branch (10036:33): [True: 36.4k, False: 0]
  ------------------
10037|  36.4k|}
_ZN7httplib6detail6fields13is_field_nameERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
10000|  50.8k|inline bool is_field_name(const std::string &s) { return is_token(s); }
_ZN7httplib6detail6fields8is_tokenERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
 9992|  50.8k|inline bool is_token(const std::string &s) {
 9993|  50.8k|  if (s.empty()) { return false; }
  ------------------
  |  Branch (9993:7): [True: 66, False: 50.7k]
  ------------------
 9994|   525k|  for (auto c : s) {
  ------------------
  |  Branch (9994:15): [True: 525k, False: 50.6k]
  ------------------
 9995|   525k|    if (!is_token_char(c)) { return false; }
  ------------------
  |  Branch (9995:9): [True: 133, False: 525k]
  ------------------
 9996|   525k|  }
 9997|  50.6k|  return true;
 9998|  50.7k|}
_ZN7httplib6detail6fields13is_token_charEc:
 9986|   525k|inline bool is_token_char(char c) {
 9987|   525k|  return is_ascii_alnum(c) || c == '!' || c == '#' || c == '$' || c == '%' ||
  ------------------
  |  Branch (9987:10): [True: 479k, False: 46.2k]
  |  Branch (9987:31): [True: 418, False: 45.7k]
  |  Branch (9987:43): [True: 1.30k, False: 44.4k]
  |  Branch (9987:55): [True: 810, False: 43.6k]
  |  Branch (9987:67): [True: 370, False: 43.3k]
  ------------------
 9988|  43.3k|         c == '&' || c == '\'' || c == '*' || c == '+' || c == '-' ||
  ------------------
  |  Branch (9988:10): [True: 955, False: 42.3k]
  |  Branch (9988:22): [True: 697, False: 41.6k]
  |  Branch (9988:35): [True: 2.46k, False: 39.1k]
  |  Branch (9988:47): [True: 455, False: 38.7k]
  |  Branch (9988:59): [True: 30.6k, False: 8.09k]
  ------------------
 9989|  8.09k|         c == '.' || c == '^' || c == '_' || c == '`' || c == '|' || c == '~';
  ------------------
  |  Branch (9989:10): [True: 656, False: 7.44k]
  |  Branch (9989:22): [True: 1.97k, False: 5.46k]
  |  Branch (9989:34): [True: 2.86k, False: 2.60k]
  |  Branch (9989:46): [True: 827, False: 1.78k]
  |  Branch (9989:58): [True: 573, False: 1.20k]
  |  Branch (9989:70): [True: 1.07k, False: 133]
  ------------------
 9990|   525k|}
_ZN7httplib6detail14is_ascii_alnumEc:
  590|   525k|inline bool is_ascii_alnum(char c) {
  591|   525k|  return is_ascii_digit(c) || is_ascii_alpha(c);
  ------------------
  |  Branch (591:10): [True: 10.5k, False: 515k]
  |  Branch (591:31): [True: 468k, False: 46.2k]
  ------------------
  592|   525k|}
_ZN7httplib6detail14is_ascii_digitEc:
  584|   568k|inline bool is_ascii_digit(char c) { return '0' <= c && c <= '9'; }
  ------------------
  |  Branch (584:45): [True: 526k, False: 42.6k]
  |  Branch (584:57): [True: 46.1k, False: 480k]
  ------------------
_ZN7httplib6detail14is_ascii_alphaEc:
  586|   515k|inline bool is_ascii_alpha(char c) {
  587|   515k|  return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z');
  ------------------
  |  Branch (587:11): [True: 371k, False: 143k]
  |  Branch (587:23): [True: 369k, False: 1.65k]
  |  Branch (587:37): [True: 106k, False: 38.8k]
  |  Branch (587:49): [True: 99.1k, False: 7.31k]
  ------------------
  588|   515k|}
_ZN7httplib6detail6fields14is_field_valueERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
10033|  53.5k|inline bool is_field_value(const std::string &s) { return is_field_content(s); }
_ZN7httplib6detail6fields16is_field_contentERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
10008|  53.5k|inline bool is_field_content(const std::string &s) {
10009|  53.5k|  if (s.empty()) { return true; }
  ------------------
  |  Branch (10009:7): [True: 8.24k, False: 45.2k]
  ------------------
10010|       |
10011|  45.2k|  if (s.size() == 1) {
  ------------------
  |  Branch (10011:7): [True: 9.59k, False: 35.6k]
  ------------------
10012|  9.59k|    return is_field_vchar(s[0]);
10013|  35.6k|  } else if (s.size() == 2) {
  ------------------
  |  Branch (10013:14): [True: 420, False: 35.2k]
  ------------------
10014|    420|    return is_field_vchar(s[0]) && is_field_vchar(s[1]);
  ------------------
  |  Branch (10014:12): [True: 419, False: 1]
  |  Branch (10014:36): [True: 419, False: 0]
  ------------------
10015|  35.2k|  } else {
10016|  35.2k|    size_t i = 0;
10017|       |
10018|  35.2k|    if (!is_field_vchar(s[i])) { return false; }
  ------------------
  |  Branch (10018:9): [True: 4, False: 35.2k]
  ------------------
10019|  35.2k|    i++;
10020|       |
10021|  2.27M|    while (i < s.size() - 1) {
  ------------------
  |  Branch (10021:12): [True: 2.24M, False: 35.2k]
  ------------------
10022|  2.24M|      auto c = s[i++];
10023|  2.24M|      if (c == ' ' || c == '\t' || is_field_vchar(c)) {
  ------------------
  |  Branch (10023:11): [True: 84.2k, False: 2.15M]
  |  Branch (10023:23): [True: 962, False: 2.15M]
  |  Branch (10023:36): [True: 2.15M, False: 32]
  ------------------
10024|  2.24M|      } else {
10025|     32|        return false;
10026|     32|      }
10027|  2.24M|    }
10028|       |
10029|  35.2k|    return is_field_vchar(s[i]);
10030|  35.2k|  }
10031|  45.2k|}
_ZN7httplib6detail6fields14is_field_vcharEc:
10006|  2.23M|inline bool is_field_vchar(char c) { return is_vchar(c) || is_obs_text(c); }
  ------------------
  |  Branch (10006:45): [True: 1.35M, False: 879k]
  |  Branch (10006:60): [True: 879k, False: 62]
  ------------------
_ZN7httplib6detail6fields8is_vcharEc:
10002|  2.23M|inline bool is_vchar(char c) { return c >= 33 && c <= 126; }
  ------------------
  |  Branch (10002:39): [True: 1.35M, False: 879k]
  |  Branch (10002:50): [True: 1.35M, False: 4]
  ------------------
_ZN7httplib6detail6fields11is_obs_textEc:
10004|   879k|inline bool is_obs_text(char c) { return 128 <= static_cast<unsigned char>(c); }
_ZN7httplib6detail26insertion_ordered_multimapINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS0_11case_ignore8equal_toEE10iterator_tIKNS2_4pairIS8_S8_EEEppEv:
 1066|  16.6k|    iterator_t &operator++() {
 1067|       |      // Saturating, so that advancing past the last entry of a key (which
 1068|       |      // get_multimap_value() does when asked for an out-of-range id) stays at
 1069|       |      // end() instead of running off the container.
 1070|  16.6k|      if (idx_ >= size_) { return *this; }
  ------------------
  |  Branch (1070:11): [True: 0, False: 16.6k]
  ------------------
 1071|  16.6k|      ++idx_;
 1072|  16.6k|      if (key_idx_ != npos()) {
  ------------------
  |  Branch (1072:11): [True: 2.41k, False: 14.2k]
  ------------------
 1073|  2.88k|        while (idx_ < size_ && !matches(idx_)) {
  ------------------
  |  Branch (1073:16): [True: 1.76k, False: 1.12k]
  |  Branch (1073:32): [True: 476, False: 1.28k]
  ------------------
 1074|    476|          ++idx_;
 1075|    476|        }
 1076|  2.41k|      }
 1077|  16.6k|      return *this;
 1078|  16.6k|    }
_ZNK7httplib6detail26insertion_ordered_multimapINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS0_11case_ignore8equal_toEE10iterator_tIKNS2_4pairIS8_S8_EEE7matchesEm:
 1118|  1.76k|    bool matches(size_type i) const {
 1119|  1.76k|      return keys_equal(data_[i].first, data_[key_idx_].first);
 1120|  1.76k|    }
_ZN7httplib6detail26insertion_ordered_multimapINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS0_11case_ignore8equal_toEE10keys_equalERKS8_SD_:
 1037|  51.1k|  static bool keys_equal(const std::string &a, const std::string &b) {
 1038|  51.1k|    return KeyEqual()(a, b);
 1039|  51.1k|  }
_ZNK7httplib6detail11case_ignore8equal_toclERKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEESB_:
  636|  51.1k|  bool operator()(const std::string &a, const std::string &b) const {
  637|  51.1k|    return equal(a, b);
  638|  51.1k|  }
_ZN7httplib6detail11case_ignore5equalERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEESA_:
  628|  52.6k|inline bool equal(const std::string &a, const std::string &b) {
  629|  52.6k|  return a.size() == b.size() &&
  ------------------
  |  Branch (629:10): [True: 9.85k, False: 42.7k]
  ------------------
  630|  9.85k|         std::equal(a.begin(), a.end(), b.begin(), [](char ca, char cb) {
  ------------------
  |  Branch (630:10): [True: 7.14k, False: 2.71k]
  ------------------
  631|  9.85k|           return to_lower(ca) == to_lower(cb);
  632|  9.85k|         });
  633|  52.6k|}
_ZZN7httplib6detail11case_ignore5equalERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEESA_ENKUlccE_clEcc:
  630|   116k|         std::equal(a.begin(), a.end(), b.begin(), [](char ca, char cb) {
  631|   116k|           return to_lower(ca) == to_lower(cb);
  632|   116k|         });
_ZN7httplib6detail11case_ignore8to_lowerEi:
  596|   234k|inline unsigned char to_lower(int c) {
  597|   234k|  const static unsigned char table[256] = {
  598|   234k|      0,   1,   2,   3,   4,   5,   6,   7,   8,   9,   10,  11,  12,  13,  14,
  599|   234k|      15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27,  28,  29,
  600|   234k|      30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,  41,  42,  43,  44,
  601|   234k|      45,  46,  47,  48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,
  602|   234k|      60,  61,  62,  63,  64,  97,  98,  99,  100, 101, 102, 103, 104, 105, 106,
  603|   234k|      107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121,
  604|   234k|      122, 91,  92,  93,  94,  95,  96,  97,  98,  99,  100, 101, 102, 103, 104,
  605|   234k|      105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
  606|   234k|      120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134,
  607|   234k|      135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
  608|   234k|      150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,
  609|   234k|      165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179,
  610|   234k|      180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 224, 225, 226,
  611|   234k|      227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241,
  612|   234k|      242, 243, 244, 245, 246, 215, 248, 249, 250, 251, 252, 253, 254, 223, 224,
  613|   234k|      225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
  614|   234k|      240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254,
  615|   234k|      255,
  616|   234k|  };
  617|   234k|  return table[(unsigned char)(char)c];
  618|   234k|}
_ZN7httplib6Stream5writeEPKc:
11580|  3.08k|inline ssize_t Stream::write(const char *ptr) {
11581|  3.08k|  return write(ptr, strlen(ptr));
11582|  3.08k|}
_ZN7httplib6detail26insertion_ordered_multimapINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS2_8equal_toIS8_EEEC2Ev:
 1132|  3.08k|  insertion_ordered_multimap() = default;
_ZN7httplib6detail26insertion_ordered_multimapINS_9FormFieldENSt3__18equal_toINS3_12basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEEEEC2Ev:
 1132|  3.08k|  insertion_ordered_multimap() = default;
_ZN7httplib6detail26insertion_ordered_multimapINS_8FormDataENSt3__18equal_toINS3_12basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEEEEC2Ev:
 1132|  3.08k|  insertion_ordered_multimap() = default;
_ZN7httplib8ResponseC2Ev:
 1800|  3.08k|  Response() = default;
_ZN7httplib8UserDataC2Ev:
 1328|  3.08k|  UserData() = default;
_ZN7httplib10ClientImpl15process_requestERNS_6StreamERNS_7RequestERNS_8ResponseEbRNS_5ErrorE:
15826|  3.08k|                                        Error &error) {
15827|       |  // Auto-add Expect: 100-continue for large bodies
15828|  3.08k|  if (CPPHTTPLIB_EXPECT_100_THRESHOLD > 0 && !req.has_header("Expect")) {
  ------------------
  |  |   82|  3.08k|#define CPPHTTPLIB_EXPECT_100_THRESHOLD 1024
  ------------------
  |  Branch (15828:7): [True: 3.08k, Folded]
  |  Branch (15828:7): [True: 3.08k, False: 0]
  |  Branch (15828:46): [True: 3.08k, False: 0]
  ------------------
15829|  3.08k|    auto body_size = req.body.empty() ? req.content_length_ : req.body.size();
  ------------------
  |  Branch (15829:22): [True: 3.08k, False: 0]
  ------------------
15830|  3.08k|    if (body_size >= CPPHTTPLIB_EXPECT_100_THRESHOLD) {
  ------------------
  |  |   82|  3.08k|#define CPPHTTPLIB_EXPECT_100_THRESHOLD 1024
  ------------------
  |  Branch (15830:9): [True: 0, False: 3.08k]
  ------------------
15831|      0|      req.set_header("Expect", "100-continue");
15832|      0|    }
15833|  3.08k|  }
15834|       |
15835|       |  // Check for Expect: 100-continue
15836|  3.08k|  auto expect_100_continue =
15837|  3.08k|      detail::has_header_token(req.headers, "Expect", "100-continue");
15838|       |
15839|       |  // Send request (skip body if using Expect: 100-continue)
15840|  3.08k|  auto write_request_success =
15841|  3.08k|      write_request(strm, req, close_connection, error, expect_100_continue);
15842|       |
15843|       |#ifdef CPPHTTPLIB_SSL_ENABLED
15844|       |  if (is_ssl() && !expect_100_continue) {
15845|       |    auto is_proxy_enabled = is_proxy_enabled_for_host(host_);
15846|       |    if (!is_proxy_enabled) {
15847|       |      if (tls::is_peer_closed(socket_.ssl, socket_.sock)) {
15848|       |        error = Error::SSLPeerCouldBeClosed_;
15849|       |        output_error_log(error, &req);
15850|       |        return false;
15851|       |      }
15852|       |    }
15853|       |  }
15854|       |#endif
15855|       |
15856|       |  // Handle Expect: 100-continue.
15857|       |  //
15858|       |  // Wait for an interim/early response by attempting to read the status line
15859|       |  // under a short timeout, instead of trusting raw socket readability. Over
15860|       |  // TLS, post-handshake records (e.g. session tickets) make the socket
15861|       |  // readable without any HTTP response being available; relying on
15862|       |  // `select_read` there caused the body to be withheld forever and the
15863|       |  // request to fail with `Read` (#2458). If no status line arrives within the
15864|       |  // timeout, send the body anyway (matching curl's behavior).
15865|  3.08k|  auto status_line_read = false;
15866|  3.08k|  if (expect_100_continue && write_request_success) {
  ------------------
  |  Branch (15866:7): [True: 0, False: 3.08k]
  |  Branch (15866:30): [True: 0, False: 0]
  ------------------
15867|      0|    if (CPPHTTPLIB_EXPECT_100_TIMEOUT_MSECOND > 0) {
  ------------------
  |  |   86|      0|#define CPPHTTPLIB_EXPECT_100_TIMEOUT_MSECOND 1000
  ------------------
  |  Branch (15867:9): [True: 0, Folded]
  ------------------
15868|      0|      time_t sec = CPPHTTPLIB_EXPECT_100_TIMEOUT_MSECOND / 1000;
  ------------------
  |  |   86|      0|#define CPPHTTPLIB_EXPECT_100_TIMEOUT_MSECOND 1000
  ------------------
15869|      0|      time_t usec = (CPPHTTPLIB_EXPECT_100_TIMEOUT_MSECOND % 1000) * 1000;
  ------------------
  |  |   86|      0|#define CPPHTTPLIB_EXPECT_100_TIMEOUT_MSECOND 1000
  ------------------
15870|      0|      strm.set_read_timeout(sec, usec);
15871|      0|      status_line_read = read_response_line(strm, req, res, false);
15872|      0|      strm.set_read_timeout(read_timeout_sec_, read_timeout_usec_);
15873|      0|    }
15874|       |
15875|      0|    if (!status_line_read) {
  ------------------
  |  Branch (15875:9): [True: 0, False: 0]
  ------------------
15876|       |      // No interim response within the timeout: send the body and handle the
15877|       |      // response as usual.
15878|      0|      if (!write_request_body(strm, req, error)) { return false; }
  ------------------
  |  Branch (15878:11): [True: 0, False: 0]
  ------------------
15879|      0|      expect_100_continue = false; // Switch to normal response handling
15880|      0|    }
15881|      0|  }
15882|       |
15883|       |  // Receive response and headers
15884|       |  // When using Expect: 100-continue, don't auto-skip `100 Continue` response
15885|  3.08k|  if ((!status_line_read &&
  ------------------
  |  Branch (15885:8): [True: 3.08k, False: 0]
  ------------------
15886|  3.08k|       !read_response_line(strm, req, res, !expect_100_continue)) ||
  ------------------
  |  Branch (15886:8): [True: 431, False: 2.65k]
  ------------------
15887|  2.65k|      !detail::read_headers(strm, res.headers)) {
  ------------------
  |  Branch (15887:7): [True: 848, False: 1.80k]
  ------------------
15888|  1.27k|    if (write_request_success) { error = Error::Read; }
  ------------------
  |  Branch (15888:9): [True: 1.27k, False: 0]
  ------------------
15889|  1.27k|    output_error_log(error, &req);
15890|  1.27k|    return false;
15891|  1.27k|  }
15892|       |
15893|  1.80k|  if (!write_request_success) { return false; }
  ------------------
  |  Branch (15893:7): [True: 0, False: 1.80k]
  ------------------
15894|       |
15895|       |  // Handle Expect: 100-continue response
15896|  1.80k|  if (expect_100_continue) {
  ------------------
  |  Branch (15896:7): [True: 0, False: 1.80k]
  ------------------
15897|      0|    if (res.status == StatusCode::Continue_100) {
  ------------------
  |  Branch (15897:9): [True: 0, False: 0]
  ------------------
15898|       |      // Server accepted, send the body
15899|      0|      if (!write_request_body(strm, req, error)) { return false; }
  ------------------
  |  Branch (15899:11): [True: 0, False: 0]
  ------------------
15900|       |
15901|       |      // Read the actual response
15902|      0|      res.headers.clear();
15903|      0|      res.body.clear();
15904|      0|      if (!read_response_line(strm, req, res) ||
  ------------------
  |  Branch (15904:11): [True: 0, False: 0]
  ------------------
15905|      0|          !detail::read_headers(strm, res.headers)) {
  ------------------
  |  Branch (15905:11): [True: 0, False: 0]
  ------------------
15906|      0|        error = Error::Read;
15907|      0|        output_error_log(error, &req);
15908|      0|        return false;
15909|      0|      }
15910|      0|    }
15911|       |    // If not 100 Continue, server returned an error; proceed with that response
15912|      0|  }
15913|       |
15914|       |  // Body
15915|  1.80k|  if ((res.status != StatusCode::NoContent_204) && req.method != "HEAD" &&
  ------------------
  |  Branch (15915:7): [True: 1.79k, False: 8]
  |  Branch (15915:52): [True: 1.79k, False: 0]
  ------------------
15916|  1.79k|      req.method != "CONNECT") {
  ------------------
  |  Branch (15916:7): [True: 1.79k, False: 0]
  ------------------
15917|  1.79k|    auto redirect = 300 < res.status && res.status < 400 &&
  ------------------
  |  Branch (15917:21): [True: 739, False: 1.05k]
  |  Branch (15917:41): [True: 252, False: 487]
  ------------------
15918|    252|                    res.status != StatusCode::NotModified_304 &&
  ------------------
  |  Branch (15918:21): [True: 236, False: 16]
  ------------------
15919|    236|                    follow_location_;
  ------------------
  |  Branch (15919:21): [True: 0, False: 236]
  ------------------
15920|       |
15921|  1.79k|    if (req.response_handler && !redirect) {
  ------------------
  |  Branch (15921:9): [True: 0, False: 1.79k]
  |  Branch (15921:33): [True: 0, False: 0]
  ------------------
15922|      0|      if (!req.response_handler(res)) {
  ------------------
  |  Branch (15922:11): [True: 0, False: 0]
  ------------------
15923|      0|        error = Error::Canceled;
15924|      0|        output_error_log(error, &req);
15925|      0|        return false;
15926|      0|      }
15927|      0|    }
15928|       |
15929|  1.79k|    auto out =
15930|  1.79k|        req.content_receiver
  ------------------
  |  Branch (15930:9): [True: 0, False: 1.79k]
  ------------------
15931|  1.79k|            ? static_cast<ContentReceiverWithProgress>(
15932|      0|                  [&](const char *buf, size_t n, size_t off, size_t len) {
15933|      0|                    if (redirect) { return true; }
15934|      0|                    auto ret = req.content_receiver(buf, n, off, len);
15935|      0|                    if (!ret) {
15936|      0|                      error = Error::Canceled;
15937|      0|                      output_error_log(error, &req);
15938|      0|                    }
15939|      0|                    return ret;
15940|      0|                  })
15941|  1.79k|            : static_cast<ContentReceiverWithProgress>(
15942|  1.79k|                  [&](const char *buf, size_t n, size_t /*off*/,
15943|  1.79k|                      size_t /*len*/) {
15944|  1.79k|                    assert(res.body.size() + n <= res.body.max_size());
15945|  1.79k|                    if (payload_max_length_ > 0 &&
15946|  1.79k|                        (res.body.size() >= payload_max_length_ ||
15947|  1.79k|                         n > payload_max_length_ - res.body.size())) {
15948|  1.79k|                      return false;
15949|  1.79k|                    }
15950|  1.79k|                    res.body.append(buf, n);
15951|  1.79k|                    return true;
15952|  1.79k|                  });
15953|       |
15954|  1.79k|    auto progress = [&](size_t current, size_t total) {
15955|  1.79k|      if (!req.download_progress || redirect) { return true; }
15956|  1.79k|      auto ret = req.download_progress(current, total);
15957|  1.79k|      if (!ret) {
15958|  1.79k|        error = Error::Canceled;
15959|  1.79k|        output_error_log(error, &req);
15960|  1.79k|      }
15961|  1.79k|      return ret;
15962|  1.79k|    };
15963|       |
15964|  1.79k|    if (res.has_header("Content-Length")) {
  ------------------
  |  Branch (15964:9): [True: 620, False: 1.17k]
  ------------------
15965|    620|      if (!req.content_receiver) {
  ------------------
  |  Branch (15965:11): [True: 620, False: 0]
  ------------------
15966|    620|        auto len = res.get_header_value_u64("Content-Length");
15967|    620|        if (len > res.body.max_size()) {
  ------------------
  |  Branch (15967:13): [True: 66, False: 554]
  ------------------
15968|     66|          error = Error::Read;
15969|     66|          output_error_log(error, &req);
15970|     66|          return false;
15971|     66|        }
15972|       |        // Cap the reservation by payload_max_length_ to avoid OOM when a
15973|       |        // hostile or malformed server sends an enormous Content-Length.
15974|       |        // The actual body read below is bounded by payload_max_length_,
15975|       |        // so reserving more than that is never useful.
15976|    554|        auto reserve_len = static_cast<size_t>(len);
15977|    554|        if (payload_max_length_ > 0 && reserve_len > payload_max_length_) {
  ------------------
  |  Branch (15977:13): [True: 554, False: 0]
  |  Branch (15977:40): [True: 320, False: 234]
  ------------------
15978|    320|          reserve_len = payload_max_length_;
15979|    320|        }
15980|    554|        res.body.reserve(reserve_len);
15981|    554|      }
15982|    620|    }
15983|       |
15984|  1.73k|    if (res.status != StatusCode::NotModified_304) {
  ------------------
  |  Branch (15984:9): [True: 1.71k, False: 16]
  ------------------
15985|  1.71k|      auto content_status = 0;
15986|  1.71k|      auto max_length = (!has_payload_max_length_ && req.content_receiver)
  ------------------
  |  Branch (15986:26): [True: 1.71k, False: 0]
  |  Branch (15986:54): [True: 0, False: 1.71k]
  ------------------
15987|  1.71k|                            ? (std::numeric_limits<size_t>::max)()
15988|  1.71k|                            : payload_max_length_;
15989|  1.71k|      if (!detail::read_content(strm, res, max_length, content_status,
  ------------------
  |  Branch (15989:11): [True: 1.26k, False: 452]
  ------------------
15990|  1.71k|                                std::move(progress), std::move(out),
15991|  1.71k|                                decompress_)) {
15992|  1.26k|        if (error != Error::Canceled) {
  ------------------
  |  Branch (15992:13): [True: 1.26k, False: 0]
  ------------------
15993|       |          // Tell the caller apart from a plain read failure when the body could
15994|       |          // not be decoded because of its Content-Encoding.
15995|  1.26k|          switch (content_status) {
15996|      2|          case StatusCode::UnsupportedMediaType_415:
  ------------------
  |  Branch (15996:11): [True: 2, False: 1.26k]
  ------------------
15997|      2|            error = Error::UnsupportedContentEncoding;
15998|      2|            break;
15999|      0|          case StatusCode::InternalServerError_500:
  ------------------
  |  Branch (15999:11): [True: 0, False: 1.26k]
  ------------------
16000|      0|            error = Error::Compression;
16001|      0|            break;
16002|  1.26k|          default: error = Error::Read; break;
  ------------------
  |  Branch (16002:11): [True: 1.26k, False: 2]
  ------------------
16003|  1.26k|          }
16004|  1.26k|        }
16005|  1.26k|        output_error_log(error, &req);
16006|  1.26k|        return false;
16007|  1.26k|      }
16008|  1.71k|    }
16009|  1.73k|  }
16010|       |
16011|       |  // Log
16012|    476|  output_log(req, res);
16013|       |
16014|    476|  return true;
16015|  1.80k|}
_ZNK7httplib7Request10has_headerERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
11288|  18.5k|inline bool Request::has_header(const std::string &key) const {
11289|  18.5k|  return detail::has_header(headers, key);
11290|  18.5k|}
_ZN7httplib6detail10has_headerERKNS0_26insertion_ordered_multimapINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS0_11case_ignore8equal_toEEERKS8_:
 7909|  19.5k|inline bool has_header(const Headers &headers, const std::string &key) {
 7910|  19.5k|  if (is_prohibited_header_name(key)) { return false; }
  ------------------
  |  Branch (7910:7): [True: 0, False: 19.5k]
  ------------------
 7911|  19.5k|  return headers.find(key) != headers.end();
 7912|  19.5k|}
_ZN7httplib6detail25is_prohibited_header_nameERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
 7897|  19.5k|inline bool is_prohibited_header_name(const std::string &name) {
 7898|  19.5k|  using udl::operator""_t;
 7899|       |
 7900|  19.5k|  switch (str2tag(name)) {
 7901|      0|  case "REMOTE_ADDR"_t:
  ------------------
  |  Branch (7901:3): [True: 0, False: 19.5k]
  ------------------
 7902|      0|  case "REMOTE_PORT"_t:
  ------------------
  |  Branch (7902:3): [True: 0, False: 19.5k]
  ------------------
 7903|      0|  case "LOCAL_ADDR"_t:
  ------------------
  |  Branch (7903:3): [True: 0, False: 19.5k]
  ------------------
 7904|      0|  case "LOCAL_PORT"_t: return true;
  ------------------
  |  Branch (7904:3): [True: 0, False: 19.5k]
  ------------------
 7905|  19.5k|  default: return false;
  ------------------
  |  Branch (7905:3): [True: 19.5k, False: 0]
  ------------------
 7906|  19.5k|  }
 7907|  19.5k|}
_ZN7httplib6detail7str2tagERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
 7294|  19.5k|inline unsigned int str2tag(const std::string &s) {
 7295|       |  // Iterative form of str2tag_core: the recursive constexpr version is kept
 7296|       |  // for compile-time UDL evaluation of short string literals, but at runtime
 7297|       |  // we may receive arbitrarily long inputs (e.g. fuzzed Content-Type) that
 7298|       |  // would blow the stack with one frame per character.
 7299|  19.5k|  unsigned int h = 0;
 7300|   177k|  for (auto c : s) {
  ------------------
  |  Branch (7300:15): [True: 177k, False: 19.5k]
  ------------------
 7301|   177k|    h = (((std::numeric_limits<unsigned int>::max)() >> 6) & h * 33) ^
 7302|   177k|        static_cast<unsigned char>(c);
 7303|   177k|  }
 7304|  19.5k|  return h;
 7305|  19.5k|}
_ZNK7httplib6detail26insertion_ordered_multimapINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS0_11case_ignore8equal_toEE4findERKS8_:
 1178|  21.3k|  const_iterator find(const std::string &key) const {
 1179|  21.3k|    auto i = index_of(key);
 1180|  21.3k|    return i == npos() ? end() : make_citer(i, i);
  ------------------
  |  Branch (1180:12): [True: 20.1k, False: 1.15k]
  ------------------
 1181|  21.3k|  }
_ZNK7httplib6detail26insertion_ordered_multimapINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS0_11case_ignore8equal_toEE8index_ofERKS8_:
 1263|  31.1k|  size_type index_of(const std::string &key) const {
 1264|  74.6k|    for (size_type i = 0; i < entries_.size(); i++) {
  ------------------
  |  Branch (1264:27): [True: 47.7k, False: 26.8k]
  ------------------
 1265|  47.7k|      if (keys_equal(entries_[i].first, key)) { return i; }
  ------------------
  |  Branch (1265:11): [True: 4.23k, False: 43.5k]
  ------------------
 1266|  47.7k|    }
 1267|  26.8k|    return npos();
 1268|  31.1k|  }
_ZN7httplib7Request10set_headerERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEES9_:
11302|  8.04k|                                const std::string &val) {
11303|  8.04k|  detail::set_header(headers, key, val);
11304|  8.04k|}
_ZN7httplib6detail10set_headerERNS0_26insertion_ordered_multimapINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS0_11case_ignore8equal_toEEERKS8_SE_:
 7988|  8.04k|                       const std::string &val) {
 7989|  8.04k|  if (fields::is_field_valid(key, val)) { headers.emplace(key, val); }
  ------------------
  |  Branch (7989:7): [True: 8.04k, False: 0]
  ------------------
 7990|  8.04k|}
_ZN7httplib6detail26insertion_ordered_multimapINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS0_11case_ignore8equal_toEE7emplaceIJRKS8_SE_EEENSB_10iterator_tINS2_4pairIS8_S8_EEEEDpOT_:
 1161|  18.3k|  template <typename... Args> iterator emplace(Args &&...args) {
 1162|  18.3k|    entries_.emplace_back(std::forward<Args>(args)...);
 1163|  18.3k|    return make_iter(entries_.size() - 1, npos());
 1164|  18.3k|  }
_ZN7httplib6detail26insertion_ordered_multimapINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS0_11case_ignore8equal_toEE9make_iterEmm:
 1270|  40.7k|  iterator make_iter(size_type idx, size_type key_idx) {
 1271|  40.7k|    return iterator(entries_.data(), idx, entries_.size(), key_idx);
 1272|  40.7k|  }
_ZN7httplib6detail26insertion_ordered_multimapINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS0_11case_ignore8equal_toEE10iterator_tINS2_4pairIS8_S8_EEEC2EPSE_mmm:
 1116|  40.7k|        : data_(data), idx_(idx), size_(size), key_idx_(key_idx) {}
_ZN7httplib6detail16has_header_tokenERKNS0_26insertion_ordered_multimapINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS0_11case_ignore8equal_toEEERKS8_SF_:
 7959|  3.08k|                             const std::string &token) {
 7960|       |  // RFC 9110 7.6.1: a comma-separated token list field such as Connection may
 7961|       |  // carry several tokens, and RFC 9110 5.3 lets that list be split across
 7962|       |  // several lines. Match complete tokens rather than searching the raw value,
 7963|       |  // so that a value such as "notupgrade" is not read as the token "upgrade".
 7964|  3.08k|  auto rng = headers.equal_range(key);
 7965|  3.08k|  for (auto it = rng.first; it != rng.second; ++it) {
  ------------------
  |  Branch (7965:29): [True: 0, False: 3.08k]
  ------------------
 7966|      0|    const auto &value = it->second;
 7967|      0|    if (split_find(value.data(), value.data() + value.size(), ',',
  ------------------
  |  Branch (7967:9): [True: 0, False: 0]
  ------------------
 7968|      0|                   [&](const char *b, const char *e) {
 7969|      0|                     return case_ignore::equal(std::string(b, e), token);
 7970|      0|                   })) {
 7971|      0|      return true;
 7972|      0|    }
 7973|      0|  }
 7974|  3.08k|  return false;
 7975|  3.08k|}
_ZNK7httplib6detail26insertion_ordered_multimapINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS0_11case_ignore8equal_toEE11equal_rangeERKS8_:
 1198|  7.82k|  equal_range(const std::string &key) const {
 1199|  7.82k|    auto i = index_of(key);
 1200|  7.82k|    return i == npos() ? std::make_pair(end(), end())
  ------------------
  |  Branch (1200:12): [True: 5.54k, False: 2.28k]
  ------------------
 1201|  7.82k|                       : std::make_pair(make_citer(i, i), end());
 1202|  7.82k|  }
_ZNK7httplib6detail26insertion_ordered_multimapINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS0_11case_ignore8equal_toEE10iterator_tIKNS2_4pairIS8_S8_EEEptEv:
 1064|  5.53k|    pointer operator->() const { return data_ + idx_; }
_ZN7httplib6detail4trimEPKcS2_mm:
 5857|  13.1k|                                      size_t right) {
 5858|  21.4k|  while (b + left < e && is_space_or_tab(b[left])) {
  ------------------
  |  Branch (5858:10): [True: 21.3k, False: 105]
  |  Branch (5858:26): [True: 8.27k, False: 13.0k]
  ------------------
 5859|  8.27k|    left++;
 5860|  8.27k|  }
 5861|  21.4k|  while (right > 0 && is_space_or_tab(b[right - 1])) {
  ------------------
  |  Branch (5861:10): [True: 21.3k, False: 129]
  |  Branch (5861:23): [True: 8.28k, False: 13.0k]
  ------------------
 5862|  8.28k|    right--;
 5863|  8.28k|  }
 5864|  13.1k|  return std::make_pair(left, right);
 5865|  13.1k|}
_ZN7httplib6detail15is_space_or_tabEc:
 5720|  68.4k|inline bool is_space_or_tab(char c) { return c == ' ' || c == '\t'; }
  ------------------
  |  Branch (5720:46): [True: 17.3k, False: 51.0k]
  |  Branch (5720:58): [True: 983, False: 50.0k]
  ------------------
_ZN7httplib10ClientImpl13write_requestERNS_6StreamERNS_7RequestEbRNS_5ErrorEb:
15474|  3.08k|                                      bool skip_body) {
15475|       |  // Prepare additional headers
15476|  3.08k|  if (close_connection) {
  ------------------
  |  Branch (15476:7): [True: 0, False: 3.08k]
  ------------------
15477|      0|    if (!req.has_header("Connection")) {
  ------------------
  |  Branch (15477:9): [True: 0, False: 0]
  ------------------
15478|      0|      req.set_header("Connection", "close");
15479|      0|    }
15480|      0|  }
15481|       |
15482|  3.08k|  std::string ct_for_defaults;
15483|  3.08k|  if (!req.has_header("Content-Type") && !req.body.empty()) {
  ------------------
  |  Branch (15483:7): [True: 3.08k, False: 0]
  |  Branch (15483:7): [True: 0, False: 3.08k]
  |  Branch (15483:42): [True: 0, False: 3.08k]
  ------------------
15484|      0|    ct_for_defaults = "text/plain";
15485|      0|  }
15486|  3.08k|  prepare_default_headers(req, false, ct_for_defaults);
15487|       |
15488|  3.08k|  if (req.body.empty()) {
  ------------------
  |  Branch (15488:7): [True: 3.08k, False: 0]
  ------------------
15489|  3.08k|    if (req.content_provider_) {
  ------------------
  |  Branch (15489:9): [True: 0, False: 3.08k]
  ------------------
15490|      0|      if (!req.is_chunked_content_provider_) {
  ------------------
  |  Branch (15490:11): [True: 0, False: 0]
  ------------------
15491|      0|        if (!req.has_header("Content-Length")) {
  ------------------
  |  Branch (15491:13): [True: 0, False: 0]
  ------------------
15492|      0|          auto length = std::to_string(req.content_length_);
15493|      0|          req.set_header("Content-Length", length);
15494|      0|        }
15495|      0|      }
15496|  3.08k|    } else {
15497|  3.08k|      if (req.method == "POST" || req.method == "PUT" ||
  ------------------
  |  Branch (15497:11): [True: 639, False: 2.44k]
  |  Branch (15497:35): [True: 951, False: 1.49k]
  ------------------
15498|  1.87k|          req.method == "PATCH") {
  ------------------
  |  Branch (15498:11): [True: 284, False: 1.21k]
  ------------------
15499|  1.87k|        req.set_header("Content-Length", "0");
15500|  1.87k|      }
15501|  3.08k|    }
15502|  3.08k|  }
15503|       |
15504|  3.08k|  if (!basic_auth_password_.empty() || !basic_auth_username_.empty()) {
  ------------------
  |  Branch (15504:7): [True: 0, False: 3.08k]
  |  Branch (15504:40): [True: 0, False: 3.08k]
  ------------------
15505|      0|    if (!req.has_header("Authorization")) {
  ------------------
  |  Branch (15505:9): [True: 0, False: 0]
  ------------------
15506|      0|      req.headers.insert(make_basic_authentication_header(
15507|      0|          basic_auth_username_, basic_auth_password_, false));
15508|      0|    }
15509|      0|  }
15510|       |
15511|  3.08k|  if (!bearer_token_auth_token_.empty()) {
  ------------------
  |  Branch (15511:7): [True: 0, False: 3.08k]
  ------------------
15512|      0|    if (!req.has_header("Authorization")) {
  ------------------
  |  Branch (15512:9): [True: 0, False: 0]
  ------------------
15513|      0|      req.headers.insert(make_bearer_token_authentication_header(
15514|      0|          bearer_token_auth_token_, false));
15515|      0|    }
15516|      0|  }
15517|       |
15518|       |  // Proxy-Authorization is only sent when the proxy is actually used for
15519|       |  // this target — otherwise NO_PROXY-matched requests would leak proxy
15520|       |  // credentials directly to the destination server.
15521|  3.08k|  if (is_proxy_enabled_for_host(host_)) {
  ------------------
  |  Branch (15521:7): [True: 0, False: 3.08k]
  ------------------
15522|      0|    if (!proxy_basic_auth_username_.empty() &&
  ------------------
  |  Branch (15522:9): [True: 0, False: 0]
  |  Branch (15522:9): [True: 0, False: 0]
  ------------------
15523|      0|        !proxy_basic_auth_password_.empty() &&
  ------------------
  |  Branch (15523:9): [True: 0, False: 0]
  ------------------
15524|      0|        !req.has_header("Proxy-Authorization")) {
  ------------------
  |  Branch (15524:9): [True: 0, False: 0]
  ------------------
15525|      0|      req.headers.insert(make_basic_authentication_header(
15526|      0|          proxy_basic_auth_username_, proxy_basic_auth_password_, true));
15527|      0|    }
15528|      0|    if (!proxy_bearer_token_auth_token_.empty() &&
  ------------------
  |  Branch (15528:9): [True: 0, False: 0]
  |  Branch (15528:9): [True: 0, False: 0]
  ------------------
15529|      0|        !req.has_header("Proxy-Authorization")) {
  ------------------
  |  Branch (15529:9): [True: 0, False: 0]
  ------------------
15530|      0|      req.headers.insert(make_bearer_token_authentication_header(
15531|      0|          proxy_bearer_token_auth_token_, true));
15532|      0|    }
15533|      0|  }
15534|       |
15535|       |  // Request line and headers
15536|  3.08k|  {
15537|  3.08k|    detail::BufferStream bstrm;
15538|       |
15539|       |    // Extract the query from req.path. The encoding itself is delegated to
15540|       |    // `encode_request_target`; the raw query is still needed here to decide
15541|       |    // between populating `req.params` from it and falling back to building a
15542|       |    // query out of caller-supplied `req.params`.
15543|  3.08k|    auto query_pos = req.path.find('?');
15544|  3.08k|    auto query_part = query_pos == std::string::npos
  ------------------
  |  Branch (15544:23): [True: 3.08k, False: 0]
  ------------------
15545|  3.08k|                          ? std::string()
15546|  3.08k|                          : req.path.substr(query_pos + 1);
15547|       |
15548|  3.08k|    auto path_with_query =
15549|  3.08k|        detail::encode_request_target(req.path, path_encode_);
15550|       |
15551|  3.08k|    if (!query_part.empty()) {
  ------------------
  |  Branch (15551:9): [True: 0, False: 3.08k]
  ------------------
15552|       |      // The query already came in through `req.path`; still populate
15553|       |      // `req.params` for handlers/users who read them.
15554|      0|      detail::parse_query_text(query_part, req.params);
15555|  3.08k|    } else if (!req.params.empty()) {
  ------------------
  |  Branch (15555:16): [True: 0, False: 3.08k]
  ------------------
15556|       |      // No query in `req.path`; build one from `req.params` so existing
15557|       |      // callers that pass `Params` separately continue to work.
15558|      0|      path_with_query = append_query_params(path_with_query, req.params);
15559|      0|    }
15560|       |
15561|       |    // Write request line and headers
15562|  3.08k|    if (detail::write_request_line(bstrm, req.method, path_with_query) < 0) {
  ------------------
  |  Branch (15562:9): [True: 0, False: 3.08k]
  ------------------
15563|       |      // A rejected target (e.g. CR/LF smuggled in via a decoded redirect
15564|       |      // Location under set_path_encode(false)) must fail the request cleanly
15565|       |      // instead of emitting a request-line-less, header-injecting request.
15566|      0|      error = Error::Write;
15567|      0|      output_error_log(error, &req);
15568|      0|      return false;
15569|      0|    }
15570|  3.08k|    if (!detail::check_and_write_headers(bstrm, req.headers, header_writer_,
  ------------------
  |  Branch (15570:9): [True: 0, False: 3.08k]
  ------------------
15571|  3.08k|                                         error)) {
15572|      0|      output_error_log(error, &req);
15573|      0|      return false;
15574|      0|    }
15575|       |
15576|       |    // Flush buffer
15577|  3.08k|    auto &data = bstrm.get_buffer();
15578|  3.08k|    if (!detail::write_data(strm, data.data(), data.size())) {
  ------------------
  |  Branch (15578:9): [True: 0, False: 3.08k]
  ------------------
15579|      0|      error = Error::Write;
15580|      0|      output_error_log(error, &req);
15581|      0|      return false;
15582|      0|    }
15583|  3.08k|  }
15584|       |
15585|       |  // After sending request line and headers, wait briefly for an early server
15586|       |  // response (e.g. 4xx) and avoid sending a potentially large request body
15587|       |  // unnecessarily. This workaround is only enabled on Windows because Unix
15588|       |  // platforms surface write errors (EPIPE) earlier; on Windows kernel send
15589|       |  // buffering can accept large writes even when the peer already responded.
15590|       |  // Check the stream first (which covers SSL via `is_readable()`), then
15591|       |  // fall back to select on the socket. Only perform the wait for very large
15592|       |  // request bodies to avoid interfering with normal small requests and
15593|       |  // reduce side-effects. Poll briefly (up to 50ms as default) for an early
15594|       |  // response. Skip this check when using Expect: 100-continue, as the protocol
15595|       |  // handles early responses properly.
15596|       |#if defined(_WIN32)
15597|       |  if (!skip_body &&
15598|       |      req.body.size() > CPPHTTPLIB_WAIT_EARLY_SERVER_RESPONSE_THRESHOLD &&
15599|       |      req.path.size() > CPPHTTPLIB_REQUEST_URI_MAX_LENGTH) {
15600|       |    auto start = std::chrono::high_resolution_clock::now();
15601|       |
15602|       |    for (;;) {
15603|       |      // Prefer socket-level readiness to avoid SSL_pending() false-positives
15604|       |      // from SSL internals. If the underlying socket is readable, assume an
15605|       |      // early response may be present.
15606|       |      auto sock = strm.socket();
15607|       |      if (sock != INVALID_SOCKET && detail::select_read(sock, 0, 0) > 0) {
15608|       |        return false;
15609|       |      }
15610|       |
15611|       |      // Fallback to stream-level check for non-socket streams or when the
15612|       |      // socket isn't reporting readable. Avoid using `is_readable()` for
15613|       |      // SSL, since `SSL_pending()` may report buffered records that do not
15614|       |      // indicate a complete application-level response yet.
15615|       |      if (!is_ssl() && strm.is_readable()) { return false; }
15616|       |
15617|       |      auto now = std::chrono::high_resolution_clock::now();
15618|       |      auto elapsed =
15619|       |          std::chrono::duration_cast<std::chrono::milliseconds>(now - start)
15620|       |              .count();
15621|       |      if (elapsed >= CPPHTTPLIB_WAIT_EARLY_SERVER_RESPONSE_TIMEOUT_MSECOND) {
15622|       |        break;
15623|       |      }
15624|       |
15625|       |      std::this_thread::sleep_for(std::chrono::milliseconds(1));
15626|       |    }
15627|       |  }
15628|       |#endif
15629|       |
15630|       |  // Body
15631|  3.08k|  if (skip_body) { return true; }
  ------------------
  |  Branch (15631:7): [True: 0, False: 3.08k]
  ------------------
15632|       |
15633|  3.08k|  return write_request_body(strm, req, error);
15634|  3.08k|}
_ZN7httplib10ClientImpl23prepare_default_headersERNS_7RequestEbRKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEE:
14820|  3.08k|                                                const std::string &ct) {
14821|  3.08k|  (void)for_stream;
14822|  3.08k|  for (const auto &header : default_headers_) {
  ------------------
  |  Branch (14822:27): [True: 0, False: 3.08k]
  ------------------
14823|      0|    if (!r.has_header(header.first)) { r.headers.insert(header); }
  ------------------
  |  Branch (14823:9): [True: 0, False: 0]
  ------------------
14824|      0|  }
14825|       |
14826|       |  // RFC 9110 5.3 recommends sending control data such as Host first, so
14827|       |  // prepend it rather than appending it after the caller's own fields.
14828|  3.08k|  if (!r.has_header("Host")) {
  ------------------
  |  Branch (14828:7): [True: 3.08k, False: 0]
  ------------------
14829|  3.08k|    r.headers.emplace_front(
14830|  3.08k|        "Host", detail::make_default_host_header_value(host_, port_, is_ssl(),
14831|  3.08k|                                                       address_family_));
14832|  3.08k|  }
14833|       |
14834|  3.08k|  if (!r.has_header("Accept")) { r.headers.emplace("Accept", "*/*"); }
  ------------------
  |  Branch (14834:7): [True: 3.08k, False: 0]
  ------------------
14835|       |
14836|  3.08k|  if (!r.content_receiver) {
  ------------------
  |  Branch (14836:7): [True: 3.08k, False: 0]
  ------------------
14837|  3.08k|    if (!r.has_header("Accept-Encoding")) {
  ------------------
  |  Branch (14837:9): [True: 3.08k, False: 0]
  ------------------
14838|  3.08k|      std::string accept_encoding;
14839|       |#ifdef CPPHTTPLIB_BROTLI_SUPPORT
14840|       |      accept_encoding = "br";
14841|       |#endif
14842|  3.08k|#ifdef CPPHTTPLIB_ZLIB_SUPPORT
14843|  3.08k|      if (!accept_encoding.empty()) { accept_encoding += ", "; }
  ------------------
  |  Branch (14843:11): [True: 0, False: 3.08k]
  ------------------
14844|  3.08k|      accept_encoding += "gzip, deflate";
14845|  3.08k|#endif
14846|       |#ifdef CPPHTTPLIB_ZSTD_SUPPORT
14847|       |      if (!accept_encoding.empty()) { accept_encoding += ", "; }
14848|       |      accept_encoding += "zstd";
14849|       |#endif
14850|  3.08k|      r.set_header("Accept-Encoding", accept_encoding);
14851|  3.08k|    }
14852|       |
14853|  3.08k|    detail::add_default_user_agent_header(r);
14854|  3.08k|  }
14855|       |
14856|  3.08k|  if (!r.body.empty()) {
  ------------------
  |  Branch (14856:7): [True: 0, False: 3.08k]
  ------------------
14857|      0|    if (!ct.empty() && !r.has_header("Content-Type")) {
  ------------------
  |  Branch (14857:9): [True: 0, False: 0]
  |  Branch (14857:9): [True: 0, False: 0]
  |  Branch (14857:24): [True: 0, False: 0]
  ------------------
14858|      0|      r.headers.emplace("Content-Type", ct);
14859|      0|    }
14860|      0|    if (!r.has_header("Content-Length")) {
  ------------------
  |  Branch (14860:9): [True: 0, False: 0]
  ------------------
14861|      0|      r.headers.emplace("Content-Length", std::to_string(r.body.size()));
14862|      0|    }
14863|      0|  }
14864|  3.08k|}
_ZN7httplib6detail26insertion_ordered_multimapINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS0_11case_ignore8equal_toEE5beginEv:
 1139|  6.16k|  iterator begin() { return make_iter(0, npos()); }
_ZN7httplib6detail26insertion_ordered_multimapINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS0_11case_ignore8equal_toEE3endEv:
 1140|  9.33k|  iterator end() { return make_iter(entries_.size(), npos()); }
_ZNK7httplib6detail26insertion_ordered_multimapINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS0_11case_ignore8equal_toEE10iterator_tINS2_4pairIS8_S8_EEEneISE_EEbRKNSC_IT_EE:
 1107|  23.7k|    template <typename U> bool operator!=(const iterator_t<U> &rhs) const {
 1108|  23.7k|      return idx_ != rhs.idx_;
 1109|  23.7k|    }
_ZNK7httplib6detail26insertion_ordered_multimapINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS0_11case_ignore8equal_toEE10iterator_tINS2_4pairIS8_S8_EEEdeEv:
 1063|  14.2k|    reference operator*() const { return data_[idx_]; }
_ZN7httplib6detail26insertion_ordered_multimapINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS0_11case_ignore8equal_toEE10iterator_tINS2_4pairIS8_S8_EEEppEv:
 1066|  15.6k|    iterator_t &operator++() {
 1067|       |      // Saturating, so that advancing past the last entry of a key (which
 1068|       |      // get_multimap_value() does when asked for an out-of-range id) stays at
 1069|       |      // end() instead of running off the container.
 1070|  15.6k|      if (idx_ >= size_) { return *this; }
  ------------------
  |  Branch (1070:11): [True: 0, False: 15.6k]
  ------------------
 1071|  15.6k|      ++idx_;
 1072|  15.6k|      if (key_idx_ != npos()) {
  ------------------
  |  Branch (1072:11): [True: 1.39k, False: 14.2k]
  ------------------
 1073|  2.22k|        while (idx_ < size_ && !matches(idx_)) {
  ------------------
  |  Branch (1073:16): [True: 1.60k, False: 621]
  |  Branch (1073:32): [True: 831, False: 774]
  ------------------
 1074|    831|          ++idx_;
 1075|    831|        }
 1076|  1.39k|      }
 1077|  15.6k|      return *this;
 1078|  15.6k|    }
_ZNK7httplib6detail26insertion_ordered_multimapINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS0_11case_ignore8equal_toEE10iterator_tINS2_4pairIS8_S8_EEE7matchesEm:
 1118|  1.60k|    bool matches(size_type i) const {
 1119|  1.60k|      return keys_equal(data_[i].first, data_[key_idx_].first);
 1120|  1.60k|    }
_ZN7httplib6detail26insertion_ordered_multimapINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS0_11case_ignore8equal_toEE13emplace_frontIJRA5_KcS8_EEENSB_10iterator_tINS2_4pairIS8_S8_EEEEDpOT_:
 1168|  3.08k|  template <typename... Args> iterator emplace_front(Args &&...args) {
 1169|  3.08k|    entries_.emplace(entries_.begin(), std::forward<Args>(args)...);
 1170|  3.08k|    return make_iter(0, npos());
 1171|  3.08k|  }
_ZN7httplib6detail30make_default_host_header_valueERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEibi:
12159|  3.08k|                                                  int address_family) {
12160|  3.08k|  if (address_family == AF_UNIX) { return "localhost"; }
  ------------------
  |  Branch (12160:7): [True: 0, False: 3.08k]
  ------------------
12161|  3.08k|  return make_host_and_port_string(host, port, is_ssl);
12162|  3.08k|}
_ZN7httplib6detail25make_host_and_port_stringERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEib:
12136|  3.08k|                                             bool is_ssl) {
12137|  3.08k|  auto result = prepare_host_string(host);
12138|       |
12139|       |  // Append port if not default
12140|  3.08k|  if ((!is_ssl && port == 80) || (is_ssl && port == 443)) {
  ------------------
  |  Branch (12140:8): [True: 3.08k, False: 0]
  |  Branch (12140:19): [True: 0, False: 3.08k]
  |  Branch (12140:35): [True: 0, False: 3.08k]
  |  Branch (12140:45): [True: 0, False: 0]
  ------------------
12141|      0|    ; // do nothing
12142|  3.08k|  } else {
12143|  3.08k|    result += ":" + std::to_string(port);
12144|  3.08k|  }
12145|       |
12146|  3.08k|  return result;
12147|  3.08k|}
_ZN7httplib6detail19prepare_host_stringERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
12123|  3.08k|inline std::string prepare_host_string(const std::string &host) {
12124|       |  // Enclose IPv6 address in brackets (but not if already enclosed)
12125|  3.08k|  if (host.find(':') == std::string::npos ||
  ------------------
  |  Branch (12125:7): [True: 3.08k, False: 0]
  ------------------
12126|  3.08k|      (!host.empty() && host[0] == '[')) {
  ------------------
  |  Branch (12126:8): [True: 0, False: 0]
  |  Branch (12126:25): [True: 0, False: 0]
  ------------------
12127|       |    // IPv4, hostname, or already bracketed IPv6
12128|  3.08k|    return host;
12129|  3.08k|  } else {
12130|       |    // IPv6 address without brackets
12131|      0|    return "[" + host + "]";
12132|      0|  }
12133|  3.08k|}
_ZN7httplib6detail26insertion_ordered_multimapINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS0_11case_ignore8equal_toEE7emplaceIJRA7_KcRA4_SD_EEENSB_10iterator_tINS2_4pairIS8_S8_EEEEDpOT_:
 1161|  3.08k|  template <typename... Args> iterator emplace(Args &&...args) {
 1162|  3.08k|    entries_.emplace_back(std::forward<Args>(args)...);
 1163|  3.08k|    return make_iter(entries_.size() - 1, npos());
 1164|  3.08k|  }
_ZN7httplib6detail29add_default_user_agent_headerERNS_7RequestE:
12164|  3.08k|inline void add_default_user_agent_header(Request &req) {
12165|  3.08k|#ifndef CPPHTTPLIB_NO_DEFAULT_USER_AGENT
12166|  3.08k|  if (!req.has_header("User-Agent")) {
  ------------------
  |  Branch (12166:7): [True: 3.08k, False: 0]
  ------------------
12167|  3.08k|    req.set_header("User-Agent",
12168|  3.08k|                   std::string("cpp-httplib/") + CPPHTTPLIB_VERSION);
  ------------------
  |  |   11|  3.08k|#define CPPHTTPLIB_VERSION "0.53.1"
  ------------------
12169|  3.08k|  }
12170|       |#else
12171|       |  (void)req;
12172|       |#endif
12173|  3.08k|}
_ZNK7httplib10ClientImpl25is_proxy_enabled_for_hostERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
14576|  3.08k|ClientImpl::is_proxy_enabled_for_host(const std::string &host) const {
14577|  3.08k|  if (proxy_host_.empty() || proxy_port_ == -1) { return false; }
  ------------------
  |  Branch (14577:7): [True: 3.08k, False: 0]
  |  Branch (14577:30): [True: 0, False: 0]
  ------------------
14578|      0|  if (no_proxy_entries_.empty()) { return true; }
  ------------------
  |  Branch (14578:7): [True: 0, False: 0]
  ------------------
14579|       |  // host_ is const so its normalized form is invariant; cache it. The
14580|       |  // cross-host path (setup_redirect_client passing next_host) re-normalizes.
14581|      0|  if (host == host_) {
  ------------------
  |  Branch (14581:7): [True: 0, False: 0]
  ------------------
14582|      0|    if (!host_normalized_valid_) {
  ------------------
  |  Branch (14582:9): [True: 0, False: 0]
  ------------------
14583|      0|      host_normalized_ = detail::normalize_target(host_);
14584|      0|      host_normalized_valid_ = true;
14585|      0|    }
14586|      0|    return !detail::host_matches_no_proxy(host_normalized_, no_proxy_entries_);
14587|      0|  }
14588|      0|  auto target = detail::normalize_target(host);
14589|      0|  return !detail::host_matches_no_proxy(target, no_proxy_entries_);
14590|      0|}
_ZN7httplib6detail12BufferStreamC2Ev:
 3670|  3.08k|  BufferStream() = default;
_ZN7httplib6detail21encode_request_targetERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEb:
 8861|  3.08k|                                         bool path_encode) {
 8862|       |  // `substr(0, npos)` yields the whole string, which is what the no-query
 8863|       |  // case needs.
 8864|  3.08k|  auto query_pos = target.find('?');
 8865|  3.08k|  auto path_part = target.substr(0, query_pos);
 8866|  3.08k|  std::string query_part;
 8867|  3.08k|  if (query_pos != std::string::npos) {
  ------------------
  |  Branch (8867:7): [True: 0, False: 3.08k]
  ------------------
 8868|      0|    query_part = target.substr(query_pos + 1);
 8869|      0|  }
 8870|       |
 8871|  3.08k|  auto result = path_encode ? encode_path(path_part) : std::move(path_part);
  ------------------
  |  Branch (8871:17): [True: 3.08k, False: 0]
  ------------------
 8872|       |
 8873|  3.08k|  if (!query_part.empty()) {
  ------------------
  |  Branch (8873:7): [True: 0, False: 3.08k]
  ------------------
 8874|       |    // When path encoding is disabled the caller has supplied an already-encoded
 8875|       |    // target and expects the exact bytes to be sent on the wire, so skip
 8876|       |    // normalization for the query too. Normalizing would decode-then-re-encode
 8877|       |    // it and corrupt pre-encoded binary payloads (e.g. turning `%20` into `+`,
 8878|       |    // which a strict RFC 3986 server decodes back as `+`, not a space).
 8879|      0|    if (path_encode) {
  ------------------
  |  Branch (8879:9): [True: 0, False: 0]
  ------------------
 8880|      0|      auto normalized = normalize_query_string(query_part);
 8881|      0|      if (!normalized.empty()) {
  ------------------
  |  Branch (8881:11): [True: 0, False: 0]
  ------------------
 8882|      0|        result += '?';
 8883|      0|        result += normalized;
 8884|      0|      }
 8885|      0|    } else {
 8886|      0|      result += '?';
 8887|      0|      result += query_part;
 8888|      0|    }
 8889|      0|  }
 8890|       |
 8891|  3.08k|  return result;
 8892|  3.08k|}
_ZN7httplib6detail11encode_pathERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
 5681|  3.08k|inline std::string encode_path(const std::string &s) {
 5682|  3.08k|  std::string result;
 5683|  3.08k|  result.reserve(s.size());
 5684|       |
 5685|  6.16k|  for (size_t i = 0; s[i]; i++) {
  ------------------
  |  Branch (5685:22): [True: 3.08k, False: 3.08k]
  ------------------
 5686|  3.08k|    switch (s[i]) {
 5687|      0|    case ' ': result += "%20"; break;
  ------------------
  |  Branch (5687:5): [True: 0, False: 3.08k]
  ------------------
 5688|      0|    case '+': result += "%2B"; break;
  ------------------
  |  Branch (5688:5): [True: 0, False: 3.08k]
  ------------------
 5689|      0|    case '\r': result += "%0D"; break;
  ------------------
  |  Branch (5689:5): [True: 0, False: 3.08k]
  ------------------
 5690|      0|    case '\n': result += "%0A"; break;
  ------------------
  |  Branch (5690:5): [True: 0, False: 3.08k]
  ------------------
 5691|      0|    case '\'': result += "%27"; break;
  ------------------
  |  Branch (5691:5): [True: 0, False: 3.08k]
  ------------------
 5692|      0|    case ',': result += "%2C"; break;
  ------------------
  |  Branch (5692:5): [True: 0, False: 3.08k]
  ------------------
 5693|       |    // case ':': result += "%3A"; break; // ok? probably...
 5694|      0|    case ';': result += "%3B"; break;
  ------------------
  |  Branch (5694:5): [True: 0, False: 3.08k]
  ------------------
 5695|  3.08k|    default:
  ------------------
  |  Branch (5695:5): [True: 3.08k, False: 0]
  ------------------
 5696|  3.08k|      auto c = static_cast<uint8_t>(s[i]);
 5697|  3.08k|      if (c >= 0x80) {
  ------------------
  |  Branch (5697:11): [True: 0, False: 3.08k]
  ------------------
 5698|      0|        result += '%';
 5699|      0|        char hex[4];
 5700|      0|        auto len = snprintf(hex, sizeof(hex) - 1, "%02X", c);
 5701|      0|        assert(len == 2);
  ------------------
  |  Branch (5701:9): [True: 0, False: 0]
  ------------------
 5702|      0|        result.append(hex, static_cast<size_t>(len));
 5703|  3.08k|      } else {
 5704|  3.08k|        result += s[i];
 5705|  3.08k|      }
 5706|  3.08k|      break;
 5707|  3.08k|    }
 5708|  3.08k|  }
 5709|       |
 5710|  3.08k|  return result;
 5711|  3.08k|}
_ZN7httplib6detail5splitEPKcS2_cNSt3__18functionIFvS2_S2_EEE:
 5901|  1.37k|                  std::function<void(const char *, const char *)> fn) {
 5902|  1.37k|  return split(b, e, d, (std::numeric_limits<size_t>::max)(), std::move(fn));
 5903|  1.37k|}
_ZN7httplib6detail5splitEPKcS2_cmNSt3__18functionIFvS2_S2_EEE:
 5906|  1.37k|                  std::function<void(const char *, const char *)> fn) {
 5907|  1.37k|  size_t i = 0;
 5908|  1.37k|  size_t beg = 0;
 5909|  1.37k|  size_t count = 1;
 5910|       |
 5911|   153k|  while (e ? (b + i < e) : (b[i] != '\0')) {
  ------------------
  |  Branch (5911:10): [True: 153k, False: 0]
  |  Branch (5911:10): [True: 152k, False: 1.37k]
  ------------------
 5912|   152k|    if (b[i] == d && count < m) {
  ------------------
  |  Branch (5912:9): [True: 12.0k, False: 140k]
  |  Branch (5912:22): [True: 12.0k, False: 0]
  ------------------
 5913|  12.0k|      auto r = trim(b, e, beg, i);
 5914|  12.0k|      if (r.first < r.second) { fn(&b[r.first], &b[r.second]); }
  ------------------
  |  Branch (5914:11): [True: 3.02k, False: 8.99k]
  ------------------
 5915|  12.0k|      beg = i + 1;
 5916|  12.0k|      count++;
 5917|  12.0k|    }
 5918|   152k|    i++;
 5919|   152k|  }
 5920|       |
 5921|  1.37k|  if (i) {
  ------------------
  |  Branch (5921:7): [True: 1.17k, False: 198]
  ------------------
 5922|  1.17k|    auto r = trim(b, e, beg, i);
 5923|  1.17k|    if (r.first < r.second) { fn(&b[r.first], &b[r.second]); }
  ------------------
  |  Branch (5923:9): [True: 1.06k, False: 105]
  ------------------
 5924|  1.17k|  }
 5925|  1.37k|}
_ZN7httplib6detail6is_hexEcRi:
 5073|  15.5k|inline bool is_hex(char c, int &v) {
 5074|  15.5k|  if (is_ascii_digit(c)) {
  ------------------
  |  Branch (5074:7): [True: 7.97k, False: 7.60k]
  ------------------
 5075|  7.97k|    v = c - '0';
 5076|  7.97k|    return true;
 5077|  7.97k|  } else if ('A' <= c && c <= 'F') {
  ------------------
  |  Branch (5077:14): [True: 3.69k, False: 3.91k]
  |  Branch (5077:26): [True: 1.21k, False: 2.47k]
  ------------------
 5078|  1.21k|    v = c - 'A' + 10;
 5079|  1.21k|    return true;
 5080|  6.38k|  } else if ('a' <= c && c <= 'f') {
  ------------------
  |  Branch (5080:14): [True: 2.47k, False: 3.91k]
  |  Branch (5080:26): [True: 2.45k, False: 20]
  ------------------
 5081|  2.45k|    v = c - 'a' + 10;
 5082|  2.45k|    return true;
 5083|  2.45k|  }
 5084|  3.93k|  return false;
 5085|  15.5k|}
_ZNK7httplib6detail26insertion_ordered_multimapINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS2_8equal_toIS8_EEE5emptyEv:
 1146|  3.08k|  bool empty() const { return entries_.empty(); }
_ZN7httplib6detail18write_request_lineERNS_6StreamERKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEESB_:
 8390|  3.08k|                                  const std::string &path) {
 8391|       |  // A request target must not carry CR/LF (or other control octets); otherwise
 8392|       |  // a value smuggled into it splits the request line and injects headers or a
 8393|       |  // whole request. The same field-value check already guards header values in
 8394|       |  // check_and_write_headers and the request target in
 8395|       |  // perform_websocket_handshake; apply it here too.
 8396|  3.08k|  if (!fields::is_field_value(path)) { return -1; }
  ------------------
  |  Branch (8396:7): [True: 0, False: 3.08k]
  ------------------
 8397|       |
 8398|  3.08k|  std::string s = method;
 8399|  3.08k|  s += ' ';
 8400|  3.08k|  s += path;
 8401|  3.08k|  s += " HTTP/1.1\r\n";
 8402|  3.08k|  return strm.write(s.data(), s.size());
 8403|  3.08k|}
_ZN7httplib6detail23check_and_write_headersINSt3__18functionIFlRNS_6StreamERNS0_26insertion_ordered_multimapINS2_12basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS0_11case_ignore8equal_toEEEEEEEEbS5_SG_T_RNS_5ErrorE:
12347|  3.08k|                                    T header_writer, Error &error) {
12348|  14.2k|  for (const auto &h : headers) {
  ------------------
  |  Branch (12348:22): [True: 14.2k, False: 3.08k]
  ------------------
12349|  14.2k|    if (!detail::fields::is_field_valid(h.first, h.second)) {
  ------------------
  |  Branch (12349:9): [True: 0, False: 14.2k]
  ------------------
12350|      0|      error = Error::InvalidHeaders;
12351|      0|      return false;
12352|      0|    }
12353|  14.2k|  }
12354|  3.08k|  if (header_writer(strm, headers) <= 0) {
  ------------------
  |  Branch (12354:7): [True: 0, False: 3.08k]
  ------------------
12355|      0|    error = Error::Write;
12356|      0|    return false;
12357|      0|  }
12358|  3.08k|  return true;
12359|  3.08k|}
_ZNK7httplib6detail12BufferStream10get_bufferEv:
12014|  3.08k|inline const std::string &BufferStream::get_buffer() const { return buffer; }
_ZN7httplib6detail10write_dataERNS_6StreamEPKcm:
 8440|  3.08k|inline bool write_data(Stream &strm, const char *d, size_t l) {
 8441|  3.08k|  size_t offset = 0;
 8442|  6.16k|  while (offset < l) {
  ------------------
  |  Branch (8442:10): [True: 3.08k, False: 3.08k]
  ------------------
 8443|  3.08k|    auto length = strm.write(d + offset, l - offset);
 8444|  3.08k|    if (length < 0) { return false; }
  ------------------
  |  Branch (8444:9): [True: 0, False: 3.08k]
  ------------------
 8445|  3.08k|    offset += static_cast<size_t>(length);
 8446|  3.08k|  }
 8447|  3.08k|  return true;
 8448|  3.08k|}
_ZNK7httplib10ClientImpl18read_response_lineERNS_6StreamERKNS_7RequestERNS_8ResponseEb:
14673|  3.08k|                                           bool skip_100_continue) const {
14674|  3.08k|  std::array<char, 2048> buf{};
14675|       |
14676|  3.08k|  detail::stream_line_reader line_reader(strm, buf.data(), buf.size());
14677|       |
14678|  3.08k|  if (!line_reader.getline()) { return false; }
  ------------------
  |  Branch (14678:7): [True: 9, False: 3.07k]
  ------------------
14679|       |
14680|  3.07k|  if (!detail::parse_status_line(line_reader.ptr(), res.version, res.status,
  ------------------
  |  Branch (14680:7): [True: 215, False: 2.86k]
  ------------------
14681|  3.07k|                                 res.reason)) {
14682|    215|    return req.method == "CONNECT";
14683|    215|  }
14684|       |
14685|       |  // Ignore '100 Continue' (only when not using Expect: 100-continue explicitly)
14686|  8.25k|  while (skip_100_continue && res.status == StatusCode::Continue_100) {
  ------------------
  |  Branch (14686:10): [True: 8.25k, False: 0]
  |  Branch (14686:31): [True: 5.59k, False: 2.65k]
  ------------------
14687|  5.59k|    if (!line_reader.getline()) { return false; } // CRLF
  ------------------
  |  Branch (14687:9): [True: 67, False: 5.53k]
  ------------------
14688|  5.53k|    if (!line_reader.getline()) { return false; } // next response line
  ------------------
  |  Branch (14688:9): [True: 13, False: 5.51k]
  ------------------
14689|       |
14690|  5.51k|    if (!detail::parse_status_line(line_reader.ptr(), res.version, res.status,
  ------------------
  |  Branch (14690:9): [True: 127, False: 5.39k]
  ------------------
14691|  5.51k|                                   res.reason)) {
14692|    127|      return false;
14693|    127|    }
14694|  5.51k|  }
14695|       |
14696|  2.65k|  return true;
14697|  2.86k|}
_ZN7httplib6detail18stream_line_readerC2ERNS_6StreamEPcm:
 6014|  13.1k|    : strm_(strm), fixed_buffer_(fixed_buffer),
 6015|  13.1k|      fixed_buffer_size_(fixed_buffer_size) {}
_ZN7httplib6detail18stream_line_reader7getlineEv:
 6038|  38.2k|inline bool stream_line_reader::getline() {
 6039|  38.2k|  fixed_buffer_used_size_ = 0;
 6040|  38.2k|  growable_buffer_.clear();
 6041|       |
 6042|  38.2k|#ifndef CPPHTTPLIB_ALLOW_LF_AS_LINE_TERMINATOR
 6043|  38.2k|  char prev_byte = 0;
 6044|  38.2k|#endif
 6045|       |
 6046|  3.69M|  for (size_t i = 0;; i++) {
 6047|       |    // Fast path: whatever the stream has already buffered can be scanned for
 6048|       |    // the terminator in one pass. Asking for a byte at a time costs a virtual
 6049|       |    // call, a bounds check and a one-byte copy per character of the request.
 6050|  3.69M|    size_t buffered_size = 0;
 6051|  3.69M|    if (auto buffered = strm_.buffered_data(buffered_size)) {
  ------------------
  |  Branch (6051:14): [True: 0, False: 3.69M]
  ------------------
 6052|      0|      auto take = buffered_size;
 6053|      0|      auto terminated = false;
 6054|       |
 6055|      0|      for (size_t at = 0; at < buffered_size;) {
  ------------------
  |  Branch (6055:27): [True: 0, False: 0]
  ------------------
 6056|      0|        auto nl = static_cast<const char *>(
 6057|      0|            memchr(buffered + at, '\n', buffered_size - at));
 6058|      0|        if (!nl) { break; }
  ------------------
  |  Branch (6058:13): [True: 0, False: 0]
  ------------------
 6059|      0|        auto pos = static_cast<size_t>(nl - buffered);
 6060|       |#ifdef CPPHTTPLIB_ALLOW_LF_AS_LINE_TERMINATOR
 6061|       |        take = pos + 1;
 6062|       |        terminated = true;
 6063|       |        break;
 6064|       |#else
 6065|       |        // A bare LF does not end the line; keep looking for CRLF. The CR may
 6066|       |        // be the last byte of an earlier chunk, hence prev_byte.
 6067|      0|        if ((pos > 0 ? buffered[pos - 1] : prev_byte) == '\r') {
  ------------------
  |  Branch (6067:13): [True: 0, False: 0]
  |  Branch (6067:14): [True: 0, False: 0]
  ------------------
 6068|      0|          take = pos + 1;
 6069|      0|          terminated = true;
 6070|      0|          break;
 6071|      0|        }
 6072|      0|        at = pos + 1;
 6073|      0|#endif
 6074|      0|      }
 6075|       |
 6076|      0|      if (size() + take > CPPHTTPLIB_MAX_LINE_LENGTH) { return false; }
  ------------------
  |  |  211|      0|#define CPPHTTPLIB_MAX_LINE_LENGTH 32768
  ------------------
  |  Branch (6076:11): [True: 0, False: 0]
  ------------------
 6077|      0|#ifndef CPPHTTPLIB_ALLOW_LF_AS_LINE_TERMINATOR
 6078|      0|      prev_byte = buffered[take - 1];
 6079|      0|#endif
 6080|      0|      append(buffered, take);
 6081|      0|      strm_.consume_buffered(take);
 6082|      0|      i += take;
 6083|      0|      if (terminated) { return true; }
  ------------------
  |  Branch (6083:11): [True: 0, False: 0]
  ------------------
 6084|      0|      continue;
 6085|      0|    }
 6086|       |
 6087|  3.69M|    if (size() >= CPPHTTPLIB_MAX_LINE_LENGTH) {
  ------------------
  |  |  211|  3.69M|#define CPPHTTPLIB_MAX_LINE_LENGTH 32768
  ------------------
  |  Branch (6087:9): [True: 3, False: 3.69M]
  ------------------
 6088|       |      // Treat exceptionally long lines as an error to
 6089|       |      // prevent infinite loops/memory exhaustion
 6090|      3|      return false;
 6091|      3|    }
 6092|  3.69M|    char byte;
 6093|  3.69M|    auto n = strm_.read(&byte, 1);
 6094|       |
 6095|  3.69M|    if (n < 0) {
  ------------------
  |  Branch (6095:9): [True: 0, False: 3.69M]
  ------------------
 6096|      0|      return false;
 6097|  3.69M|    } else if (n == 0) {
  ------------------
  |  Branch (6097:16): [True: 1.38k, False: 3.68M]
  ------------------
 6098|  1.38k|      if (i == 0) {
  ------------------
  |  Branch (6098:11): [True: 493, False: 891]
  ------------------
 6099|    493|        return false;
 6100|    891|      } else {
 6101|    891|        break;
 6102|    891|      }
 6103|  1.38k|    }
 6104|       |
 6105|  3.68M|    append(byte);
 6106|       |
 6107|       |#ifdef CPPHTTPLIB_ALLOW_LF_AS_LINE_TERMINATOR
 6108|       |    if (byte == '\n') { break; }
 6109|       |#else
 6110|  3.68M|    if (prev_byte == '\r' && byte == '\n') { break; }
  ------------------
  |  Branch (6110:9): [True: 37.4k, False: 3.65M]
  |  Branch (6110:30): [True: 36.9k, False: 565]
  ------------------
 6111|  3.65M|    prev_byte = byte;
 6112|  3.65M|#endif
 6113|  3.65M|  }
 6114|       |
 6115|  37.7k|  return true;
 6116|  38.2k|}
_ZNK7httplib6detail18stream_line_reader4sizeEv:
 6025|  3.75M|inline size_t stream_line_reader::size() const {
 6026|  3.75M|  if (growable_buffer_.empty()) {
  ------------------
  |  Branch (6026:7): [True: 1.94M, False: 1.81M]
  ------------------
 6027|  1.94M|    return fixed_buffer_used_size_;
 6028|  1.94M|  } else {
 6029|  1.81M|    return growable_buffer_.size();
 6030|  1.81M|  }
 6031|  3.75M|}
_ZN7httplib6detail18stream_line_reader6appendEPKcm:
 6120|  3.68M|inline void stream_line_reader::append(const char *data, size_t size) {
 6121|       |  // Once the line has outgrown the fixed buffer everything must keep going to
 6122|       |  // the growable one, even if a later chunk would have fit. Without the
 6123|       |  // emptiness check a short append after a long one would land in the fixed
 6124|       |  // buffer, which ptr() and size() no longer look at, and be lost.
 6125|  3.68M|  if (growable_buffer_.empty() &&
  ------------------
  |  Branch (6125:7): [True: 1.87M, False: 1.81M]
  ------------------
 6126|  1.87M|      fixed_buffer_used_size_ + size < fixed_buffer_size_) {
  ------------------
  |  Branch (6126:7): [True: 1.87M, False: 910]
  ------------------
 6127|  1.87M|    memcpy(fixed_buffer_ + fixed_buffer_used_size_, data, size);
 6128|  1.87M|    fixed_buffer_used_size_ += size;
 6129|  1.87M|    fixed_buffer_[fixed_buffer_used_size_] = '\0';
 6130|  1.87M|  } else {
 6131|       |    // Unlike the per-character overload, this can be the very first append of
 6132|       |    // the line, so the fixed buffer may hold nothing and carry no terminator
 6133|       |    // yet. assign() takes an explicit length and does not need one.
 6134|  1.81M|    if (growable_buffer_.empty()) {
  ------------------
  |  Branch (6134:9): [True: 910, False: 1.81M]
  ------------------
 6135|    910|      growable_buffer_.assign(fixed_buffer_, fixed_buffer_used_size_);
 6136|    910|    }
 6137|  1.81M|    growable_buffer_.append(data, size);
 6138|  1.81M|  }
 6139|  3.68M|}
_ZN7httplib6detail18stream_line_reader6appendEc:
 6118|  3.68M|inline void stream_line_reader::append(char c) { append(&c, 1); }
_ZN7httplib6detail17parse_status_lineEPKcRNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEERiSA_:
 8049|  8.59k|                              int &status, std::string &reason) {
 8050|       |#ifdef CPPHTTPLIB_ALLOW_LF_AS_LINE_TERMINATOR
 8051|       |  thread_local const std::regex re("(HTTP/1\\.[01]) (\\d{3})(?: (.*?))?\r?\n");
 8052|       |#else
 8053|  8.59k|  thread_local const std::regex re("(HTTP/1\\.[01]) (\\d{3})(?: (.*?))?\r\n");
 8054|  8.59k|#endif
 8055|       |
 8056|  8.59k|  std::cmatch m;
 8057|  8.59k|  if (!std::regex_match(line, m, re)) { return false; }
  ------------------
  |  Branch (8057:7): [True: 342, False: 8.25k]
  ------------------
 8058|  8.25k|  version = std::string(m[1]);
 8059|  8.25k|  status = std::stoi(std::string(m[2]));
 8060|  8.25k|  reason = std::string(m[3]);
 8061|  8.25k|  return true;
 8062|  8.59k|}
_ZNK7httplib6detail18stream_line_reader3ptrEv:
 6017|  61.0k|inline const char *stream_line_reader::ptr() const {
 6018|  61.0k|  if (growable_buffer_.empty()) {
  ------------------
  |  Branch (6018:7): [True: 58.4k, False: 2.53k]
  ------------------
 6019|  58.4k|    return fixed_buffer_;
 6020|  58.4k|  } else {
 6021|  2.53k|    return growable_buffer_.data();
 6022|  2.53k|  }
 6023|  61.0k|}
_ZN7httplib10ClientImpl18write_request_bodyERNS_6StreamERNS_7RequestERNS_5ErrorE:
15637|  3.08k|                                           Error &error) {
15638|  3.08k|  if (req.body.empty()) {
  ------------------
  |  Branch (15638:7): [True: 3.08k, False: 0]
  ------------------
15639|  3.08k|    return write_content_with_provider(strm, req, error);
15640|  3.08k|  }
15641|       |
15642|      0|  if (req.upload_progress) {
  ------------------
  |  Branch (15642:7): [True: 0, False: 0]
  ------------------
15643|      0|    auto body_size = req.body.size();
15644|      0|    size_t written = 0;
15645|      0|    auto data = req.body.data();
15646|       |
15647|      0|    while (written < body_size) {
  ------------------
  |  Branch (15647:12): [True: 0, False: 0]
  ------------------
15648|      0|      size_t to_write = (std::min)(CPPHTTPLIB_SEND_BUFSIZ, body_size - written);
  ------------------
  |  |  176|      0|#define CPPHTTPLIB_SEND_BUFSIZ size_t(16384u)
  ------------------
15649|      0|      if (!detail::write_data(strm, data + written, to_write)) {
  ------------------
  |  Branch (15649:11): [True: 0, False: 0]
  ------------------
15650|      0|        error = Error::Write;
15651|      0|        output_error_log(error, &req);
15652|      0|        return false;
15653|      0|      }
15654|      0|      written += to_write;
15655|       |
15656|      0|      if (!req.upload_progress(written, body_size)) {
  ------------------
  |  Branch (15656:11): [True: 0, False: 0]
  ------------------
15657|      0|        error = Error::Canceled;
15658|      0|        output_error_log(error, &req);
15659|      0|        return false;
15660|      0|      }
15661|      0|    }
15662|      0|  } else {
15663|      0|    if (!detail::write_data(strm, req.body.data(), req.body.size())) {
  ------------------
  |  Branch (15663:9): [True: 0, False: 0]
  ------------------
15664|      0|      error = Error::Write;
15665|      0|      output_error_log(error, &req);
15666|      0|      return false;
15667|      0|    }
15668|      0|  }
15669|       |
15670|      0|  return true;
15671|      0|}
_ZNK7httplib10ClientImpl27write_content_with_providerERNS_6StreamERKNS_7RequestERNS_5ErrorE:
15453|  3.08k|                                                    Error &error) const {
15454|  3.08k|  auto is_shutting_down = []() { return false; };
15455|       |
15456|  3.08k|  if (req.is_chunked_content_provider_) {
  ------------------
  |  Branch (15456:7): [True: 0, False: 3.08k]
  ------------------
15457|      0|    auto compressor = compress_ ? detail::create_compressor().first
  ------------------
  |  Branch (15457:23): [True: 0, False: 0]
  ------------------
15458|      0|                                : std::unique_ptr<detail::compressor>();
15459|      0|    if (!compressor) {
  ------------------
  |  Branch (15459:9): [True: 0, False: 0]
  ------------------
15460|      0|      compressor = detail::make_unique<detail::nocompressor>();
15461|      0|    }
15462|       |
15463|      0|    return detail::write_content_chunked(strm, req.content_provider_,
15464|      0|                                         is_shutting_down, *compressor, error);
15465|  3.08k|  } else {
15466|  3.08k|    return detail::write_content_with_progress(
15467|  3.08k|        strm, req.content_provider_, 0, req.content_length_, is_shutting_down,
15468|  3.08k|        req.upload_progress, error);
15469|  3.08k|  }
15470|  3.08k|}
_ZN7httplib8DataSinkC2Ev:
 1434|  3.08k|  DataSink() : os(&sb_), sb_(*this) {}
_ZN7httplib8DataSink19data_sink_streambufC2ERS0_:
 1457|  3.08k|    explicit data_sink_streambuf(DataSink &sink) : sink_(sink) {}
_ZN7httplib6detail27write_content_with_progressIZNKS_10ClientImpl27write_content_with_providerERNS_6StreamERKNS_7RequestERNS_5ErrorEEUlvE_EEbS4_RKNSt3__18functionIFbmmRNS_8DataSinkEEEEmmT_RKNSC_IFbmmEEES9_:
 8456|  3.08k|                                        Error &error) {
 8457|  3.08k|  size_t end_offset = offset + length;
 8458|  3.08k|  size_t start_offset = offset;
 8459|  3.08k|  auto ok = true;
 8460|  3.08k|  auto finished = false;
 8461|  3.08k|  DataSink data_sink;
 8462|       |
 8463|  3.08k|  data_sink.write = [&](const char *d, size_t l) -> bool {
 8464|  3.08k|    if (ok) {
 8465|  3.08k|      if (write_data(strm, d, l)) {
 8466|  3.08k|        offset += l;
 8467|       |
 8468|  3.08k|        if (upload_progress && length > 0) {
 8469|  3.08k|          size_t current_written = offset - start_offset;
 8470|  3.08k|          if (!upload_progress(current_written, length)) {
 8471|  3.08k|            ok = false;
 8472|  3.08k|            return false;
 8473|  3.08k|          }
 8474|  3.08k|        }
 8475|  3.08k|      } else {
 8476|  3.08k|        ok = false;
 8477|  3.08k|      }
 8478|  3.08k|    }
 8479|  3.08k|    return ok;
 8480|  3.08k|  };
 8481|       |
 8482|  3.08k|  data_sink.is_writable = [&]() -> bool { return strm.is_peer_alive(); };
 8483|       |
 8484|       |  // The body is framed by `length`, so a provider that reports itself done
 8485|       |  // early has truncated it. Record that and let the short-body check below
 8486|       |  // fail the write, rather than calling the provider again forever.
 8487|  3.08k|  data_sink.done = [&]() { finished = true; };
 8488|       |
 8489|  3.08k|  while (offset < end_offset && !finished && !is_shutting_down()) {
  ------------------
  |  Branch (8489:10): [True: 0, False: 3.08k]
  |  Branch (8489:33): [True: 0, False: 0]
  |  Branch (8489:46): [True: 0, False: 0]
  ------------------
 8490|      0|    auto last_offset = offset;
 8491|       |
 8492|      0|    if (!strm.wait_writable() || !strm.is_peer_alive()) {
  ------------------
  |  Branch (8492:9): [True: 0, False: 0]
  |  Branch (8492:34): [True: 0, False: 0]
  ------------------
 8493|      0|      error = Error::Write;
 8494|      0|      return false;
 8495|      0|    } else if (!content_provider(offset, end_offset - offset, data_sink)) {
  ------------------
  |  Branch (8495:16): [True: 0, False: 0]
  ------------------
 8496|      0|      error = Error::Canceled;
 8497|      0|      return false;
 8498|      0|    } else if (!ok) {
  ------------------
  |  Branch (8498:16): [True: 0, False: 0]
  ------------------
 8499|      0|      error = Error::Write;
 8500|      0|      return false;
 8501|      0|    }
 8502|       |
 8503|       |    // A provider that reports success without writing anything and without
 8504|       |    // reporting itself done gets handed the same offset and length again on
 8505|       |    // the next pass, so it would spin here for as long as the peer stays
 8506|       |    // connected. Treat making no progress as a short body, like done() early.
 8507|      0|    if (!finished && offset == last_offset) {
  ------------------
  |  Branch (8507:9): [True: 0, False: 0]
  |  Branch (8507:22): [True: 0, False: 0]
  ------------------
 8508|      0|      error = Error::Write;
 8509|      0|      return false;
 8510|      0|    }
 8511|      0|  }
 8512|       |
 8513|  3.08k|  if (offset < end_offset) { // done() called early, or is_shutting_down()
  ------------------
  |  Branch (8513:7): [True: 0, False: 3.08k]
  ------------------
 8514|      0|    error = Error::Write;
 8515|      0|    return false;
 8516|      0|  }
 8517|       |
 8518|  3.08k|  error = Error::Success;
 8519|  3.08k|  return true;
 8520|  3.08k|}
_ZN7httplib6detail12read_headersERNS_6StreamERNS0_26insertion_ordered_multimapINSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEENS0_11case_ignore8equal_toEEE:
 7992|  2.65k|inline bool read_headers(Stream &strm, Headers &headers) {
 7993|  2.65k|  const auto bufsiz = 2048;
 7994|  2.65k|  char buf[bufsiz];
 7995|  2.65k|  stream_line_reader line_reader(strm, buf, bufsiz);
 7996|       |
 7997|  2.65k|  size_t header_count = 0;
 7998|       |
 7999|  12.9k|  for (;;) {
 8000|  12.9k|    if (!line_reader.getline()) { return false; }
  ------------------
  |  Branch (8000:9): [True: 314, False: 12.6k]
  ------------------
 8001|       |
 8002|       |    // Check if the line ends with CRLF.
 8003|  12.6k|    auto line_terminator_len = 2;
 8004|  12.6k|    if (line_reader.end_with_crlf()) {
  ------------------
  |  Branch (8004:9): [True: 12.6k, False: 75]
  ------------------
 8005|       |      // Blank line indicates end of headers.
 8006|  12.6k|      if (line_reader.size() == 2) { break; }
  ------------------
  |  Branch (8006:11): [True: 1.98k, False: 10.6k]
  ------------------
 8007|  12.6k|    } else {
 8008|       |#ifdef CPPHTTPLIB_ALLOW_LF_AS_LINE_TERMINATOR
 8009|       |      // Blank line indicates end of headers.
 8010|       |      if (line_reader.size() == 1) { break; }
 8011|       |      line_terminator_len = 1;
 8012|       |#else
 8013|     75|      continue; // Skip invalid line.
 8014|     75|#endif
 8015|     75|    }
 8016|       |
 8017|  10.6k|    if (line_reader.size() > CPPHTTPLIB_HEADER_MAX_LENGTH) { return false; }
  ------------------
  |  |  114|  10.6k|#define CPPHTTPLIB_HEADER_MAX_LENGTH 8192
  ------------------
  |  Branch (8017:9): [True: 4, False: 10.6k]
  ------------------
 8018|       |
 8019|       |    // Check header count limit
 8020|  10.6k|    if (header_count >= CPPHTTPLIB_HEADER_MAX_COUNT) { return false; }
  ------------------
  |  |  118|  10.6k|#define CPPHTTPLIB_HEADER_MAX_COUNT 100
  ------------------
  |  Branch (8020:9): [True: 1, False: 10.6k]
  ------------------
 8021|       |
 8022|       |    // Exclude line terminator
 8023|  10.6k|    auto end = line_reader.ptr() + line_reader.size() - line_terminator_len;
 8024|       |
 8025|  10.6k|    if (!parse_header(line_reader.ptr(), end,
  ------------------
  |  Branch (8025:9): [True: 349, False: 10.2k]
  ------------------
 8026|  10.6k|                      [&](const std::string &key, const std::string &val) {
 8027|  10.6k|                        headers.emplace(key, val);
 8028|  10.6k|                      })) {
 8029|    349|      return false;
 8030|    349|    }
 8031|       |
 8032|  10.2k|    header_count++;
 8033|  10.2k|  }
 8034|       |
 8035|       |  // RFC 9110 Section 8.6: Reject requests with multiple Content-Length
 8036|       |  // headers that have different values to prevent request smuggling.
 8037|  1.98k|  auto cl_range = headers.equal_range("Content-Length");
 8038|  1.98k|  if (cl_range.first != cl_range.second) {
  ------------------
  |  Branch (8038:7): [True: 801, False: 1.18k]
  ------------------
 8039|    801|    const auto &first_val = cl_range.first->second;
 8040|  1.39k|    for (auto it = std::next(cl_range.first); it != cl_range.second; ++it) {
  ------------------
  |  Branch (8040:47): [True: 774, False: 621]
  ------------------
 8041|    774|      if (it->second != first_val) { return false; }
  ------------------
  |  Branch (8041:11): [True: 180, False: 594]
  ------------------
 8042|    774|    }
 8043|    801|  }
 8044|       |
 8045|  1.80k|  return true;
 8046|  1.98k|}
_ZNK7httplib6detail18stream_line_reader13end_with_crlfEv:
 6033|  12.6k|inline bool stream_line_reader::end_with_crlf() const {
 6034|  12.6k|  auto end = ptr() + size();
 6035|  12.6k|  return size() >= 2 && end[-2] == '\r' && end[-1] == '\n';
  ------------------
  |  Branch (6035:10): [True: 12.6k, False: 35]
  |  Branch (6035:25): [True: 12.6k, False: 22]
  |  Branch (6035:44): [True: 12.6k, False: 18]
  ------------------
 6036|  12.6k|}
_ZN7httplib6detail12parse_headerIZNS0_12read_headersERNS_6StreamERNS0_26insertion_ordered_multimapINSt3__112basic_stringIcNS5_11char_traitsIcEENS5_9allocatorIcEEEENS0_11case_ignore8equal_toEEEEUlRKSB_SH_E_EEbPKcSK_T_:
 5726|  10.6k|inline bool parse_header(const char *beg, const char *end, T fn) {
 5727|       |  // Skip trailing spaces and tabs.
 5728|  10.8k|  while (beg < end && is_space_or_tab(end[-1])) {
  ------------------
  |  Branch (5728:10): [True: 10.8k, False: 16]
  |  Branch (5728:23): [True: 278, False: 10.6k]
  ------------------
 5729|    278|    end--;
 5730|    278|  }
 5731|       |
 5732|  10.6k|  auto p = beg;
 5733|   203k|  while (p < end && *p != ':') {
  ------------------
  |  Branch (5733:10): [True: 203k, False: 275]
  |  Branch (5733:21): [True: 193k, False: 10.3k]
  ------------------
 5734|   193k|    p++;
 5735|   193k|  }
 5736|       |
 5737|  10.6k|  auto name = std::string(beg, p);
 5738|  10.6k|  if (!detail::fields::is_field_name(name)) { return false; }
  ------------------
  |  Branch (5738:7): [True: 124, False: 10.4k]
  ------------------
 5739|       |
 5740|  10.4k|  if (p == end) { return false; }
  ------------------
  |  Branch (5740:7): [True: 180, False: 10.3k]
  ------------------
 5741|       |
 5742|  10.3k|  auto key_end = p;
 5743|       |
 5744|  10.3k|  if (*p++ != ':') { return false; }
  ------------------
  |  Branch (5744:7): [True: 0, False: 10.3k]
  ------------------
 5745|       |
 5746|  10.6k|  while (p < end && is_space_or_tab(*p)) {
  ------------------
  |  Branch (5746:10): [True: 4.44k, False: 6.24k]
  |  Branch (5746:21): [True: 378, False: 4.06k]
  ------------------
 5747|    378|    p++;
 5748|    378|  }
 5749|       |
 5750|  10.3k|  if (p <= end) {
  ------------------
  |  Branch (5750:7): [True: 10.3k, False: 0]
  ------------------
 5751|  10.3k|    auto key_len = key_end - beg;
 5752|  10.3k|    if (!key_len) { return false; }
  ------------------
  |  Branch (5752:9): [True: 0, False: 10.3k]
  ------------------
 5753|       |
 5754|  10.3k|    auto key = std::string(beg, key_end);
 5755|  10.3k|    auto val = std::string(p, end);
 5756|       |
 5757|  10.3k|    if (!detail::fields::is_field_value(val)) { return false; }
  ------------------
  |  Branch (5757:9): [True: 45, False: 10.2k]
  ------------------
 5758|       |
 5759|       |    // RFC 9110 §5.5: header field values are opaque octets and MUST NOT be
 5760|       |    // percent-decoded by the recipient. Applications that need to interpret a
 5761|       |    // value as a URI component should call httplib::decode_uri_component()
 5762|       |    // (or decode_path_component()) explicitly.
 5763|  10.2k|    fn(key, val);
 5764|       |
 5765|  10.2k|    return true;
 5766|  10.3k|  }
 5767|       |
 5768|      0|  return false;
 5769|  10.3k|}
_ZZN7httplib6detail12read_headersERNS_6StreamERNS0_26insertion_ordered_multimapINSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEENS0_11case_ignore8equal_toEEEENKUlRKSA_SG_E_clESG_SG_:
 8026|  10.2k|                      [&](const std::string &key, const std::string &val) {
 8027|  10.2k|                        headers.emplace(key, val);
 8028|  10.2k|                      })) {
_ZN7httplib6detail26insertion_ordered_multimapINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS0_11case_ignore8equal_toEE11equal_rangeERKS8_:
 1191|  1.98k|  std::pair<iterator, iterator> equal_range(const std::string &key) {
 1192|  1.98k|    auto i = index_of(key);
 1193|  1.98k|    return i == npos() ? std::make_pair(end(), end())
  ------------------
  |  Branch (1193:12): [True: 1.18k, False: 801]
  ------------------
 1194|  1.98k|                       : std::make_pair(make_iter(i, i), end());
 1195|  1.98k|  }
_ZNK7httplib6detail26insertion_ordered_multimapINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS0_11case_ignore8equal_toEE10iterator_tINS2_4pairIS8_S8_EEEptEv:
 1064|  1.57k|    pointer operator->() const { return data_ + idx_; }
_ZNK7httplib10ClientImpl16output_error_logERKNS_5ErrorEPKNS_7RequestE:
15817|  2.60k|                                         const Request *req) const {
15818|  2.60k|  if (error_logger_) {
  ------------------
  |  Branch (15818:7): [True: 0, False: 2.60k]
  ------------------
15819|      0|    std::lock_guard<std::mutex> guard(logger_mutex_);
15820|      0|    error_logger_(err, req);
15821|      0|  }
15822|  2.60k|}
_ZZN7httplib10ClientImpl15process_requestERNS_6StreamERNS_7RequestERNS_8ResponseEbRNS_5ErrorEENKUlPKcmmmE0_clESA_mmm:
15943|   124k|                      size_t /*len*/) {
15944|   124k|                    assert(res.body.size() + n <= res.body.max_size());
  ------------------
  |  Branch (15944:21): [True: 124k, False: 0]
  ------------------
15945|   124k|                    if (payload_max_length_ > 0 &&
  ------------------
  |  Branch (15945:25): [True: 124k, False: 0]
  ------------------
15946|   124k|                        (res.body.size() >= payload_max_length_ ||
  ------------------
  |  Branch (15946:26): [True: 0, False: 124k]
  ------------------
15947|   124k|                         n > payload_max_length_ - res.body.size())) {
  ------------------
  |  Branch (15947:26): [True: 0, False: 124k]
  ------------------
15948|      0|                      return false;
15949|      0|                    }
15950|   124k|                    res.body.append(buf, n);
15951|   124k|                    return true;
15952|   124k|                  });
_ZNK7httplib8Response10has_headerERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
11447|  1.79k|inline bool Response::has_header(const std::string &key) const {
11448|  1.79k|  return headers.find(key) != headers.end();
11449|  1.79k|}
_ZNK7httplib8Response20get_header_value_u64ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEmm:
11443|    620|                                             size_t id) const {
11444|    620|  return detail::get_header_value_u64(headers, key, def, id);
11445|    620|}
_ZN7httplib6detail20get_header_value_u64ERKNS0_26insertion_ordered_multimapINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS0_11case_ignore8equal_toEEERKS8_mm:
 3425|    620|                                   size_t id) {
 3426|    620|  auto dummy = false;
 3427|    620|  return get_header_value_u64(headers, key, def, id, dummy);
 3428|    620|}
_ZN7httplib6detail20get_header_value_u64ERKNS0_26insertion_ordered_multimapINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS0_11case_ignore8equal_toEEERKS8_mmRb:
 3397|  1.15k|                                   size_t id, bool &is_invalid_value) {
 3398|  1.15k|  is_invalid_value = false;
 3399|  1.15k|  auto rng = headers.equal_range(key);
 3400|  1.15k|  auto it = rng.first;
 3401|  1.15k|  std::advance(it, static_cast<ssize_t>(id));
 3402|  1.15k|  if (it != rng.second) {
  ------------------
  |  Branch (3402:7): [True: 1.15k, False: 0]
  ------------------
 3403|  1.15k|    if (is_numeric(it->second)) {
  ------------------
  |  Branch (3403:9): [True: 1.00k, False: 150]
  ------------------
 3404|       |      // Parse at size_t width so an out-of-range Content-Length is reported
 3405|       |      // rather than silently saturated/truncated (a value above 2^32 would
 3406|       |      // otherwise wrap to a small framing length on 32-bit builds). Flag it
 3407|       |      // and return SIZE_MAX so the existing oversized-value guards reject it.
 3408|  1.00k|      size_t val = 0;
 3409|  1.00k|      const auto &s = it->second;
 3410|  1.00k|      auto r = from_chars(s.data(), s.data() + s.size(), val);
 3411|  1.00k|      if (r.ec == std::errc::result_out_of_range) {
  ------------------
  |  Branch (3411:11): [True: 63, False: 940]
  ------------------
 3412|     63|        is_invalid_value = true;
 3413|     63|        return (std::numeric_limits<size_t>::max)();
 3414|     63|      }
 3415|    940|      return val;
 3416|  1.00k|    } else {
 3417|    150|      is_invalid_value = true;
 3418|    150|    }
 3419|  1.15k|  }
 3420|    150|  return def;
 3421|  1.15k|}
_ZN7httplib6detail10is_numericERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
 3391|  1.15k|inline bool is_numeric(const std::string &str) {
 3392|  1.15k|  return !str.empty() && std::all_of(str.cbegin(), str.cend(), is_ascii_digit);
  ------------------
  |  Branch (3392:10): [True: 1.02k, False: 130]
  |  Branch (3392:26): [True: 1.00k, False: 20]
  ------------------
 3393|  1.15k|}
_ZN7httplib6detail10from_charsImEENS0_17from_chars_resultIT_EEPKcS6_RS3_i:
  700|  1.00k|                                       T &value, int base = 10) {
  701|  1.00k|  value = 0;
  702|  1.00k|  const char *p = first;
  703|  1.00k|  bool negative = false;
  704|       |
  705|  1.00k|  if (p != last && *p == '-') {
  ------------------
  |  Branch (705:7): [True: 1.00k, False: 0]
  |  Branch (705:20): [True: 0, False: 1.00k]
  ------------------
  706|      0|    negative = true;
  707|      0|    ++p;
  708|      0|  }
  709|  1.00k|  if (p == last) { return {first, std::errc::invalid_argument}; }
  ------------------
  |  Branch (709:7): [True: 0, False: 1.00k]
  ------------------
  710|       |
  711|  1.00k|  T result = 0;
  712|  14.7k|  for (; p != last; ++p) {
  ------------------
  |  Branch (712:10): [True: 13.7k, False: 940]
  ------------------
  713|  13.7k|    char c = *p;
  714|  13.7k|    int digit = -1;
  715|  13.7k|    if (is_ascii_digit(c)) {
  ------------------
  |  Branch (715:9): [True: 13.7k, False: 0]
  ------------------
  716|  13.7k|      digit = c - '0';
  717|  13.7k|    } else if ('a' <= c && c <= 'z') {
  ------------------
  |  Branch (717:16): [True: 0, False: 0]
  |  Branch (717:28): [True: 0, False: 0]
  ------------------
  718|      0|      digit = c - 'a' + 10;
  719|      0|    } else if ('A' <= c && c <= 'Z') {
  ------------------
  |  Branch (719:16): [True: 0, False: 0]
  |  Branch (719:28): [True: 0, False: 0]
  ------------------
  720|      0|      digit = c - 'A' + 10;
  721|      0|    } else {
  722|      0|      break;
  723|      0|    }
  724|       |
  725|  13.7k|    if (digit < 0 || digit >= base) { break; }
  ------------------
  |  Branch (725:9): [True: 0, False: 13.7k]
  |  Branch (725:22): [True: 0, False: 13.7k]
  ------------------
  726|  13.7k|    if (result > ((std::numeric_limits<T>::max)() - digit) / base) {
  ------------------
  |  Branch (726:9): [True: 63, False: 13.7k]
  ------------------
  727|     63|      return {p, std::errc::result_out_of_range};
  728|     63|    }
  729|  13.7k|    result = result * base + digit;
  730|  13.7k|  }
  731|       |
  732|    940|  if (p == first || (negative && p == first + 1)) {
  ------------------
  |  Branch (732:7): [True: 0, False: 940]
  |  Branch (732:22): [True: 0, False: 940]
  |  Branch (732:34): [True: 0, False: 0]
  ------------------
  733|      0|    return {first, std::errc::invalid_argument};
  734|      0|  }
  735|       |
  736|    940|  value = negative ? T(0) - result : result;
  ------------------
  |  Branch (736:11): [True: 0, False: 940]
  ------------------
  737|    940|  return {p, std::errc{}};
  738|    940|}
_ZN7httplib6detail12read_contentINS_8ResponseEEEbRNS_6StreamERT_mRiNSt3__18functionIFbmmEEENS9_IFbPKcmmmEEEb:
 8332|  1.71k|                  ContentReceiverWithProgress receiver, bool decompress) {
 8333|  1.71k|  bool exceed_payload_max_length = false;
 8334|  1.71k|  return prepare_content_receiver(
 8335|  1.71k|      x, status, std::move(receiver), decompress, payload_max_length,
 8336|  1.71k|      exceed_payload_max_length, [&](const ContentReceiverWithProgress &out) {
 8337|  1.71k|        auto ret = true;
 8338|       |        // Note: exceed_payload_max_length may also be set by the decompressor
 8339|       |        // wrapper in prepare_content_receiver when the decompressed payload
 8340|       |        // size exceeds the limit.
 8341|       |
 8342|  1.71k|        if (is_chunked_transfer_encoding(x.headers)) {
 8343|  1.71k|          auto result = read_content_chunked(strm, x, payload_max_length, out);
 8344|  1.71k|          if (result == ReadContentResult::Success) {
 8345|  1.71k|            ret = true;
 8346|  1.71k|          } else if (result == ReadContentResult::PayloadTooLarge) {
 8347|  1.71k|            exceed_payload_max_length = true;
 8348|  1.71k|            ret = false;
 8349|  1.71k|          } else {
 8350|  1.71k|            ret = false;
 8351|  1.71k|          }
 8352|  1.71k|        } else if (!has_header(x.headers, "Content-Length")) {
 8353|  1.71k|          auto result =
 8354|  1.71k|              read_content_without_length(strm, payload_max_length, out);
 8355|  1.71k|          if (result == ReadContentResult::Success) {
 8356|  1.71k|            ret = true;
 8357|  1.71k|          } else if (result == ReadContentResult::PayloadTooLarge) {
 8358|  1.71k|            exceed_payload_max_length = true;
 8359|  1.71k|            ret = false;
 8360|  1.71k|          } else {
 8361|  1.71k|            ret = false;
 8362|  1.71k|          }
 8363|  1.71k|        } else {
 8364|  1.71k|          auto is_invalid_value = false;
 8365|  1.71k|          auto len = get_header_value_u64(x.headers, "Content-Length",
 8366|  1.71k|                                          (std::numeric_limits<size_t>::max)(),
 8367|  1.71k|                                          0, is_invalid_value);
 8368|       |
 8369|  1.71k|          if (is_invalid_value) {
 8370|  1.71k|            ret = false;
 8371|  1.71k|          } else if (len > 0) {
 8372|  1.71k|            auto result = read_content_with_length(
 8373|  1.71k|                strm, len, std::move(progress), out, payload_max_length);
 8374|  1.71k|            ret = (result == ReadContentResult::Success);
 8375|  1.71k|            if (result == ReadContentResult::PayloadTooLarge) {
 8376|  1.71k|              exceed_payload_max_length = true;
 8377|  1.71k|            }
 8378|  1.71k|          }
 8379|  1.71k|        }
 8380|       |
 8381|  1.71k|        if (!ret) {
 8382|  1.71k|          status = exceed_payload_max_length ? StatusCode::PayloadTooLarge_413
 8383|  1.71k|                                             : StatusCode::BadRequest_400;
 8384|  1.71k|        }
 8385|  1.71k|        return ret;
 8386|  1.71k|      });
 8387|  1.71k|}
_ZN7httplib6detail24prepare_content_receiverINS_8ResponseEZNS0_12read_contentIS2_EEbRNS_6StreamERT_mRiNSt3__18functionIFbmmEEENSA_IFbPKcmmmEEEbEUlRKSG_E_EEbS7_S8_SG_bmRbT0_:
 8278|  1.71k|                              bool &exceed_payload_max_length, U callback) {
 8279|  1.71k|  if (decompress) {
  ------------------
  |  Branch (8279:7): [True: 1.71k, False: 0]
  ------------------
 8280|  1.71k|    auto encoding = get_combined_header_value(x.headers, "Content-Encoding");
 8281|  1.71k|    std::unique_ptr<decompressor> decompressor;
 8282|       |
 8283|  1.71k|    if (!encoding.empty()) {
  ------------------
  |  Branch (8283:9): [True: 179, False: 1.53k]
  ------------------
 8284|       |      // A coding we know about but were not built with is an error. An
 8285|       |      // unrecognized coding (including "identity") is left alone and the
 8286|       |      // payload is passed through as-is, since some servers misuse the header,
 8287|       |      // e.g. by sending a character set such as "Content-Encoding: UTF-8".
 8288|    179|      decompressor = detail::create_decompressor(encoding);
 8289|    179|      if (!decompressor && detail::is_known_content_encoding(encoding)) {
  ------------------
  |  Branch (8289:11): [True: 41, False: 138]
  |  Branch (8289:28): [True: 2, False: 39]
  ------------------
 8290|      2|        status = StatusCode::UnsupportedMediaType_415;
 8291|      2|        return false;
 8292|      2|      }
 8293|    179|    }
 8294|       |
 8295|  1.71k|    if (decompressor) {
  ------------------
  |  Branch (8295:9): [True: 138, False: 1.57k]
  ------------------
 8296|    138|      if (decompressor->is_valid()) {
  ------------------
  |  Branch (8296:11): [True: 138, False: 0]
  ------------------
 8297|    138|        size_t decompressed_size = 0;
 8298|    138|        ContentReceiverWithProgress out = [&](const char *buf, size_t n,
 8299|    138|                                              size_t off, size_t len) {
 8300|    138|          return decompressor->decompress(
 8301|    138|              buf, n, [&](const char *buf2, size_t n2) {
 8302|       |                // Guard against zip-bomb: check
 8303|       |                // decompressed size against limit.
 8304|    138|                if (payload_max_length > 0 &&
 8305|    138|                    (decompressed_size >= payload_max_length ||
 8306|    138|                     n2 > payload_max_length - decompressed_size)) {
 8307|    138|                  exceed_payload_max_length = true;
 8308|    138|                  return false;
 8309|    138|                }
 8310|    138|                decompressed_size += n2;
 8311|    138|                return receiver(buf2, n2, off, len);
 8312|    138|              });
 8313|    138|        };
 8314|    138|        return callback(std::move(out));
 8315|    138|      } else {
 8316|      0|        status = StatusCode::InternalServerError_500;
 8317|      0|        return false;
 8318|      0|      }
 8319|    138|    }
 8320|  1.71k|  }
 8321|       |
 8322|  1.57k|  ContentReceiverWithProgress out = [&](const char *buf, size_t n, size_t off,
 8323|  1.57k|                                        size_t len) {
 8324|  1.57k|    return receiver(buf, n, off, len);
 8325|  1.57k|  };
 8326|  1.57k|  return callback(std::move(out));
 8327|  1.71k|}
_ZN7httplib6detail25get_combined_header_valueERKNS0_26insertion_ordered_multimapINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS0_11case_ignore8equal_toEEERKS8_:
 7944|  1.87k|                                             const std::string &key) {
 7945|  1.87k|  std::string combined;
 7946|  1.87k|  auto rng = headers.equal_range(key);
 7947|  2.91k|  for (auto it = rng.first; it != rng.second; ++it) {
  ------------------
  |  Branch (7947:29): [True: 1.04k, False: 1.87k]
  ------------------
 7948|       |    // RFC 9110 Section 5.6.1.2: a recipient has to parse and ignore empty list
 7949|       |    // elements, so an empty field line must not contribute a bare comma to the
 7950|       |    // combined value.
 7951|  1.04k|    if (it->second.empty()) { continue; }
  ------------------
  |  Branch (7951:9): [True: 72, False: 969]
  ------------------
 7952|    969|    if (!combined.empty()) { combined += ", "; }
  ------------------
  |  Branch (7952:9): [True: 790, False: 179]
  ------------------
 7953|    969|    combined += it->second;
 7954|    969|  }
 7955|  1.87k|  return combined;
 7956|  1.87k|}
_ZN7httplib6detail19create_decompressorERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
 7862|    179|create_decompressor(const std::string &encoding) {
 7863|    179|  std::unique_ptr<decompressor> decompressor;
 7864|       |
 7865|    179|  if (is_zlib_encoding(encoding)) {
  ------------------
  |  Branch (7865:7): [True: 138, False: 41]
  ------------------
 7866|    138|#ifdef CPPHTTPLIB_ZLIB_SUPPORT
 7867|    138|    decompressor = detail::make_unique<gzip_decompressor>();
 7868|    138|#endif
 7869|    138|  } else if (is_brotli_encoding(encoding)) {
  ------------------
  |  Branch (7869:14): [True: 1, False: 40]
  ------------------
 7870|       |#ifdef CPPHTTPLIB_BROTLI_SUPPORT
 7871|       |    decompressor = detail::make_unique<brotli_decompressor>();
 7872|       |#endif
 7873|     40|  } else if (is_zstd_encoding(encoding)) {
  ------------------
  |  Branch (7873:14): [True: 1, False: 39]
  ------------------
 7874|       |#ifdef CPPHTTPLIB_ZSTD_SUPPORT
 7875|       |    decompressor = detail::make_unique<zstd_decompressor>();
 7876|       |#endif
 7877|      1|  }
 7878|       |
 7879|    179|  return decompressor;
 7880|    179|}
_ZN7httplib6detail16is_zlib_encodingERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
 7841|    220|inline bool is_zlib_encoding(const std::string &encoding) {
 7842|    220|  return case_ignore::equal(encoding, "gzip") ||
  ------------------
  |  Branch (7842:10): [True: 16, False: 204]
  ------------------
 7843|    204|         case_ignore::equal(encoding, "deflate");
  ------------------
  |  Branch (7843:10): [True: 122, False: 82]
  ------------------
 7844|    220|}
_ZN7httplib6detail11make_uniqueINS0_17gzip_decompressorEJEEENSt3__19enable_ifIXntsr3std8is_arrayIT_EE5valueENS3_10unique_ptrIS5_NS3_14default_deleteIS5_EEEEE4typeEDpOT0_:
  568|    138|make_unique(Args &&...args) {
  569|    138|  return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
  570|    138|}
_ZN7httplib6detail17gzip_decompressorC2Ev:
 7636|    138|inline gzip_decompressor::gzip_decompressor() {
 7637|    138|  std::memset(&strm_, 0, sizeof(strm_));
 7638|    138|  strm_.zalloc = Z_NULL;
 7639|    138|  strm_.zfree = Z_NULL;
 7640|    138|  strm_.opaque = Z_NULL;
 7641|       |
 7642|       |  // 15 is the value of wbits, which should be at the maximum possible value
 7643|       |  // to ensure that any gzip stream can be decoded. The offset of 32 specifies
 7644|       |  // that the stream type should be automatically detected either gzip or
 7645|       |  // deflate.
 7646|    138|  is_valid_ = inflateInit2(&strm_, 32 + 15) == Z_OK;
 7647|    138|}
_ZN7httplib6detail18is_brotli_encodingERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
 7846|     82|inline bool is_brotli_encoding(const std::string &encoding) {
 7847|     82|  return case_ignore::equal(encoding, "br");
 7848|     82|}
_ZN7httplib6detail16is_zstd_encodingERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
 7850|     80|inline bool is_zstd_encoding(const std::string &encoding) {
 7851|     80|  return case_ignore::equal(encoding, "zstd");
 7852|     80|}
_ZN7httplib6detail25is_known_content_encodingERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
 7856|     41|inline bool is_known_content_encoding(const std::string &encoding) {
 7857|     41|  return is_zlib_encoding(encoding) || is_brotli_encoding(encoding) ||
  ------------------
  |  Branch (7857:10): [True: 0, False: 41]
  |  Branch (7857:40): [True: 1, False: 40]
  ------------------
 7858|     40|         is_zstd_encoding(encoding);
  ------------------
  |  Branch (7858:10): [True: 1, False: 39]
  ------------------
 7859|     41|}
_ZZN7httplib6detail24prepare_content_receiverINS_8ResponseEZNS0_12read_contentIS2_EEbRNS_6StreamERT_mRiNSt3__18functionIFbmmEEENSA_IFbPKcmmmEEEbEUlRKSG_E_EEbS7_S8_SG_bmRbT0_ENKUlSE_mmmE_clESE_mmm:
 8299|  1.94k|                                              size_t off, size_t len) {
 8300|  1.94k|          return decompressor->decompress(
 8301|  1.94k|              buf, n, [&](const char *buf2, size_t n2) {
 8302|       |                // Guard against zip-bomb: check
 8303|       |                // decompressed size against limit.
 8304|  1.94k|                if (payload_max_length > 0 &&
 8305|  1.94k|                    (decompressed_size >= payload_max_length ||
 8306|  1.94k|                     n2 > payload_max_length - decompressed_size)) {
 8307|  1.94k|                  exceed_payload_max_length = true;
 8308|  1.94k|                  return false;
 8309|  1.94k|                }
 8310|  1.94k|                decompressed_size += n2;
 8311|  1.94k|                return receiver(buf2, n2, off, len);
 8312|  1.94k|              });
 8313|  1.94k|        };
_ZZZN7httplib6detail24prepare_content_receiverINS_8ResponseEZNS0_12read_contentIS2_EEbRNS_6StreamERT_mRiNSt3__18functionIFbmmEEENSA_IFbPKcmmmEEEbEUlRKSG_E_EEbS7_S8_SG_bmRbT0_ENKUlSE_mmmE_clESE_mmmENKUlSE_mE_clESE_m:
 8301|   120k|              buf, n, [&](const char *buf2, size_t n2) {
 8302|       |                // Guard against zip-bomb: check
 8303|       |                // decompressed size against limit.
 8304|   120k|                if (payload_max_length > 0 &&
  ------------------
  |  Branch (8304:21): [True: 120k, False: 0]
  ------------------
 8305|   120k|                    (decompressed_size >= payload_max_length ||
  ------------------
  |  Branch (8305:22): [True: 1, False: 120k]
  ------------------
 8306|   120k|                     n2 > payload_max_length - decompressed_size)) {
  ------------------
  |  Branch (8306:22): [True: 13, False: 120k]
  ------------------
 8307|     14|                  exceed_payload_max_length = true;
 8308|     14|                  return false;
 8309|     14|                }
 8310|   120k|                decompressed_size += n2;
 8311|   120k|                return receiver(buf2, n2, off, len);
 8312|   120k|              });
_ZZN7httplib6detail12read_contentINS_8ResponseEEEbRNS_6StreamERT_mRiNSt3__18functionIFbmmEEENS9_IFbPKcmmmEEEbENKUlRKSF_E_clESH_:
 8336|  1.71k|      exceed_payload_max_length, [&](const ContentReceiverWithProgress &out) {
 8337|  1.71k|        auto ret = true;
 8338|       |        // Note: exceed_payload_max_length may also be set by the decompressor
 8339|       |        // wrapper in prepare_content_receiver when the decompressed payload
 8340|       |        // size exceeds the limit.
 8341|       |
 8342|  1.71k|        if (is_chunked_transfer_encoding(x.headers)) {
  ------------------
  |  Branch (8342:13): [True: 708, False: 1.00k]
  ------------------
 8343|    708|          auto result = read_content_chunked(strm, x, payload_max_length, out);
 8344|    708|          if (result == ReadContentResult::Success) {
  ------------------
  |  Branch (8344:15): [True: 1, False: 707]
  ------------------
 8345|      1|            ret = true;
 8346|    707|          } else if (result == ReadContentResult::PayloadTooLarge) {
  ------------------
  |  Branch (8346:22): [True: 0, False: 707]
  ------------------
 8347|      0|            exceed_payload_max_length = true;
 8348|      0|            ret = false;
 8349|    707|          } else {
 8350|    707|            ret = false;
 8351|    707|          }
 8352|  1.00k|        } else if (!has_header(x.headers, "Content-Length")) {
  ------------------
  |  Branch (8352:20): [True: 472, False: 533]
  ------------------
 8353|    472|          auto result =
 8354|    472|              read_content_without_length(strm, payload_max_length, out);
 8355|    472|          if (result == ReadContentResult::Success) {
  ------------------
  |  Branch (8355:15): [True: 437, False: 35]
  ------------------
 8356|    437|            ret = true;
 8357|    437|          } else if (result == ReadContentResult::PayloadTooLarge) {
  ------------------
  |  Branch (8357:22): [True: 0, False: 35]
  ------------------
 8358|      0|            exceed_payload_max_length = true;
 8359|      0|            ret = false;
 8360|     35|          } else {
 8361|     35|            ret = false;
 8362|     35|          }
 8363|    533|        } else {
 8364|    533|          auto is_invalid_value = false;
 8365|    533|          auto len = get_header_value_u64(x.headers, "Content-Length",
 8366|    533|                                          (std::numeric_limits<size_t>::max)(),
 8367|    533|                                          0, is_invalid_value);
 8368|       |
 8369|    533|          if (is_invalid_value) {
  ------------------
  |  Branch (8369:15): [True: 68, False: 465]
  ------------------
 8370|     68|            ret = false;
 8371|    465|          } else if (len > 0) {
  ------------------
  |  Branch (8371:22): [True: 452, False: 13]
  ------------------
 8372|    452|            auto result = read_content_with_length(
 8373|    452|                strm, len, std::move(progress), out, payload_max_length);
 8374|    452|            ret = (result == ReadContentResult::Success);
 8375|    452|            if (result == ReadContentResult::PayloadTooLarge) {
  ------------------
  |  Branch (8375:17): [True: 0, False: 452]
  ------------------
 8376|      0|              exceed_payload_max_length = true;
 8377|      0|            }
 8378|    452|          }
 8379|    533|        }
 8380|       |
 8381|  1.71k|        if (!ret) {
  ------------------
  |  Branch (8381:13): [True: 1.26k, False: 452]
  ------------------
 8382|  1.26k|          status = exceed_payload_max_length ? StatusCode::PayloadTooLarge_413
  ------------------
  |  Branch (8382:20): [True: 14, False: 1.24k]
  ------------------
 8383|  1.26k|                                             : StatusCode::BadRequest_400;
 8384|  1.26k|        }
 8385|  1.71k|        return ret;
 8386|  1.71k|      });
_ZN7httplib6detail28is_chunked_transfer_encodingERKNS0_26insertion_ordered_multimapINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS0_11case_ignore8equal_toEEE:
 8242|  1.71k|inline bool is_chunked_transfer_encoding(const Headers &headers) {
 8243|       |  // RFC 9112 6.1: a message is framed with the chunked coding when "chunked"
 8244|       |  // is the final transfer coding. A single field value may list several
 8245|       |  // codings ("gzip, chunked"), and RFC 9110 5.3 lets that list be split across
 8246|       |  // several Transfer-Encoding lines, which combine into one comma-separated
 8247|       |  // list in the order the lines were received. Headers preserves that order,
 8248|       |  // so the final coding is the last token of the last line. Match it
 8249|       |  // case-insensitively rather than comparing the whole value against
 8250|       |  // "chunked".
 8251|       |  //
 8252|       |  // Security: reading a chunked message as unframed leaves its body in the
 8253|       |  // socket, where a keep-alive connection parses it as a smuggled request.
 8254|       |  // Server::process_request() answers 400 and closes when the final coding is
 8255|       |  // not chunked, so a request whose framing cannot be determined never
 8256|       |  // reaches the "no body" path.
 8257|  1.71k|  auto rng = headers.equal_range("Transfer-Encoding");
 8258|  1.71k|  if (rng.first == rng.second) { return false; }
  ------------------
  |  Branch (8258:7): [True: 777, False: 936]
  ------------------
 8259|       |
 8260|       |  // Cleared per line, so a trailing line carrying no coding at all leaves the
 8261|       |  // combined list ending in nothing rather than inheriting the line before it.
 8262|    936|  std::string last_coding;
 8263|       |
 8264|  2.30k|  for (auto it = rng.first; it != rng.second; ++it) {
  ------------------
  |  Branch (8264:29): [True: 1.37k, False: 936]
  ------------------
 8265|  1.37k|    const auto &value = it->second;
 8266|  1.37k|    last_coding.clear();
 8267|  1.37k|    split(value.data(), value.data() + value.size(), ',',
 8268|  1.37k|          [&](const char *b, const char *e) { last_coding.assign(b, e); });
 8269|  1.37k|  }
 8270|       |
 8271|    936|  return case_ignore::equal(last_coding, "chunked");
 8272|  1.71k|}
_ZNK7httplib6detail26insertion_ordered_multimapINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS0_11case_ignore8equal_toEE10iterator_tIKNS2_4pairIS8_S8_EEEeqISF_EEbRKNSC_IT_EE:
 1103|  1.71k|    template <typename U> bool operator==(const iterator_t<U> &rhs) const {
 1104|  1.71k|      return idx_ == rhs.idx_;
 1105|  1.71k|    }
_ZZN7httplib6detail28is_chunked_transfer_encodingERKNS0_26insertion_ordered_multimapINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS0_11case_ignore8equal_toEEEENKUlPKcSF_E_clESF_SF_:
 8268|  4.09k|          [&](const char *b, const char *e) { last_coding.assign(b, e); });
_ZN7httplib6detail20read_content_chunkedINS_8ResponseEEENS0_17ReadContentResultERNS_6StreamERT_mNSt3__18functionIFbPKcmmmEEE:
 8210|    708|                                              ContentReceiverWithProgress out) {
 8211|    708|  detail::ChunkedDecoder dec(strm);
 8212|       |
 8213|    708|  char buf[CPPHTTPLIB_RECV_BUFSIZ];
 8214|    708|  size_t total_len = 0;
 8215|       |
 8216|  4.50k|  for (;;) {
 8217|  4.50k|    size_t chunk_offset = 0;
 8218|  4.50k|    size_t chunk_total = 0;
 8219|  4.50k|    auto n = dec.read_payload(buf, sizeof(buf), chunk_offset, chunk_total);
 8220|  4.50k|    if (n < 0) { return ReadContentResult::Error; }
  ------------------
  |  Branch (8220:9): [True: 530, False: 3.97k]
  ------------------
 8221|       |
 8222|  3.97k|    if (n == 0) {
  ------------------
  |  Branch (8222:9): [True: 176, False: 3.80k]
  ------------------
 8223|    176|      if (!dec.parse_trailers_into(x.trailers, x.headers)) {
  ------------------
  |  Branch (8223:11): [True: 175, False: 1]
  ------------------
 8224|    175|        return ReadContentResult::Error;
 8225|    175|      }
 8226|      1|      return ReadContentResult::Success;
 8227|    176|    }
 8228|       |
 8229|  3.80k|    if (total_len > payload_max_length ||
  ------------------
  |  Branch (8229:9): [True: 0, False: 3.80k]
  ------------------
 8230|  3.80k|        payload_max_length - total_len < static_cast<size_t>(n)) {
  ------------------
  |  Branch (8230:9): [True: 0, False: 3.80k]
  ------------------
 8231|      0|      return ReadContentResult::PayloadTooLarge;
 8232|      0|    }
 8233|       |
 8234|  3.80k|    if (!out(buf, static_cast<size_t>(n), chunk_offset, chunk_total)) {
  ------------------
  |  Branch (8234:9): [True: 2, False: 3.79k]
  ------------------
 8235|      2|      return ReadContentResult::Error;
 8236|      2|    }
 8237|       |
 8238|  3.79k|    total_len += static_cast<size_t>(n);
 8239|  3.79k|  }
 8240|    708|}
_ZN7httplib6detail14ChunkedDecoderC2ERNS_6StreamE:
15108|    708|inline ChunkedDecoder::ChunkedDecoder(Stream &s) : strm(s) {}
_ZN7httplib6detail14ChunkedDecoder12read_payloadEPcmRmS3_:
15112|  4.50k|                                            size_t &out_chunk_total) {
15113|  4.50k|  if (finished) { return 0; }
  ------------------
  |  Branch (15113:7): [True: 0, False: 4.50k]
  ------------------
15114|       |
15115|  4.50k|  if (chunk_remaining == 0) {
  ------------------
  |  Branch (15115:7): [True: 3.97k, False: 533]
  ------------------
15116|  3.97k|    stream_line_reader lr(strm, line_buf, sizeof(line_buf));
15117|  3.97k|    if (!lr.getline()) { return -1; }
  ------------------
  |  Branch (15117:9): [True: 25, False: 3.94k]
  ------------------
15118|       |
15119|       |    // RFC 9112 §7.1: chunk-size = 1*HEXDIG
15120|  3.94k|    const char *p = lr.ptr();
15121|  3.94k|    int v = 0;
15122|  3.94k|    if (!is_hex(*p, v)) { return -1; }
  ------------------
  |  Branch (15122:9): [True: 36, False: 3.91k]
  ------------------
15123|       |
15124|  3.91k|    size_t chunk_len = 0;
15125|  3.91k|    constexpr size_t chunk_len_max = (std::numeric_limits<size_t>::max)();
15126|  11.6k|    for (; is_hex(*p, v); ++p) {
  ------------------
  |  Branch (15126:12): [True: 7.73k, False: 3.90k]
  ------------------
15127|  7.73k|      if (chunk_len > (chunk_len_max >> 4)) { return -1; }
  ------------------
  |  Branch (15127:11): [True: 10, False: 7.72k]
  ------------------
15128|  7.72k|      chunk_len = (chunk_len << 4) | static_cast<size_t>(v);
15129|  7.72k|    }
15130|       |
15131|  4.29k|    while (is_space_or_tab(*p)) {
  ------------------
  |  Branch (15131:12): [True: 396, False: 3.90k]
  ------------------
15132|    396|      ++p;
15133|    396|    }
15134|  3.90k|    if (*p != '\0' && *p != ';' && *p != '\r' && *p != '\n') { return -1; }
  ------------------
  |  Branch (15134:9): [True: 3.46k, False: 434]
  |  Branch (15134:23): [True: 3.25k, False: 209]
  |  Branch (15134:36): [True: 264, False: 2.99k]
  |  Branch (15134:50): [True: 47, False: 217]
  ------------------
15135|       |
15136|  3.85k|    if (chunk_len == 0) {
  ------------------
  |  Branch (15136:9): [True: 176, False: 3.67k]
  ------------------
15137|    176|      chunk_remaining = 0;
15138|    176|      finished = true;
15139|    176|      out_chunk_offset = 0;
15140|    176|      out_chunk_total = 0;
15141|    176|      return 0;
15142|    176|    }
15143|       |
15144|  3.67k|    chunk_remaining = chunk_len;
15145|  3.67k|    last_chunk_total = chunk_remaining;
15146|  3.67k|    last_chunk_offset = 0;
15147|  3.67k|  }
15148|       |
15149|  4.21k|  auto to_read = (std::min)(chunk_remaining, len);
15150|  4.21k|  auto n = strm.read(buf, to_read);
15151|  4.21k|  if (n <= 0) { return -1; }
  ------------------
  |  Branch (15151:7): [True: 381, False: 3.83k]
  ------------------
15152|       |
15153|  3.83k|  auto offset_before = last_chunk_offset;
15154|  3.83k|  last_chunk_offset += static_cast<size_t>(n);
15155|  3.83k|  chunk_remaining -= static_cast<size_t>(n);
15156|       |
15157|  3.83k|  out_chunk_offset = offset_before;
15158|  3.83k|  out_chunk_total = last_chunk_total;
15159|       |
15160|  3.83k|  if (chunk_remaining == 0) {
  ------------------
  |  Branch (15160:7): [True: 3.29k, False: 535]
  ------------------
15161|  3.29k|    stream_line_reader lr(strm, line_buf, sizeof(line_buf));
15162|  3.29k|    if (!lr.getline()) { return -1; }
  ------------------
  |  Branch (15162:9): [True: 4, False: 3.29k]
  ------------------
15163|  3.29k|    if (std::strcmp(lr.ptr(), "\r\n") != 0) { return -1; }
  ------------------
  |  Branch (15163:9): [True: 27, False: 3.26k]
  ------------------
15164|  3.29k|  }
15165|       |
15166|  3.80k|  return n;
15167|  3.83k|}
_ZN7httplib6detail14ChunkedDecoder19parse_trailers_intoERNS0_26insertion_ordered_multimapINSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEENS0_11case_ignore8equal_toEEERKSC_:
15170|    176|                                                const Headers &src_headers) {
15171|    176|  stream_line_reader lr(strm, line_buf, sizeof(line_buf));
15172|    176|  if (!lr.getline()) { return false; }
  ------------------
  |  Branch (15172:7): [True: 19, False: 157]
  ------------------
15173|    157|  return parse_trailers(lr, dest, src_headers);
15174|    176|}
_ZN7httplib6detail14parse_trailersERNS0_18stream_line_readerERNS0_26insertion_ordered_multimapINSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEENS0_11case_ignore8equal_toEEERKSD_:
 5772|    157|                           const Headers &src_headers) {
 5773|       |  // NOTE: In RFC 9112, '7.1 Chunked Transfer Coding' mentions "The chunked
 5774|       |  // transfer coding is complete when a chunk with a chunk-size of zero is
 5775|       |  // received, possibly followed by a trailer section, and finally terminated by
 5776|       |  // an empty line". https://www.rfc-editor.org/rfc/rfc9112.html#section-7.1
 5777|       |  //
 5778|       |  // In '7.1.3. Decoding Chunked', however, the pseudo-code in the section
 5779|       |  // doesn't care for the existence of the final CRLF. In other words, it seems
 5780|       |  // to be ok whether the final CRLF exists or not in the chunked data.
 5781|       |  // https://www.rfc-editor.org/rfc/rfc9112.html#section-7.1.3
 5782|       |  //
 5783|       |  // According to the reference code in RFC 9112, cpp-httplib now allows
 5784|       |  // chunked transfer coding data without the final CRLF.
 5785|       |
 5786|       |  // RFC 7230 Section 4.1.2 - Headers prohibited in trailers
 5787|    157|  thread_local case_ignore::unordered_set<std::string> prohibited_trailers = {
 5788|    157|      "transfer-encoding",
 5789|    157|      "content-length",
 5790|    157|      "host",
 5791|    157|      "authorization",
 5792|    157|      "www-authenticate",
 5793|    157|      "proxy-authenticate",
 5794|    157|      "proxy-authorization",
 5795|    157|      "cookie",
 5796|    157|      "set-cookie",
 5797|    157|      "cache-control",
 5798|    157|      "expect",
 5799|    157|      "max-forwards",
 5800|    157|      "pragma",
 5801|    157|      "range",
 5802|    157|      "te",
 5803|    157|      "age",
 5804|    157|      "expires",
 5805|    157|      "date",
 5806|    157|      "location",
 5807|    157|      "retry-after",
 5808|    157|      "vary",
 5809|    157|      "warning",
 5810|    157|      "content-encoding",
 5811|    157|      "content-type",
 5812|    157|      "content-range",
 5813|    157|      "trailer"};
 5814|       |
 5815|    157|  case_ignore::unordered_set<std::string> declared_trailers;
 5816|    157|  auto trailer_header = get_combined_header_value(src_headers, "Trailer");
 5817|    157|  if (!trailer_header.empty()) {
  ------------------
  |  Branch (5817:7): [True: 0, False: 157]
  ------------------
 5818|       |    // split() trims each token and skips empty ones, so the name arrives ready
 5819|       |    // to look up.
 5820|      0|    split(trailer_header.data(), trailer_header.data() + trailer_header.size(),
 5821|      0|          ',', [&](const char *b, const char *e) {
 5822|      0|            std::string key(b, e);
 5823|      0|            if (prohibited_trailers.find(key) == prohibited_trailers.end()) {
 5824|      0|              declared_trailers.insert(key);
 5825|      0|            }
 5826|      0|          });
 5827|      0|  }
 5828|       |
 5829|    157|  size_t trailer_header_count = 0;
 5830|  3.75k|  while (strcmp(line_reader.ptr(), "\r\n") != 0) {
  ------------------
  |  Branch (5830:10): [True: 3.75k, False: 1]
  ------------------
 5831|  3.75k|    if (line_reader.size() > CPPHTTPLIB_HEADER_MAX_LENGTH) { return false; }
  ------------------
  |  |  114|  3.75k|#define CPPHTTPLIB_HEADER_MAX_LENGTH 8192
  ------------------
  |  Branch (5831:9): [True: 2, False: 3.75k]
  ------------------
 5832|  3.75k|    if (trailer_header_count >= CPPHTTPLIB_HEADER_MAX_COUNT) { return false; }
  ------------------
  |  |  118|  3.75k|#define CPPHTTPLIB_HEADER_MAX_COUNT 100
  ------------------
  |  Branch (5832:9): [True: 0, False: 3.75k]
  ------------------
 5833|       |
 5834|  3.75k|    constexpr auto line_terminator_len = 2;
 5835|  3.75k|    auto line_beg = line_reader.ptr();
 5836|  3.75k|    auto line_end =
 5837|  3.75k|        line_reader.ptr() + line_reader.size() - line_terminator_len;
 5838|       |
 5839|  3.75k|    if (!parse_header(line_beg, line_end,
  ------------------
  |  Branch (5839:9): [True: 109, False: 3.64k]
  ------------------
 5840|  3.75k|                      [&](const std::string &key, const std::string &val) {
 5841|  3.75k|                        if (declared_trailers.find(key) !=
 5842|  3.75k|                            declared_trailers.end()) {
 5843|  3.75k|                          dest.emplace(key, val);
 5844|  3.75k|                          trailer_header_count++;
 5845|  3.75k|                        }
 5846|  3.75k|                      })) {
 5847|    109|      return false;
 5848|    109|    }
 5849|       |
 5850|  3.64k|    if (!line_reader.getline()) { return false; }
  ------------------
  |  Branch (5850:9): [True: 45, False: 3.59k]
  ------------------
 5851|  3.64k|  }
 5852|       |
 5853|      1|  return true;
 5854|    157|}
_ZNK7httplib6detail11case_ignore4hashclERKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEE:
  642|     26|  size_t operator()(const std::string &key) const {
  643|     26|    return hash_core(key.data(), key.size(), 0);
  644|     26|  }
_ZNK7httplib6detail11case_ignore4hash9hash_coreEPKcmm:
  646|    279|  size_t hash_core(const char *s, size_t l, size_t h) const {
  647|    279|    return (l == 0) ? h
  ------------------
  |  Branch (647:12): [True: 26, False: 253]
  ------------------
  648|    279|                    : hash_core(s + 1, l - 1,
  649|       |                                // Unsets the 6 high bits of h, therefore no
  650|       |                                // overflow happens
  651|    253|                                (((std::numeric_limits<size_t>::max)() >> 6) &
  652|    253|                                 h * 33) ^
  653|    253|                                    static_cast<unsigned char>(to_lower(*s)));
  654|    279|  }
_ZN7httplib6detail12parse_headerIZNS0_14parse_trailersERNS0_18stream_line_readerERNS0_26insertion_ordered_multimapINSt3__112basic_stringIcNS5_11char_traitsIcEENS5_9allocatorIcEEEENS0_11case_ignore8equal_toEEERKSE_EUlRKSB_SJ_E_EEbPKcSM_T_:
 5726|  3.75k|inline bool parse_header(const char *beg, const char *end, T fn) {
 5727|       |  // Skip trailing spaces and tabs.
 5728|  4.01k|  while (beg < end && is_space_or_tab(end[-1])) {
  ------------------
  |  Branch (5728:10): [True: 3.97k, False: 41]
  |  Branch (5728:23): [True: 269, False: 3.70k]
  ------------------
 5729|    269|    end--;
 5730|    269|  }
 5731|       |
 5732|  3.75k|  auto p = beg;
 5733|  83.8k|  while (p < end && *p != ':') {
  ------------------
  |  Branch (5733:10): [True: 83.7k, False: 81]
  |  Branch (5733:21): [True: 80.1k, False: 3.66k]
  ------------------
 5734|  80.1k|    p++;
 5735|  80.1k|  }
 5736|       |
 5737|  3.75k|  auto name = std::string(beg, p);
 5738|  3.75k|  if (!detail::fields::is_field_name(name)) { return false; }
  ------------------
  |  Branch (5738:7): [True: 75, False: 3.67k]
  ------------------
 5739|       |
 5740|  3.67k|  if (p == end) { return false; }
  ------------------
  |  Branch (5740:7): [True: 17, False: 3.65k]
  ------------------
 5741|       |
 5742|  3.65k|  auto key_end = p;
 5743|       |
 5744|  3.65k|  if (*p++ != ':') { return false; }
  ------------------
  |  Branch (5744:7): [True: 0, False: 3.65k]
  ------------------
 5745|       |
 5746|  4.13k|  while (p < end && is_space_or_tab(*p)) {
  ------------------
  |  Branch (5746:10): [True: 2.13k, False: 2.00k]
  |  Branch (5746:21): [True: 481, False: 1.65k]
  ------------------
 5747|    481|    p++;
 5748|    481|  }
 5749|       |
 5750|  3.65k|  if (p <= end) {
  ------------------
  |  Branch (5750:7): [True: 3.65k, False: 0]
  ------------------
 5751|  3.65k|    auto key_len = key_end - beg;
 5752|  3.65k|    if (!key_len) { return false; }
  ------------------
  |  Branch (5752:9): [True: 0, False: 3.65k]
  ------------------
 5753|       |
 5754|  3.65k|    auto key = std::string(beg, key_end);
 5755|  3.65k|    auto val = std::string(p, end);
 5756|       |
 5757|  3.65k|    if (!detail::fields::is_field_value(val)) { return false; }
  ------------------
  |  Branch (5757:9): [True: 17, False: 3.64k]
  ------------------
 5758|       |
 5759|       |    // RFC 9110 §5.5: header field values are opaque octets and MUST NOT be
 5760|       |    // percent-decoded by the recipient. Applications that need to interpret a
 5761|       |    // value as a URI component should call httplib::decode_uri_component()
 5762|       |    // (or decode_path_component()) explicitly.
 5763|  3.64k|    fn(key, val);
 5764|       |
 5765|  3.64k|    return true;
 5766|  3.65k|  }
 5767|       |
 5768|      0|  return false;
 5769|  3.65k|}
_ZZN7httplib6detail14parse_trailersERNS0_18stream_line_readerERNS0_26insertion_ordered_multimapINSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEENS0_11case_ignore8equal_toEEERKSD_ENKUlRKSA_SI_E_clESI_SI_:
 5840|  3.64k|                      [&](const std::string &key, const std::string &val) {
 5841|  3.64k|                        if (declared_trailers.find(key) !=
  ------------------
  |  Branch (5841:29): [True: 0, False: 3.64k]
  ------------------
 5842|  3.64k|                            declared_trailers.end()) {
 5843|      0|                          dest.emplace(key, val);
 5844|      0|                          trailer_header_count++;
 5845|      0|                        }
 5846|  3.64k|                      })) {
_ZN7httplib6detail27read_content_without_lengthERNS_6StreamEmNSt3__18functionIFbPKcmmmEEE:
 8184|    472|                            ContentReceiverWithProgress out) {
 8185|    472|  char buf[CPPHTTPLIB_RECV_BUFSIZ];
 8186|    472|  size_t r = 0;
 8187|  1.79k|  for (;;) {
 8188|  1.79k|    auto n = strm.read(buf, CPPHTTPLIB_RECV_BUFSIZ);
  ------------------
  |  |  172|  1.79k|#define CPPHTTPLIB_RECV_BUFSIZ size_t(16384u)
  ------------------
 8189|  1.79k|    if (n == 0) { return ReadContentResult::Success; }
  ------------------
  |  Branch (8189:9): [True: 437, False: 1.35k]
  ------------------
 8190|  1.35k|    if (n < 0) { return ReadContentResult::Error; }
  ------------------
  |  Branch (8190:9): [True: 0, False: 1.35k]
  ------------------
 8191|       |
 8192|       |    // Check if adding this data would exceed the payload limit
 8193|  1.35k|    if (r > payload_max_length ||
  ------------------
  |  Branch (8193:9): [True: 0, False: 1.35k]
  ------------------
 8194|  1.35k|        payload_max_length - r < static_cast<size_t>(n)) {
  ------------------
  |  Branch (8194:9): [True: 0, False: 1.35k]
  ------------------
 8195|      0|      return ReadContentResult::PayloadTooLarge;
 8196|      0|    }
 8197|       |
 8198|  1.35k|    if (!out(buf, static_cast<size_t>(n), r, 0)) {
  ------------------
  |  Branch (8198:9): [True: 35, False: 1.31k]
  ------------------
 8199|     35|      return ReadContentResult::Error;
 8200|     35|    }
 8201|  1.31k|    r += static_cast<size_t>(n);
 8202|  1.31k|  }
 8203|       |
 8204|      0|  return ReadContentResult::Success;
 8205|    472|}
_ZN7httplib6detail24read_content_with_lengthERNS_6StreamEmNSt3__18functionIFbmmEEENS4_IFbPKcmmmEEEm:
 8144|    452|    size_t payload_max_length = (std::numeric_limits<size_t>::max)()) {
 8145|    452|  char buf[CPPHTTPLIB_RECV_BUFSIZ];
 8146|       |
 8147|    452|  detail::BodyReader br;
 8148|    452|  br.stream = &strm;
 8149|    452|  br.has_content_length = true;
 8150|    452|  br.content_length = len;
 8151|    452|  br.payload_max_length = payload_max_length;
 8152|    452|  br.chunked = false;
 8153|    452|  br.bytes_read = 0;
 8154|    452|  br.last_error = Error::Success;
 8155|       |
 8156|    452|  size_t r = 0;
 8157|  1.01k|  while (r < len) {
  ------------------
  |  Branch (8157:10): [True: 1.00k, False: 1]
  ------------------
 8158|  1.00k|    auto read_len = static_cast<size_t>(len - r);
 8159|  1.00k|    auto to_read = (std::min)(read_len, CPPHTTPLIB_RECV_BUFSIZ);
  ------------------
  |  |  172|  1.00k|#define CPPHTTPLIB_RECV_BUFSIZ size_t(16384u)
  ------------------
 8160|  1.00k|    auto n = detail::read_body_content(&strm, br, buf, to_read);
 8161|  1.00k|    if (n <= 0) {
  ------------------
  |  Branch (8161:9): [True: 448, False: 561]
  ------------------
 8162|       |      // Check if it was a payload size error
 8163|    448|      if (br.last_error == Error::ExceedMaxPayloadSize) {
  ------------------
  |  Branch (8163:11): [True: 0, False: 448]
  ------------------
 8164|      0|        return ReadContentResult::PayloadTooLarge;
 8165|      0|      }
 8166|    448|      return ReadContentResult::Error;
 8167|    448|    }
 8168|       |
 8169|    561|    if (!out(buf, static_cast<size_t>(n), r, len)) {
  ------------------
  |  Branch (8169:9): [True: 3, False: 558]
  ------------------
 8170|      3|      return ReadContentResult::Error;
 8171|      3|    }
 8172|    558|    r += static_cast<size_t>(n);
 8173|       |
 8174|    558|    if (progress) {
  ------------------
  |  Branch (8174:9): [True: 558, False: 0]
  ------------------
 8175|    558|      if (!progress(r, len)) { return ReadContentResult::Error; }
  ------------------
  |  Branch (8175:11): [True: 0, False: 558]
  ------------------
 8176|    558|    }
 8177|    558|  }
 8178|       |
 8179|      1|  return ReadContentResult::Success;
 8180|    452|}
_ZN7httplib6detail17read_body_contentEPNS_6StreamERNS0_10BodyReaderEPcm:
 2574|  1.00k|                                 size_t len) {
 2575|  1.00k|  (void)stream;
 2576|  1.00k|  return br.read(buf, len);
 2577|  1.00k|}
_ZN7httplib6detail10BodyReader4readEPcm:
11589|  1.00k|inline ssize_t detail::BodyReader::read(char *buf, size_t len) {
11590|  1.00k|  if (!stream) {
  ------------------
  |  Branch (11590:7): [True: 0, False: 1.00k]
  ------------------
11591|      0|    last_error = Error::Connection;
11592|      0|    return -1;
11593|      0|  }
11594|  1.00k|  if (eof) { return 0; }
  ------------------
  |  Branch (11594:7): [True: 0, False: 1.00k]
  ------------------
11595|       |
11596|  1.00k|  if (!chunked) {
  ------------------
  |  Branch (11596:7): [True: 1.00k, False: 0]
  ------------------
11597|       |    // Content-Length based reading
11598|  1.00k|    if (has_content_length && bytes_read >= content_length) {
  ------------------
  |  Branch (11598:9): [True: 1.00k, False: 0]
  |  Branch (11598:31): [True: 0, False: 1.00k]
  ------------------
11599|      0|      eof = true;
11600|      0|      return 0;
11601|      0|    }
11602|       |
11603|  1.00k|    auto to_read = len;
11604|  1.00k|    if (has_content_length) {
  ------------------
  |  Branch (11604:9): [True: 1.00k, False: 0]
  ------------------
11605|  1.00k|      auto remaining = content_length - bytes_read;
11606|  1.00k|      to_read = (std::min)(len, remaining);
11607|  1.00k|    }
11608|  1.00k|    auto n = stream->read(buf, to_read);
11609|       |
11610|  1.00k|    if (n < 0) {
  ------------------
  |  Branch (11610:9): [True: 0, False: 1.00k]
  ------------------
11611|      0|      last_error = stream->get_error();
11612|      0|      if (last_error == Error::Success) { last_error = Error::Read; }
  ------------------
  |  Branch (11612:11): [True: 0, False: 0]
  ------------------
11613|      0|      eof = true;
11614|      0|      return n;
11615|      0|    }
11616|  1.00k|    if (n == 0) {
  ------------------
  |  Branch (11616:9): [True: 448, False: 561]
  ------------------
11617|       |      // Unexpected EOF before content_length
11618|    448|      last_error = stream->get_error();
11619|    448|      if (last_error == Error::Success) { last_error = Error::Read; }
  ------------------
  |  Branch (11619:11): [True: 448, False: 0]
  ------------------
11620|    448|      eof = true;
11621|    448|      return 0;
11622|    448|    }
11623|       |
11624|    561|    bytes_read += static_cast<size_t>(n);
11625|    561|    if (has_content_length && bytes_read >= content_length) { eof = true; }
  ------------------
  |  Branch (11625:9): [True: 561, False: 0]
  |  Branch (11625:31): [True: 1, False: 560]
  ------------------
11626|    561|    if (payload_max_length > 0 && bytes_read > payload_max_length) {
  ------------------
  |  Branch (11626:9): [True: 561, False: 0]
  |  Branch (11626:35): [True: 0, False: 561]
  ------------------
11627|      0|      last_error = Error::ExceedMaxPayloadSize;
11628|      0|      eof = true;
11629|      0|      return -1;
11630|      0|    }
11631|    561|    return n;
11632|    561|  }
11633|       |
11634|       |  // Chunked transfer encoding: delegate to shared decoder instance.
11635|      0|  if (!chunked_decoder) { chunked_decoder.reset(new ChunkedDecoder(*stream)); }
  ------------------
  |  Branch (11635:7): [True: 0, False: 0]
  ------------------
11636|       |
11637|      0|  size_t chunk_offset = 0;
11638|      0|  size_t chunk_total = 0;
11639|      0|  auto n = chunked_decoder->read_payload(buf, len, chunk_offset, chunk_total);
11640|      0|  if (n < 0) {
  ------------------
  |  Branch (11640:7): [True: 0, False: 0]
  ------------------
11641|      0|    last_error = stream->get_error();
11642|      0|    if (last_error == Error::Success) { last_error = Error::Read; }
  ------------------
  |  Branch (11642:9): [True: 0, False: 0]
  ------------------
11643|      0|    eof = true;
11644|      0|    return n;
11645|      0|  }
11646|       |
11647|      0|  if (n == 0) {
  ------------------
  |  Branch (11647:7): [True: 0, False: 0]
  ------------------
11648|       |    // Final chunk observed. Leave trailer parsing to the caller (StreamHandle).
11649|      0|    eof = true;
11650|      0|    return 0;
11651|      0|  }
11652|       |
11653|      0|  bytes_read += static_cast<size_t>(n);
11654|      0|  if (payload_max_length > 0 && bytes_read > payload_max_length) {
  ------------------
  |  Branch (11654:7): [True: 0, False: 0]
  |  Branch (11654:33): [True: 0, False: 0]
  ------------------
11655|      0|    last_error = Error::ExceedMaxPayloadSize;
11656|      0|    eof = true;
11657|      0|    return -1;
11658|      0|  }
11659|      0|  return n;
11660|      0|}
_ZNK7httplib6Stream9get_errorEv:
 1910|    448|  Error get_error() const { return error_; }
_ZZN7httplib6detail24prepare_content_receiverINS_8ResponseEZNS0_12read_contentIS2_EEbRNS_6StreamERT_mRiNSt3__18functionIFbmmEEENSA_IFbPKcmmmEEEbEUlRKSG_E_EEbS7_S8_SG_bmRbT0_ENKUlSE_mmmE0_clESE_mmm:
 8323|  3.76k|                                        size_t len) {
 8324|  3.76k|    return receiver(buf, n, off, len);
 8325|  3.76k|  };
_ZZN7httplib10ClientImpl15process_requestERNS_6StreamERNS_7RequestERNS_8ResponseEbRNS_5ErrorEENKUlmmE_clEmm:
15954|    558|    auto progress = [&](size_t current, size_t total) {
15955|    558|      if (!req.download_progress || redirect) { return true; }
  ------------------
  |  Branch (15955:11): [True: 558, False: 0]
  |  Branch (15955:37): [True: 0, False: 0]
  ------------------
15956|      0|      auto ret = req.download_progress(current, total);
15957|      0|      if (!ret) {
  ------------------
  |  Branch (15957:11): [True: 0, False: 0]
  ------------------
15958|      0|        error = Error::Canceled;
15959|      0|        output_error_log(error, &req);
15960|      0|      }
15961|      0|      return ret;
15962|    558|    };
_ZNK7httplib10ClientImpl10output_logERKNS_7RequestERKNS_8ResponseE:
15809|    476|                                   const Response &res) const {
15810|    476|  if (logger_) {
  ------------------
  |  Branch (15810:7): [True: 0, False: 476]
  ------------------
15811|      0|    std::lock_guard<std::mutex> guard(logger_mutex_);
15812|      0|    logger_(req, res);
15813|      0|  }
15814|    476|}
_ZN7httplib8ResponseD2Ev:
 1805|  3.08k|  ~Response() {
 1806|  3.08k|    if (content_provider_resource_releaser_) {
  ------------------
  |  Branch (1806:9): [True: 0, False: 3.08k]
  ------------------
 1807|      0|      content_provider_resource_releaser_(content_provider_success_);
 1808|      0|    }
 1809|  3.08k|  }
_ZNK7httplib6detail17gzip_decompressor8is_validEv:
 7651|    138|inline bool gzip_decompressor::is_valid() const { return is_valid_; }
_ZN7httplib6detail17gzip_decompressor10decompressEPKcmNSt3__18functionIFbS3_mEEE:
 7654|  1.94k|                                          Callback callback) {
 7655|  1.94k|  assert(is_valid_);
  ------------------
  |  Branch (7655:3): [True: 1.94k, False: 0]
  ------------------
 7656|       |
 7657|  1.94k|  auto ret = Z_OK;
 7658|       |
 7659|  1.94k|  do {
 7660|  1.94k|    constexpr size_t max_avail_in =
 7661|  1.94k|        (std::numeric_limits<decltype(strm_.avail_in)>::max)();
 7662|       |
 7663|  1.94k|    strm_.avail_in = static_cast<decltype(strm_.avail_in)>(
 7664|  1.94k|        (std::min)(data_length, max_avail_in));
 7665|  1.94k|    strm_.next_in = const_cast<Bytef *>(reinterpret_cast<const Bytef *>(data));
 7666|       |
 7667|  1.94k|    data_length -= strm_.avail_in;
 7668|  1.94k|    data += strm_.avail_in;
 7669|       |
 7670|  1.94k|    std::array<char, CPPHTTPLIB_COMPRESSION_BUFSIZ> buff{};
 7671|   122k|    while (strm_.avail_in > 0 && ret == Z_OK) {
  ------------------
  |  Branch (7671:12): [True: 120k, False: 1.64k]
  |  Branch (7671:34): [True: 120k, False: 258]
  ------------------
 7672|   120k|      strm_.avail_out = static_cast<uInt>(buff.size());
 7673|   120k|      strm_.next_out = reinterpret_cast<Bytef *>(buff.data());
 7674|       |
 7675|   120k|      ret = inflate(&strm_, Z_NO_FLUSH);
 7676|       |
 7677|   120k|      assert(ret != Z_STREAM_ERROR);
  ------------------
  |  Branch (7677:7): [True: 120k, False: 0]
  ------------------
 7678|   120k|      switch (ret) {
  ------------------
  |  Branch (7678:15): [True: 26, False: 120k]
  ------------------
 7679|      1|      case Z_NEED_DICT:
  ------------------
  |  Branch (7679:7): [True: 1, False: 120k]
  ------------------
 7680|     26|      case Z_DATA_ERROR:
  ------------------
  |  Branch (7680:7): [True: 25, False: 120k]
  ------------------
 7681|     26|      case Z_MEM_ERROR: inflateEnd(&strm_); return false;
  ------------------
  |  Branch (7681:7): [True: 0, False: 120k]
  ------------------
 7682|   120k|      }
 7683|       |
 7684|   120k|      if (!callback(buff.data(), buff.size() - strm_.avail_out)) {
  ------------------
  |  Branch (7684:11): [True: 14, False: 120k]
  ------------------
 7685|     14|        return false;
 7686|     14|      }
 7687|   120k|    }
 7688|       |
 7689|  1.90k|    if (ret != Z_OK && ret != Z_STREAM_END) { return false; }
  ------------------
  |  Branch (7689:9): [True: 259, False: 1.64k]
  |  Branch (7689:24): [True: 0, False: 259]
  ------------------
 7690|       |
 7691|  1.90k|  } while (data_length > 0);
  ------------------
  |  Branch (7691:12): [True: 0, False: 1.90k]
  ------------------
 7692|       |
 7693|  1.90k|  return true;
 7694|  1.94k|}
_ZN7httplib6detail12BufferStreamD2Ev:
 3671|  3.08k|  ~BufferStream() override = default;
_ZN7httplib6detail12BufferStream5writeEPKcm:
11999|  20.3k|inline ssize_t BufferStream::write(const char *ptr, size_t size) {
12000|  20.3k|  buffer.append(ptr, size);
12001|  20.3k|  return static_cast<ssize_t>(size);
12002|  20.3k|}
_ZNK7httplib6Stream13buffered_dataERm:
 1899|  3.69M|  virtual const char *buffered_data(size_t &size) const {
 1900|  3.69M|    size = 0;
 1901|  3.69M|    return nullptr;
 1902|  3.69M|  }
_ZNK7httplib10ClientImpl6is_sslEv:
16073|  3.08k|inline bool ClientImpl::is_ssl() const { return false; }

LLVMFuzzerTestOneInput:
   69|  3.08k|extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
   70|  3.08k|  if (size < 1) return 0;
  ------------------
  |  Branch (70:7): [True: 0, False: 3.08k]
  ------------------
   71|       |
   72|  3.08k|  FuzzedStream stream{data + 1, size - 1};
   73|  3.08k|  FuzzableClient client;
   74|       |
   75|       |  // Use the first byte to select method
   76|  3.08k|  std::string method;
   77|  3.08k|  switch (data[0] % 6) {
  ------------------
  |  Branch (77:11): [True: 3.08k, False: 0]
  ------------------
   78|    147|  case 0: method = "GET"; break;
  ------------------
  |  Branch (78:3): [True: 147, False: 2.93k]
  ------------------
   79|    639|  case 1: method = "POST"; break;
  ------------------
  |  Branch (79:3): [True: 639, False: 2.44k]
  ------------------
   80|    951|  case 2: method = "PUT"; break;
  ------------------
  |  Branch (80:3): [True: 951, False: 2.13k]
  ------------------
   81|    284|  case 3: method = "PATCH"; break;
  ------------------
  |  Branch (81:3): [True: 284, False: 2.80k]
  ------------------
   82|    264|  case 4: method = "DELETE"; break;
  ------------------
  |  Branch (82:3): [True: 264, False: 2.82k]
  ------------------
   83|    799|  case 5: method = "OPTIONS"; break;
  ------------------
  |  Branch (83:3): [True: 799, False: 2.28k]
  ------------------
   84|  3.08k|  }
   85|       |
   86|  3.08k|  client.ProcessFuzzedResponse(stream, method);
   87|  3.08k|  return 0;
   88|  3.08k|}
_ZN12FuzzedStreamC2EPKhm:
    8|  3.08k|      : data_(data), size_(size), read_pos_(0) {}
_ZN12FuzzedStream4readEPcm:
   10|  3.69M|  ssize_t read(char *ptr, size_t size) override {
   11|  3.69M|    if (size + read_pos_ > size_) { size = size_ - read_pos_; }
  ------------------
  |  Branch (11:9): [True: 3.15k, False: 3.69M]
  ------------------
   12|  3.69M|    memcpy(ptr, data_ + read_pos_, size);
   13|  3.69M|    read_pos_ += size;
   14|  3.69M|    return static_cast<ssize_t>(size);
   15|  3.69M|  }
_ZN12FuzzedStream5writeEPKcm:
   17|  3.08k|  ssize_t write(const char *ptr, size_t size) override {
   18|  3.08k|    request_.append(ptr, size);
   19|  3.08k|    return static_cast<ssize_t>(size);
   20|  3.08k|  }
_ZN14FuzzableClientC2Ev:
   55|  3.08k|  FuzzableClient() : httplib::ClientImpl("localhost", 8080) {}
_ZN14FuzzableClient21ProcessFuzzedResponseER12FuzzedStreamRKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
   57|  3.08k|  void ProcessFuzzedResponse(FuzzedStream &stream, const std::string &method) {
   58|  3.08k|    httplib::Request req;
   59|  3.08k|    req.method = method;
   60|  3.08k|    req.path = "/";
   61|  3.08k|    httplib::Response res;
   62|  3.08k|    bool close_connection = false;
   63|  3.08k|    httplib::Error error = httplib::Error::Success;
   64|       |
   65|  3.08k|    process_request(stream, req, res, close_connection, error);
   66|  3.08k|  }

