From e3e9a221812a8d914f49cbec141b306600242cb9 Mon Sep 17 00:00:00 2001 From: Chunting Gu Date: Thu, 11 Oct 2018 14:32:34 +0800 Subject: [PATCH] Limit the HTTP body content to dump/log. --- example/rest_github_client/CMakeLists.txt | 2 +- example/rest_github_client/main.cc | 27 ++++++++++++++++++++++- webcc/globals.h | 5 +++++ webcc/http_message.cc | 24 ++++++++++++++++++-- 4 files changed, 54 insertions(+), 4 deletions(-) diff --git a/example/rest_github_client/CMakeLists.txt b/example/rest_github_client/CMakeLists.txt index f1d9fce..3c9917d 100644 --- a/example/rest_github_client/CMakeLists.txt +++ b/example/rest_github_client/CMakeLists.txt @@ -5,6 +5,6 @@ if(WIN32) set(SSL_LIBS ${SSL_LIBS} crypt32) endif() -target_link_libraries(rest_github_client webcc ${Boost_LIBRARIES}) +target_link_libraries(rest_github_client webcc jsoncpp ${Boost_LIBRARIES}) target_link_libraries(rest_github_client "${CMAKE_THREAD_LIBS_INIT}") target_link_libraries(rest_github_client ${SSL_LIBS}) diff --git a/example/rest_github_client/main.cc b/example/rest_github_client/main.cc index 09b5b5c..3c06dbd 100644 --- a/example/rest_github_client/main.cc +++ b/example/rest_github_client/main.cc @@ -1,13 +1,38 @@ #include +#include "json/json.h" + #include "webcc/rest_ssl_client.h" #include "webcc/logger.h" +static Json::Value StringToJson(const std::string& str) { + Json::Value json; + + Json::CharReaderBuilder builder; + std::stringstream stream(str); + std::string errs; + if (!Json::parseFromStream(builder, stream, &json, &errs)) { + std::cerr << errs << std::endl; + } + + return json; +} + void Test() { webcc::RestSslClient client("api.github.com"); if (client.Get("/events")) { - std::cout << client.response()->content() << std::endl; + Json::Value json = StringToJson(client.response()->content()); + + // Pretty print the JSON. + + Json::StreamWriterBuilder builder; + builder["indentation"] = " "; + + std::unique_ptr writer(builder.newStreamWriter()); + writer->write(json, &std::cout); + + std::cout << std::endl; } else { std::cout << webcc::DescribeError(client.error()); if (client.timed_out()) { diff --git a/webcc/globals.h b/webcc/globals.h index 863e5ce..aeeff7b 100644 --- a/webcc/globals.h +++ b/webcc/globals.h @@ -40,6 +40,11 @@ const std::size_t kInvalidLength = std::string::npos; // Default timeout for reading response. const int kMaxReadSeconds = 30; +// Max size of the HTTP body to dump/log. +// If the HTTP, e.g., response, has a very large content, it will be truncated +// when dumped/logged. +const std::size_t kMaxDumpSize = 2048; + // HTTP headers. extern const std::string kHost; extern const std::string kContentType; diff --git a/webcc/http_message.cc b/webcc/http_message.cc index 17c39e1..f9a0cdf 100644 --- a/webcc/http_message.cc +++ b/webcc/http_message.cc @@ -77,14 +77,34 @@ void HttpMessage::Dump(std::ostream& os, std::size_t indent, os << indent_str << std::endl; + // NOTE: The content will be truncated if it's too large to display. + if (!content_.empty()) { if (indent == 0) { - os << content_ << std::endl; + if (content_.size() > kMaxDumpSize) { + os.write(content_.c_str(), kMaxDumpSize); + os << "..." << std::endl; + } else { + os << content_ << std::endl; + } } else { + // Split by EOL to achieve more readability. std::vector splitted; boost::split(splitted, content_, boost::is_any_of(CRLF)); + + std::size_t size = 0; + for (const std::string& line : splitted) { - os << indent_str << line << std::endl; + os << indent_str; + + if (line.size() + size > kMaxDumpSize) { + os.write(line.c_str(), kMaxDumpSize - size); + os << "..." << std::endl; + break; + } else { + os << line << std::endl; + size += line.size(); + } } } }