Added set_read_timeout. Fix #248.
This commit is contained in:
parent
5f32c424c2
commit
f0b1b5dbfd
191
httplib.h
191
httplib.h
@ -326,7 +326,8 @@ public:
|
|||||||
|
|
||||||
class SocketStream : public Stream {
|
class SocketStream : public Stream {
|
||||||
public:
|
public:
|
||||||
SocketStream(socket_t sock);
|
SocketStream(socket_t sock, time_t read_timeout_sec,
|
||||||
|
time_t read_timeout_usec);
|
||||||
virtual ~SocketStream();
|
virtual ~SocketStream();
|
||||||
|
|
||||||
virtual int read(char *ptr, size_t size);
|
virtual int read(char *ptr, size_t size);
|
||||||
@ -337,6 +338,8 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
socket_t sock_;
|
socket_t sock_;
|
||||||
|
time_t read_timeout_sec_;
|
||||||
|
time_t read_timeout_usec_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class BufferStream : public Stream {
|
class BufferStream : public Stream {
|
||||||
@ -497,6 +500,7 @@ public:
|
|||||||
void set_logger(Logger logger);
|
void set_logger(Logger logger);
|
||||||
|
|
||||||
void set_keep_alive_max_count(size_t count);
|
void set_keep_alive_max_count(size_t count);
|
||||||
|
void set_read_timeout(time_t sec, time_t usec);
|
||||||
void set_payload_max_length(size_t length);
|
void set_payload_max_length(size_t length);
|
||||||
|
|
||||||
bool bind_to_port(const char *host, int port, int socket_flags = 0);
|
bool bind_to_port(const char *host, int port, int socket_flags = 0);
|
||||||
@ -516,6 +520,8 @@ protected:
|
|||||||
std::function<void(Request &)> setup_request);
|
std::function<void(Request &)> setup_request);
|
||||||
|
|
||||||
size_t keep_alive_max_count_;
|
size_t keep_alive_max_count_;
|
||||||
|
time_t read_timeout_sec_;
|
||||||
|
time_t read_timeout_usec_;
|
||||||
size_t payload_max_length_;
|
size_t payload_max_length_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -605,8 +611,7 @@ public:
|
|||||||
const char *content_type,
|
const char *content_type,
|
||||||
bool compress = false);
|
bool compress = false);
|
||||||
|
|
||||||
std::shared_ptr<Response> Post(const char *path,
|
std::shared_ptr<Response> Post(const char *path, size_t content_length,
|
||||||
size_t content_length,
|
|
||||||
ContentProvider content_provider,
|
ContentProvider content_provider,
|
||||||
const char *content_type,
|
const char *content_type,
|
||||||
bool compress = false);
|
bool compress = false);
|
||||||
@ -640,8 +645,7 @@ public:
|
|||||||
const char *content_type,
|
const char *content_type,
|
||||||
bool compress = false);
|
bool compress = false);
|
||||||
|
|
||||||
std::shared_ptr<Response> Put(const char *path,
|
std::shared_ptr<Response> Put(const char *path, size_t content_length,
|
||||||
size_t content_length,
|
|
||||||
ContentProvider content_provider,
|
ContentProvider content_provider,
|
||||||
const char *content_type,
|
const char *content_type,
|
||||||
bool compress = false);
|
bool compress = false);
|
||||||
@ -661,8 +665,7 @@ public:
|
|||||||
const char *content_type,
|
const char *content_type,
|
||||||
bool compress = false);
|
bool compress = false);
|
||||||
|
|
||||||
std::shared_ptr<Response> Patch(const char *path,
|
std::shared_ptr<Response> Patch(const char *path, size_t content_length,
|
||||||
size_t content_length,
|
|
||||||
ContentProvider content_provider,
|
ContentProvider content_provider,
|
||||||
const char *content_type,
|
const char *content_type,
|
||||||
bool compress = false);
|
bool compress = false);
|
||||||
@ -694,6 +697,7 @@ public:
|
|||||||
std::vector<Response> &responses);
|
std::vector<Response> &responses);
|
||||||
|
|
||||||
void set_keep_alive_max_count(size_t count);
|
void set_keep_alive_max_count(size_t count);
|
||||||
|
void set_read_timeout(time_t sec, time_t usec);
|
||||||
|
|
||||||
void follow_location(bool on);
|
void follow_location(bool on);
|
||||||
|
|
||||||
@ -706,6 +710,8 @@ protected:
|
|||||||
time_t timeout_sec_;
|
time_t timeout_sec_;
|
||||||
const std::string host_and_port_;
|
const std::string host_and_port_;
|
||||||
size_t keep_alive_max_count_;
|
size_t keep_alive_max_count_;
|
||||||
|
time_t read_timeout_sec_;
|
||||||
|
time_t read_timeout_usec_;
|
||||||
size_t follow_location_;
|
size_t follow_location_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -714,10 +720,9 @@ private:
|
|||||||
void write_request(Stream &strm, const Request &req, bool last_connection);
|
void write_request(Stream &strm, const Request &req, bool last_connection);
|
||||||
bool redirect(const Request &req, Response &res);
|
bool redirect(const Request &req, Response &res);
|
||||||
|
|
||||||
std::shared_ptr<Response> send_with_content_provider(
|
std::shared_ptr<Response>
|
||||||
const char *method,
|
send_with_content_provider(const char *method, const char *path,
|
||||||
const char *path, const Headers &headers,
|
const Headers &headers, const std::string &body,
|
||||||
const std::string& body,
|
|
||||||
size_t content_length,
|
size_t content_length,
|
||||||
ContentProvider content_provider,
|
ContentProvider content_provider,
|
||||||
const char *content_type, bool compress);
|
const char *content_type, bool compress);
|
||||||
@ -764,7 +769,8 @@ inline void Post(std::vector<Request> &requests, const char *path,
|
|||||||
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
||||||
class SSLSocketStream : public Stream {
|
class SSLSocketStream : public Stream {
|
||||||
public:
|
public:
|
||||||
SSLSocketStream(socket_t sock, SSL *ssl);
|
SSLSocketStream(socket_t sock, SSL *ssl, time_t read_timeout_sec,
|
||||||
|
time_t read_timeout_usec);
|
||||||
virtual ~SSLSocketStream();
|
virtual ~SSLSocketStream();
|
||||||
|
|
||||||
virtual int read(char *ptr, size_t size);
|
virtual int read(char *ptr, size_t size);
|
||||||
@ -776,6 +782,8 @@ public:
|
|||||||
private:
|
private:
|
||||||
socket_t sock_;
|
socket_t sock_;
|
||||||
SSL *ssl_;
|
SSL *ssl_;
|
||||||
|
time_t read_timeout_sec_;
|
||||||
|
time_t read_timeout_usec_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SSLServer : public Server {
|
class SSLServer : public Server {
|
||||||
@ -1166,7 +1174,9 @@ inline bool wait_until_socket_is_ready(socket_t sock, time_t sec, time_t usec) {
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline bool process_and_close_socket(bool is_client_request, socket_t sock,
|
inline bool process_and_close_socket(bool is_client_request, socket_t sock,
|
||||||
size_t keep_alive_max_count, T callback) {
|
size_t keep_alive_max_count,
|
||||||
|
time_t read_timeout_sec,
|
||||||
|
time_t read_timeout_usec, T callback) {
|
||||||
assert(keep_alive_max_count > 0);
|
assert(keep_alive_max_count > 0);
|
||||||
|
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
@ -1177,7 +1187,7 @@ inline bool process_and_close_socket(bool is_client_request, socket_t sock,
|
|||||||
(is_client_request ||
|
(is_client_request ||
|
||||||
detail::select_read(sock, CPPHTTPLIB_KEEPALIVE_TIMEOUT_SECOND,
|
detail::select_read(sock, CPPHTTPLIB_KEEPALIVE_TIMEOUT_SECOND,
|
||||||
CPPHTTPLIB_KEEPALIVE_TIMEOUT_USECOND) > 0)) {
|
CPPHTTPLIB_KEEPALIVE_TIMEOUT_USECOND) > 0)) {
|
||||||
SocketStream strm(sock);
|
SocketStream strm(sock, read_timeout_sec, read_timeout_usec);
|
||||||
auto last_connection = count == 1;
|
auto last_connection = count == 1;
|
||||||
auto connection_close = false;
|
auto connection_close = false;
|
||||||
|
|
||||||
@ -1187,7 +1197,7 @@ inline bool process_and_close_socket(bool is_client_request, socket_t sock,
|
|||||||
count--;
|
count--;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
SocketStream strm(sock);
|
SocketStream strm(sock, read_timeout_sec, read_timeout_usec);
|
||||||
auto dummy_connection_close = false;
|
auto dummy_connection_close = false;
|
||||||
ret = callback(strm, true, dummy_connection_close);
|
ret = callback(strm, true, dummy_connection_close);
|
||||||
}
|
}
|
||||||
@ -1655,7 +1665,8 @@ inline int write_headers(Stream &strm, const T &info, const Headers &headers) {
|
|||||||
return write_len;
|
return write_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline ssize_t write_content(Stream &strm, ContentProviderWithCloser content_provider,
|
inline ssize_t write_content(Stream &strm,
|
||||||
|
ContentProviderWithCloser content_provider,
|
||||||
size_t offset, size_t length) {
|
size_t offset, size_t length) {
|
||||||
size_t begin_offset = offset;
|
size_t begin_offset = offset;
|
||||||
size_t end_offset = offset + length;
|
size_t end_offset = offset + length;
|
||||||
@ -1673,7 +1684,8 @@ inline ssize_t write_content(Stream &strm, ContentProviderWithCloser content_pro
|
|||||||
return static_cast<ssize_t>(offset - begin_offset);
|
return static_cast<ssize_t>(offset - begin_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline ssize_t write_content_chunked(Stream &strm,
|
inline ssize_t
|
||||||
|
write_content_chunked(Stream &strm,
|
||||||
ContentProviderWithCloser content_provider) {
|
ContentProviderWithCloser content_provider) {
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
auto data_available = true;
|
auto data_available = true;
|
||||||
@ -2245,13 +2257,15 @@ inline int Stream::write_format(const char *fmt, const Args &... args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Socket stream implementation
|
// Socket stream implementation
|
||||||
inline SocketStream::SocketStream(socket_t sock) : sock_(sock) {}
|
inline SocketStream::SocketStream(socket_t sock, time_t read_timeout_sec,
|
||||||
|
time_t read_timeout_usec)
|
||||||
|
: sock_(sock), read_timeout_sec_(read_timeout_sec),
|
||||||
|
read_timeout_usec_(read_timeout_usec) {}
|
||||||
|
|
||||||
inline SocketStream::~SocketStream() {}
|
inline SocketStream::~SocketStream() {}
|
||||||
|
|
||||||
inline int SocketStream::read(char *ptr, size_t size) {
|
inline int SocketStream::read(char *ptr, size_t size) {
|
||||||
if (detail::select_read(sock_, CPPHTTPLIB_READ_TIMEOUT_SECOND,
|
if (detail::select_read(sock_, read_timeout_sec_, read_timeout_usec_) > 0) {
|
||||||
CPPHTTPLIB_READ_TIMEOUT_USECOND) > 0) {
|
|
||||||
return recv(sock_, ptr, static_cast<int>(size), 0);
|
return recv(sock_, ptr, static_cast<int>(size), 0);
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
@ -2302,6 +2316,8 @@ inline const std::string &BufferStream::get_buffer() const { return buffer; }
|
|||||||
// HTTP server implementation
|
// HTTP server implementation
|
||||||
inline Server::Server()
|
inline Server::Server()
|
||||||
: keep_alive_max_count_(CPPHTTPLIB_KEEPALIVE_MAX_COUNT),
|
: keep_alive_max_count_(CPPHTTPLIB_KEEPALIVE_MAX_COUNT),
|
||||||
|
read_timeout_sec_(CPPHTTPLIB_READ_TIMEOUT_SECOND),
|
||||||
|
read_timeout_usec_(CPPHTTPLIB_READ_TIMEOUT_USECOND),
|
||||||
payload_max_length_(CPPHTTPLIB_PAYLOAD_MAX_LENGTH), is_running_(false),
|
payload_max_length_(CPPHTTPLIB_PAYLOAD_MAX_LENGTH), is_running_(false),
|
||||||
svr_sock_(INVALID_SOCKET) {
|
svr_sock_(INVALID_SOCKET) {
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
@ -2370,6 +2386,11 @@ inline void Server::set_keep_alive_max_count(size_t count) {
|
|||||||
keep_alive_max_count_ = count;
|
keep_alive_max_count_ = count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void Server::set_read_timeout(time_t sec, time_t usec) {
|
||||||
|
read_timeout_sec_ = sec;
|
||||||
|
read_timeout_usec_ = usec;
|
||||||
|
}
|
||||||
|
|
||||||
inline void Server::set_payload_max_length(size_t length) {
|
inline void Server::set_payload_max_length(size_t length) {
|
||||||
payload_max_length_ = length;
|
payload_max_length_ = length;
|
||||||
}
|
}
|
||||||
@ -2472,8 +2493,8 @@ inline bool Server::write_response(Stream &strm, bool last_connection,
|
|||||||
if (req.ranges.empty()) {
|
if (req.ranges.empty()) {
|
||||||
length = res.content_length;
|
length = res.content_length;
|
||||||
} else if (req.ranges.size() == 1) {
|
} else if (req.ranges.size() == 1) {
|
||||||
auto offsets = detail::get_range_offset_and_length(
|
auto offsets =
|
||||||
req, res.content_length, 0);
|
detail::get_range_offset_and_length(req, res.content_length, 0);
|
||||||
auto offset = offsets.first;
|
auto offset = offsets.first;
|
||||||
length = offsets.second;
|
length = offsets.second;
|
||||||
auto content_range = detail::make_content_range_header_field(
|
auto content_range = detail::make_content_range_header_field(
|
||||||
@ -2554,8 +2575,8 @@ Server::write_content_with_provider(Stream &strm, const Request &req,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (req.ranges.size() == 1) {
|
} else if (req.ranges.size() == 1) {
|
||||||
auto offsets = detail::get_range_offset_and_length(
|
auto offsets =
|
||||||
req, res.content_length, 0);
|
detail::get_range_offset_and_length(req, res.content_length, 0);
|
||||||
auto offset = offsets.first;
|
auto offset = offsets.first;
|
||||||
auto length = offsets.second;
|
auto length = offsets.second;
|
||||||
if (detail::write_content(strm, res.content_provider, offset, length) <
|
if (detail::write_content(strm, res.content_provider, offset, length) <
|
||||||
@ -2812,7 +2833,7 @@ inline bool Server::is_valid() const { return true; }
|
|||||||
|
|
||||||
inline bool Server::process_and_close_socket(socket_t sock) {
|
inline bool Server::process_and_close_socket(socket_t sock) {
|
||||||
return detail::process_and_close_socket(
|
return detail::process_and_close_socket(
|
||||||
false, sock, keep_alive_max_count_,
|
false, sock, keep_alive_max_count_, read_timeout_sec_, read_timeout_usec_,
|
||||||
[this](Stream &strm, bool last_connection, bool &connection_close) {
|
[this](Stream &strm, bool last_connection, bool &connection_close) {
|
||||||
return process_request(strm, last_connection, connection_close,
|
return process_request(strm, last_connection, connection_close,
|
||||||
nullptr);
|
nullptr);
|
||||||
@ -2824,6 +2845,8 @@ inline Client::Client(const char *host, int port, time_t timeout_sec)
|
|||||||
: host_(host), port_(port), timeout_sec_(timeout_sec),
|
: host_(host), port_(port), timeout_sec_(timeout_sec),
|
||||||
host_and_port_(host_ + ":" + std::to_string(port_)),
|
host_and_port_(host_ + ":" + std::to_string(port_)),
|
||||||
keep_alive_max_count_(CPPHTTPLIB_KEEPALIVE_MAX_COUNT),
|
keep_alive_max_count_(CPPHTTPLIB_KEEPALIVE_MAX_COUNT),
|
||||||
|
read_timeout_sec_(CPPHTTPLIB_READ_TIMEOUT_SECOND),
|
||||||
|
read_timeout_usec_(CPPHTTPLIB_READ_TIMEOUT_USECOND),
|
||||||
follow_location_(false) {}
|
follow_location_(false) {}
|
||||||
|
|
||||||
inline Client::~Client() {}
|
inline Client::~Client() {}
|
||||||
@ -3027,8 +3050,7 @@ inline void Client::write_request(Stream &strm, const Request &req,
|
|||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
size_t end_offset = req.content_length;
|
size_t end_offset = req.content_length;
|
||||||
while (offset < end_offset) {
|
while (offset < end_offset) {
|
||||||
req.content_provider(
|
req.content_provider(offset, end_offset - offset,
|
||||||
offset, end_offset - offset,
|
|
||||||
[&](const char *d, size_t l) {
|
[&](const char *d, size_t l) {
|
||||||
auto written_length = strm.write(d, l);
|
auto written_length = strm.write(d, l);
|
||||||
offset += written_length;
|
offset += written_length;
|
||||||
@ -3040,14 +3062,10 @@ inline void Client::write_request(Stream &strm, const Request &req,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::shared_ptr<Response>
|
inline std::shared_ptr<Response> Client::send_with_content_provider(
|
||||||
Client::send_with_content_provider(
|
const char *method, const char *path, const Headers &headers,
|
||||||
const char *method,
|
const std::string &body, size_t content_length,
|
||||||
const char *path, const Headers &headers,
|
ContentProvider content_provider, const char *content_type, bool compress) {
|
||||||
const std::string& body,
|
|
||||||
size_t content_length,
|
|
||||||
ContentProvider content_provider,
|
|
||||||
const char *content_type, bool compress) {
|
|
||||||
|
|
||||||
Request req;
|
Request req;
|
||||||
req.method = method;
|
req.method = method;
|
||||||
@ -3061,9 +3079,7 @@ Client::send_with_content_provider(
|
|||||||
if (content_provider) {
|
if (content_provider) {
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
while (offset < content_length) {
|
while (offset < content_length) {
|
||||||
content_provider(
|
content_provider(offset, content_length - offset,
|
||||||
offset,
|
|
||||||
content_length - offset,
|
|
||||||
[&](const char *data, size_t data_len) {
|
[&](const char *data, size_t data_len) {
|
||||||
req.body.append(data, data_len);
|
req.body.append(data, data_len);
|
||||||
offset += data_len;
|
offset += data_len;
|
||||||
@ -3075,8 +3091,7 @@ Client::send_with_content_provider(
|
|||||||
|
|
||||||
if (!detail::compress(req.body)) { return nullptr; }
|
if (!detail::compress(req.body)) { return nullptr; }
|
||||||
req.headers.emplace("Content-Encoding", "gzip");
|
req.headers.emplace("Content-Encoding", "gzip");
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
if (content_provider) {
|
if (content_provider) {
|
||||||
@ -3148,7 +3163,9 @@ inline bool Client::process_and_close_socket(
|
|||||||
bool &connection_close)>
|
bool &connection_close)>
|
||||||
callback) {
|
callback) {
|
||||||
request_count = std::min(request_count, keep_alive_max_count_);
|
request_count = std::min(request_count, keep_alive_max_count_);
|
||||||
return detail::process_and_close_socket(true, sock, request_count, callback);
|
return detail::process_and_close_socket(true, sock, request_count,
|
||||||
|
read_timeout_sec_, read_timeout_usec_,
|
||||||
|
callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool Client::is_ssl() const { return false; }
|
inline bool Client::is_ssl() const { return false; }
|
||||||
@ -3258,8 +3275,8 @@ inline std::shared_ptr<Response> Client::Post(const char *path,
|
|||||||
inline std::shared_ptr<Response>
|
inline std::shared_ptr<Response>
|
||||||
Client::Post(const char *path, const Headers &headers, const std::string &body,
|
Client::Post(const char *path, const Headers &headers, const std::string &body,
|
||||||
const char *content_type, bool compress) {
|
const char *content_type, bool compress) {
|
||||||
return send_with_content_provider(
|
return send_with_content_provider("POST", path, headers, body, 0, nullptr,
|
||||||
"POST", path, headers, body, 0, nullptr, content_type, compress);
|
content_type, compress);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::shared_ptr<Response>
|
inline std::shared_ptr<Response>
|
||||||
@ -3272,16 +3289,17 @@ inline std::shared_ptr<Response> Client::Post(const char *path,
|
|||||||
ContentProvider content_provider,
|
ContentProvider content_provider,
|
||||||
const char *content_type,
|
const char *content_type,
|
||||||
bool compress) {
|
bool compress) {
|
||||||
return Post(path, Headers(), content_length, content_provider, content_type, compress);
|
return Post(path, Headers(), content_length, content_provider, content_type,
|
||||||
|
compress);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::shared_ptr<Response>
|
inline std::shared_ptr<Response>
|
||||||
Client::Post(const char *path, const Headers &headers,
|
Client::Post(const char *path, const Headers &headers, size_t content_length,
|
||||||
size_t content_length,
|
ContentProvider content_provider, const char *content_type,
|
||||||
ContentProvider content_provider,
|
bool compress) {
|
||||||
const char *content_type, bool compress) {
|
return send_with_content_provider("POST", path, headers, std::string(),
|
||||||
return send_with_content_provider(
|
content_length, content_provider,
|
||||||
"POST", path, headers, std::string(), content_length, content_provider, content_type, compress);
|
content_type, compress);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::shared_ptr<Response> Client::Post(const char *path,
|
inline std::shared_ptr<Response> Client::Post(const char *path,
|
||||||
@ -3343,8 +3361,8 @@ inline std::shared_ptr<Response> Client::Put(const char *path,
|
|||||||
inline std::shared_ptr<Response>
|
inline std::shared_ptr<Response>
|
||||||
Client::Put(const char *path, const Headers &headers, const std::string &body,
|
Client::Put(const char *path, const Headers &headers, const std::string &body,
|
||||||
const char *content_type, bool compress) {
|
const char *content_type, bool compress) {
|
||||||
return send_with_content_provider(
|
return send_with_content_provider("PUT", path, headers, body, 0, nullptr,
|
||||||
"PUT", path, headers, body, 0, nullptr, content_type, compress);
|
content_type, compress);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::shared_ptr<Response> Client::Put(const char *path,
|
inline std::shared_ptr<Response> Client::Put(const char *path,
|
||||||
@ -3352,16 +3370,17 @@ inline std::shared_ptr<Response> Client::Put(const char *path,
|
|||||||
ContentProvider content_provider,
|
ContentProvider content_provider,
|
||||||
const char *content_type,
|
const char *content_type,
|
||||||
bool compress) {
|
bool compress) {
|
||||||
return Put(path, Headers(), content_length, content_provider, content_type, compress);
|
return Put(path, Headers(), content_length, content_provider, content_type,
|
||||||
|
compress);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::shared_ptr<Response>
|
inline std::shared_ptr<Response>
|
||||||
Client::Put(const char *path, const Headers &headers,
|
Client::Put(const char *path, const Headers &headers, size_t content_length,
|
||||||
size_t content_length,
|
ContentProvider content_provider, const char *content_type,
|
||||||
ContentProvider content_provider,
|
bool compress) {
|
||||||
const char *content_type, bool compress) {
|
return send_with_content_provider("PUT", path, headers, std::string(),
|
||||||
return send_with_content_provider(
|
content_length, content_provider,
|
||||||
"PUT", path, headers, std::string(), content_length, content_provider, content_type, compress);
|
content_type, compress);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::shared_ptr<Response> Client::Patch(const char *path,
|
inline std::shared_ptr<Response> Client::Patch(const char *path,
|
||||||
@ -3374,8 +3393,8 @@ inline std::shared_ptr<Response> Client::Patch(const char *path,
|
|||||||
inline std::shared_ptr<Response>
|
inline std::shared_ptr<Response>
|
||||||
Client::Patch(const char *path, const Headers &headers, const std::string &body,
|
Client::Patch(const char *path, const Headers &headers, const std::string &body,
|
||||||
const char *content_type, bool compress) {
|
const char *content_type, bool compress) {
|
||||||
return send_with_content_provider(
|
return send_with_content_provider("PATCH", path, headers, body, 0, nullptr,
|
||||||
"PATCH", path, headers, body, 0, nullptr, content_type, compress);
|
content_type, compress);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::shared_ptr<Response> Client::Patch(const char *path,
|
inline std::shared_ptr<Response> Client::Patch(const char *path,
|
||||||
@ -3383,16 +3402,17 @@ inline std::shared_ptr<Response> Client::Patch(const char *path,
|
|||||||
ContentProvider content_provider,
|
ContentProvider content_provider,
|
||||||
const char *content_type,
|
const char *content_type,
|
||||||
bool compress) {
|
bool compress) {
|
||||||
return Patch(path, Headers(), content_length, content_provider, content_type, compress);
|
return Patch(path, Headers(), content_length, content_provider, content_type,
|
||||||
|
compress);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::shared_ptr<Response>
|
inline std::shared_ptr<Response>
|
||||||
Client::Patch(const char *path, const Headers &headers,
|
Client::Patch(const char *path, const Headers &headers, size_t content_length,
|
||||||
size_t content_length,
|
ContentProvider content_provider, const char *content_type,
|
||||||
ContentProvider content_provider,
|
bool compress) {
|
||||||
const char *content_type, bool compress) {
|
return send_with_content_provider("PATCH", path, headers, std::string(),
|
||||||
return send_with_content_provider(
|
content_length, content_provider,
|
||||||
"PATCH", path, headers, std::string(), content_length, content_provider, content_type, compress);
|
content_type, compress);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::shared_ptr<Response> Client::Delete(const char *path) {
|
inline std::shared_ptr<Response> Client::Delete(const char *path) {
|
||||||
@ -3447,6 +3467,11 @@ inline void Client::set_keep_alive_max_count(size_t count) {
|
|||||||
keep_alive_max_count_ = count;
|
keep_alive_max_count_ = count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void Client::set_read_timeout(time_t sec, time_t usec) {
|
||||||
|
read_timeout_sec_ = sec;
|
||||||
|
read_timeout_usec_ = usec;
|
||||||
|
}
|
||||||
|
|
||||||
inline void Client::follow_location(bool on) { follow_location_ = on; }
|
inline void Client::follow_location(bool on) { follow_location_ = on; }
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3456,11 +3481,10 @@ inline void Client::follow_location(bool on) { follow_location_ = on; }
|
|||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
template <typename U, typename V, typename T>
|
template <typename U, typename V, typename T>
|
||||||
inline bool process_and_close_socket_ssl(bool is_client_request, socket_t sock,
|
inline bool process_and_close_socket_ssl(
|
||||||
size_t keep_alive_max_count,
|
bool is_client_request, socket_t sock, size_t keep_alive_max_count,
|
||||||
SSL_CTX *ctx, std::mutex &ctx_mutex,
|
time_t read_timeout_sec, time_t read_timeout_usec, SSL_CTX *ctx,
|
||||||
U SSL_connect_or_accept, V setup,
|
std::mutex &ctx_mutex, U SSL_connect_or_accept, V setup, T callback) {
|
||||||
T callback) {
|
|
||||||
assert(keep_alive_max_count > 0);
|
assert(keep_alive_max_count > 0);
|
||||||
|
|
||||||
SSL *ssl = nullptr;
|
SSL *ssl = nullptr;
|
||||||
@ -3497,7 +3521,7 @@ inline bool process_and_close_socket_ssl(bool is_client_request, socket_t sock,
|
|||||||
(is_client_request ||
|
(is_client_request ||
|
||||||
detail::select_read(sock, CPPHTTPLIB_KEEPALIVE_TIMEOUT_SECOND,
|
detail::select_read(sock, CPPHTTPLIB_KEEPALIVE_TIMEOUT_SECOND,
|
||||||
CPPHTTPLIB_KEEPALIVE_TIMEOUT_USECOND) > 0)) {
|
CPPHTTPLIB_KEEPALIVE_TIMEOUT_USECOND) > 0)) {
|
||||||
SSLSocketStream strm(sock, ssl);
|
SSLSocketStream strm(sock, ssl, read_timeout_sec, read_timeout_usec);
|
||||||
auto last_connection = count == 1;
|
auto last_connection = count == 1;
|
||||||
auto connection_close = false;
|
auto connection_close = false;
|
||||||
|
|
||||||
@ -3507,7 +3531,7 @@ inline bool process_and_close_socket_ssl(bool is_client_request, socket_t sock,
|
|||||||
count--;
|
count--;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
SSLSocketStream strm(sock, ssl);
|
SSLSocketStream strm(sock, ssl, read_timeout_sec, read_timeout_usec);
|
||||||
auto dummy_connection_close = false;
|
auto dummy_connection_close = false;
|
||||||
ret = callback(ssl, strm, true, dummy_connection_close);
|
ret = callback(ssl, strm, true, dummy_connection_close);
|
||||||
}
|
}
|
||||||
@ -3580,15 +3604,17 @@ static SSLInit sslinit_;
|
|||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
// SSL socket stream implementation
|
// SSL socket stream implementation
|
||||||
inline SSLSocketStream::SSLSocketStream(socket_t sock, SSL *ssl)
|
inline SSLSocketStream::SSLSocketStream(socket_t sock, SSL *ssl,
|
||||||
: sock_(sock), ssl_(ssl) {}
|
time_t read_timeout_sec,
|
||||||
|
time_t read_timeout_usec)
|
||||||
|
: sock_(sock), ssl_(ssl), read_timeout_sec_(read_timeout_sec),
|
||||||
|
read_timeout_usec_(read_timeout_usec) {}
|
||||||
|
|
||||||
inline SSLSocketStream::~SSLSocketStream() {}
|
inline SSLSocketStream::~SSLSocketStream() {}
|
||||||
|
|
||||||
inline int SSLSocketStream::read(char *ptr, size_t size) {
|
inline int SSLSocketStream::read(char *ptr, size_t size) {
|
||||||
if (SSL_pending(ssl_) > 0 ||
|
if (SSL_pending(ssl_) > 0 ||
|
||||||
detail::select_read(sock_, CPPHTTPLIB_READ_TIMEOUT_SECOND,
|
detail::select_read(sock_, read_timeout_sec_, read_timeout_usec_) > 0) {
|
||||||
CPPHTTPLIB_READ_TIMEOUT_USECOND) > 0) {
|
|
||||||
return SSL_read(ssl_, ptr, static_cast<int>(size));
|
return SSL_read(ssl_, ptr, static_cast<int>(size));
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
@ -3657,8 +3683,8 @@ inline bool SSLServer::is_valid() const { return ctx_; }
|
|||||||
|
|
||||||
inline bool SSLServer::process_and_close_socket(socket_t sock) {
|
inline bool SSLServer::process_and_close_socket(socket_t sock) {
|
||||||
return detail::process_and_close_socket_ssl(
|
return detail::process_and_close_socket_ssl(
|
||||||
false, sock, keep_alive_max_count_, ctx_, ctx_mutex_, SSL_accept,
|
false, sock, keep_alive_max_count_, read_timeout_sec_, read_timeout_usec_,
|
||||||
[](SSL * /*ssl*/) { return true; },
|
ctx_, ctx_mutex_, SSL_accept, [](SSL * /*ssl*/) { return true; },
|
||||||
[this](SSL *ssl, Stream &strm, bool last_connection,
|
[this](SSL *ssl, Stream &strm, bool last_connection,
|
||||||
bool &connection_close) {
|
bool &connection_close) {
|
||||||
return process_request(strm, last_connection, connection_close,
|
return process_request(strm, last_connection, connection_close,
|
||||||
@ -3720,7 +3746,8 @@ inline bool SSLClient::process_and_close_socket(
|
|||||||
|
|
||||||
return is_valid() &&
|
return is_valid() &&
|
||||||
detail::process_and_close_socket_ssl(
|
detail::process_and_close_socket_ssl(
|
||||||
true, sock, request_count, ctx_, ctx_mutex_,
|
true, sock, request_count, read_timeout_sec_, read_timeout_usec_,
|
||||||
|
ctx_, ctx_mutex_,
|
||||||
[&](SSL *ssl) {
|
[&](SSL *ssl) {
|
||||||
if (ca_cert_file_path_.empty()) {
|
if (ca_cert_file_path_.empty()) {
|
||||||
SSL_CTX_set_verify(ctx_, SSL_VERIFY_NONE, nullptr);
|
SSL_CTX_set_verify(ctx_, SSL_VERIFY_NONE, nullptr);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user