diff options
| author | Stefan Boberg <[email protected]> | 2025-03-04 09:38:13 +0100 |
|---|---|---|
| committer | GitHub Enterprise <[email protected]> | 2025-03-04 09:38:13 +0100 |
| commit | 2232eb28256ec54beaf3dbe06f5176698c7245a0 (patch) | |
| tree | de7ae8468a0b4b79003b0c0f1fcbab72abdc36d6 /src/zenhttp/include | |
| parent | refactor use chunk sequence download (#291) (diff) | |
| download | zen-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.h | 48 |
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); } } |