From c7cb743a690f36de44c50f6c996a0ed68f52b830 Mon Sep 17 00:00:00 2001 From: Benjamin Sergeant Date: Wed, 5 Jun 2019 15:52:31 -0700 Subject: [PATCH] fix command line tools --- ixwebsocket/IXHttpClient.cpp | 59 +++++++++++++++++------------------- ixwebsocket/IXHttpClient.h | 20 ++++++------ test/CMakeLists.txt | 4 +-- test/IXHttpClientTest.cpp | 53 ++++++++++++++++---------------- ws/IXSentryClient.cpp | 34 ++++++++++----------- ws/ws_http_client.cpp | 44 +++++++++++++-------------- 6 files changed, 105 insertions(+), 109 deletions(-) diff --git a/ixwebsocket/IXHttpClient.cpp b/ixwebsocket/IXHttpClient.cpp index ae661b9c..d39ac253 100644 --- a/ixwebsocket/IXHttpClient.cpp +++ b/ixwebsocket/IXHttpClient.cpp @@ -13,7 +13,6 @@ #include #include #include -#include #include @@ -96,20 +95,18 @@ namespace ix if (_stop) return; - HttpResponsePtr response = request(args->url, args->verb, args->body, *args); + HttpResponsePtr response = request(args->url, args->verb, args->body, args); onResponseCallback(response); if (_stop) return; } - - std::cout << "HttpClient::run() finished" << std::endl; } HttpResponsePtr HttpClient::request( const std::string& url, const std::string& verb, const std::string& body, - const HttpRequestArgs& args, + HttpRequestArgsPtr args, int redirects) { uint64_t uploadSize = 0; @@ -146,13 +143,13 @@ namespace ix ss << verb << " " << path << " HTTP/1.1\r\n"; ss << "Host: " << host << "\r\n"; - if (args.compress) + if (args->compress) { ss << "Accept-Encoding: gzip" << "\r\n"; } // Append extra headers - for (auto&& it : args.extraHeaders) + for (auto&& it : args->extraHeaders) { ss << it.first << ": " << it.second << "\r\n"; } @@ -174,7 +171,7 @@ namespace ix ss << "Content-Length: " << body.size() << "\r\n"; // Set default Content-Type if unspecified - if (args.extraHeaders.find("Content-Type") == args.extraHeaders.end()) + if (args->extraHeaders.find("Content-Type") == args->extraHeaders.end()) { ss << "Content-Type: application/x-www-form-urlencoded" << "\r\n"; } @@ -192,7 +189,7 @@ namespace ix // Make a cancellation object dealing with connection timeout auto isCancellationRequested = - makeCancellationRequestWithTimeout(args.connectTimeout, requestInitCancellation); + makeCancellationRequestWithTimeout(args->connectTimeout, requestInitCancellation); bool success = _socket->connect(host, port, errMsg, isCancellationRequested); if (!success) @@ -206,9 +203,9 @@ namespace ix // Make a new cancellation object dealing with transfer timeout isCancellationRequested = - makeCancellationRequestWithTimeout(args.transferTimeout, requestInitCancellation); + makeCancellationRequestWithTimeout(args->transferTimeout, requestInitCancellation); - if (args.verbose) + if (args->verbose) { std::stringstream ss; ss << "Sending " << verb << " request " @@ -244,7 +241,7 @@ namespace ix uploadSize, downloadSize); } - if (args.verbose) + if (args->verbose) { std::stringstream ss; ss << "Status line " << line; @@ -272,7 +269,7 @@ namespace ix } // Redirect ? - if ((code >= 301 && code <= 308) && args.followRedirects) + if ((code >= 301 && code <= 308) && args->followRedirects) { if (headers.find("Location") == headers.end()) { @@ -282,7 +279,7 @@ namespace ix uploadSize, downloadSize); } - if (redirects >= args.maxRedirects) + if (redirects >= args->maxRedirects) { std::stringstream ss; ss << "Too many redirects: " << redirects; @@ -314,7 +311,7 @@ namespace ix payload.reserve(contentLength); auto chunkResult = _socket->readBytes(contentLength, - args.onProgressCallback, + args->onProgressCallback, isCancellationRequested); if (!chunkResult.first) { @@ -347,7 +344,7 @@ namespace ix ss << std::hex << line; ss >> chunkSize; - if (args.verbose) + if (args->verbose) { std::stringstream oss; oss << "Reading " << chunkSize << " bytes" @@ -359,7 +356,7 @@ namespace ix // Read a chunk auto chunkResult = _socket->readBytes((size_t) chunkSize, - args.onProgressCallback, + args->onProgressCallback, isCancellationRequested); if (!chunkResult.first) { @@ -417,47 +414,47 @@ namespace ix } HttpResponsePtr HttpClient::get(const std::string& url, - const HttpRequestArgs& args) + HttpRequestArgsPtr args) { return request(url, kGet, std::string(), args); } HttpResponsePtr HttpClient::head(const std::string& url, - const HttpRequestArgs& args) + HttpRequestArgsPtr args) { return request(url, kHead, std::string(), args); } HttpResponsePtr HttpClient::del(const std::string& url, - const HttpRequestArgs& args) + HttpRequestArgsPtr args) { return request(url, kDel, std::string(), args); } HttpResponsePtr HttpClient::post(const std::string& url, - const HttpParameters& httpParameters, - const HttpRequestArgs& args) + const HttpParameters& httpParameters, + HttpRequestArgsPtr args) { return request(url, kPost, serializeHttpParameters(httpParameters), args); } HttpResponsePtr HttpClient::post(const std::string& url, - const std::string& body, - const HttpRequestArgs& args) + const std::string& body, + HttpRequestArgsPtr args) { return request(url, kPost, body, args); } HttpResponsePtr HttpClient::put(const std::string& url, - const HttpParameters& httpParameters, - const HttpRequestArgs& args) + const HttpParameters& httpParameters, + HttpRequestArgsPtr args) { return request(url, kPut, serializeHttpParameters(httpParameters), args); } HttpResponsePtr HttpClient::put(const std::string& url, - const std::string& body, - const HttpRequestArgs& args) + const std::string& body, + const HttpRequestArgsPtr args) { return request(url, kPut, body, args); } @@ -559,11 +556,11 @@ namespace ix } void HttpClient::log(const std::string& msg, - const HttpRequestArgs& args) + HttpRequestArgsPtr args) { - if (args.logger) + if (args->logger) { - args.logger(msg); + args->logger(msg); } } } diff --git a/ixwebsocket/IXHttpClient.h b/ixwebsocket/IXHttpClient.h index a41a0a06..7a0e7273 100644 --- a/ixwebsocket/IXHttpClient.h +++ b/ixwebsocket/IXHttpClient.h @@ -98,32 +98,32 @@ namespace ix HttpClient(bool async = false); ~HttpClient(); - HttpResponsePtr get(const std::string& url, const HttpRequestArgs& args); - HttpResponsePtr head(const std::string& url, const HttpRequestArgs& args); - HttpResponsePtr del(const std::string& url, const HttpRequestArgs& args); + HttpResponsePtr get(const std::string& url, HttpRequestArgsPtr args); + HttpResponsePtr head(const std::string& url, HttpRequestArgsPtr args); + HttpResponsePtr del(const std::string& url, HttpRequestArgsPtr args); HttpResponsePtr post(const std::string& url, const HttpParameters& httpParameters, - const HttpRequestArgs& args); + HttpRequestArgsPtr args); HttpResponsePtr post(const std::string& url, const std::string& body, - const HttpRequestArgs& args); + HttpRequestArgsPtr args); HttpResponsePtr put(const std::string& url, const HttpParameters& httpParameters, - const HttpRequestArgs& args); + HttpRequestArgsPtr args); HttpResponsePtr put(const std::string& url, const std::string& body, - const HttpRequestArgs& args); + HttpRequestArgsPtr args); HttpResponsePtr request(const std::string& url, const std::string& verb, const std::string& body, - const HttpRequestArgs& args, + HttpRequestArgsPtr args, int redirects = 0); // Async API - HttpRequestArgsPtr createRequest(const std::string& url, + HttpRequestArgsPtr createRequest(const std::string& url = std::string(), const std::string& verb = HttpClient::kGet); bool performRequest(HttpRequestArgsPtr request, @@ -140,7 +140,7 @@ namespace ix const static std::string kPut; private: - void log(const std::string& msg, const HttpRequestArgs& args); + void log(const std::string& msg, HttpRequestArgsPtr args); bool gzipInflate(const std::string& in, std::string& out); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 17bd0035..31a9867d 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -10,8 +10,8 @@ set (CMAKE_CXX_STANDARD 14) if (NOT WIN32) set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../third_party/sanitizers-cmake/cmake" ${CMAKE_MODULE_PATH}) find_package(Sanitizers) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address") - set(CMAKE_LD_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread") + set(CMAKE_LD_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread") option(USE_TLS "Add TLS support" ON) endif() diff --git a/test/IXHttpClientTest.cpp b/test/IXHttpClientTest.cpp index c7cdbc82..95087735 100644 --- a/test/IXHttpClientTest.cpp +++ b/test/IXHttpClientTest.cpp @@ -15,30 +15,30 @@ TEST_CASE("http client", "[http]") { SECTION("Connect to a remote HTTP server") { - std::string url("http://httpbin.org/"); - + HttpClient httpClient; WebSocketHttpHeaders headers; - HttpRequestArgs args; - args.extraHeaders = headers; - args.connectTimeout = 60; - args.transferTimeout = 60; - args.followRedirects = true; - args.maxRedirects = 10; - args.verbose = true; - args.compress = true; - args.logger = [](const std::string& msg) + std::string url("http://httpbin.org/"); + auto args = httpClient.createRequest(url); + + args->extraHeaders = headers; + args->connectTimeout = 60; + args->transferTimeout = 60; + args->followRedirects = true; + args->maxRedirects = 10; + args->verbose = true; + args->compress = true; + args->logger = [](const std::string& msg) { std::cout << msg; }; - args.onProgressCallback = [](int current, int total) -> bool + args->onProgressCallback = [](int current, int total) -> bool { std::cerr << "\r" << "Downloaded " << current << " bytes out of " << total; return true; }; - HttpClient httpClient; auto response = httpClient.get(url, args); for (auto it : response->headers) @@ -56,30 +56,30 @@ TEST_CASE("http client", "[http]") SECTION("Connect to a remote HTTPS server") { - std::string url("https://httpbin.org/"); - + HttpClient httpClient; WebSocketHttpHeaders headers; - HttpRequestArgs args; - args.extraHeaders = headers; - args.connectTimeout = 60; - args.transferTimeout = 60; - args.followRedirects = true; - args.maxRedirects = 10; - args.verbose = true; - args.compress = true; - args.logger = [](const std::string& msg) + std::string url("https://httpbin.org/"); + auto args = httpClient.createRequest(url); + + args->extraHeaders = headers; + args->connectTimeout = 60; + args->transferTimeout = 60; + args->followRedirects = true; + args->maxRedirects = 10; + args->verbose = true; + args->compress = true; + args->logger = [](const std::string& msg) { std::cout << msg; }; - args.onProgressCallback = [](int current, int total) -> bool + args->onProgressCallback = [](int current, int total) -> bool { std::cerr << "\r" << "Downloaded " << current << " bytes out of " << total; return true; }; - HttpClient httpClient; auto response = httpClient.get(url, args); for (auto it : response->headers) @@ -144,7 +144,6 @@ TEST_CASE("http client", "[http]") wait += 10; } - std::cerr << "Done" << std::endl; REQUIRE(statusCode == 200); } diff --git a/ws/IXSentryClient.cpp b/ws/IXSentryClient.cpp index 5e78e420..11334e56 100644 --- a/ws/IXSentryClient.cpp +++ b/ws/IXSentryClient.cpp @@ -141,42 +141,42 @@ namespace ix bool SentryClient::send(const Json::Value& msg, bool verbose) { - HttpRequestArgs args; - args.extraHeaders["X-Sentry-Auth"] = SentryClient::computeAuthHeader(); - args.connectTimeout = 60; - args.transferTimeout = 5 * 60; - args.followRedirects = true; - args.verbose = verbose; - args.logger = [](const std::string& msg) + auto args = _httpClient.createRequest(); + args->extraHeaders["X-Sentry-Auth"] = SentryClient::computeAuthHeader(); + args->connectTimeout = 60; + args->transferTimeout = 5 * 60; + args->followRedirects = true; + args->verbose = verbose; + args->logger = [](const std::string& msg) { std::cout << msg; }; std::string body = computePayload(msg); - HttpResponse response = _httpClient.post(_url, body, args); + HttpResponsePtr response = _httpClient.post(_url, body, args); if (verbose) { - for (auto it : response.headers) + for (auto it : response->headers) { std::cerr << it.first << ": " << it.second << std::endl; } - std::cerr << "Upload size: " << response.uploadSize << std::endl; - std::cerr << "Download size: " << response.downloadSize << std::endl; + std::cerr << "Upload size: " << response->uploadSize << std::endl; + std::cerr << "Download size: " << response->downloadSize << std::endl; - std::cerr << "Status: " << response.statusCode << std::endl; - if (response.errorCode != HttpErrorCode::Ok) + std::cerr << "Status: " << response->statusCode << std::endl; + if (response->errorCode != HttpErrorCode::Ok) { - std::cerr << "error message: " << response.errorMsg << std::endl; + std::cerr << "error message: " << response->errorMsg << std::endl; } - if (response.headers["Content-Type"] != "application/octet-stream") + if (response->headers["Content-Type"] != "application/octet-stream") { - std::cerr << "payload: " << response.payload << std::endl; + std::cerr << "payload: " << response->payload << std::endl; } } - return response.statusCode == 200; + return response->statusCode == 200; } } // namespace ix diff --git a/ws/ws_http_client.cpp b/ws/ws_http_client.cpp index 2a2b366d..52b79c17 100644 --- a/ws/ws_http_client.cpp +++ b/ws/ws_http_client.cpp @@ -95,19 +95,20 @@ namespace ix const std::string& output, bool compress) { - HttpRequestArgs args; - args.extraHeaders = parseHeaders(headersData); - args.connectTimeout = connectTimeout; - args.transferTimeout = transferTimeout; - args.followRedirects = followRedirects; - args.maxRedirects = maxRedirects; - args.verbose = verbose; - args.compress = compress; - args.logger = [](const std::string& msg) + HttpClient httpClient; + auto args = httpClient.createRequest(); + args->extraHeaders = parseHeaders(headersData); + args->connectTimeout = connectTimeout; + args->transferTimeout = transferTimeout; + args->followRedirects = followRedirects; + args->maxRedirects = maxRedirects; + args->verbose = verbose; + args->compress = compress; + args->logger = [](const std::string& msg) { std::cout << msg; }; - args.onProgressCallback = [](int current, int total) -> bool + args->onProgressCallback = [](int current, int total) -> bool { std::cerr << "\r" << "Downloaded " << current << " bytes out of " << total; @@ -116,8 +117,7 @@ namespace ix HttpParameters httpParameters = parsePostParameters(data); - HttpClient httpClient; - HttpResponse response; + HttpResponsePtr response; if (headersOnly) { response = httpClient.head(url, args); @@ -133,21 +133,21 @@ namespace ix std::cerr << std::endl; - for (auto it : response.headers) + for (auto it : response->headers) { std::cerr << it.first << ": " << it.second << std::endl; } - std::cerr << "Upload size: " << response.uploadSize << std::endl; - std::cerr << "Download size: " << response.downloadSize << std::endl; + std::cerr << "Upload size: " << response->uploadSize << std::endl; + std::cerr << "Download size: " << response->downloadSize << std::endl; - std::cerr << "Status: " << response.statusCode << std::endl; - if (response.errorCode != HttpErrorCode::Ok) + std::cerr << "Status: " << response->statusCode << std::endl; + if (response->errorCode != HttpErrorCode::Ok) { - std::cerr << "error message: " << response.errorMsg << std::endl; + std::cerr << "error message: " << response->errorMsg << std::endl; } - if (!headersOnly && response.errorCode == HttpErrorCode::Ok) + if (!headersOnly && response->errorCode == HttpErrorCode::Ok) { if (save || !output.empty()) { @@ -160,14 +160,14 @@ namespace ix std::cout << "Writing to disk: " << filename << std::endl; std::ofstream out(filename); - out.write((char*)&response.payload.front(), response.payload.size()); + out.write((char*)&response->payload.front(), response->payload.size()); out.close(); } else { - if (response.headers["Content-Type"] != "application/octet-stream") + if (response->headers["Content-Type"] != "application/octet-stream") { - std::cout << "payload: " << response.payload << std::endl; + std::cout << "payload: " << response->payload << std::endl; } else {