[Libreoffice-commits] online.git: android/lib Makefile.am wsd/FileServer.cpp wsd/FileServer.hpp wsd/LOOLWSD.cpp wsd/LOOLWSD.hpp wsd/RequestDetails.cpp wsd/RequestDetails.hpp wsd/ServerURL.hpp

Michael Meeks (via logerrit) logerrit at kemper.freedesktop.org
Tue May 12 18:30:35 UTC 2020


 Makefile.am                                |    2 
 android/lib/src/main/cpp/CMakeLists.txt.in |    1 
 wsd/FileServer.cpp                         |   22 ++--
 wsd/FileServer.hpp                         |   14 ++
 wsd/LOOLWSD.cpp                            |  159 ++++-------------------------
 wsd/LOOLWSD.hpp                            |    1 
 wsd/RequestDetails.cpp                     |   81 ++++++++++++++
 wsd/RequestDetails.hpp                     |   96 +++++++++++++++++
 wsd/ServerURL.hpp                          |   15 --
 9 files changed, 237 insertions(+), 154 deletions(-)

New commits:
commit dec683218a0c26ecb5f13fd66c653024c2212cb7
Author:     Michael Meeks <michael.meeks at collabora.com>
AuthorDate: Tue May 12 16:19:41 2020 +0100
Commit:     Michael Meeks <michael.meeks at collabora.com>
CommitDate: Tue May 12 20:30:17 2020 +0200

    Proxy: move RequestDetails to its own header.
    
    Share it with various other places requiring similar data.
    
    Change-Id: I873f56798f5a34dcf7440456bd649b68f6d3df98
    Reviewed-on: https://gerrit.libreoffice.org/c/online/+/94069
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
    Reviewed-by: Michael Meeks <michael.meeks at collabora.com>

diff --git a/Makefile.am b/Makefile.am
index 1b5beb47c..d3c79a36b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -115,6 +115,7 @@ loolwsd_sources = common/Crypto.cpp \
                   wsd/LOOLWSD.cpp \
                   wsd/ClientSession.cpp \
                   wsd/FileServer.cpp \
+                  wsd/RequestDetails.cpp \
                   wsd/Storage.cpp \
                   wsd/TileCache.cpp \
                   wsd/ProofKey.cpp
@@ -224,6 +225,7 @@ wsd_headers = wsd/Admin.hpp \
               wsd/LOOLWSD.hpp \
               wsd/ProofKey.hpp \
               wsd/QueueHandler.hpp \
+              wsd/RequestDetails.hpp \
               wsd/SenderQueue.hpp \
               wsd/ServerURL.hpp \
               wsd/Storage.hpp \
diff --git a/android/lib/src/main/cpp/CMakeLists.txt.in b/android/lib/src/main/cpp/CMakeLists.txt.in
index 7b5b5323f..ad43e806c 100644
--- a/android/lib/src/main/cpp/CMakeLists.txt.in
+++ b/android/lib/src/main/cpp/CMakeLists.txt.in
@@ -19,6 +19,7 @@ add_library(androidapp SHARED
             ../../../../../wsd/ClientSession.cpp
             ../../../../../wsd/DocumentBroker.cpp
             ../../../../../wsd/LOOLWSD.cpp
+	    ../../../../../wsd/RequestDetails.cpp
             ../../../../../wsd/Storage.cpp
             ../../../../../wsd/TileCache.cpp)
 
diff --git a/wsd/FileServer.cpp b/wsd/FileServer.cpp
index 8809a582a..3533a389f 100644
--- a/wsd/FileServer.cpp
+++ b/wsd/FileServer.cpp
@@ -265,7 +265,9 @@ bool FileServerRequestHandler::isAdminLoggedIn(const HTTPRequest& request,
     return true;
 }
 
-void FileServerRequestHandler::handleRequest(const HTTPRequest& request, Poco::MemoryInputStream& message,
+void FileServerRequestHandler::handleRequest(const HTTPRequest& request,
+                                             const RequestDetails &requestDetails,
+                                             Poco::MemoryInputStream& message,
                                              const std::shared_ptr<StreamSocket>& socket)
 {
     try
@@ -347,7 +349,7 @@ void FileServerRequestHandler::handleRequest(const HTTPRequest& request, Poco::M
         const std::string loleafletHtml = config.getString("loleaflet_html", "loleaflet.html");
         if (endPoint == loleafletHtml)
         {
-            preprocessFile(request, message, socket);
+            preprocessFile(request, requestDetails, message, socket);
             return;
         }
 
@@ -358,7 +360,7 @@ void FileServerRequestHandler::handleRequest(const HTTPRequest& request, Poco::M
                 endPoint == "adminHistory.html" ||
                 endPoint == "adminAnalytics.html")
             {
-                preprocessAdminFile(request, socket);
+                preprocessAdminFile(request, requestDetails, socket);
                 return;
             }
 
@@ -644,10 +646,12 @@ constexpr char BRANDING_UNSUPPORTED[] = "branding-unsupported";
 namespace {
 }
 
-void FileServerRequestHandler::preprocessFile(const HTTPRequest& request, Poco::MemoryInputStream& message,
+void FileServerRequestHandler::preprocessFile(const HTTPRequest& request,
+                                              const RequestDetails &requestDetails,
+                                              Poco::MemoryInputStream& message,
                                               const std::shared_ptr<StreamSocket>& socket)
 {
-    ServerURL cnxDetails(request);
+    ServerURL cnxDetails(requestDetails);
 
     const Poco::URI::QueryParameters params = Poco::URI(request.getURI()).getQueryParameters();
 
@@ -691,7 +695,7 @@ void FileServerRequestHandler::preprocessFile(const HTTPRequest& request, Poco::
     }
 
     std::string socketProxy = "false";
-    if (request.has("ProxyPrefix"))
+    if (requestDetails.isProxy())
         socketProxy = "true";
     Poco::replaceInPlace(preprocess, std::string("%SOCKET_PROXY%"), socketProxy);
 
@@ -905,7 +909,9 @@ void FileServerRequestHandler::preprocessFile(const HTTPRequest& request, Poco::
     LOG_DBG("Sent file: " << relPath << ": " << preprocess);
 }
 
-void FileServerRequestHandler::preprocessAdminFile(const HTTPRequest& request,const std::shared_ptr<StreamSocket>& socket)
+void FileServerRequestHandler::preprocessAdminFile(const HTTPRequest& request,
+                                                   const RequestDetails &requestDetails,
+                                                   const std::shared_ptr<StreamSocket>& socket)
 {
     Poco::Net::HTTPResponse response;
 
@@ -915,7 +921,7 @@ void FileServerRequestHandler::preprocessAdminFile(const HTTPRequest& request,co
     if (!FileServerRequestHandler::isAdminLoggedIn(request, response))
         throw Poco::Net::NotAuthenticatedException("Invalid admin login");
 
-    ServerURL cnxDetails(request);
+    ServerURL cnxDetails(requestDetails);
     std::string responseRoot = cnxDetails.getResponseRoot();
 
     static const std::string scriptJS("<script src=\"%s/loleaflet/" LOOLWSD_VERSION_HASH "/%s.js\"></script>");
diff --git a/wsd/FileServer.hpp b/wsd/FileServer.hpp
index 47ab86d3c..58cbb0b28 100644
--- a/wsd/FileServer.hpp
+++ b/wsd/FileServer.hpp
@@ -14,19 +14,27 @@
 
 #include <Poco/MemoryStream.h>
 
+class RequestDetails;
 /// Handles file requests over HTTP(S).
 class FileServerRequestHandler
 {
     static std::string getRequestPathname(const Poco::Net::HTTPRequest& request);
 
-    static void preprocessFile(const Poco::Net::HTTPRequest& request, Poco::MemoryInputStream& message,
+    static void preprocessFile(const Poco::Net::HTTPRequest& request,
+                               const RequestDetails &requestDetails,
+                               Poco::MemoryInputStream& message,
                                const std::shared_ptr<StreamSocket>& socket);
-    static void preprocessAdminFile(const Poco::Net::HTTPRequest& request, const std::shared_ptr<StreamSocket>& socket);
+    static void preprocessAdminFile(const Poco::Net::HTTPRequest& request,
+                                    const RequestDetails &requestDetails,
+                                    const std::shared_ptr<StreamSocket>& socket);
 public:
     /// Evaluate if the cookie exists, and if not, ask for the credentials.
     static bool isAdminLoggedIn(const Poco::Net::HTTPRequest& request, Poco::Net::HTTPResponse& response);
 
-    static void handleRequest(const Poco::Net::HTTPRequest& request, Poco::MemoryInputStream& message, const std::shared_ptr<StreamSocket>& socket);
+    static void handleRequest(const Poco::Net::HTTPRequest& request,
+                              const RequestDetails &requestDetails,
+                              Poco::MemoryInputStream& message,
+                              const std::shared_ptr<StreamSocket>& socket);
 
     /// Read all files that we can serve into memory and compress them.
     static void initialize();
diff --git a/wsd/LOOLWSD.cpp b/wsd/LOOLWSD.cpp
index a528238e5..7f455e93a 100644
--- a/wsd/LOOLWSD.cpp
+++ b/wsd/LOOLWSD.cpp
@@ -276,108 +276,6 @@ void alertAllUsersInternal(const std::string& msg)
 
 } // end anonymous namespace
 
-class RequestDetails {
-    Poco::URI _uri;
-    bool _isGet;
-    bool _isHead;
-    bool _isProxy;
-    bool _isWebSocket;
-    std::string _uriString;
-    StringVector _pathSegs;
-public:
-    RequestDetails(Poco::Net::HTTPRequest &request)
-    {
-        // Check and remove the ServiceRoot from the request.getURI()
-        if (!Util::startsWith(request.getURI(), LOOLWSD::ServiceRoot))
-            throw BadRequestException("The request does not start with prefix: " + LOOLWSD::ServiceRoot);
-
-        // re-writes ServiceRoot out of request
-        _uriString = request.getURI().substr(LOOLWSD::ServiceRoot.length());
-        request.setURI(_uriString);
-        _uri = Poco::URI(_uriString);
-        const std::string &method = request.getMethod();
-        _isGet = method == "GET";
-        _isHead = method == "HEAD";
-        _isProxy = request.has("ProxyPrefix");
-        auto it = request.find("Upgrade");
-        _isWebSocket = it != request.end() && (Poco::icompare(it->second, "websocket") == 0);
-
-        std::vector<StringToken> tokens;
-        if (_uriString.size() > 0)
-        {
-            size_t i, start;
-            for (i = start = 0; i < _uriString.size(); ++i)
-            {
-                if (_uriString[i] == '/' || _uriString[i] == '?')
-                {
-                    if (i - start > 1) // ignore empty
-                        tokens.emplace_back(start, i - start);
-                    start = i + 1;
-                }
-            }
-            if (i - start > 1) // ignore empty
-                tokens.emplace_back(start, i - start);
-            _pathSegs = StringVector(_uriString, tokens);
-        }
-    }
-    // matches the WOPISrc if used. For load balancing
-    // must be 2nd element in the path after /lool/<here>
-    std::string getDocumentURI() const
-    {
-        assert(equals(0, "lool"));
-        std::string decodedUri;
-        Poco::URI::decode(_pathSegs[1], decodedUri);
-        return decodedUri;
-    }
-    std::string getURI() const
-    {
-        return _uriString;
-    }
-    bool isProxy() const
-    {
-        return _isProxy;
-    }
-    bool isWebSocket() const
-    {
-        return _isWebSocket;
-    }
-    bool isGet(const char *path) const
-    {
-        return _isGet && _uriString == path;
-    }
-    bool isGetOrHead(const char *path) const
-    {
-        return (_isGet || _isHead) && _uriString == path;
-    }
-    bool startsWith(const char *path)
-    {
-        return !strncmp(_uriString.c_str(), path, strlen(path));
-    }
-    bool equals(size_t index, const char *string) const
-    {
-        return _pathSegs.equals(index, string);
-    }
-    std::string operator[](size_t index) const
-    {
-        return _pathSegs[index];
-    }
-    size_t size() const
-    {
-        return _pathSegs.size();
-    }
-    std::string toString() const
-    {
-        std::ostringstream oss;
-        oss << _uriString << " " << (_isGet?"G":"")
-            << (_isHead?"H":"") << (_isProxy?"Proxy":"")
-            << (_isWebSocket?"WebSocket":"");
-        oss << " path: " << _pathSegs.size();
-        for (size_t i = 0; i < _pathSegs.size(); ++i)
-            oss << " '" << _pathSegs[i] << "'";
-        return oss.str();
-    }
-};
-
 void LOOLWSD::checkSessionLimitsAndWarnClients()
 {
 #if !ENABLE_SUPPORT_KEY
@@ -2377,7 +2275,9 @@ private:
             else if (requestDetails.equals(0, "loleaflet"))
             {
                 // File server
-                handleFileServerRequest(request, message, socket);
+                assert(socket && "Must have a valid socket");
+                FileServerRequestHandler::handleRequest(request, requestDetails, message, socket);
+                socket->shutdown();
             }
             else if (requestDetails.equals(0, "lool") &&
                      requestDetails.equals(1, "adminws"))
@@ -2443,7 +2343,7 @@ private:
 
             else if (requestDetails.isGet("/hosting/discovery") ||
                      requestDetails.isGet("/hosting/discovery/"))
-                handleWopiDiscoveryRequest(request, socket);
+                handleWopiDiscoveryRequest(requestDetails, socket);
 
             else if (requestDetails.isGet(CAPABILITIES_END_POINT))
                 handleCapabilitiesRequest(request, socket);
@@ -2459,11 +2359,11 @@ private:
             }
 
             else if (requestDetails.isProxy() && requestDetails.equals(2, "ws"))
-                handleClientProxyRequest(request, requestDetails.getDocumentURI(), message, disposition);
+                handleClientProxyRequest(request, requestDetails, message, disposition);
 
             else if (requestDetails.equals(0, "lool") &&
                      requestDetails.equals(2, "ws") && requestDetails.isWebSocket())
-                handleClientWsUpgrade(request, requestDetails.getDocumentURI(), disposition, socket);
+                handleClientWsUpgrade(request, requestDetails, disposition, socket);
 
             else if (!requestDetails.isWebSocket() && requestDetails.equals(0, "lool"))
             {
@@ -2512,7 +2412,8 @@ private:
         // The 2nd parameter is the response to the HULLO message (which we
         // respond with the path of the document)
         handleClientWsUpgrade(
-            request, std::string(socket->getInBuffer().data(), socket->getInBuffer().size()),
+            request, RequestDetails(std::string(socket->getInBuffer().data(),
+                                                socket->getInBuffer().size())),
             disposition, socket);
         socket->getInBuffer().clear();
 #endif
@@ -2529,21 +2430,12 @@ private:
     }
 
 #if !MOBILEAPP
-    void handleFileServerRequest(const Poco::Net::HTTPRequest& request,
-                                 Poco::MemoryInputStream& message,
-                                 const std::shared_ptr<StreamSocket>& socket)
-    {
-        assert(socket && "Must have a valid socket");
-        FileServerRequestHandler::handleRequest(request, message, socket);
-        socket->shutdown();
-    }
-
-    void handleRootRequest(const Poco::Net::HTTPRequest& request,
+    void handleRootRequest(const RequestDetails& requestDetails,
                            const std::shared_ptr<StreamSocket>& socket)
     {
         assert(socket && "Must have a valid socket");
 
-        LOG_DBG("HTTP request: " << request.getURI());
+        LOG_DBG("HTTP request: " << requestDetails.getURI());
         const std::string mimeType = "text/plain";
         const std::string responseString = "OK";
 
@@ -2555,22 +2447,20 @@ private:
             "Content-Type: " << mimeType << "\r\n"
             "\r\n";
 
-        if (request.getMethod() == Poco::Net::HTTPRequest::HTTP_GET)
-        {
+        if (requestDetails.isGet())
             oss << responseString;
-        }
 
         socket->send(oss.str());
         socket->shutdown();
         LOG_INF("Sent / response successfully.");
     }
 
-    void handleFaviconRequest(const Poco::Net::HTTPRequest& request,
+    void handleFaviconRequest(const RequestDetails &requestDetails,
                               const std::shared_ptr<StreamSocket>& socket)
     {
         assert(socket && "Must have a valid socket");
 
-        LOG_DBG("Favicon request: " << request.getURI());
+        LOG_DBG("Favicon request: " << requestDetails.getURI());
         std::string mimeType = "image/vnd.microsoft.icon";
         std::string faviconPath = Path(Application::instance().commandPath()).parent().toString() + "favicon.ico";
         if (!File(faviconPath).exists())
@@ -2583,12 +2473,12 @@ private:
         socket->shutdown();
     }
 
-    void handleWopiDiscoveryRequest(const Poco::Net::HTTPRequest& request,
+    void handleWopiDiscoveryRequest(const RequestDetails &requestDetails,
                                     const std::shared_ptr<StreamSocket>& socket)
     {
         assert(socket && "Must have a valid socket");
 
-        LOG_DBG("Wopi discovery request: " << request.getURI());
+        LOG_DBG("Wopi discovery request: " << requestDetails.getURI());
 
         std::string xml = getFileContent("discovery.xml");
         std::string srvUrl =
@@ -2597,10 +2487,10 @@ private:
 #else
             "http://"
 #endif
-            + (LOOLWSD::ServerName.empty() ? request.getHost() : LOOLWSD::ServerName)
+            + (LOOLWSD::ServerName.empty() ? requestDetails.getHostUntrusted() : LOOLWSD::ServerName)
             + LOOLWSD::ServiceRoot;
-        if (request.has("ProxyPrefix"))
-            srvUrl = request["ProxyPrefix"];
+        if (requestDetails.isProxy())
+            srvUrl = requestDetails.getProxyPrefix();
         Poco::replaceInPlace(xml, std::string("%SRV_URI%"), srvUrl);
 
         // TODO: Refactor this to some common handler.
@@ -3015,13 +2905,14 @@ private:
 #endif
 
     void handleClientProxyRequest(const Poco::Net::HTTPRequest& request,
-                                  std::string url,
+                                  const RequestDetails &requestDetails,
                                   Poco::MemoryInputStream& message,
                                   SocketDisposition &disposition)
     {
         if (!request.has("SessionId"))
             throw BadRequestException("No session id header on proxied request");
 
+        std::string url = requestDetails.getDocumentURI();
         std::string sessionId = request.get("SessionId");
 
         LOG_INF("URL [" << url << "].");
@@ -3045,7 +2936,7 @@ private:
             }
         }
 
-        ServerURL serverURL(request);
+        ServerURL serverURL(requestDetails);
 
         LOG_INF("URL [" << LOOLWSD::anonymizeUrl(url) << "] is " << (isReadOnly ? "readonly" : "writable") << ".");
         (void)request; (void)message; (void)disposition;
@@ -3112,14 +3003,16 @@ private:
         }
     }
 
-    void handleClientWsUpgrade(const Poco::Net::HTTPRequest& request, const std::string& url,
+    void handleClientWsUpgrade(const Poco::Net::HTTPRequest& request,
+                               const RequestDetails &requestDetails,
                                SocketDisposition& disposition,
                                const std::shared_ptr<StreamSocket>& socket)
     {
+        std::string url = requestDetails.getDocumentURI();
         assert(socket && "Must have a valid socket");
 
         // must be trace for anonymization
-        LOG_TRC("Client WS request: " << request.getURI() << ", url: " << url << ", socket #" << socket->getFD());
+        LOG_TRC("Client WS request: " << requestDetails.getURI() << ", url: " << url << ", socket #" << socket->getFD());
 
         // First Upgrade.
         auto ws = std::make_shared<WebSocketHandler>(_socket, request);
@@ -3173,7 +3066,7 @@ private:
                 DocumentBroker::ChildType::Interactive, url, docKey, _id, uriPublic);
             if (docBroker)
             {
-                ServerURL serverURL(request);
+                ServerURL serverURL(requestDetails);
                 std::shared_ptr<ClientSession> clientSession =
                     docBroker->createNewClientSession(ws, _id, uriPublic, isReadOnly, serverURL);
                 if (clientSession)
diff --git a/wsd/LOOLWSD.hpp b/wsd/LOOLWSD.hpp
index f5cb6c69d..e161d5fd9 100644
--- a/wsd/LOOLWSD.hpp
+++ b/wsd/LOOLWSD.hpp
@@ -25,6 +25,7 @@
 
 #include "Util.hpp"
 #include "FileUtil.hpp"
+#include "RequestDetails.hpp"
 #include "WebSocketHandler.hpp"
 
 class ChildProcess;
diff --git a/wsd/RequestDetails.cpp b/wsd/RequestDetails.cpp
new file mode 100644
index 000000000..f2127b83f
--- /dev/null
+++ b/wsd/RequestDetails.cpp
@@ -0,0 +1,81 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <config.h>
+#include <Poco/URI.h>
+#include "LOOLWSD.hpp"
+#include "Exceptions.hpp"
+#include "RequestDetails.hpp"
+
+RequestDetails::RequestDetails(Poco::Net::HTTPRequest &request)
+    : _isMobile(false)
+{
+    // Check and remove the ServiceRoot from the request.getURI()
+    if (!Util::startsWith(request.getURI(), LOOLWSD::ServiceRoot))
+        throw BadRequestException("The request does not start with prefix: " + LOOLWSD::ServiceRoot);
+
+    // re-writes ServiceRoot out of request
+    _uriString = request.getURI().substr(LOOLWSD::ServiceRoot.length());
+    request.setURI(_uriString);
+    const std::string &method = request.getMethod();
+    _isGet = method == "GET";
+    _isHead = method == "HEAD";
+    auto it = request.find("ProxyPrefix");
+	_isProxy = it != request.end();
+    if (_isProxy)
+        _proxyPrefix = it->second;
+    it = request.find("Upgrade");
+    _isWebSocket = it != request.end() && (Poco::icompare(it->second, "websocket") == 0);
+#if MOBILEAPP
+    // request.getHost fires an exception on mobile.
+#else
+	_hostUntrusted = request.getHost();
+#endif
+
+    std::vector<StringToken> tokens;
+    if (_uriString.size() > 0)
+    {
+        size_t i, start;
+        for (i = start = 0; i < _uriString.size(); ++i)
+        {
+            if (_uriString[i] == '/' || _uriString[i] == '?')
+            {
+                if (i - start > 1) // ignore empty
+                    tokens.emplace_back(start, i - start);
+                start = i + 1;
+            }
+        }
+        if (i - start > 1) // ignore empty
+            tokens.emplace_back(start, i - start);
+        _pathSegs = StringVector(_uriString, tokens);
+    }
+}
+
+RequestDetails::RequestDetails(const std::string &mobileURI)
+    : _isGet(false)
+    , _isHead(false)
+    , _isProxy(false)
+    , _isWebSocket(false)
+{
+    _isMobile = true;
+    _uriString = mobileURI;
+}
+
+std::string RequestDetails::getDocumentURI() const
+{
+    if (_isMobile)
+        return _uriString;
+
+    assert(equals(0, "lool"));
+    std::string docURI;
+    Poco::URI::decode(_pathSegs[1], docURI);
+    return docURI;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/wsd/RequestDetails.hpp b/wsd/RequestDetails.hpp
new file mode 100644
index 000000000..68cd9b533
--- /dev/null
+++ b/wsd/RequestDetails.hpp
@@ -0,0 +1,96 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#include <Poco/Net/HTTPRequest.h>
+
+/**
+ * A class to encapsulate various useful pieces from the request.
+ * as well as path parsing goodness.
+ */
+class RequestDetails {
+    bool _isGet : 1;
+    bool _isHead : 1;
+    bool _isProxy : 1;
+    bool _isWebSocket : 1;
+    bool _isMobile : 1;
+    std::string _uriString;
+    std::string _proxyPrefix;
+    std::string _hostUntrusted;
+    std::string _documentURI;
+    StringVector _pathSegs;
+public:
+    RequestDetails(Poco::Net::HTTPRequest &request);
+    RequestDetails(const std::string &mobileURI);
+    // matches the WOPISrc if used. For load balancing
+    // must be 2nd element in the path after /lool/<here>
+    std::string getDocumentURI() const;
+    std::string getURI() const
+    {
+        return _uriString;
+    }
+    bool isProxy() const
+    {
+        return _isProxy;
+    }
+    const std::string getProxyPrefix() const
+    {
+        return _proxyPrefix;
+    }
+    const std::string getHostUntrusted() const
+    {
+        return _hostUntrusted;
+    }
+    bool isWebSocket() const
+    {
+        return _isWebSocket;
+    }
+    bool isGet() const
+    {
+        return _isGet;
+    }
+    bool isGet(const char *path) const
+    {
+        return _isGet && _uriString == path;
+    }
+    bool isGetOrHead(const char *path) const
+    {
+        return (_isGet || _isHead) && _uriString == path;
+    }
+    bool startsWith(const char *path)
+    {
+        return !strncmp(_uriString.c_str(), path, strlen(path));
+    }
+    bool equals(size_t index, const char *string) const
+    {
+        return _pathSegs.equals(index, string);
+    }
+    std::string operator[](size_t index) const
+    {
+        return _pathSegs[index];
+    }
+    size_t size() const
+    {
+        return _pathSegs.size();
+    }
+    std::string toString() const
+    {
+        std::ostringstream oss;
+        oss << _uriString << " " << (_isGet?"G":"")
+            << (_isHead?"H":"") << (_isProxy?"Proxy":"")
+            << (_isWebSocket?"WebSocket":"");
+        oss << " path: " << _pathSegs.size();
+        for (size_t i = 0; i < _pathSegs.size(); ++i)
+            oss << " '" << _pathSegs[i] << "'";
+        return oss.str();
+    }
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/wsd/ServerURL.hpp b/wsd/ServerURL.hpp
index bfe9992b4..d7532f2a6 100644
--- a/wsd/ServerURL.hpp
+++ b/wsd/ServerURL.hpp
@@ -10,11 +10,11 @@
 #pragma once
 
 #include <string>
-#include <Poco/Net/HTTPRequest.h>
+#include "RequestDetails.hpp"
 #include "LOOLWSD.hpp"
 
 /** This class helps us to build a URL that will reliably point back
- * at our service. It does very simple splitting of proxy U
+ * at our service. It does very simple splitting of proxy URL
  * and handles the proxy prefix feature.
  */
 class ServerURL
@@ -24,15 +24,10 @@ class ServerURL
     std::string _schemeAuthority;
     std::string _pathPlus;
 public:
-    ServerURL(const Poco::Net::HTTPRequest &request)
+    ServerURL(const RequestDetails &requestDetails)
     {
-#if MOBILEAPP
-        (void)request;
-        // getHost fires an exception on mobile.
-        init("mobile", "");
-#else
-        init(request.getHost(), request.get("ProxyPrefix", ""));
-#endif
+        init(requestDetails.getHostUntrusted(),
+             requestDetails.getProxyPrefix());
     }
 
     explicit ServerURL()


More information about the Libreoffice-commits mailing list