Commit 4f70487c authored by jan.koester's avatar jan.koester
Browse files

test

parent a0b57b95
Loading
Loading
Loading
Loading
+14 −1
Changes for src/http/HttpProxyServer.cpp: 14 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -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;
@@ -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;