diff options
| author | Zousar Shaker <[email protected]> | 2021-11-24 22:21:12 -0700 |
|---|---|---|
| committer | Zousar Shaker <[email protected]> | 2021-11-24 22:21:12 -0700 |
| commit | 9c78b8c02637649379e80d5da9875026b3c665f1 (patch) | |
| tree | 0e0bab8a4f28cdea568645245a3f9ba31387b41a /zenhttp/httpasio.cpp | |
| parent | Merge pull request #27 from EpicGames/asio-acceptor (diff) | |
| download | zen-9c78b8c02637649379e80d5da9875026b3c665f1.tar.xz zen-9c78b8c02637649379e80d5da9875026b3c665f1.zip | |
Fix asio request routing so that a url of "/cas" will route to the service for prefix "/cas/".
Also change the behavior for asio request routing to adhere to the "longest match rule" like http.sys.
Diffstat (limited to 'zenhttp/httpasio.cpp')
| -rw-r--r-- | zenhttp/httpasio.cpp | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/zenhttp/httpasio.cpp b/zenhttp/httpasio.cpp index d5fe9adbb..ad0f7fefa 100644 --- a/zenhttp/httpasio.cpp +++ b/zenhttp/httpasio.cpp @@ -935,7 +935,7 @@ HttpAsioServerRequest::HttpAsioServerRequest(asio_http::HttpRequest& Request, Ht const int PrefixLength = Service.UriPrefixLength(); std::string_view Uri = Request.Url(); - Uri.remove_prefix(PrefixLength); + Uri.remove_prefix(std::min(PrefixLength, static_cast<int>(Uri.size()))); m_Uri = Uri; m_QueryString = Request.QueryString(); @@ -1099,6 +1099,10 @@ HttpAsioServerImpl::RegisterService(const char* InUrlPath, HttpService& Service) { std::string_view UrlPath(InUrlPath); Service.SetUriPrefixLength(UrlPath.size()); + if (!UrlPath.empty() && UrlPath[UrlPath.size() - 1] == '/') + { + UrlPath.remove_suffix(1); + } RwLock::ExclusiveLockScope _(m_Lock); m_UriHandlers.push_back({std::string(UrlPath), &Service}); @@ -1109,16 +1113,22 @@ HttpAsioServerImpl::RouteRequest(std::string_view Url) { RwLock::SharedLockScope _(m_Lock); + HttpService* CandidateService = nullptr; + std::string::size_type CandidateMatchSize = 0; for (const ServiceEntry& SvcEntry : m_UriHandlers) { const std::string& SvcUrl = SvcEntry.ServiceUrlPath; - if (Url.compare(0, SvcUrl.size(), SvcUrl) == 0) + std::string::size_type SvcUrlSize = SvcUrl.size(); + if ((SvcUrlSize >= CandidateMatchSize) && + Url.compare(0, SvcUrlSize, SvcUrl) == 0 && + ((SvcUrlSize == Url.size()) || (Url[SvcUrlSize] == '/'))) { - return SvcEntry.Service; + CandidateMatchSize = SvcUrl.size(); + CandidateService = SvcEntry.Service; } } - return nullptr; + return CandidateService; } } // namespace zen::asio_http |