diff options
Diffstat (limited to 'src/zenhttp/httpclient.cpp')
| -rw-r--r-- | src/zenhttp/httpclient.cpp | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/src/zenhttp/httpclient.cpp b/src/zenhttp/httpclient.cpp index 9d5846f71..b6a07250e 100644 --- a/src/zenhttp/httpclient.cpp +++ b/src/zenhttp/httpclient.cpp @@ -320,6 +320,62 @@ HttpClient::Response::IsSuccess() const noexcept return !Error && IsHttpSuccessCode(StatusCode); } +std::string_view +HttpClient::Response::FindHeader(std::string_view Name) const +{ + // Scan the raw arena first - the async client populates this and leaves + // Header empty by default. Lines are "Key: Value\r\n" (the trailing \r\n + // is what curl hands the HEADER callback; we keep it verbatim). + if (!HeaderArena.empty()) + { + std::string_view View(HeaderArena); + while (!View.empty()) + { + const size_t LineEnd = View.find('\n'); + std::string_view Line = LineEnd == std::string_view::npos ? View : View.substr(0, LineEnd); + View = LineEnd == std::string_view::npos ? std::string_view{} : View.substr(LineEnd + 1); + + while (!Line.empty() && (Line.back() == '\r' || Line.back() == '\n')) + { + Line.remove_suffix(1); + } + if (Line.empty()) + { + continue; + } + const size_t Colon = Line.find(':'); + if (Colon == std::string_view::npos) + { + continue; // HTTP status line or malformed + } + std::string_view K = Line.substr(0, Colon); + std::string_view V = Line.substr(Colon + 1); + while (!K.empty() && K.back() == ' ') + { + K.remove_suffix(1); + } + while (!V.empty() && V.front() == ' ') + { + V.remove_prefix(1); + } + if (StrCaseEquals(K, Name)) + { + return V; + } + } + } + + // Fall back to the parsed map (sync client populates this). + for (const auto& [K, V] : *Header) + { + if (StrCaseEquals(K, Name)) + { + return V; + } + } + return {}; +} + std::string HttpClient::Response::ErrorMessage(std::string_view Prefix) const { |