http gzip compression
This commit is contained in:
parent
1db3568375
commit
6d56f7223a
@ -14,6 +14,8 @@
|
|||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include <zlib.h>
|
||||||
|
|
||||||
namespace ix
|
namespace ix
|
||||||
{
|
{
|
||||||
HttpClient::HttpClient()
|
HttpClient::HttpClient()
|
||||||
@ -71,6 +73,11 @@ namespace ix
|
|||||||
ss << "User-Agent: ixwebsocket/1.0.0" << "\r\n";
|
ss << "User-Agent: ixwebsocket/1.0.0" << "\r\n";
|
||||||
ss << "Accept: */*" << "\r\n";
|
ss << "Accept: */*" << "\r\n";
|
||||||
|
|
||||||
|
if (args.compress)
|
||||||
|
{
|
||||||
|
ss << "Accept-Encoding: gzip" << "\r\n";
|
||||||
|
}
|
||||||
|
|
||||||
// Append extra headers
|
// Append extra headers
|
||||||
for (auto&& it : args.extraHeaders)
|
for (auto&& it : args.extraHeaders)
|
||||||
{
|
{
|
||||||
@ -193,11 +200,13 @@ namespace ix
|
|||||||
{
|
{
|
||||||
ss.str("");
|
ss.str("");
|
||||||
ss << "Cannot read byte";
|
ss << "Cannot read byte";
|
||||||
return std::make_tuple(-1, headers, payload, ss.str());
|
return std::make_tuple(-1, headers, payload, "Cannot read byte");
|
||||||
}
|
}
|
||||||
|
|
||||||
payload += c;
|
payload += c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::cout << "I WAS HERE" << std::endl;
|
||||||
}
|
}
|
||||||
else if (headers.find("transfer-encoding") != headers.end() &&
|
else if (headers.find("transfer-encoding") != headers.end() &&
|
||||||
headers["transfer-encoding"] == "chunked")
|
headers["transfer-encoding"] == "chunked")
|
||||||
@ -264,7 +273,21 @@ namespace ix
|
|||||||
{
|
{
|
||||||
code = 0; // 0 ?
|
code = 0; // 0 ?
|
||||||
std::string errorMsg("Cannot read http body");
|
std::string errorMsg("Cannot read http body");
|
||||||
return std::make_tuple(code, headers, payload, errorMsg);
|
return std::make_tuple(-1, headers, payload, errorMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the content was compressed with gzip, decode it
|
||||||
|
if (headers["Content-Encoding"] == "gzip")
|
||||||
|
{
|
||||||
|
if (args.verbose) std::cout << "Decoding gzip..." << std::endl;
|
||||||
|
|
||||||
|
std::string decompressedPayload;
|
||||||
|
if (!gzipInflate(payload, decompressedPayload))
|
||||||
|
{
|
||||||
|
std::string errorMsg("Error decompressing payload");
|
||||||
|
return std::make_tuple(-1, headers, payload, errorMsg);
|
||||||
|
}
|
||||||
|
payload = decompressedPayload;
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::make_tuple(code, headers, payload, "");
|
return std::make_tuple(code, headers, payload, "");
|
||||||
@ -338,4 +361,53 @@ namespace ix
|
|||||||
}
|
}
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool HttpClient::gzipInflate(
|
||||||
|
const std::string& in,
|
||||||
|
std::string& out)
|
||||||
|
{
|
||||||
|
z_stream inflateState;
|
||||||
|
memset(&inflateState, 0, sizeof(inflateState));
|
||||||
|
|
||||||
|
inflateState.zalloc = Z_NULL;
|
||||||
|
inflateState.zfree = Z_NULL;
|
||||||
|
inflateState.opaque = Z_NULL;
|
||||||
|
inflateState.avail_in = 0;
|
||||||
|
inflateState.next_in = Z_NULL;
|
||||||
|
|
||||||
|
if (inflateInit2(&inflateState, 16+MAX_WBITS) != Z_OK)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inflateState.avail_in = (uInt) in.size();
|
||||||
|
inflateState.next_in = (unsigned char *)(const_cast<char *>(in.data()));
|
||||||
|
|
||||||
|
const int kBufferSize = 1 << 14;
|
||||||
|
|
||||||
|
std::unique_ptr<unsigned char[]> compressBuffer =
|
||||||
|
std::make_unique<unsigned char[]>(kBufferSize);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
inflateState.avail_out = (uInt) kBufferSize;
|
||||||
|
inflateState.next_out = compressBuffer.get();
|
||||||
|
|
||||||
|
int ret = inflate(&inflateState, Z_SYNC_FLUSH);
|
||||||
|
|
||||||
|
if (ret == Z_NEED_DICT || ret == Z_DATA_ERROR || ret == Z_MEM_ERROR)
|
||||||
|
{
|
||||||
|
inflateEnd(&inflateState);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
out.append(
|
||||||
|
reinterpret_cast<char *>(compressBuffer.get()),
|
||||||
|
kBufferSize - inflateState.avail_out
|
||||||
|
);
|
||||||
|
} while (inflateState.avail_out == 0);
|
||||||
|
|
||||||
|
inflateEnd(&inflateState);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ namespace ix
|
|||||||
int timeoutSecs;
|
int timeoutSecs;
|
||||||
bool followRedirects;
|
bool followRedirects;
|
||||||
bool verbose;
|
bool verbose;
|
||||||
|
bool compress;
|
||||||
};
|
};
|
||||||
|
|
||||||
class HttpClient {
|
class HttpClient {
|
||||||
@ -54,6 +55,10 @@ namespace ix
|
|||||||
|
|
||||||
std::string urlEncode(const std::string& value);
|
std::string urlEncode(const std::string& value);
|
||||||
|
|
||||||
|
bool gzipInflate(
|
||||||
|
const std::string& in,
|
||||||
|
std::string& out);
|
||||||
|
|
||||||
std::shared_ptr<Socket> _socket;
|
std::shared_ptr<Socket> _socket;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -57,9 +57,6 @@ namespace ix
|
|||||||
std::string name(lineStr.substr(0, colon));
|
std::string name(lineStr.substr(0, colon));
|
||||||
std::string value(lineStr.substr(colon + 2, i - colon - 4));
|
std::string value(lineStr.substr(colon + 2, i - colon - 4));
|
||||||
|
|
||||||
// Make the name lower case.
|
|
||||||
std::transform(name.begin(), name.end(), name.begin(), ::tolower);
|
|
||||||
|
|
||||||
headers[name] = value;
|
headers[name] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,7 @@ int main(int argc, char** argv)
|
|||||||
bool followRedirects = false;
|
bool followRedirects = false;
|
||||||
bool verbose = false;
|
bool verbose = false;
|
||||||
bool save = false;
|
bool save = false;
|
||||||
|
bool compress = false;
|
||||||
int port = 8080;
|
int port = 8080;
|
||||||
int connectTimeOutSeconds = 3;
|
int connectTimeOutSeconds = 3;
|
||||||
|
|
||||||
@ -71,6 +72,7 @@ int main(int argc, char** argv)
|
|||||||
httpClientApp->add_flag("-L", followRedirects, "Header");
|
httpClientApp->add_flag("-L", followRedirects, "Header");
|
||||||
httpClientApp->add_flag("-v", verbose, "Verbose");
|
httpClientApp->add_flag("-v", verbose, "Verbose");
|
||||||
httpClientApp->add_flag("-O", save, "Save to disk");
|
httpClientApp->add_flag("-O", save, "Save to disk");
|
||||||
|
httpClientApp->add_flag("--compress", compress, "gzip compression");
|
||||||
httpClientApp->add_option("--connect-timeout", connectTimeOutSeconds, "Connection timeout");
|
httpClientApp->add_option("--connect-timeout", connectTimeOutSeconds, "Connection timeout");
|
||||||
|
|
||||||
CLI11_PARSE(app, argc, argv);
|
CLI11_PARSE(app, argc, argv);
|
||||||
@ -114,7 +116,8 @@ int main(int argc, char** argv)
|
|||||||
{
|
{
|
||||||
return ix::ws_http_client_main(url, headers, data,
|
return ix::ws_http_client_main(url, headers, data,
|
||||||
headersOnly, connectTimeOutSeconds,
|
headersOnly, connectTimeOutSeconds,
|
||||||
followRedirects, verbose, save, output);
|
followRedirects, verbose, save, output,
|
||||||
|
compress);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
3
ws/ws.h
3
ws/ws.h
@ -17,7 +17,8 @@ namespace ix
|
|||||||
bool followRedirects,
|
bool followRedirects,
|
||||||
bool verbose,
|
bool verbose,
|
||||||
bool save,
|
bool save,
|
||||||
const std::string& output);
|
const std::string& output,
|
||||||
|
bool compress);
|
||||||
|
|
||||||
int ws_ping_pong_main(const std::string& url);
|
int ws_ping_pong_main(const std::string& url);
|
||||||
|
|
||||||
|
@ -90,7 +90,8 @@ namespace ix
|
|||||||
bool followRedirects,
|
bool followRedirects,
|
||||||
bool verbose,
|
bool verbose,
|
||||||
bool save,
|
bool save,
|
||||||
const std::string& output)
|
const std::string& output,
|
||||||
|
bool compress)
|
||||||
{
|
{
|
||||||
HttpRequestArgs args;
|
HttpRequestArgs args;
|
||||||
args.url = url;
|
args.url = url;
|
||||||
@ -98,6 +99,7 @@ namespace ix
|
|||||||
args.timeoutSecs = timeoutSecs;
|
args.timeoutSecs = timeoutSecs;
|
||||||
args.followRedirects = followRedirects;
|
args.followRedirects = followRedirects;
|
||||||
args.verbose = verbose;
|
args.verbose = verbose;
|
||||||
|
args.compress = compress;
|
||||||
|
|
||||||
HttpParameters httpParameters = parsePostParameters(data);
|
HttpParameters httpParameters = parsePostParameters(data);
|
||||||
|
|
||||||
@ -127,24 +129,13 @@ namespace ix
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::cerr << "error code: " << errorCode << std::endl;
|
std::cerr << "error code: " << errorCode << std::endl;
|
||||||
if (!errorMsg.empty())
|
if (errorCode != 200)
|
||||||
{
|
{
|
||||||
std::cerr << "error message: " << errorMsg << std::endl;
|
std::cerr << "error message: " << errorMsg << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!headersOnly && errorCode == 200)
|
if (!headersOnly && errorCode == 200)
|
||||||
{
|
{
|
||||||
if (responseHeaders["Content-Type"] != "application/octet-stream")
|
|
||||||
{
|
|
||||||
std::cout << "payload: " << payload << std::endl;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::cerr << "Binary output can mess up your terminal." << std::endl;
|
|
||||||
std::cerr << "Use the -O flag to save the file to disk." << std::endl;
|
|
||||||
std::cerr << "You can also use the --output option to specify a filename." << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (save || !output.empty())
|
if (save || !output.empty())
|
||||||
{
|
{
|
||||||
// FIMXE we should decode the url first
|
// FIMXE we should decode the url first
|
||||||
@ -159,6 +150,19 @@ namespace ix
|
|||||||
out.write((char*)&payload.front(), payload.size());
|
out.write((char*)&payload.front(), payload.size());
|
||||||
out.close();
|
out.close();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (responseHeaders["Content-Type"] != "application/octet-stream")
|
||||||
|
{
|
||||||
|
std::cout << "payload: " << payload << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cerr << "Binary output can mess up your terminal." << std::endl;
|
||||||
|
std::cerr << "Use the -O flag to save the file to disk." << std::endl;
|
||||||
|
std::cerr << "You can also use the --output option to specify a filename." << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user