This commit is contained in:
yhirose 2018-09-23 12:02:17 -04:00
parent 9546ec842b
commit 4d7cee81eb
2 changed files with 36 additions and 12 deletions

View file

@ -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 (has_header(x.headers, "Content-Length")) {
auto len = get_header_value_int(x.headers, "Content-Length", 0);
if (len) { 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");
} }

View file

@ -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/");