aboutsummaryrefslogtreecommitdiff
path: root/zenhttp/httpasio.cpp
diff options
context:
space:
mode:
authorZousar Shaker <[email protected]>2021-11-24 22:21:12 -0700
committerZousar Shaker <[email protected]>2021-11-24 22:21:12 -0700
commit9c78b8c02637649379e80d5da9875026b3c665f1 (patch)
tree0e0bab8a4f28cdea568645245a3f9ba31387b41a /zenhttp/httpasio.cpp
parentMerge pull request #27 from EpicGames/asio-acceptor (diff)
downloadzen-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.cpp18
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