Browse Source

Merge branch 'gulrak-feature-response-handler-with-content-receiver'

yhirose 6 years ago
parent
commit
6f8f51496d
2 changed files with 72 additions and 3 deletions
  1. 40 3
      httplib.h
  2. 32 0
      test/test.cc

+ 40 - 3
httplib.h

@@ -153,6 +153,9 @@ typedef std::function<bool(const char *data, size_t data_length, size_t offset,
 
 
 typedef std::function<bool(uint64_t current, uint64_t total)> Progress;
 typedef std::function<bool(uint64_t current, uint64_t total)> Progress;
 
 
+struct Response;
+typedef std::function<bool(const Response& response)> ResponseHandler;
+
 struct MultipartFile {
 struct MultipartFile {
   std::string filename;
   std::string filename;
   std::string content_type;
   std::string content_type;
@@ -188,6 +191,7 @@ struct Request {
 
 
   // for client
   // for client
   size_t redirect_count = CPPHTTPLIB_REDIRECT_MAX_COUNT;
   size_t redirect_count = CPPHTTPLIB_REDIRECT_MAX_COUNT;
+  ResponseHandler response_handler;
   ContentReceiver content_receiver;
   ContentReceiver content_receiver;
   Progress progress;
   Progress progress;
 
 
@@ -518,6 +522,15 @@ public:
                                 ContentReceiver content_receiver,
                                 ContentReceiver content_receiver,
                                 Progress progress);
                                 Progress progress);
 
 
+  std::shared_ptr<Response> Get(const char *path, const Headers &headers,
+                                ResponseHandler response_handler,
+                                ContentReceiver content_receiver);
+
+  std::shared_ptr<Response> Get(const char *path, const Headers &headers,
+                                ResponseHandler response_handler,
+                                ContentReceiver content_receiver,
+                                Progress progress);
+
   std::shared_ptr<Response> Head(const char *path);
   std::shared_ptr<Response> Head(const char *path);
 
 
   std::shared_ptr<Response> Head(const char *path, const Headers &headers);
   std::shared_ptr<Response> Head(const char *path, const Headers &headers);
@@ -1555,6 +1568,7 @@ inline bool redirect(T &cli, const Request &req, Response &res,
   new_req.headers = req.headers;
   new_req.headers = req.headers;
   new_req.body = req.body;
   new_req.body = req.body;
   new_req.redirect_count = req.redirect_count - 1;
   new_req.redirect_count = req.redirect_count - 1;
+  new_req.response_handler = req.response_handler;
   new_req.content_receiver = req.content_receiver;
   new_req.content_receiver = req.content_receiver;
   new_req.progress = req.progress;
   new_req.progress = req.progress;
 
 
@@ -2869,6 +2883,12 @@ inline bool Client::process_request(Stream &strm, const Request &req,
     connection_close = true;
     connection_close = true;
   }
   }
 
 
+  if (req.response_handler) {
+    if(!req.response_handler(res)) {
+      return false;
+    }
+  }
+
   // Body
   // Body
   if (req.method != "HEAD") {
   if (req.method != "HEAD") {
     detail::ContentReceiverCore out = [&](const char *buf, size_t n) {
     detail::ContentReceiverCore out = [&](const char *buf, size_t n) {
@@ -2940,30 +2960,47 @@ Client::Get(const char *path, const Headers &headers, Progress progress) {
 inline std::shared_ptr<Response> Client::Get(const char *path,
 inline std::shared_ptr<Response> Client::Get(const char *path,
                                              ContentReceiver content_receiver) {
                                              ContentReceiver content_receiver) {
   Progress dummy;
   Progress dummy;
-  return Get(path, Headers(), content_receiver, dummy);
+  return Get(path, Headers(), nullptr, content_receiver, dummy);
 }
 }
 
 
 inline std::shared_ptr<Response> Client::Get(const char *path,
 inline std::shared_ptr<Response> Client::Get(const char *path,
                                              ContentReceiver content_receiver,
                                              ContentReceiver content_receiver,
                                              Progress progress) {
                                              Progress progress) {
-  return Get(path, Headers(), content_receiver, progress);
+  return Get(path, Headers(), nullptr, content_receiver, progress);
+}
+
+inline std::shared_ptr<Response> Client::Get(const char *path,
+                                             const Headers &headers,
+                                             ContentReceiver content_receiver) {
+  Progress dummy;
+  return Get(path, headers, nullptr, content_receiver, dummy);
+}
+
+inline std::shared_ptr<Response> 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<Response> Client::Get(const char *path,
 inline std::shared_ptr<Response> Client::Get(const char *path,
                                              const Headers &headers,
                                              const Headers &headers,
+                                             ResponseHandler response_handler,
                                              ContentReceiver content_receiver) {
                                              ContentReceiver content_receiver) {
   Progress dummy;
   Progress dummy;
-  return Get(path, headers, content_receiver, dummy);
+  return Get(path, headers, response_handler, content_receiver, dummy);
 }
 }
 
 
 inline std::shared_ptr<Response> Client::Get(const char *path,
 inline std::shared_ptr<Response> Client::Get(const char *path,
                                              const Headers &headers,
                                              const Headers &headers,
+                                             ResponseHandler response_handler,
                                              ContentReceiver content_receiver,
                                              ContentReceiver content_receiver,
                                              Progress progress) {
                                              Progress progress) {
   Request req;
   Request req;
   req.method = "GET";
   req.method = "GET";
   req.path = path;
   req.path = path;
   req.headers = headers;
   req.headers = headers;
+  req.response_handler = response_handler;
   req.content_receiver = content_receiver;
   req.content_receiver = content_receiver;
   req.progress = progress;
   req.progress = progress;
 
 

+ 32 - 0
test/test.cc

@@ -242,6 +242,38 @@ TEST(ChunkedEncodingTest, WithContentReceiver) {
   EXPECT_EQ(out, body);
   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) {
 TEST(RangeTest, FromHTTPBin) {
   auto host = "httpbin.org";
   auto host = "httpbin.org";
   auto sec = 5;
   auto sec = 5;