From e9575bcb783d9b731c133be47c50b03130d9ef8d Mon Sep 17 00:00:00 2001 From: tmahring Date: Fri, 11 Sep 2020 02:27:01 +0200 Subject: [PATCH] don't replace plus with space in headers (#649) * don't replace plus with space in headers * fixed forward handling with changed header parsing * add test for boundaries containing plus chars --- httplib.h | 4 ++-- test/test.cc | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/httplib.h b/httplib.h index dc5fefd..8bf8604 100644 --- a/httplib.h +++ b/httplib.h @@ -2464,7 +2464,7 @@ inline bool parse_header(const char *beg, const char *end, T fn) { } if (p < end) { - fn(std::string(beg, key_end), decode_url(std::string(p, end), true)); + fn(std::string(beg, key_end), decode_url(std::string(p, end), false)); return true; } @@ -4768,7 +4768,7 @@ inline bool ClientImpl::redirect(const Request &req, Response &res) { return false; } - auto location = res.get_header_value("location"); + auto location = detail::decode_url(res.get_header_value("location"), true); if (location.empty()) { return false; } const static std::regex re( diff --git a/test/test.cc b/test/test.cc index 46cea48..910d2c3 100644 --- a/test/test.cc +++ b/test/test.cc @@ -2323,6 +2323,41 @@ TEST_F(ServerTest, PostMulitpartFilsContentReceiver) { EXPECT_EQ(200, res->status); } +TEST_F(ServerTest, PostMulitpartPlusBoundary) { + MultipartFormDataItems items = { + {"text1", "text default", "", ""}, + {"text2", "aωb", "", ""}, + {"file1", "h\ne\n\nl\nl\no\n", "hello.txt", "text/plain"}, + {"file2", "{\n \"world\", true\n}\n", "world.json", "application/json"}, + {"file3", "", "", "application/octet-stream"}, + }; + + auto boundary = std::string("+++++"); + + std::string body; + + for (const auto &item : items) { + body += "--" + boundary + "\r\n"; + body += "Content-Disposition: form-data; name=\"" + item.name + "\""; + if (!item.filename.empty()) { + body += "; filename=\"" + item.filename + "\""; + } + body += "\r\n"; + if (!item.content_type.empty()) { + body += "Content-Type: " + item.content_type + "\r\n"; + } + body += "\r\n"; + body += item.content + "\r\n"; + } + body += "--" + boundary + "--\r\n"; + + std::string content_type = "multipart/form-data; boundary=" + boundary; + auto res = cli_.Post("/content_receiver", body, content_type.c_str()); + + ASSERT_TRUE(res); + EXPECT_EQ(200, res->status); +} + TEST_F(ServerTest, PostContentReceiverGzip) { cli_.set_compress(true); auto res = cli_.Post("/content_receiver", "content", "text/plain");