diff --git a/httplib.h b/httplib.h index 30e512d..e1bbe14 100644 --- a/httplib.h +++ b/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*(.*)$)~", diff --git a/test/test.cc b/test/test.cc index 8af6355..4862369 100644 --- a/test/test.cc +++ b/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