Browse Source

Added check code to compress and decompress

yhirose 6 years ago
parent
commit
31cdadc4b1
1 changed files with 25 additions and 10 deletions
  1. 25 10
      httplib.h

+ 25 - 10
httplib.h

@@ -908,7 +908,7 @@ inline bool can_compress(const std::string &content_type) {
          content_type == "application/xhtml+xml";
          content_type == "application/xhtml+xml";
 }
 }
 
 
-inline void compress(std::string &content) {
+inline bool compress(std::string &content) {
   z_stream strm;
   z_stream strm;
   strm.zalloc = Z_NULL;
   strm.zalloc = Z_NULL;
   strm.zfree = Z_NULL;
   strm.zfree = Z_NULL;
@@ -916,7 +916,7 @@ inline void compress(std::string &content) {
 
 
   auto ret = deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 31, 8,
   auto ret = deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 31, 8,
                           Z_DEFAULT_STRATEGY);
                           Z_DEFAULT_STRATEGY);
-  if (ret != Z_OK) { return; }
+  if (ret != Z_OK) { return false; }
 
 
   strm.avail_in = content.size();
   strm.avail_in = content.size();
   strm.next_in = (Bytef *)content.data();
   strm.next_in = (Bytef *)content.data();
@@ -928,16 +928,21 @@ inline void compress(std::string &content) {
   do {
   do {
     strm.avail_out = bufsiz;
     strm.avail_out = bufsiz;
     strm.next_out = (Bytef *)buff;
     strm.next_out = (Bytef *)buff;
-    deflate(&strm, Z_FINISH);
+    ret = deflate(&strm, Z_FINISH);
+    assert(ret != Z_STREAM_ERROR);
     compressed.append(buff, bufsiz - strm.avail_out);
     compressed.append(buff, bufsiz - strm.avail_out);
   } while (strm.avail_out == 0);
   } while (strm.avail_out == 0);
 
 
+  assert(ret == Z_STREAM_END);
+  assert(strm.avail_in == 0);
+
   content.swap(compressed);
   content.swap(compressed);
 
 
   deflateEnd(&strm);
   deflateEnd(&strm);
+  return true;
 }
 }
 
 
-inline void decompress(std::string &content) {
+inline bool decompress(std::string &content) {
   z_stream strm;
   z_stream strm;
   strm.zalloc = Z_NULL;
   strm.zalloc = Z_NULL;
   strm.zfree = Z_NULL;
   strm.zfree = Z_NULL;
@@ -947,7 +952,7 @@ inline void decompress(std::string &content) {
   // ensure that any gzip stream can be decoded. The offset of 16 specifies that
   // 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.
   // the stream to decompress will be formatted with a gzip wrapper.
   auto ret = inflateInit2(&strm, 16 + 15);
   auto ret = inflateInit2(&strm, 16 + 15);
-  if (ret != Z_OK) { return; }
+  if (ret != Z_OK) { return false; }
 
 
   strm.avail_in = content.size();
   strm.avail_in = content.size();
   strm.next_in = (Bytef *)content.data();
   strm.next_in = (Bytef *)content.data();
@@ -959,13 +964,22 @@ inline void decompress(std::string &content) {
   do {
   do {
     strm.avail_out = bufsiz;
     strm.avail_out = bufsiz;
     strm.next_out = (Bytef *)buff;
     strm.next_out = (Bytef *)buff;
-    inflate(&strm, Z_NO_FLUSH);
+
+    ret = inflate(&strm, Z_NO_FLUSH);
+    assert(ret != Z_STREAM_ERROR);
+    switch (ret) {
+    case Z_NEED_DICT:
+    case Z_DATA_ERROR:
+    case Z_MEM_ERROR: inflateEnd(&strm); return ret;
+    }
+
     decompressed.append(buff, bufsiz - strm.avail_out);
     decompressed.append(buff, bufsiz - strm.avail_out);
   } while (strm.avail_out == 0);
   } while (strm.avail_out == 0);
 
 
   content.swap(decompressed);
   content.swap(decompressed);
 
 
   inflateEnd(&strm);
   inflateEnd(&strm);
+  return ret == Z_STREAM_END;
 }
 }
 #endif
 #endif
 
 
@@ -1140,7 +1154,7 @@ bool read_content(Stream &strm, T &x, uint64_t payload_max_length, int &status,
   if (ret) {
   if (ret) {
 #ifdef CPPHTTPLIB_ZLIB_SUPPORT
 #ifdef CPPHTTPLIB_ZLIB_SUPPORT
     if (x.get_header_value("Content-Encoding") == "gzip") {
     if (x.get_header_value("Content-Encoding") == "gzip") {
-      detail::decompress(x.body);
+      ret = detail::decompress(x.body);
     }
     }
 #endif
 #endif
   } else {
   } else {
@@ -1158,7 +1172,7 @@ template <typename T> inline void write_headers(Stream &strm, const T &info) {
 }
 }
 
 
 template <typename T>
 template <typename T>
-inline void write_content_chunked(Stream &strm, const T& x) {
+inline void write_content_chunked(Stream &strm, const T &x) {
   auto chunked_response = !x.has_header("Content-Length");
   auto chunked_response = !x.has_header("Content-Length");
   uint64_t offset = 0;
   uint64_t offset = 0;
   auto data_available = true;
   auto data_available = true;
@@ -1695,8 +1709,9 @@ inline void Server::write_response(Stream &strm, bool last_connection,
     const auto &encodings = req.get_header_value("Accept-Encoding");
     const auto &encodings = req.get_header_value("Accept-Encoding");
     if (encodings.find("gzip") != std::string::npos &&
     if (encodings.find("gzip") != std::string::npos &&
         detail::can_compress(res.get_header_value("Content-Type"))) {
         detail::can_compress(res.get_header_value("Content-Type"))) {
-      detail::compress(res.body);
-      res.set_header("Content-Encoding", "gzip");
+      if (detail::compress(res.body)) {
+        res.set_header("Content-Encoding", "gzip");
+      }
     }
     }
 #endif
 #endif