diff --git a/README.md b/README.md index 95dbe2d..48350db 100644 --- a/README.md +++ b/README.md @@ -559,13 +559,21 @@ The server applies gzip compression to the following MIME type contents: * application/xml * application/xhtml+xml -### Compress content on client +### Compress request body on client ```c++ cli.set_compress(true); res = cli.Post("/resource/foo", "...", "text/plain"); ``` +### Compress response body on client + +```c++ +cli.set_decompress(false); +res = cli.Get("/resource/foo", {{"Accept-Encoding", "gzip, deflate"}}); +res->body; // Compressed data +``` + Split httplib.h into .h and .cc ------------------------------- diff --git a/httplib.h b/httplib.h index 23d8fb0..f25745c 100644 --- a/httplib.h +++ b/httplib.h @@ -778,6 +778,8 @@ public: void set_compress(bool on); + void set_decompress(bool on); + void set_interface(const char *intf); void set_proxy(const char *host, int port); @@ -821,6 +823,7 @@ protected: bool follow_location_ = false; bool compress_ = false; + bool decompress_ = true; std::string interface_; @@ -853,6 +856,7 @@ protected: #endif follow_location_ = rhs.follow_location_; compress_ = rhs.compress_; + decompress_ = rhs.decompress_; interface_ = rhs.interface_; proxy_host_ = rhs.proxy_host_; proxy_port_ = rhs.proxy_port_; @@ -1281,6 +1285,11 @@ public: return *this; } + Client2 &set_decompress(bool on) { + cli_->set_decompress(on); + return *this; + } + Client2 &set_interface(const char *intf) { cli_->set_interface(intf); return *this; @@ -2395,7 +2404,7 @@ inline bool is_chunked_transfer_encoding(const Headers &headers) { template bool read_content(Stream &strm, T &x, size_t payload_max_length, int &status, - Progress progress, ContentReceiver receiver) { + Progress progress, ContentReceiver receiver, bool decompress) { ContentReceiver out = [&](const char *buf, size_t n) { return receiver(buf, n); @@ -2403,26 +2412,31 @@ bool read_content(Stream &strm, T &x, size_t payload_max_length, int &status, #ifdef CPPHTTPLIB_ZLIB_SUPPORT decompressor decompressor; +#endif - std::string content_encoding = x.get_header_value("Content-Encoding"); - if (content_encoding.find("gzip") != std::string::npos || - content_encoding.find("deflate") != std::string::npos) { - if (!decompressor.is_valid()) { - status = 500; + if (decompress) { +#ifdef CPPHTTPLIB_ZLIB_SUPPORT + std::string content_encoding = x.get_header_value("Content-Encoding"); + if (content_encoding.find("gzip") != std::string::npos || + content_encoding.find("deflate") != std::string::npos) { + if (!decompressor.is_valid()) { + status = 500; + return false; + } + + out = [&](const char *buf, size_t n) { + return decompressor.decompress(buf, n, [&](const char *buf, size_t n) { + return receiver(buf, n); + }); + }; + } +#else + if (x.get_header_value("Content-Encoding") == "gzip") { + status = 415; return false; } - - out = [&](const char *buf, size_t n) { - return decompressor.decompress( - buf, n, [&](const char *buf, size_t n) { return receiver(buf, n); }); - }; - } -#else - if (x.get_header_value("Content-Encoding") == "gzip") { - status = 415; - return false; - } #endif + } auto ret = true; auto exceed_payload_max_length = false; @@ -3883,7 +3897,7 @@ inline bool Server::read_content_core(Stream &strm, Request &req, Response &res, } if (!detail::read_content(strm, req, payload_max_length_, res.status, - Progress(), out)) { + Progress(), out, true)) { return false; } @@ -4663,7 +4677,7 @@ inline bool Client::process_request(Stream &strm, const Request &req, int dummy_status; if (!detail::read_content(strm, res, (std::numeric_limits::max)(), - dummy_status, req.progress, out)) { + dummy_status, req.progress, out, decompress_)) { return false; } } @@ -5025,6 +5039,8 @@ inline void Client::set_follow_location(bool on) { follow_location_ = on; } inline void Client::set_compress(bool on) { compress_ = on; } +inline void Client::set_decompress(bool on) { decompress_ = on; } + inline void Client::set_interface(const char *intf) { interface_ = intf; } inline void Client::set_proxy(const char *host, int port) { diff --git a/test/test.cc b/test/test.cc index e77c369..2a2ce2a 100644 --- a/test/test.cc +++ b/test/test.cc @@ -2206,6 +2206,21 @@ TEST_F(ServerTest, GzipWithContentReceiver) { EXPECT_EQ(200, res->status); } +TEST_F(ServerTest, GzipWithoutDecompressing) { + Headers headers; + headers.emplace("Accept-Encoding", "gzip, deflate"); + + cli_.set_decompress(false); + auto res = cli_.Get("/gzip", headers); + + ASSERT_TRUE(res != nullptr); + EXPECT_EQ("gzip", res->get_header_value("Content-Encoding")); + EXPECT_EQ("text/plain", res->get_header_value("Content-Type")); + EXPECT_EQ("33", res->get_header_value("Content-Length")); + EXPECT_EQ(33, res->body.size()); + EXPECT_EQ(200, res->status); +} + TEST_F(ServerTest, GzipWithContentReceiverWithoutAcceptEncoding) { Headers headers; std::string body;