Browse Source

Simplified ContentReceiver interface

yhirose 6 years ago
parent
commit
9d57899352
3 changed files with 45 additions and 87 deletions
  1. 1 1
      README.md
  2. 12 38
      httplib.h
  3. 32 48
      test/test.cc

+ 1 - 1
README.md

@@ -194,7 +194,7 @@ int main(void)
   std::string body;
 
   auto res = cli.Get("/large-data",
-    [&](const char *data, uint64_t data_length, uint64_t offset, uint64_t content_length) {
+    [&](const char *data, uint64_t data_length) {
       body.append(data, data_length);
     });
 

+ 12 - 38
httplib.h

@@ -202,8 +202,7 @@ typedef std::function<void(size_t offset, size_t length, DataSink sink,
                            Done done)>
     ContentProviderWithCloser;
 
-typedef std::function<bool(const char *data, size_t data_length, size_t offset,
-                           uint64_t content_length)>
+typedef std::function<bool(const char *data, size_t data_length)>
     ContentReceiver;
 
 typedef std::function<bool(ContentReceiver receiver)> ContentReader;
@@ -1523,12 +1522,8 @@ inline bool read_headers(Stream &strm, Headers &headers) {
   return true;
 }
 
-typedef std::function<bool(const char *data, size_t data_length)>
-    ContentReceiverCore;
-
 inline bool read_content_with_length(Stream &strm, uint64_t len,
-                                     Progress progress,
-                                     ContentReceiverCore out) {
+                                     Progress progress, ContentReceiver out) {
   char buf[CPPHTTPLIB_RECV_BUFSIZ];
 
   uint64_t r = 0;
@@ -1560,7 +1555,7 @@ inline void skip_content_with_length(Stream &strm, uint64_t len) {
   }
 }
 
-inline bool read_content_without_length(Stream &strm, ContentReceiverCore out) {
+inline bool read_content_without_length(Stream &strm, ContentReceiver out) {
   char buf[CPPHTTPLIB_RECV_BUFSIZ];
   for (;;) {
     auto n = strm.read(buf, CPPHTTPLIB_RECV_BUFSIZ);
@@ -1575,7 +1570,7 @@ inline bool read_content_without_length(Stream &strm, ContentReceiverCore out) {
   return true;
 }
 
-inline bool read_content_chunked(Stream &strm, ContentReceiverCore out) {
+inline bool read_content_chunked(Stream &strm, ContentReceiver out) {
   const auto bufsiz = 16;
   char buf[bufsiz];
 
@@ -1615,9 +1610,9 @@ inline bool is_chunked_transfer_encoding(const Headers &headers) {
 
 template <typename T>
 bool read_content(Stream &strm, T &x, size_t payload_max_length, int &status,
-                  Progress progress, ContentReceiverCore receiver) {
+                  Progress progress, ContentReceiver receiver) {
 
-  ContentReceiverCore out = [&](const char *buf, size_t n) {
+  ContentReceiver out = [&](const char *buf, size_t n) {
     return receiver(buf, n);
   };
 
@@ -2673,19 +2668,9 @@ inline bool
 Server::read_content_with_content_receiver(Stream &strm, bool last_connection,
                                            Request &req, Response &res,
                                            ContentReceiver receiver) {
-  size_t offset = 0;
-
-  size_t length = 0;
-  if (req.get_header_value("Content-Encoding") != "gzip") {
-    length = get_header_value_uint64(req.headers, "Content-Length", 0);
-  }
-
-  if (!detail::read_content(strm, req, payload_max_length_, res.status,
-                            Progress(), [&](const char *buf, size_t n) {
-                              auto ret = receiver(buf, n, offset, length);
-                              offset += n;
-                              return ret;
-                            })) {
+  if (!detail::read_content(
+          strm, req, payload_max_length_, res.status, Progress(),
+          [&](const char *buf, size_t n) { return receiver(buf, n); })) {
     return write_response(strm, last_connection, req, res);
   }
 
@@ -3253,26 +3238,15 @@ inline bool Client::process_request(Stream &strm, const Request &req,
 
   // Body
   if (req.method != "HEAD") {
-    detail::ContentReceiverCore out = [&](const char *buf, size_t n) {
+    ContentReceiver out = [&](const char *buf, size_t n) {
       if (res.body.size() + n > res.body.max_size()) { return false; }
       res.body.append(buf, n);
       return true;
     };
 
     if (req.content_receiver) {
-      auto offset = std::make_shared<size_t>();
-
-      size_t length = 0;
-      if (res.get_header_value("Content-Encoding") != "gzip") {
-        length = get_header_value_uint64(res.headers, "Content-Length", 0);
-      }
-
-      auto receiver = req.content_receiver;
-
-      out = [offset, length, receiver](const char *buf, size_t n) {
-        auto ret = receiver(buf, n, *offset, length);
-        (*offset) += n;
-        return ret;
+      out = [&](const char *buf, size_t n) {
+        return req.content_receiver(buf, n);
       };
     }
 

+ 32 - 48
test/test.cc

@@ -229,7 +229,7 @@ TEST(ChunkedEncodingTest, WithContentReceiver) {
   std::string body;
   auto res =
       cli.Get("/httpgallery/chunked/chunkedimage.aspx?0.4153841143030137",
-              [&](const char *data, size_t data_length, uint64_t, uint64_t) {
+              [&](const char *data, size_t data_length) {
                 body.append(data, data_length);
                 return true;
               });
@@ -261,7 +261,7 @@ TEST(ChunkedEncodingTest, WithResponseHandlerAndContentReceiver) {
         EXPECT_EQ(200, response.status);
         return true;
       },
-      [&](const char *data, size_t data_length, uint64_t, uint64_t) {
+      [&](const char *data, size_t data_length) {
         body.append(data, data_length);
         return true;
       });
@@ -745,18 +745,10 @@ protected:
                 EXPECT_EQ("5", req.get_header_value("Content-Length"));
               })
         .Post("/content_receiver",
-              [&](const Request & req, Response &res,
+              [&](const Request & /*req*/, Response &res,
                   const ContentReader &content_reader) {
                 std::string body;
-                content_reader([&](const char *data, size_t data_length,
-                                   size_t offset,
-                                   uint64_t content_length) {
-                  EXPECT_EQ(offset, 0);
-                  if (req.get_header_value("Content-Encoding") == "gzip") {
-                    EXPECT_EQ(content_length, 0);
-                  } else {
-                    EXPECT_EQ(content_length, 7);
-                  }
+                content_reader([&](const char *data, size_t data_length) {
                   EXPECT_EQ(data_length, 7);
                   body.append(data, data_length);
                   return true;
@@ -768,9 +760,7 @@ protected:
              [&](const Request & /*req*/, Response &res,
                  const ContentReader &content_reader) {
                std::string body;
-               content_reader([&](const char *data, size_t data_length,
-                                  size_t /*offset*/,
-                                  uint64_t /*content_length*/) {
+               content_reader([&](const char *data, size_t data_length) {
                  body.append(data, data_length);
                  return true;
                });
@@ -781,9 +771,7 @@ protected:
                [&](const Request & /*req*/, Response &res,
                    const ContentReader &content_reader) {
                  std::string body;
-                 content_reader([&](const char *data, size_t data_length,
-                                    size_t /*offset*/,
-                                    uint64_t /*content_length*/) {
+                 content_reader([&](const char *data, size_t data_length) {
                    body.append(data, data_length);
                    return true;
                  });
@@ -1284,10 +1272,15 @@ TEST_F(ServerTest, GetStreamedWithRangeMultipart) {
 }
 
 TEST_F(ServerTest, GetStreamedEndless) {
+  size_t offset = 0;
   auto res = cli_.Get("/streamed-cancel",
-                      [](const char * /*data*/, uint64_t /*data_length*/,
-                         uint64_t offset,
-                         uint64_t /*content_length*/) { return offset < 100; });
+                      [&](const char * /*data*/, uint64_t data_length) {
+                        if (offset < 100) {
+                          offset += data_length;
+                          return true;
+                        }
+                        return false;
+                      });
   ASSERT_TRUE(res == nullptr);
 }
 
@@ -1579,15 +1572,12 @@ TEST_F(ServerTest, GzipWithContentReceiver) {
   Headers headers;
   headers.emplace("Accept-Encoding", "gzip, deflate");
   std::string body;
-  auto res = cli_.Get("/gzip", headers,
-                      [&](const char *data, uint64_t data_length,
-                          uint64_t offset, uint64_t content_length) {
-                        EXPECT_EQ(data_length, 100);
-                        EXPECT_EQ(offset, 0);
-                        EXPECT_EQ(content_length, 0);
-                        body.append(data, data_length);
-                        return true;
-                      });
+  auto res =
+      cli_.Get("/gzip", headers, [&](const char *data, uint64_t data_length) {
+        EXPECT_EQ(data_length, 100);
+        body.append(data, data_length);
+        return true;
+      });
 
   ASSERT_TRUE(res != nullptr);
   EXPECT_EQ("gzip", res->get_header_value("Content-Encoding"));
@@ -1602,15 +1592,12 @@ TEST_F(ServerTest, GzipWithContentReceiver) {
 TEST_F(ServerTest, GzipWithContentReceiverWithoutAcceptEncoding) {
   Headers headers;
   std::string body;
-  auto res = cli_.Get("/gzip", headers,
-                      [&](const char *data, uint64_t data_length,
-                          uint64_t offset, uint64_t content_length) {
-                        EXPECT_EQ(data_length, 100);
-                        EXPECT_EQ(offset, 0);
-                        EXPECT_EQ(content_length, 100);
-                        body.append(data, data_length);
-                        return true;
-                      });
+  auto res =
+      cli_.Get("/gzip", headers, [&](const char *data, uint64_t data_length) {
+        EXPECT_EQ(data_length, 100);
+        body.append(data, data_length);
+        return true;
+      });
 
   ASSERT_TRUE(res != nullptr);
   EXPECT_EQ("", res->get_header_value("Content-Encoding"));
@@ -1641,15 +1628,12 @@ TEST_F(ServerTest, NoGzipWithContentReceiver) {
   Headers headers;
   headers.emplace("Accept-Encoding", "gzip, deflate");
   std::string body;
-  auto res = cli_.Get("/nogzip", headers,
-                      [&](const char *data, uint64_t data_length,
-                          uint64_t offset, uint64_t content_length) {
-                        EXPECT_EQ(data_length, 100);
-                        EXPECT_EQ(offset, 0);
-                        EXPECT_EQ(content_length, 100);
-                        body.append(data, data_length);
-                        return true;
-                      });
+  auto res =
+      cli_.Get("/nogzip", headers, [&](const char *data, uint64_t data_length) {
+        EXPECT_EQ(data_length, 100);
+        body.append(data, data_length);
+        return true;
+      });
 
   ASSERT_TRUE(res != nullptr);
   EXPECT_EQ(false, res->has_header("Content-Encoding"));