Commit 3d62e7ff authored by Jan Koester's avatar Jan Koester
Browse files

dav support

parent 3eea21e9
Loading
Loading
Loading
Loading
+18 −15
Changes for src/http/HttpProxyServer.cpp: 18 added lines, 15 removed lines.
Original line number Diff line number Diff line
@@ -17,19 +17,6 @@ namespace proxyplus::httpproxy {

namespace {

std::string methodName(int requestType) {
    switch (requestType) {
        case GETREQUEST: return "GET";
        case POSTREQUEST: return "POST";
        case PUTREQUEST: return "PUT";
        case DELETEREQUEST: return "DELETE";
        case OPTIONSREQUEST: return "OPTIONS";
        case HEADREQUEST: return "HEAD";
        case PATCHREQUEST: return "PATCH";
        default: return "UNKNOWN";
    }
}

// Parses a hex-encoded SHA-256 fingerprint (e.g. "AB:CD:..." or "abcd...", as produced by
// `openssl x509 -noout -fingerprint -sha256`) into its raw 32 bytes. Returns empty on any
// malformed input -- callers skip those rather than fail the whole route.
@@ -389,7 +376,10 @@ void HttpProxyController::RequestEvent(libhttppp::HttpRequest &curreq, const int
                                        ULONG_PTR /*args*/) {
    try {
        std::string sourceIp = sourceIpOf(curreq);
        std::string method = methodName(curreq.getRequestType());
        const int requestType = curreq.getRequestType();
        // The original token, not RequestMethodName(requestType): libhttppp maps methods it
        // doesn't know to GETREQUEST, and those must hit the 501 below, not be proxied as GET.
        std::string method = curreq.getRequestMethod();
        std::string url = curreq.getRequestURL();

        if (method == "GET" && tryServeAcmeChallenge(curreq, url)) return;
@@ -466,10 +456,14 @@ void HttpProxyController::RequestEvent(libhttppp::HttpRequest &curreq, const int
            }
        }

        // WebDAV methods are what Nextcloud/ownCloud clients and CalDAV/CardDAV sync use
        // (remote.php/dav) -- without them a DAV mount only gets as far as OPTIONS.
        static const std::set<std::string> kForwardableMethods = {
            "GET", "POST", "PUT", "DELETE", "OPTIONS", "HEAD", "PATCH",
            "PROPFIND", "PROPPATCH", "MKCOL", "COPY", "MOVE", "LOCK", "UNLOCK", "REPORT", "SEARCH",
        };
        if (!kForwardableMethods.count(method)) {
        if (!kForwardableMethods.count(method) ||
            libhttppp::RequestMethodName(requestType) != method) {
            sendError(curreq, HTTP501, "forwarding not implemented for method " + method);
            return;
        }
@@ -608,6 +602,15 @@ void HttpProxyController::RequestEvent(libhttppp::HttpRequest &curreq, const int
            } else if (method == "HEAD") {
                outreq.setRequestType(HEADREQUEST);
                body = client.Head(outreq, /*maxTries=*/1);
            } else if (method != "GET") {
                // WebDAV: forward the body whenever the client sent one (PROPFIND/PROPPATCH/
                // LOCK/REPORT/SEARCH carry XML; COPY/MOVE usually don't). Depth/Destination/
                // Overwrite/If/Lock-Token pass through via the header copy above.
                outreq.setRequestType(requestType);
                std::vector<char> requestBody(curreq.RecvData.begin(), curreq.RecvData.end());
                body = client.Request(requestType, outreq,
                                      requestBody.empty() ? nullptr : &requestBody,
                                      /*maxTries=*/1);
            } else {
                outreq.setRequestType(GETREQUEST);