|
|
|
@@ -237,6 +237,27 @@ 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) {
|
|
|
|
|
return std::unique_ptr<T>(new T(std::forward<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) {
|
|
|
|
|
typedef typename std::remove_extent<T>::type RT;
|
|
|
|
|
return std::unique_ptr<T>(new RT[n]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct ci {
|
|
|
|
|
bool operator()(const std::string &s1, const std::string &s2) const {
|
|
|
|
|
return std::lexicographical_compare(
|
|
|
|
@@ -317,14 +338,17 @@ public:
|
|
|
|
|
ContentReceiver receiver)>;
|
|
|
|
|
|
|
|
|
|
ContentReader(Reader reader, MultipartReader multipart_reader)
|
|
|
|
|
: reader_(reader), multipart_reader_(multipart_reader) {}
|
|
|
|
|
: reader_(std::move(reader)),
|
|
|
|
|
multipart_reader_(std::move(multipart_reader)) {}
|
|
|
|
|
|
|
|
|
|
bool operator()(MultipartContentHeader header,
|
|
|
|
|
ContentReceiver receiver) const {
|
|
|
|
|
return multipart_reader_(header, receiver);
|
|
|
|
|
return multipart_reader_(std::move(header), std::move(receiver));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool operator()(ContentReceiver receiver) const { return reader_(receiver); }
|
|
|
|
|
bool operator()(ContentReceiver receiver) const {
|
|
|
|
|
return reader_(std::move(receiver));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Reader reader_;
|
|
|
|
|
MultipartReader multipart_reader_;
|
|
|
|
@@ -475,7 +499,7 @@ public:
|
|
|
|
|
|
|
|
|
|
void enqueue(std::function<void()> fn) override {
|
|
|
|
|
std::unique_lock<std::mutex> lock(mutex_);
|
|
|
|
|
jobs_.push_back(fn);
|
|
|
|
|
jobs_.push_back(std::move(fn));
|
|
|
|
|
cond_.notify_one();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -704,13 +728,14 @@ enum Error {
|
|
|
|
|
Canceled,
|
|
|
|
|
SSLConnection,
|
|
|
|
|
SSLLoadingCerts,
|
|
|
|
|
SSLServerVerification
|
|
|
|
|
SSLServerVerification,
|
|
|
|
|
UnsupportedMultipartBoundaryChars
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class Result {
|
|
|
|
|
public:
|
|
|
|
|
Result(const std::shared_ptr<Response> &res, Error err)
|
|
|
|
|
: res_(res), err_(err) {}
|
|
|
|
|
Result(std::unique_ptr<Response> res, Error err)
|
|
|
|
|
: res_(std::move(res)), err_(err) {}
|
|
|
|
|
operator bool() const { return res_ != nullptr; }
|
|
|
|
|
bool operator==(std::nullptr_t) const { return res_ == nullptr; }
|
|
|
|
|
bool operator!=(std::nullptr_t) const { return res_ != nullptr; }
|
|
|
|
@@ -720,7 +745,7 @@ public:
|
|
|
|
|
Error error() const { return err_; }
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
std::shared_ptr<Response> res_;
|
|
|
|
|
std::unique_ptr<Response> res_;
|
|
|
|
|
Error err_;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
@@ -777,6 +802,9 @@ public:
|
|
|
|
|
Result Post(const char *path, const MultipartFormDataItems &items);
|
|
|
|
|
Result Post(const char *path, const Headers &headers,
|
|
|
|
|
const MultipartFormDataItems &items);
|
|
|
|
|
Result Post(const char *path, const Headers &headers,
|
|
|
|
|
const MultipartFormDataItems &items,
|
|
|
|
|
const std::string& boundary);
|
|
|
|
|
|
|
|
|
|
Result Put(const char *path);
|
|
|
|
|
Result Put(const char *path, const std::string &body,
|
|
|
|
@@ -943,7 +971,7 @@ private:
|
|
|
|
|
bool handle_request(Stream &strm, const Request &req, Response &res,
|
|
|
|
|
bool close_connection);
|
|
|
|
|
void stop_core();
|
|
|
|
|
std::shared_ptr<Response> send_with_content_provider(
|
|
|
|
|
std::unique_ptr<Response> send_with_content_provider(
|
|
|
|
|
const char *method, const char *path, const Headers &headers,
|
|
|
|
|
const std::string &body, size_t content_length,
|
|
|
|
|
ContentProvider content_provider, const char *content_type);
|
|
|
|
@@ -1012,6 +1040,9 @@ public:
|
|
|
|
|
Result Post(const char *path, const MultipartFormDataItems &items);
|
|
|
|
|
Result Post(const char *path, const Headers &headers,
|
|
|
|
|
const MultipartFormDataItems &items);
|
|
|
|
|
Result Post(const char *path, const Headers &headers,
|
|
|
|
|
const MultipartFormDataItems &items,
|
|
|
|
|
const std::string& boundary);
|
|
|
|
|
Result Put(const char *path);
|
|
|
|
|
Result Put(const char *path, const std::string &body,
|
|
|
|
|
const char *content_type);
|
|
|
|
@@ -1098,7 +1129,7 @@ public:
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
std::shared_ptr<ClientImpl> cli_;
|
|
|
|
|
std::unique_ptr<ClientImpl> cli_;
|
|
|
|
|
|
|
|
|
|
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
|
|
|
|
bool is_ssl_ = false;
|
|
|
|
@@ -1944,7 +1975,7 @@ inline socket_t create_client_socket(const char *host, int port,
|
|
|
|
|
time_t timeout_sec, time_t timeout_usec,
|
|
|
|
|
const std::string &intf, Error &error) {
|
|
|
|
|
auto sock = create_socket(
|
|
|
|
|
host, port, 0, tcp_nodelay, socket_options,
|
|
|
|
|
host, port, 0, tcp_nodelay, std::move(socket_options),
|
|
|
|
|
[&](socket_t sock, struct addrinfo &ai) -> bool {
|
|
|
|
|
if (!intf.empty()) {
|
|
|
|
|
#ifdef USE_IF2IP
|
|
|
|
@@ -2574,19 +2605,19 @@ bool prepare_content_receiver(T &x, int &status, ContentReceiver receiver,
|
|
|
|
|
bool decompress, U callback) {
|
|
|
|
|
if (decompress) {
|
|
|
|
|
std::string encoding = x.get_header_value("Content-Encoding");
|
|
|
|
|
std::shared_ptr<decompressor> decompressor;
|
|
|
|
|
std::unique_ptr<decompressor> decompressor;
|
|
|
|
|
|
|
|
|
|
if (encoding.find("gzip") != std::string::npos ||
|
|
|
|
|
encoding.find("deflate") != std::string::npos) {
|
|
|
|
|
#ifdef CPPHTTPLIB_ZLIB_SUPPORT
|
|
|
|
|
decompressor = std::make_shared<gzip_decompressor>();
|
|
|
|
|
decompressor = detail::make_unique<gzip_decompressor>();
|
|
|
|
|
#else
|
|
|
|
|
status = 415;
|
|
|
|
|
return false;
|
|
|
|
|
#endif
|
|
|
|
|
} else if (encoding.find("br") != std::string::npos) {
|
|
|
|
|
#ifdef CPPHTTPLIB_BROTLI_SUPPORT
|
|
|
|
|
decompressor = std::make_shared<brotli_decompressor>();
|
|
|
|
|
decompressor = detail::make_unique<brotli_decompressor>();
|
|
|
|
|
#else
|
|
|
|
|
status = 415;
|
|
|
|
|
return false;
|
|
|
|
@@ -2600,7 +2631,7 @@ bool prepare_content_receiver(T &x, int &status, ContentReceiver receiver,
|
|
|
|
|
buf, n,
|
|
|
|
|
[&](const char *buf, size_t n) { return receiver(buf, n); });
|
|
|
|
|
};
|
|
|
|
|
return callback(out);
|
|
|
|
|
return callback(std::move(out));
|
|
|
|
|
} else {
|
|
|
|
|
status = 500;
|
|
|
|
|
return false;
|
|
|
|
@@ -2611,7 +2642,7 @@ bool prepare_content_receiver(T &x, int &status, ContentReceiver receiver,
|
|
|
|
|
ContentReceiver out = [&](const char *buf, size_t n) {
|
|
|
|
|
return receiver(buf, n);
|
|
|
|
|
};
|
|
|
|
|
return callback(out);
|
|
|
|
|
return callback(std::move(out));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
@@ -2619,7 +2650,7 @@ bool read_content(Stream &strm, T &x, size_t payload_max_length, int &status,
|
|
|
|
|
Progress progress, ContentReceiver receiver,
|
|
|
|
|
bool decompress) {
|
|
|
|
|
return prepare_content_receiver(
|
|
|
|
|
x, status, receiver, decompress, [&](const ContentReceiver &out) {
|
|
|
|
|
x, status, std::move(receiver), decompress, [&](const ContentReceiver &out) {
|
|
|
|
|
auto ret = true;
|
|
|
|
|
auto exceed_payload_max_length = false;
|
|
|
|
|
|
|
|
|
@@ -2634,7 +2665,7 @@ bool read_content(Stream &strm, T &x, size_t payload_max_length, int &status,
|
|
|
|
|
skip_content_with_length(strm, len);
|
|
|
|
|
ret = false;
|
|
|
|
|
} else if (len > 0) {
|
|
|
|
|
ret = read_content_with_length(strm, len, progress, out);
|
|
|
|
|
ret = read_content_with_length(strm, len, std::move(progress), out);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -2918,7 +2949,7 @@ public:
|
|
|
|
|
bool is_valid() const { return is_valid_; }
|
|
|
|
|
|
|
|
|
|
template <typename T, typename U>
|
|
|
|
|
bool parse(const char *buf, size_t n, T content_callback, U header_callback) {
|
|
|
|
|
bool parse(const char *buf, size_t n, const T &content_callback, const U &header_callback) {
|
|
|
|
|
|
|
|
|
|
static const std::regex re_content_disposition(
|
|
|
|
|
"^Content-Disposition:\\s*form-data;\\s*name=\"(.*?)\"(?:;\\s*filename="
|
|
|
|
@@ -3090,8 +3121,13 @@ inline std::string make_multipart_data_boundary() {
|
|
|
|
|
static const char data[] =
|
|
|
|
|
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
|
|
|
|
|
|
|
|
|
// std::random_device might actually be deterministic on some
|
|
|
|
|
// platforms, but due to lack of support in the c++ standard library,
|
|
|
|
|
// doing better requires either some ugly hacks or breaking portability.
|
|
|
|
|
std::random_device seed_gen;
|
|
|
|
|
std::mt19937 engine(seed_gen());
|
|
|
|
|
// Request 128 bits of entropy for initialization
|
|
|
|
|
std::seed_seq seed_sequence{seed_gen(), seed_gen(), seed_gen(), seed_gen()};
|
|
|
|
|
std::mt19937 engine(seed_sequence);
|
|
|
|
|
|
|
|
|
|
std::string result = "--cpp-httplib-multipart-data-";
|
|
|
|
|
|
|
|
|
@@ -3451,7 +3487,7 @@ inline std::pair<std::string, std::string> make_range_header(Ranges ranges) {
|
|
|
|
|
if (r.second != -1) { field += std::to_string(r.second); }
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
return std::make_pair("Range", field);
|
|
|
|
|
return std::make_pair("Range", std::move(field));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline std::pair<std::string, std::string>
|
|
|
|
@@ -3460,7 +3496,7 @@ make_basic_authentication_header(const std::string &username,
|
|
|
|
|
bool is_proxy = false) {
|
|
|
|
|
auto field = "Basic " + detail::base64_encode(username + ":" + password);
|
|
|
|
|
auto key = is_proxy ? "Proxy-Authorization" : "Authorization";
|
|
|
|
|
return std::make_pair(key, field);
|
|
|
|
|
return std::make_pair(key, std::move(field));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline std::pair<std::string, std::string>
|
|
|
|
@@ -3468,7 +3504,7 @@ make_bearer_token_authentication_header(const std::string &token,
|
|
|
|
|
bool is_proxy = false) {
|
|
|
|
|
auto field = "Bearer " + token;
|
|
|
|
|
auto key = is_proxy ? "Proxy-Authorization" : "Authorization";
|
|
|
|
|
return std::make_pair(key, field);
|
|
|
|
|
return std::make_pair(key, std::move(field));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Request implementation
|
|
|
|
@@ -3761,60 +3797,66 @@ inline Server::Server()
|
|
|
|
|
inline Server::~Server() {}
|
|
|
|
|
|
|
|
|
|
inline Server &Server::Get(const char *pattern, Handler handler) {
|
|
|
|
|
get_handlers_.push_back(std::make_pair(std::regex(pattern), handler));
|
|
|
|
|
get_handlers_.push_back(std::make_pair(std::regex(pattern),
|
|
|
|
|
std::move(handler)));
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline Server &Server::Post(const char *pattern, Handler handler) {
|
|
|
|
|
post_handlers_.push_back(std::make_pair(std::regex(pattern), handler));
|
|
|
|
|
post_handlers_.push_back(std::make_pair(std::regex(pattern),
|
|
|
|
|
std::move(handler)));
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline Server &Server::Post(const char *pattern,
|
|
|
|
|
HandlerWithContentReader handler) {
|
|
|
|
|
post_handlers_for_content_reader_.push_back(
|
|
|
|
|
std::make_pair(std::regex(pattern), handler));
|
|
|
|
|
std::make_pair(std::regex(pattern), std::move(handler)));
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline Server &Server::Put(const char *pattern, Handler handler) {
|
|
|
|
|
put_handlers_.push_back(std::make_pair(std::regex(pattern), handler));
|
|
|
|
|
put_handlers_.push_back(std::make_pair(std::regex(pattern),
|
|
|
|
|
std::move(handler)));
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline Server &Server::Put(const char *pattern,
|
|
|
|
|
HandlerWithContentReader handler) {
|
|
|
|
|
put_handlers_for_content_reader_.push_back(
|
|
|
|
|
std::make_pair(std::regex(pattern), handler));
|
|
|
|
|
std::make_pair(std::regex(pattern), std::move(handler)));
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline Server &Server::Patch(const char *pattern, Handler handler) {
|
|
|
|
|
patch_handlers_.push_back(std::make_pair(std::regex(pattern), handler));
|
|
|
|
|
patch_handlers_.push_back(std::make_pair(std::regex(pattern),
|
|
|
|
|
std::move(handler)));
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline Server &Server::Patch(const char *pattern,
|
|
|
|
|
HandlerWithContentReader handler) {
|
|
|
|
|
patch_handlers_for_content_reader_.push_back(
|
|
|
|
|
std::make_pair(std::regex(pattern), handler));
|
|
|
|
|
std::make_pair(std::regex(pattern), std::move(handler)));
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline Server &Server::Delete(const char *pattern, Handler handler) {
|
|
|
|
|
delete_handlers_.push_back(std::make_pair(std::regex(pattern), handler));
|
|
|
|
|
delete_handlers_.push_back(std::make_pair(std::regex(pattern),
|
|
|
|
|
std::move(handler)));
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline Server &Server::Delete(const char *pattern,
|
|
|
|
|
HandlerWithContentReader handler) {
|
|
|
|
|
delete_handlers_for_content_reader_.push_back(
|
|
|
|
|
std::make_pair(std::regex(pattern), handler));
|
|
|
|
|
std::make_pair(std::regex(pattern), std::move(handler)));
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline Server &Server::Options(const char *pattern, Handler handler) {
|
|
|
|
|
options_handlers_.push_back(std::make_pair(std::regex(pattern), handler));
|
|
|
|
|
options_handlers_.push_back(std::make_pair(std::regex(pattern),
|
|
|
|
|
std::move(handler)));
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -3860,7 +3902,7 @@ inline void Server::set_error_handler(Handler handler) {
|
|
|
|
|
inline void Server::set_tcp_nodelay(bool on) { tcp_nodelay_ = on; }
|
|
|
|
|
|
|
|
|
|
inline void Server::set_socket_options(SocketOptions socket_options) {
|
|
|
|
|
socket_options_ = socket_options;
|
|
|
|
|
socket_options_ = std::move(socket_options);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline void Server::set_logger(Logger logger) { logger_ = std::move(logger); }
|
|
|
|
@@ -4045,16 +4087,16 @@ inline bool Server::write_response(Stream &strm, bool close_connection,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (type != detail::EncodingType::None) {
|
|
|
|
|
std::shared_ptr<detail::compressor> compressor;
|
|
|
|
|
std::unique_ptr<detail::compressor> compressor;
|
|
|
|
|
|
|
|
|
|
if (type == detail::EncodingType::Gzip) {
|
|
|
|
|
#ifdef CPPHTTPLIB_ZLIB_SUPPORT
|
|
|
|
|
compressor = std::make_shared<detail::gzip_compressor>();
|
|
|
|
|
compressor = detail::make_unique<detail::gzip_compressor>();
|
|
|
|
|
res.set_header("Content-Encoding", "gzip");
|
|
|
|
|
#endif
|
|
|
|
|
} else if (type == detail::EncodingType::Brotli) {
|
|
|
|
|
#ifdef CPPHTTPLIB_BROTLI_SUPPORT
|
|
|
|
|
compressor = std::make_shared<detail::brotli_compressor>();
|
|
|
|
|
compressor = detail::make_unique<detail::brotli_compressor>();
|
|
|
|
|
res.set_header("Content-Encoding", "brotli");
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
@@ -4136,17 +4178,17 @@ Server::write_content_with_provider(Stream &strm, const Request &req,
|
|
|
|
|
if (res.is_chunked_content_provider) {
|
|
|
|
|
auto type = detail::encoding_type(req, res);
|
|
|
|
|
|
|
|
|
|
std::shared_ptr<detail::compressor> compressor;
|
|
|
|
|
std::unique_ptr<detail::compressor> compressor;
|
|
|
|
|
if (type == detail::EncodingType::Gzip) {
|
|
|
|
|
#ifdef CPPHTTPLIB_ZLIB_SUPPORT
|
|
|
|
|
compressor = std::make_shared<detail::gzip_compressor>();
|
|
|
|
|
compressor = detail::make_unique<detail::gzip_compressor>();
|
|
|
|
|
#endif
|
|
|
|
|
} else if (type == detail::EncodingType::Brotli) {
|
|
|
|
|
#ifdef CPPHTTPLIB_BROTLI_SUPPORT
|
|
|
|
|
compressor = std::make_shared<detail::brotli_compressor>();
|
|
|
|
|
compressor = detail::make_unique<detail::brotli_compressor>();
|
|
|
|
|
#endif
|
|
|
|
|
} else {
|
|
|
|
|
compressor = std::make_shared<detail::nocompressor>();
|
|
|
|
|
compressor = detail::make_unique<detail::nocompressor>();
|
|
|
|
|
}
|
|
|
|
|
assert(compressor != nullptr);
|
|
|
|
|
|
|
|
|
@@ -4198,8 +4240,9 @@ inline bool Server::read_content_with_content_receiver(
|
|
|
|
|
Stream &strm, Request &req, Response &res, ContentReceiver receiver,
|
|
|
|
|
MultipartContentHeader multipart_header,
|
|
|
|
|
ContentReceiver multipart_receiver) {
|
|
|
|
|
return read_content_core(strm, req, res, receiver, multipart_header,
|
|
|
|
|
multipart_receiver);
|
|
|
|
|
return read_content_core(strm, req, res, std::move(receiver),
|
|
|
|
|
std::move(multipart_header),
|
|
|
|
|
std::move(multipart_receiver));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline bool Server::read_content_core(Stream &strm, Request &req, Response &res,
|
|
|
|
@@ -4234,7 +4277,7 @@ inline bool Server::read_content_core(Stream &strm, Request &req, Response &res,
|
|
|
|
|
mulitpart_header);
|
|
|
|
|
};
|
|
|
|
|
} else {
|
|
|
|
|
out = receiver;
|
|
|
|
|
out = std::move(receiver);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (req.method == "DELETE" && !req.has_header("Content-Length")) {
|
|
|
|
@@ -4290,7 +4333,7 @@ inline socket_t
|
|
|
|
|
Server::create_server_socket(const char *host, int port, int socket_flags,
|
|
|
|
|
SocketOptions socket_options) const {
|
|
|
|
|
return detail::create_socket(
|
|
|
|
|
host, port, socket_flags, tcp_nodelay_, socket_options,
|
|
|
|
|
host, port, socket_flags, tcp_nodelay_, std::move(socket_options),
|
|
|
|
|
[](socket_t sock, struct addrinfo &ai) -> bool {
|
|
|
|
|
if (::bind(sock, ai.ai_addr, static_cast<socklen_t>(ai.ai_addrlen))) {
|
|
|
|
|
return false;
|
|
|
|
@@ -4392,32 +4435,38 @@ inline bool Server::routing(Request &req, Response &res, Stream &strm) {
|
|
|
|
|
{
|
|
|
|
|
ContentReader reader(
|
|
|
|
|
[&](ContentReceiver receiver) {
|
|
|
|
|
return read_content_with_content_receiver(strm, req, res, receiver,
|
|
|
|
|
return read_content_with_content_receiver(strm, req, res,
|
|
|
|
|
std::move(receiver),
|
|
|
|
|
nullptr, nullptr);
|
|
|
|
|
},
|
|
|
|
|
[&](MultipartContentHeader header, ContentReceiver receiver) {
|
|
|
|
|
return read_content_with_content_receiver(strm, req, res, nullptr,
|
|
|
|
|
header, receiver);
|
|
|
|
|
std::move(header),
|
|
|
|
|
std::move(receiver));
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (req.method == "POST") {
|
|
|
|
|
if (dispatch_request_for_content_reader(
|
|
|
|
|
req, res, reader, post_handlers_for_content_reader_)) {
|
|
|
|
|
req, res, std::move(reader),
|
|
|
|
|
post_handlers_for_content_reader_)) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
} else if (req.method == "PUT") {
|
|
|
|
|
if (dispatch_request_for_content_reader(
|
|
|
|
|
req, res, reader, put_handlers_for_content_reader_)) {
|
|
|
|
|
req, res, std::move(reader),
|
|
|
|
|
put_handlers_for_content_reader_)) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
} else if (req.method == "PATCH") {
|
|
|
|
|
if (dispatch_request_for_content_reader(
|
|
|
|
|
req, res, reader, patch_handlers_for_content_reader_)) {
|
|
|
|
|
req, res, std::move(reader),
|
|
|
|
|
patch_handlers_for_content_reader_)) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
} else if (req.method == "DELETE") {
|
|
|
|
|
if (dispatch_request_for_content_reader(
|
|
|
|
|
req, res, reader, delete_handlers_for_content_reader_)) {
|
|
|
|
|
req, res, std::move(reader),
|
|
|
|
|
delete_handlers_for_content_reader_)) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@@ -4973,7 +5022,7 @@ inline bool ClientImpl::write_request(Stream &strm, const Request &req,
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline std::shared_ptr<Response> ClientImpl::send_with_content_provider(
|
|
|
|
|
inline std::unique_ptr<Response> ClientImpl::send_with_content_provider(
|
|
|
|
|
const char *method, const char *path, const Headers &headers,
|
|
|
|
|
const std::string &body, size_t content_length,
|
|
|
|
|
ContentProvider content_provider, const char *content_type) {
|
|
|
|
@@ -5036,15 +5085,15 @@ inline std::shared_ptr<Response> ClientImpl::send_with_content_provider(
|
|
|
|
|
{
|
|
|
|
|
if (content_provider) {
|
|
|
|
|
req.content_length = content_length;
|
|
|
|
|
req.content_provider = content_provider;
|
|
|
|
|
req.content_provider = std::move(content_provider);
|
|
|
|
|
} else {
|
|
|
|
|
req.body = body;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto res = std::make_shared<Response>();
|
|
|
|
|
auto res = detail::make_unique<Response>();
|
|
|
|
|
|
|
|
|
|
return send(req, *res) ? res : nullptr;
|
|
|
|
|
return send(req, *res) ? std::move(res) : nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline bool ClientImpl::process_request(Stream &strm, const Request &req,
|
|
|
|
@@ -5090,7 +5139,8 @@ inline bool ClientImpl::process_request(Stream &strm, const Request &req,
|
|
|
|
|
|
|
|
|
|
int dummy_status;
|
|
|
|
|
if (!detail::read_content(strm, res, (std::numeric_limits<size_t>::max)(),
|
|
|
|
|
dummy_status, progress, out, decompress_)) {
|
|
|
|
|
dummy_status, std::move(progress), std::move(out),
|
|
|
|
|
decompress_)) {
|
|
|
|
|
if (error_ != Error::Canceled) { error_ = Error::Read; }
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
@@ -5112,7 +5162,8 @@ ClientImpl::process_socket(Socket &socket,
|
|
|
|
|
std::function<bool(Stream &strm)> callback) {
|
|
|
|
|
return detail::process_client_socket(socket.sock, read_timeout_sec_,
|
|
|
|
|
read_timeout_usec_, write_timeout_sec_,
|
|
|
|
|
write_timeout_usec_, callback);
|
|
|
|
|
write_timeout_usec_,
|
|
|
|
|
std::move(callback));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline bool ClientImpl::is_ssl() const { return false; }
|
|
|
|
@@ -5138,9 +5189,9 @@ inline Result ClientImpl::Get(const char *path, const Headers &headers,
|
|
|
|
|
req.headers.insert(headers.begin(), headers.end());
|
|
|
|
|
req.progress = std::move(progress);
|
|
|
|
|
|
|
|
|
|
auto res = std::make_shared<Response>();
|
|
|
|
|
auto res = detail::make_unique<Response>();
|
|
|
|
|
auto ret = send(req, *res);
|
|
|
|
|
return Result{ret ? res : nullptr, get_last_error()};
|
|
|
|
|
return Result{ret ? std::move(res) : nullptr, get_last_error()};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline Result ClientImpl::Get(const char *path,
|
|
|
|
@@ -5170,23 +5221,23 @@ inline Result ClientImpl::Get(const char *path, const Headers &headers,
|
|
|
|
|
inline Result ClientImpl::Get(const char *path,
|
|
|
|
|
ResponseHandler response_handler,
|
|
|
|
|
ContentReceiver content_receiver) {
|
|
|
|
|
return Get(path, Headers(), std::move(response_handler), content_receiver,
|
|
|
|
|
nullptr);
|
|
|
|
|
return Get(path, Headers(), std::move(response_handler),
|
|
|
|
|
std::move(content_receiver), nullptr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline Result ClientImpl::Get(const char *path, const Headers &headers,
|
|
|
|
|
ResponseHandler response_handler,
|
|
|
|
|
ContentReceiver content_receiver) {
|
|
|
|
|
return Get(path, headers, std::move(response_handler), content_receiver,
|
|
|
|
|
nullptr);
|
|
|
|
|
return Get(path, headers, std::move(response_handler),
|
|
|
|
|
std::move(content_receiver), nullptr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline Result ClientImpl::Get(const char *path,
|
|
|
|
|
ResponseHandler response_handler,
|
|
|
|
|
ContentReceiver content_receiver,
|
|
|
|
|
Progress progress) {
|
|
|
|
|
return Get(path, Headers(), std::move(response_handler), content_receiver,
|
|
|
|
|
progress);
|
|
|
|
|
return Get(path, Headers(), std::move(response_handler),
|
|
|
|
|
std::move(content_receiver), std::move(progress));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline Result ClientImpl::Get(const char *path, const Headers &headers,
|
|
|
|
@@ -5202,9 +5253,9 @@ inline Result ClientImpl::Get(const char *path, const Headers &headers,
|
|
|
|
|
req.content_receiver = std::move(content_receiver);
|
|
|
|
|
req.progress = std::move(progress);
|
|
|
|
|
|
|
|
|
|
auto res = std::make_shared<Response>();
|
|
|
|
|
auto res = detail::make_unique<Response>();
|
|
|
|
|
auto ret = send(req, *res);
|
|
|
|
|
return Result{ret ? res : nullptr, get_last_error()};
|
|
|
|
|
return Result{ret ? std::move(res) : nullptr, get_last_error()};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline Result ClientImpl::Head(const char *path) {
|
|
|
|
@@ -5218,9 +5269,9 @@ inline Result ClientImpl::Head(const char *path, const Headers &headers) {
|
|
|
|
|
req.headers.insert(headers.begin(), headers.end());
|
|
|
|
|
req.path = path;
|
|
|
|
|
|
|
|
|
|
auto res = std::make_shared<Response>();
|
|
|
|
|
auto res = detail::make_unique<Response>();
|
|
|
|
|
auto ret = send(req, *res);
|
|
|
|
|
return Result{ret ? res : nullptr, get_last_error()};
|
|
|
|
|
return Result{ret ? std::move(res) : nullptr, get_last_error()};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline Result ClientImpl::Post(const char *path) {
|
|
|
|
@@ -5237,7 +5288,7 @@ inline Result ClientImpl::Post(const char *path, const Headers &headers,
|
|
|
|
|
const char *content_type) {
|
|
|
|
|
auto ret = send_with_content_provider("POST", path, headers, body, 0, nullptr,
|
|
|
|
|
content_type);
|
|
|
|
|
return Result{ret, get_last_error()};
|
|
|
|
|
return Result{std::move(ret), get_last_error()};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline Result ClientImpl::Post(const char *path, const Params ¶ms) {
|
|
|
|
@@ -5247,7 +5298,8 @@ inline Result ClientImpl::Post(const char *path, const Params ¶ms) {
|
|
|
|
|
inline Result ClientImpl::Post(const char *path, size_t content_length,
|
|
|
|
|
ContentProvider content_provider,
|
|
|
|
|
const char *content_type) {
|
|
|
|
|
return Post(path, Headers(), content_length, content_provider, content_type);
|
|
|
|
|
return Post(path, Headers(), content_length, std::move(content_provider),
|
|
|
|
|
content_type);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline Result ClientImpl::Post(const char *path, const Headers &headers,
|
|
|
|
@@ -5255,9 +5307,10 @@ inline Result ClientImpl::Post(const char *path, const Headers &headers,
|
|
|
|
|
ContentProvider content_provider,
|
|
|
|
|
const char *content_type) {
|
|
|
|
|
auto ret = send_with_content_provider("POST", path, headers, std::string(),
|
|
|
|
|
content_length, content_provider,
|
|
|
|
|
content_length,
|
|
|
|
|
std::move(content_provider),
|
|
|
|
|
content_type);
|
|
|
|
|
return Result{ret, get_last_error()};
|
|
|
|
|
return Result{std::move(ret), get_last_error()};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline Result ClientImpl::Post(const char *path, const Headers &headers,
|
|
|
|
@@ -5273,7 +5326,18 @@ inline Result ClientImpl::Post(const char *path,
|
|
|
|
|
|
|
|
|
|
inline Result ClientImpl::Post(const char *path, const Headers &headers,
|
|
|
|
|
const MultipartFormDataItems &items) {
|
|
|
|
|
auto boundary = detail::make_multipart_data_boundary();
|
|
|
|
|
return Post(path, headers, items, detail::make_multipart_data_boundary());
|
|
|
|
|
}
|
|
|
|
|
inline Result ClientImpl::Post(const char *path, const Headers &headers,
|
|
|
|
|
const MultipartFormDataItems &items,
|
|
|
|
|
const std::string& boundary) {
|
|
|
|
|
for (size_t i = 0; i < boundary.size(); i++) {
|
|
|
|
|
char c = boundary[i];
|
|
|
|
|
if (!std::isalnum(c) && c != '-' && c != '_') {
|
|
|
|
|
error_ = Error::UnsupportedMultipartBoundaryChars;
|
|
|
|
|
return Result{nullptr, error_};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string body;
|
|
|
|
|
|
|
|
|
@@ -5311,13 +5375,14 @@ inline Result ClientImpl::Put(const char *path, const Headers &headers,
|
|
|
|
|
const char *content_type) {
|
|
|
|
|
auto ret = send_with_content_provider("PUT", path, headers, body, 0, nullptr,
|
|
|
|
|
content_type);
|
|
|
|
|
return Result{ret, get_last_error()};
|
|
|
|
|
return Result{std::move(ret), get_last_error()};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline Result ClientImpl::Put(const char *path, size_t content_length,
|
|
|
|
|
ContentProvider content_provider,
|
|
|
|
|
const char *content_type) {
|
|
|
|
|
return Put(path, Headers(), content_length, content_provider, content_type);
|
|
|
|
|
return Put(path, Headers(), content_length, std::move(content_provider),
|
|
|
|
|
content_type);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline Result ClientImpl::Put(const char *path, const Headers &headers,
|
|
|
|
@@ -5325,9 +5390,10 @@ inline Result ClientImpl::Put(const char *path, const Headers &headers,
|
|
|
|
|
ContentProvider content_provider,
|
|
|
|
|
const char *content_type) {
|
|
|
|
|
auto ret = send_with_content_provider("PUT", path, headers, std::string(),
|
|
|
|
|
content_length, content_provider,
|
|
|
|
|
content_length,
|
|
|
|
|
std::move(content_provider),
|
|
|
|
|
content_type);
|
|
|
|
|
return Result{ret, get_last_error()};
|
|
|
|
|
return Result{std::move(ret), get_last_error()};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline Result ClientImpl::Put(const char *path, const Params ¶ms) {
|
|
|
|
@@ -5350,13 +5416,14 @@ inline Result ClientImpl::Patch(const char *path, const Headers &headers,
|
|
|
|
|
const char *content_type) {
|
|
|
|
|
auto ret = send_with_content_provider("PATCH", path, headers, body, 0,
|
|
|
|
|
nullptr, content_type);
|
|
|
|
|
return Result{ret, get_last_error()};
|
|
|
|
|
return Result{std::move(ret), get_last_error()};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline Result ClientImpl::Patch(const char *path, size_t content_length,
|
|
|
|
|
ContentProvider content_provider,
|
|
|
|
|
const char *content_type) {
|
|
|
|
|
return Patch(path, Headers(), content_length, content_provider, content_type);
|
|
|
|
|
return Patch(path, Headers(), content_length, std::move(content_provider),
|
|
|
|
|
content_type);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline Result ClientImpl::Patch(const char *path, const Headers &headers,
|
|
|
|
@@ -5364,9 +5431,10 @@ inline Result ClientImpl::Patch(const char *path, const Headers &headers,
|
|
|
|
|
ContentProvider content_provider,
|
|
|
|
|
const char *content_type) {
|
|
|
|
|
auto ret = send_with_content_provider("PATCH", path, headers, std::string(),
|
|
|
|
|
content_length, content_provider,
|
|
|
|
|
content_length,
|
|
|
|
|
std::move(content_provider),
|
|
|
|
|
content_type);
|
|
|
|
|
return Result{ret, get_last_error()};
|
|
|
|
|
return Result{std::move(ret), get_last_error()};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline Result ClientImpl::Delete(const char *path) {
|
|
|
|
@@ -5394,9 +5462,9 @@ inline Result ClientImpl::Delete(const char *path, const Headers &headers,
|
|
|
|
|
if (content_type) { req.headers.emplace("Content-Type", content_type); }
|
|
|
|
|
req.body = body;
|
|
|
|
|
|
|
|
|
|
auto res = std::make_shared<Response>();
|
|
|
|
|
auto res = detail::make_unique<Response>();
|
|
|
|
|
auto ret = send(req, *res);
|
|
|
|
|
return Result{ret ? res : nullptr, get_last_error()};
|
|
|
|
|
return Result{ret ? std::move(res) : nullptr, get_last_error()};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline Result ClientImpl::Options(const char *path) {
|
|
|
|
@@ -5410,9 +5478,9 @@ inline Result ClientImpl::Options(const char *path, const Headers &headers) {
|
|
|
|
|
req.headers.insert(headers.begin(), headers.end());
|
|
|
|
|
req.path = path;
|
|
|
|
|
|
|
|
|
|
auto res = std::make_shared<Response>();
|
|
|
|
|
auto res = detail::make_unique<Response>();
|
|
|
|
|
auto ret = send(req, *res);
|
|
|
|
|
return Result{ret ? res : nullptr, get_last_error()};
|
|
|
|
|
return Result{ret ? std::move(res) : nullptr, get_last_error()};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline size_t ClientImpl::is_socket_open() const {
|
|
|
|
@@ -5479,7 +5547,7 @@ inline void ClientImpl::set_default_headers(Headers headers) {
|
|
|
|
|
inline void ClientImpl::set_tcp_nodelay(bool on) { tcp_nodelay_ = on; }
|
|
|
|
|
|
|
|
|
|
inline void ClientImpl::set_socket_options(SocketOptions socket_options) {
|
|
|
|
|
socket_options_ = socket_options;
|
|
|
|
|
socket_options_ = std::move(socket_options);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline void ClientImpl::set_compress(bool on) { compress_ = on; }
|
|
|
|
@@ -5788,9 +5856,12 @@ inline bool SSLServer::process_and_close_socket(socket_t sock) {
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
detail::ssl_delete(ctx_mutex_, ssl, ret);
|
|
|
|
|
detail::shutdown_socket(sock);
|
|
|
|
|
detail::close_socket(sock);
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
detail::shutdown_socket(sock);
|
|
|
|
|
detail::close_socket(sock);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
@@ -6024,7 +6095,7 @@ SSLClient::process_socket(Socket &socket,
|
|
|
|
|
assert(socket.ssl);
|
|
|
|
|
return detail::process_client_socket_ssl(
|
|
|
|
|
socket.ssl, socket.sock, read_timeout_sec_, read_timeout_usec_,
|
|
|
|
|
write_timeout_sec_, write_timeout_usec_, callback);
|
|
|
|
|
write_timeout_sec_, write_timeout_usec_, std::move(callback));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline bool SSLClient::is_ssl() const { return true; }
|
|
|
|
@@ -6187,28 +6258,28 @@ inline Client::Client(const char *scheme_host_port,
|
|
|
|
|
|
|
|
|
|
if (is_ssl) {
|
|
|
|
|
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
|
|
|
|
cli_ = std::make_shared<SSLClient>(host.c_str(), port, client_cert_path,
|
|
|
|
|
client_key_path);
|
|
|
|
|
cli_ = detail::make_unique<SSLClient>(host.c_str(), port,
|
|
|
|
|
client_cert_path, client_key_path);
|
|
|
|
|
is_ssl_ = is_ssl;
|
|
|
|
|
#endif
|
|
|
|
|
} else {
|
|
|
|
|
cli_ = std::make_shared<ClientImpl>(host.c_str(), port, client_cert_path,
|
|
|
|
|
client_key_path);
|
|
|
|
|
cli_ = detail::make_unique<ClientImpl>(host.c_str(), port,
|
|
|
|
|
client_cert_path, client_key_path);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
cli_ = std::make_shared<ClientImpl>(scheme_host_port, 80, client_cert_path,
|
|
|
|
|
client_key_path);
|
|
|
|
|
cli_ = detail::make_unique<ClientImpl>(scheme_host_port, 80,
|
|
|
|
|
client_cert_path, client_key_path);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline Client::Client(const std::string &host, int port)
|
|
|
|
|
: cli_(std::make_shared<ClientImpl>(host, port)) {}
|
|
|
|
|
: cli_(detail::make_unique<ClientImpl>(host, port)) {}
|
|
|
|
|
|
|
|
|
|
inline Client::Client(const std::string &host, int port,
|
|
|
|
|
const std::string &client_cert_path,
|
|
|
|
|
const std::string &client_key_path)
|
|
|
|
|
: cli_(std::make_shared<ClientImpl>(host, port, client_cert_path,
|
|
|
|
|
client_key_path)) {}
|
|
|
|
|
: cli_(detail::make_unique<ClientImpl>(host, port, client_cert_path,
|
|
|
|
|
client_key_path)) {}
|
|
|
|
|
|
|
|
|
|
inline Client::~Client() {}
|
|
|
|
|
|
|
|
|
@@ -6221,11 +6292,11 @@ inline Result Client::Get(const char *path, const Headers &headers) {
|
|
|
|
|
return cli_->Get(path, headers);
|
|
|
|
|
}
|
|
|
|
|
inline Result Client::Get(const char *path, Progress progress) {
|
|
|
|
|
return cli_->Get(path, progress);
|
|
|
|
|
return cli_->Get(path, std::move(progress));
|
|
|
|
|
}
|
|
|
|
|
inline Result Client::Get(const char *path, const Headers &headers,
|
|
|
|
|
Progress progress) {
|
|
|
|
|
return cli_->Get(path, headers, progress);
|
|
|
|
|
return cli_->Get(path, headers, std::move(progress));
|
|
|
|
|
}
|
|
|
|
|
inline Result Client::Get(const char *path, ContentReceiver content_receiver) {
|
|
|
|
|
return cli_->Get(path, std::move(content_receiver));
|
|
|
|
@@ -6262,7 +6333,8 @@ inline Result Client::Get(const char *path, ResponseHandler response_handler,
|
|
|
|
|
inline Result Client::Get(const char *path, const Headers &headers,
|
|
|
|
|
ResponseHandler response_handler,
|
|
|
|
|
ContentReceiver content_receiver, Progress progress) {
|
|
|
|
|
return cli_->Get(path, headers, response_handler, content_receiver, progress);
|
|
|
|
|
return cli_->Get(path, headers, std::move(response_handler),
|
|
|
|
|
std::move(content_receiver), std::move(progress));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline Result Client::Head(const char *path) { return cli_->Head(path); }
|
|
|
|
@@ -6282,13 +6354,14 @@ inline Result Client::Post(const char *path, const Headers &headers,
|
|
|
|
|
inline Result Client::Post(const char *path, size_t content_length,
|
|
|
|
|
ContentProvider content_provider,
|
|
|
|
|
const char *content_type) {
|
|
|
|
|
return cli_->Post(path, content_length, content_provider, content_type);
|
|
|
|
|
return cli_->Post(path, content_length, std::move(content_provider),
|
|
|
|
|
content_type);
|
|
|
|
|
}
|
|
|
|
|
inline Result Client::Post(const char *path, const Headers &headers,
|
|
|
|
|
size_t content_length,
|
|
|
|
|
ContentProvider content_provider,
|
|
|
|
|
const char *content_type) {
|
|
|
|
|
return cli_->Post(path, headers, content_length, content_provider,
|
|
|
|
|
return cli_->Post(path, headers, content_length, std::move(content_provider),
|
|
|
|
|
content_type);
|
|
|
|
|
}
|
|
|
|
|
inline Result Client::Post(const char *path, const Params ¶ms) {
|
|
|
|
@@ -6306,6 +6379,11 @@ inline Result Client::Post(const char *path, const Headers &headers,
|
|
|
|
|
const MultipartFormDataItems &items) {
|
|
|
|
|
return cli_->Post(path, headers, items);
|
|
|
|
|
}
|
|
|
|
|
inline Result Client::Post(const char *path, const Headers &headers,
|
|
|
|
|
const MultipartFormDataItems &items,
|
|
|
|
|
const std::string& boundary) {
|
|
|
|
|
return cli_->Post(path, headers, items, boundary);
|
|
|
|
|
}
|
|
|
|
|
inline Result Client::Put(const char *path) { return cli_->Put(path); }
|
|
|
|
|
inline Result Client::Put(const char *path, const std::string &body,
|
|
|
|
|
const char *content_type) {
|
|
|
|
@@ -6318,13 +6396,14 @@ inline Result Client::Put(const char *path, const Headers &headers,
|
|
|
|
|
inline Result Client::Put(const char *path, size_t content_length,
|
|
|
|
|
ContentProvider content_provider,
|
|
|
|
|
const char *content_type) {
|
|
|
|
|
return cli_->Put(path, content_length, content_provider, content_type);
|
|
|
|
|
return cli_->Put(path, content_length, std::move(content_provider),
|
|
|
|
|
content_type);
|
|
|
|
|
}
|
|
|
|
|
inline Result Client::Put(const char *path, const Headers &headers,
|
|
|
|
|
size_t content_length,
|
|
|
|
|
ContentProvider content_provider,
|
|
|
|
|
const char *content_type) {
|
|
|
|
|
return cli_->Put(path, headers, content_length, content_provider,
|
|
|
|
|
return cli_->Put(path, headers, content_length, std::move(content_provider),
|
|
|
|
|
content_type);
|
|
|
|
|
}
|
|
|
|
|
inline Result Client::Put(const char *path, const Params ¶ms) {
|
|
|
|
@@ -6345,13 +6424,14 @@ inline Result Client::Patch(const char *path, const Headers &headers,
|
|
|
|
|
inline Result Client::Patch(const char *path, size_t content_length,
|
|
|
|
|
ContentProvider content_provider,
|
|
|
|
|
const char *content_type) {
|
|
|
|
|
return cli_->Patch(path, content_length, content_provider, content_type);
|
|
|
|
|
return cli_->Patch(path, content_length, std::move(content_provider),
|
|
|
|
|
content_type);
|
|
|
|
|
}
|
|
|
|
|
inline Result Client::Patch(const char *path, const Headers &headers,
|
|
|
|
|
size_t content_length,
|
|
|
|
|
ContentProvider content_provider,
|
|
|
|
|
const char *content_type) {
|
|
|
|
|
return cli_->Patch(path, headers, content_length, content_provider,
|
|
|
|
|
return cli_->Patch(path, headers, content_length, std::move(content_provider),
|
|
|
|
|
content_type);
|
|
|
|
|
}
|
|
|
|
|
inline Result Client::Delete(const char *path) { return cli_->Delete(path); }
|
|
|
|
@@ -6386,7 +6466,7 @@ inline void Client::set_default_headers(Headers headers) {
|
|
|
|
|
|
|
|
|
|
inline void Client::set_tcp_nodelay(bool on) { cli_->set_tcp_nodelay(on); }
|
|
|
|
|
inline void Client::set_socket_options(SocketOptions socket_options) {
|
|
|
|
|
cli_->set_socket_options(socket_options);
|
|
|
|
|
cli_->set_socket_options(std::move(socket_options));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline void Client::set_connection_timeout(time_t sec, time_t usec) {
|
|
|
|
|