Commit 079ca564 authored by jan.koester's avatar jan.koester
Browse files

test

parent 747b70a2
Loading
Loading
Loading
Loading
+15 −2
Changes for src/http/HttpProxyServer.cpp: 15 added lines, 2 removed lines.
Original line number Diff line number Diff line
@@ -103,6 +103,19 @@ netplus::TlsTrustPolicy trustPolicyFor(const store::HttpRouteRecord &route) {

} // namespace

std::string detail::buildForwardTarget(const std::string &routePath,
                                       const std::string &originalTarget,
                                       const std::string &pathPrefix) {
    std::string target = routePath.substr(pathPrefix.size());
    if (target.empty() || target[0] != '/') target = "/" + target;

    // HttpRequest::getRequestURL() intentionally strips the query string for route matching.
    // Recover it from getRequest(), which retains the complete request target for H1/H2/H3.
    const size_t query = originalTarget.find('?');
    if (query != std::string::npos) target.append(originalTarget.substr(query));
    return target;
}

HttpProxyController::HttpProxyController(std::vector<netplus::socket *> serverSockets,
                                          std::string listenerLabel,
                                          bool tlsActive,
@@ -371,8 +384,8 @@ void HttpProxyController::RequestEvent(libhttppp::HttpRequest &curreq, const int

        // The route matches on pathPrefix (e.g. "/bolli"), but the backend is mounted
        // at "/" and knows nothing about that prefix -- forward the remainder only.
        std::string forwardPath = url.substr(matched.pathPrefix.size());
        if (forwardPath.empty() || forwardPath[0] != '/') forwardPath = "/" + forwardPath;
        std::string forwardPath = detail::buildForwardTarget(
            url, curreq.getRequest(), matched.pathPrefix);

        bool upstreamOk = false;
        try {
+11 −0
Changes for src/http/HttpProxyServer.h: 11 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -17,6 +17,17 @@

namespace proxyplus::httpproxy {

namespace detail {

// Builds the origin-form request target sent upstream. routePath is deliberately the
// query-free value used for route matching, while originalTarget supplies the query string
// that must survive proxying (notably Git smart HTTP's ?service=git-upload-pack discovery).
std::string buildForwardTarget(const std::string &routePath,
                               const std::string &originalTarget,
                               const std::string &pathPrefix);

} // namespace detail

// The per-connection request handler. There is no reverse-proxy class in libhttppp (see
// docs/ARCHITECTURE.md §4) -- this combines HttpEvent::RequestEvent (inbound) with
// HttpClient (outbound) itself.
+4 −0
Changes for test/CMakeLists.txt: 4 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -19,3 +19,7 @@ add_test(NAME test_jose COMMAND test_jose)
add_executable(test_loadbalancer test_loadbalancer.cpp)
target_link_libraries(test_loadbalancer PRIVATE proxyplus_core)
add_test(NAME test_loadbalancer COMMAND test_loadbalancer)

add_executable(test_http_proxy_paths test_http_proxy_paths.cpp)
target_link_libraries(test_http_proxy_paths PRIVATE proxyplus_core)
add_test(NAME test_http_proxy_paths COMMAND test_http_proxy_paths)
+30 −0
Changes for test/test_http_proxy_paths.cpp: 30 added lines, 0 removed lines.
Original line number Diff line number Diff line
#include <cassert>
#include <iostream>

#include "../src/http/HttpProxyServer.h"

using proxyplus::httpproxy::detail::buildForwardTarget;

int main() {
    assert(buildForwardTarget("/git/tuxist/authdb.git/info/refs",
                              "/git/tuxist/authdb.git/info/refs?service=git-upload-pack",
                              "/git") ==
           "/tuxist/authdb.git/info/refs?service=git-upload-pack");

    assert(buildForwardTarget("/git/tuxist/authdb.git/git-upload-pack",
                              "/git/tuxist/authdb.git/git-upload-pack",
                              "/git") ==
           "/tuxist/authdb.git/git-upload-pack");

    assert(buildForwardTarget("/git", "/git?service=git-upload-pack", "/git") ==
           "/?service=git-upload-pack");

    // Absolute-form request targets are legal in HTTP/1.1 and still carry the same query.
    assert(buildForwardTarget("/git/project/info/refs",
                              "https://git.tuxist.de/git/project/info/refs?service=git-upload-pack",
                              "/git") ==
           "/project/info/refs?service=git-upload-pack");

    std::cout << "test_http_proxy_paths: OK" << std::endl;
    return 0;
}