From 4d7cee81eb106c502738b8a9980422a93dba148a Mon Sep 17 00:00:00 2001 From: yhirose Date: Sun, 23 Sep 2018 12:02:17 -0400 Subject: [PATCH] Fix #95 --- httplib.h | 36 ++++++++++++++++++++++++------------ test/test.cc | 12 ++++++++++++ 2 files changed, 36 insertions(+), 12 deletions(-) diff --git a/httplib.h b/httplib.h index fd6049b..ba37d16 100644 --- a/httplib.h +++ b/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); if (it != headers.end()) { @@ -755,7 +761,7 @@ inline const char* get_header_value(const Headers& headers, const char* key, con 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); if (it != headers.end()) { @@ -877,20 +883,22 @@ inline bool read_content_chunked(Stream& strm, std::string& out) template 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); } else { const auto& encoding = get_header_value(x.headers, "Transfer-Encoding", ""); - if (!strcasecmp(encoding, "chunked")) { 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; } @@ -1301,7 +1309,7 @@ inline std::pair make_range_header(uint64_t value, Arg // Request implementation 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 @@ -1578,7 +1586,7 @@ inline void Server::write_response(Stream& strm, bool last_connection, const Req req.get_header_value("Connection") == "close") { res.set_header("Connection", "close"); } - + if (!last_connection && req.get_header_value("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"); // } - 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")) { req.set_header("Content-Type", "text/plain"); } diff --git a/test/test.cc b/test/test.cc index 6169b60..66b8c45 100644 --- a/test/test.cc +++ b/test/test.cc @@ -398,6 +398,10 @@ protected: 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) { EXPECT_EQ(req.body, "PUT"); res.set_content(req.body, "text/plain"); @@ -560,6 +564,14 @@ TEST_F(ServerTest, PostMethod2) 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) { auto res = cli_.Get("/dir/");