aboutsummaryrefslogtreecommitdiff
path: root/src/zenhttp/include
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2025-03-04 09:38:13 +0100
committerGitHub Enterprise <[email protected]>2025-03-04 09:38:13 +0100
commit2232eb28256ec54beaf3dbe06f5176698c7245a0 (patch)
treede7ae8468a0b4b79003b0c0f1fcbab72abdc36d6 /src/zenhttp/include
parentrefactor use chunk sequence download (#291) (diff)
downloadzen-2232eb28256ec54beaf3dbe06f5176698c7245a0.tar.xz
zen-2232eb28256ec54beaf3dbe06f5176698c7245a0.zip
limit and validate responses before logging the text (#292)
Improvement: When logging HTTP responses, the body is now sanity checked to ensure it is human readable, and the length of the output is capped to prevent inadvertent log bloat
Diffstat (limited to 'src/zenhttp/include')
-rw-r--r--src/zenhttp/include/zenhttp/formatters.h48
1 files changed, 47 insertions, 1 deletions
diff --git a/src/zenhttp/include/zenhttp/formatters.h b/src/zenhttp/include/zenhttp/formatters.h
index 538136238..0fa5dc6da 100644
--- a/src/zenhttp/include/zenhttp/formatters.h
+++ b/src/zenhttp/include/zenhttp/formatters.h
@@ -13,6 +13,50 @@ ZEN_THIRD_PARTY_INCLUDES_START
#include <fmt/format.h>
ZEN_THIRD_PARTY_INCLUDES_END
+namespace zen {
+
+struct BodyLogFormatter
+{
+private:
+ std::string_view ResponseText;
+ zen::ExtendableStringBuilder<128> ModifiedResponse;
+
+public:
+ explicit BodyLogFormatter(std::string_view InResponseText) : ResponseText(InResponseText)
+ {
+ using namespace std::literals;
+
+ const int TextSizeLimit = 1024;
+
+ // Trim invalid UTF8
+
+ auto InvalidIt = zen::FindFirstInvalidUtf8Byte(ResponseText);
+
+ if (InvalidIt != end(ResponseText))
+ {
+ ResponseText = ResponseText.substr(0, InvalidIt - begin(ResponseText));
+ }
+
+ if (ResponseText.empty())
+ {
+ ResponseText = "<suppressed non-text response>"sv;
+ }
+
+ if (ResponseText.size() > TextSizeLimit)
+ {
+ const auto TruncatedString = "[truncated response] "sv;
+ ModifiedResponse.Append(TruncatedString);
+ ModifiedResponse.Append(ResponseText.data(), TextSizeLimit - TruncatedString.size());
+
+ ResponseText = ModifiedResponse;
+ }
+ }
+
+ inline std::string_view GetText() const { return ResponseText; }
+};
+
+} // namespace zen
+
template<>
struct fmt::formatter<cpr::Response>
{
@@ -57,6 +101,8 @@ struct fmt::formatter<cpr::Response>
}
else
{
+ zen::BodyLogFormatter Body(Response.text);
+
return fmt::format_to(Ctx.out(),
"Url: {}, Status: {}, Bytes: {}/{} (Up/Down), Elapsed: {}s, Reponse: '{}', Reason: '{}'",
Response.url.str(),
@@ -64,7 +110,7 @@ struct fmt::formatter<cpr::Response>
Response.uploaded_bytes,
Response.downloaded_bytes,
Response.elapsed,
- Response.text,
+ Body.GetText(),
Response.reason);
}
}