common/Common.hpp |    4 
 net/Socket.hpp    |   39 ++++++
 wsd/LOOLWSD.cpp   |  312 ++++++++++++++++++++++++------------------------------
 3 files changed, 181 insertions(+), 174 deletions(-)

New commits:
commit faf24f7888badcca4d851d289a7b9e31da9d4e5c
Author: Michael Meeks <michael.me...@collabora.com>
Date:   Tue Apr 25 22:12:07 2017 +0100

    SocketDisposition - controls socket movement & lifecyle.
    
    It is important that moving sockets between polls happens in a
    safe and readable fashion, this enforces that.

diff --git a/net/Socket.hpp b/net/Socket.hpp
index 014f023d..694e82a5 100644
--- a/net/Socket.hpp
+++ b/net/Socket.hpp
@@ -198,6 +198,11 @@ public:
         }
     }
 
+    const std::thread::id &getThreadOwner()
+    {
+        return _owner;
+    }
+
     /// Asserts in the debug builds, otherwise just logs.
     void assertCorrectThread()
     {
@@ -250,7 +255,6 @@ private:
     std::thread::id _owner;
 };
 
-
 /// Handles non-blocking socket event polling.
 /// Only polls on N-Sockets and invokes callback and
 /// doesn't manage buffers or client data.
@@ -913,6 +917,39 @@ protected:
     friend class SimpleResponseClient;
 };
 
+/// Helper to allow us to easily defer the movement of a socket
+/// between polls to clarify thread ownership.
+class SocketDisposition
+{
+    std::shared_ptr<StreamSocket> _socket;
+    typedef std::function<void(const std::shared_ptr<StreamSocket> &)> 
MoveFunction;
+    MoveFunction _socketMove;
+    SocketHandlerInterface::SocketOwnership _socketOwnership;
+public:
+    SocketDisposition(const std::shared_ptr<StreamSocket> &socket) :
+        _socket(socket),
+        _socketOwnership(SocketHandlerInterface::SocketOwnership::UNCHANGED)
+    {}
+    ~SocketDisposition()
+    {
+        assert (!_socketMove);
+    }
+    void setMove(MoveFunction moveFn)
+    {
+        _socketMove = moveFn;
+        _socketOwnership = SocketHandlerInterface::SocketOwnership::MOVED;
+    }
+    SocketHandlerInterface::SocketOwnership execute()
+    {
+        // We should have hard ownership of this socket.
+        assert(_socket->getThreadOwner() == std::this_thread::get_id());
+        if (_socketMove)
+            _socketMove(_socket);
+        _socketMove = nullptr;
+        return _socketOwnership;
+    }
+};
+
 namespace HttpHelper
 {
     /// Sends file as HTTP response.
diff --git a/wsd/LOOLWSD.cpp b/wsd/LOOLWSD.cpp
index 6071c85e..a783b269 100644
--- a/wsd/LOOLWSD.cpp
+++ b/wsd/LOOLWSD.cpp
@@ -1591,7 +1591,7 @@ private:
             return SocketHandlerInterface::SocketOwnership::UNCHANGED;
         }
 
-        SocketHandlerInterface::SocketOwnership socketOwnership = 
SocketHandlerInterface::SocketOwnership::UNCHANGED;
+        SocketDisposition tailDisposition(socket);
         try
         {
             // Routing
@@ -1607,12 +1607,13 @@ private:
             // Admin connections
             else if (reqPathSegs.size() >= 2 && reqPathSegs[0] == "lool" && 
reqPathSegs[1] == "adminws")
             {
-                LOG_ERR("Admin request: " << request.getURI());
+                LOG_INF("Admin request: " << request.getURI());
                 if (AdminSocketHandler::handleInitialRequest(_socket, request))
                 {
-                    // Hand the socket over to the Admin poll.
-                    Admin::instance().insertNewSocket(socket);
-                    socketOwnership = 
SocketHandlerInterface::SocketOwnership::MOVED;
+                    tailDisposition.setMove([](const 
std::shared_ptr<StreamSocket> &moveSocket){
+                            // Hand the socket over to the Admin poll.
+                            Admin::instance().insertNewSocket(moveSocket);
+                        });
                 }
             }
             // Client post and websocket connections
@@ -1637,12 +1638,12 @@ private:
                     reqPathTokens.count() > 0 && reqPathTokens[0] == "lool")
                 {
                     // All post requests have url prefix 'lool'.
-                    socketOwnership = handlePostRequest(request, message);
+                    handlePostRequest(request, message, tailDisposition);
                 }
                 else if (reqPathTokens.count() > 2 && reqPathTokens[0] == 
"lool" && reqPathTokens[2] == "ws" &&
                          request.find("Upgrade") != request.end() && 
Poco::icompare(request["Upgrade"], "websocket") == 0)
                 {
-                    socketOwnership = handleClientWsUpgrade(request, 
reqPathTokens[1]);
+                    handleClientWsUpgrade(request, reqPathTokens[1], 
tailDisposition);
                 }
                 else
                 {
@@ -1671,7 +1672,7 @@ private:
         // if we succeeded - remove the request from our input buffer
         // we expect one request per socket
         in.erase(in.begin(), itBody);
-        return socketOwnership;
+        return tailDisposition.execute();
     }
 
     int getPollEvents(std::chrono::steady_clock::time_point /* now */,
@@ -1806,14 +1807,14 @@ private:
         return "application/octet-stream";
     }
 
-    SocketHandlerInterface::SocketOwnership handlePostRequest(const 
Poco::Net::HTTPRequest& request, Poco::MemoryInputStream& message)
+    void handlePostRequest(const Poco::Net::HTTPRequest& request, 
Poco::MemoryInputStream& message,
+                           SocketDisposition &tailDisposition)
     {
         LOG_INF("Post request: [" << request.getURI() << "]");
 
         Poco::Net::HTTPResponse response;
         auto socket = _socket.lock();
 
-        SocketHandlerInterface::SocketOwnership socketOwnership = 
SocketHandlerInterface::SocketOwnership::UNCHANGED;
         StringTokenizer tokens(request.getURI(), "/?");
         if (tokens.count() >= 3 && tokens[2] == "convert-to")
         {
@@ -1851,21 +1852,22 @@ private:
                     auto clientSession = createNewClientSession(nullptr, _id, 
uriPublic, docBroker, isReadOnly);
                     if (clientSession)
                     {
-                        // Transfer the client socket to the DocumentBroker.
-                        socketOwnership = 
SocketHandlerInterface::SocketOwnership::MOVED;
+                        tailDisposition.setMove([docBroker, clientSession, 
format]
+                                                (const 
std::shared_ptr<StreamSocket> &moveSocket)
+                        { // Perform all of this after removing the socket
 
                         // Make sure the thread is running before adding 
callback.
                         docBroker->startThread();
 
                         // We no longer own this socket.
-                        socket->setThreadOwner(std::thread::id(0));
+                        moveSocket->setThreadOwner(std::thread::id(0));
 
-                        docBroker->addCallback([docBroker, socket, 
clientSession, format]()
+                        docBroker->addCallback([docBroker, moveSocket, 
clientSession, format]()
                         {
-                            clientSession->setSaveAsSocket(socket);
+                            clientSession->setSaveAsSocket(moveSocket);
 
                             // Move the socket into DocBroker.
-                            docBroker->addSocketToPoll(socket);
+                            docBroker->addSocketToPoll(moveSocket);
 
                             // First add and load the session.
                             docBroker->addSession(clientSession);
@@ -1889,6 +1891,7 @@ private:
                             std::vector<char> saveasRequest(saveas.begin(), 
saveas.end());
                             clientSession->handleMessage(true, 
WebSocketHandler::WSOpCode::Text, saveasRequest);
                         });
+                        });
 
                         sent = true;
                     }
@@ -1902,8 +1905,6 @@ private:
                 // TODO: We should differentiate between bad request and 
failed conversion.
                 throw BadRequestException("Failed to convert and send file.");
             }
-
-            return socketOwnership;
         }
         else if (tokens.count() >= 4 && tokens[3] == "insertfile")
         {
@@ -1943,7 +1944,7 @@ private:
                     File(tmpPath).moveTo(fileName);
                     response.setContentLength(0);
                     socket->send(response);
-                    return socketOwnership;
+                    return;
                 }
             }
         }
@@ -2010,21 +2011,20 @@ private:
             {
                 LOG_ERR("Download file [" << filePath.toString() << "] not 
found.");
             }
-
             (void)responded;
-            return socketOwnership;
         }
 
         throw BadRequestException("Invalid or unknown request.");
     }
 
-    SocketHandlerInterface::SocketOwnership handleClientWsUpgrade(const 
Poco::Net::HTTPRequest& request, const std::string& url)
+    void handleClientWsUpgrade(const Poco::Net::HTTPRequest& request, const 
std::string& url,
+                               SocketDisposition &tailDisposition)
     {
         auto socket = _socket.lock();
         if (!socket)
         {
             LOG_WRN("No socket to handle client WS upgrade for request: " << 
request.getURI() << ", url: " << url);
-            return SocketHandlerInterface::SocketOwnership::UNCHANGED;
+            return;
         }
 
         LOG_INF("Client WS request: " << request.getURI() << ", url: " << url 
<< ", socket #" << socket->getFD());
@@ -2036,7 +2036,7 @@ private:
         {
             LOG_ERR("Limit on maximum number of connections of " << 
MAX_CONNECTIONS << " reached.");
             shutdownLimitReached(ws);
-            return SocketHandlerInterface::SocketOwnership::UNCHANGED;
+            return;
         }
 
         LOG_INF("Starting GET request handler for session [" << _id << "] on 
url [" << url << "].");
@@ -2064,8 +2064,6 @@ private:
 
         LOG_INF("URL [" << url << "] is " << (isReadOnly ? "readonly" : 
"writable") << ".");
 
-        SocketHandlerInterface::SocketOwnership socketOwnership = 
SocketHandlerInterface::SocketOwnership::UNCHANGED;
-
         // Request a kit process for this doc.
         auto docBroker = findOrCreateDocBroker(ws, url, docKey, _id, 
uriPublic);
         if (docBroker)
@@ -2073,28 +2071,28 @@ private:
             auto clientSession = createNewClientSession(&ws, _id, uriPublic, 
docBroker, isReadOnly);
             if (clientSession)
             {
-                // Transfer the client socket to the DocumentBroker.
-
-                // Remove from current poll as we're moving ownership.
-                socketOwnership = 
SocketHandlerInterface::SocketOwnership::MOVED;
-
-                // Make sure the thread is running before adding callback.
-                docBroker->startThread();
+                // Transfer the client socket to the DocumentBroker when we 
get back to the poll:
+                tailDisposition.setMove([docBroker, clientSession]
+                                        (const std::shared_ptr<StreamSocket> 
&moveSocket)
+                {
+                    // Make sure the thread is running before adding callback.
+                    docBroker->startThread();
 
-                // We no longer own this socket.
-                socket->setThreadOwner(std::thread::id(0));
+                    // We no longer own this socket.
+                    moveSocket->setThreadOwner(std::thread::id(0));
 
-                docBroker->addCallback([docBroker, socket, clientSession]()
-                {
-                    // Set the ClientSession to handle Socket events.
-                    socket->setHandler(clientSession);
-                    LOG_DBG("Socket #" << socket->getFD() << " handler is " << 
clientSession->getName());
+                    docBroker->addCallback([docBroker, moveSocket, 
clientSession]()
+                    {
+                        // Set the ClientSession to handle Socket events.
+                        moveSocket->setHandler(clientSession);
+                        LOG_DBG("Socket #" << moveSocket->getFD() << " handler 
is " << clientSession->getName());
 
-                    // Move the socket into DocBroker.
-                    docBroker->addSocketToPoll(socket);
+                        // Move the socket into DocBroker.
+                        docBroker->addSocketToPoll(moveSocket);
 
-                    // Add and load the session.
-                    docBroker->addSession(clientSession);
+                        // Add and load the session.
+                        docBroker->addSession(clientSession);
+                    });
                 });
             }
             else
@@ -2105,8 +2103,6 @@ private:
         }
         else
             LOG_WRN("Failed to create DocBroker with docKey [" << docKey << 
"].");
-
-        return socketOwnership;
     }
 
 private:
commit c8d1c18cb54acf82f8b6de2252365eac93e90a58
Author: Michael Meeks <michael.me...@collabora.com>
Date:   Tue Apr 25 21:35:20 2017 +0100

    Revert "wsd: correctly remove request from socket buffer"
    
    This reverts commit c851c3e93be565dfa14906febbdf6208e9d422cd.

diff --git a/common/Common.hpp b/common/Common.hpp
index b0b018b2..09bafad3 100644
--- a/common/Common.hpp
+++ b/common/Common.hpp
@@ -34,8 +34,8 @@ constexpr auto CHILD_URI = "/loolws/child?";
 constexpr auto NEW_CHILD_URI = "/loolws/newchild?";
 constexpr auto LO_JAIL_SUBPATH = "lo";
 
-/// The HTTP response User-Agent.
-constexpr auto HTTP_AGENT_STRING = "LOOLWSD Agent " LOOLWSD_VERSION;
+/// The HTTP response User-Agent. TODO: Include version.
+constexpr auto HTTP_AGENT_STRING = "LOOLWSD Agent";
 
 // The client port number, both loolwsd and the kits have this.
 extern int ClientPortNumber;
diff --git a/wsd/LOOLWSD.cpp b/wsd/LOOLWSD.cpp
index 4e136d4e..6071c85e 100644
--- a/wsd/LOOLWSD.cpp
+++ b/wsd/LOOLWSD.cpp
@@ -1598,47 +1598,46 @@ private:
             Poco::URI requestUri(request.getURI());
             std::vector<std::string> reqPathSegs;
             requestUri.getPathSegments(reqPathSegs);
-            const StringTokenizer reqPathTokens(request.getURI(), "/?", 
StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM);
 
-            if (request.getMethod() == HTTPRequest::HTTP_GET ||
-                request.getMethod() == HTTPRequest::HTTP_HEAD)
+            // File server
+            if (reqPathSegs.size() >= 1 && reqPathSegs[0] == "loleaflet")
             {
-                // Clear the request header already consumed.
-                in.erase(in.begin(), itBody);
-
-                // File server
-                if (!(request.find("Upgrade") != request.end() && 
Poco::icompare(request["Upgrade"], "websocket") == 0) &&
-                    reqPathTokens.count() >= 5 && reqPathTokens[0] == "lool")
-                {
-                    // All post requests have url prefix 'lool'.
-                    handleFileDownloadRequest(request);
-                }
-                else if (reqPathSegs.size() >= 1 && reqPathSegs[0] == 
"loleaflet")
-                {
-                    handleFileServerRequest(request, message);
-                }
-                else if (reqPathSegs.size() >= 2 && reqPathSegs[0] == "lool" 
&& reqPathSegs[1] == "adminws")
-                {
-                    // Admin connections
-                    LOG_INF("Admin request: " << request.getURI());
-                    if (AdminSocketHandler::handleInitialRequest(_socket, 
request))
-                    {
-                        // Hand the socket over to the Admin poll.
-                        Admin::instance().insertNewSocket(socket);
-                        socketOwnership = 
SocketHandlerInterface::SocketOwnership::MOVED;
-                    }
-                }
-                else if (request.getURI() == "/")
-                {
-                    handleRootRequest(request);
-                }
-                else if (request.getURI() == "/favicon.ico")
+                handleFileServerRequest(request, message);
+            }
+            // Admin connections
+            else if (reqPathSegs.size() >= 2 && reqPathSegs[0] == "lool" && 
reqPathSegs[1] == "adminws")
+            {
+                LOG_ERR("Admin request: " << request.getURI());
+                if (AdminSocketHandler::handleInitialRequest(_socket, request))
                 {
-                    handleFaviconRequest(request);
+                    // Hand the socket over to the Admin poll.
+                    Admin::instance().insertNewSocket(socket);
+                    socketOwnership = 
SocketHandlerInterface::SocketOwnership::MOVED;
                 }
-                else if (request.getURI() == "/hosting/discovery")
+            }
+            // Client post and websocket connections
+            else if ((request.getMethod() == HTTPRequest::HTTP_GET ||
+                      request.getMethod() == HTTPRequest::HTTP_HEAD) &&
+                     request.getURI() == "/")
+            {
+                handleRootRequest(request);
+            }
+            else if (request.getMethod() == HTTPRequest::HTTP_GET && 
request.getURI() == "/favicon.ico")
+            {
+                handleFaviconRequest(request);
+            }
+            else if (request.getMethod() == HTTPRequest::HTTP_GET && 
request.getURI() == "/hosting/discovery")
+            {
+                handleWopiDiscoveryRequest(request);
+            }
+            else
+            {
+                StringTokenizer reqPathTokens(request.getURI(), "/?", 
StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM);
+                if (!(request.find("Upgrade") != request.end() && 
Poco::icompare(request["Upgrade"], "websocket") == 0) &&
+                    reqPathTokens.count() > 0 && reqPathTokens[0] == "lool")
                 {
-                    handleWopiDiscoveryRequest(request);
+                    // All post requests have url prefix 'lool'.
+                    socketOwnership = handlePostRequest(request, message);
                 }
                 else if (reqPathTokens.count() > 2 && reqPathTokens[0] == 
"lool" && reqPathTokens[2] == "ws" &&
                          request.find("Upgrade") != request.end() && 
Poco::icompare(request["Upgrade"], "websocket") == 0)
@@ -1647,31 +1646,19 @@ private:
                 }
                 else
                 {
-                    throw std::runtime_error("Bad request.");
-                }
-
-                return socketOwnership;
-            }
-            else if (request.getMethod() == HTTPRequest::HTTP_POST)
-            {
-                if (reqPathSegs.size() >= 1 && reqPathSegs[0] == "loleaflet")
-                {
-                    handleFileServerRequest(request, message);
-                    return socketOwnership;
-                }
-
-                if (!(request.find("Upgrade") != request.end() && 
Poco::icompare(request["Upgrade"], "websocket") == 0) &&
-                    reqPathTokens.count() > 0 && reqPathTokens[0] == "lool")
-                {
-                    // All post requests have url prefix 'lool'.
-                    socketOwnership = handlePostRequest(request, message);
-                    in.erase(in.begin(), itBody);
-                    return socketOwnership;
+                    LOG_ERR("Unknown resource: " << request.getURI());
+
+                    // Bad request.
+                    std::ostringstream oss;
+                    oss << "HTTP/1.1 400\r\n"
+                        << "Date: " << 
Poco::DateTimeFormatter::format(Poco::Timestamp(), 
Poco::DateTimeFormat::HTTP_FORMAT) << "\r\n"
+                        << "User-Agent: LOOLWSD WOPI Agent\r\n"
+                        << "Content-Length: 0\r\n"
+                        << "\r\n";
+                    socket->send(oss.str());
+                    socket->shutdown();
                 }
             }
-
-            LOG_ERR("#" << socket->getFD() << " Unknown request: [" <<
-                    LOOLProtocol::getAbbreviatedMessage(in) << "].");
         }
         catch (const std::exception& exc)
         {
@@ -1681,17 +1668,10 @@ private:
                     LOOLProtocol::getAbbreviatedMessage(in) << "]: " << 
exc.what());
         }
 
-        // Bad request.
-        std::ostringstream oss;
-        oss << "HTTP/1.1 400\r\n"
-            << "Date: " << Poco::DateTimeFormatter::format(Poco::Timestamp(), 
Poco::DateTimeFormat::HTTP_FORMAT) << "\r\n"
-            << "User-Agent: " << HTTP_AGENT_STRING << "\r\n"
-            << "Content-Length: 0\r\n"
-            << "\r\n";
-        socket->send(oss.str());
-        socket->shutdown();
-
-        return SocketHandlerInterface::SocketOwnership::UNCHANGED;
+        // if we succeeded - remove the request from our input buffer
+        // we expect one request per socket
+        in.erase(in.begin(), itBody);
+        return socketOwnership;
     }
 
     int getPollEvents(std::chrono::steady_clock::time_point /* now */,
@@ -1967,81 +1947,75 @@ private:
                 }
             }
         }
-
-        throw BadRequestException("Invalid or unknown request.");
-    }
-
-    void handleFileDownloadRequest(const Poco::Net::HTTPRequest& request)
-    {
-        LOG_INF("File download request.");
-
-        Poco::Net::HTTPResponse response;
-        auto socket = _socket.lock();
-
-        StringTokenizer tokens(request.getURI(), "/?");
-        // TODO: Check that the user in question has access to this file!
-
-        // 1. Validate the dockey
-        std::string decodedUri;
-        URI::decode(tokens[2], decodedUri);
-        const auto docKey = 
DocumentBroker::getDocKey(DocumentBroker::sanitizeURI(decodedUri));
-        std::unique_lock<std::mutex> docBrokersLock(DocBrokersMutex);
-        auto docBrokerIt = DocBrokers.find(docKey);
-        if (docBrokerIt == DocBrokers.end())
+        else if (tokens.count() >= 6)
         {
-            throw BadRequestException("DocKey [" + docKey + "] is invalid.");
-        }
+            LOG_INF("File download request.");
+            // TODO: Check that the user in question has access to this file!
 
-        // 2. Cross-check if received child id is correct
-        if (docBrokerIt->second->getJailId() != tokens[3])
-        {
-            throw BadRequestException("ChildId does not correspond to docKey");
-        }
+            // 1. Validate the dockey
+            std::string decodedUri;
+            URI::decode(tokens[2], decodedUri);
+            const auto docKey = 
DocumentBroker::getDocKey(DocumentBroker::sanitizeURI(decodedUri));
+            std::unique_lock<std::mutex> docBrokersLock(DocBrokersMutex);
+            auto docBrokerIt = DocBrokers.find(docKey);
+            if (docBrokerIt == DocBrokers.end())
+            {
+                throw BadRequestException("DocKey [" + docKey + "] is 
invalid.");
+            }
 
-        // 3. Don't let user download the file in main doc directory containing
-        // the document being edited otherwise we will end up deleting main 
directory
-        // after download finishes
-        if (docBrokerIt->second->getJailId() == tokens[4])
-        {
-            throw BadRequestException("RandomDir cannot be equal to ChildId");
-        }
-        docBrokersLock.unlock();
-
-        std::string fileName;
-        bool responded = false;
-        URI::decode(tokens[5], fileName);
-        const Path filePath(LOOLWSD::ChildRoot + tokens[3]
-                            + JAILED_DOCUMENT_ROOT + tokens[4] + "/" + 
fileName);
-        LOG_INF("HTTP request for: " << filePath.toString());
-        if (filePath.isAbsolute() && File(filePath).exists())
-        {
-            std::string contentType = getContentType(fileName);
-            if (Poco::Path(fileName).getExtension() == "pdf")
+            // 2. Cross-check if received child id is correct
+            if (docBrokerIt->second->getJailId() != tokens[3])
             {
-                contentType = "application/pdf";
-                response.set("Content-Disposition", "attachment; filename=\"" 
+ fileName + "\"");
+                throw BadRequestException("ChildId does not correspond to 
docKey");
             }
 
-            try
+            // 3. Don't let user download the file in main doc directory 
containing
+            // the document being edited otherwise we will end up deleting 
main directory
+            // after download finishes
+            if (docBrokerIt->second->getJailId() == tokens[4])
             {
-                HttpHelper::sendFile(socket, filePath.toString(), contentType, 
response);
-                responded = true;
+                throw BadRequestException("RandomDir cannot be equal to 
ChildId");
+            }
+            docBrokersLock.unlock();
+
+            std::string fileName;
+            bool responded = false;
+            URI::decode(tokens[5], fileName);
+            const Path filePath(LOOLWSD::ChildRoot + tokens[3]
+                                + JAILED_DOCUMENT_ROOT + tokens[4] + "/" + 
fileName);
+            LOG_INF("HTTP request for: " << filePath.toString());
+            if (filePath.isAbsolute() && File(filePath).exists())
+            {
+                std::string contentType = getContentType(fileName);
+                if (Poco::Path(fileName).getExtension() == "pdf")
+                {
+                    contentType = "application/pdf";
+                    response.set("Content-Disposition", "attachment; 
filename=\"" + fileName + "\"");
+                }
+
+                try
+                {
+                    HttpHelper::sendFile(socket, filePath.toString(), 
contentType, response);
+                    responded = true;
+                }
+                catch (const Exception& exc)
+                {
+                    LOG_ERR("Error sending file to client: " << 
exc.displayText() <<
+                            (exc.nested() ? " (" + exc.nested()->displayText() 
+ ")" : ""));
+                }
+
+                FileUtil::removeFile(File(filePath.parent()).path(), true);
             }
-            catch (const Exception& exc)
+            else
             {
-                LOG_ERR("Error sending file to client: " << exc.displayText() 
<<
-                        (exc.nested() ? " (" + exc.nested()->displayText() + 
")" : ""));
+                LOG_ERR("Download file [" << filePath.toString() << "] not 
found.");
             }
 
-            FileUtil::removeFile(File(filePath.parent()).path(), true);
-        }
-        else
-        {
-            LOG_ERR("Download file [" << filePath.toString() << "] not 
found.");
+            (void)responded;
+            return socketOwnership;
         }
 
-        // TODO: Use this to send failure response.
-        (void)responded;
+        throw BadRequestException("Invalid or unknown request.");
     }
 
     SocketHandlerInterface::SocketOwnership handleClientWsUpgrade(const 
Poco::Net::HTTPRequest& request, const std::string& url)
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to