This commit is contained in:
yhirose 2021-08-30 17:16:31 -04:00
parent 1cc6930363
commit 0823d5c7f2

114
httplib.h
View file

@ -582,23 +582,7 @@ using Logger = std::function<void(const Request &, const Response &)>;
using SocketOptions = std::function<void(socket_t sock)>; using SocketOptions = std::function<void(socket_t sock)>;
inline void default_socket_options(socket_t sock) { void default_socket_options(socket_t sock);
int yes = 1;
#ifdef _WIN32
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<char *>(&yes),
sizeof(yes));
setsockopt(sock, SOL_SOCKET, SO_EXCLUSIVEADDRUSE,
reinterpret_cast<char *>(&yes), sizeof(yes));
#else
#ifdef SO_REUSEPORT
setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, reinterpret_cast<void *>(&yes),
sizeof(yes));
#else
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<void *>(&yes),
sizeof(yes));
#endif
#endif
}
class Server { class Server {
public: public:
@ -800,33 +784,9 @@ enum class Error {
Compression, Compression,
}; };
inline std::string to_string(const Error error) { std::string to_string(const Error error);
switch (error) {
case Error::Success: return "Success";
case Error::Connection: return "Connection";
case Error::BindIPAddress: return "BindIPAddress";
case Error::Read: return "Read";
case Error::Write: return "Write";
case Error::ExceedRedirectCount: return "ExceedRedirectCount";
case Error::Canceled: return "Canceled";
case Error::SSLConnection: return "SSLConnection";
case Error::SSLLoadingCerts: return "SSLLoadingCerts";
case Error::SSLServerVerification: return "SSLServerVerification";
case Error::UnsupportedMultipartBoundaryChars:
return "UnsupportedMultipartBoundaryChars";
case Error::Compression: return "Compression";
case Error::Unknown: return "Unknown";
default: break;
}
return "Invalid"; std::ostream &operator<<(std::ostream &os, const Error &obj);
}
inline std::ostream &operator<<(std::ostream &os, const Error &obj) {
os << to_string(obj);
os << " (" << static_cast<std::underlying_type<Error>::type>(obj) << ')';
return os;
}
class Result { class Result {
public: public:
@ -1546,6 +1506,24 @@ inline ssize_t Stream::write_format(const char *fmt, const Args &... args) {
} }
} }
inline void default_socket_options(socket_t sock) {
int yes = 1;
#ifdef _WIN32
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<char *>(&yes),
sizeof(yes));
setsockopt(sock, SOL_SOCKET, SO_EXCLUSIVEADDRUSE,
reinterpret_cast<char *>(&yes), sizeof(yes));
#else
#ifdef SO_REUSEPORT
setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, reinterpret_cast<void *>(&yes),
sizeof(yes));
#else
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<void *>(&yes),
sizeof(yes));
#endif
#endif
}
template <class Rep, class Period> template <class Rep, class Period>
inline Server & inline Server &
Server::set_read_timeout(const std::chrono::duration<Rep, Period> &duration) { Server::set_read_timeout(const std::chrono::duration<Rep, Period> &duration) {
@ -1570,6 +1548,34 @@ Server::set_idle_interval(const std::chrono::duration<Rep, Period> &duration) {
return *this; return *this;
} }
inline std::string to_string(const Error error) {
switch (error) {
case Error::Success: return "Success";
case Error::Connection: return "Connection";
case Error::BindIPAddress: return "BindIPAddress";
case Error::Read: return "Read";
case Error::Write: return "Write";
case Error::ExceedRedirectCount: return "ExceedRedirectCount";
case Error::Canceled: return "Canceled";
case Error::SSLConnection: return "SSLConnection";
case Error::SSLLoadingCerts: return "SSLLoadingCerts";
case Error::SSLServerVerification: return "SSLServerVerification";
case Error::UnsupportedMultipartBoundaryChars:
return "UnsupportedMultipartBoundaryChars";
case Error::Compression: return "Compression";
case Error::Unknown: return "Unknown";
default: break;
}
return "Invalid";
}
inline std::ostream &operator<<(std::ostream &os, const Error &obj) {
os << to_string(obj);
os << " (" << static_cast<std::underlying_type<Error>::type>(obj) << ')';
return os;
}
template <typename T> template <typename T>
inline T Result::get_request_header_value(const char *key, size_t id) const { inline T Result::get_request_header_value(const char *key, size_t id) const {
return detail::get_header_value<T>(request_headers_, key, id, 0); return detail::get_header_value<T>(request_headers_, key, id, 0);
@ -1620,6 +1626,8 @@ Client::set_write_timeout(const std::chrono::duration<Rep, Period> &duration) {
* .h + .cc. * .h + .cc.
*/ */
std::string append_query_params(const char *path, const Params &params);
std::pair<std::string, std::string> make_range_header(Ranges ranges); std::pair<std::string, std::string> make_range_header(Ranges ranges);
std::pair<std::string, std::string> std::pair<std::string, std::string>
@ -3503,14 +3511,6 @@ inline std::string params_to_query_str(const Params &params) {
return query; return query;
} }
inline std::string append_query_params(const char *path, const Params &params) {
std::string path_with_query = path;
const static std::regex re("[^?]+\\?.*");
auto delm = std::regex_match(path, re) ? '&' : '?';
path_with_query += delm + params_to_query_str(params);
return path_with_query;
}
inline void parse_query_text(const std::string &s, Params &params) { inline void parse_query_text(const std::string &s, Params &params) {
std::set<std::string> cache; std::set<std::string> cache;
split(s.data(), s.data() + s.size(), '&', [&](const char *b, const char *e) { split(s.data(), s.data() + s.size(), '&', [&](const char *b, const char *e) {
@ -4144,6 +4144,14 @@ private:
} // namespace detail } // namespace detail
inline std::string append_query_params(const char *path, const Params &params) {
std::string path_with_query = path;
const static std::regex re("[^?]+\\?.*");
auto delm = std::regex_match(path, re) ? '&' : '?';
path_with_query += delm + detail::params_to_query_str(params);
return path_with_query;
}
// Header utilities // Header utilities
inline std::pair<std::string, std::string> make_range_header(Ranges ranges) { inline std::pair<std::string, std::string> make_range_header(Ranges ranges) {
std::string field = "bytes="; std::string field = "bytes=";
@ -6237,7 +6245,7 @@ inline Result ClientImpl::Get(const char *path, const Params &params,
const Headers &headers, Progress progress) { const Headers &headers, Progress progress) {
if (params.empty()) { return Get(path, headers); } if (params.empty()) { return Get(path, headers); }
std::string path_with_query = detail::append_query_params(path, params); std::string path_with_query = append_query_params(path, params);
return Get(path_with_query.c_str(), headers, progress); return Get(path_with_query.c_str(), headers, progress);
} }
@ -6257,7 +6265,7 @@ inline Result ClientImpl::Get(const char *path, const Params &params,
return Get(path, headers, response_handler, content_receiver, progress); return Get(path, headers, response_handler, content_receiver, progress);
} }
std::string path_with_query = detail::append_query_params(path, params); std::string path_with_query = append_query_params(path, params);
return Get(path_with_query.c_str(), headers, response_handler, return Get(path_with_query.c_str(), headers, response_handler,
content_receiver, progress); content_receiver, progress);
} }