diff options
| author | Zousar Shaker <[email protected]> | 2021-11-30 23:46:12 -0700 |
|---|---|---|
| committer | Zousar Shaker <[email protected]> | 2021-11-30 23:46:12 -0700 |
| commit | e77dab8eeaa0c20fa0dfc973a225d682ac8a1c6e (patch) | |
| tree | fb7ed72a752794e27a518a1d1164e8ef1d1a4b07 | |
| parent | Address review feedback and fix issue when deploying. (diff) | |
| download | zen-e77dab8eeaa0c20fa0dfc973a225d682ac8a1c6e.tar.xz zen-e77dab8eeaa0c20fa0dfc973a225d682ac8a1c6e.zip | |
Handle double slashes in URL path by normalizing them away like http.sys.
Also treat backslashes in the path as forward slashes.
Only allocate memory for the altered URL if needed.
| -rw-r--r-- | zenhttp/httpasio.cpp | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/zenhttp/httpasio.cpp b/zenhttp/httpasio.cpp index b9db108db..ecca05e08 100644 --- a/zenhttp/httpasio.cpp +++ b/zenhttp/httpasio.cpp @@ -122,7 +122,7 @@ struct HttpRequest HttpVerb RequestVerb() const { return m_RequestVerb; } bool IsKeepAlive() const { return m_KeepAlive; } - std::string_view Url() const { return std::string_view(m_Url, m_UrlLength); } + 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); } IoBuffer Body() { return m_BodyBuffer; } @@ -179,6 +179,7 @@ private: uint64_t m_BodyPosition = 0; http_parser m_Parser; char m_HeaderBuffer[1024]; + std::string m_NormalizedUrl; void AppendInputBytes(const char* Data, size_t Bytes); void AppendCurrentHeader(); @@ -816,6 +817,34 @@ HttpRequest::OnHeadersComplete() m_QueryLength = Url.size() - QuerySplit - 1; } + bool bLastCharWasSeparator = false; + for (std::string_view::size_type UrlIndex = 0; UrlIndex < m_UrlLength; ++UrlIndex) + { + char UrlChar = m_Url[UrlIndex]; + bool bIsSeparator = (UrlChar == '\\') || (UrlChar == '/'); + + if ((UrlChar == '\\') || (bIsSeparator && bLastCharWasSeparator)) + { + if (m_NormalizedUrl.empty()) + { + m_NormalizedUrl.reserve(m_UrlLength); + m_NormalizedUrl.append(m_Url, UrlIndex); + } + + if (!bLastCharWasSeparator) + { + m_NormalizedUrl.push_back('/'); + } + } + else if (!m_NormalizedUrl.empty()) + { + m_NormalizedUrl.push_back(UrlChar); + } + + bLastCharWasSeparator = bIsSeparator; + } + + return 0; } @@ -856,6 +885,7 @@ HttpRequest::ResetState() m_BodyBuffer = {}; m_BodyPosition = 0; m_Headers.clear(); + m_NormalizedUrl.clear(); } int |