Browse Source

Support for deflate compression (#360)

rymis 5 years ago
parent
commit
f2bb9c45d6
2 changed files with 24 additions and 8 deletions
  1. 11 8
      httplib.h
  2. 13 0
      test/test.cc

+ 11 - 8
httplib.h

@@ -1667,14 +1667,15 @@ inline bool compress(std::string &content) {
 class decompressor {
 class decompressor {
 public:
 public:
   decompressor() {
   decompressor() {
+    std::memset(&strm, 0, sizeof(strm));
     strm.zalloc = Z_NULL;
     strm.zalloc = Z_NULL;
     strm.zfree = Z_NULL;
     strm.zfree = Z_NULL;
     strm.opaque = Z_NULL;
     strm.opaque = Z_NULL;
 
 
     // 15 is the value of wbits, which should be at the maximum possible value
     // 15 is the value of wbits, which should be at the maximum possible value
-    // to ensure that any gzip stream can be decoded. The offset of 16 specifies
-    // that the stream to decompress will be formatted with a gzip wrapper.
-    is_valid_ = inflateInit2(&strm, 16 + 15) == Z_OK;
+    // to ensure that any gzip stream can be decoded. The offset of 32 specifies
+    // that the stream type should be automatically detected either gzip or deflate.
+    is_valid_ = inflateInit2(&strm, 32 + 15) == Z_OK;
   }
   }
 
 
   ~decompressor() { inflateEnd(&strm); }
   ~decompressor() { inflateEnd(&strm); }
@@ -1872,12 +1873,14 @@ bool read_content(Stream &strm, T &x, size_t payload_max_length, int &status,
 #ifdef CPPHTTPLIB_ZLIB_SUPPORT
 #ifdef CPPHTTPLIB_ZLIB_SUPPORT
   decompressor decompressor;
   decompressor decompressor;
 
 
-  if (!decompressor.is_valid()) {
-    status = 500;
-    return false;
-  }
+  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;
+    }
 
 
-  if (x.get_header_value("Content-Encoding") == "gzip") {
     out = [&](const char *buf, size_t n) {
     out = [&](const char *buf, size_t n) {
       return decompressor.decompress(
       return decompressor.decompress(
           buf, n, [&](const char *buf, size_t n) { return receiver(buf, n); });
           buf, n, [&](const char *buf, size_t n) { return receiver(buf, n); });

+ 13 - 0
test/test.cc

@@ -1705,6 +1705,19 @@ TEST_F(ServerTest, PutLargeFileWithGzip) {
   EXPECT_EQ(200, res->status);
   EXPECT_EQ(200, res->status);
   EXPECT_EQ(LARGE_DATA, res->body);
   EXPECT_EQ(LARGE_DATA, res->body);
 }
 }
+
+TEST_F(ServerTest, PutContentWithDeflate) {
+  cli_.set_compress(false);
+  httplib::Headers headers;
+  headers.emplace("Content-Encoding", "deflate");
+  // PUT in deflate format:
+  auto res = cli_.Put("/put", headers, "\170\234\013\010\015\001\0\001\361\0\372", "text/plain");
+
+  ASSERT_TRUE(res != nullptr);
+  EXPECT_EQ(200, res->status);
+  EXPECT_EQ("PUT", res->body);
+}
+
 #endif
 #endif
 
 
 TEST_F(ServerTest, Patch) {
 TEST_F(ServerTest, Patch) {