Loading src/http/HttpProxyServer.cpp +14 −1 Changes for src/http/HttpProxyServer.cpp: 14 added lines, 1 removed line. Original line number Diff line number Diff line Loading @@ -59,6 +59,19 @@ std::string normalizeHost(const std::string &hostHeader) { return host; } // A plain url.rfind(prefix, 0) == 0 is a raw character-prefix test with no notion of path // segments: pathPrefix "/app" would wrongly also match "/application/foo" (and even "/app2" // wins the longest-prefix tiebreak over "/app" only by luck of also being defined -- with no // "/app2" route at all, "/app2/foo" would silently be swallowed by "/app"). Require the match // to land on a segment boundary: either url == prefix exactly, prefix already ends in '/' (so // it supplies its own separator), or the very next character in url is '/'. bool pathPrefixMatches(const std::string &url, const std::string &prefix) { if (url.rfind(prefix, 0) != 0) return false; if (url.size() == prefix.size()) return true; if (!prefix.empty() && prefix.back() == '/') return true; return url[prefix.size()] == '/'; } netplus::TlsTrustPolicy trustPolicyFor(const store::HttpRouteRecord &route) { netplus::TlsTrustPolicy policy; policy.verifyPeer = route.tlsVerifyUpstream; Loading Loading @@ -256,7 +269,7 @@ void HttpProxyController::RequestEvent(libhttppp::HttpRequest &curreq, const int bool bestIsDomainSpecific = false; auto routes = _configStore.listHttpRoutes(); for (const auto &route : routes) { if (url.rfind(route.pathPrefix, 0) != 0) continue; if (!pathPrefixMatches(url, route.pathPrefix)) continue; bool wildcard = route.domain.empty() || route.domain == "*"; if (!wildcard && normalizeHost(route.domain) != requestHost) continue; bool domainSpecific = !wildcard; Loading Loading
src/http/HttpProxyServer.cpp +14 −1 Changes for src/http/HttpProxyServer.cpp: 14 added lines, 1 removed line. Original line number Diff line number Diff line Loading @@ -59,6 +59,19 @@ std::string normalizeHost(const std::string &hostHeader) { return host; } // A plain url.rfind(prefix, 0) == 0 is a raw character-prefix test with no notion of path // segments: pathPrefix "/app" would wrongly also match "/application/foo" (and even "/app2" // wins the longest-prefix tiebreak over "/app" only by luck of also being defined -- with no // "/app2" route at all, "/app2/foo" would silently be swallowed by "/app"). Require the match // to land on a segment boundary: either url == prefix exactly, prefix already ends in '/' (so // it supplies its own separator), or the very next character in url is '/'. bool pathPrefixMatches(const std::string &url, const std::string &prefix) { if (url.rfind(prefix, 0) != 0) return false; if (url.size() == prefix.size()) return true; if (!prefix.empty() && prefix.back() == '/') return true; return url[prefix.size()] == '/'; } netplus::TlsTrustPolicy trustPolicyFor(const store::HttpRouteRecord &route) { netplus::TlsTrustPolicy policy; policy.verifyPeer = route.tlsVerifyUpstream; Loading Loading @@ -256,7 +269,7 @@ void HttpProxyController::RequestEvent(libhttppp::HttpRequest &curreq, const int bool bestIsDomainSpecific = false; auto routes = _configStore.listHttpRoutes(); for (const auto &route : routes) { if (url.rfind(route.pathPrefix, 0) != 0) continue; if (!pathPrefixMatches(url, route.pathPrefix)) continue; bool wildcard = route.domain.empty() || route.domain == "*"; if (!wildcard && normalizeHost(route.domain) != requestHost) continue; bool domainSpecific = !wildcard; Loading