(http server) support gzip compression
This commit is contained in:
		@@ -1,6 +1,10 @@
 | 
				
			|||||||
# Changelog
 | 
					# Changelog
 | 
				
			||||||
All changes to this project will be documented in this file.
 | 
					All changes to this project will be documented in this file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## [9.6.5] - 2020-05-29
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(http server) support gzip compression
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## [9.6.4] - 2020-05-20
 | 
					## [9.6.4] - 2020-05-20
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(compiler fix) support clang 5 and earlier (contributed by @LunarWatcher)
 | 
					(compiler fix) support clang 5 and earlier (contributed by @LunarWatcher)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,6 +12,7 @@
 | 
				
			|||||||
#include <fstream>
 | 
					#include <fstream>
 | 
				
			||||||
#include <sstream>
 | 
					#include <sstream>
 | 
				
			||||||
#include <vector>
 | 
					#include <vector>
 | 
				
			||||||
 | 
					#include <zlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace
 | 
					namespace
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -38,6 +39,47 @@ namespace
 | 
				
			|||||||
        auto vec = res.second;
 | 
					        auto vec = res.second;
 | 
				
			||||||
        return std::make_pair(res.first, std::string(vec.begin(), vec.end()));
 | 
					        return std::make_pair(res.first, std::string(vec.begin(), vec.end()));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::string gzipCompress(const std::string& str)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        z_stream zs; // z_stream is zlib's control structure
 | 
				
			||||||
 | 
					        memset(&zs, 0, sizeof(zs));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // deflateInit2 configure the file format: request gzip instead of deflate
 | 
				
			||||||
 | 
					        const int windowBits = 15;
 | 
				
			||||||
 | 
					        const int GZIP_ENCODING = 16;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        deflateInit2(&zs, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
 | 
				
			||||||
 | 
					                     windowBits | GZIP_ENCODING, 8,
 | 
				
			||||||
 | 
					                     Z_DEFAULT_STRATEGY);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        zs.next_in = (Bytef*) str.data();
 | 
				
			||||||
 | 
					        zs.avail_in = (uInt) str.size(); // set the z_stream's input
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        int ret;
 | 
				
			||||||
 | 
					        char outbuffer[32768];
 | 
				
			||||||
 | 
					        std::string outstring;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // retrieve the compressed bytes blockwise
 | 
				
			||||||
 | 
					        do
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            zs.next_out = reinterpret_cast<Bytef*>(outbuffer);
 | 
				
			||||||
 | 
					            zs.avail_out = sizeof(outbuffer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            ret = deflate(&zs, Z_FINISH);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if(outstring.size() < zs.total_out)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                // append the block to the output string
 | 
				
			||||||
 | 
					                outstring.append(outbuffer,
 | 
				
			||||||
 | 
					                                 zs.total_out - outstring.size());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } while(ret == Z_OK);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        deflateEnd(&zs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return outstring;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
} // namespace
 | 
					} // namespace
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace ix
 | 
					namespace ix
 | 
				
			||||||
@@ -120,6 +162,12 @@ namespace ix
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                std::string content = res.second;
 | 
					                std::string content = res.second;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                std::string acceptEncoding = request->headers["Accept-encoding"];
 | 
				
			||||||
 | 
					                if (acceptEncoding == "gzip" or acceptEncoding == "*")
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    content = gzipCompress(content);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                // Log request
 | 
					                // Log request
 | 
				
			||||||
                std::stringstream ss;
 | 
					                std::stringstream ss;
 | 
				
			||||||
                ss << request->method << " " << request->headers["User-Agent"] << " "
 | 
					                ss << request->method << " " << request->headers["User-Agent"] << " "
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,4 +6,4 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define IX_WEBSOCKET_VERSION "9.6.4"
 | 
					#define IX_WEBSOCKET_VERSION "9.6.5"
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								makefile
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								makefile
									
									
									
									
									
								
							@@ -29,7 +29,7 @@ ws_mbedtls_install:
 | 
				
			|||||||
	mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_BUILD_TYPE=MinSizeRel -DUSE_TLS=1 -DUSE_WS=1 -DUSE_MBED_TLS=1 .. ; ninja install)
 | 
						mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_BUILD_TYPE=MinSizeRel -DUSE_TLS=1 -DUSE_WS=1 -DUSE_MBED_TLS=1 .. ; ninja install)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ws:
 | 
					ws:
 | 
				
			||||||
	mkdir -p build && (cd build ; cmake -DCMAKE_BUILD_TYPE=Debug -DUSE_TLS=1 -DUSE_WS=1 .. ; make -j 4)
 | 
						mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_BUILD_TYPE=Debug -DUSE_TLS=1 -DUSE_WS=1 .. ; ninja install)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ws_install:
 | 
					ws_install:
 | 
				
			||||||
	mkdir -p build && (cd build ; cmake -DCMAKE_BUILD_TYPE=MinSizeRel -DUSE_TLS=1 -DUSE_WS=1 .. ; make -j 4 install)
 | 
						mkdir -p build && (cd build ; cmake -DCMAKE_BUILD_TYPE=MinSizeRel -DUSE_TLS=1 -DUSE_WS=1 .. ; make -j 4 install)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -109,8 +109,11 @@ namespace ix
 | 
				
			|||||||
        args->verbose = verbose;
 | 
					        args->verbose = verbose;
 | 
				
			||||||
        args->compress = compress;
 | 
					        args->compress = compress;
 | 
				
			||||||
        args->logger = [](const std::string& msg) { spdlog::info(msg); };
 | 
					        args->logger = [](const std::string& msg) { spdlog::info(msg); };
 | 
				
			||||||
        args->onProgressCallback = [](int current, int total) -> bool {
 | 
					        args->onProgressCallback = [verbose](int current, int total) -> bool {
 | 
				
			||||||
            spdlog::info("Downloaded {} bytes out of {}", current, total);
 | 
					            if (verbose)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                spdlog::info("Downloaded {} bytes out of {}", current, total);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            return true;
 | 
					            return true;
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user