(http client + server + ws) Add support for compressing http client requests with gzip. --compress_request argument is used in ws to enable this. The Content-Encoding is set to gzip, and decoded on the server side if present.
This commit is contained in:
		@@ -2,6 +2,10 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
All changes to this project will be documented in this file.
 | 
					All changes to this project will be documented in this file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## [10.5.1] - 2020-10-09
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(http client + server + ws) Add support for compressing http client requests with gzip. --compress_request argument is used in ws to enable this. The Content-Encoding is set to gzip, and decoded on the server side if present.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## [10.5.0] - 2020-09-30
 | 
					## [10.5.0] - 2020-09-30
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(http client + server + ws) Add support for uploading files with ws -F foo=@filename, new -D http server option to debug incoming client requests, internal api changed for http POST, PUT and PATCH to supply an HttpFormDataParameters
 | 
					(http client + server + ws) Add support for uploading files with ws -F foo=@filename, new -D http server option to debug incoming client requests, internal api changed for http POST, PUT and PATCH to supply an HttpFormDataParameters
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,6 +7,7 @@
 | 
				
			|||||||
#include "IXHttp.h"
 | 
					#include "IXHttp.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "IXCancellationRequest.h"
 | 
					#include "IXCancellationRequest.h"
 | 
				
			||||||
 | 
					#include "IXGzipCodec.h"
 | 
				
			||||||
#include "IXSocket.h"
 | 
					#include "IXSocket.h"
 | 
				
			||||||
#include <sstream>
 | 
					#include <sstream>
 | 
				
			||||||
#include <vector>
 | 
					#include <vector>
 | 
				
			||||||
@@ -157,6 +158,23 @@ namespace ix
 | 
				
			|||||||
            body = res.second;
 | 
					            body = res.second;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // If the content was compressed with gzip, decode it
 | 
				
			||||||
 | 
					        if (headers["Content-Encoding"] == "gzip")
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					#ifdef IXWEBSOCKET_USE_ZLIB
 | 
				
			||||||
 | 
					            std::string decompressedPayload;
 | 
				
			||||||
 | 
					            if (!gzipDecompress(body, decompressedPayload))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return std::make_tuple(
 | 
				
			||||||
 | 
					                    false, std::string("Error during gzip decompression of the body"), httpRequest);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            body = decompressedPayload;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					            std::string errorMsg("ixwebsocket was not compiled with gzip support on");
 | 
				
			||||||
 | 
					            return std::make_tuple(false, errorMsg, httpRequest);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        httpRequest = std::make_shared<HttpRequest>(uri, method, httpVersion, body, headers);
 | 
					        httpRequest = std::make_shared<HttpRequest>(uri, method, httpVersion, body, headers);
 | 
				
			||||||
        return std::make_tuple(true, "", httpRequest);
 | 
					        return std::make_tuple(true, "", httpRequest);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -84,6 +84,7 @@ namespace ix
 | 
				
			|||||||
        int maxRedirects = 5;
 | 
					        int maxRedirects = 5;
 | 
				
			||||||
        bool verbose = false;
 | 
					        bool verbose = false;
 | 
				
			||||||
        bool compress = true;
 | 
					        bool compress = true;
 | 
				
			||||||
 | 
					        bool compressRequest = false;
 | 
				
			||||||
        Logger logger;
 | 
					        Logger logger;
 | 
				
			||||||
        OnProgressCallback onProgressCallback;
 | 
					        OnProgressCallback onProgressCallback;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -203,6 +203,13 @@ namespace ix
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if (verb == kPost || verb == kPut || verb == kPatch || _forceBody)
 | 
					        if (verb == kPost || verb == kPut || verb == kPatch || _forceBody)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
					            // Set request compression header
 | 
				
			||||||
 | 
					            if (args->compressRequest)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                ss << "Content-Encoding: gzip"
 | 
				
			||||||
 | 
					                   << "\r\n";
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            ss << "Content-Length: " << body.size() << "\r\n";
 | 
					            ss << "Content-Length: " << body.size() << "\r\n";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Set default Content-Type if unspecified
 | 
					            // Set default Content-Type if unspecified
 | 
				
			||||||
@@ -553,23 +560,41 @@ namespace ix
 | 
				
			|||||||
        return request(url, kDel, std::string(), args);
 | 
					        return request(url, kDel, std::string(), args);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    HttpResponsePtr HttpClient::post(const std::string& url,
 | 
					    HttpResponsePtr HttpClient::request(const std::string& url,
 | 
				
			||||||
                                     const HttpParameters& httpParameters,
 | 
					                                        const std::string& verb,
 | 
				
			||||||
                                     const HttpFormDataParameters& httpFormDataParameters,
 | 
					                                        const HttpParameters& httpParameters,
 | 
				
			||||||
                                     HttpRequestArgsPtr args)
 | 
					                                        const HttpFormDataParameters& httpFormDataParameters,
 | 
				
			||||||
 | 
					                                        HttpRequestArgsPtr args)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        std::string body;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (httpFormDataParameters.empty())
 | 
					        if (httpFormDataParameters.empty())
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return request(url, kPost, serializeHttpParameters(httpParameters), args);
 | 
					            body = serializeHttpParameters(httpParameters);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            std::string multipartBoundary = generateMultipartBoundary();
 | 
					            std::string multipartBoundary = generateMultipartBoundary();
 | 
				
			||||||
            args->multipartBoundary = multipartBoundary;
 | 
					            args->multipartBoundary = multipartBoundary;
 | 
				
			||||||
            std::string body = serializeHttpFormDataParameters(
 | 
					            body = serializeHttpFormDataParameters(
 | 
				
			||||||
                multipartBoundary, httpFormDataParameters, httpParameters);
 | 
					                multipartBoundary, httpFormDataParameters, httpParameters);
 | 
				
			||||||
            return request(url, kPost, body, args);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (args->compressRequest)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            body = gzipCompress(body);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return request(url, verb, body, args);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    HttpResponsePtr HttpClient::post(const std::string& url,
 | 
				
			||||||
 | 
					                                     const HttpParameters& httpParameters,
 | 
				
			||||||
 | 
					                                     const HttpFormDataParameters& httpFormDataParameters,
 | 
				
			||||||
 | 
					                                     HttpRequestArgsPtr args)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return request(url, kPost, httpParameters, httpFormDataParameters, args);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    HttpResponsePtr HttpClient::post(const std::string& url,
 | 
					    HttpResponsePtr HttpClient::post(const std::string& url,
 | 
				
			||||||
@@ -584,18 +609,7 @@ namespace ix
 | 
				
			|||||||
                                    const HttpFormDataParameters& httpFormDataParameters,
 | 
					                                    const HttpFormDataParameters& httpFormDataParameters,
 | 
				
			||||||
                                    HttpRequestArgsPtr args)
 | 
					                                    HttpRequestArgsPtr args)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (httpFormDataParameters.empty())
 | 
					        return request(url, kPut, httpParameters, httpFormDataParameters, args);
 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            return request(url, kPut, serializeHttpParameters(httpParameters), args);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        else
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            std::string multipartBoundary = generateMultipartBoundary();
 | 
					 | 
				
			||||||
            args->multipartBoundary = multipartBoundary;
 | 
					 | 
				
			||||||
            std::string body = serializeHttpFormDataParameters(
 | 
					 | 
				
			||||||
                multipartBoundary, httpFormDataParameters, httpParameters);
 | 
					 | 
				
			||||||
            return request(url, kPut, body, args);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    HttpResponsePtr HttpClient::put(const std::string& url,
 | 
					    HttpResponsePtr HttpClient::put(const std::string& url,
 | 
				
			||||||
@@ -610,18 +624,7 @@ namespace ix
 | 
				
			|||||||
                                      const HttpFormDataParameters& httpFormDataParameters,
 | 
					                                      const HttpFormDataParameters& httpFormDataParameters,
 | 
				
			||||||
                                      HttpRequestArgsPtr args)
 | 
					                                      HttpRequestArgsPtr args)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (httpFormDataParameters.empty())
 | 
					        return request(url, kPatch, httpParameters, httpFormDataParameters, args);
 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            return request(url, kPatch, serializeHttpParameters(httpParameters), args);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        else
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            std::string multipartBoundary = generateMultipartBoundary();
 | 
					 | 
				
			||||||
            args->multipartBoundary = multipartBoundary;
 | 
					 | 
				
			||||||
            std::string body = serializeHttpFormDataParameters(
 | 
					 | 
				
			||||||
                multipartBoundary, httpFormDataParameters, httpParameters);
 | 
					 | 
				
			||||||
            return request(url, kPatch, body, args);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    HttpResponsePtr HttpClient::patch(const std::string& url,
 | 
					    HttpResponsePtr HttpClient::patch(const std::string& url,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -61,7 +61,15 @@ namespace ix
 | 
				
			|||||||
                                const std::string& body,
 | 
					                                const std::string& body,
 | 
				
			||||||
                                HttpRequestArgsPtr args,
 | 
					                                HttpRequestArgsPtr args,
 | 
				
			||||||
                                int redirects = 0);
 | 
					                                int redirects = 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        HttpResponsePtr request(const std::string& url,
 | 
				
			||||||
 | 
					                                const std::string& verb,
 | 
				
			||||||
 | 
					                                const HttpParameters& httpParameters,
 | 
				
			||||||
 | 
					                                const HttpFormDataParameters& httpFormDataParameters,
 | 
				
			||||||
 | 
					                                HttpRequestArgsPtr args);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void setForceBody(bool value);
 | 
					        void setForceBody(bool value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Async API
 | 
					        // Async API
 | 
				
			||||||
        HttpRequestArgsPtr createRequest(const std::string& url = std::string(),
 | 
					        HttpRequestArgsPtr createRequest(const std::string& url = std::string(),
 | 
				
			||||||
                                         const std::string& verb = HttpClient::kGet);
 | 
					                                         const std::string& verb = HttpClient::kGet);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,4 +6,4 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define IX_WEBSOCKET_VERSION "10.5.0"
 | 
					#define IX_WEBSOCKET_VERSION "10.5.1"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1540,6 +1540,7 @@ namespace ix
 | 
				
			|||||||
                            bool save,
 | 
					                            bool save,
 | 
				
			||||||
                            const std::string& output,
 | 
					                            const std::string& output,
 | 
				
			||||||
                            bool compress,
 | 
					                            bool compress,
 | 
				
			||||||
 | 
					                            bool compressRequest,
 | 
				
			||||||
                            const ix::SocketTLSOptions& tlsOptions)
 | 
					                            const ix::SocketTLSOptions& tlsOptions)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        HttpClient httpClient;
 | 
					        HttpClient httpClient;
 | 
				
			||||||
@@ -1553,6 +1554,7 @@ namespace ix
 | 
				
			|||||||
        args->maxRedirects = maxRedirects;
 | 
					        args->maxRedirects = maxRedirects;
 | 
				
			||||||
        args->verbose = verbose;
 | 
					        args->verbose = verbose;
 | 
				
			||||||
        args->compress = compress;
 | 
					        args->compress = compress;
 | 
				
			||||||
 | 
					        args->compressRequest = compressRequest;
 | 
				
			||||||
        args->logger = [](const std::string& msg) { spdlog::info(msg); };
 | 
					        args->logger = [](const std::string& msg) { spdlog::info(msg); };
 | 
				
			||||||
        args->onProgressCallback = [verbose](int current, int total) -> bool {
 | 
					        args->onProgressCallback = [verbose](int current, int total) -> bool {
 | 
				
			||||||
            if (verbose)
 | 
					            if (verbose)
 | 
				
			||||||
@@ -3022,6 +3024,7 @@ int main(int argc, char** argv)
 | 
				
			|||||||
    bool quiet = false;
 | 
					    bool quiet = false;
 | 
				
			||||||
    bool fluentd = false;
 | 
					    bool fluentd = false;
 | 
				
			||||||
    bool compress = false;
 | 
					    bool compress = false;
 | 
				
			||||||
 | 
					    bool compressRequest = false;
 | 
				
			||||||
    bool stress = false;
 | 
					    bool stress = false;
 | 
				
			||||||
    bool disableAutomaticReconnection = false;
 | 
					    bool disableAutomaticReconnection = false;
 | 
				
			||||||
    bool disablePerMessageDeflate = false;
 | 
					    bool disablePerMessageDeflate = false;
 | 
				
			||||||
@@ -3198,6 +3201,7 @@ int main(int argc, char** argv)
 | 
				
			|||||||
    httpClientApp->add_flag("-v", verbose, "Verbose");
 | 
					    httpClientApp->add_flag("-v", verbose, "Verbose");
 | 
				
			||||||
    httpClientApp->add_flag("-O", save, "Save output to disk");
 | 
					    httpClientApp->add_flag("-O", save, "Save output to disk");
 | 
				
			||||||
    httpClientApp->add_flag("--compressed", compress, "Enable gzip compression");
 | 
					    httpClientApp->add_flag("--compressed", compress, "Enable gzip compression");
 | 
				
			||||||
 | 
					    httpClientApp->add_flag("--compress_request", compressRequest, "Compress request with gzip");
 | 
				
			||||||
    httpClientApp->add_option("--connect-timeout", connectTimeOut, "Connection timeout");
 | 
					    httpClientApp->add_option("--connect-timeout", connectTimeOut, "Connection timeout");
 | 
				
			||||||
    httpClientApp->add_option("--transfer-timeout", transferTimeout, "Transfer timeout");
 | 
					    httpClientApp->add_option("--transfer-timeout", transferTimeout, "Transfer timeout");
 | 
				
			||||||
    addTLSOptions(httpClientApp);
 | 
					    addTLSOptions(httpClientApp);
 | 
				
			||||||
@@ -3523,6 +3527,7 @@ int main(int argc, char** argv)
 | 
				
			|||||||
                                      save,
 | 
					                                      save,
 | 
				
			||||||
                                      output,
 | 
					                                      output,
 | 
				
			||||||
                                      compress,
 | 
					                                      compress,
 | 
				
			||||||
 | 
					                                      compressRequest,
 | 
				
			||||||
                                      tlsOptions);
 | 
					                                      tlsOptions);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else if (app.got_subcommand("redis_cli"))
 | 
					    else if (app.got_subcommand("redis_cli"))
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user