mirror of
https://github.com/yhirose/cpp-httplib
synced 2024-11-21 14:29:10 -07:00
Fixed #1031
This commit is contained in:
parent
1cc6930363
commit
0823d5c7f2
1 changed files with 61 additions and 53 deletions
114
httplib.h
114
httplib.h
|
@ -582,23 +582,7 @@ using Logger = std::function<void(const Request &, const Response &)>;
|
|||
|
||||
using SocketOptions = std::function<void(socket_t sock)>;
|
||||
|
||||
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
|
||||
}
|
||||
void default_socket_options(socket_t sock);
|
||||
|
||||
class Server {
|
||||
public:
|
||||
|
@ -800,33 +784,9 @@ enum class Error {
|
|||
Compression,
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
std::string to_string(const Error error);
|
||||
|
||||
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;
|
||||
}
|
||||
std::ostream &operator<<(std::ostream &os, const Error &obj);
|
||||
|
||||
class Result {
|
||||
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>
|
||||
inline Server &
|
||||
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;
|
||||
}
|
||||
|
||||
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>
|
||||
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);
|
||||
|
@ -1620,6 +1626,8 @@ Client::set_write_timeout(const std::chrono::duration<Rep, Period> &duration) {
|
|||
* .h + .cc.
|
||||
*/
|
||||
|
||||
std::string append_query_params(const char *path, const Params ¶ms);
|
||||
|
||||
std::pair<std::string, std::string> make_range_header(Ranges ranges);
|
||||
|
||||
std::pair<std::string, std::string>
|
||||
|
@ -3503,14 +3511,6 @@ inline std::string params_to_query_str(const Params ¶ms) {
|
|||
return query;
|
||||
}
|
||||
|
||||
inline std::string append_query_params(const char *path, const Params ¶ms) {
|
||||
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 ¶ms) {
|
||||
std::set<std::string> cache;
|
||||
split(s.data(), s.data() + s.size(), '&', [&](const char *b, const char *e) {
|
||||
|
@ -4144,6 +4144,14 @@ private:
|
|||
|
||||
} // namespace detail
|
||||
|
||||
inline std::string append_query_params(const char *path, const Params ¶ms) {
|
||||
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
|
||||
inline std::pair<std::string, std::string> make_range_header(Ranges ranges) {
|
||||
std::string field = "bytes=";
|
||||
|
@ -6237,7 +6245,7 @@ inline Result ClientImpl::Get(const char *path, const Params ¶ms,
|
|||
const Headers &headers, Progress progress) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -6257,7 +6265,7 @@ inline Result ClientImpl::Get(const char *path, const Params ¶ms,
|
|||
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,
|
||||
content_receiver, progress);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue