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)>;
|
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 ¶ms);
|
||||||
|
|
||||||
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 ¶ms) {
|
||||||
return query;
|
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) {
|
inline void parse_query_text(const std::string &s, Params ¶ms) {
|
||||||
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 ¶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
|
// 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 ¶ms,
|
||||||
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 ¶ms,
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue