diff options
| author | Dan Engelbrecht <[email protected]> | 2025-09-04 13:17:47 +0200 |
|---|---|---|
| committer | GitHub Enterprise <[email protected]> | 2025-09-04 13:17:47 +0200 |
| commit | 4b7a193ee5533ad82ef1c6b7a673db42b1e8a36f (patch) | |
| tree | fa463ea20972d8e5ff24e35029743cb9296795e6 /src/zenhttp/servers/httpparser.h | |
| parent | add validation of compact binary payloads before reading them (#483) (diff) | |
| download | zen-4b7a193ee5533ad82ef1c6b7a673db42b1e8a36f.tar.xz zen-4b7a193ee5533ad82ef1c6b7a673db42b1e8a36f.zip | |
asio large header support (#484)
- Improvement: Allow large headers support in asio server implementation
Diffstat (limited to 'src/zenhttp/servers/httpparser.h')
| -rw-r--r-- | src/zenhttp/servers/httpparser.h | 103 |
1 files changed, 50 insertions, 53 deletions
diff --git a/src/zenhttp/servers/httpparser.h b/src/zenhttp/servers/httpparser.h index bdbcab4d9..0d2664ec5 100644 --- a/src/zenhttp/servers/httpparser.h +++ b/src/zenhttp/servers/httpparser.h @@ -5,6 +5,8 @@ #include <zencore/uid.h> #include <zenhttp/httpcommon.h> +#include <EASTL/fixed_vector.h> + ZEN_THIRD_PARTY_INCLUDES_START #include <http_parser.h> ZEN_THIRD_PARTY_INCLUDES_END @@ -31,73 +33,68 @@ struct HttpRequestParser HttpVerb RequestVerb() const { return m_RequestVerb; } bool IsKeepAlive() const { return m_KeepAlive; } - std::string_view Url() const { return m_NormalizedUrl.empty() ? std::string_view(m_Url, m_UrlLength) : m_NormalizedUrl; } - std::string_view QueryString() const { return std::string_view(m_QueryString, m_QueryLength); } + std::string_view Url() const { return m_NormalizedUrl.empty() ? GetHeaderSubString(m_UrlRange) : m_NormalizedUrl; } + std::string_view QueryString() const { return GetHeaderSubString(m_QueryStringRange); } IoBuffer Body() { return m_BodyBuffer; } - inline HttpContentType ContentType() - { - if (m_ContentTypeHeaderIndex < 0) - { - return HttpContentType::kUnknownContentType; - } - - return ParseContentType(m_Headers[m_ContentTypeHeaderIndex].Value); - } + inline HttpContentType ContentType() { return ParseContentType(GetHeaderValue(m_ContentTypeHeaderIndex)); } - inline HttpContentType AcceptType() - { - if (m_AcceptHeaderIndex < 0) - { - return HttpContentType::kUnknownContentType; - } - - return ParseContentType(m_Headers[m_AcceptHeaderIndex].Value); - } + inline HttpContentType AcceptType() { return ParseContentType(GetHeaderValue(m_AcceptHeaderIndex)); } Oid SessionId() const { return m_SessionId; } int RequestId() const { return m_RequestId; } - std::string_view RangeHeader() const { return m_RangeHeaderIndex != -1 ? m_Headers[m_RangeHeaderIndex].Value : std::string_view(); } + std::string_view RangeHeader() const { return GetHeaderValue(m_RangeHeaderIndex); } private: + struct HeaderRange + { + uint32_t Offset = 0; + uint32_t Length = 0; + }; + struct HeaderEntry { - HeaderEntry() = default; + HeaderRange NameRange; + HeaderRange ValueRange; + }; - HeaderEntry(std::string_view InName, std::string_view InValue) : Name(InName), Value(InValue) {} + inline std::string_view GetHeaderValue(int8_t HeaderIndex) const + { + if (HeaderIndex == -1) + { + return {}; + } + ZEN_ASSERT(size_t(HeaderIndex) < m_HeaderEntries.size()); + return GetHeaderSubString(m_HeaderEntries[HeaderIndex].ValueRange); + } - std::string_view Name; - std::string_view Value; - }; + std::string_view GetHeaderSubString(const HeaderRange& Range) const + { + ZEN_ASSERT_SLOW(Range.Offset + Range.Length <= m_HeaderData.size()); + return std::string_view(m_HeaderData.begin(), m_HeaderData.size()).substr(Range.Offset, Range.Length); + } - HttpRequestParserCallbacks& m_Connection; - char* m_HeaderCursor = m_HeaderBuffer; - char* m_Url = nullptr; - size_t m_UrlLength = 0; - char* m_QueryString = nullptr; - size_t m_QueryLength = 0; - char* m_CurrentHeaderName = nullptr; // Used while parsing headers - size_t m_CurrentHeaderNameLength = 0; - char* m_CurrentHeaderValue = nullptr; // Used while parsing headers - size_t m_CurrentHeaderValueLength = 0; - std::vector<HeaderEntry> m_Headers; - int8_t m_ContentLengthHeaderIndex; - int8_t m_AcceptHeaderIndex; - int8_t m_ContentTypeHeaderIndex; - int8_t m_RangeHeaderIndex; - HttpVerb m_RequestVerb; - std::atomic_bool m_KeepAlive{false}; - bool m_Expect100Continue = false; - int m_RequestId = -1; - Oid m_SessionId{}; - IoBuffer m_BodyBuffer; - uint64_t m_BodyPosition = 0; - http_parser m_Parser; - char m_HeaderBuffer[1024]; - std::string m_NormalizedUrl; - - void AppendCurrentHeader(); + HttpRequestParserCallbacks& m_Connection; + HeaderRange m_UrlRange; + HeaderRange m_QueryStringRange; + eastl::fixed_vector<HeaderEntry, 16> m_HeaderEntries; + int8_t m_ContentLengthHeaderIndex; + int8_t m_AcceptHeaderIndex; + int8_t m_ContentTypeHeaderIndex; + int8_t m_RangeHeaderIndex; + HttpVerb m_RequestVerb; + std::atomic_bool m_KeepAlive{false}; + bool m_Expect100Continue = false; + int m_RequestId = -1; + Oid m_SessionId{}; + IoBuffer m_BodyBuffer; + uint64_t m_BodyPosition = 0; + http_parser m_Parser; + eastl::fixed_vector<char, 512> m_HeaderData; + std::string m_NormalizedUrl; + + void ParseCurrentHeader(); int OnMessageBegin(); int OnUrl(const char* Data, size_t Bytes); |