yhirose 2 years ago
parent
commit
cddaedaff8
2 changed files with 59 additions and 3 deletions
  1. 12 3
      httplib.h
  2. 47 0
      test/test.cc

+ 12 - 3
httplib.h

@@ -4332,10 +4332,19 @@ public:
             break;
           }
 
-          static const std::string header_name = "content-type:";
+          static const std::string header_content_type = "Content-Type:";
+          static const std::string header_content_length = "Content-Length:";
+
           const auto header = buf_head(pos);
-          if (start_with_case_ignore(header, header_name)) {
-            file_.content_type = trim_copy(header.substr(header_name.size()));
+          if (start_with_case_ignore(header, header_content_type)) {
+            file_.content_type =
+                trim_copy(header.substr(header_content_type.size()));
+          } else if (start_with_case_ignore(header, header_content_length)) {
+            // NOTE: For now, we ignore the content length. In the future, the
+            // parser should check if the actual body length is same as this
+            // value.
+            // auto content_length = std::stoi(
+            //     trim_copy(header.substr(header_content_length.size())));
           } else {
             static const std::regex re_content_disposition(
                 R"~(^Content-Disposition:\s*form-data;\s*(.*)$)~",

+ 47 - 0
test/test.cc

@@ -6298,6 +6298,53 @@ TEST(MultipartFormDataTest, CloseDelimiterWithoutCRLF) {
   ASSERT_EQ("200", resonse.substr(9, 3));
 }
 
+TEST(MultipartFormDataTest, ContentLength) {
+  auto handled = false;
+
+  Server svr;
+  svr.Post("/test", [&](const Request &req, Response &) {
+    ASSERT_EQ(2u, req.files.size());
+
+    auto it = req.files.begin();
+    ASSERT_EQ("text1", it->second.name);
+    ASSERT_EQ("text1", it->second.content);
+
+    ++it;
+    ASSERT_EQ("text2", it->second.name);
+    ASSERT_EQ("text2", it->second.content);
+
+    handled = true;
+  });
+
+  thread t = thread([&] { svr.listen(HOST, PORT); });
+  auto se = detail::scope_exit([&] {
+    svr.stop();
+    t.join();
+    ASSERT_FALSE(svr.is_running());
+    ASSERT_TRUE(handled);
+  });
+
+  svr.wait_until_ready();
+
+  auto req = "POST /test HTTP/1.1\r\n"
+             "Content-Type: multipart/form-data;boundary=--------\r\n"
+             "Content-Length: 167\r\n"
+             "\r\n----------\r\n"
+             "Content-Disposition: form-data; name=\"text1\"\r\n"
+             "Content-Length: 5\r\n"
+             "\r\n"
+             "text1"
+             "\r\n----------\r\n"
+             "Content-Disposition: form-data; name=\"text2\"\r\n"
+             "\r\n"
+             "text2"
+             "\r\n------------\r\n";
+
+  std::string resonse;
+  ASSERT_TRUE(send_request(1, req, &resonse));
+  ASSERT_EQ("200", resonse.substr(9, 3));
+}
+
 #endif
 
 #ifndef _WIN32