yhirose 7 years ago
parent
commit
4d7cee81eb
2 changed files with 36 additions and 12 deletions
  1. 24 12
      httplib.h
  2. 12 0
      test/test.cc

+ 24 - 12
httplib.h

@@ -746,7 +746,13 @@ inline const char* status_message(int status)
     }
     }
 }
 }
 
 
-inline const char* get_header_value(const Headers& headers, const char* key, const char* def)
+inline bool has_header(const Headers& headers, const char* key)
+{
+    return headers.find(key) != headers.end();
+}
+
+inline const char* get_header_value(
+    const Headers& headers, const char* key, const char* def = nullptr)
 {
 {
     auto it = headers.find(key);
     auto it = headers.find(key);
     if (it != headers.end()) {
     if (it != headers.end()) {
@@ -755,7 +761,7 @@ inline const char* get_header_value(const Headers& headers, const char* key, con
     return def;
     return def;
 }
 }
 
 
-inline int get_header_value_int(const Headers& headers, const char* key, int def)
+inline int get_header_value_int(const Headers& headers, const char* key, int def = 0)
 {
 {
     auto it = headers.find(key);
     auto it = headers.find(key);
     if (it != headers.end()) {
     if (it != headers.end()) {
@@ -877,20 +883,22 @@ inline bool read_content_chunked(Stream& strm, std::string& out)
 template <typename T>
 template <typename T>
 bool read_content(Stream& strm, T& x, Progress progress = Progress())
 bool read_content(Stream& strm, T& x, Progress progress = Progress())
 {
 {
-    auto len = get_header_value_int(x.headers, "Content-Length", 0);
-
-    if (len) {
+    if (has_header(x.headers, "Content-Length")) {
+        auto len = get_header_value_int(x.headers, "Content-Length", 0);
+        if (len == 0) {
+            const auto& encoding = get_header_value(x.headers, "Transfer-Encoding", "");
+            if (!strcasecmp(encoding, "chunked")) {
+                return read_content_chunked(strm, x.body);
+            }
+        }
         return read_content_with_length(strm, x.body, len, progress);
         return read_content_with_length(strm, x.body, len, progress);
     } else {
     } else {
         const auto& encoding = get_header_value(x.headers, "Transfer-Encoding", "");
         const auto& encoding = get_header_value(x.headers, "Transfer-Encoding", "");
-
         if (!strcasecmp(encoding, "chunked")) {
         if (!strcasecmp(encoding, "chunked")) {
             return read_content_chunked(strm, x.body);
             return read_content_chunked(strm, x.body);
-        } else {
-            return read_content_without_length(strm, x.body);
         }
         }
+        return read_content_without_length(strm, x.body);
     }
     }
-
     return true;
     return true;
 }
 }
 
 
@@ -1301,7 +1309,7 @@ inline std::pair<std::string, std::string> make_range_header(uint64_t value, Arg
 // Request implementation
 // Request implementation
 inline bool Request::has_header(const char* key) const
 inline bool Request::has_header(const char* key) const
 {
 {
-    return headers.find(key) != headers.end();
+    return detail::has_header(headers, key);
 }
 }
 
 
 inline std::string Request::get_header_value(const char* key) const
 inline std::string Request::get_header_value(const char* key) const
@@ -1578,7 +1586,7 @@ inline void Server::write_response(Stream& strm, bool last_connection, const Req
         req.get_header_value("Connection") == "close") {
         req.get_header_value("Connection") == "close") {
         res.set_header("Connection", "close");
         res.set_header("Connection", "close");
     }
     }
-    
+
     if (!last_connection &&
     if (!last_connection &&
         req.get_header_value("Connection") == "Keep-Alive") {
         req.get_header_value("Connection") == "Keep-Alive") {
         res.set_header("Connection", "Keep-Alive");
         res.set_header("Connection", "Keep-Alive");
@@ -1988,7 +1996,11 @@ inline void Client::write_request(Stream& strm, Request& req)
         req.set_header("Connection", "close");
         req.set_header("Connection", "close");
     // }
     // }
 
 
-    if (!req.body.empty()) {
+    if (req.body.empty()) {
+        if (req.method == "POST" || req.method == "PUT") {
+            req.set_header("Content-Length", "0");
+        }
+    } else {
         if (!req.has_header("Content-Type")) {
         if (!req.has_header("Content-Type")) {
             req.set_header("Content-Type", "text/plain");
             req.set_header("Content-Type", "text/plain");
         }
         }

+ 12 - 0
test/test.cc

@@ -398,6 +398,10 @@ protected:
                     EXPECT_EQ(0u, file.length);
                     EXPECT_EQ(0u, file.length);
                 }
                 }
             })
             })
+            .Post("/empty", [&](const Request& req, Response& res) {
+                EXPECT_EQ(req.body, "");
+                res.set_content("empty", "text/plain");
+            })
             .Put("/put", [&](const Request& req, Response& res) {
             .Put("/put", [&](const Request& req, Response& res) {
                 EXPECT_EQ(req.body, "PUT");
                 EXPECT_EQ(req.body, "PUT");
                 res.set_content(req.body, "text/plain");
                 res.set_content(req.body, "text/plain");
@@ -560,6 +564,14 @@ TEST_F(ServerTest, PostMethod2)
     ASSERT_EQ("coder", res->body);
     ASSERT_EQ("coder", res->body);
 }
 }
 
 
+TEST_F(ServerTest, PostEmptyContent)
+{
+    auto res = cli_.Post("/empty", "", "text/plain");
+    ASSERT_TRUE(res != nullptr);
+    ASSERT_EQ(200, res->status);
+    ASSERT_EQ("empty", res->body);
+}
+
 TEST_F(ServerTest, GetMethodDir)
 TEST_F(ServerTest, GetMethodDir)
 {
 {
 	auto res = cli_.Get("/dir/");
 	auto res = cli_.Get("/dir/");