diff --git a/httplib.h b/httplib.h index f9d59a1..d4b60b5 100644 --- a/httplib.h +++ b/httplib.h @@ -153,6 +153,9 @@ typedef std::function Progress; +struct Response; +typedef std::function ResponseHandler; + struct MultipartFile { std::string filename; std::string content_type; @@ -188,6 +191,7 @@ struct Request { // for client size_t redirect_count = CPPHTTPLIB_REDIRECT_MAX_COUNT; + ResponseHandler response_handler; ContentReceiver content_receiver; Progress progress; @@ -518,6 +522,15 @@ public: ContentReceiver content_receiver, Progress progress); + std::shared_ptr Get(const char *path, const Headers &headers, + ResponseHandler response_handler, + ContentReceiver content_receiver); + + std::shared_ptr Get(const char *path, const Headers &headers, + ResponseHandler response_handler, + ContentReceiver content_receiver, + Progress progress); + std::shared_ptr Head(const char *path); std::shared_ptr Head(const char *path, const Headers &headers); @@ -2869,6 +2882,12 @@ inline bool Client::process_request(Stream &strm, const Request &req, connection_close = true; } + if (req.response_handler) { + if(!req.response_handler(res)) { + return false; + } + } + // Body if (req.method != "HEAD") { detail::ContentReceiverCore out = [&](const char *buf, size_t n) { @@ -2940,30 +2959,47 @@ Client::Get(const char *path, const Headers &headers, Progress progress) { inline std::shared_ptr Client::Get(const char *path, ContentReceiver content_receiver) { Progress dummy; - return Get(path, Headers(), content_receiver, dummy); + return Get(path, Headers(), nullptr, content_receiver, dummy); } inline std::shared_ptr Client::Get(const char *path, ContentReceiver content_receiver, Progress progress) { - return Get(path, Headers(), content_receiver, progress); + return Get(path, Headers(), nullptr, content_receiver, progress); } inline std::shared_ptr Client::Get(const char *path, const Headers &headers, ContentReceiver content_receiver) { Progress dummy; - return Get(path, headers, content_receiver, dummy); + return Get(path, headers, nullptr, content_receiver, dummy); } inline std::shared_ptr Client::Get(const char *path, const Headers &headers, ContentReceiver content_receiver, Progress progress) { + return Get(path, headers, nullptr, content_receiver, progress); +} + +inline std::shared_ptr Client::Get(const char *path, + const Headers &headers, + ResponseHandler response_handler, + ContentReceiver content_receiver) { + Progress dummy; + return Get(path, headers, response_handler, content_receiver, dummy); +} + +inline std::shared_ptr Client::Get(const char *path, + const Headers &headers, + ResponseHandler response_handler, + ContentReceiver content_receiver, + Progress progress) { Request req; req.method = "GET"; req.path = path; req.headers = headers; + req.response_handler = response_handler; req.content_receiver = content_receiver; req.progress = progress; diff --git a/test/test.cc b/test/test.cc index 57049c3..24651a0 100644 --- a/test/test.cc +++ b/test/test.cc @@ -242,6 +242,38 @@ TEST(ChunkedEncodingTest, WithContentReceiver) { EXPECT_EQ(out, body); } +TEST(ChunkedEncodingTest, WithResponseHandlerAndContentReceiver) { + auto host = "www.httpwatch.com"; + auto sec = 2; + +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + auto port = 443; + httplib::SSLClient cli(host, port, sec); +#else + auto port = 80; + httplib::Client cli(host, port, sec); +#endif + + std::string body; + auto res = + cli.Get("/httpgallery/chunked/chunkedimage.aspx?0.4153841143030137", Headers(), + [&](const Response& response) { + EXPECT_EQ(200, response.status); + return true; + }, + [&](const char *data, size_t data_length, uint64_t, uint64_t) { + body.append(data, data_length); + return true; + }); + ASSERT_TRUE(res != nullptr); + + std::string out; + httplib::detail::read_file("./image.jpg", out); + + EXPECT_EQ(200, res->status); + EXPECT_EQ(out, body); +} + TEST(RangeTest, FromHTTPBin) { auto host = "httpbin.org"; auto sec = 5;