aboutsummaryrefslogtreecommitdiff
path: root/src/zenhttp/servers/httpparser.h
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2025-09-04 13:17:47 +0200
committerGitHub Enterprise <[email protected]>2025-09-04 13:17:47 +0200
commit4b7a193ee5533ad82ef1c6b7a673db42b1e8a36f (patch)
treefa463ea20972d8e5ff24e35029743cb9296795e6 /src/zenhttp/servers/httpparser.h
parentadd validation of compact binary payloads before reading them (#483) (diff)
downloadzen-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.h103
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);