chromium/third_party/crashpad/crashpad/third_party/cpp-httplib/cpp-httplib/httplib.h

//
//  httplib.h
//
//  Copyright (c) 2024 Yuji Hirose. All rights reserved.
//  MIT License
//

#ifndef CPPHTTPLIB_HTTPLIB_H
#define CPPHTTPLIB_HTTPLIB_H

#define CPPHTTPLIB_VERSION

/*
 * Configuration
 */

#ifndef CPPHTTPLIB_KEEPALIVE_TIMEOUT_SECOND
#define CPPHTTPLIB_KEEPALIVE_TIMEOUT_SECOND
#endif

#ifndef CPPHTTPLIB_KEEPALIVE_MAX_COUNT
#define CPPHTTPLIB_KEEPALIVE_MAX_COUNT
#endif

#ifndef CPPHTTPLIB_CONNECTION_TIMEOUT_SECOND
#define CPPHTTPLIB_CONNECTION_TIMEOUT_SECOND
#endif

#ifndef CPPHTTPLIB_CONNECTION_TIMEOUT_USECOND
#define CPPHTTPLIB_CONNECTION_TIMEOUT_USECOND
#endif

#ifndef CPPHTTPLIB_READ_TIMEOUT_SECOND
#define CPPHTTPLIB_READ_TIMEOUT_SECOND
#endif

#ifndef CPPHTTPLIB_READ_TIMEOUT_USECOND
#define CPPHTTPLIB_READ_TIMEOUT_USECOND
#endif

#ifndef CPPHTTPLIB_WRITE_TIMEOUT_SECOND
#define CPPHTTPLIB_WRITE_TIMEOUT_SECOND
#endif

#ifndef CPPHTTPLIB_WRITE_TIMEOUT_USECOND
#define CPPHTTPLIB_WRITE_TIMEOUT_USECOND
#endif

#ifndef CPPHTTPLIB_IDLE_INTERVAL_SECOND
#define CPPHTTPLIB_IDLE_INTERVAL_SECOND
#endif

#ifndef CPPHTTPLIB_IDLE_INTERVAL_USECOND
#ifdef _WIN32
#define CPPHTTPLIB_IDLE_INTERVAL_USECOND
#else
#define CPPHTTPLIB_IDLE_INTERVAL_USECOND
#endif
#endif

#ifndef CPPHTTPLIB_REQUEST_URI_MAX_LENGTH
#define CPPHTTPLIB_REQUEST_URI_MAX_LENGTH
#endif

#ifndef CPPHTTPLIB_HEADER_MAX_LENGTH
#define CPPHTTPLIB_HEADER_MAX_LENGTH
#endif

#ifndef CPPHTTPLIB_REDIRECT_MAX_COUNT
#define CPPHTTPLIB_REDIRECT_MAX_COUNT
#endif

#ifndef CPPHTTPLIB_MULTIPART_FORM_DATA_FILE_MAX_COUNT
#define CPPHTTPLIB_MULTIPART_FORM_DATA_FILE_MAX_COUNT
#endif

#ifndef CPPHTTPLIB_PAYLOAD_MAX_LENGTH
#define CPPHTTPLIB_PAYLOAD_MAX_LENGTH
#endif

#ifndef CPPHTTPLIB_FORM_URL_ENCODED_PAYLOAD_MAX_LENGTH
#define CPPHTTPLIB_FORM_URL_ENCODED_PAYLOAD_MAX_LENGTH
#endif

#ifndef CPPHTTPLIB_RANGE_MAX_COUNT
#define CPPHTTPLIB_RANGE_MAX_COUNT
#endif

#ifndef CPPHTTPLIB_TCP_NODELAY
#define CPPHTTPLIB_TCP_NODELAY
#endif

#ifndef CPPHTTPLIB_RECV_BUFSIZ
#define CPPHTTPLIB_RECV_BUFSIZ
#endif

#ifndef CPPHTTPLIB_COMPRESSION_BUFSIZ
#define CPPHTTPLIB_COMPRESSION_BUFSIZ
#endif

#ifndef CPPHTTPLIB_THREAD_POOL_COUNT
#define CPPHTTPLIB_THREAD_POOL_COUNT
#endif

#ifndef CPPHTTPLIB_RECV_FLAGS
#define CPPHTTPLIB_RECV_FLAGS
#endif

#ifndef CPPHTTPLIB_SEND_FLAGS
#define CPPHTTPLIB_SEND_FLAGS
#endif

#ifndef CPPHTTPLIB_LISTEN_BACKLOG
#define CPPHTTPLIB_LISTEN_BACKLOG
#endif

#define CPPHTTPLIB_NO_EXCEPTIONS

/*
 * Headers
 */

#ifdef _WIN32
#ifndef _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#endif //_CRT_SECURE_NO_WARNINGS

#ifndef _CRT_NONSTDC_NO_DEPRECATE
#define _CRT_NONSTDC_NO_DEPRECATE
#endif //_CRT_NONSTDC_NO_DEPRECATE

#if defined(_MSC_VER)
#if _MSC_VER < 1900
#error Sorry, Visual Studio versions prior to 2015 are not supported
#endif

#pragma comment(lib, "ws2_32.lib")

#ifdef _WIN64
using ssize_t = __int64;
#else
using ssize_t = long;
#endif
#endif // _MSC_VER

#ifndef S_ISREG
#define S_ISREG
#endif // S_ISREG

#ifndef S_ISDIR
#define S_ISDIR
#endif // S_ISDIR

#ifndef NOMINMAX
#define NOMINMAX
#endif // NOMINMAX

#include <io.h>
#include <winsock2.h>
#include <ws2tcpip.h>

#ifndef WSA_FLAG_NO_HANDLE_INHERIT
#define WSA_FLAG_NO_HANDLE_INHERIT
#endif

using socket_t = SOCKET;
#ifdef CPPHTTPLIB_USE_POLL
#define poll
#endif

#else // not _WIN32

#include <arpa/inet.h>
#if !defined(_AIX) && !defined(__MVS__)
#include <ifaddrs.h>
#endif
#ifdef __MVS__
#include <strings.h>
#ifndef NI_MAXHOST
#define NI_MAXHOST
#endif
#endif
#include <net/if.h>
#include <netdb.h>
#include <netinet/in.h>
#ifdef __linux__
#include <resolv.h>
#endif
#include <netinet/tcp.h>
#ifdef CPPHTTPLIB_USE_POLL
#include <poll.h>
#endif
#include <csignal>
#include <pthread.h>
#include <sys/mman.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>

socket_t;
#ifndef INVALID_SOCKET
#define INVALID_SOCKET
#endif
#endif //_WIN32

#include <algorithm>
#include <array>
#include <atomic>
#include <cassert>
#include <cctype>
#include <climits>
#include <condition_variable>
#include <cstring>
#include <errno.h>
#include <exception>
#include <fcntl.h>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <memory>
#include <mutex>
#include <random>
#include <regex>
#include <set>
#include <sstream>
#include <string>
#include <sys/stat.h>
#include <thread>
#include <unordered_map>
#include <unordered_set>
#include <utility>

#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
#ifdef _WIN32
#include <wincrypt.h>

// these are defined in wincrypt.h and it breaks compilation if BoringSSL is
// used
#undef X509_NAME
#undef X509_CERT_PAIR
#undef X509_EXTENSIONS
#undef PKCS7_SIGNER_INFO

#ifdef _MSC_VER
#pragma comment(lib, "crypt32.lib")
#endif
#elif defined(CPPHTTPLIB_USE_CERTS_FROM_MACOSX_KEYCHAIN) && defined(__APPLE__)
#include <TargetConditionals.h>
#if TARGET_OS_OSX
#include <CoreFoundation/CoreFoundation.h>
#include <Security/Security.h>
#endif // TARGET_OS_OSX
#endif // _WIN32

#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/ssl.h>
#include <openssl/x509v3.h>

#if defined(_WIN32) && defined(OPENSSL_USE_APPLINK)
#include <openssl/applink.c>
#endif

#include <iostream>
#include <sstream>

#if defined(OPENSSL_IS_BORINGSSL)
#if OPENSSL_VERSION_NUMBER < 0x1010107f
#error Please use OpenSSL or a current version of BoringSSL
#endif
#define SSL_get1_peer_certificate
#elif OPENSSL_VERSION_NUMBER < 0x30000000L
#error Sorry, OpenSSL versions prior to 3.0.0 are not supported
#endif

#endif

#ifdef CPPHTTPLIB_ZLIB_SUPPORT
#include "third_party/zlib/zlib_crashpad.h"
#endif

#ifdef CPPHTTPLIB_BROTLI_SUPPORT
#include <brotli/decode.h>
#include <brotli/encode.h>
#endif

/*
 * Declaration
 */
namespace httplib {

namespace detail {

/*
 * Backport std::make_unique from C++14.
 *
 * NOTE: This code came up with the following stackoverflow post:
 * https://stackoverflow.com/questions/10149840/c-arrays-and-make-unique
 *
 */

template <class T, class... Args>
typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
make_unique(Args &&...args) {}

template <class T>
typename std::enable_if<std::is_array<T>::value, std::unique_ptr<T>>::type
make_unique(std::size_t n) {}

struct ci {};

// This is based on
// "http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4189".

struct scope_exit {};

} // namespace detail

enum StatusCode {};

Headers;

Params;
Match;

Progress;

struct Response;
ResponseHandler;

struct MultipartFormData {};
MultipartFormDataItems;
MultipartFormDataMap;

class DataSink {};

ContentProvider;

ContentProviderWithoutLength;

ContentProviderResourceReleaser;

struct MultipartFormDataProvider {};
MultipartFormDataProviderItems;

ContentReceiverWithProgress;

ContentReceiver;

MultipartContentHeader;

class ContentReader {};

Range;
Ranges;

struct Request {};

struct Response {};

class Stream {};

class TaskQueue {};

class ThreadPool final : public TaskQueue {};

Logger;

SocketOptions;

void default_socket_options(socket_t sock);

const char *status_message(int status);

std::string get_bearer_token_auth(const Request &req);

namespace detail {

class MatcherBase {};

/**
 * Captures parameters in request path and stores them in Request::path_params
 *
 * Capture name is a substring of a pattern from : to /.
 * The rest of the pattern is matched agains the request path directly
 * Parameters are captured starting from the next character after
 * the end of the last matched static pattern fragment until the next /.
 *
 * Example pattern:
 * "/path/fragments/:capture/more/fragments/:second_capture"
 * Static fragments:
 * "/path/fragments/", "more/fragments/"
 *
 * Given the following request path:
 * "/path/fragments/:1/more/fragments/:2"
 * the resulting capture will be
 * {{"capture", "1"}, {"second_capture", "2"}}
 */
class PathParamsMatcher final : public MatcherBase {};

/**
 * Performs std::regex_match on request path
 * and stores the result in Request::matches
 *
 * Note that regex match is performed directly on the whole request.
 * This means that wildcard patterns may match multiple path segments with /:
 * "/begin/(.*)/end" will match both "/begin/middle/end" and "/begin/1/2/end".
 */
class RegexMatcher final : public MatcherBase {};

ssize_t write_headers(Stream &strm, const Headers &headers);

} // namespace detail

class Server {};

enum class Error {};

std::string to_string(Error error);

std::ostream &operator<<(std::ostream &os, const Error &obj);

class Result {};

class ClientImpl {};

class Client {};

#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
class SSLServer : public Server {};

class SSLClient final : public ClientImpl {};
#endif

/*
 * Implementation of template methods.
 */

namespace detail {

template <typename T, typename U>
inline void duration_to_sec_and_usec(const T &duration, U callback) {}

inline uint64_t get_header_value_u64(const Headers &headers,
                                     const std::string &key, size_t id,
                                     uint64_t def) {}

} // namespace detail

inline uint64_t Request::get_header_value_u64(const std::string &key,
                                              size_t id) const {}

inline uint64_t Response::get_header_value_u64(const std::string &key,
                                               size_t id) const {}

template <typename... Args>
inline ssize_t Stream::write_format(const char *fmt, const Args &...args) {}

inline void default_socket_options(socket_t sock) {}

inline const char *status_message(int status) {}

inline std::string get_bearer_token_auth(const Request &req) {}

template <class Rep, class Period>
inline Server &
Server::set_read_timeout(const std::chrono::duration<Rep, Period> &duration) {}

template <class Rep, class Period>
inline Server &
Server::set_write_timeout(const std::chrono::duration<Rep, Period> &duration) {}

template <class Rep, class Period>
inline Server &
Server::set_idle_interval(const std::chrono::duration<Rep, Period> &duration) {}

inline std::string to_string(const Error error) {}

inline std::ostream &operator<<(std::ostream &os, const Error &obj) {}

inline uint64_t Result::get_request_header_value_u64(const std::string &key,
                                                     size_t id) const {}

template <class Rep, class Period>
inline void ClientImpl::set_connection_timeout(
    const std::chrono::duration<Rep, Period> &duration) {}

template <class Rep, class Period>
inline void ClientImpl::set_read_timeout(
    const std::chrono::duration<Rep, Period> &duration) {}

template <class Rep, class Period>
inline void ClientImpl::set_write_timeout(
    const std::chrono::duration<Rep, Period> &duration) {}

template <class Rep, class Period>
inline void Client::set_connection_timeout(
    const std::chrono::duration<Rep, Period> &duration) {}

template <class Rep, class Period>
inline void
Client::set_read_timeout(const std::chrono::duration<Rep, Period> &duration) {}

template <class Rep, class Period>
inline void
Client::set_write_timeout(const std::chrono::duration<Rep, Period> &duration) {}

/*
 * Forward declarations and types that will be part of the .h file if split into
 * .h + .cc.
 */

std::string hosted_at(const std::string &hostname);

void hosted_at(const std::string &hostname, std::vector<std::string> &addrs);

std::string append_query_params(const std::string &path, const Params &params);

std::pair<std::string, std::string> make_range_header(const Ranges &ranges);

std::pair<std::string, std::string>
make_basic_authentication_header(const std::string &username,
                                 const std::string &password,
                                 bool is_proxy = false);

namespace detail {

std::string encode_query_param(const std::string &value);

std::string decode_url(const std::string &s, bool convert_plus_to_space);

void read_file(const std::string &path, std::string &out);

std::string trim_copy(const std::string &s);

void divide(
    const char *data, std::size_t size, char d,
    std::function<void(const char *, std::size_t, const char *, std::size_t)>
        fn);

void divide(
    const std::string &str, char d,
    std::function<void(const char *, std::size_t, const char *, std::size_t)>
        fn);

void split(const char *b, const char *e, char d,
           std::function<void(const char *, const char *)> fn);

void split(const char *b, const char *e, char d, size_t m,
           std::function<void(const char *, const char *)> fn);

bool process_client_socket(socket_t sock, time_t read_timeout_sec,
                           time_t read_timeout_usec, time_t write_timeout_sec,
                           time_t write_timeout_usec,
                           std::function<bool(Stream &)> callback);

socket_t create_client_socket(
    const std::string &host, const std::string &ip, int port,
    int address_family, bool tcp_nodelay, SocketOptions socket_options,
    time_t connection_timeout_sec, time_t connection_timeout_usec,
    time_t read_timeout_sec, time_t read_timeout_usec, time_t write_timeout_sec,
    time_t write_timeout_usec, const std::string &intf, Error &error);

const char *get_header_value(const Headers &headers, const std::string &key,
                             size_t id = 0, const char *def = nullptr);

std::string params_to_query_str(const Params &params);

void parse_query_text(const char *data, std::size_t size, Params &params);

void parse_query_text(const std::string &s, Params &params);

bool parse_multipart_boundary(const std::string &content_type,
                              std::string &boundary);

bool parse_range_header(const std::string &s, Ranges &ranges);

int close_socket(socket_t sock);

ssize_t send_socket(socket_t sock, const void *ptr, size_t size, int flags);

ssize_t read_socket(socket_t sock, void *ptr, size_t size, int flags);

enum class EncodingType {};

EncodingType encoding_type(const Request &req, const Response &res);

class BufferStream final : public Stream {};

class compressor {};

class decompressor {};

class nocompressor final : public compressor {};

#ifdef CPPHTTPLIB_ZLIB_SUPPORT
class gzip_compressor final : public compressor {};

class gzip_decompressor final : public decompressor {};
#endif

#ifdef CPPHTTPLIB_BROTLI_SUPPORT
class brotli_compressor final : public compressor {
public:
  brotli_compressor();
  ~brotli_compressor();

  bool compress(const char *data, size_t data_length, bool last,
                Callback callback) override;

private:
  BrotliEncoderState *state_ = nullptr;
};

class brotli_decompressor final : public decompressor {
public:
  brotli_decompressor();
  ~brotli_decompressor();

  bool is_valid() const override;

  bool decompress(const char *data, size_t data_length,
                  Callback callback) override;

private:
  BrotliDecoderResult decoder_r;
  BrotliDecoderState *decoder_s = nullptr;
};
#endif

// NOTE: until the read size reaches `fixed_buffer_size`, use `fixed_buffer`
// to store data. The call can set memory on stack for performance.
class stream_line_reader {};

class mmap {};

} // namespace detail

// ----------------------------------------------------------------------------

/*
 * Implementation that will be part of the .cc file if split into .h + .cc.
 */

namespace detail {

inline bool is_hex(char c, int &v) {}

inline bool from_hex_to_i(const std::string &s, size_t i, size_t cnt,
                          int &val) {}

inline std::string from_i_to_hex(size_t n) {}

inline size_t to_utf8(int code, char *buff) {}

// NOTE: This code came up with the following stackoverflow post:
// https://stackoverflow.com/questions/180947/base64-decode-snippet-in-c
inline std::string base64_encode(const std::string &in) {}

inline bool is_file(const std::string &path) {}

inline bool is_dir(const std::string &path) {}

inline bool is_valid_path(const std::string &path) {}

inline std::string encode_query_param(const std::string &value) {}

inline std::string encode_url(const std::string &s) {}

inline std::string decode_url(const std::string &s,
                              bool convert_plus_to_space) {}

inline void read_file(const std::string &path, std::string &out) {}

inline std::string file_extension(const std::string &path) {}

inline bool is_space_or_tab(char c) {}

inline std::pair<size_t, size_t> trim(const char *b, const char *e, size_t left,
                                      size_t right) {}

inline std::string trim_copy(const std::string &s) {}

inline std::string trim_double_quotes_copy(const std::string &s) {}

inline void
divide(const char *data, std::size_t size, char d,
       std::function<void(const char *, std::size_t, const char *, std::size_t)>
           fn) {}

inline void
divide(const std::string &str, char d,
       std::function<void(const char *, std::size_t, const char *, std::size_t)>
           fn) {}

inline void split(const char *b, const char *e, char d,
                  std::function<void(const char *, const char *)> fn) {}

inline void split(const char *b, const char *e, char d, size_t m,
                  std::function<void(const char *, const char *)> fn) {}

inline stream_line_reader::stream_line_reader(Stream &strm, char *fixed_buffer,
                                              size_t fixed_buffer_size)
    :{}

inline const char *stream_line_reader::ptr() const {}

inline size_t stream_line_reader::size() const {}

inline bool stream_line_reader::end_with_crlf() const {}

inline bool stream_line_reader::getline() {}

inline void stream_line_reader::append(char c) {}

inline mmap::mmap(const char *path)
#if defined(_WIN32)
    :{}

inline mmap::~mmap() {}

inline bool mmap::open(const char *path) {}

inline bool mmap::is_open() const {}

inline size_t mmap::size() const {}

inline const char *mmap::data() const {}

inline void mmap::close() {}
inline int close_socket(socket_t sock) {}

template <typename T> inline ssize_t handle_EINTR(T fn) {}

inline ssize_t read_socket(socket_t sock, void *ptr, size_t size, int flags) {}

inline ssize_t send_socket(socket_t sock, const void *ptr, size_t size,
                           int flags) {}

inline ssize_t select_read(socket_t sock, time_t sec, time_t usec) {}

inline ssize_t select_write(socket_t sock, time_t sec, time_t usec) {}

inline Error wait_until_socket_is_ready(socket_t sock, time_t sec,
                                        time_t usec) {}

inline bool is_socket_alive(socket_t sock) {}

class SocketStream final : public Stream {};

#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
class SSLSocketStream final : public Stream {};
#endif

inline bool keep_alive(socket_t sock, time_t keep_alive_timeout_sec) {}

template <typename T>
inline bool
process_server_socket_core(const std::atomic<socket_t> &svr_sock, socket_t sock,
                           size_t keep_alive_max_count,
                           time_t keep_alive_timeout_sec, T callback) {}

template <typename T>
inline bool
process_server_socket(const std::atomic<socket_t> &svr_sock, socket_t sock,
                      size_t keep_alive_max_count,
                      time_t keep_alive_timeout_sec, time_t read_timeout_sec,
                      time_t read_timeout_usec, time_t write_timeout_sec,
                      time_t write_timeout_usec, T callback) {}

inline bool process_client_socket(socket_t sock, time_t read_timeout_sec,
                                  time_t read_timeout_usec,
                                  time_t write_timeout_sec,
                                  time_t write_timeout_usec,
                                  std::function<bool(Stream &)> callback) {}

inline int shutdown_socket(socket_t sock) {}

template <typename BindOrConnect>
socket_t create_socket(const std::string &host, const std::string &ip, int port,
                       int address_family, int socket_flags, bool tcp_nodelay,
                       SocketOptions socket_options,
                       BindOrConnect bind_or_connect) {}

inline void set_nonblocking(socket_t sock, bool nonblocking) {}

inline bool is_connection_error() {}

inline bool bind_ip_address(socket_t sock, const std::string &host) {}

#if !defined _WIN32 && !defined ANDROID && !defined _AIX && !defined __MVS__
#define USE_IF2IP
#endif

#ifdef USE_IF2IP
inline std::string if2ip(int address_family, const std::string &ifn) {}
#endif

inline socket_t create_client_socket(
    const std::string &host, const std::string &ip, int port,
    int address_family, bool tcp_nodelay, SocketOptions socket_options,
    time_t connection_timeout_sec, time_t connection_timeout_usec,
    time_t read_timeout_sec, time_t read_timeout_usec, time_t write_timeout_sec,
    time_t write_timeout_usec, const std::string &intf, Error &error) {}

inline bool get_ip_and_port(const struct sockaddr_storage &addr,
                            socklen_t addr_len, std::string &ip, int &port) {}

inline void get_local_ip_and_port(socket_t sock, std::string &ip, int &port) {}

inline void get_remote_ip_and_port(socket_t sock, std::string &ip, int &port) {}

inline constexpr unsigned int str2tag_core(const char *s, size_t l,
                                           unsigned int h) {}

inline unsigned int str2tag(const std::string &s) {}

namespace udl {

inline constexpr unsigned int operator"" _t(const char *s, size_t l) {}

} // namespace udl

inline std::string
find_content_type(const std::string &path,
                  const std::map<std::string, std::string> &user_data,
                  const std::string &default_content_type) {}

inline bool can_compress_content_type(const std::string &content_type) {}

inline EncodingType encoding_type(const Request &req, const Response &res) {}

inline bool nocompressor::compress(const char *data, size_t data_length,
                                   bool /*last*/, Callback callback) {}

#ifdef CPPHTTPLIB_ZLIB_SUPPORT
inline gzip_compressor::gzip_compressor() {}

inline gzip_compressor::~gzip_compressor() {}

inline bool gzip_compressor::compress(const char *data, size_t data_length,
                                      bool last, Callback callback) {}

inline gzip_decompressor::gzip_decompressor() {}

inline gzip_decompressor::~gzip_decompressor() {}

inline bool gzip_decompressor::is_valid() const {}

inline bool gzip_decompressor::decompress(const char *data, size_t data_length,
                                          Callback callback) {}
#endif

#ifdef CPPHTTPLIB_BROTLI_SUPPORT
inline brotli_compressor::brotli_compressor() {
  state_ = BrotliEncoderCreateInstance(nullptr, nullptr, nullptr);
}

inline brotli_compressor::~brotli_compressor() {
  BrotliEncoderDestroyInstance(state_);
}

inline bool brotli_compressor::compress(const char *data, size_t data_length,
                                        bool last, Callback callback) {
  std::array<uint8_t, CPPHTTPLIB_COMPRESSION_BUFSIZ> buff{};

  auto operation = last ? BROTLI_OPERATION_FINISH : BROTLI_OPERATION_PROCESS;
  auto available_in = data_length;
  auto next_in = reinterpret_cast<const uint8_t *>(data);

  for (;;) {
    if (last) {
      if (BrotliEncoderIsFinished(state_)) { break; }
    } else {
      if (!available_in) { break; }
    }

    auto available_out = buff.size();
    auto next_out = buff.data();

    if (!BrotliEncoderCompressStream(state_, operation, &available_in, &next_in,
                                     &available_out, &next_out, nullptr)) {
      return false;
    }

    auto output_bytes = buff.size() - available_out;
    if (output_bytes) {
      callback(reinterpret_cast<const char *>(buff.data()), output_bytes);
    }
  }

  return true;
}

inline brotli_decompressor::brotli_decompressor() {
  decoder_s = BrotliDecoderCreateInstance(0, 0, 0);
  decoder_r = decoder_s ? BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT
                        : BROTLI_DECODER_RESULT_ERROR;
}

inline brotli_decompressor::~brotli_decompressor() {
  if (decoder_s) { BrotliDecoderDestroyInstance(decoder_s); }
}

inline bool brotli_decompressor::is_valid() const { return decoder_s; }

inline bool brotli_decompressor::decompress(const char *data,
                                            size_t data_length,
                                            Callback callback) {
  if (decoder_r == BROTLI_DECODER_RESULT_SUCCESS ||
      decoder_r == BROTLI_DECODER_RESULT_ERROR) {
    return 0;
  }

  auto next_in = reinterpret_cast<const uint8_t *>(data);
  size_t avail_in = data_length;
  size_t total_out;

  decoder_r = BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT;

  std::array<char, CPPHTTPLIB_COMPRESSION_BUFSIZ> buff{};
  while (decoder_r == BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT) {
    char *next_out = buff.data();
    size_t avail_out = buff.size();

    decoder_r = BrotliDecoderDecompressStream(
        decoder_s, &avail_in, &next_in, &avail_out,
        reinterpret_cast<uint8_t **>(&next_out), &total_out);

    if (decoder_r == BROTLI_DECODER_RESULT_ERROR) { return false; }

    if (!callback(buff.data(), buff.size() - avail_out)) { return false; }
  }

  return decoder_r == BROTLI_DECODER_RESULT_SUCCESS ||
         decoder_r == BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT;
}
#endif

inline bool has_header(const Headers &headers, const std::string &key) {}

inline const char *get_header_value(const Headers &headers,
                                    const std::string &key, size_t id,
                                    const char *def) {}

inline bool compare_case_ignore(const std::string &a, const std::string &b) {}

template <typename T>
inline bool parse_header(const char *beg, const char *end, T fn) {}

inline bool read_headers(Stream &strm, Headers &headers) {}

inline bool read_content_with_length(Stream &strm, uint64_t len,
                                     Progress progress,
                                     ContentReceiverWithProgress out) {}

inline void skip_content_with_length(Stream &strm, uint64_t len) {}

inline bool read_content_without_length(Stream &strm,
                                        ContentReceiverWithProgress out) {}

template <typename T>
inline bool read_content_chunked(Stream &strm, T &x,
                                 ContentReceiverWithProgress out) {}

inline bool is_chunked_transfer_encoding(const Headers &headers) {}

template <typename T, typename U>
bool prepare_content_receiver(T &x, int &status,
                              ContentReceiverWithProgress receiver,
                              bool decompress, U callback) {}

template <typename T>
bool read_content(Stream &strm, T &x, size_t payload_max_length, int &status,
                  Progress progress, ContentReceiverWithProgress receiver,
                  bool decompress) {} // namespace detail

inline ssize_t write_headers(Stream &strm, const Headers &headers) {}

inline bool write_data(Stream &strm, const char *d, size_t l) {}

template <typename T>
inline bool write_content(Stream &strm, const ContentProvider &content_provider,
                          size_t offset, size_t length, T is_shutting_down,
                          Error &error) {}

template <typename T>
inline bool write_content(Stream &strm, const ContentProvider &content_provider,
                          size_t offset, size_t length,
                          const T &is_shutting_down) {}

template <typename T>
inline bool
write_content_without_length(Stream &strm,
                             const ContentProvider &content_provider,
                             const T &is_shutting_down) {}

template <typename T, typename U>
inline bool
write_content_chunked(Stream &strm, const ContentProvider &content_provider,
                      const T &is_shutting_down, U &compressor, Error &error) {}

template <typename T, typename U>
inline bool write_content_chunked(Stream &strm,
                                  const ContentProvider &content_provider,
                                  const T &is_shutting_down, U &compressor) {}

template <typename T>
inline bool redirect(T &cli, Request &req, Response &res,
                     const std::string &path, const std::string &location,
                     Error &error) {}

inline std::string params_to_query_str(const Params &params) {}

inline void parse_query_text(const char *data, std::size_t size,
                             Params &params) {}

inline void parse_query_text(const std::string &s, Params &params) {}

inline bool parse_multipart_boundary(const std::string &content_type,
                                     std::string &boundary) {}

inline void parse_disposition_params(const std::string &s, Params &params) {}

#ifdef CPPHTTPLIB_NO_EXCEPTIONS
inline bool parse_range_header(const std::string &s, Ranges &ranges) {}
#else
} catch (...) { return false; }
#endif

class MultipartFormDataParser {};

inline std::string to_lower(const char *beg, const char *end) {}

inline std::string random_string(size_t length) {}

inline std::string make_multipart_data_boundary() {}

inline bool is_multipart_boundary_chars_valid(const std::string &boundary) {}

template <typename T>
inline std::string
serialize_multipart_formdata_item_begin(const T &item,
                                        const std::string &boundary) {}

inline std::string serialize_multipart_formdata_item_end() {}

inline std::string
serialize_multipart_formdata_finish(const std::string &boundary) {}

inline std::string
serialize_multipart_formdata_get_content_type(const std::string &boundary) {}

inline std::string
serialize_multipart_formdata(const MultipartFormDataItems &items,
                             const std::string &boundary, bool finish = true) {}

inline bool range_error(Request &req, Response &res) {}

inline std::pair<size_t, size_t>
get_range_offset_and_length(Range r, size_t content_length) {}

inline std::string make_content_range_header_field(
    const std::pair<size_t, size_t> &offset_and_length, size_t content_length) {}

template <typename SToken, typename CToken, typename Content>
bool process_multipart_ranges_data(const Request &req,
                                   const std::string &boundary,
                                   const std::string &content_type,
                                   size_t content_length, SToken stoken,
                                   CToken ctoken, Content content) {}

inline void make_multipart_ranges_data(const Request &req, Response &res,
                                       const std::string &boundary,
                                       const std::string &content_type,
                                       size_t content_length,
                                       std::string &data) {}

inline size_t get_multipart_ranges_data_length(const Request &req,
                                               const std::string &boundary,
                                               const std::string &content_type,
                                               size_t content_length) {}

template <typename T>
inline bool
write_multipart_ranges_data(Stream &strm, const Request &req, Response &res,
                            const std::string &boundary,
                            const std::string &content_type,
                            size_t content_length, const T &is_shutting_down) {}

inline bool expect_content(const Request &req) {}

inline bool has_crlf(const std::string &s) {}

#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
inline std::string message_digest(const std::string &s, const EVP_MD *algo) {}

inline std::string MD5(const std::string &s) {}

inline std::string SHA_256(const std::string &s) {}

inline std::string SHA_512(const std::string &s) {}
#endif

#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
#ifdef _WIN32
// NOTE: This code came up with the following stackoverflow post:
// https://stackoverflow.com/questions/9507184/can-openssl-on-windows-use-the-system-certificate-store
inline bool load_system_certs_on_windows(X509_STORE *store) {
  auto hStore = CertOpenSystemStoreW((HCRYPTPROV_LEGACY)NULL, L"ROOT");
  if (!hStore) { return false; }

  auto result = false;
  PCCERT_CONTEXT pContext = NULL;
  while ((pContext = CertEnumCertificatesInStore(hStore, pContext)) !=
         nullptr) {
    auto encoded_cert =
        static_cast<const unsigned char *>(pContext->pbCertEncoded);

    auto x509 = d2i_X509(NULL, &encoded_cert, pContext->cbCertEncoded);
    if (x509) {
      X509_STORE_add_cert(store, x509);
      X509_free(x509);
      result = true;
    }
  }

  CertFreeCertificateContext(pContext);
  CertCloseStore(hStore, 0);

  return result;
}
#elif defined(CPPHTTPLIB_USE_CERTS_FROM_MACOSX_KEYCHAIN) && defined(__APPLE__)
#if TARGET_OS_OSX
template <typename T>
using CFObjectPtr =
    std::unique_ptr<typename std::remove_pointer<T>::type, void (*)(CFTypeRef)>;

inline void cf_object_ptr_deleter(CFTypeRef obj) {
  if (obj) { CFRelease(obj); }
}

inline bool retrieve_certs_from_keychain(CFObjectPtr<CFArrayRef> &certs) {
  CFStringRef keys[] = {kSecClass, kSecMatchLimit, kSecReturnRef};
  CFTypeRef values[] = {kSecClassCertificate, kSecMatchLimitAll,
                        kCFBooleanTrue};

  CFObjectPtr<CFDictionaryRef> query(
      CFDictionaryCreate(nullptr, reinterpret_cast<const void **>(keys), values,
                         sizeof(keys) / sizeof(keys[0]),
                         &kCFTypeDictionaryKeyCallBacks,
                         &kCFTypeDictionaryValueCallBacks),
      cf_object_ptr_deleter);

  if (!query) { return false; }

  CFTypeRef security_items = nullptr;
  if (SecItemCopyMatching(query.get(), &security_items) != errSecSuccess ||
      CFArrayGetTypeID() != CFGetTypeID(security_items)) {
    return false;
  }

  certs.reset(reinterpret_cast<CFArrayRef>(security_items));
  return true;
}

inline bool retrieve_root_certs_from_keychain(CFObjectPtr<CFArrayRef> &certs) {
  CFArrayRef root_security_items = nullptr;
  if (SecTrustCopyAnchorCertificates(&root_security_items) != errSecSuccess) {
    return false;
  }

  certs.reset(root_security_items);
  return true;
}

inline bool add_certs_to_x509_store(CFArrayRef certs, X509_STORE *store) {
  auto result = false;
  for (auto i = 0; i < CFArrayGetCount(certs); ++i) {
    const auto cert = reinterpret_cast<const __SecCertificate *>(
        CFArrayGetValueAtIndex(certs, i));

    if (SecCertificateGetTypeID() != CFGetTypeID(cert)) { continue; }

    CFDataRef cert_data = nullptr;
    if (SecItemExport(cert, kSecFormatX509Cert, 0, nullptr, &cert_data) !=
        errSecSuccess) {
      continue;
    }

    CFObjectPtr<CFDataRef> cert_data_ptr(cert_data, cf_object_ptr_deleter);

    auto encoded_cert = static_cast<const unsigned char *>(
        CFDataGetBytePtr(cert_data_ptr.get()));

    auto x509 =
        d2i_X509(NULL, &encoded_cert, CFDataGetLength(cert_data_ptr.get()));

    if (x509) {
      X509_STORE_add_cert(store, x509);
      X509_free(x509);
      result = true;
    }
  }

  return result;
}

inline bool load_system_certs_on_macos(X509_STORE *store) {
  auto result = false;
  CFObjectPtr<CFArrayRef> certs(nullptr, cf_object_ptr_deleter);
  if (retrieve_certs_from_keychain(certs) && certs) {
    result = add_certs_to_x509_store(certs.get(), store);
  }

  if (retrieve_root_certs_from_keychain(certs) && certs) {
    result = add_certs_to_x509_store(certs.get(), store) || result;
  }

  return result;
}
#endif // TARGET_OS_OSX
#endif // _WIN32
#endif // CPPHTTPLIB_OPENSSL_SUPPORT

#ifdef _WIN32
class WSInit {
public:
  WSInit() {
    WSADATA wsaData;
    if (WSAStartup(0x0002, &wsaData) == 0) is_valid_ = true;
  }

  ~WSInit() {
    if (is_valid_) WSACleanup();
  }

  bool is_valid_ = false;
};

static WSInit wsinit_;
#endif

#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
inline std::pair<std::string, std::string> make_digest_authentication_header(
    const Request &req, const std::map<std::string, std::string> &auth,
    size_t cnonce_count, const std::string &cnonce, const std::string &username,
    const std::string &password, bool is_proxy = false) {}
#endif

inline bool parse_www_authenticate(const Response &res,
                                   std::map<std::string, std::string> &auth,
                                   bool is_proxy) {}

class ContentProviderAdapter {};

} // namespace detail

inline std::string hosted_at(const std::string &hostname) {}

inline void hosted_at(const std::string &hostname,
                      std::vector<std::string> &addrs) {}

inline std::string append_query_params(const std::string &path,
                                       const Params &params) {}

// Header utilities
inline std::pair<std::string, std::string>
make_range_header(const Ranges &ranges) {}

inline std::pair<std::string, std::string>
make_basic_authentication_header(const std::string &username,
                                 const std::string &password, bool is_proxy) {}

inline std::pair<std::string, std::string>
make_bearer_token_authentication_header(const std::string &token,
                                        bool is_proxy = false) {}

// Request implementation
inline bool Request::has_header(const std::string &key) const {}

inline std::string Request::get_header_value(const std::string &key,
                                             size_t id) const {}

inline size_t Request::get_header_value_count(const std::string &key) const {}

inline void Request::set_header(const std::string &key,
                                const std::string &val) {}

inline bool Request::has_param(const std::string &key) const {}

inline std::string Request::get_param_value(const std::string &key,
                                            size_t id) const {}

inline size_t Request::get_param_value_count(const std::string &key) const {}

inline bool Request::is_multipart_form_data() const {}

inline bool Request::has_file(const std::string &key) const {}

inline MultipartFormData Request::get_file_value(const std::string &key) const {}

inline std::vector<MultipartFormData>
Request::get_file_values(const std::string &key) const {}

// Response implementation
inline bool Response::has_header(const std::string &key) const {}

inline std::string Response::get_header_value(const std::string &key,
                                              size_t id) const {}

inline size_t Response::get_header_value_count(const std::string &key) const {}

inline void Response::set_header(const std::string &key,
                                 const std::string &val) {}

inline void Response::set_redirect(const std::string &url, int stat) {}

inline void Response::set_content(const char *s, size_t n,
                                  const std::string &content_type) {}

inline void Response::set_content(const std::string &s,
                                  const std::string &content_type) {}

inline void Response::set_content(std::string &&s,
                                  const std::string &content_type) {}

inline void Response::set_content_provider(
    size_t in_length, const std::string &content_type, ContentProvider provider,
    ContentProviderResourceReleaser resource_releaser) {}

inline void Response::set_content_provider(
    const std::string &content_type, ContentProviderWithoutLength provider,
    ContentProviderResourceReleaser resource_releaser) {}

inline void Response::set_chunked_content_provider(
    const std::string &content_type, ContentProviderWithoutLength provider,
    ContentProviderResourceReleaser resource_releaser) {}

// Result implementation
inline bool Result::has_request_header(const std::string &key) const {}

inline std::string Result::get_request_header_value(const std::string &key,
                                                    size_t id) const {}

inline size_t
Result::get_request_header_value_count(const std::string &key) const {}

// Stream implementation
inline ssize_t Stream::write(const char *ptr) {}

inline ssize_t Stream::write(const std::string &s) {}

namespace detail {

// Socket stream implementation
inline SocketStream::SocketStream(socket_t sock, time_t read_timeout_sec,
                                  time_t read_timeout_usec,
                                  time_t write_timeout_sec,
                                  time_t write_timeout_usec)
    :{}

inline SocketStream::~SocketStream() = default;

inline bool SocketStream::is_readable() const {}

inline bool SocketStream::is_writable() const {}

inline ssize_t SocketStream::read(char *ptr, size_t size) {}

inline ssize_t SocketStream::write(const char *ptr, size_t size) {}

inline void SocketStream::get_remote_ip_and_port(std::string &ip,
                                                 int &port) const {}

inline void SocketStream::get_local_ip_and_port(std::string &ip,
                                                int &port) const {}

inline socket_t SocketStream::socket() const {}

// Buffer stream implementation
inline bool BufferStream::is_readable() const {}

inline bool BufferStream::is_writable() const {}

inline ssize_t BufferStream::read(char *ptr, size_t size) {}

inline ssize_t BufferStream::write(const char *ptr, size_t size) {}

inline void BufferStream::get_remote_ip_and_port(std::string & /*ip*/,
                                                 int & /*port*/) const {}

inline void BufferStream::get_local_ip_and_port(std::string & /*ip*/,
                                                int & /*port*/) const {}

inline socket_t BufferStream::socket() const {}

inline const std::string &BufferStream::get_buffer() const {}

inline PathParamsMatcher::PathParamsMatcher(const std::string &pattern) {}

inline bool PathParamsMatcher::match(Request &request) const {}

inline bool RegexMatcher::match(Request &request) const {}

} // namespace detail

// HTTP server implementation
inline Server::Server()
    :{}

inline Server::~Server() = default;

inline std::unique_ptr<detail::MatcherBase>
Server::make_matcher(const std::string &pattern) {}

inline Server &Server::Get(const std::string &pattern, Handler handler) {}

inline Server &Server::Post(const std::string &pattern, Handler handler) {}

inline Server &Server::Post(const std::string &pattern,
                            HandlerWithContentReader handler) {}

inline Server &Server::Put(const std::string &pattern, Handler handler) {}

inline Server &Server::Put(const std::string &pattern,
                           HandlerWithContentReader handler) {}

inline Server &Server::Patch(const std::string &pattern, Handler handler) {}

inline Server &Server::Patch(const std::string &pattern,
                             HandlerWithContentReader handler) {}

inline Server &Server::Delete(const std::string &pattern, Handler handler) {}

inline Server &Server::Delete(const std::string &pattern,
                              HandlerWithContentReader handler) {}

inline Server &Server::Options(const std::string &pattern, Handler handler) {}

inline bool Server::set_base_dir(const std::string &dir,
                                 const std::string &mount_point) {}

inline bool Server::set_mount_point(const std::string &mount_point,
                                    const std::string &dir, Headers headers) {}

inline bool Server::remove_mount_point(const std::string &mount_point) {}

inline Server &
Server::set_file_extension_and_mimetype_mapping(const std::string &ext,
                                                const std::string &mime) {}

inline Server &Server::set_default_file_mimetype(const std::string &mime) {}

inline Server &Server::set_file_request_handler(Handler handler) {}

inline Server &Server::set_error_handler_core(HandlerWithResponse handler,
                                              std::true_type) {}

inline Server &Server::set_error_handler_core(Handler handler,
                                              std::false_type) {}

inline Server &Server::set_exception_handler(ExceptionHandler handler) {}

inline Server &Server::set_pre_routing_handler(HandlerWithResponse handler) {}

inline Server &Server::set_post_routing_handler(Handler handler) {}

inline Server &Server::set_logger(Logger logger) {}

inline Server &
Server::set_expect_100_continue_handler(Expect100ContinueHandler handler) {}

inline Server &Server::set_address_family(int family) {}

inline Server &Server::set_tcp_nodelay(bool on) {}

inline Server &Server::set_socket_options(SocketOptions socket_options) {}

inline Server &Server::set_default_headers(Headers headers) {}

inline Server &Server::set_header_writer(
    std::function<ssize_t(Stream &, Headers &)> const &writer) {}

inline Server &Server::set_keep_alive_max_count(size_t count) {}

inline Server &Server::set_keep_alive_timeout(time_t sec) {}

inline Server &Server::set_read_timeout(time_t sec, time_t usec) {}

inline Server &Server::set_write_timeout(time_t sec, time_t usec) {}

inline Server &Server::set_idle_interval(time_t sec, time_t usec) {}

inline Server &Server::set_payload_max_length(size_t length) {}

inline bool Server::bind_to_port(const std::string &host, int port,
                                 int socket_flags) {}
inline int Server::bind_to_any_port(const std::string &host, int socket_flags) {}

inline bool Server::listen_after_bind() {}

inline bool Server::listen(const std::string &host, int port,
                           int socket_flags) {}

inline bool Server::is_running() const {}

inline void Server::wait_until_ready() const {}

inline void Server::stop() {}

inline bool Server::parse_request_line(const char *s, Request &req) const {}

inline bool Server::write_response(Stream &strm, bool close_connection,
                                   Request &req, Response &res) {}

inline bool Server::write_response_with_content(Stream &strm,
                                                bool close_connection,
                                                const Request &req,
                                                Response &res) {}

inline bool Server::write_response_core(Stream &strm, bool close_connection,
                                        const Request &req, Response &res,
                                        bool need_apply_ranges) {}

inline bool
Server::write_content_with_provider(Stream &strm, const Request &req,
                                    Response &res, const std::string &boundary,
                                    const std::string &content_type) {}

inline bool Server::read_content(Stream &strm, Request &req, Response &res) {}

inline bool Server::read_content_with_content_receiver(
    Stream &strm, Request &req, Response &res, ContentReceiver receiver,
    MultipartContentHeader multipart_header,
    ContentReceiver multipart_receiver) {}

inline bool
Server::read_content_core(Stream &strm, Request &req, Response &res,
                          ContentReceiver receiver,
                          MultipartContentHeader multipart_header,
                          ContentReceiver multipart_receiver) const {}

inline bool Server::handle_file_request(const Request &req, Response &res,
                                        bool head) {}

inline socket_t
Server::create_server_socket(const std::string &host, int port,
                             int socket_flags,
                             SocketOptions socket_options) const {}

inline int Server::bind_internal(const std::string &host, int port,
                                 int socket_flags) {}

inline bool Server::listen_internal() {}

inline bool Server::routing(Request &req, Response &res, Stream &strm) {}

inline bool Server::dispatch_request(Request &req, Response &res,
                                     const Handlers &handlers) const {}

inline void Server::apply_ranges(const Request &req, Response &res,
                                 std::string &content_type,
                                 std::string &boundary) const {}

inline bool Server::dispatch_request_for_content_reader(
    Request &req, Response &res, ContentReader content_reader,
    const HandlersForContentReader &handlers) const {}

inline bool
Server::process_request(Stream &strm, bool close_connection,
                        bool &connection_closed,
                        const std::function<void(Request &)> &setup_request) {}

inline bool Server::is_valid() const {}

inline bool Server::process_and_close_socket(socket_t sock) {}

// HTTP client implementation
inline ClientImpl::ClientImpl(const std::string &host)
    :{}

inline ClientImpl::ClientImpl(const std::string &host, int port)
    :{}

inline ClientImpl::ClientImpl(const std::string &host, int port,
                              const std::string &client_cert_path,
                              const std::string &client_key_path)
    :{}

inline ClientImpl::~ClientImpl() {}

inline bool ClientImpl::is_valid() const {}

inline void ClientImpl::copy_settings(const ClientImpl &rhs) {}

inline socket_t ClientImpl::create_client_socket(Error &error) const {}

inline bool ClientImpl::create_and_connect_socket(Socket &socket,
                                                  Error &error) {}

inline void ClientImpl::shutdown_ssl(Socket & /*socket*/,
                                     bool /*shutdown_gracefully*/) {}

inline void ClientImpl::shutdown_socket(Socket &socket) const {}

inline void ClientImpl::close_socket(Socket &socket) {}

inline bool ClientImpl::read_response_line(Stream &strm, const Request &req,
                                           Response &res) const {}

inline bool ClientImpl::send(Request &req, Response &res, Error &error) {}

inline bool ClientImpl::send_(Request &req, Response &res, Error &error) {}

inline Result ClientImpl::send(const Request &req) {}

inline Result ClientImpl::send_(Request &&req) {}

inline bool ClientImpl::handle_request(Stream &strm, Request &req,
                                       Response &res, bool close_connection,
                                       Error &error) {}

inline bool ClientImpl::redirect(Request &req, Response &res, Error &error) {}

inline bool ClientImpl::write_content_with_provider(Stream &strm,
                                                    const Request &req,
                                                    Error &error) const {}

inline bool ClientImpl::write_request(Stream &strm, Request &req,
                                      bool close_connection, Error &error) {}

inline std::unique_ptr<Response> ClientImpl::send_with_content_provider(
    Request &req, const char *body, size_t content_length,
    ContentProvider content_provider,
    ContentProviderWithoutLength content_provider_without_length,
    const std::string &content_type, Error &error) {}

inline Result ClientImpl::send_with_content_provider(
    const std::string &method, const std::string &path, const Headers &headers,
    const char *body, size_t content_length, ContentProvider content_provider,
    ContentProviderWithoutLength content_provider_without_length,
    const std::string &content_type, Progress progress) {}

inline std::string
ClientImpl::adjust_host_string(const std::string &host) const {}

inline bool ClientImpl::process_request(Stream &strm, Request &req,
                                        Response &res, bool close_connection,
                                        Error &error) {}

inline ContentProviderWithoutLength ClientImpl::get_multipart_content_provider(
    const std::string &boundary, const MultipartFormDataItems &items,
    const MultipartFormDataProviderItems &provider_items) const {}

inline bool
ClientImpl::process_socket(const Socket &socket,
                           std::function<bool(Stream &strm)> callback) {}

inline bool ClientImpl::is_ssl() const {}

inline Result ClientImpl::Get(const std::string &path) {}

inline Result ClientImpl::Get(const std::string &path, Progress progress) {}

inline Result ClientImpl::Get(const std::string &path, const Headers &headers) {}

inline Result ClientImpl::Get(const std::string &path, const Headers &headers,
                              Progress progress) {}

inline Result ClientImpl::Get(const std::string &path,
                              ContentReceiver content_receiver) {}

inline Result ClientImpl::Get(const std::string &path,
                              ContentReceiver content_receiver,
                              Progress progress) {}

inline Result ClientImpl::Get(const std::string &path, const Headers &headers,
                              ContentReceiver content_receiver) {}

inline Result ClientImpl::Get(const std::string &path, const Headers &headers,
                              ContentReceiver content_receiver,
                              Progress progress) {}

inline Result ClientImpl::Get(const std::string &path,
                              ResponseHandler response_handler,
                              ContentReceiver content_receiver) {}

inline Result ClientImpl::Get(const std::string &path, const Headers &headers,
                              ResponseHandler response_handler,
                              ContentReceiver content_receiver) {}

inline Result ClientImpl::Get(const std::string &path,
                              ResponseHandler response_handler,
                              ContentReceiver content_receiver,
                              Progress progress) {}

inline Result ClientImpl::Get(const std::string &path, const Headers &headers,
                              ResponseHandler response_handler,
                              ContentReceiver content_receiver,
                              Progress progress) {}

inline Result ClientImpl::Get(const std::string &path, const Params &params,
                              const Headers &headers, Progress progress) {}

inline Result ClientImpl::Get(const std::string &path, const Params &params,
                              const Headers &headers,
                              ContentReceiver content_receiver,
                              Progress progress) {}

inline Result ClientImpl::Get(const std::string &path, const Params &params,
                              const Headers &headers,
                              ResponseHandler response_handler,
                              ContentReceiver content_receiver,
                              Progress progress) {}

inline Result ClientImpl::Head(const std::string &path) {}

inline Result ClientImpl::Head(const std::string &path,
                               const Headers &headers) {}

inline Result ClientImpl::Post(const std::string &path) {}

inline Result ClientImpl::Post(const std::string &path,
                               const Headers &headers) {}

inline Result ClientImpl::Post(const std::string &path, const char *body,
                               size_t content_length,
                               const std::string &content_type) {}

inline Result ClientImpl::Post(const std::string &path, const Headers &headers,
                               const char *body, size_t content_length,
                               const std::string &content_type) {}

inline Result ClientImpl::Post(const std::string &path, const Headers &headers,
                               const char *body, size_t content_length,
                               const std::string &content_type,
                               Progress progress) {}

inline Result ClientImpl::Post(const std::string &path, const std::string &body,
                               const std::string &content_type) {}

inline Result ClientImpl::Post(const std::string &path, const std::string &body,
                               const std::string &content_type,
                               Progress progress) {}

inline Result ClientImpl::Post(const std::string &path, const Headers &headers,
                               const std::string &body,
                               const std::string &content_type) {}

inline Result ClientImpl::Post(const std::string &path, const Headers &headers,
                               const std::string &body,
                               const std::string &content_type,
                               Progress progress) {}

inline Result ClientImpl::Post(const std::string &path, const Params &params) {}

inline Result ClientImpl::Post(const std::string &path, size_t content_length,
                               ContentProvider content_provider,
                               const std::string &content_type) {}

inline Result ClientImpl::Post(const std::string &path,
                               ContentProviderWithoutLength content_provider,
                               const std::string &content_type) {}

inline Result ClientImpl::Post(const std::string &path, const Headers &headers,
                               size_t content_length,
                               ContentProvider content_provider,
                               const std::string &content_type) {}

inline Result ClientImpl::Post(const std::string &path, const Headers &headers,
                               ContentProviderWithoutLength content_provider,
                               const std::string &content_type) {}

inline Result ClientImpl::Post(const std::string &path, const Headers &headers,
                               const Params &params) {}

inline Result ClientImpl::Post(const std::string &path, const Headers &headers,
                               const Params &params, Progress progress) {}

inline Result ClientImpl::Post(const std::string &path,
                               const MultipartFormDataItems &items) {}

inline Result ClientImpl::Post(const std::string &path, const Headers &headers,
                               const MultipartFormDataItems &items) {}

inline Result ClientImpl::Post(const std::string &path, const Headers &headers,
                               const MultipartFormDataItems &items,
                               const std::string &boundary) {}

inline Result
ClientImpl::Post(const std::string &path, const Headers &headers,
                 const MultipartFormDataItems &items,
                 const MultipartFormDataProviderItems &provider_items) {}

inline Result ClientImpl::Put(const std::string &path) {}

inline Result ClientImpl::Put(const std::string &path, const char *body,
                              size_t content_length,
                              const std::string &content_type) {}

inline Result ClientImpl::Put(const std::string &path, const Headers &headers,
                              const char *body, size_t content_length,
                              const std::string &content_type) {}

inline Result ClientImpl::Put(const std::string &path, const Headers &headers,
                              const char *body, size_t content_length,
                              const std::string &content_type,
                              Progress progress) {}

inline Result ClientImpl::Put(const std::string &path, const std::string &body,
                              const std::string &content_type) {}

inline Result ClientImpl::Put(const std::string &path, const std::string &body,
                              const std::string &content_type,
                              Progress progress) {}

inline Result ClientImpl::Put(const std::string &path, const Headers &headers,
                              const std::string &body,
                              const std::string &content_type) {}

inline Result ClientImpl::Put(const std::string &path, const Headers &headers,
                              const std::string &body,
                              const std::string &content_type,
                              Progress progress) {}

inline Result ClientImpl::Put(const std::string &path, size_t content_length,
                              ContentProvider content_provider,
                              const std::string &content_type) {}

inline Result ClientImpl::Put(const std::string &path,
                              ContentProviderWithoutLength content_provider,
                              const std::string &content_type) {}

inline Result ClientImpl::Put(const std::string &path, const Headers &headers,
                              size_t content_length,
                              ContentProvider content_provider,
                              const std::string &content_type) {}

inline Result ClientImpl::Put(const std::string &path, const Headers &headers,
                              ContentProviderWithoutLength content_provider,
                              const std::string &content_type) {}

inline Result ClientImpl::Put(const std::string &path, const Params &params) {}

inline Result ClientImpl::Put(const std::string &path, const Headers &headers,
                              const Params &params) {}

inline Result ClientImpl::Put(const std::string &path, const Headers &headers,
                              const Params &params, Progress progress) {}

inline Result ClientImpl::Put(const std::string &path,
                              const MultipartFormDataItems &items) {}

inline Result ClientImpl::Put(const std::string &path, const Headers &headers,
                              const MultipartFormDataItems &items) {}

inline Result ClientImpl::Put(const std::string &path, const Headers &headers,
                              const MultipartFormDataItems &items,
                              const std::string &boundary) {}

inline Result
ClientImpl::Put(const std::string &path, const Headers &headers,
                const MultipartFormDataItems &items,
                const MultipartFormDataProviderItems &provider_items) {}
inline Result ClientImpl::Patch(const std::string &path) {}

inline Result ClientImpl::Patch(const std::string &path, const char *body,
                                size_t content_length,
                                const std::string &content_type) {}

inline Result ClientImpl::Patch(const std::string &path, const char *body,
                                size_t content_length,
                                const std::string &content_type,
                                Progress progress) {}

inline Result ClientImpl::Patch(const std::string &path, const Headers &headers,
                                const char *body, size_t content_length,
                                const std::string &content_type) {}

inline Result ClientImpl::Patch(const std::string &path, const Headers &headers,
                                const char *body, size_t content_length,
                                const std::string &content_type,
                                Progress progress) {}

inline Result ClientImpl::Patch(const std::string &path,
                                const std::string &body,
                                const std::string &content_type) {}

inline Result ClientImpl::Patch(const std::string &path,
                                const std::string &body,
                                const std::string &content_type,
                                Progress progress) {}

inline Result ClientImpl::Patch(const std::string &path, const Headers &headers,
                                const std::string &body,
                                const std::string &content_type) {}

inline Result ClientImpl::Patch(const std::string &path, const Headers &headers,
                                const std::string &body,
                                const std::string &content_type,
                                Progress progress) {}

inline Result ClientImpl::Patch(const std::string &path, size_t content_length,
                                ContentProvider content_provider,
                                const std::string &content_type) {}

inline Result ClientImpl::Patch(const std::string &path,
                                ContentProviderWithoutLength content_provider,
                                const std::string &content_type) {}

inline Result ClientImpl::Patch(const std::string &path, const Headers &headers,
                                size_t content_length,
                                ContentProvider content_provider,
                                const std::string &content_type) {}

inline Result ClientImpl::Patch(const std::string &path, const Headers &headers,
                                ContentProviderWithoutLength content_provider,
                                const std::string &content_type) {}

inline Result ClientImpl::Delete(const std::string &path) {}

inline Result ClientImpl::Delete(const std::string &path,
                                 const Headers &headers) {}

inline Result ClientImpl::Delete(const std::string &path, const char *body,
                                 size_t content_length,
                                 const std::string &content_type) {}

inline Result ClientImpl::Delete(const std::string &path, const char *body,
                                 size_t content_length,
                                 const std::string &content_type,
                                 Progress progress) {}

inline Result ClientImpl::Delete(const std::string &path,
                                 const Headers &headers, const char *body,
                                 size_t content_length,
                                 const std::string &content_type) {}

inline Result ClientImpl::Delete(const std::string &path,
                                 const Headers &headers, const char *body,
                                 size_t content_length,
                                 const std::string &content_type,
                                 Progress progress) {}

inline Result ClientImpl::Delete(const std::string &path,
                                 const std::string &body,
                                 const std::string &content_type) {}

inline Result ClientImpl::Delete(const std::string &path,
                                 const std::string &body,
                                 const std::string &content_type,
                                 Progress progress) {}

inline Result ClientImpl::Delete(const std::string &path,
                                 const Headers &headers,
                                 const std::string &body,
                                 const std::string &content_type) {}

inline Result ClientImpl::Delete(const std::string &path,
                                 const Headers &headers,
                                 const std::string &body,
                                 const std::string &content_type,
                                 Progress progress) {}

inline Result ClientImpl::Options(const std::string &path) {}

inline Result ClientImpl::Options(const std::string &path,
                                  const Headers &headers) {}

inline void ClientImpl::stop() {}

inline std::string ClientImpl::host() const {}

inline int ClientImpl::port() const {}

inline size_t ClientImpl::is_socket_open() const {}

inline socket_t ClientImpl::socket() const {}

inline void ClientImpl::set_connection_timeout(time_t sec, time_t usec) {}

inline void ClientImpl::set_read_timeout(time_t sec, time_t usec) {}

inline void ClientImpl::set_write_timeout(time_t sec, time_t usec) {}

inline void ClientImpl::set_basic_auth(const std::string &username,
                                       const std::string &password) {}

inline void ClientImpl::set_bearer_token_auth(const std::string &token) {}

#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
inline void ClientImpl::set_digest_auth(const std::string &username,
                                        const std::string &password) {}
#endif

inline void ClientImpl::set_keep_alive(bool on) {}

inline void ClientImpl::set_follow_location(bool on) {}

inline void ClientImpl::set_url_encode(bool on) {}

inline void
ClientImpl::set_hostname_addr_map(std::map<std::string, std::string> addr_map) {}

inline void ClientImpl::set_default_headers(Headers headers) {}

inline void ClientImpl::set_header_writer(
    std::function<ssize_t(Stream &, Headers &)> const &writer) {}

inline void ClientImpl::set_address_family(int family) {}

inline void ClientImpl::set_tcp_nodelay(bool on) {}

inline void ClientImpl::set_socket_options(SocketOptions socket_options) {}

inline void ClientImpl::set_compress(bool on) {}

inline void ClientImpl::set_decompress(bool on) {}

inline void ClientImpl::set_interface(const std::string &intf) {}

inline void ClientImpl::set_proxy(const std::string &host, int port) {}

inline void ClientImpl::set_proxy_basic_auth(const std::string &username,
                                             const std::string &password) {}

inline void ClientImpl::set_proxy_bearer_token_auth(const std::string &token) {}

#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
inline void ClientImpl::set_proxy_digest_auth(const std::string &username,
                                              const std::string &password) {}

inline void ClientImpl::set_ca_cert_path(const std::string &ca_cert_file_path,
                                         const std::string &ca_cert_dir_path) {}

inline void ClientImpl::set_ca_cert_store(X509_STORE *ca_cert_store) {}

inline X509_STORE *ClientImpl::create_ca_cert_store(const char *ca_cert,
                                                    std::size_t size) const {}

inline void ClientImpl::enable_server_certificate_verification(bool enabled) {}
#endif

inline void ClientImpl::set_logger(Logger logger) {}

/*
 * SSL Implementation
 */
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
namespace detail {

template <typename U, typename V>
inline SSL *ssl_new(socket_t sock, SSL_CTX *ctx, std::mutex &ctx_mutex,
                    U SSL_connect_or_accept, V setup) {}

inline void ssl_delete(std::mutex &ctx_mutex, SSL *ssl, socket_t sock,
                       bool shutdown_gracefully) {}

template <typename U>
bool ssl_connect_or_accept_nonblocking(socket_t sock, SSL *ssl,
                                       U ssl_connect_or_accept,
                                       time_t timeout_sec,
                                       time_t timeout_usec) {}

template <typename T>
inline bool process_server_socket_ssl(
    const std::atomic<socket_t> &svr_sock, SSL *ssl, socket_t sock,
    size_t keep_alive_max_count, time_t keep_alive_timeout_sec,
    time_t read_timeout_sec, time_t read_timeout_usec, time_t write_timeout_sec,
    time_t write_timeout_usec, T callback) {}

template <typename T>
inline bool
process_client_socket_ssl(SSL *ssl, socket_t sock, time_t read_timeout_sec,
                          time_t read_timeout_usec, time_t write_timeout_sec,
                          time_t write_timeout_usec, T callback) {}

class SSLInit {};

// SSL socket stream implementation
inline SSLSocketStream::SSLSocketStream(socket_t sock, SSL *ssl,
                                        time_t read_timeout_sec,
                                        time_t read_timeout_usec,
                                        time_t write_timeout_sec,
                                        time_t write_timeout_usec)
    :{}

inline SSLSocketStream::~SSLSocketStream() = default;

inline bool SSLSocketStream::is_readable() const {}

inline bool SSLSocketStream::is_writable() const {}

inline ssize_t SSLSocketStream::read(char *ptr, size_t size) {}

inline ssize_t SSLSocketStream::write(const char *ptr, size_t size) {}

inline void SSLSocketStream::get_remote_ip_and_port(std::string &ip,
                                                    int &port) const {}

inline void SSLSocketStream::get_local_ip_and_port(std::string &ip,
                                                   int &port) const {}

inline socket_t SSLSocketStream::socket() const {}

static SSLInit sslinit_;

} // namespace detail

// SSL HTTP server implementation
inline SSLServer::SSLServer(const char *cert_path, const char *private_key_path,
                            const char *client_ca_cert_file_path,
                            const char *client_ca_cert_dir_path,
                            const char *private_key_password) {}

inline SSLServer::SSLServer(X509 *cert, EVP_PKEY *private_key,
                            X509_STORE *client_ca_cert_store) {}

inline SSLServer::SSLServer(
    const std::function<bool(SSL_CTX &ssl_ctx)> &setup_ssl_ctx_callback) {}

inline SSLServer::~SSLServer() {}

inline bool SSLServer::is_valid() const {}

inline SSL_CTX *SSLServer::ssl_context() const {}

inline void SSLServer::update_certs(X509 *cert, EVP_PKEY *private_key,
                                    X509_STORE *client_ca_cert_store) {}

inline bool SSLServer::process_and_close_socket(socket_t sock) {}

// SSL HTTP client implementation
inline SSLClient::SSLClient(const std::string &host)
    :{}

inline SSLClient::SSLClient(const std::string &host, int port)
    :{}

inline SSLClient::SSLClient(const std::string &host, int port,
                            const std::string &client_cert_path,
                            const std::string &client_key_path,
                            const std::string &private_key_password)
    :{}

inline SSLClient::SSLClient(const std::string &host, int port,
                            X509 *client_cert, EVP_PKEY *client_key,
                            const std::string &private_key_password)
    :{}

inline SSLClient::~SSLClient() {}

inline bool SSLClient::is_valid() const {}

inline void SSLClient::set_ca_cert_store(X509_STORE *ca_cert_store) {}

inline void SSLClient::load_ca_cert_store(const char *ca_cert,
                                          std::size_t size) {}

inline long SSLClient::get_openssl_verify_result() const {}

inline SSL_CTX *SSLClient::ssl_context() const {}

inline bool SSLClient::create_and_connect_socket(Socket &socket, Error &error) {}

// Assumes that socket_mutex_ is locked and that there are no requests in flight
inline bool SSLClient::connect_with_proxy(Socket &socket, Response &res,
                                          bool &success, Error &error) {}

inline bool SSLClient::load_certs() {}

inline bool SSLClient::initialize_ssl(Socket &socket, Error &error) {}

inline void SSLClient::shutdown_ssl(Socket &socket, bool shutdown_gracefully) {}

inline void SSLClient::shutdown_ssl_impl(Socket &socket,
                                         bool shutdown_gracefully) {}

inline bool
SSLClient::process_socket(const Socket &socket,
                          std::function<bool(Stream &strm)> callback) {}

inline bool SSLClient::is_ssl() const {}

inline bool SSLClient::verify_host(X509 *server_cert) const {}

inline bool
SSLClient::verify_host_with_subject_alt_name(X509 *server_cert) const {}

inline bool SSLClient::verify_host_with_common_name(X509 *server_cert) const {}

inline bool SSLClient::check_host_name(const char *pattern,
                                       size_t pattern_len) const {}
#endif

// Universal client implementation
inline Client::Client(const std::string &scheme_host_port)
    :{}

inline Client::Client(const std::string &scheme_host_port,
                      const std::string &client_cert_path,
                      const std::string &client_key_path) {} // namespace detail

inline Client::Client(const std::string &host, int port)
    :{}

inline Client::Client(const std::string &host, int port,
                      const std::string &client_cert_path,
                      const std::string &client_key_path)
    :{}

inline Client::~Client() = default;

inline bool Client::is_valid() const {}

inline Result Client::Get(const std::string &path) {}
inline Result Client::Get(const std::string &path, const Headers &headers) {}
inline Result Client::Get(const std::string &path, Progress progress) {}
inline Result Client::Get(const std::string &path, const Headers &headers,
                          Progress progress) {}
inline Result Client::Get(const std::string &path,
                          ContentReceiver content_receiver) {}
inline Result Client::Get(const std::string &path, const Headers &headers,
                          ContentReceiver content_receiver) {}
inline Result Client::Get(const std::string &path,
                          ContentReceiver content_receiver, Progress progress) {}
inline Result Client::Get(const std::string &path, const Headers &headers,
                          ContentReceiver content_receiver, Progress progress) {}
inline Result Client::Get(const std::string &path,
                          ResponseHandler response_handler,
                          ContentReceiver content_receiver) {}
inline Result Client::Get(const std::string &path, const Headers &headers,
                          ResponseHandler response_handler,
                          ContentReceiver content_receiver) {}
inline Result Client::Get(const std::string &path,
                          ResponseHandler response_handler,
                          ContentReceiver content_receiver, Progress progress) {}
inline Result Client::Get(const std::string &path, const Headers &headers,
                          ResponseHandler response_handler,
                          ContentReceiver content_receiver, Progress progress) {}
inline Result Client::Get(const std::string &path, const Params &params,
                          const Headers &headers, Progress progress) {}
inline Result Client::Get(const std::string &path, const Params &params,
                          const Headers &headers,
                          ContentReceiver content_receiver, Progress progress) {}
inline Result Client::Get(const std::string &path, const Params &params,
                          const Headers &headers,
                          ResponseHandler response_handler,
                          ContentReceiver content_receiver, Progress progress) {}

inline Result Client::Head(const std::string &path) {}
inline Result Client::Head(const std::string &path, const Headers &headers) {}

inline Result Client::Post(const std::string &path) {}
inline Result Client::Post(const std::string &path, const Headers &headers) {}
inline Result Client::Post(const std::string &path, const char *body,
                           size_t content_length,
                           const std::string &content_type) {}
inline Result Client::Post(const std::string &path, const Headers &headers,
                           const char *body, size_t content_length,
                           const std::string &content_type) {}
inline Result Client::Post(const std::string &path, const Headers &headers,
                           const char *body, size_t content_length,
                           const std::string &content_type, Progress progress) {}
inline Result Client::Post(const std::string &path, const std::string &body,
                           const std::string &content_type) {}
inline Result Client::Post(const std::string &path, const std::string &body,
                           const std::string &content_type, Progress progress) {}
inline Result Client::Post(const std::string &path, const Headers &headers,
                           const std::string &body,
                           const std::string &content_type) {}
inline Result Client::Post(const std::string &path, const Headers &headers,
                           const std::string &body,
                           const std::string &content_type, Progress progress) {}
inline Result Client::Post(const std::string &path, size_t content_length,
                           ContentProvider content_provider,
                           const std::string &content_type) {}
inline Result Client::Post(const std::string &path,
                           ContentProviderWithoutLength content_provider,
                           const std::string &content_type) {}
inline Result Client::Post(const std::string &path, const Headers &headers,
                           size_t content_length,
                           ContentProvider content_provider,
                           const std::string &content_type) {}
inline Result Client::Post(const std::string &path, const Headers &headers,
                           ContentProviderWithoutLength content_provider,
                           const std::string &content_type) {}
inline Result Client::Post(const std::string &path, const Params &params) {}
inline Result Client::Post(const std::string &path, const Headers &headers,
                           const Params &params) {}
inline Result Client::Post(const std::string &path, const Headers &headers,
                           const Params &params, Progress progress) {}
inline Result Client::Post(const std::string &path,
                           const MultipartFormDataItems &items) {}
inline Result Client::Post(const std::string &path, const Headers &headers,
                           const MultipartFormDataItems &items) {}
inline Result Client::Post(const std::string &path, const Headers &headers,
                           const MultipartFormDataItems &items,
                           const std::string &boundary) {}
inline Result
Client::Post(const std::string &path, const Headers &headers,
             const MultipartFormDataItems &items,
             const MultipartFormDataProviderItems &provider_items) {}
inline Result Client::Put(const std::string &path) {}
inline Result Client::Put(const std::string &path, const char *body,
                          size_t content_length,
                          const std::string &content_type) {}
inline Result Client::Put(const std::string &path, const Headers &headers,
                          const char *body, size_t content_length,
                          const std::string &content_type) {}
inline Result Client::Put(const std::string &path, const Headers &headers,
                          const char *body, size_t content_length,
                          const std::string &content_type, Progress progress) {}
inline Result Client::Put(const std::string &path, const std::string &body,
                          const std::string &content_type) {}
inline Result Client::Put(const std::string &path, const std::string &body,
                          const std::string &content_type, Progress progress) {}
inline Result Client::Put(const std::string &path, const Headers &headers,
                          const std::string &body,
                          const std::string &content_type) {}
inline Result Client::Put(const std::string &path, const Headers &headers,
                          const std::string &body,
                          const std::string &content_type, Progress progress) {}
inline Result Client::Put(const std::string &path, size_t content_length,
                          ContentProvider content_provider,
                          const std::string &content_type) {}
inline Result Client::Put(const std::string &path,
                          ContentProviderWithoutLength content_provider,
                          const std::string &content_type) {}
inline Result Client::Put(const std::string &path, const Headers &headers,
                          size_t content_length,
                          ContentProvider content_provider,
                          const std::string &content_type) {}
inline Result Client::Put(const std::string &path, const Headers &headers,
                          ContentProviderWithoutLength content_provider,
                          const std::string &content_type) {}
inline Result Client::Put(const std::string &path, const Params &params) {}
inline Result Client::Put(const std::string &path, const Headers &headers,
                          const Params &params) {}
inline Result Client::Put(const std::string &path, const Headers &headers,
                          const Params &params, Progress progress) {}
inline Result Client::Put(const std::string &path,
                          const MultipartFormDataItems &items) {}
inline Result Client::Put(const std::string &path, const Headers &headers,
                          const MultipartFormDataItems &items) {}
inline Result Client::Put(const std::string &path, const Headers &headers,
                          const MultipartFormDataItems &items,
                          const std::string &boundary) {}
inline Result
Client::Put(const std::string &path, const Headers &headers,
            const MultipartFormDataItems &items,
            const MultipartFormDataProviderItems &provider_items) {}
inline Result Client::Patch(const std::string &path) {}
inline Result Client::Patch(const std::string &path, const char *body,
                            size_t content_length,
                            const std::string &content_type) {}
inline Result Client::Patch(const std::string &path, const char *body,
                            size_t content_length,
                            const std::string &content_type,
                            Progress progress) {}
inline Result Client::Patch(const std::string &path, const Headers &headers,
                            const char *body, size_t content_length,
                            const std::string &content_type) {}
inline Result Client::Patch(const std::string &path, const Headers &headers,
                            const char *body, size_t content_length,
                            const std::string &content_type,
                            Progress progress) {}
inline Result Client::Patch(const std::string &path, const std::string &body,
                            const std::string &content_type) {}
inline Result Client::Patch(const std::string &path, const std::string &body,
                            const std::string &content_type,
                            Progress progress) {}
inline Result Client::Patch(const std::string &path, const Headers &headers,
                            const std::string &body,
                            const std::string &content_type) {}
inline Result Client::Patch(const std::string &path, const Headers &headers,
                            const std::string &body,
                            const std::string &content_type,
                            Progress progress) {}
inline Result Client::Patch(const std::string &path, size_t content_length,
                            ContentProvider content_provider,
                            const std::string &content_type) {}
inline Result Client::Patch(const std::string &path,
                            ContentProviderWithoutLength content_provider,
                            const std::string &content_type) {}
inline Result Client::Patch(const std::string &path, const Headers &headers,
                            size_t content_length,
                            ContentProvider content_provider,
                            const std::string &content_type) {}
inline Result Client::Patch(const std::string &path, const Headers &headers,
                            ContentProviderWithoutLength content_provider,
                            const std::string &content_type) {}
inline Result Client::Delete(const std::string &path) {}
inline Result Client::Delete(const std::string &path, const Headers &headers) {}
inline Result Client::Delete(const std::string &path, const char *body,
                             size_t content_length,
                             const std::string &content_type) {}
inline Result Client::Delete(const std::string &path, const char *body,
                             size_t content_length,
                             const std::string &content_type,
                             Progress progress) {}
inline Result Client::Delete(const std::string &path, const Headers &headers,
                             const char *body, size_t content_length,
                             const std::string &content_type) {}
inline Result Client::Delete(const std::string &path, const Headers &headers,
                             const char *body, size_t content_length,
                             const std::string &content_type,
                             Progress progress) {}
inline Result Client::Delete(const std::string &path, const std::string &body,
                             const std::string &content_type) {}
inline Result Client::Delete(const std::string &path, const std::string &body,
                             const std::string &content_type,
                             Progress progress) {}
inline Result Client::Delete(const std::string &path, const Headers &headers,
                             const std::string &body,
                             const std::string &content_type) {}
inline Result Client::Delete(const std::string &path, const Headers &headers,
                             const std::string &body,
                             const std::string &content_type,
                             Progress progress) {}
inline Result Client::Options(const std::string &path) {}
inline Result Client::Options(const std::string &path, const Headers &headers) {}

inline bool Client::send(Request &req, Response &res, Error &error) {}

inline Result Client::send(const Request &req) {}

inline void Client::stop() {}

inline std::string Client::host() const {}

inline int Client::port() const {}

inline size_t Client::is_socket_open() const {}

inline socket_t Client::socket() const {}

inline void
Client::set_hostname_addr_map(std::map<std::string, std::string> addr_map) {}

inline void Client::set_default_headers(Headers headers) {}

inline void Client::set_header_writer(
    std::function<ssize_t(Stream &, Headers &)> const &writer) {}

inline void Client::set_address_family(int family) {}

inline void Client::set_tcp_nodelay(bool on) {}

inline void Client::set_socket_options(SocketOptions socket_options) {}

inline void Client::set_connection_timeout(time_t sec, time_t usec) {}

inline void Client::set_read_timeout(time_t sec, time_t usec) {}

inline void Client::set_write_timeout(time_t sec, time_t usec) {}

inline void Client::set_basic_auth(const std::string &username,
                                   const std::string &password) {}
inline void Client::set_bearer_token_auth(const std::string &token) {}
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
inline void Client::set_digest_auth(const std::string &username,
                                    const std::string &password) {}
#endif

inline void Client::set_keep_alive(bool on) {}
inline void Client::set_follow_location(bool on) {}

inline void Client::set_url_encode(bool on) {}

inline void Client::set_compress(bool on) {}

inline void Client::set_decompress(bool on) {}

inline void Client::set_interface(const std::string &intf) {}

inline void Client::set_proxy(const std::string &host, int port) {}
inline void Client::set_proxy_basic_auth(const std::string &username,
                                         const std::string &password) {}
inline void Client::set_proxy_bearer_token_auth(const std::string &token) {}
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
inline void Client::set_proxy_digest_auth(const std::string &username,
                                          const std::string &password) {}
#endif

#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
inline void Client::enable_server_certificate_verification(bool enabled) {}
#endif

inline void Client::set_logger(Logger logger) {}

#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
inline void Client::set_ca_cert_path(const std::string &ca_cert_file_path,
                                     const std::string &ca_cert_dir_path) {}

inline void Client::set_ca_cert_store(X509_STORE *ca_cert_store) {}

inline void Client::load_ca_cert_store(const char *ca_cert, std::size_t size) {}

inline long Client::get_openssl_verify_result() const {}

inline SSL_CTX *Client::ssl_context() const {}
#endif

// ----------------------------------------------------------------------------

} // namespace httplib

#if defined(_WIN32) && defined(CPPHTTPLIB_USE_POLL)
#undef poll
#endif

#endif // CPPHTTPLIB_HTTPLIB_H