You've already forked cpp-httplib
Resolve #2237
This commit is contained in:
79
httplib.h
79
httplib.h
@@ -1052,6 +1052,9 @@ private:
|
||||
|
||||
ssize_t write_headers(Stream &strm, const Headers &headers);
|
||||
|
||||
std::string make_host_and_port_string(const std::string &host, int port,
|
||||
bool is_ssl);
|
||||
|
||||
} // namespace detail
|
||||
|
||||
class Server {
|
||||
@@ -1719,8 +1722,6 @@ private:
|
||||
const std::string &boundary, const UploadFormDataItems &items,
|
||||
const FormDataProviderItems &provider_items) const;
|
||||
|
||||
std::string adjust_host_string(const std::string &host) const;
|
||||
|
||||
virtual bool
|
||||
process_socket(const Socket &socket,
|
||||
std::chrono::time_point<std::chrono::steady_clock> start_time,
|
||||
@@ -7261,6 +7262,30 @@ inline bool RegexMatcher::match(Request &request) const {
|
||||
return std::regex_match(request.path, request.matches, regex_);
|
||||
}
|
||||
|
||||
inline std::string make_host_and_port_string(const std::string &host, int port,
|
||||
bool is_ssl) {
|
||||
std::string result;
|
||||
|
||||
// Enclose IPv6 address in brackets (but not if already enclosed)
|
||||
if (host.find(':') == std::string::npos ||
|
||||
(!host.empty() && host[0] == '[')) {
|
||||
// IPv4, hostname, or already bracketed IPv6
|
||||
result = host;
|
||||
} else {
|
||||
// IPv6 address without brackets
|
||||
result = "[" + host + "]";
|
||||
}
|
||||
|
||||
// Append port if not default
|
||||
if ((!is_ssl && port == 80) || (is_ssl && port == 443)) {
|
||||
; // do nothing
|
||||
} else {
|
||||
result += ":" + std::to_string(port);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// HTTP server implementation
|
||||
@@ -8522,7 +8547,7 @@ inline ClientImpl::ClientImpl(const std::string &host, int port,
|
||||
const std::string &client_cert_path,
|
||||
const std::string &client_key_path)
|
||||
: host_(detail::escape_abstract_namespace_unix_domain(host)), port_(port),
|
||||
host_and_port_(adjust_host_string(host_) + ":" + std::to_string(port)),
|
||||
host_and_port_(detail::make_host_and_port_string(host_, port, is_ssl())),
|
||||
client_cert_path_(client_cert_path), client_key_path_(client_key_path) {}
|
||||
|
||||
inline ClientImpl::~ClientImpl() {
|
||||
@@ -8703,8 +8728,9 @@ inline bool ClientImpl::send_(Request &req, Response &res, Error &error) {
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(socket_mutex_);
|
||||
|
||||
// Set this to false immediately - if it ever gets set to true by the end of
|
||||
// the request, we know another thread instructed us to close the socket.
|
||||
// Set this to false immediately - if it ever gets set to true by the end
|
||||
// of the request, we know another thread instructed us to close the
|
||||
// socket.
|
||||
socket_should_be_closed_when_request_is_done_ = false;
|
||||
|
||||
auto is_alive = false;
|
||||
@@ -8720,10 +8746,10 @@ inline bool ClientImpl::send_(Request &req, Response &res, Error &error) {
|
||||
#endif
|
||||
|
||||
if (!is_alive) {
|
||||
// Attempt to avoid sigpipe by shutting down non-gracefully if it seems
|
||||
// like the other side has already closed the connection Also, there
|
||||
// cannot be any requests in flight from other threads since we locked
|
||||
// request_mutex_, so safe to close everything immediately
|
||||
// Attempt to avoid sigpipe by shutting down non-gracefully if it
|
||||
// seems like the other side has already closed the connection Also,
|
||||
// there cannot be any requests in flight from other threads since we
|
||||
// locked request_mutex_, so safe to close everything immediately
|
||||
const bool shutdown_gracefully = false;
|
||||
shutdown_ssl(socket_, shutdown_gracefully);
|
||||
shutdown_socket(socket_);
|
||||
@@ -9027,7 +9053,8 @@ inline bool ClientImpl::create_redirect_client(
|
||||
}
|
||||
}
|
||||
|
||||
// New method for robust client setup (based on basic_manual_redirect.cpp logic)
|
||||
// New method for robust client setup (based on basic_manual_redirect.cpp
|
||||
// logic)
|
||||
template <typename ClientType>
|
||||
inline void ClientImpl::setup_redirect_client(ClientType &client) {
|
||||
// Copy basic settings first
|
||||
@@ -9131,18 +9158,8 @@ inline bool ClientImpl::write_request(Stream &strm, Request &req,
|
||||
// curl behavior)
|
||||
if (address_family_ == AF_UNIX) {
|
||||
req.set_header("Host", "localhost");
|
||||
} else if (is_ssl()) {
|
||||
if (port_ == 443) {
|
||||
req.set_header("Host", host_);
|
||||
} else {
|
||||
req.set_header("Host", host_and_port_);
|
||||
}
|
||||
} else {
|
||||
if (port_ == 80) {
|
||||
req.set_header("Host", host_);
|
||||
} else {
|
||||
req.set_header("Host", host_and_port_);
|
||||
}
|
||||
req.set_header("Host", host_and_port_);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9409,12 +9426,6 @@ inline Result ClientImpl::send_with_content_provider(
|
||||
#endif
|
||||
}
|
||||
|
||||
inline std::string
|
||||
ClientImpl::adjust_host_string(const std::string &host) const {
|
||||
if (host.find(':') != std::string::npos) { return "[" + host + "]"; }
|
||||
return host;
|
||||
}
|
||||
|
||||
inline void ClientImpl::output_log(const Request &req,
|
||||
const Response &res) const {
|
||||
if (logger_) {
|
||||
@@ -9538,8 +9549,8 @@ inline ContentProviderWithoutLength ClientImpl::get_multipart_content_provider(
|
||||
const FormDataProviderItems &provider_items) const {
|
||||
size_t cur_item = 0;
|
||||
size_t cur_start = 0;
|
||||
// cur_item and cur_start are copied to within the std::function and maintain
|
||||
// state between successive calls
|
||||
// cur_item and cur_start are copied to within the std::function and
|
||||
// maintain state between successive calls
|
||||
return [&, cur_item, cur_start](size_t offset,
|
||||
DataSink &sink) mutable -> bool {
|
||||
if (!offset && !items.empty()) {
|
||||
@@ -10251,8 +10262,8 @@ inline void ClientImpl::stop() {
|
||||
// If there is anything ongoing right now, the ONLY thread-safe thing we can
|
||||
// do is to shutdown_socket, so that threads using this socket suddenly
|
||||
// discover they can't read/write any more and error out. Everything else
|
||||
// (closing the socket, shutting ssl down) is unsafe because these actions are
|
||||
// not thread-safe.
|
||||
// (closing the socket, shutting ssl down) is unsafe because these actions
|
||||
// are not thread-safe.
|
||||
if (socket_requests_in_flight_ > 0) {
|
||||
shutdown_socket(socket_);
|
||||
|
||||
@@ -10889,7 +10900,8 @@ inline void SSLClient::set_ca_cert_store(X509_STORE *ca_cert_store) {
|
||||
if (ca_cert_store) {
|
||||
if (ctx_) {
|
||||
if (SSL_CTX_get_cert_store(ctx_) != ca_cert_store) {
|
||||
// Free memory allocated for old cert and use new store `ca_cert_store`
|
||||
// Free memory allocated for old cert and use new store
|
||||
// `ca_cert_store`
|
||||
SSL_CTX_set_cert_store(ctx_, ca_cert_store);
|
||||
ca_cert_store_ = ca_cert_store;
|
||||
}
|
||||
@@ -10914,7 +10926,8 @@ inline bool SSLClient::create_and_connect_socket(Socket &socket, Error &error) {
|
||||
return is_valid() && ClientImpl::create_and_connect_socket(socket, error);
|
||||
}
|
||||
|
||||
// Assumes that socket_mutex_ is locked and that there are no requests in flight
|
||||
// Assumes that socket_mutex_ is locked and that there are no requests in
|
||||
// flight
|
||||
inline bool SSLClient::connect_with_proxy(
|
||||
Socket &socket,
|
||||
std::chrono::time_point<std::chrono::steady_clock> start_time,
|
||||
|
||||
Reference in New Issue
Block a user