mirror of
https://github.com/yhirose/cpp-httplib.git
synced 2025-05-10 09:43:51 +00:00
commit
ae43c96984
@ -301,7 +301,7 @@ res = cli.Options("/resource/foo");
|
|||||||
### Connection Timeout
|
### Connection Timeout
|
||||||
|
|
||||||
```c++
|
```c++
|
||||||
httplib::Client cli("localhost", 8080, 5); // timeouts in 5 seconds
|
cli.set_timeout_sec(5); // timeouts in 5 seconds
|
||||||
```
|
```
|
||||||
### With Progress Callback
|
### With Progress Callback
|
||||||
|
|
||||||
|
40
httplib.h
40
httplib.h
@ -614,7 +614,7 @@ private:
|
|||||||
|
|
||||||
class Client {
|
class Client {
|
||||||
public:
|
public:
|
||||||
explicit Client(const char *host, int port = 80, time_t timeout_sec = 300);
|
explicit Client(const char *host, int port = 80);
|
||||||
|
|
||||||
virtual ~Client();
|
virtual ~Client();
|
||||||
|
|
||||||
@ -734,6 +734,8 @@ public:
|
|||||||
bool send(const std::vector<Request> &requests,
|
bool send(const std::vector<Request> &requests,
|
||||||
std::vector<Response> &responses);
|
std::vector<Response> &responses);
|
||||||
|
|
||||||
|
void set_timeout_sec(time_t timeout_sec);
|
||||||
|
|
||||||
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_read_timeout(time_t sec, time_t usec);
|
||||||
@ -752,15 +754,17 @@ protected:
|
|||||||
|
|
||||||
const std::string host_;
|
const std::string host_;
|
||||||
const int port_;
|
const int port_;
|
||||||
time_t timeout_sec_;
|
|
||||||
const std::string host_and_port_;
|
const std::string host_and_port_;
|
||||||
size_t keep_alive_max_count_;
|
|
||||||
time_t read_timeout_sec_;
|
// Options
|
||||||
time_t read_timeout_usec_;
|
time_t timeout_sec_ = 300;
|
||||||
bool follow_location_;
|
size_t keep_alive_max_count_ = CPPHTTPLIB_KEEPALIVE_MAX_COUNT;
|
||||||
|
time_t read_timeout_sec_ = CPPHTTPLIB_READ_TIMEOUT_SECOND;
|
||||||
|
time_t read_timeout_usec_ = CPPHTTPLIB_READ_TIMEOUT_USECOND;
|
||||||
std::string username_;
|
std::string username_;
|
||||||
std::string password_;
|
std::string password_;
|
||||||
bool compress_;
|
bool follow_location_ = false;
|
||||||
|
bool compress_ = false;
|
||||||
std::string interface_;
|
std::string interface_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -852,7 +856,7 @@ private:
|
|||||||
|
|
||||||
class SSLClient : public Client {
|
class SSLClient : public Client {
|
||||||
public:
|
public:
|
||||||
SSLClient(const char *host, int port = 443, time_t timeout_sec = 300,
|
SSLClient(const char *host, int port = 443,
|
||||||
const char *client_cert_path = nullptr,
|
const char *client_cert_path = nullptr,
|
||||||
const char *client_key_path = nullptr);
|
const char *client_key_path = nullptr);
|
||||||
|
|
||||||
@ -884,6 +888,8 @@ private:
|
|||||||
SSL_CTX *ctx_;
|
SSL_CTX *ctx_;
|
||||||
std::mutex ctx_mutex_;
|
std::mutex ctx_mutex_;
|
||||||
std::vector<std::string> host_components_;
|
std::vector<std::string> host_components_;
|
||||||
|
|
||||||
|
// Options
|
||||||
std::string ca_cert_file_path_;
|
std::string ca_cert_file_path_;
|
||||||
std::string ca_cert_dir_path_;
|
std::string ca_cert_dir_path_;
|
||||||
bool server_certificate_verification_ = false;
|
bool server_certificate_verification_ = false;
|
||||||
@ -3371,13 +3377,9 @@ inline bool Server::process_and_close_socket(socket_t sock) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// HTTP client implementation
|
// HTTP client implementation
|
||||||
inline Client::Client(const char *host, int port, time_t timeout_sec)
|
inline Client::Client(const char *host, int port)
|
||||||
: host_(host), port_(port), timeout_sec_(timeout_sec),
|
: host_(host), port_(port),
|
||||||
host_and_port_(host_ + ":" + std::to_string(port_)),
|
host_and_port_(host_ + ":" + std::to_string(port_)) {}
|
||||||
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), compress_(false) {}
|
|
||||||
|
|
||||||
inline Client::~Client() {}
|
inline Client::~Client() {}
|
||||||
|
|
||||||
@ -4004,6 +4006,10 @@ inline std::shared_ptr<Response> Client::Options(const char *path,
|
|||||||
return send(req, *res) ? res : nullptr;
|
return send(req, *res) ? res : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void Client::set_timeout_sec(time_t timeout_sec) {
|
||||||
|
timeout_sec_ = timeout_sec;
|
||||||
|
}
|
||||||
|
|
||||||
inline void Client::set_keep_alive_max_count(size_t count) {
|
inline void Client::set_keep_alive_max_count(size_t count) {
|
||||||
keep_alive_max_count_ = count;
|
keep_alive_max_count_ = count;
|
||||||
}
|
}
|
||||||
@ -4243,10 +4249,10 @@ inline bool SSLServer::process_and_close_socket(socket_t sock) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SSL HTTP client implementation
|
// SSL HTTP client implementation
|
||||||
inline SSLClient::SSLClient(const char *host, int port, time_t timeout_sec,
|
inline SSLClient::SSLClient(const char *host, int port,
|
||||||
const char *client_cert_path,
|
const char *client_cert_path,
|
||||||
const char *client_key_path)
|
const char *client_key_path)
|
||||||
: Client(host, port, timeout_sec) {
|
: Client(host, port) {
|
||||||
ctx_ = SSL_CTX_new(SSLv23_client_method());
|
ctx_ = SSL_CTX_new(SSLv23_client_method());
|
||||||
|
|
||||||
detail::split(&host_[0], &host_[host_.size()], '.',
|
detail::split(&host_[0], &host_[host_.size()], '.',
|
||||||
|
69
test/test.cc
69
test/test.cc
@ -204,15 +204,15 @@ TEST(ParseHeaderValueTest, Range) {
|
|||||||
|
|
||||||
TEST(ChunkedEncodingTest, FromHTTPWatch) {
|
TEST(ChunkedEncodingTest, FromHTTPWatch) {
|
||||||
auto host = "www.httpwatch.com";
|
auto host = "www.httpwatch.com";
|
||||||
auto sec = 2;
|
|
||||||
|
|
||||||
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
||||||
auto port = 443;
|
auto port = 443;
|
||||||
httplib::SSLClient cli(host, port, sec);
|
httplib::SSLClient cli(host, port);
|
||||||
#else
|
#else
|
||||||
auto port = 80;
|
auto port = 80;
|
||||||
httplib::Client cli(host, port, sec);
|
httplib::Client cli(host, port);
|
||||||
#endif
|
#endif
|
||||||
|
cli.set_timeout_sec(2);
|
||||||
|
|
||||||
auto res =
|
auto res =
|
||||||
cli.Get("/httpgallery/chunked/chunkedimage.aspx?0.4153841143030137");
|
cli.Get("/httpgallery/chunked/chunkedimage.aspx?0.4153841143030137");
|
||||||
@ -227,15 +227,15 @@ TEST(ChunkedEncodingTest, FromHTTPWatch) {
|
|||||||
|
|
||||||
TEST(ChunkedEncodingTest, WithContentReceiver) {
|
TEST(ChunkedEncodingTest, WithContentReceiver) {
|
||||||
auto host = "www.httpwatch.com";
|
auto host = "www.httpwatch.com";
|
||||||
auto sec = 2;
|
|
||||||
|
|
||||||
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
||||||
auto port = 443;
|
auto port = 443;
|
||||||
httplib::SSLClient cli(host, port, sec);
|
httplib::SSLClient cli(host, port);
|
||||||
#else
|
#else
|
||||||
auto port = 80;
|
auto port = 80;
|
||||||
httplib::Client cli(host, port, sec);
|
httplib::Client cli(host, port);
|
||||||
#endif
|
#endif
|
||||||
|
cli.set_timeout_sec(2);
|
||||||
|
|
||||||
std::string body;
|
std::string body;
|
||||||
auto res =
|
auto res =
|
||||||
@ -255,15 +255,15 @@ TEST(ChunkedEncodingTest, WithContentReceiver) {
|
|||||||
|
|
||||||
TEST(ChunkedEncodingTest, WithResponseHandlerAndContentReceiver) {
|
TEST(ChunkedEncodingTest, WithResponseHandlerAndContentReceiver) {
|
||||||
auto host = "www.httpwatch.com";
|
auto host = "www.httpwatch.com";
|
||||||
auto sec = 2;
|
|
||||||
|
|
||||||
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
||||||
auto port = 443;
|
auto port = 443;
|
||||||
httplib::SSLClient cli(host, port, sec);
|
httplib::SSLClient cli(host, port);
|
||||||
#else
|
#else
|
||||||
auto port = 80;
|
auto port = 80;
|
||||||
httplib::Client cli(host, port, sec);
|
httplib::Client cli(host, port);
|
||||||
#endif
|
#endif
|
||||||
|
cli.set_timeout_sec(2);
|
||||||
|
|
||||||
std::string body;
|
std::string body;
|
||||||
auto res = cli.Get(
|
auto res = cli.Get(
|
||||||
@ -287,15 +287,15 @@ TEST(ChunkedEncodingTest, WithResponseHandlerAndContentReceiver) {
|
|||||||
|
|
||||||
TEST(RangeTest, FromHTTPBin) {
|
TEST(RangeTest, FromHTTPBin) {
|
||||||
auto host = "httpbin.org";
|
auto host = "httpbin.org";
|
||||||
auto sec = 5;
|
|
||||||
|
|
||||||
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
||||||
auto port = 443;
|
auto port = 443;
|
||||||
httplib::SSLClient cli(host, port, sec);
|
httplib::SSLClient cli(host, port);
|
||||||
#else
|
#else
|
||||||
auto port = 80;
|
auto port = 80;
|
||||||
httplib::Client cli(host, port, sec);
|
httplib::Client cli(host, port);
|
||||||
#endif
|
#endif
|
||||||
|
cli.set_timeout_sec(5);
|
||||||
|
|
||||||
{
|
{
|
||||||
httplib::Headers headers;
|
httplib::Headers headers;
|
||||||
@ -347,15 +347,15 @@ TEST(RangeTest, FromHTTPBin) {
|
|||||||
|
|
||||||
TEST(ConnectionErrorTest, InvalidHost) {
|
TEST(ConnectionErrorTest, InvalidHost) {
|
||||||
auto host = "-abcde.com";
|
auto host = "-abcde.com";
|
||||||
auto sec = 2;
|
|
||||||
|
|
||||||
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
||||||
auto port = 443;
|
auto port = 443;
|
||||||
httplib::SSLClient cli(host, port, sec);
|
httplib::SSLClient cli(host, port);
|
||||||
#else
|
#else
|
||||||
auto port = 80;
|
auto port = 80;
|
||||||
httplib::Client cli(host, port, sec);
|
httplib::Client cli(host, port);
|
||||||
#endif
|
#endif
|
||||||
|
cli.set_timeout_sec(2);
|
||||||
|
|
||||||
auto res = cli.Get("/");
|
auto res = cli.Get("/");
|
||||||
ASSERT_TRUE(res == nullptr);
|
ASSERT_TRUE(res == nullptr);
|
||||||
@ -363,15 +363,15 @@ TEST(ConnectionErrorTest, InvalidHost) {
|
|||||||
|
|
||||||
TEST(ConnectionErrorTest, InvalidPort) {
|
TEST(ConnectionErrorTest, InvalidPort) {
|
||||||
auto host = "localhost";
|
auto host = "localhost";
|
||||||
auto sec = 2;
|
|
||||||
|
|
||||||
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
||||||
auto port = 44380;
|
auto port = 44380;
|
||||||
httplib::SSLClient cli(host, port, sec);
|
httplib::SSLClient cli(host, port);
|
||||||
#else
|
#else
|
||||||
auto port = 8080;
|
auto port = 8080;
|
||||||
httplib::Client cli(host, port, sec);
|
httplib::Client cli(host, port);
|
||||||
#endif
|
#endif
|
||||||
|
cli.set_timeout_sec(2);
|
||||||
|
|
||||||
auto res = cli.Get("/");
|
auto res = cli.Get("/");
|
||||||
ASSERT_TRUE(res == nullptr);
|
ASSERT_TRUE(res == nullptr);
|
||||||
@ -379,15 +379,15 @@ TEST(ConnectionErrorTest, InvalidPort) {
|
|||||||
|
|
||||||
TEST(ConnectionErrorTest, Timeout) {
|
TEST(ConnectionErrorTest, Timeout) {
|
||||||
auto host = "google.com";
|
auto host = "google.com";
|
||||||
auto sec = 2;
|
|
||||||
|
|
||||||
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
||||||
auto port = 44380;
|
auto port = 44380;
|
||||||
httplib::SSLClient cli(host, port, sec);
|
httplib::SSLClient cli(host, port);
|
||||||
#else
|
#else
|
||||||
auto port = 8080;
|
auto port = 8080;
|
||||||
httplib::Client cli(host, port, sec);
|
httplib::Client cli(host, port);
|
||||||
#endif
|
#endif
|
||||||
|
cli.set_timeout_sec(2);
|
||||||
|
|
||||||
auto res = cli.Get("/");
|
auto res = cli.Get("/");
|
||||||
ASSERT_TRUE(res == nullptr);
|
ASSERT_TRUE(res == nullptr);
|
||||||
@ -395,15 +395,15 @@ TEST(ConnectionErrorTest, Timeout) {
|
|||||||
|
|
||||||
TEST(CancelTest, NoCancel) {
|
TEST(CancelTest, NoCancel) {
|
||||||
auto host = "httpbin.org";
|
auto host = "httpbin.org";
|
||||||
auto sec = 5;
|
|
||||||
|
|
||||||
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
||||||
auto port = 443;
|
auto port = 443;
|
||||||
httplib::SSLClient cli(host, port, sec);
|
httplib::SSLClient cli(host, port);
|
||||||
#else
|
#else
|
||||||
auto port = 80;
|
auto port = 80;
|
||||||
httplib::Client cli(host, port, sec);
|
httplib::Client cli(host, port);
|
||||||
#endif
|
#endif
|
||||||
|
cli.set_timeout_sec(5);
|
||||||
|
|
||||||
auto res = cli.Get("/range/32", [](uint64_t, uint64_t) { return true; });
|
auto res = cli.Get("/range/32", [](uint64_t, uint64_t) { return true; });
|
||||||
ASSERT_TRUE(res != nullptr);
|
ASSERT_TRUE(res != nullptr);
|
||||||
@ -413,31 +413,31 @@ TEST(CancelTest, NoCancel) {
|
|||||||
|
|
||||||
TEST(CancelTest, WithCancelSmallPayload) {
|
TEST(CancelTest, WithCancelSmallPayload) {
|
||||||
auto host = "httpbin.org";
|
auto host = "httpbin.org";
|
||||||
auto sec = 5;
|
|
||||||
|
|
||||||
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
||||||
auto port = 443;
|
auto port = 443;
|
||||||
httplib::SSLClient cli(host, port, sec);
|
httplib::SSLClient cli(host, port);
|
||||||
#else
|
#else
|
||||||
auto port = 80;
|
auto port = 80;
|
||||||
httplib::Client cli(host, port, sec);
|
httplib::Client cli(host, port);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
auto res = cli.Get("/range/32", [](uint64_t, uint64_t) { return false; });
|
auto res = cli.Get("/range/32", [](uint64_t, uint64_t) { return false; });
|
||||||
|
cli.set_timeout_sec(5);
|
||||||
ASSERT_TRUE(res == nullptr);
|
ASSERT_TRUE(res == nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(CancelTest, WithCancelLargePayload) {
|
TEST(CancelTest, WithCancelLargePayload) {
|
||||||
auto host = "httpbin.org";
|
auto host = "httpbin.org";
|
||||||
auto sec = 5;
|
|
||||||
|
|
||||||
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
||||||
auto port = 443;
|
auto port = 443;
|
||||||
httplib::SSLClient cli(host, port, sec);
|
httplib::SSLClient cli(host, port);
|
||||||
#else
|
#else
|
||||||
auto port = 80;
|
auto port = 80;
|
||||||
httplib::Client cli(host, port, sec);
|
httplib::Client cli(host, port);
|
||||||
#endif
|
#endif
|
||||||
|
cli.set_timeout_sec(5);
|
||||||
|
|
||||||
uint32_t count = 0;
|
uint32_t count = 0;
|
||||||
httplib::Headers headers;
|
httplib::Headers headers;
|
||||||
@ -2090,9 +2090,10 @@ TEST(SSLClientServerTest, ClientCertPresent) {
|
|||||||
thread t = thread([&]() { ASSERT_TRUE(svr.listen(HOST, PORT)); });
|
thread t = thread([&]() { ASSERT_TRUE(svr.listen(HOST, PORT)); });
|
||||||
msleep(1);
|
msleep(1);
|
||||||
|
|
||||||
httplib::SSLClient cli(HOST, PORT, 30, CLIENT_CERT_FILE,
|
httplib::SSLClient cli(HOST, PORT, CLIENT_CERT_FILE,
|
||||||
CLIENT_PRIVATE_KEY_FILE);
|
CLIENT_PRIVATE_KEY_FILE);
|
||||||
auto res = cli.Get("/test");
|
auto res = cli.Get("/test");
|
||||||
|
cli.set_timeout_sec(30);
|
||||||
ASSERT_TRUE(res != nullptr);
|
ASSERT_TRUE(res != nullptr);
|
||||||
ASSERT_EQ(200, res->status);
|
ASSERT_EQ(200, res->status);
|
||||||
|
|
||||||
@ -2109,8 +2110,9 @@ TEST(SSLClientServerTest, ClientCertMissing) {
|
|||||||
thread t = thread([&]() { ASSERT_TRUE(svr.listen(HOST, PORT)); });
|
thread t = thread([&]() { ASSERT_TRUE(svr.listen(HOST, PORT)); });
|
||||||
msleep(1);
|
msleep(1);
|
||||||
|
|
||||||
httplib::SSLClient cli(HOST, PORT, 30);
|
httplib::SSLClient cli(HOST, PORT);
|
||||||
auto res = cli.Get("/test");
|
auto res = cli.Get("/test");
|
||||||
|
cli.set_timeout_sec(30);
|
||||||
ASSERT_TRUE(res == nullptr);
|
ASSERT_TRUE(res == nullptr);
|
||||||
|
|
||||||
svr.stop();
|
svr.stop();
|
||||||
@ -2130,9 +2132,10 @@ TEST(SSLClientServerTest, TrustDirOptional) {
|
|||||||
thread t = thread([&]() { ASSERT_TRUE(svr.listen(HOST, PORT)); });
|
thread t = thread([&]() { ASSERT_TRUE(svr.listen(HOST, PORT)); });
|
||||||
msleep(1);
|
msleep(1);
|
||||||
|
|
||||||
httplib::SSLClient cli(HOST, PORT, 30, CLIENT_CERT_FILE,
|
httplib::SSLClient cli(HOST, PORT, CLIENT_CERT_FILE,
|
||||||
CLIENT_PRIVATE_KEY_FILE);
|
CLIENT_PRIVATE_KEY_FILE);
|
||||||
auto res = cli.Get("/test");
|
auto res = cli.Get("/test");
|
||||||
|
cli.set_timeout_sec(30);
|
||||||
ASSERT_TRUE(res != nullptr);
|
ASSERT_TRUE(res != nullptr);
|
||||||
ASSERT_EQ(200, res->status);
|
ASSERT_EQ(200, res->status);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user