_ZN7httplib6detail17gzip_decompressorD2Ev:
 6806|     86|inline gzip_decompressor::~gzip_decompressor() { inflateEnd(&strm_); }
_ZN7httplib10ClientImplD2Ev:
12569|  1.96k|inline ClientImpl::~ClientImpl() {
12570|       |  // Wait until all the requests in flight are handled.
12571|  1.96k|  size_t retry_count = 10;
12572|  1.96k|  while (retry_count-- > 0) {
  ------------------
  |  Branch (12572:10): [True: 1.96k, False: 0]
  ------------------
12573|  1.96k|    {
12574|  1.96k|      std::lock_guard<std::mutex> guard(socket_mutex_);
12575|  1.96k|      if (socket_requests_in_flight_ == 0) { break; }
  ------------------
  |  Branch (12575:11): [True: 1.96k, False: 0]
  ------------------
12576|  1.96k|    }
12577|      0|    std::this_thread::sleep_for(std::chrono::milliseconds{1});
12578|      0|  }
12579|       |
12580|  1.96k|  std::lock_guard<std::mutex> guard(socket_mutex_);
12581|  1.96k|  shutdown_socket(socket_);
12582|  1.96k|  close_socket(socket_);
12583|  1.96k|}
_ZN7httplib6detail12decompressorD2Ev:
 3136|     86|  virtual ~decompressor() = default;
_ZN7httplib6StreamD2Ev:
 1450|  3.92k|  virtual ~Stream() = default;
_ZNK7httplib10ClientImpl15shutdown_socketERNS0_6SocketE:
12698|  1.96k|inline void ClientImpl::shutdown_socket(Socket &socket) const {
12699|  1.96k|  if (socket.sock == INVALID_SOCKET) { return; }
  ------------------
  |  |  300|  1.96k|#define INVALID_SOCKET (-1)
  ------------------
  |  Branch (12699:7): [True: 1.96k, False: 0]
  ------------------
12700|      0|  detail::shutdown_socket(socket.sock);
12701|      0|}
_ZN7httplib10ClientImpl12close_socketERNS0_6SocketE:
12703|  1.96k|inline void ClientImpl::close_socket(Socket &socket) {
12704|       |  // If there are requests in flight in another thread, usually closing
12705|       |  // the socket will be fine and they will simply receive an error when
12706|       |  // using the closed socket, but it is still a bug since rarely the OS
12707|       |  // may reassign the socket id to be used for a new socket, and then
12708|       |  // suddenly they will be operating on a live socket that is different
12709|       |  // than the one they intended!
12710|  1.96k|  assert(socket_requests_in_flight_ == 0 ||
  ------------------
  |  Branch (12710:3): [True: 1.96k, False: 0]
  |  Branch (12710:3): [True: 0, False: 0]
  |  Branch (12710:3): [True: 1.96k, False: 0]
  ------------------
12711|  1.96k|         socket_requests_are_from_thread_ == std::this_thread::get_id());
12712|       |
12713|       |  // It is also a bug if this happens while SSL is still active
12714|       |#ifdef CPPHTTPLIB_SSL_ENABLED
12715|       |  assert(socket.ssl == nullptr);
12716|       |#endif
12717|       |
12718|  1.96k|  if (socket.sock == INVALID_SOCKET) { return; }
  ------------------
  |  |  300|  1.96k|#define INVALID_SOCKET (-1)
  ------------------
  |  Branch (12718:7): [True: 1.96k, False: 0]
  ------------------
12719|      0|  detail::close_socket(socket.sock);
12720|      0|  socket.sock = INVALID_SOCKET;
  ------------------
  |  |  300|      0|#define INVALID_SOCKET (-1)
  ------------------
12721|      0|}
_ZN7httplib10ClientImplC2ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEi:
12561|  1.96k|    : ClientImpl(host, port, std::string(), std::string()) {}
_ZN7httplib10ClientImplC2ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEiS9_S9_:
12566|  1.96k|    : host_(detail::escape_abstract_namespace_unix_domain(host)), port_(port),
12567|  1.96k|      client_cert_path_(client_cert_path), client_key_path_(client_key_path) {}
_ZN7httplib6detail37escape_abstract_namespace_unix_domainERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
 5730|  1.96k|inline std::string escape_abstract_namespace_unix_domain(const std::string &s) {
 5731|  1.96k|  if (s.size() > 1 && s[0] == '\0') {
  ------------------
  |  Branch (5731:7): [True: 1.96k, False: 0]
  |  Branch (5731:23): [True: 0, False: 1.96k]
  ------------------
 5732|      0|    auto ret = s;
 5733|      0|    ret[0] = '@';
 5734|      0|    return ret;
 5735|      0|  }
 5736|  1.96k|  return s;
 5737|  1.96k|}
_ZN7httplib6detail13write_headersERNS_6StreamERKNSt3__118unordered_multimapINS3_12basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEESA_NS0_11case_ignore4hashENSB_8equal_toENS8_INS3_4pairIKSA_SA_EEEEEE:
 7428|  1.96k|inline ssize_t write_headers(Stream &strm, const Headers &headers) {
 7429|  1.96k|  ssize_t write_len = 0;
 7430|  9.16k|  for (const auto &x : headers) {
  ------------------
  |  Branch (7430:22): [True: 9.16k, False: 1.96k]
  ------------------
 7431|  9.16k|    std::string s;
 7432|  9.16k|    s = x.first;
 7433|  9.16k|    s += ": ";
 7434|  9.16k|    s += x.second;
 7435|  9.16k|    s += "\r\n";
 7436|       |
 7437|  9.16k|    auto len = strm.write(s.data(), s.size());
 7438|  9.16k|    if (len < 0) { return len; }
  ------------------
  |  Branch (7438:9): [True: 0, False: 9.16k]
  ------------------
 7439|  9.16k|    write_len += len;
 7440|  9.16k|  }
 7441|  1.96k|  auto len = strm.write("\r\n");
 7442|  1.96k|  if (len < 0) { return len; }
  ------------------
  |  Branch (7442:7): [True: 0, False: 1.96k]
  ------------------
 7443|  1.96k|  write_len += len;
 7444|  1.96k|  return write_len;
 7445|  1.96k|}
_ZN7httplib6Stream5writeEPKc:
10076|  1.96k|inline ssize_t Stream::write(const char *ptr) {
10077|  1.96k|  return write(ptr, strlen(ptr));
10078|  1.96k|}
_ZN7httplib8ResponseC2Ev:
 1383|  1.96k|  Response() = default;
_ZN7httplib8UserDataC2Ev:
  936|  1.96k|  UserData() = default;
_ZN7httplib10ClientImpl15process_requestERNS_6StreamERNS_7RequestERNS_8ResponseEbRNS_5ErrorE:
13876|  1.96k|                                        Error &error) {
13877|       |  // Auto-add Expect: 100-continue for large bodies
13878|  1.96k|  if (CPPHTTPLIB_EXPECT_100_THRESHOLD > 0 && !req.has_header("Expect")) {
  ------------------
  |  |   82|  1.96k|#define CPPHTTPLIB_EXPECT_100_THRESHOLD 1024
  ------------------
  |  Branch (13878:7): [True: 1.96k, Folded]
  |  Branch (13878:7): [True: 1.96k, False: 0]
  |  Branch (13878:46): [True: 1.96k, False: 0]
  ------------------
13879|  1.96k|    auto body_size = req.body.empty() ? req.content_length_ : req.body.size();
  ------------------
  |  Branch (13879:22): [True: 1.96k, False: 0]
  ------------------
13880|  1.96k|    if (body_size >= CPPHTTPLIB_EXPECT_100_THRESHOLD) {
  ------------------
  |  |   82|  1.96k|#define CPPHTTPLIB_EXPECT_100_THRESHOLD 1024
  ------------------
  |  Branch (13880:9): [True: 0, False: 1.96k]
  ------------------
13881|      0|      req.set_header("Expect", "100-continue");
13882|      0|    }
13883|  1.96k|  }
13884|       |
13885|       |  // Check for Expect: 100-continue
13886|  1.96k|  auto expect_100_continue = req.get_header_value("Expect") == "100-continue";
13887|       |
13888|       |  // Send request (skip body if using Expect: 100-continue)
13889|  1.96k|  auto write_request_success =
13890|  1.96k|      write_request(strm, req, close_connection, error, expect_100_continue);
13891|       |
13892|       |#ifdef CPPHTTPLIB_SSL_ENABLED
13893|       |  if (is_ssl() && !expect_100_continue) {
13894|       |    auto is_proxy_enabled = is_proxy_enabled_for_host(host_);
13895|       |    if (!is_proxy_enabled) {
13896|       |      if (tls::is_peer_closed(socket_.ssl, socket_.sock)) {
13897|       |        error = Error::SSLPeerCouldBeClosed_;
13898|       |        output_error_log(error, &req);
13899|       |        return false;
13900|       |      }
13901|       |    }
13902|       |  }
13903|       |#endif
13904|       |
13905|       |  // Handle Expect: 100-continue.
13906|       |  //
13907|       |  // Wait for an interim/early response by attempting to read the status line
13908|       |  // under a short timeout, instead of trusting raw socket readability. Over
13909|       |  // TLS, post-handshake records (e.g. session tickets) make the socket
13910|       |  // readable without any HTTP response being available; relying on
13911|       |  // `select_read` there caused the body to be withheld forever and the
13912|       |  // request to fail with `Read` (#2458). If no status line arrives within the
13913|       |  // timeout, send the body anyway (matching curl's behavior).
13914|  1.96k|  auto status_line_read = false;
13915|  1.96k|  if (expect_100_continue && write_request_success) {
  ------------------
  |  Branch (13915:7): [True: 0, False: 1.96k]
  |  Branch (13915:30): [True: 0, False: 0]
  ------------------
13916|      0|    if (CPPHTTPLIB_EXPECT_100_TIMEOUT_MSECOND > 0) {
  ------------------
  |  |   86|      0|#define CPPHTTPLIB_EXPECT_100_TIMEOUT_MSECOND 1000
  ------------------
  |  Branch (13916:9): [True: 0, Folded]
  ------------------
13917|      0|      time_t sec = CPPHTTPLIB_EXPECT_100_TIMEOUT_MSECOND / 1000;
  ------------------
  |  |   86|      0|#define CPPHTTPLIB_EXPECT_100_TIMEOUT_MSECOND 1000
  ------------------
13918|      0|      time_t usec = (CPPHTTPLIB_EXPECT_100_TIMEOUT_MSECOND % 1000) * 1000;
  ------------------
  |  |   86|      0|#define CPPHTTPLIB_EXPECT_100_TIMEOUT_MSECOND 1000
  ------------------
13919|      0|      strm.set_read_timeout(sec, usec);
13920|      0|      status_line_read = read_response_line(strm, req, res, false);
13921|      0|      strm.set_read_timeout(read_timeout_sec_, read_timeout_usec_);
13922|      0|    }
13923|       |
13924|      0|    if (!status_line_read) {
  ------------------
  |  Branch (13924:9): [True: 0, False: 0]
  ------------------
13925|       |      // No interim response within the timeout: send the body and handle the
13926|       |      // response as usual.
13927|      0|      if (!write_request_body(strm, req, error)) { return false; }
  ------------------
  |  Branch (13927:11): [True: 0, False: 0]
  ------------------
13928|      0|      expect_100_continue = false; // Switch to normal response handling
13929|      0|    }
13930|      0|  }
13931|       |
13932|       |  // Receive response and headers
13933|       |  // When using Expect: 100-continue, don't auto-skip `100 Continue` response
13934|  1.96k|  if ((!status_line_read &&
  ------------------
  |  Branch (13934:8): [True: 1.96k, False: 0]
  ------------------
13935|  1.96k|       !read_response_line(strm, req, res, !expect_100_continue)) ||
  ------------------
  |  Branch (13935:8): [True: 323, False: 1.64k]
  ------------------
13936|  1.64k|      !detail::read_headers(strm, res.headers)) {
  ------------------
  |  Branch (13936:7): [True: 1.05k, False: 586]
  ------------------
13937|  1.37k|    if (write_request_success) { error = Error::Read; }
  ------------------
  |  Branch (13937:9): [True: 1.37k, False: 0]
  ------------------
13938|  1.37k|    output_error_log(error, &req);
13939|  1.37k|    return false;
13940|  1.37k|  }
13941|       |
13942|    586|  if (!write_request_success) { return false; }
  ------------------
  |  Branch (13942:7): [True: 0, False: 586]
  ------------------
13943|       |
13944|       |  // Handle Expect: 100-continue response
13945|    586|  if (expect_100_continue) {
  ------------------
  |  Branch (13945:7): [True: 0, False: 586]
  ------------------
13946|      0|    if (res.status == StatusCode::Continue_100) {
  ------------------
  |  Branch (13946:9): [True: 0, False: 0]
  ------------------
13947|       |      // Server accepted, send the body
13948|      0|      if (!write_request_body(strm, req, error)) { return false; }
  ------------------
  |  Branch (13948:11): [True: 0, False: 0]
  ------------------
13949|       |
13950|       |      // Read the actual response
13951|      0|      res.headers.clear();
13952|      0|      res.body.clear();
13953|      0|      if (!read_response_line(strm, req, res) ||
  ------------------
  |  Branch (13953:11): [True: 0, False: 0]
  ------------------
13954|      0|          !detail::read_headers(strm, res.headers)) {
  ------------------
  |  Branch (13954:11): [True: 0, False: 0]
  ------------------
13955|      0|        error = Error::Read;
13956|      0|        output_error_log(error, &req);
13957|      0|        return false;
13958|      0|      }
13959|      0|    }
13960|       |    // If not 100 Continue, server returned an error; proceed with that response
13961|      0|  }
13962|       |
13963|       |  // Body
13964|    586|  if ((res.status != StatusCode::NoContent_204) && req.method != "HEAD" &&
  ------------------
  |  Branch (13964:7): [True: 583, False: 3]
  |  Branch (13964:52): [True: 583, False: 0]
  ------------------
13965|    583|      req.method != "CONNECT") {
  ------------------
  |  Branch (13965:7): [True: 583, False: 0]
  ------------------
13966|    583|    auto redirect = 300 < res.status && res.status < 400 &&
  ------------------
  |  Branch (13966:21): [True: 199, False: 384]
  |  Branch (13966:41): [True: 26, False: 173]
  ------------------
13967|     26|                    res.status != StatusCode::NotModified_304 &&
  ------------------
  |  Branch (13967:21): [True: 25, False: 1]
  ------------------
13968|     25|                    follow_location_;
  ------------------
  |  Branch (13968:21): [True: 0, False: 25]
  ------------------
13969|       |
13970|    583|    if (req.response_handler && !redirect) {
  ------------------
  |  Branch (13970:9): [True: 0, False: 583]
  |  Branch (13970:33): [True: 0, False: 0]
  ------------------
13971|      0|      if (!req.response_handler(res)) {
  ------------------
  |  Branch (13971:11): [True: 0, False: 0]
  ------------------
13972|      0|        error = Error::Canceled;
13973|      0|        output_error_log(error, &req);
13974|      0|        return false;
13975|      0|      }
13976|      0|    }
13977|       |
13978|    583|    auto out =
13979|    583|        req.content_receiver
  ------------------
  |  Branch (13979:9): [True: 0, False: 583]
  ------------------
13980|    583|            ? static_cast<ContentReceiverWithProgress>(
13981|      0|                  [&](const char *buf, size_t n, size_t off, size_t len) {
13982|      0|                    if (redirect) { return true; }
13983|      0|                    auto ret = req.content_receiver(buf, n, off, len);
13984|      0|                    if (!ret) {
13985|      0|                      error = Error::Canceled;
13986|      0|                      output_error_log(error, &req);
13987|      0|                    }
13988|      0|                    return ret;
13989|      0|                  })
13990|    583|            : static_cast<ContentReceiverWithProgress>(
13991|    583|                  [&](const char *buf, size_t n, size_t /*off*/,
13992|    583|                      size_t /*len*/) {
13993|    583|                    assert(res.body.size() + n <= res.body.max_size());
13994|    583|                    if (payload_max_length_ > 0 &&
13995|    583|                        (res.body.size() >= payload_max_length_ ||
13996|    583|                         n > payload_max_length_ - res.body.size())) {
13997|    583|                      return false;
13998|    583|                    }
13999|    583|                    res.body.append(buf, n);
14000|    583|                    return true;
14001|    583|                  });
14002|       |
14003|    583|    auto progress = [&](size_t current, size_t total) {
14004|    583|      if (!req.download_progress || redirect) { return true; }
14005|    583|      auto ret = req.download_progress(current, total);
14006|    583|      if (!ret) {
14007|    583|        error = Error::Canceled;
14008|    583|        output_error_log(error, &req);
14009|    583|      }
14010|    583|      return ret;
14011|    583|    };
14012|       |
14013|    583|    if (res.has_header("Content-Length")) {
  ------------------
  |  Branch (14013:9): [True: 18, False: 565]
  ------------------
14014|     18|      if (!req.content_receiver) {
  ------------------
  |  Branch (14014:11): [True: 18, False: 0]
  ------------------
14015|     18|        auto len = res.get_header_value_u64("Content-Length");
14016|     18|        if (len > res.body.max_size()) {
  ------------------
  |  Branch (14016:13): [True: 1, False: 17]
  ------------------
14017|      1|          error = Error::Read;
14018|      1|          output_error_log(error, &req);
14019|      1|          return false;
14020|      1|        }
14021|       |        // Cap the reservation by payload_max_length_ to avoid OOM when a
14022|       |        // hostile or malformed server sends an enormous Content-Length.
14023|       |        // The actual body read below is bounded by payload_max_length_,
14024|       |        // so reserving more than that is never useful.
14025|     17|        auto reserve_len = static_cast<size_t>(len);
14026|     17|        if (payload_max_length_ > 0 && reserve_len > payload_max_length_) {
  ------------------
  |  Branch (14026:13): [True: 17, False: 0]
  |  Branch (14026:40): [True: 0, False: 17]
  ------------------
14027|      0|          reserve_len = payload_max_length_;
14028|      0|        }
14029|     17|        res.body.reserve(reserve_len);
14030|     17|      }
14031|     18|    }
14032|       |
14033|    582|    if (res.status != StatusCode::NotModified_304) {
  ------------------
  |  Branch (14033:9): [True: 581, False: 1]
  ------------------
14034|    581|      int dummy_status;
14035|    581|      auto max_length = (!has_payload_max_length_ && req.content_receiver)
  ------------------
  |  Branch (14035:26): [True: 581, False: 0]
  |  Branch (14035:54): [True: 0, False: 581]
  ------------------
14036|    581|                            ? (std::numeric_limits<size_t>::max)()
14037|    581|                            : payload_max_length_;
14038|    581|      if (!detail::read_content(strm, res, max_length, dummy_status,
  ------------------
  |  Branch (14038:11): [True: 227, False: 354]
  ------------------
14039|    581|                                std::move(progress), std::move(out),
14040|    581|                                decompress_)) {
14041|    227|        if (error != Error::Canceled) { error = Error::Read; }
  ------------------
  |  Branch (14041:13): [True: 227, False: 0]
  ------------------
14042|    227|        output_error_log(error, &req);
14043|    227|        return false;
14044|    227|      }
14045|    581|    }
14046|    582|  }
14047|       |
14048|       |  // Log
14049|    358|  output_log(req, res);
14050|       |
14051|    358|  return true;
14052|    586|}
_ZNK7httplib7Request10has_headerERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
 9825|  11.7k|inline bool Request::has_header(const std::string &key) const {
 9826|  11.7k|  return detail::has_header(headers, key);
 9827|  11.7k|}
_ZN7httplib6detail10has_headerERKNSt3__118unordered_multimapINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEES8_NS0_11case_ignore4hashENS9_8equal_toENS6_INS1_4pairIKS8_S8_EEEEEERSD_:
 7043|  12.1k|inline bool has_header(const Headers &headers, const std::string &key) {
 7044|  12.1k|  if (is_prohibited_header_name(key)) { return false; }
  ------------------
  |  Branch (7044:7): [True: 0, False: 12.1k]
  ------------------
 7045|  12.1k|  return headers.find(key) != headers.end();
 7046|  12.1k|}
_ZN7httplib6detail25is_prohibited_header_nameERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
 7031|  15.2k|inline bool is_prohibited_header_name(const std::string &name) {
 7032|  15.2k|  using udl::operator""_t;
 7033|       |
 7034|  15.2k|  switch (str2tag(name)) {
 7035|      0|  case "REMOTE_ADDR"_t:
  ------------------
  |  Branch (7035:3): [True: 0, False: 15.2k]
  ------------------
 7036|      0|  case "REMOTE_PORT"_t:
  ------------------
  |  Branch (7036:3): [True: 0, False: 15.2k]
  ------------------
 7037|      0|  case "LOCAL_ADDR"_t:
  ------------------
  |  Branch (7037:3): [True: 0, False: 15.2k]
  ------------------
 7038|      0|  case "LOCAL_PORT"_t: return true;
  ------------------
  |  Branch (7038:3): [True: 0, False: 15.2k]
  ------------------
 7039|  15.2k|  default: return false;
  ------------------
  |  Branch (7039:3): [True: 15.2k, False: 0]
  ------------------
 7040|  15.2k|  }
 7041|  15.2k|}
_ZN7httplib6detail7str2tagERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
 6449|  15.2k|inline unsigned int str2tag(const std::string &s) {
 6450|       |  // Iterative form of str2tag_core: the recursive constexpr version is kept
 6451|       |  // for compile-time UDL evaluation of short string literals, but at runtime
 6452|       |  // we may receive arbitrarily long inputs (e.g. fuzzed Content-Type) that
 6453|       |  // would blow the stack with one frame per character.
 6454|  15.2k|  unsigned int h = 0;
 6455|   138k|  for (auto c : s) {
  ------------------
  |  Branch (6455:15): [True: 138k, False: 15.2k]
  ------------------
 6456|   138k|    h = (((std::numeric_limits<unsigned int>::max)() >> 6) & h * 33) ^
 6457|   138k|        static_cast<unsigned char>(c);
 6458|   138k|  }
 6459|  15.2k|  return h;
 6460|  15.2k|}
_ZNK7httplib6detail11case_ignore4hashclERKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEE:
  591|  44.7k|  size_t operator()(const std::string &key) const {
  592|  44.7k|    return hash_core(key.data(), key.size(), 0);
  593|  44.7k|  }
_ZNK7httplib6detail11case_ignore4hash9hash_coreEPKcmm:
  595|   726k|  size_t hash_core(const char *s, size_t l, size_t h) const {
  596|   726k|    return (l == 0) ? h
  ------------------
  |  Branch (596:12): [True: 44.7k, False: 682k]
  ------------------
  597|   726k|                    : hash_core(s + 1, l - 1,
  598|       |                                // Unsets the 6 high bits of h, therefore no
  599|       |                                // overflow happens
  600|   682k|                                (((std::numeric_limits<size_t>::max)() >> 6) &
  601|   682k|                                 h * 33) ^
  602|   682k|                                    static_cast<unsigned char>(to_lower(*s)));
  603|   726k|  }
_ZN7httplib6detail11case_ignore8to_lowerEi:
  545|  1.50M|inline unsigned char to_lower(int c) {
  546|  1.50M|  const static unsigned char table[256] = {
  547|  1.50M|      0,   1,   2,   3,   4,   5,   6,   7,   8,   9,   10,  11,  12,  13,  14,
  548|  1.50M|      15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27,  28,  29,
  549|  1.50M|      30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,  41,  42,  43,  44,
  550|  1.50M|      45,  46,  47,  48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,
  551|  1.50M|      60,  61,  62,  63,  64,  97,  98,  99,  100, 101, 102, 103, 104, 105, 106,
  552|  1.50M|      107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121,
  553|  1.50M|      122, 91,  92,  93,  94,  95,  96,  97,  98,  99,  100, 101, 102, 103, 104,
  554|  1.50M|      105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
  555|  1.50M|      120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134,
  556|  1.50M|      135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
  557|  1.50M|      150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,
  558|  1.50M|      165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179,
  559|  1.50M|      180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 224, 225, 226,
  560|  1.50M|      227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241,
  561|  1.50M|      242, 243, 244, 245, 246, 215, 248, 249, 250, 251, 252, 253, 254, 223, 224,
  562|  1.50M|      225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
  563|  1.50M|      240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254,
  564|  1.50M|      255,
  565|  1.50M|  };
  566|  1.50M|  return table[(unsigned char)(char)c];
  567|  1.50M|}
_ZNK7httplib6detail11case_ignore8equal_toclERKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEESB_:
  585|  92.1k|  bool operator()(const std::string &a, const std::string &b) const {
  586|  92.1k|    return equal(a, b);
  587|  92.1k|  }
_ZN7httplib6detail11case_ignore5equalERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEESA_:
  577|  92.5k|inline bool equal(const std::string &a, const std::string &b) {
  578|  92.5k|  return a.size() == b.size() &&
  ------------------
  |  Branch (578:10): [True: 91.9k, False: 664]
  ------------------
  579|  91.9k|         std::equal(a.begin(), a.end(), b.begin(), [](char ca, char cb) {
  ------------------
  |  Branch (579:10): [True: 91.7k, False: 155]
  ------------------
  580|  91.9k|           return to_lower(ca) == to_lower(cb);
  581|  91.9k|         });
  582|  92.5k|}
_ZZN7httplib6detail11case_ignore5equalERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEESA_ENKUlccE_clEcc:
  579|   412k|         std::equal(a.begin(), a.end(), b.begin(), [](char ca, char cb) {
  580|   412k|           return to_lower(ca) == to_lower(cb);
  581|   412k|         });
_ZN7httplib7Request10set_headerERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEES9_:
 9839|  5.24k|                                const std::string &val) {
 9840|  5.24k|  detail::set_header(headers, key, val);
 9841|  5.24k|}
_ZN7httplib6detail10set_headerERNSt3__118unordered_multimapINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEES8_NS0_11case_ignore4hashENS9_8equal_toENS6_INS1_4pairIKS8_S8_EEEEEERSD_SI_:
 7084|  5.24k|                       const std::string &val) {
 7085|  5.24k|  if (fields::is_field_name(key) && fields::is_field_value(val)) {
  ------------------
  |  Branch (7085:7): [True: 5.24k, False: 0]
  |  Branch (7085:37): [True: 5.24k, False: 0]
  ------------------
 7086|  5.24k|    headers.emplace(key, val);
 7087|  5.24k|  }
 7088|  5.24k|}
_ZN7httplib6detail6fields13is_field_nameERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
 8763|  23.9k|inline bool is_field_name(const std::string &s) { return is_token(s); }
_ZN7httplib6detail6fields8is_tokenERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
 8755|  23.9k|inline bool is_token(const std::string &s) {
 8756|  23.9k|  if (s.empty()) { return false; }
  ------------------
  |  Branch (8756:7): [True: 13, False: 23.9k]
  ------------------
 8757|   379k|  for (auto c : s) {
  ------------------
  |  Branch (8757:15): [True: 379k, False: 23.7k]
  ------------------
 8758|   379k|    if (!is_token_char(c)) { return false; }
  ------------------
  |  Branch (8758:9): [True: 176, False: 379k]
  ------------------
 8759|   379k|  }
 8760|  23.7k|  return true;
 8761|  23.9k|}
_ZN7httplib6detail6fields13is_token_charEc:
 8748|   379k|inline bool is_token_char(char c) {
 8749|   379k|  return std::isalnum(static_cast<unsigned char>(c)) || c == '!' || c == '#' ||
  ------------------
  |  Branch (8749:10): [True: 331k, False: 48.6k]
  |  Branch (8749:57): [True: 868, False: 47.8k]
  |  Branch (8749:69): [True: 2.47k, False: 45.3k]
  ------------------
 8750|  45.3k|         c == '$' || c == '%' || c == '&' || c == '\'' || c == '*' ||
  ------------------
  |  Branch (8750:10): [True: 484, False: 44.8k]
  |  Branch (8750:22): [True: 1.98k, False: 42.8k]
  |  Branch (8750:34): [True: 578, False: 42.2k]
  |  Branch (8750:46): [True: 2.27k, False: 40.0k]
  |  Branch (8750:59): [True: 14.6k, False: 25.3k]
  ------------------
 8751|  25.3k|         c == '+' || c == '-' || c == '.' || c == '^' || c == '_' || c == '`' ||
  ------------------
  |  Branch (8751:10): [True: 5.34k, False: 20.0k]
  |  Branch (8751:22): [True: 13.4k, False: 6.52k]
  |  Branch (8751:34): [True: 870, False: 5.65k]
  |  Branch (8751:46): [True: 2.40k, False: 3.24k]
  |  Branch (8751:58): [True: 421, False: 2.82k]
  |  Branch (8751:70): [True: 1.03k, False: 1.79k]
  ------------------
 8752|  1.79k|         c == '|' || c == '~';
  ------------------
  |  Branch (8752:10): [True: 633, False: 1.16k]
  |  Branch (8752:22): [True: 986, False: 176]
  ------------------
 8753|   379k|}
_ZN7httplib6detail6fields14is_field_valueERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
 8796|  23.6k|inline bool is_field_value(const std::string &s) { return is_field_content(s); }
_ZN7httplib6detail6fields16is_field_contentERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
 8771|  23.6k|inline bool is_field_content(const std::string &s) {
 8772|  23.6k|  if (s.empty()) { return true; }
  ------------------
  |  Branch (8772:7): [True: 825, False: 22.7k]
  ------------------
 8773|       |
 8774|  22.7k|  if (s.size() == 1) {
  ------------------
  |  Branch (8774:7): [True: 3.23k, False: 19.5k]
  ------------------
 8775|  3.23k|    return is_field_vchar(s[0]);
 8776|  19.5k|  } else if (s.size() == 2) {
  ------------------
  |  Branch (8776:14): [True: 1.36k, False: 18.1k]
  ------------------
 8777|  1.36k|    return is_field_vchar(s[0]) && is_field_vchar(s[1]);
  ------------------
  |  Branch (8777:12): [True: 1.35k, False: 4]
  |  Branch (8777:36): [True: 1.35k, False: 1]
  ------------------
 8778|  18.1k|  } else {
 8779|  18.1k|    size_t i = 0;
 8780|       |
 8781|  18.1k|    if (!is_field_vchar(s[i])) { return false; }
  ------------------
  |  Branch (8781:9): [True: 1, False: 18.1k]
  ------------------
 8782|  18.1k|    i++;
 8783|       |
 8784|   744k|    while (i < s.size() - 1) {
  ------------------
  |  Branch (8784:12): [True: 726k, False: 18.1k]
  ------------------
 8785|   726k|      auto c = s[i++];
 8786|   726k|      if (c == ' ' || c == '\t' || is_field_vchar(c)) {
  ------------------
  |  Branch (8786:11): [True: 9.96k, False: 716k]
  |  Branch (8786:23): [True: 1.25k, False: 715k]
  |  Branch (8786:36): [True: 715k, False: 64]
  ------------------
 8787|   726k|      } else {
 8788|     64|        return false;
 8789|     64|      }
 8790|   726k|    }
 8791|       |
 8792|  18.1k|    return is_field_vchar(s[i]);
 8793|  18.1k|  }
 8794|  22.7k|}
_ZN7httplib6detail6fields14is_field_vcharEc:
 8769|   757k|inline bool is_field_vchar(char c) { return is_vchar(c) || is_obs_text(c); }
  ------------------
  |  Branch (8769:45): [True: 558k, False: 199k]
  |  Branch (8769:60): [True: 199k, False: 78]
  ------------------
_ZN7httplib6detail6fields8is_vcharEc:
 8765|   757k|inline bool is_vchar(char c) { return c >= 33 && c <= 126; }
  ------------------
  |  Branch (8765:39): [True: 558k, False: 199k]
  |  Branch (8765:50): [True: 558k, False: 2]
  ------------------
_ZN7httplib6detail6fields11is_obs_textEc:
 8767|   199k|inline bool is_obs_text(char c) { return 128 <= static_cast<unsigned char>(c); }
_ZNK7httplib7Request16get_header_valueERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEPKcm:
 9830|  1.96k|                                             const char *def, size_t id) const {
 9831|  1.96k|  return detail::get_header_value(headers, key, def, id);
 9832|  1.96k|}
_ZN7httplib6detail16get_header_valueERKNSt3__118unordered_multimapINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEES8_NS0_11case_ignore4hashENS9_8equal_toENS6_INS1_4pairIKS8_S8_EEEEEERSD_PKcm:
 7050|  3.01k|                                    size_t id) {
 7051|  3.01k|  if (is_prohibited_header_name(key)) {
  ------------------
  |  Branch (7051:7): [True: 0, False: 3.01k]
  ------------------
 7052|      0|#ifndef CPPHTTPLIB_NO_EXCEPTIONS
 7053|      0|    std::string msg = "Prohibited header name '" + key + "' is specified.";
 7054|      0|    throw std::invalid_argument(msg);
 7055|       |#else
 7056|       |    return "";
 7057|       |#endif
 7058|      0|  }
 7059|       |
 7060|  3.01k|  auto rng = headers.equal_range(key);
 7061|  3.01k|  auto it = rng.first;
 7062|  3.01k|  std::advance(it, static_cast<ssize_t>(id));
 7063|  3.01k|  if (it != rng.second) { return it->second.c_str(); }
  ------------------
  |  Branch (7063:7): [True: 268, False: 2.75k]
  ------------------
 7064|  2.75k|  return def;
 7065|  3.01k|}
_ZN7httplib10ClientImpl13write_requestERNS_6StreamERNS_7RequestEbRNS_5ErrorEb:
13529|  1.96k|                                      bool skip_body) {
13530|       |  // Prepare additional headers
13531|  1.96k|  if (close_connection) {
  ------------------
  |  Branch (13531:7): [True: 0, False: 1.96k]
  ------------------
13532|      0|    if (!req.has_header("Connection")) {
  ------------------
  |  Branch (13532:9): [True: 0, False: 0]
  ------------------
13533|      0|      req.set_header("Connection", "close");
13534|      0|    }
13535|      0|  }
13536|       |
13537|  1.96k|  std::string ct_for_defaults;
13538|  1.96k|  if (!req.has_header("Content-Type") && !req.body.empty()) {
  ------------------
  |  Branch (13538:7): [True: 1.96k, False: 0]
  |  Branch (13538:7): [True: 0, False: 1.96k]
  |  Branch (13538:42): [True: 0, False: 1.96k]
  ------------------
13539|      0|    ct_for_defaults = "text/plain";
13540|      0|  }
13541|  1.96k|  prepare_default_headers(req, false, ct_for_defaults);
13542|       |
13543|  1.96k|  if (req.body.empty()) {
  ------------------
  |  Branch (13543:7): [True: 1.96k, False: 0]
  ------------------
13544|  1.96k|    if (req.content_provider_) {
  ------------------
  |  Branch (13544:9): [True: 0, False: 1.96k]
  ------------------
13545|      0|      if (!req.is_chunked_content_provider_) {
  ------------------
  |  Branch (13545:11): [True: 0, False: 0]
  ------------------
13546|      0|        if (!req.has_header("Content-Length")) {
  ------------------
  |  Branch (13546:13): [True: 0, False: 0]
  ------------------
13547|      0|          auto length = std::to_string(req.content_length_);
13548|      0|          req.set_header("Content-Length", length);
13549|      0|        }
13550|      0|      }
13551|  1.96k|    } else {
13552|  1.96k|      if (req.method == "POST" || req.method == "PUT" ||
  ------------------
  |  Branch (13552:11): [True: 564, False: 1.40k]
  |  Branch (13552:35): [True: 551, False: 849]
  ------------------
13553|  1.31k|          req.method == "PATCH") {
  ------------------
  |  Branch (13553:11): [True: 198, False: 651]
  ------------------
13554|  1.31k|        req.set_header("Content-Length", "0");
13555|  1.31k|      }
13556|  1.96k|    }
13557|  1.96k|  }
13558|       |
13559|  1.96k|  if (!basic_auth_password_.empty() || !basic_auth_username_.empty()) {
  ------------------
  |  Branch (13559:7): [True: 0, False: 1.96k]
  |  Branch (13559:40): [True: 0, False: 1.96k]
  ------------------
13560|      0|    if (!req.has_header("Authorization")) {
  ------------------
  |  Branch (13560:9): [True: 0, False: 0]
  ------------------
13561|      0|      req.headers.insert(make_basic_authentication_header(
13562|      0|          basic_auth_username_, basic_auth_password_, false));
13563|      0|    }
13564|      0|  }
13565|       |
13566|  1.96k|  if (!bearer_token_auth_token_.empty()) {
  ------------------
  |  Branch (13566:7): [True: 0, False: 1.96k]
  ------------------
13567|      0|    if (!req.has_header("Authorization")) {
  ------------------
  |  Branch (13567:9): [True: 0, False: 0]
  ------------------
13568|      0|      req.headers.insert(make_bearer_token_authentication_header(
13569|      0|          bearer_token_auth_token_, false));
13570|      0|    }
13571|      0|  }
13572|       |
13573|       |  // Proxy-Authorization is only sent when the proxy is actually used for
13574|       |  // this target — otherwise NO_PROXY-matched requests would leak proxy
13575|       |  // credentials directly to the destination server.
13576|  1.96k|  if (is_proxy_enabled_for_host(host_)) {
  ------------------
  |  Branch (13576:7): [True: 0, False: 1.96k]
  ------------------
13577|      0|    if (!proxy_basic_auth_username_.empty() &&
  ------------------
  |  Branch (13577:9): [True: 0, False: 0]
  |  Branch (13577:9): [True: 0, False: 0]
  ------------------
13578|      0|        !proxy_basic_auth_password_.empty() &&
  ------------------
  |  Branch (13578:9): [True: 0, False: 0]
  ------------------
13579|      0|        !req.has_header("Proxy-Authorization")) {
  ------------------
  |  Branch (13579:9): [True: 0, False: 0]
  ------------------
13580|      0|      req.headers.insert(make_basic_authentication_header(
13581|      0|          proxy_basic_auth_username_, proxy_basic_auth_password_, true));
13582|      0|    }
13583|      0|    if (!proxy_bearer_token_auth_token_.empty() &&
  ------------------
  |  Branch (13583:9): [True: 0, False: 0]
  |  Branch (13583:9): [True: 0, False: 0]
  ------------------
13584|      0|        !req.has_header("Proxy-Authorization")) {
  ------------------
  |  Branch (13584:9): [True: 0, False: 0]
  ------------------
13585|      0|      req.headers.insert(make_bearer_token_authentication_header(
13586|      0|          proxy_bearer_token_auth_token_, true));
13587|      0|    }
13588|      0|  }
13589|       |
13590|       |  // Request line and headers
13591|  1.96k|  {
13592|  1.96k|    detail::BufferStream bstrm;
13593|       |
13594|       |    // Extract path and query from req.path
13595|  1.96k|    std::string path_part, query_part;
13596|  1.96k|    auto query_pos = req.path.find('?');
13597|  1.96k|    if (query_pos != std::string::npos) {
  ------------------
  |  Branch (13597:9): [True: 0, False: 1.96k]
  ------------------
13598|      0|      path_part = req.path.substr(0, query_pos);
13599|      0|      query_part = req.path.substr(query_pos + 1);
13600|  1.96k|    } else {
13601|  1.96k|      path_part = req.path;
13602|  1.96k|      query_part = "";
13603|  1.96k|    }
13604|       |
13605|       |    // Encode path part. If the original `req.path` already contained a
13606|       |    // query component, preserve its raw query string (including parameter
13607|       |    // order) instead of reparsing and reassembling it which may reorder
13608|       |    // parameters due to container ordering (e.g. `Params` uses
13609|       |    // `std::multimap`). When there is no query in `req.path`, fall back to
13610|       |    // building a query from `req.params` so existing callers that pass
13611|       |    // `Params` continue to work.
13612|  1.96k|    auto path_with_query =
13613|  1.96k|        path_encode_ ? detail::encode_path(path_part) : path_part;
  ------------------
  |  Branch (13613:9): [True: 1.96k, False: 0]
  ------------------
13614|       |
13615|  1.96k|    if (!query_part.empty()) {
  ------------------
  |  Branch (13615:9): [True: 0, False: 1.96k]
  ------------------
13616|       |      // Normalize the query string (decode then re-encode) while preserving
13617|       |      // the original parameter order.
13618|      0|      auto normalized = detail::normalize_query_string(query_part);
13619|      0|      if (!normalized.empty()) { path_with_query += '?' + normalized; }
  ------------------
  |  Branch (13619:11): [True: 0, False: 0]
  ------------------
13620|       |
13621|       |      // Still populate req.params for handlers/users who read them.
13622|      0|      detail::parse_query_text(query_part, req.params);
13623|  1.96k|    } else {
13624|       |      // No query in path; parse any query_part (empty) and append params
13625|       |      // from `req.params` when present (preserves prior behavior for
13626|       |      // callers who provide Params separately).
13627|  1.96k|      detail::parse_query_text(query_part, req.params);
13628|  1.96k|      if (!req.params.empty()) {
  ------------------
  |  Branch (13628:11): [True: 0, False: 1.96k]
  ------------------
13629|      0|        path_with_query = append_query_params(path_with_query, req.params);
13630|      0|      }
13631|  1.96k|    }
13632|       |
13633|       |    // Write request line and headers
13634|  1.96k|    detail::write_request_line(bstrm, req.method, path_with_query);
13635|  1.96k|    if (!detail::check_and_write_headers(bstrm, req.headers, header_writer_,
  ------------------
  |  Branch (13635:9): [True: 0, False: 1.96k]
  ------------------
13636|  1.96k|                                         error)) {
13637|      0|      output_error_log(error, &req);
13638|      0|      return false;
13639|      0|    }
13640|       |
13641|       |    // Flush buffer
13642|  1.96k|    auto &data = bstrm.get_buffer();
13643|  1.96k|    if (!detail::write_data(strm, data.data(), data.size())) {
  ------------------
  |  Branch (13643:9): [True: 0, False: 1.96k]
  ------------------
13644|      0|      error = Error::Write;
13645|      0|      output_error_log(error, &req);
13646|      0|      return false;
13647|      0|    }
13648|  1.96k|  }
13649|       |
13650|       |  // After sending request line and headers, wait briefly for an early server
13651|       |  // response (e.g. 4xx) and avoid sending a potentially large request body
13652|       |  // unnecessarily. This workaround is only enabled on Windows because Unix
13653|       |  // platforms surface write errors (EPIPE) earlier; on Windows kernel send
13654|       |  // buffering can accept large writes even when the peer already responded.
13655|       |  // Check the stream first (which covers SSL via `is_readable()`), then
13656|       |  // fall back to select on the socket. Only perform the wait for very large
13657|       |  // request bodies to avoid interfering with normal small requests and
13658|       |  // reduce side-effects. Poll briefly (up to 50ms as default) for an early
13659|       |  // response. Skip this check when using Expect: 100-continue, as the protocol
13660|       |  // handles early responses properly.
13661|       |#if defined(_WIN32)
13662|       |  if (!skip_body &&
13663|       |      req.body.size() > CPPHTTPLIB_WAIT_EARLY_SERVER_RESPONSE_THRESHOLD &&
13664|       |      req.path.size() > CPPHTTPLIB_REQUEST_URI_MAX_LENGTH) {
13665|       |    auto start = std::chrono::high_resolution_clock::now();
13666|       |
13667|       |    for (;;) {
13668|       |      // Prefer socket-level readiness to avoid SSL_pending() false-positives
13669|       |      // from SSL internals. If the underlying socket is readable, assume an
13670|       |      // early response may be present.
13671|       |      auto sock = strm.socket();
13672|       |      if (sock != INVALID_SOCKET && detail::select_read(sock, 0, 0) > 0) {
13673|       |        return false;
13674|       |      }
13675|       |
13676|       |      // Fallback to stream-level check for non-socket streams or when the
13677|       |      // socket isn't reporting readable. Avoid using `is_readable()` for
13678|       |      // SSL, since `SSL_pending()` may report buffered records that do not
13679|       |      // indicate a complete application-level response yet.
13680|       |      if (!is_ssl() && strm.is_readable()) { return false; }
13681|       |
13682|       |      auto now = std::chrono::high_resolution_clock::now();
13683|       |      auto elapsed =
13684|       |          std::chrono::duration_cast<std::chrono::milliseconds>(now - start)
13685|       |              .count();
13686|       |      if (elapsed >= CPPHTTPLIB_WAIT_EARLY_SERVER_RESPONSE_TIMEOUT_MSECOND) {
13687|       |        break;
13688|       |      }
13689|       |
13690|       |      std::this_thread::sleep_for(std::chrono::milliseconds(1));
13691|       |    }
13692|       |  }
13693|       |#endif
13694|       |
13695|       |  // Body
13696|  1.96k|  if (skip_body) { return true; }
  ------------------
  |  Branch (13696:7): [True: 0, False: 1.96k]
  ------------------
13697|       |
13698|  1.96k|  return write_request_body(strm, req, error);
13699|  1.96k|}
_ZN7httplib10ClientImpl23prepare_default_headersERNS_7RequestEbRKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEE:
12887|  1.96k|                                                const std::string &ct) {
12888|  1.96k|  (void)for_stream;
12889|  1.96k|  for (const auto &header : default_headers_) {
  ------------------
  |  Branch (12889:27): [True: 0, False: 1.96k]
  ------------------
12890|      0|    if (!r.has_header(header.first)) { r.headers.insert(header); }
  ------------------
  |  Branch (12890:9): [True: 0, False: 0]
  ------------------
12891|      0|  }
12892|       |
12893|  1.96k|  if (!r.has_header("Host")) {
  ------------------
  |  Branch (12893:7): [True: 1.96k, False: 0]
  ------------------
12894|  1.96k|    if (address_family_ == AF_UNIX) {
  ------------------
  |  Branch (12894:9): [True: 0, False: 1.96k]
  ------------------
12895|      0|      r.headers.emplace("Host", "localhost");
12896|  1.96k|    } else {
12897|  1.96k|      r.headers.emplace(
12898|  1.96k|          "Host", detail::make_host_and_port_string(host_, port_, is_ssl()));
12899|  1.96k|    }
12900|  1.96k|  }
12901|       |
12902|  1.96k|  if (!r.has_header("Accept")) { r.headers.emplace("Accept", "*/*"); }
  ------------------
  |  Branch (12902:7): [True: 1.96k, False: 0]
  ------------------
12903|       |
12904|  1.96k|  if (!r.content_receiver) {
  ------------------
  |  Branch (12904:7): [True: 1.96k, False: 0]
  ------------------
12905|  1.96k|    if (!r.has_header("Accept-Encoding")) {
  ------------------
  |  Branch (12905:9): [True: 1.96k, False: 0]
  ------------------
12906|  1.96k|      std::string accept_encoding;
12907|       |#ifdef CPPHTTPLIB_BROTLI_SUPPORT
12908|       |      accept_encoding = "br";
12909|       |#endif
12910|  1.96k|#ifdef CPPHTTPLIB_ZLIB_SUPPORT
12911|  1.96k|      if (!accept_encoding.empty()) { accept_encoding += ", "; }
  ------------------
  |  Branch (12911:11): [True: 0, False: 1.96k]
  ------------------
12912|  1.96k|      accept_encoding += "gzip, deflate";
12913|  1.96k|#endif
12914|       |#ifdef CPPHTTPLIB_ZSTD_SUPPORT
12915|       |      if (!accept_encoding.empty()) { accept_encoding += ", "; }
12916|       |      accept_encoding += "zstd";
12917|       |#endif
12918|  1.96k|      r.set_header("Accept-Encoding", accept_encoding);
12919|  1.96k|    }
12920|       |
12921|  1.96k|#ifndef CPPHTTPLIB_NO_DEFAULT_USER_AGENT
12922|  1.96k|    if (!r.has_header("User-Agent")) {
  ------------------
  |  Branch (12922:9): [True: 1.96k, False: 0]
  ------------------
12923|  1.96k|      auto agent = std::string("cpp-httplib/") + CPPHTTPLIB_VERSION;
  ------------------
  |  |   11|  1.96k|#define CPPHTTPLIB_VERSION "0.47.0"
  ------------------
12924|  1.96k|      r.set_header("User-Agent", agent);
12925|  1.96k|    }
12926|  1.96k|#endif
12927|  1.96k|  }
12928|       |
12929|  1.96k|  if (!r.body.empty()) {
  ------------------
  |  Branch (12929:7): [True: 0, False: 1.96k]
  ------------------
12930|      0|    if (!ct.empty() && !r.has_header("Content-Type")) {
  ------------------
  |  Branch (12930:9): [True: 0, False: 0]
  |  Branch (12930:9): [True: 0, False: 0]
  |  Branch (12930:24): [True: 0, False: 0]
  ------------------
12931|      0|      r.headers.emplace("Content-Type", ct);
12932|      0|    }
12933|      0|    if (!r.has_header("Content-Length")) {
  ------------------
  |  Branch (12933:9): [True: 0, False: 0]
  ------------------
12934|      0|      r.headers.emplace("Content-Length", std::to_string(r.body.size()));
12935|      0|    }
12936|      0|  }
12937|  1.96k|}
_ZN7httplib6detail25make_host_and_port_stringERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEib:
10603|  1.96k|                                             bool is_ssl) {
10604|  1.96k|  auto result = prepare_host_string(host);
10605|       |
10606|       |  // Append port if not default
10607|  1.96k|  if ((!is_ssl && port == 80) || (is_ssl && port == 443)) {
  ------------------
  |  Branch (10607:8): [True: 1.96k, False: 0]
  |  Branch (10607:19): [True: 0, False: 1.96k]
  |  Branch (10607:35): [True: 0, False: 1.96k]
  |  Branch (10607:45): [True: 0, False: 0]
  ------------------
10608|      0|    ; // do nothing
10609|  1.96k|  } else {
10610|  1.96k|    result += ":" + std::to_string(port);
10611|  1.96k|  }
10612|       |
10613|  1.96k|  return result;
10614|  1.96k|}
_ZN7httplib6detail19prepare_host_stringERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
10590|  1.96k|inline std::string prepare_host_string(const std::string &host) {
10591|       |  // Enclose IPv6 address in brackets (but not if already enclosed)
10592|  1.96k|  if (host.find(':') == std::string::npos ||
  ------------------
  |  Branch (10592:7): [True: 1.96k, False: 0]
  ------------------
10593|  1.96k|      (!host.empty() && host[0] == '[')) {
  ------------------
  |  Branch (10593:8): [True: 0, False: 0]
  |  Branch (10593:25): [True: 0, False: 0]
  ------------------
10594|       |    // IPv4, hostname, or already bracketed IPv6
10595|  1.96k|    return host;
10596|  1.96k|  } else {
10597|       |    // IPv6 address without brackets
10598|      0|    return "[" + host + "]";
10599|      0|  }
10600|  1.96k|}
_ZNK7httplib10ClientImpl25is_proxy_enabled_for_hostERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
12634|  1.96k|ClientImpl::is_proxy_enabled_for_host(const std::string &host) const {
12635|  1.96k|  if (proxy_host_.empty() || proxy_port_ == -1) { return false; }
  ------------------
  |  Branch (12635:7): [True: 1.96k, False: 0]
  |  Branch (12635:30): [True: 0, False: 0]
  ------------------
12636|      0|  if (no_proxy_entries_.empty()) { return true; }
  ------------------
  |  Branch (12636:7): [True: 0, False: 0]
  ------------------
12637|       |  // host_ is const so its normalized form is invariant; cache it. The
12638|       |  // cross-host path (setup_redirect_client passing next_host) re-normalizes.
12639|      0|  if (host == host_) {
  ------------------
  |  Branch (12639:7): [True: 0, False: 0]
  ------------------
12640|      0|    if (!host_normalized_valid_) {
  ------------------
  |  Branch (12640:9): [True: 0, False: 0]
  ------------------
12641|      0|      host_normalized_ = detail::normalize_target(host_);
12642|      0|      host_normalized_valid_ = true;
12643|      0|    }
12644|      0|    return !detail::host_matches_no_proxy(host_normalized_, no_proxy_entries_);
12645|      0|  }
12646|      0|  auto target = detail::normalize_target(host);
12647|      0|  return !detail::host_matches_no_proxy(target, no_proxy_entries_);
12648|      0|}
_ZN7httplib6detail12BufferStreamC2Ev:
 3105|  1.96k|  BufferStream() = default;
_ZN7httplib6detail11encode_pathERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
 5011|  1.96k|inline std::string encode_path(const std::string &s) {
 5012|  1.96k|  std::string result;
 5013|  1.96k|  result.reserve(s.size());
 5014|       |
 5015|  3.92k|  for (size_t i = 0; s[i]; i++) {
  ------------------
  |  Branch (5015:22): [True: 1.96k, False: 1.96k]
  ------------------
 5016|  1.96k|    switch (s[i]) {
 5017|      0|    case ' ': result += "%20"; break;
  ------------------
  |  Branch (5017:5): [True: 0, False: 1.96k]
  ------------------
 5018|      0|    case '+': result += "%2B"; break;
  ------------------
  |  Branch (5018:5): [True: 0, False: 1.96k]
  ------------------
 5019|      0|    case '\r': result += "%0D"; break;
  ------------------
  |  Branch (5019:5): [True: 0, False: 1.96k]
  ------------------
 5020|      0|    case '\n': result += "%0A"; break;
  ------------------
  |  Branch (5020:5): [True: 0, False: 1.96k]
  ------------------
 5021|      0|    case '\'': result += "%27"; break;
  ------------------
  |  Branch (5021:5): [True: 0, False: 1.96k]
  ------------------
 5022|      0|    case ',': result += "%2C"; break;
  ------------------
  |  Branch (5022:5): [True: 0, False: 1.96k]
  ------------------
 5023|       |    // case ':': result += "%3A"; break; // ok? probably...
 5024|      0|    case ';': result += "%3B"; break;
  ------------------
  |  Branch (5024:5): [True: 0, False: 1.96k]
  ------------------
 5025|  1.96k|    default:
  ------------------
  |  Branch (5025:5): [True: 1.96k, False: 0]
  ------------------
 5026|  1.96k|      auto c = static_cast<uint8_t>(s[i]);
 5027|  1.96k|      if (c >= 0x80) {
  ------------------
  |  Branch (5027:11): [True: 0, False: 1.96k]
  ------------------
 5028|      0|        result += '%';
 5029|      0|        char hex[4];
 5030|      0|        auto len = snprintf(hex, sizeof(hex) - 1, "%02X", c);
 5031|      0|        assert(len == 2);
  ------------------
  |  Branch (5031:9): [True: 0, False: 0]
  ------------------
 5032|      0|        result.append(hex, static_cast<size_t>(len));
 5033|  1.96k|      } else {
 5034|  1.96k|        result += s[i];
 5035|  1.96k|      }
 5036|  1.96k|      break;
 5037|  1.96k|    }
 5038|  1.96k|  }
 5039|       |
 5040|  1.96k|  return result;
 5041|  1.96k|}
_ZN7httplib6detail5splitEPKcS2_cNSt3__18functionIFvS2_S2_EEE:
 5239|  1.96k|                  std::function<void(const char *, const char *)> fn) {
 5240|  1.96k|  return split(b, e, d, (std::numeric_limits<size_t>::max)(), std::move(fn));
 5241|  1.96k|}
_ZN7httplib6detail5splitEPKcS2_cmNSt3__18functionIFvS2_S2_EEE:
 5244|  1.96k|                  std::function<void(const char *, const char *)> fn) {
 5245|  1.96k|  size_t i = 0;
 5246|  1.96k|  size_t beg = 0;
 5247|  1.96k|  size_t count = 1;
 5248|       |
 5249|  1.96k|  while (e ? (b + i < e) : (b[i] != '\0')) {
  ------------------
  |  Branch (5249:10): [True: 1.96k, False: 0]
  |  Branch (5249:10): [True: 0, False: 1.96k]
  ------------------
 5250|      0|    if (b[i] == d && count < m) {
  ------------------
  |  Branch (5250:9): [True: 0, False: 0]
  |  Branch (5250:22): [True: 0, False: 0]
  ------------------
 5251|      0|      auto r = trim(b, e, beg, i);
 5252|      0|      if (r.first < r.second) { fn(&b[r.first], &b[r.second]); }
  ------------------
  |  Branch (5252:11): [True: 0, False: 0]
  ------------------
 5253|      0|      beg = i + 1;
 5254|      0|      count++;
 5255|      0|    }
 5256|      0|    i++;
 5257|      0|  }
 5258|       |
 5259|  1.96k|  if (i) {
  ------------------
  |  Branch (5259:7): [True: 0, False: 1.96k]
  ------------------
 5260|      0|    auto r = trim(b, e, beg, i);
 5261|      0|    if (r.first < r.second) { fn(&b[r.first], &b[r.second]); }
  ------------------
  |  Branch (5261:9): [True: 0, False: 0]
  ------------------
 5262|      0|  }
 5263|  1.96k|}
_ZN7httplib6detail15is_space_or_tabEc:
 5050|  19.1k|inline bool is_space_or_tab(char c) { return c == ' ' || c == '\t'; }
  ------------------
  |  Branch (5050:46): [True: 945, False: 18.1k]
  |  Branch (5050:58): [True: 208, False: 17.9k]
  ------------------
_ZN7httplib6detail16parse_query_textERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEERNS1_8multimapIS7_S7_NS1_4lessIS7_EENS5_INS1_4pairIS8_S7_EEEEEE:
 7739|  1.96k|inline void parse_query_text(const std::string &s, Params &params) {
 7740|  1.96k|  parse_query_text(s.data(), s.size(), params);
 7741|  1.96k|}
_ZN7httplib6detail16parse_query_textEPKcmRNSt3__18multimapINS3_12basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEESA_NS3_4lessISA_EENS8_INS3_4pairIKSA_SA_EEEEEE:
 7717|  1.96k|                             Params &params) {
 7718|  1.96k|  std::set<std::string> cache;
 7719|  1.96k|  split(data, data + size, '&', [&](const char *b, const char *e) {
 7720|  1.96k|    std::string kv(b, e);
 7721|  1.96k|    if (cache.find(kv) != cache.end()) { return; }
 7722|  1.96k|    cache.insert(std::move(kv));
 7723|       |
 7724|  1.96k|    std::string key;
 7725|  1.96k|    std::string val;
 7726|  1.96k|    divide(b, static_cast<std::size_t>(e - b), '=',
 7727|  1.96k|           [&](const char *lhs_data, std::size_t lhs_size, const char *rhs_data,
 7728|  1.96k|               std::size_t rhs_size) {
 7729|  1.96k|             key.assign(lhs_data, lhs_size);
 7730|  1.96k|             val.assign(rhs_data, rhs_size);
 7731|  1.96k|           });
 7732|       |
 7733|  1.96k|    if (!key.empty()) {
 7734|  1.96k|      params.emplace(decode_query_component(key), decode_query_component(val));
 7735|  1.96k|    }
 7736|  1.96k|  });
 7737|  1.96k|}
_ZN7httplib6detail18write_request_lineERNS_6StreamERKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEESB_:
 7411|  1.96k|                                  const std::string &path) {
 7412|  1.96k|  std::string s = method;
 7413|  1.96k|  s += ' ';
 7414|  1.96k|  s += path;
 7415|  1.96k|  s += " HTTP/1.1\r\n";
 7416|  1.96k|  return strm.write(s.data(), s.size());
 7417|  1.96k|}
_ZN7httplib6detail23check_and_write_headersINSt3__18functionIFlRNS_6StreamERNS2_18unordered_multimapINS2_12basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEESC_NS0_11case_ignore4hashENSD_8equal_toENSA_INS2_4pairIKSC_SC_EEEEEEEEEEEbS5_SL_T_RNS_5ErrorE:
10794|  1.96k|                                    T header_writer, Error &error) {
10795|  9.16k|  for (const auto &h : headers) {
  ------------------
  |  Branch (10795:22): [True: 9.16k, False: 1.96k]
  ------------------
10796|  9.16k|    if (!detail::fields::is_field_name(h.first) ||
  ------------------
  |  Branch (10796:9): [True: 0, False: 9.16k]
  ------------------
10797|  9.16k|        !detail::fields::is_field_value(h.second)) {
  ------------------
  |  Branch (10797:9): [True: 0, False: 9.16k]
  ------------------
10798|      0|      error = Error::InvalidHeaders;
10799|      0|      return false;
10800|      0|    }
10801|  9.16k|  }
10802|  1.96k|  if (header_writer(strm, headers) <= 0) {
  ------------------
  |  Branch (10802:7): [True: 0, False: 1.96k]
  ------------------
10803|      0|    error = Error::Write;
10804|      0|    return false;
10805|      0|  }
10806|  1.96k|  return true;
10807|  1.96k|}
_ZNK7httplib6detail12BufferStream10get_bufferEv:
10490|  1.96k|inline const std::string &BufferStream::get_buffer() const { return buffer; }
_ZN7httplib6detail10write_dataERNS_6StreamEPKcm:
 7447|  1.96k|inline bool write_data(Stream &strm, const char *d, size_t l) {
 7448|  1.96k|  size_t offset = 0;
 7449|  3.92k|  while (offset < l) {
  ------------------
  |  Branch (7449:10): [True: 1.96k, False: 1.96k]
  ------------------
 7450|  1.96k|    auto length = strm.write(d + offset, l - offset);
 7451|  1.96k|    if (length < 0) { return false; }
  ------------------
  |  Branch (7451:9): [True: 0, False: 1.96k]
  ------------------
 7452|  1.96k|    offset += static_cast<size_t>(length);
 7453|  1.96k|  }
 7454|  1.96k|  return true;
 7455|  1.96k|}
_ZNK7httplib10ClientImpl18read_response_lineERNS_6StreamERKNS_7RequestERNS_8ResponseEb:
12731|  1.96k|                                           bool skip_100_continue) const {
12732|  1.96k|  std::array<char, 2048> buf{};
12733|       |
12734|  1.96k|  detail::stream_line_reader line_reader(strm, buf.data(), buf.size());
12735|       |
12736|  1.96k|  if (!line_reader.getline()) { return false; }
  ------------------
  |  Branch (12736:7): [True: 7, False: 1.95k]
  ------------------
12737|       |
12738|       |#ifdef CPPHTTPLIB_ALLOW_LF_AS_LINE_TERMINATOR
12739|       |  thread_local const std::regex re("(HTTP/1\\.[01]) (\\d{3})(?: (.*?))?\r?\n");
12740|       |#else
12741|  1.95k|  thread_local const std::regex re("(HTTP/1\\.[01]) (\\d{3})(?: (.*?))?\r\n");
12742|  1.95k|#endif
12743|       |
12744|  1.95k|  std::cmatch m;
12745|  1.95k|  if (!std::regex_match(line_reader.ptr(), m, re)) {
  ------------------
  |  Branch (12745:7): [True: 210, False: 1.74k]
  ------------------
12746|    210|    return req.method == "CONNECT";
12747|    210|  }
12748|  1.74k|  res.version = std::string(m[1]);
12749|  1.74k|  res.status = std::stoi(std::string(m[2]));
12750|  1.74k|  res.reason = std::string(m[3]);
12751|       |
12752|       |  // Ignore '100 Continue' (only when not using Expect: 100-continue explicitly)
12753|  6.68k|  while (skip_100_continue && res.status == StatusCode::Continue_100) {
  ------------------
  |  Branch (12753:10): [True: 6.68k, False: 0]
  |  Branch (12753:31): [True: 5.04k, False: 1.64k]
  ------------------
12754|  5.04k|    if (!line_reader.getline()) { return false; } // CRLF
  ------------------
  |  Branch (12754:9): [True: 7, False: 5.04k]
  ------------------
12755|  5.04k|    if (!line_reader.getline()) { return false; } // next response line
  ------------------
  |  Branch (12755:9): [True: 12, False: 5.02k]
  ------------------
12756|       |
12757|  5.02k|    if (!std::regex_match(line_reader.ptr(), m, re)) { return false; }
  ------------------
  |  Branch (12757:9): [True: 87, False: 4.94k]
  ------------------
12758|  4.94k|    res.version = std::string(m[1]);
12759|  4.94k|    res.status = std::stoi(std::string(m[2]));
12760|  4.94k|    res.reason = std::string(m[3]);
12761|  4.94k|  }
12762|       |
12763|  1.64k|  return true;
12764|  1.74k|}
_ZN7httplib6detail18stream_line_readerC2ERNS_6StreamEPcm:
 5303|  3.69k|    : strm_(strm), fixed_buffer_(fixed_buffer),
 5304|  3.69k|      fixed_buffer_size_(fixed_buffer_size) {}
_ZN7httplib6detail18stream_line_reader7getlineEv:
 5327|  23.4k|inline bool stream_line_reader::getline() {
 5328|  23.4k|  fixed_buffer_used_size_ = 0;
 5329|  23.4k|  growable_buffer_.clear();
 5330|       |
 5331|  23.4k|#ifndef CPPHTTPLIB_ALLOW_LF_AS_LINE_TERMINATOR
 5332|  23.4k|  char prev_byte = 0;
 5333|  23.4k|#endif
 5334|       |
 5335|  2.12M|  for (size_t i = 0;; i++) {
 5336|  2.12M|    if (size() >= CPPHTTPLIB_MAX_LINE_LENGTH) {
  ------------------
  |  |  189|  2.12M|#define CPPHTTPLIB_MAX_LINE_LENGTH 32768
  ------------------
  |  Branch (5336:9): [True: 3, False: 2.12M]
  ------------------
 5337|       |      // Treat exceptionally long lines as an error to
 5338|       |      // prevent infinite loops/memory exhaustion
 5339|      3|      return false;
 5340|      3|    }
 5341|  2.12M|    char byte;
 5342|  2.12M|    auto n = strm_.read(&byte, 1);
 5343|       |
 5344|  2.12M|    if (n < 0) {
  ------------------
  |  Branch (5344:9): [True: 0, False: 2.12M]
  ------------------
 5345|      0|      return false;
 5346|  2.12M|    } else if (n == 0) {
  ------------------
  |  Branch (5346:16): [True: 1.50k, False: 2.12M]
  ------------------
 5347|  1.50k|      if (i == 0) {
  ------------------
  |  Branch (5347:11): [True: 679, False: 823]
  ------------------
 5348|    679|        return false;
 5349|    823|      } else {
 5350|    823|        break;
 5351|    823|      }
 5352|  1.50k|    }
 5353|       |
 5354|  2.12M|    append(byte);
 5355|       |
 5356|       |#ifdef CPPHTTPLIB_ALLOW_LF_AS_LINE_TERMINATOR
 5357|       |    if (byte == '\n') { break; }
 5358|       |#else
 5359|  2.12M|    if (prev_byte == '\r' && byte == '\n') { break; }
  ------------------
  |  Branch (5359:9): [True: 55.2k, False: 2.07M]
  |  Branch (5359:30): [True: 21.9k, False: 33.2k]
  ------------------
 5360|  2.10M|    prev_byte = byte;
 5361|  2.10M|#endif
 5362|  2.10M|  }
 5363|       |
 5364|  22.7k|  return true;
 5365|  23.4k|}
_ZNK7httplib6detail18stream_line_reader4sizeEv:
 5314|  2.17M|inline size_t stream_line_reader::size() const {
 5315|  2.17M|  if (growable_buffer_.empty()) {
  ------------------
  |  Branch (5315:7): [True: 1.36M, False: 807k]
  ------------------
 5316|  1.36M|    return fixed_buffer_used_size_;
 5317|  1.36M|  } else {
 5318|   807k|    return growable_buffer_.size();
 5319|   807k|  }
 5320|  2.17M|}
_ZN7httplib6detail18stream_line_reader6appendEc:
 5367|  2.12M|inline void stream_line_reader::append(char c) {
 5368|  2.12M|  if (fixed_buffer_used_size_ < fixed_buffer_size_ - 1) {
  ------------------
  |  Branch (5368:7): [True: 1.31M, False: 806k]
  ------------------
 5369|  1.31M|    fixed_buffer_[fixed_buffer_used_size_++] = c;
 5370|  1.31M|    fixed_buffer_[fixed_buffer_used_size_] = '\0';
 5371|  1.31M|  } else {
 5372|   806k|    if (growable_buffer_.empty()) {
  ------------------
  |  Branch (5372:9): [True: 266, False: 806k]
  ------------------
 5373|    266|      assert(fixed_buffer_[fixed_buffer_used_size_] == '\0');
  ------------------
  |  Branch (5373:7): [True: 266, False: 0]
  ------------------
 5374|    266|      growable_buffer_.assign(fixed_buffer_, fixed_buffer_used_size_);
 5375|    266|    }
 5376|   806k|    growable_buffer_ += c;
 5377|   806k|  }
 5378|  2.12M|}
_ZNK7httplib6detail18stream_line_reader3ptrEv:
 5306|  36.7k|inline const char *stream_line_reader::ptr() const {
 5307|  36.7k|  if (growable_buffer_.empty()) {
  ------------------
  |  Branch (5307:7): [True: 36.1k, False: 588]
  ------------------
 5308|  36.1k|    return fixed_buffer_;
 5309|  36.1k|  } else {
 5310|    588|    return growable_buffer_.data();
 5311|    588|  }
 5312|  36.7k|}
_ZN7httplib10ClientImpl18write_request_bodyERNS_6StreamERNS_7RequestERNS_5ErrorE:
13702|  1.96k|                                           Error &error) {
13703|  1.96k|  if (req.body.empty()) {
  ------------------
  |  Branch (13703:7): [True: 1.96k, False: 0]
  ------------------
13704|  1.96k|    return write_content_with_provider(strm, req, error);
13705|  1.96k|  }
13706|       |
13707|      0|  if (req.upload_progress) {
  ------------------
  |  Branch (13707:7): [True: 0, False: 0]
  ------------------
13708|      0|    auto body_size = req.body.size();
13709|      0|    size_t written = 0;
13710|      0|    auto data = req.body.data();
13711|       |
13712|      0|    while (written < body_size) {
  ------------------
  |  Branch (13712:12): [True: 0, False: 0]
  ------------------
13713|      0|      size_t to_write = (std::min)(CPPHTTPLIB_SEND_BUFSIZ, body_size - written);
  ------------------
  |  |  154|      0|#define CPPHTTPLIB_SEND_BUFSIZ size_t(16384u)
  ------------------
13714|      0|      if (!detail::write_data(strm, data + written, to_write)) {
  ------------------
  |  Branch (13714:11): [True: 0, False: 0]
  ------------------
13715|      0|        error = Error::Write;
13716|      0|        output_error_log(error, &req);
13717|      0|        return false;
13718|      0|      }
13719|      0|      written += to_write;
13720|       |
13721|      0|      if (!req.upload_progress(written, body_size)) {
  ------------------
  |  Branch (13721:11): [True: 0, False: 0]
  ------------------
13722|      0|        error = Error::Canceled;
13723|      0|        output_error_log(error, &req);
13724|      0|        return false;
13725|      0|      }
13726|      0|    }
13727|      0|  } else {
13728|      0|    if (!detail::write_data(strm, req.body.data(), req.body.size())) {
  ------------------
  |  Branch (13728:9): [True: 0, False: 0]
  ------------------
13729|      0|      error = Error::Write;
13730|      0|      output_error_log(error, &req);
13731|      0|      return false;
13732|      0|    }
13733|      0|  }
13734|       |
13735|      0|  return true;
13736|      0|}
_ZNK7httplib10ClientImpl27write_content_with_providerERNS_6StreamERKNS_7RequestERNS_5ErrorE:
13508|  1.96k|                                                    Error &error) const {
13509|  1.96k|  auto is_shutting_down = []() { return false; };
13510|       |
13511|  1.96k|  if (req.is_chunked_content_provider_) {
  ------------------
  |  Branch (13511:7): [True: 0, False: 1.96k]
  ------------------
13512|      0|    auto compressor = compress_ ? detail::create_compressor().first
  ------------------
  |  Branch (13512:23): [True: 0, False: 0]
  ------------------
13513|      0|                                : std::unique_ptr<detail::compressor>();
13514|      0|    if (!compressor) {
  ------------------
  |  Branch (13514:9): [True: 0, False: 0]
  ------------------
13515|      0|      compressor = detail::make_unique<detail::nocompressor>();
13516|      0|    }
13517|       |
13518|      0|    return detail::write_content_chunked(strm, req.content_provider_,
13519|      0|                                         is_shutting_down, *compressor, error);
13520|  1.96k|  } else {
13521|  1.96k|    return detail::write_content_with_progress(
13522|  1.96k|        strm, req.content_provider_, 0, req.content_length_, is_shutting_down,
13523|  1.96k|        req.upload_progress, error);
13524|  1.96k|  }
13525|  1.96k|}
_ZN7httplib8DataSinkC2Ev:
 1035|  1.96k|  DataSink() : os(&sb_), sb_(*this) {}
_ZN7httplib8DataSink19data_sink_streambufC2ERS0_:
 1051|  1.96k|    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_:
 7463|  1.96k|                                        Error &error) {
 7464|  1.96k|  size_t end_offset = offset + length;
 7465|  1.96k|  size_t start_offset = offset;
 7466|  1.96k|  auto ok = true;
 7467|  1.96k|  DataSink data_sink;
 7468|       |
 7469|  1.96k|  data_sink.write = [&](const char *d, size_t l) -> bool {
 7470|  1.96k|    if (ok) {
 7471|  1.96k|      if (write_data(strm, d, l)) {
 7472|  1.96k|        offset += l;
 7473|       |
 7474|  1.96k|        if (upload_progress && length > 0) {
 7475|  1.96k|          size_t current_written = offset - start_offset;
 7476|  1.96k|          if (!upload_progress(current_written, length)) {
 7477|  1.96k|            ok = false;
 7478|  1.96k|            return false;
 7479|  1.96k|          }
 7480|  1.96k|        }
 7481|  1.96k|      } else {
 7482|  1.96k|        ok = false;
 7483|  1.96k|      }
 7484|  1.96k|    }
 7485|  1.96k|    return ok;
 7486|  1.96k|  };
 7487|       |
 7488|  1.96k|  data_sink.is_writable = [&]() -> bool { return strm.is_peer_alive(); };
 7489|       |
 7490|  1.96k|  while (offset < end_offset && !is_shutting_down()) {
  ------------------
  |  Branch (7490:10): [True: 0, False: 1.96k]
  |  Branch (7490:33): [True: 0, False: 0]
  ------------------
 7491|      0|    if (!strm.wait_writable() || !strm.is_peer_alive()) {
  ------------------
  |  Branch (7491:9): [True: 0, False: 0]
  |  Branch (7491:34): [True: 0, False: 0]
  ------------------
 7492|      0|      error = Error::Write;
 7493|      0|      return false;
 7494|      0|    } else if (!content_provider(offset, end_offset - offset, data_sink)) {
  ------------------
  |  Branch (7494:16): [True: 0, False: 0]
  ------------------
 7495|      0|      error = Error::Canceled;
 7496|      0|      return false;
 7497|      0|    } else if (!ok) {
  ------------------
  |  Branch (7497:16): [True: 0, False: 0]
  ------------------
 7498|      0|      error = Error::Write;
 7499|      0|      return false;
 7500|      0|    }
 7501|      0|  }
 7502|       |
 7503|  1.96k|  if (offset < end_offset) { // exited due to is_shutting_down(), not completion
  ------------------
  |  Branch (7503:7): [True: 0, False: 1.96k]
  ------------------
 7504|      0|    error = Error::Write;
 7505|      0|    return false;
 7506|      0|  }
 7507|       |
 7508|  1.96k|  error = Error::Success;
 7509|  1.96k|  return true;
 7510|  1.96k|}
_ZN7httplib6detail12read_headersERNS_6StreamERNSt3__118unordered_multimapINS3_12basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEESA_NS0_11case_ignore4hashENSB_8equal_toENS8_INS3_4pairIKSA_SA_EEEEEE:
 7090|  1.64k|inline bool read_headers(Stream &strm, Headers &headers) {
 7091|  1.64k|  const auto bufsiz = 2048;
 7092|  1.64k|  char buf[bufsiz];
 7093|  1.64k|  stream_line_reader line_reader(strm, buf, bufsiz);
 7094|       |
 7095|  1.64k|  size_t header_count = 0;
 7096|       |
 7097|  11.3k|  for (;;) {
 7098|  11.3k|    if (!line_reader.getline()) { return false; }
  ------------------
  |  Branch (7098:9): [True: 655, False: 10.6k]
  ------------------
 7099|       |
 7100|       |    // Check if the line ends with CRLF.
 7101|  10.6k|    auto line_terminator_len = 2;
 7102|  10.6k|    if (line_reader.end_with_crlf()) {
  ------------------
  |  Branch (7102:9): [True: 10.1k, False: 542]
  ------------------
 7103|       |      // Blank line indicates end of headers.
 7104|  10.1k|      if (line_reader.size() == 2) { break; }
  ------------------
  |  Branch (7104:11): [True: 592, False: 9.51k]
  ------------------
 7105|  10.1k|    } else {
 7106|       |#ifdef CPPHTTPLIB_ALLOW_LF_AS_LINE_TERMINATOR
 7107|       |      // Blank line indicates end of headers.
 7108|       |      if (line_reader.size() == 1) { break; }
 7109|       |      line_terminator_len = 1;
 7110|       |#else
 7111|    542|      continue; // Skip invalid line.
 7112|    542|#endif
 7113|    542|    }
 7114|       |
 7115|  9.51k|    if (line_reader.size() > CPPHTTPLIB_HEADER_MAX_LENGTH) { return false; }
  ------------------
  |  |  114|  9.51k|#define CPPHTTPLIB_HEADER_MAX_LENGTH 8192
  ------------------
  |  Branch (7115:9): [True: 3, False: 9.51k]
  ------------------
 7116|       |
 7117|       |    // Check header count limit
 7118|  9.51k|    if (header_count >= CPPHTTPLIB_HEADER_MAX_COUNT) { return false; }
  ------------------
  |  |  118|  9.51k|#define CPPHTTPLIB_HEADER_MAX_COUNT 100
  ------------------
  |  Branch (7118:9): [True: 8, False: 9.50k]
  ------------------
 7119|       |
 7120|       |    // Exclude line terminator
 7121|  9.50k|    auto end = line_reader.ptr() + line_reader.size() - line_terminator_len;
 7122|       |
 7123|  9.50k|    if (!parse_header(line_reader.ptr(), end,
  ------------------
  |  Branch (7123:9): [True: 383, False: 9.12k]
  ------------------
 7124|  9.50k|                      [&](const std::string &key, const std::string &val) {
 7125|  9.50k|                        headers.emplace(key, val);
 7126|  9.50k|                      })) {
 7127|    383|      return false;
 7128|    383|    }
 7129|       |
 7130|  9.12k|    header_count++;
 7131|  9.12k|  }
 7132|       |
 7133|       |  // RFC 9110 Section 8.6: Reject requests with multiple Content-Length
 7134|       |  // headers that have different values to prevent request smuggling.
 7135|    592|  auto cl_range = headers.equal_range("Content-Length");
 7136|    592|  if (cl_range.first != cl_range.second) {
  ------------------
  |  Branch (7136:7): [True: 24, False: 568]
  ------------------
 7137|     24|    const auto &first_val = cl_range.first->second;
 7138|     51|    for (auto it = std::next(cl_range.first); it != cl_range.second; ++it) {
  ------------------
  |  Branch (7138:47): [True: 33, False: 18]
  ------------------
 7139|     33|      if (it->second != first_val) { return false; }
  ------------------
  |  Branch (7139:11): [True: 6, False: 27]
  ------------------
 7140|     33|    }
 7141|     24|  }
 7142|       |
 7143|    586|  return true;
 7144|    592|}
_ZNK7httplib6detail18stream_line_reader13end_with_crlfEv:
 5322|  10.6k|inline bool stream_line_reader::end_with_crlf() const {
 5323|  10.6k|  auto end = ptr() + size();
 5324|  10.6k|  return size() >= 2 && end[-2] == '\r' && end[-1] == '\n';
  ------------------
  |  Branch (5324:10): [True: 10.5k, False: 118]
  |  Branch (5324:25): [True: 10.1k, False: 402]
  |  Branch (5324:44): [True: 10.1k, False: 22]
  ------------------
 5325|  10.6k|}
_ZN7httplib6detail12parse_headerIZNS0_12read_headersERNS_6StreamERNSt3__118unordered_multimapINS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEESB_NS0_11case_ignore4hashENSC_8equal_toENS9_INS4_4pairIKSB_SB_EEEEEEEUlRSG_SL_E_EEbPKcSO_T_:
 5056|  9.50k|inline bool parse_header(const char *beg, const char *end, T fn) {
 5057|       |  // Skip trailing spaces and tabs.
 5058|  9.87k|  while (beg < end && is_space_or_tab(end[-1])) {
  ------------------
  |  Branch (5058:10): [True: 9.86k, False: 10]
  |  Branch (5058:23): [True: 365, False: 9.49k]
  ------------------
 5059|    365|    end--;
 5060|    365|  }
 5061|       |
 5062|  9.50k|  auto p = beg;
 5063|   306k|  while (p < end && *p != ':') {
  ------------------
  |  Branch (5063:10): [True: 305k, False: 272]
  |  Branch (5063:21): [True: 296k, False: 9.23k]
  ------------------
 5064|   296k|    p++;
 5065|   296k|  }
 5066|       |
 5067|  9.50k|  auto name = std::string(beg, p);
 5068|  9.50k|  if (!detail::fields::is_field_name(name)) { return false; }
  ------------------
  |  Branch (5068:7): [True: 189, False: 9.31k]
  ------------------
 5069|       |
 5070|  9.31k|  if (p == end) { return false; }
  ------------------
  |  Branch (5070:7): [True: 116, False: 9.20k]
  ------------------
 5071|       |
 5072|  9.20k|  auto key_end = p;
 5073|       |
 5074|  9.20k|  if (*p++ != ':') { return false; }
  ------------------
  |  Branch (5074:7): [True: 0, False: 9.20k]
  ------------------
 5075|       |
 5076|  9.99k|  while (p < end && is_space_or_tab(*p)) {
  ------------------
  |  Branch (5076:10): [True: 9.16k, False: 825]
  |  Branch (5076:21): [True: 788, False: 8.37k]
  ------------------
 5077|    788|    p++;
 5078|    788|  }
 5079|       |
 5080|  9.20k|  if (p <= end) {
  ------------------
  |  Branch (5080:7): [True: 9.20k, False: 0]
  ------------------
 5081|  9.20k|    auto key_len = key_end - beg;
 5082|  9.20k|    if (!key_len) { return false; }
  ------------------
  |  Branch (5082:9): [True: 0, False: 9.20k]
  ------------------
 5083|       |
 5084|  9.20k|    auto key = std::string(beg, key_end);
 5085|  9.20k|    auto val = std::string(p, end);
 5086|       |
 5087|  9.20k|    if (!detail::fields::is_field_value(val)) { return false; }
  ------------------
  |  Branch (5087:9): [True: 78, False: 9.12k]
  ------------------
 5088|       |
 5089|       |    // RFC 9110 §5.5: header field values are opaque octets and MUST NOT be
 5090|       |    // percent-decoded by the recipient. Applications that need to interpret a
 5091|       |    // value as a URI component should call httplib::decode_uri_component()
 5092|       |    // (or decode_path_component()) explicitly.
 5093|  9.12k|    fn(key, val);
 5094|       |
 5095|  9.12k|    return true;
 5096|  9.20k|  }
 5097|       |
 5098|      0|  return false;
 5099|  9.20k|}
_ZZN7httplib6detail12read_headersERNS_6StreamERNSt3__118unordered_multimapINS3_12basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEESA_NS0_11case_ignore4hashENSB_8equal_toENS8_INS3_4pairIKSA_SA_EEEEEEENKUlRSF_SK_E_clESK_SK_:
 7124|  9.12k|                      [&](const std::string &key, const std::string &val) {
 7125|  9.12k|                        headers.emplace(key, val);
 7126|  9.12k|                      })) {
_ZNK7httplib10ClientImpl16output_error_logERKNS_5ErrorEPKNS_7RequestE:
13867|  1.60k|                                         const Request *req) const {
13868|  1.60k|  if (error_logger_) {
  ------------------
  |  Branch (13868:7): [True: 0, False: 1.60k]
  ------------------
13869|      0|    std::lock_guard<std::mutex> guard(logger_mutex_);
13870|      0|    error_logger_(err, req);
13871|      0|  }
13872|  1.60k|}
_ZZN7httplib10ClientImpl15process_requestERNS_6StreamERNS_7RequestERNS_8ResponseEbRNS_5ErrorEENKUlPKcmmmE0_clESA_mmm:
13992|  52.0k|                      size_t /*len*/) {
13993|  52.0k|                    assert(res.body.size() + n <= res.body.max_size());
  ------------------
  |  Branch (13993:21): [True: 52.0k, False: 0]
  ------------------
13994|  52.0k|                    if (payload_max_length_ > 0 &&
  ------------------
  |  Branch (13994:25): [True: 52.0k, False: 0]
  ------------------
13995|  52.0k|                        (res.body.size() >= payload_max_length_ ||
  ------------------
  |  Branch (13995:26): [True: 0, False: 52.0k]
  ------------------
13996|  52.0k|                         n > payload_max_length_ - res.body.size())) {
  ------------------
  |  Branch (13996:26): [True: 0, False: 52.0k]
  ------------------
13997|      0|                      return false;
13998|      0|                    }
13999|  52.0k|                    res.body.append(buf, n);
14000|  52.0k|                    return true;
14001|  52.0k|                  });
_ZNK7httplib8Response10has_headerERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
 9946|    583|inline bool Response::has_header(const std::string &key) const {
 9947|    583|  return headers.find(key) != headers.end();
 9948|    583|}
_ZNK7httplib8Response20get_header_value_u64ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEmm:
 9942|     18|                                             size_t id) const {
 9943|     18|  return detail::get_header_value_u64(headers, key, def, id);
 9944|     18|}
_ZN7httplib6detail20get_header_value_u64ERKNSt3__118unordered_multimapINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEES8_NS0_11case_ignore4hashENS9_8equal_toENS6_INS1_4pairIKS8_S8_EEEEEERSD_mm:
 2879|     18|                                   size_t id) {
 2880|     18|  auto dummy = false;
 2881|     18|  return get_header_value_u64(headers, key, def, id, dummy);
 2882|     18|}
_ZN7httplib6detail20get_header_value_u64ERKNSt3__118unordered_multimapINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEES8_NS0_11case_ignore4hashENS9_8equal_toENS6_INS1_4pairIKS8_S8_EEEEEERSD_mmRb:
 2862|     26|                                   size_t id, bool &is_invalid_value) {
 2863|     26|  is_invalid_value = false;
 2864|     26|  auto rng = headers.equal_range(key);
 2865|     26|  auto it = rng.first;
 2866|     26|  std::advance(it, static_cast<ssize_t>(id));
 2867|     26|  if (it != rng.second) {
  ------------------
  |  Branch (2867:7): [True: 26, False: 0]
  ------------------
 2868|     26|    if (is_numeric(it->second)) {
  ------------------
  |  Branch (2868:9): [True: 6, False: 20]
  ------------------
 2869|      6|      return static_cast<size_t>(std::strtoull(it->second.data(), nullptr, 10));
 2870|     20|    } else {
 2871|     20|      is_invalid_value = true;
 2872|     20|    }
 2873|     26|  }
 2874|     20|  return def;
 2875|     26|}
_ZN7httplib6detail10is_numericERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
 2854|     26|inline bool is_numeric(const std::string &str) {
 2855|     26|  return !str.empty() &&
  ------------------
  |  Branch (2855:10): [True: 24, False: 2]
  ------------------
 2856|     24|         std::all_of(str.cbegin(), str.cend(),
  ------------------
  |  Branch (2856:10): [True: 6, False: 18]
  ------------------
 2857|     24|                     [](unsigned char c) { return std::isdigit(c); });
 2858|     26|}
_ZZN7httplib6detail10is_numericERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEENKUlhE_clEh:
 2857|    606|                     [](unsigned char c) { return std::isdigit(c); });
_ZN7httplib6detail12read_contentINS_8ResponseEEEbRNS_6StreamERT_mRiNSt3__18functionIFbmmEEENS9_IFbPKcmmmEEEb:
 7353|    581|                  ContentReceiverWithProgress receiver, bool decompress) {
 7354|    581|  bool exceed_payload_max_length = false;
 7355|    581|  return prepare_content_receiver(
 7356|    581|      x, status, std::move(receiver), decompress, payload_max_length,
 7357|    581|      exceed_payload_max_length, [&](const ContentReceiverWithProgress &out) {
 7358|    581|        auto ret = true;
 7359|       |        // Note: exceed_payload_max_length may also be set by the decompressor
 7360|       |        // wrapper in prepare_content_receiver when the decompressed payload
 7361|       |        // size exceeds the limit.
 7362|       |
 7363|    581|        if (is_chunked_transfer_encoding(x.headers)) {
 7364|    581|          auto result = read_content_chunked(strm, x, payload_max_length, out);
 7365|    581|          if (result == ReadContentResult::Success) {
 7366|    581|            ret = true;
 7367|    581|          } else if (result == ReadContentResult::PayloadTooLarge) {
 7368|    581|            exceed_payload_max_length = true;
 7369|    581|            ret = false;
 7370|    581|          } else {
 7371|    581|            ret = false;
 7372|    581|          }
 7373|    581|        } else if (!has_header(x.headers, "Content-Length")) {
 7374|    581|          auto result =
 7375|    581|              read_content_without_length(strm, payload_max_length, out);
 7376|    581|          if (result == ReadContentResult::Success) {
 7377|    581|            ret = true;
 7378|    581|          } else if (result == ReadContentResult::PayloadTooLarge) {
 7379|    581|            exceed_payload_max_length = true;
 7380|    581|            ret = false;
 7381|    581|          } else {
 7382|    581|            ret = false;
 7383|    581|          }
 7384|    581|        } else {
 7385|    581|          auto is_invalid_value = false;
 7386|    581|          auto len = get_header_value_u64(x.headers, "Content-Length",
 7387|    581|                                          (std::numeric_limits<size_t>::max)(),
 7388|    581|                                          0, is_invalid_value);
 7389|       |
 7390|    581|          if (is_invalid_value) {
 7391|    581|            ret = false;
 7392|    581|          } else if (len > 0) {
 7393|    581|            auto result = read_content_with_length(
 7394|    581|                strm, len, std::move(progress), out, payload_max_length);
 7395|    581|            ret = (result == ReadContentResult::Success);
 7396|    581|            if (result == ReadContentResult::PayloadTooLarge) {
 7397|    581|              exceed_payload_max_length = true;
 7398|    581|            }
 7399|    581|          }
 7400|    581|        }
 7401|       |
 7402|    581|        if (!ret) {
 7403|    581|          status = exceed_payload_max_length ? StatusCode::PayloadTooLarge_413
 7404|    581|                                             : StatusCode::BadRequest_400;
 7405|    581|        }
 7406|    581|        return ret;
 7407|    581|      });
 7408|    581|}
_ZN7httplib6detail24prepare_content_receiverINS_8ResponseEZNS0_12read_contentIS2_EEbRNS_6StreamERT_mRiNSt3__18functionIFbmmEEENSA_IFbPKcmmmEEEbEUlRKSG_E_EEbS7_S8_SG_bmRbT0_:
 7302|    581|                              bool &exceed_payload_max_length, U callback) {
 7303|    581|  if (decompress) {
  ------------------
  |  Branch (7303:7): [True: 581, False: 0]
  ------------------
 7304|    581|    std::string encoding = x.get_header_value("Content-Encoding");
 7305|    581|    std::unique_ptr<decompressor> decompressor;
 7306|       |
 7307|    581|    if (!encoding.empty()) {
  ------------------
  |  Branch (7307:9): [True: 193, False: 388]
  ------------------
 7308|    193|      decompressor = detail::create_decompressor(encoding);
 7309|    193|      if (!decompressor) {
  ------------------
  |  Branch (7309:11): [True: 107, False: 86]
  ------------------
 7310|       |        // Unsupported encoding or no support compiled in
 7311|    107|        status = StatusCode::UnsupportedMediaType_415;
 7312|    107|        return false;
 7313|    107|      }
 7314|    193|    }
 7315|       |
 7316|    474|    if (decompressor) {
  ------------------
  |  Branch (7316:9): [True: 86, False: 388]
  ------------------
 7317|     86|      if (decompressor->is_valid()) {
  ------------------
  |  Branch (7317:11): [True: 86, False: 0]
  ------------------
 7318|     86|        size_t decompressed_size = 0;
 7319|     86|        ContentReceiverWithProgress out = [&](const char *buf, size_t n,
 7320|     86|                                              size_t off, size_t len) {
 7321|     86|          return decompressor->decompress(
 7322|     86|              buf, n, [&](const char *buf2, size_t n2) {
 7323|       |                // Guard against zip-bomb: check
 7324|       |                // decompressed size against limit.
 7325|     86|                if (payload_max_length > 0 &&
 7326|     86|                    (decompressed_size >= payload_max_length ||
 7327|     86|                     n2 > payload_max_length - decompressed_size)) {
 7328|     86|                  exceed_payload_max_length = true;
 7329|     86|                  return false;
 7330|     86|                }
 7331|     86|                decompressed_size += n2;
 7332|     86|                return receiver(buf2, n2, off, len);
 7333|     86|              });
 7334|     86|        };
 7335|     86|        return callback(std::move(out));
 7336|     86|      } else {
 7337|      0|        status = StatusCode::InternalServerError_500;
 7338|      0|        return false;
 7339|      0|      }
 7340|     86|    }
 7341|    474|  }
 7342|       |
 7343|    388|  ContentReceiverWithProgress out = [&](const char *buf, size_t n, size_t off,
 7344|    388|                                        size_t len) {
 7345|    388|    return receiver(buf, n, off, len);
 7346|    388|  };
 7347|    388|  return callback(std::move(out));
 7348|    581|}
_ZNK7httplib8Response16get_header_valueERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEPKcm:
 9952|    581|                                              size_t id) const {
 9953|    581|  return detail::get_header_value(headers, key, def, id);
 9954|    581|}
_ZN7httplib6detail19create_decompressorERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
 6996|    193|create_decompressor(const std::string &encoding) {
 6997|    193|  std::unique_ptr<decompressor> decompressor;
 6998|       |
 6999|    193|  if (encoding == "gzip" || encoding == "deflate") {
  ------------------
  |  Branch (6999:7): [True: 16, False: 177]
  |  Branch (6999:29): [True: 70, False: 107]
  ------------------
 7000|     86|#ifdef CPPHTTPLIB_ZLIB_SUPPORT
 7001|     86|    decompressor = detail::make_unique<gzip_decompressor>();
 7002|     86|#endif
 7003|    107|  } else if (encoding.find("br") != std::string::npos) {
  ------------------
  |  Branch (7003:14): [True: 10, False: 97]
  ------------------
 7004|       |#ifdef CPPHTTPLIB_BROTLI_SUPPORT
 7005|       |    decompressor = detail::make_unique<brotli_decompressor>();
 7006|       |#endif
 7007|     97|  } else if (encoding == "zstd" || encoding.find("zstd") != std::string::npos) {
  ------------------
  |  Branch (7007:14): [True: 0, False: 97]
  |  Branch (7007:36): [True: 11, False: 86]
  ------------------
 7008|       |#ifdef CPPHTTPLIB_ZSTD_SUPPORT
 7009|       |    decompressor = detail::make_unique<zstd_decompressor>();
 7010|       |#endif
 7011|     11|  }
 7012|       |
 7013|    193|  return decompressor;
 7014|    193|}
_ZN7httplib6detail11make_uniqueINS0_17gzip_decompressorEJEEENSt3__19enable_ifIXntsr3std8is_arrayIT_EE5valueENS3_10unique_ptrIS5_NS3_14default_deleteIS5_EEEEE4typeEDpOT0_:
  532|     86|make_unique(Args &&...args) {
  533|     86|  return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
  534|     86|}
_ZN7httplib6detail17gzip_decompressorC2Ev:
 6793|     86|inline gzip_decompressor::gzip_decompressor() {
 6794|     86|  std::memset(&strm_, 0, sizeof(strm_));
 6795|     86|  strm_.zalloc = Z_NULL;
 6796|     86|  strm_.zfree = Z_NULL;
 6797|     86|  strm_.opaque = Z_NULL;
 6798|       |
 6799|       |  // 15 is the value of wbits, which should be at the maximum possible value
 6800|       |  // to ensure that any gzip stream can be decoded. The offset of 32 specifies
 6801|       |  // that the stream type should be automatically detected either gzip or
 6802|       |  // deflate.
 6803|     86|  is_valid_ = inflateInit2(&strm_, 32 + 15) == Z_OK;
 6804|     86|}
_ZZN7httplib6detail24prepare_content_receiverINS_8ResponseEZNS0_12read_contentIS2_EEbRNS_6StreamERT_mRiNSt3__18functionIFbmmEEENSA_IFbPKcmmmEEEbEUlRKSG_E_EEbS7_S8_SG_bmRbT0_ENKUlSE_mmmE_clESE_mmm:
 7320|    725|                                              size_t off, size_t len) {
 7321|    725|          return decompressor->decompress(
 7322|    725|              buf, n, [&](const char *buf2, size_t n2) {
 7323|       |                // Guard against zip-bomb: check
 7324|       |                // decompressed size against limit.
 7325|    725|                if (payload_max_length > 0 &&
 7326|    725|                    (decompressed_size >= payload_max_length ||
 7327|    725|                     n2 > payload_max_length - decompressed_size)) {
 7328|    725|                  exceed_payload_max_length = true;
 7329|    725|                  return false;
 7330|    725|                }
 7331|    725|                decompressed_size += n2;
 7332|    725|                return receiver(buf2, n2, off, len);
 7333|    725|              });
 7334|    725|        };
_ZZZN7httplib6detail24prepare_content_receiverINS_8ResponseEZNS0_12read_contentIS2_EEbRNS_6StreamERT_mRiNSt3__18functionIFbmmEEENSA_IFbPKcmmmEEEbEUlRKSG_E_EEbS7_S8_SG_bmRbT0_ENKUlSE_mmmE_clESE_mmmENKUlSE_mE_clESE_m:
 7322|  51.6k|              buf, n, [&](const char *buf2, size_t n2) {
 7323|       |                // Guard against zip-bomb: check
 7324|       |                // decompressed size against limit.
 7325|  51.6k|                if (payload_max_length > 0 &&
  ------------------
  |  Branch (7325:21): [True: 51.6k, False: 0]
  ------------------
 7326|  51.6k|                    (decompressed_size >= payload_max_length ||
  ------------------
  |  Branch (7326:22): [True: 0, False: 51.6k]
  ------------------
 7327|  51.6k|                     n2 > payload_max_length - decompressed_size)) {
  ------------------
  |  Branch (7327:22): [True: 4, False: 51.6k]
  ------------------
 7328|      4|                  exceed_payload_max_length = true;
 7329|      4|                  return false;
 7330|      4|                }
 7331|  51.6k|                decompressed_size += n2;
 7332|  51.6k|                return receiver(buf2, n2, off, len);
 7333|  51.6k|              });
_ZZN7httplib6detail12read_contentINS_8ResponseEEEbRNS_6StreamERT_mRiNSt3__18functionIFbmmEEENS9_IFbPKcmmmEEEbENKUlRKSF_E_clESH_:
 7357|    474|      exceed_payload_max_length, [&](const ContentReceiverWithProgress &out) {
 7358|    474|        auto ret = true;
 7359|       |        // Note: exceed_payload_max_length may also be set by the decompressor
 7360|       |        // wrapper in prepare_content_receiver when the decompressed payload
 7361|       |        // size exceeds the limit.
 7362|       |
 7363|    474|        if (is_chunked_transfer_encoding(x.headers)) {
  ------------------
  |  Branch (7363:13): [True: 73, False: 401]
  ------------------
 7364|     73|          auto result = read_content_chunked(strm, x, payload_max_length, out);
 7365|     73|          if (result == ReadContentResult::Success) {
  ------------------
  |  Branch (7365:15): [True: 0, False: 73]
  ------------------
 7366|      0|            ret = true;
 7367|     73|          } else if (result == ReadContentResult::PayloadTooLarge) {
  ------------------
  |  Branch (7367:22): [True: 0, False: 73]
  ------------------
 7368|      0|            exceed_payload_max_length = true;
 7369|      0|            ret = false;
 7370|     73|          } else {
 7371|     73|            ret = false;
 7372|     73|          }
 7373|    401|        } else if (!has_header(x.headers, "Content-Length")) {
  ------------------
  |  Branch (7373:20): [True: 393, False: 8]
  ------------------
 7374|    393|          auto result =
 7375|    393|              read_content_without_length(strm, payload_max_length, out);
 7376|    393|          if (result == ReadContentResult::Success) {
  ------------------
  |  Branch (7376:15): [True: 353, False: 40]
  ------------------
 7377|    353|            ret = true;
 7378|    353|          } else if (result == ReadContentResult::PayloadTooLarge) {
  ------------------
  |  Branch (7378:22): [True: 0, False: 40]
  ------------------
 7379|      0|            exceed_payload_max_length = true;
 7380|      0|            ret = false;
 7381|     40|          } else {
 7382|     40|            ret = false;
 7383|     40|          }
 7384|    393|        } else {
 7385|      8|          auto is_invalid_value = false;
 7386|      8|          auto len = get_header_value_u64(x.headers, "Content-Length",
 7387|      8|                                          (std::numeric_limits<size_t>::max)(),
 7388|      8|                                          0, is_invalid_value);
 7389|       |
 7390|      8|          if (is_invalid_value) {
  ------------------
  |  Branch (7390:15): [True: 6, False: 2]
  ------------------
 7391|      6|            ret = false;
 7392|      6|          } else if (len > 0) {
  ------------------
  |  Branch (7392:22): [True: 2, False: 0]
  ------------------
 7393|      2|            auto result = read_content_with_length(
 7394|      2|                strm, len, std::move(progress), out, payload_max_length);
 7395|      2|            ret = (result == ReadContentResult::Success);
 7396|      2|            if (result == ReadContentResult::PayloadTooLarge) {
  ------------------
  |  Branch (7396:17): [True: 0, False: 2]
  ------------------
 7397|      0|              exceed_payload_max_length = true;
 7398|      0|            }
 7399|      2|          }
 7400|      8|        }
 7401|       |
 7402|    474|        if (!ret) {
  ------------------
  |  Branch (7402:13): [True: 120, False: 354]
  ------------------
 7403|    120|          status = exceed_payload_max_length ? StatusCode::PayloadTooLarge_413
  ------------------
  |  Branch (7403:20): [True: 4, False: 116]
  ------------------
 7404|    120|                                             : StatusCode::BadRequest_400;
 7405|    120|        }
 7406|    474|        return ret;
 7407|    474|      });
_ZN7httplib6detail28is_chunked_transfer_encodingERKNSt3__118unordered_multimapINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEES8_NS0_11case_ignore4hashENS9_8equal_toENS6_INS1_4pairIKS8_S8_EEEEEE:
 7293|    474|inline bool is_chunked_transfer_encoding(const Headers &headers) {
 7294|    474|  return case_ignore::equal(
 7295|    474|      get_header_value(headers, "Transfer-Encoding", "", 0), "chunked");
 7296|    474|}
_ZN7httplib6detail20read_content_chunkedINS_8ResponseEEENS0_17ReadContentResultERNS_6StreamERT_mNSt3__18functionIFbPKcmmmEEE:
 7261|     73|                                              ContentReceiverWithProgress out) {
 7262|     73|  detail::ChunkedDecoder dec(strm);
 7263|       |
 7264|     73|  char buf[CPPHTTPLIB_RECV_BUFSIZ];
 7265|     73|  size_t total_len = 0;
 7266|       |
 7267|     83|  for (;;) {
 7268|     83|    size_t chunk_offset = 0;
 7269|     83|    size_t chunk_total = 0;
 7270|     83|    auto n = dec.read_payload(buf, sizeof(buf), chunk_offset, chunk_total);
 7271|     83|    if (n < 0) { return ReadContentResult::Error; }
  ------------------
  |  Branch (7271:9): [True: 73, False: 10]
  ------------------
 7272|       |
 7273|     10|    if (n == 0) {
  ------------------
  |  Branch (7273:9): [True: 0, False: 10]
  ------------------
 7274|      0|      if (!dec.parse_trailers_into(x.trailers, x.headers)) {
  ------------------
  |  Branch (7274:11): [True: 0, False: 0]
  ------------------
 7275|      0|        return ReadContentResult::Error;
 7276|      0|      }
 7277|      0|      return ReadContentResult::Success;
 7278|      0|    }
 7279|       |
 7280|     10|    if (total_len > payload_max_length ||
  ------------------
  |  Branch (7280:9): [True: 0, False: 10]
  ------------------
 7281|     10|        payload_max_length - total_len < static_cast<size_t>(n)) {
  ------------------
  |  Branch (7281:9): [True: 0, False: 10]
  ------------------
 7282|      0|      return ReadContentResult::PayloadTooLarge;
 7283|      0|    }
 7284|       |
 7285|     10|    if (!out(buf, static_cast<size_t>(n), chunk_offset, chunk_total)) {
  ------------------
  |  Branch (7285:9): [True: 0, False: 10]
  ------------------
 7286|      0|      return ReadContentResult::Error;
 7287|      0|    }
 7288|       |
 7289|     10|    total_len += static_cast<size_t>(n);
 7290|     10|  }
 7291|     73|}
_ZN7httplib6detail14ChunkedDecoderC2ERNS_6StreamE:
13163|     73|inline ChunkedDecoder::ChunkedDecoder(Stream &s) : strm(s) {}
_ZN7httplib6detail14ChunkedDecoder12read_payloadEPcmRmS3_:
13167|     83|                                            size_t &out_chunk_total) {
13168|     83|  if (finished) { return 0; }
  ------------------
  |  Branch (13168:7): [True: 0, False: 83]
  ------------------
13169|       |
13170|     83|  if (chunk_remaining == 0) {
  ------------------
  |  Branch (13170:7): [True: 80, False: 3]
  ------------------
13171|     80|    stream_line_reader lr(strm, line_buf, sizeof(line_buf));
13172|     80|    if (!lr.getline()) { return -1; }
  ------------------
  |  Branch (13172:9): [True: 1, False: 79]
  ------------------
13173|       |
13174|       |    // RFC 9112 §7.1: chunk-size = 1*HEXDIG
13175|     79|    const char *p = lr.ptr();
13176|     79|    int v = 0;
13177|     79|    if (!is_hex(*p, v)) { return -1; }
  ------------------
  |  Branch (13177:9): [True: 7, False: 72]
  ------------------
13178|       |
13179|     72|    size_t chunk_len = 0;
13180|     72|    constexpr size_t chunk_len_max = (std::numeric_limits<size_t>::max)();
13181|    209|    for (; is_hex(*p, v); ++p) {
  ------------------
  |  Branch (13181:12): [True: 138, False: 71]
  ------------------
13182|    138|      if (chunk_len > (chunk_len_max >> 4)) { return -1; }
  ------------------
  |  Branch (13182:11): [True: 1, False: 137]
  ------------------
13183|    137|      chunk_len = (chunk_len << 4) | static_cast<size_t>(v);
13184|    137|    }
13185|       |
13186|     71|    while (is_space_or_tab(*p)) {
  ------------------
  |  Branch (13186:12): [True: 0, False: 71]
  ------------------
13187|      0|      ++p;
13188|      0|    }
13189|     71|    if (*p != '\0' && *p != ';' && *p != '\r' && *p != '\n') { return -1; }
  ------------------
  |  Branch (13189:9): [True: 70, False: 1]
  |  Branch (13189:23): [True: 70, False: 0]
  |  Branch (13189:36): [True: 70, False: 0]
  |  Branch (13189:50): [True: 61, False: 9]
  ------------------
13190|       |
13191|     10|    if (chunk_len == 0) {
  ------------------
  |  Branch (13191:9): [True: 0, False: 10]
  ------------------
13192|      0|      chunk_remaining = 0;
13193|      0|      finished = true;
13194|      0|      out_chunk_offset = 0;
13195|      0|      out_chunk_total = 0;
13196|      0|      return 0;
13197|      0|    }
13198|       |
13199|     10|    chunk_remaining = chunk_len;
13200|     10|    last_chunk_total = chunk_remaining;
13201|     10|    last_chunk_offset = 0;
13202|     10|  }
13203|       |
13204|     13|  auto to_read = (std::min)(chunk_remaining, len);
13205|     13|  auto n = strm.read(buf, to_read);
13206|     13|  if (n <= 0) { return -1; }
  ------------------
  |  Branch (13206:7): [True: 2, False: 11]
  ------------------
13207|       |
13208|     11|  auto offset_before = last_chunk_offset;
13209|     11|  last_chunk_offset += static_cast<size_t>(n);
13210|     11|  chunk_remaining -= static_cast<size_t>(n);
13211|       |
13212|     11|  out_chunk_offset = offset_before;
13213|     11|  out_chunk_total = last_chunk_total;
13214|       |
13215|     11|  if (chunk_remaining == 0) {
  ------------------
  |  Branch (13215:7): [True: 8, False: 3]
  ------------------
13216|      8|    stream_line_reader lr(strm, line_buf, sizeof(line_buf));
13217|      8|    if (!lr.getline()) { return -1; }
  ------------------
  |  Branch (13217:9): [True: 0, False: 8]
  ------------------
13218|      8|    if (std::strcmp(lr.ptr(), "\r\n") != 0) { return -1; }
  ------------------
  |  Branch (13218:9): [True: 1, False: 7]
  ------------------
13219|      8|  }
13220|       |
13221|     10|  return n;
13222|     11|}
_ZN7httplib6detail6is_hexEcRi:
 4405|    288|inline bool is_hex(char c, int &v) {
 4406|    288|  if (isdigit(static_cast<unsigned char>(c))) {
  ------------------
  |  Branch (4406:7): [True: 157, False: 131]
  ------------------
 4407|    157|    v = c - '0';
 4408|    157|    return true;
 4409|    157|  } else if ('A' <= c && c <= 'F') {
  ------------------
  |  Branch (4409:14): [True: 56, False: 75]
  |  Branch (4409:26): [True: 0, False: 56]
  ------------------
 4410|      0|    v = c - 'A' + 10;
 4411|      0|    return true;
 4412|    131|  } else if ('a' <= c && c <= 'f') {
  ------------------
  |  Branch (4412:14): [True: 55, False: 76]
  |  Branch (4412:26): [True: 53, False: 2]
  ------------------
 4413|     53|    v = c - 'a' + 10;
 4414|     53|    return true;
 4415|     53|  }
 4416|     78|  return false;
 4417|    288|}
_ZN7httplib6detail27read_content_without_lengthERNS_6StreamEmNSt3__18functionIFbPKcmmmEEE:
 7235|    393|                            ContentReceiverWithProgress out) {
 7236|    393|  char buf[CPPHTTPLIB_RECV_BUFSIZ];
 7237|    393|  size_t r = 0;
 7238|  1.41k|  for (;;) {
 7239|  1.41k|    auto n = strm.read(buf, CPPHTTPLIB_RECV_BUFSIZ);
  ------------------
  |  |  150|  1.41k|#define CPPHTTPLIB_RECV_BUFSIZ size_t(16384u)
  ------------------
 7240|  1.41k|    if (n == 0) { return ReadContentResult::Success; }
  ------------------
  |  Branch (7240:9): [True: 353, False: 1.05k]
  ------------------
 7241|  1.05k|    if (n < 0) { return ReadContentResult::Error; }
  ------------------
  |  Branch (7241:9): [True: 0, False: 1.05k]
  ------------------
 7242|       |
 7243|       |    // Check if adding this data would exceed the payload limit
 7244|  1.05k|    if (r > payload_max_length ||
  ------------------
  |  Branch (7244:9): [True: 0, False: 1.05k]
  ------------------
 7245|  1.05k|        payload_max_length - r < static_cast<size_t>(n)) {
  ------------------
  |  Branch (7245:9): [True: 0, False: 1.05k]
  ------------------
 7246|      0|      return ReadContentResult::PayloadTooLarge;
 7247|      0|    }
 7248|       |
 7249|  1.05k|    if (!out(buf, static_cast<size_t>(n), r, 0)) {
  ------------------
  |  Branch (7249:9): [True: 40, False: 1.01k]
  ------------------
 7250|     40|      return ReadContentResult::Error;
 7251|     40|    }
 7252|  1.01k|    r += static_cast<size_t>(n);
 7253|  1.01k|  }
 7254|       |
 7255|      0|  return ReadContentResult::Success;
 7256|    393|}
_ZN7httplib6detail24read_content_with_lengthERNS_6StreamEmNSt3__18functionIFbmmEEENS4_IFbPKcmmmEEEm:
 7195|      2|    size_t payload_max_length = (std::numeric_limits<size_t>::max)()) {
 7196|      2|  char buf[CPPHTTPLIB_RECV_BUFSIZ];
 7197|       |
 7198|      2|  detail::BodyReader br;
 7199|      2|  br.stream = &strm;
 7200|      2|  br.has_content_length = true;
 7201|      2|  br.content_length = len;
 7202|      2|  br.payload_max_length = payload_max_length;
 7203|      2|  br.chunked = false;
 7204|      2|  br.bytes_read = 0;
 7205|      2|  br.last_error = Error::Success;
 7206|       |
 7207|      2|  size_t r = 0;
 7208|      3|  while (r < len) {
  ------------------
  |  Branch (7208:10): [True: 2, False: 1]
  ------------------
 7209|      2|    auto read_len = static_cast<size_t>(len - r);
 7210|      2|    auto to_read = (std::min)(read_len, CPPHTTPLIB_RECV_BUFSIZ);
  ------------------
  |  |  150|      2|#define CPPHTTPLIB_RECV_BUFSIZ size_t(16384u)
  ------------------
 7211|      2|    auto n = detail::read_body_content(&strm, br, buf, to_read);
 7212|      2|    if (n <= 0) {
  ------------------
  |  Branch (7212:9): [True: 0, False: 2]
  ------------------
 7213|       |      // Check if it was a payload size error
 7214|      0|      if (br.last_error == Error::ExceedMaxPayloadSize) {
  ------------------
  |  Branch (7214:11): [True: 0, False: 0]
  ------------------
 7215|      0|        return ReadContentResult::PayloadTooLarge;
 7216|      0|      }
 7217|      0|      return ReadContentResult::Error;
 7218|      0|    }
 7219|       |
 7220|      2|    if (!out(buf, static_cast<size_t>(n), r, len)) {
  ------------------
  |  Branch (7220:9): [True: 1, False: 1]
  ------------------
 7221|      1|      return ReadContentResult::Error;
 7222|      1|    }
 7223|      1|    r += static_cast<size_t>(n);
 7224|       |
 7225|      1|    if (progress) {
  ------------------
  |  Branch (7225:9): [True: 1, False: 0]
  ------------------
 7226|      1|      if (!progress(r, len)) { return ReadContentResult::Error; }
  ------------------
  |  Branch (7226:11): [True: 0, False: 1]
  ------------------
 7227|      1|    }
 7228|      1|  }
 7229|       |
 7230|      1|  return ReadContentResult::Success;
 7231|      2|}
_ZN7httplib6detail17read_body_contentEPNS_6StreamERNS0_10BodyReaderEPcm:
 2031|      2|                                 size_t len) {
 2032|      2|  (void)stream;
 2033|      2|  return br.read(buf, len);
 2034|      2|}
_ZN7httplib6detail10BodyReader4readEPcm:
10085|      2|inline ssize_t detail::BodyReader::read(char *buf, size_t len) {
10086|      2|  if (!stream) {
  ------------------
  |  Branch (10086:7): [True: 0, False: 2]
  ------------------
10087|      0|    last_error = Error::Connection;
10088|      0|    return -1;
10089|      0|  }
10090|      2|  if (eof) { return 0; }
  ------------------
  |  Branch (10090:7): [True: 0, False: 2]
  ------------------
10091|       |
10092|      2|  if (!chunked) {
  ------------------
  |  Branch (10092:7): [True: 2, False: 0]
  ------------------
10093|       |    // Content-Length based reading
10094|      2|    if (has_content_length && bytes_read >= content_length) {
  ------------------
  |  Branch (10094:9): [True: 2, False: 0]
  |  Branch (10094:31): [True: 0, False: 2]
  ------------------
10095|      0|      eof = true;
10096|      0|      return 0;
10097|      0|    }
10098|       |
10099|      2|    auto to_read = len;
10100|      2|    if (has_content_length) {
  ------------------
  |  Branch (10100:9): [True: 2, False: 0]
  ------------------
10101|      2|      auto remaining = content_length - bytes_read;
10102|      2|      to_read = (std::min)(len, remaining);
10103|      2|    }
10104|      2|    auto n = stream->read(buf, to_read);
10105|       |
10106|      2|    if (n < 0) {
  ------------------
  |  Branch (10106:9): [True: 0, False: 2]
  ------------------
10107|      0|      last_error = stream->get_error();
10108|      0|      if (last_error == Error::Success) { last_error = Error::Read; }
  ------------------
  |  Branch (10108:11): [True: 0, False: 0]
  ------------------
10109|      0|      eof = true;
10110|      0|      return n;
10111|      0|    }
10112|      2|    if (n == 0) {
  ------------------
  |  Branch (10112:9): [True: 0, False: 2]
  ------------------
10113|       |      // Unexpected EOF before content_length
10114|      0|      last_error = stream->get_error();
10115|      0|      if (last_error == Error::Success) { last_error = Error::Read; }
  ------------------
  |  Branch (10115:11): [True: 0, False: 0]
  ------------------
10116|      0|      eof = true;
10117|      0|      return 0;
10118|      0|    }
10119|       |
10120|      2|    bytes_read += static_cast<size_t>(n);
10121|      2|    if (has_content_length && bytes_read >= content_length) { eof = true; }
  ------------------
  |  Branch (10121:9): [True: 2, False: 0]
  |  Branch (10121:31): [True: 1, False: 1]
  ------------------
10122|      2|    if (payload_max_length > 0 && bytes_read > payload_max_length) {
  ------------------
  |  Branch (10122:9): [True: 2, False: 0]
  |  Branch (10122:35): [True: 0, False: 2]
  ------------------
10123|      0|      last_error = Error::ExceedMaxPayloadSize;
10124|      0|      eof = true;
10125|      0|      return -1;
10126|      0|    }
10127|      2|    return n;
10128|      2|  }
10129|       |
10130|       |  // Chunked transfer encoding: delegate to shared decoder instance.
10131|      0|  if (!chunked_decoder) { chunked_decoder.reset(new ChunkedDecoder(*stream)); }
  ------------------
  |  Branch (10131:7): [True: 0, False: 0]
  ------------------
10132|       |
10133|      0|  size_t chunk_offset = 0;
10134|      0|  size_t chunk_total = 0;
10135|      0|  auto n = chunked_decoder->read_payload(buf, len, chunk_offset, chunk_total);
10136|      0|  if (n < 0) {
  ------------------
  |  Branch (10136:7): [True: 0, False: 0]
  ------------------
10137|      0|    last_error = stream->get_error();
10138|      0|    if (last_error == Error::Success) { last_error = Error::Read; }
  ------------------
  |  Branch (10138:9): [True: 0, False: 0]
  ------------------
10139|      0|    eof = true;
10140|      0|    return n;
10141|      0|  }
10142|       |
10143|      0|  if (n == 0) {
  ------------------
  |  Branch (10143:7): [True: 0, False: 0]
  ------------------
10144|       |    // Final chunk observed. Leave trailer parsing to the caller (StreamHandle).
10145|      0|    eof = true;
10146|      0|    return 0;
10147|      0|  }
10148|       |
10149|      0|  bytes_read += static_cast<size_t>(n);
10150|      0|  if (payload_max_length > 0 && bytes_read > payload_max_length) {
  ------------------
  |  Branch (10150:7): [True: 0, False: 0]
  |  Branch (10150:33): [True: 0, False: 0]
  ------------------
10151|      0|    last_error = Error::ExceedMaxPayloadSize;
10152|      0|    eof = true;
10153|      0|    return -1;
10154|      0|  }
10155|      0|  return n;
10156|      0|}
_ZZN7httplib6detail24prepare_content_receiverINS_8ResponseEZNS0_12read_contentIS2_EEbRNS_6StreamERT_mRiNSt3__18functionIFbmmEEENSA_IFbPKcmmmEEEbEUlRKSG_E_EEbS7_S8_SG_bmRbT0_ENKUlSE_mmmE0_clESE_mmm:
 7344|    345|                                        size_t len) {
 7345|    345|    return receiver(buf, n, off, len);
 7346|    345|  };
_ZZN7httplib10ClientImpl15process_requestERNS_6StreamERNS_7RequestERNS_8ResponseEbRNS_5ErrorEENKUlmmE_clEmm:
14003|      1|    auto progress = [&](size_t current, size_t total) {
14004|      1|      if (!req.download_progress || redirect) { return true; }
  ------------------
  |  Branch (14004:11): [True: 1, False: 0]
  |  Branch (14004:37): [True: 0, False: 0]
  ------------------
14005|      0|      auto ret = req.download_progress(current, total);
14006|      0|      if (!ret) {
  ------------------
  |  Branch (14006:11): [True: 0, False: 0]
  ------------------
14007|      0|        error = Error::Canceled;
14008|      0|        output_error_log(error, &req);
14009|      0|      }
14010|      0|      return ret;
14011|      1|    };
_ZNK7httplib10ClientImpl10output_logERKNS_7RequestERKNS_8ResponseE:
13859|    358|                                   const Response &res) const {
13860|    358|  if (logger_) {
  ------------------
  |  Branch (13860:7): [True: 0, False: 358]
  ------------------
13861|      0|    std::lock_guard<std::mutex> guard(logger_mutex_);
13862|      0|    logger_(req, res);
13863|      0|  }
13864|    358|}
_ZN7httplib8ResponseD2Ev:
 1388|  1.96k|  ~Response() {
 1389|  1.96k|    if (content_provider_resource_releaser_) {
  ------------------
  |  Branch (1389:9): [True: 0, False: 1.96k]
  ------------------
 1390|      0|      content_provider_resource_releaser_(content_provider_success_);
 1391|      0|    }
 1392|  1.96k|  }
_ZNK7httplib6detail17gzip_decompressor8is_validEv:
 6808|     86|inline bool gzip_decompressor::is_valid() const { return is_valid_; }
_ZN7httplib6detail17gzip_decompressor10decompressEPKcmNSt3__18functionIFbS3_mEEE:
 6811|    725|                                          Callback callback) {
 6812|    725|  assert(is_valid_);
  ------------------
  |  Branch (6812:3): [True: 725, False: 0]
  ------------------
 6813|       |
 6814|    725|  auto ret = Z_OK;
 6815|       |
 6816|    725|  do {
 6817|    725|    constexpr size_t max_avail_in =
 6818|    725|        (std::numeric_limits<decltype(strm_.avail_in)>::max)();
 6819|       |
 6820|    725|    strm_.avail_in = static_cast<decltype(strm_.avail_in)>(
 6821|    725|        (std::min)(data_length, max_avail_in));
 6822|    725|    strm_.next_in = const_cast<Bytef *>(reinterpret_cast<const Bytef *>(data));
 6823|       |
 6824|    725|    data_length -= strm_.avail_in;
 6825|    725|    data += strm_.avail_in;
 6826|       |
 6827|    725|    std::array<char, CPPHTTPLIB_COMPRESSION_BUFSIZ> buff{};
 6828|  52.4k|    while (strm_.avail_in > 0 && ret == Z_OK) {
  ------------------
  |  Branch (6828:12): [True: 51.7k, False: 618]
  |  Branch (6828:34): [True: 51.7k, False: 66]
  ------------------
 6829|  51.7k|      strm_.avail_out = static_cast<uInt>(buff.size());
 6830|  51.7k|      strm_.next_out = reinterpret_cast<Bytef *>(buff.data());
 6831|       |
 6832|  51.7k|      ret = inflate(&strm_, Z_NO_FLUSH);
 6833|       |
 6834|  51.7k|      assert(ret != Z_STREAM_ERROR);
  ------------------
  |  Branch (6834:7): [True: 51.7k, False: 0]
  ------------------
 6835|  51.7k|      switch (ret) {
  ------------------
  |  Branch (6835:15): [True: 37, False: 51.6k]
  ------------------
 6836|      2|      case Z_NEED_DICT:
  ------------------
  |  Branch (6836:7): [True: 2, False: 51.7k]
  ------------------
 6837|     37|      case Z_DATA_ERROR:
  ------------------
  |  Branch (6837:7): [True: 35, False: 51.6k]
  ------------------
 6838|     37|      case Z_MEM_ERROR: inflateEnd(&strm_); return false;
  ------------------
  |  Branch (6838:7): [True: 0, False: 51.7k]
  ------------------
 6839|  51.7k|      }
 6840|       |
 6841|  51.6k|      if (!callback(buff.data(), buff.size() - strm_.avail_out)) {
  ------------------
  |  Branch (6841:11): [True: 4, False: 51.6k]
  ------------------
 6842|      4|        return false;
 6843|      4|      }
 6844|  51.6k|    }
 6845|       |
 6846|    684|    if (ret != Z_OK && ret != Z_STREAM_END) { return false; }
  ------------------
  |  Branch (6846:9): [True: 66, False: 618]
  |  Branch (6846:24): [True: 0, False: 66]
  ------------------
 6847|       |
 6848|    684|  } while (data_length > 0);
  ------------------
  |  Branch (6848:12): [True: 0, False: 684]
  ------------------
 6849|       |
 6850|    684|  return true;
 6851|    725|}
_ZN7httplib6detail12BufferStreamD2Ev:
 3106|  1.96k|  ~BufferStream() override = default;
_ZN7httplib6detail12BufferStream5writeEPKcm:
10475|  13.0k|inline ssize_t BufferStream::write(const char *ptr, size_t size) {
10476|  13.0k|  buffer.append(ptr, size);
10477|  13.0k|  return static_cast<ssize_t>(size);
10478|  13.0k|}
_ZNK7httplib10ClientImpl6is_sslEv:
14107|  1.96k|inline bool ClientImpl::is_ssl() const { return false; }

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

