loolwsd/Admin.cpp | 5 -- loolwsd/Admin.hpp | 4 - loolwsd/AdminModel.cpp | 4 - loolwsd/AdminModel.hpp | 11 ++--- loolwsd/ClientSession.cpp | 2 loolwsd/ClientSession.hpp | 2 loolwsd/Connect.cpp | 10 ++-- loolwsd/DocumentBroker.hpp | 8 +-- loolwsd/Exceptions.hpp | 2 loolwsd/IoUtil.cpp | 31 ++------------ loolwsd/IoUtil.hpp | 26 ++++-------- loolwsd/LOOLKit.cpp | 18 ++++---- loolwsd/LOOLProtocol.hpp | 5 +- loolwsd/LOOLSession.cpp | 10 ++-- loolwsd/LOOLSession.hpp | 8 +-- loolwsd/LOOLStress.cpp | 6 +- loolwsd/LOOLWSD.cpp | 16 +++---- loolwsd/LOOLWebSocket.hpp | 86 ++++++++++++++++++++++++++++++++++++++++ loolwsd/Makefile.am | 3 - loolwsd/Unit.hpp | 6 +- loolwsd/UnitHTTP.cpp | 2 loolwsd/UnitHTTP.hpp | 4 - loolwsd/Util.hpp | 1 loolwsd/test/TileCacheTests.cpp | 56 +++++++++++++------------- loolwsd/test/UnitAdmin.cpp | 20 ++++----- loolwsd/test/UnitFonts.cpp | 10 ++-- loolwsd/test/UnitFuzz.cpp | 4 - loolwsd/test/UnitPrefork.cpp | 8 +-- loolwsd/test/helpers.hpp | 40 +++++++++--------- loolwsd/test/httpcrashtest.cpp | 12 ++--- loolwsd/test/httpwserror.cpp | 12 ++--- loolwsd/test/httpwstest.cpp | 78 ++++++++++++++++++------------------ 32 files changed, 285 insertions(+), 225 deletions(-)
New commits: commit 0674e87831ecf035f6880b9e68d3b9fdd51c1f31 Author: Jan Holesovsky <ke...@collabora.com> Date: Thu Nov 10 09:47:25 2016 +0100 Implement a thread-safe websocket inherited from Poco::Net::WebSocket. sendFrame() implemented in LOOLWebSocket is thread safe, and also deals with large messages - sends the "nextmessage: size=..." frame before the actual large frame. The problem this is attempting to solve was that when sending a large frame, it was split to multiple packets. During that, another frame was sent from a different thread; which lead to confusion, and the resulting frame was corrupted (because it ended up composed from unrelated packets). Change-Id: Ie85952e431b1cad2fdc6e3c64df8a444ea0ae971 diff --git a/loolwsd/Admin.cpp b/loolwsd/Admin.cpp index 04d479b..12b4c50 100644 --- a/loolwsd/Admin.cpp +++ b/loolwsd/Admin.cpp @@ -21,7 +21,6 @@ #include <Poco/Net/HTTPServerResponse.h> #include <Poco/Net/NetException.h> #include <Poco/Net/SecureServerSocket.h> -#include <Poco/Net/WebSocket.h> #include <Poco/StringTokenizer.h> #include <Poco/Util/ServerApplication.h> #include <Poco/Util/Timer.h> @@ -33,6 +32,7 @@ #include "FileServer.hpp" #include "IoUtil.hpp" #include "LOOLProtocol.hpp" +#include <LOOLWebSocket.hpp> #include "LOOLWSD.hpp" #include "Log.hpp" #include "Storage.hpp" @@ -47,7 +47,6 @@ using Poco::Net::HTTPRequestHandler; using Poco::Net::HTTPResponse; using Poco::Net::HTTPServerRequest; using Poco::Net::HTTPServerResponse; -using Poco::Net::WebSocket; using Poco::Util::Application; bool AdminRequestHandler::adminCommandHandler(const std::vector<char>& payload) @@ -207,7 +206,7 @@ bool AdminRequestHandler::adminCommandHandler(const std::vector<char>& payload) /// Handle admin requests. void AdminRequestHandler::handleWSRequests(HTTPServerRequest& request, HTTPServerResponse& response, int sessionId) { - _adminWs = std::make_shared<WebSocket>(request, response); + _adminWs = std::make_shared<LOOLWebSocket>(request, response); { std::unique_lock<std::mutex> modelLock(_admin->getLock()); diff --git a/loolwsd/Admin.hpp b/loolwsd/Admin.hpp index e82775d..cb5d83f 100644 --- a/loolwsd/Admin.hpp +++ b/loolwsd/Admin.hpp @@ -15,7 +15,6 @@ #include <Poco/Net/HTTPRequest.h> #include <Poco/Net/HTTPRequestHandler.h> #include <Poco/Net/HTTPServer.h> -#include <Poco/Net/WebSocket.h> #include <Poco/Runnable.h> #include <Poco/Types.h> #include <Poco/Util/Timer.h> @@ -23,6 +22,7 @@ #include "AdminModel.hpp" #include "Log.hpp" +#include <LOOLWebSocket.hpp> class Admin; @@ -43,7 +43,7 @@ private: private: Admin* _admin; - std::shared_ptr<Poco::Net::WebSocket> _adminWs; + std::shared_ptr<LOOLWebSocket> _adminWs; int _sessionId; bool _isAuthenticated; }; diff --git a/loolwsd/AdminModel.cpp b/loolwsd/AdminModel.cpp index d460e53..62d4ab7 100644 --- a/loolwsd/AdminModel.cpp +++ b/loolwsd/AdminModel.cpp @@ -15,12 +15,12 @@ #include <sstream> #include <string> -#include <Poco/Net/WebSocket.h> #include <Poco/Process.h> #include <Poco/StringTokenizer.h> #include <Poco/URI.h> #include "LOOLProtocol.hpp" +#include <LOOLWebSocket.hpp> #include "Log.hpp" #include "Unit.hpp" #include "Util.hpp" @@ -147,7 +147,7 @@ unsigned AdminModel::getTotalMemoryUsage() return totalMem; } -void AdminModel::subscribe(int nSessionId, std::shared_ptr<Poco::Net::WebSocket>& ws) +void AdminModel::subscribe(int nSessionId, std::shared_ptr<LOOLWebSocket>& ws) { const auto ret = _subscribers.emplace(nSessionId, Subscriber(nSessionId, ws)); if (!ret.second) diff --git a/loolwsd/AdminModel.hpp b/loolwsd/AdminModel.hpp index a1c4812..b24776e 100644 --- a/loolwsd/AdminModel.hpp +++ b/loolwsd/AdminModel.hpp @@ -14,10 +14,10 @@ #include <set> #include <string> -#include <Poco/Net/WebSocket.h> #include <Poco/Process.h> #include "Log.hpp" +#include <LOOLWebSocket.hpp> #include "Util.hpp" /// A client view in Admin controller. @@ -91,7 +91,7 @@ private: class Subscriber { public: - Subscriber(int sessionId, std::shared_ptr<Poco::Net::WebSocket>& ws) + Subscriber(int sessionId, std::shared_ptr<LOOLWebSocket>& ws) : _sessionId(sessionId), _ws(ws), _start(std::time(nullptr)) @@ -117,8 +117,9 @@ public: private: /// Admin session Id int _sessionId; - /// WebSocket to use to send messages to session - std::weak_ptr<Poco::Net::WebSocket> _ws; + + /// LOOLWebSocket to use to send messages to session + std::weak_ptr<LOOLWebSocket> _ws; std::set<std::string> _subscriptions; @@ -145,7 +146,7 @@ public: /// Returns memory consumed by all active loolkit processes unsigned getTotalMemoryUsage(); - void subscribe(int sessionId, std::shared_ptr<Poco::Net::WebSocket>& ws); + void subscribe(int sessionId, std::shared_ptr<LOOLWebSocket>& ws); void subscribe(int sessionId, const std::string& command); void unsubscribe(int sessionId, const std::string& command); diff --git a/loolwsd/ClientSession.cpp b/loolwsd/ClientSession.cpp index c186619..24b53c5 100644 --- a/loolwsd/ClientSession.cpp +++ b/loolwsd/ClientSession.cpp @@ -35,7 +35,7 @@ using namespace LOOLProtocol; using Poco::StringTokenizer; ClientSession::ClientSession(const std::string& id, - const std::shared_ptr<Poco::Net::WebSocket>& ws, + const std::shared_ptr<LOOLWebSocket>& ws, const std::shared_ptr<DocumentBroker>& docBroker, const Poco::URI& uriPublic, const bool readOnly) : diff --git a/loolwsd/ClientSession.hpp b/loolwsd/ClientSession.hpp index 77ddcfa..4340f46 100644 --- a/loolwsd/ClientSession.hpp +++ b/loolwsd/ClientSession.hpp @@ -23,7 +23,7 @@ class ClientSession final : public LOOLSession, public std::enable_shared_from_t { public: ClientSession(const std::string& id, - const std::shared_ptr<Poco::Net::WebSocket>& ws, + const std::shared_ptr<LOOLWebSocket>& ws, const std::shared_ptr<DocumentBroker>& docBroker, const Poco::URI& uriPublic, const bool isReadOnly = false); diff --git a/loolwsd/Connect.cpp b/loolwsd/Connect.cpp index 3c14b22..5b550dd 100644 --- a/loolwsd/Connect.cpp +++ b/loolwsd/Connect.cpp @@ -31,7 +31,6 @@ #include <Poco/Net/TCPServer.h> #include <Poco/Net/TCPServerConnection.h> #include <Poco/Net/TCPServerConnectionFactory.h> -#include <Poco/Net/WebSocket.h> #include <Poco/Process.h> #include <Poco/SharedPtr.h> #include <Poco/StringTokenizer.h> @@ -43,6 +42,7 @@ #include "Common.hpp" #include "LOOLProtocol.hpp" +#include <LOOLWebSocket.hpp> #include "Log.hpp" #include "Util.hpp" @@ -72,11 +72,11 @@ using Poco::Util::Application; static bool closeExpected = false; static std::mutex coutMutex; -/// Prints incoming data from a WebSocket. +/// Prints incoming data from a LOOLWebSocket. class Output : public Runnable { public: - Output(WebSocket& ws) : + Output(LOOLWebSocket& ws) : _ws(ws) { } @@ -131,7 +131,7 @@ public: } } - WebSocket& _ws; + LOOLWebSocket& _ws; }; /// Program for interactive or scripted testing of a lool server. @@ -179,7 +179,7 @@ protected: URI::encode(args[0], ":/?", encodedUri); HTTPRequest request(HTTPRequest::HTTP_GET, "/lool/" + encodedUri + "/ws"); HTTPResponse response; - WebSocket ws(cs, request, response); + LOOLWebSocket ws(cs, request, response); ws.setReceiveTimeout(0); diff --git a/loolwsd/DocumentBroker.hpp b/loolwsd/DocumentBroker.hpp index 3212715..fc035f7 100644 --- a/loolwsd/DocumentBroker.hpp +++ b/loolwsd/DocumentBroker.hpp @@ -21,11 +21,11 @@ #include <string> #include <thread> -#include <Poco/Net/WebSocket.h> #include <Poco/URI.h> #include "IoUtil.hpp" #include "Log.hpp" +#include <LOOLWebSocket.hpp> #include "Storage.hpp" #include "TileCache.hpp" #include "Util.hpp" @@ -39,8 +39,8 @@ class ChildProcess { public: /// @param pid is the process ID of the child. - /// @param ws is the control WebSocket to the child. - ChildProcess(const Poco::Process::PID pid, const std::shared_ptr<Poco::Net::WebSocket>& ws) : + /// @param ws is the control LOOLWebSocket to the child. + ChildProcess(const Poco::Process::PID pid, const std::shared_ptr<LOOLWebSocket>& ws) : _pid(pid), _ws(ws), _stop(false) @@ -163,7 +163,7 @@ private: private: Poco::Process::PID _pid; - std::shared_ptr<Poco::Net::WebSocket> _ws; + std::shared_ptr<LOOLWebSocket> _ws; std::weak_ptr<DocumentBroker> _docBroker; std::thread _thread; std::atomic<bool> _stop; diff --git a/loolwsd/Exceptions.hpp b/loolwsd/Exceptions.hpp index ae2d1a6..b05d98d 100644 --- a/loolwsd/Exceptions.hpp +++ b/loolwsd/Exceptions.hpp @@ -59,7 +59,7 @@ public: }; /// An generic error-message exception meant to -/// propagate via a valid WebSocket to the client. +/// propagate via a valid LOOLWebSocket to the client. /// The contents of what() will be displayed on screen. class WebSocketErrorMessageException : public LoolException { diff --git a/loolwsd/IoUtil.cpp b/loolwsd/IoUtil.cpp index 04a6ed5..75b7026 100644 --- a/loolwsd/IoUtil.cpp +++ b/loolwsd/IoUtil.cpp @@ -22,13 +22,13 @@ #include <Poco/Net/NetException.h> #include <Poco/Net/Socket.h> -#include <Poco/Net/WebSocket.h> #include <Poco/StringTokenizer.h> #include <Poco/Thread.h> #include <Poco/URI.h> #include "Common.hpp" #include "LOOLProtocol.hpp" +#include <LOOLWebSocket.hpp> #include "Log.hpp" #include "Util.hpp" @@ -38,7 +38,7 @@ using Poco::Net::WebSocket; namespace IoUtil { -int receiveFrame(WebSocket& socket, void* buffer, int length, int& flags) +int receiveFrame(LOOLWebSocket& socket, void* buffer, int length, int& flags) { while (!TerminationFlag) { @@ -60,9 +60,9 @@ int receiveFrame(WebSocket& socket, void* buffer, int length, int& flags) return -1; } -// Synchronously process WebSocket requests and dispatch to handler. +// Synchronously process LOOLWebSocket requests and dispatch to handler. // Handler returns false to end. -void SocketProcessor(const std::shared_ptr<WebSocket>& ws, +void SocketProcessor(const std::shared_ptr<LOOLWebSocket>& ws, const std::function<bool(const std::vector<char>&)>& handler, const std::function<void()>& closeFrame, const std::function<bool()>& stopPredicate) @@ -197,11 +197,11 @@ void SocketProcessor(const std::shared_ptr<WebSocket>& ws, LOG_INF("SocketProcessor finished."); } -void shutdownWebSocket(const std::shared_ptr<Poco::Net::WebSocket>& ws) +void shutdownWebSocket(const std::shared_ptr<LOOLWebSocket>& ws) { try { - // Calling WebSocket::shutdown, in case of error, would try to send a 'close' frame + // Calling LOOLWebSocket::shutdown, in case of error, would try to send a 'close' frame // which won't work in case of broken pipe or timeout from peer. Just close the // socket in that case preventing 'close' frame from being sent. if (ws && ws->poll(Poco::Timespan(0), Socket::SelectMode::SELECT_ERROR)) @@ -258,25 +258,6 @@ ssize_t readFromPipe(int pipe, char* buffer, ssize_t size) return bytes; } -void sendLargeFrame(const std::shared_ptr<Poco::Net::WebSocket>& ws, const char *message, int length, int flags) -{ - // Size after which messages will be sent preceded with - // 'nextmessage' frame to let the receiver know in advance - // the size of larger coming message. All messages up to this - // size are considered small messages. - constexpr int SMALL_MESSAGE_SIZE = READ_BUFFER_SIZE / 2; - - if (length > SMALL_MESSAGE_SIZE) - { - const std::string nextmessage = "nextmessage: size=" + std::to_string(length); - ws->sendFrame(nextmessage.data(), nextmessage.size()); - LOG_DBG("Message is long, sent " << nextmessage); - } - - ws->sendFrame(message, length, flags); - LOG_DBG("Sent frame: " << LOOLProtocol::getAbbreviatedMessage(std::string(message, length))); -} - /// Reads a single line from a pipe. /// Returns 0 for timeout, <0 for error, and >0 on success. /// On success, line will contain the read message. diff --git a/loolwsd/IoUtil.hpp b/loolwsd/IoUtil.hpp index e0068b0..dba0aa7 100644 --- a/loolwsd/IoUtil.hpp +++ b/loolwsd/IoUtil.hpp @@ -14,24 +14,26 @@ #include <memory> #include <string> -#include <Poco/Net/WebSocket.h> +#include <LOOLWebSocket.hpp> namespace IoUtil { - // Wrapper for WebSocket::receiveFrame() that handles PING frames (by replying with a + // Wrapper for LOOLWebSocket::receiveFrame() that handles PING frames (by replying with a // PONG frame) and PONG frames. PONG frames are ignored. // Should we also factor out the handling of non-final and continuation frames into this? - int receiveFrame(Poco::Net::WebSocket& socket, void* buffer, int length, int& flags); + // TODO: move this to LOOLWebSocket directly + int receiveFrame(LOOLWebSocket& socket, void* buffer, int length, int& flags); - /// Synchronously process WebSocket requests and dispatch to handler. + /// Synchronously process LOOLWebSocket requests and dispatch to handler. /// Handler returns false to end. - void SocketProcessor(const std::shared_ptr<Poco::Net::WebSocket>& ws, + void SocketProcessor(const std::shared_ptr<LOOLWebSocket>& ws, const std::function<bool(const std::vector<char>&)>& handler, const std::function<void()>& closeFrame, const std::function<bool()>& stopPredicate); - /// Call WebSocket::shutdown() ignoring Poco::IOException. - void shutdownWebSocket(const std::shared_ptr<Poco::Net::WebSocket>& ws); + /// Call LOOLWebSocket::shutdown() ignoring Poco::IOException. + /// TODO: consider moving this directly to LOOLWebSocket + void shutdownWebSocket(const std::shared_ptr<LOOLWebSocket>& ws); ssize_t writeToPipe(int pipe, const char* buffer, ssize_t size); inline ssize_t writeToPipe(int pipe, const std::string& message) @@ -41,16 +43,6 @@ namespace IoUtil ssize_t readFromPipe(int pipe, char* buffer, ssize_t size); - /// Send frame. If it is too long, send a 'nextmessage:' before the real - /// frame. - void sendLargeFrame(const std::shared_ptr<Poco::Net::WebSocket>& ws, const char *message, int length, int flags = Poco::Net::WebSocket::FRAME_TEXT); - - /// Send frame as above, the std::string variant. - inline void sendLargeFrame(const std::shared_ptr<Poco::Net::WebSocket>& ws, const std::vector<char> &message, int flags = Poco::Net::WebSocket::FRAME_TEXT) - { - sendLargeFrame(ws, message.data(), message.size(), flags); - } - /// Helper class to handle reading from a pipe. class PipeReader { diff --git a/loolwsd/LOOLKit.cpp b/loolwsd/LOOLKit.cpp index f228be9..397dcc5 100644 --- a/loolwsd/LOOLKit.cpp +++ b/loolwsd/LOOLKit.cpp @@ -40,7 +40,6 @@ #include <Poco/Net/HTTPResponse.h> #include <Poco/Net/NetException.h> #include <Poco/Net/Socket.h> -#include <Poco/Net/WebSocket.h> #include <Poco/NotificationQueue.h> #include <Poco/Process.h> #include <Poco/Runnable.h> @@ -55,6 +54,7 @@ #include "LOKitHelper.hpp" #include "LOOLKit.hpp" #include "LOOLProtocol.hpp" +#include <LOOLWebSocket.hpp> #include "LibreOfficeKit.hpp" #include "Log.hpp" #include "Png.hpp" @@ -280,7 +280,7 @@ public: const std::string& docKey, const std::string& url, std::shared_ptr<TileQueue> tileQueue, - const std::shared_ptr<WebSocket>& ws) + const std::shared_ptr<LOOLWebSocket>& ws) : _loKit(loKit), _jailId(jailId), _docKey(docKey), @@ -450,7 +450,7 @@ public: LOG_INF("setDocumentPassword returned"); } - void renderTile(StringTokenizer& tokens, const std::shared_ptr<Poco::Net::WebSocket>& ws) + void renderTile(StringTokenizer& tokens, const std::shared_ptr<LOOLWebSocket>& ws) { assert(ws && "Expected a non-null websocket."); auto tile = TileDesc::parse(tokens); @@ -505,10 +505,10 @@ public: } LOG_TRC("Sending render-tile response (" + std::to_string(output.size()) + " bytes) for: " + response); - IoUtil::sendLargeFrame(ws, output, WebSocket::FRAME_BINARY); + ws->sendFrame(output.data(), output.size(), WebSocket::FRAME_BINARY); } - void renderCombinedTiles(StringTokenizer& tokens, const std::shared_ptr<Poco::Net::WebSocket>& ws) + void renderCombinedTiles(StringTokenizer& tokens, const std::shared_ptr<LOOLWebSocket>& ws) { assert(ws && "Expected a non-null websocket."); auto tileCombined = TileCombined::parse(tokens); @@ -605,7 +605,7 @@ public: std::copy(tileMsg.begin(), tileMsg.end(), response.begin()); std::copy(output.begin(), output.end(), response.begin() + tileMsg.size()); - IoUtil::sendLargeFrame(ws, response, WebSocket::FRAME_BINARY); + ws->sendFrame(response.data(), response.size(), WebSocket::FRAME_BINARY); } bool sendTextFrame(const std::string& message) override @@ -618,7 +618,7 @@ public: return false; } - IoUtil::sendLargeFrame(_ws, message.data(), message.size()); + _ws->sendFrame(message.data(), message.size()); return true; } catch (const Exception& exc) @@ -1244,7 +1244,7 @@ private: std::shared_ptr<lok::Document> _loKitDocument; std::shared_ptr<TileQueue> _tileQueue; - std::shared_ptr<WebSocket> _ws; + std::shared_ptr<LOOLWebSocket> _ws; // Document password provided std::string _docPassword; @@ -1462,7 +1462,7 @@ void lokit_main(const std::string& childRoot, HTTPRequest request(HTTPRequest::HTTP_GET, requestUrl); HTTPResponse response; - auto ws = std::make_shared<WebSocket>(cs, request, response); + auto ws = std::make_shared<LOOLWebSocket>(cs, request, response); ws->setReceiveTimeout(0); auto queue = std::make_shared<TileQueue>(); diff --git a/loolwsd/LOOLProtocol.hpp b/loolwsd/LOOLProtocol.hpp index fe11f2e..2c158ff 100644 --- a/loolwsd/LOOLProtocol.hpp +++ b/loolwsd/LOOLProtocol.hpp @@ -16,9 +16,10 @@ #include <string> #include <Poco/Format.h> -#include <Poco/Net/WebSocket.h> #include <Poco/StringTokenizer.h> +#include <LOOLWebSocket.hpp> + #define LOK_USE_UNSTABLE_API #include <LibreOfficeKit/LibreOfficeKitEnums.h> @@ -189,7 +190,7 @@ namespace LOOLProtocol return getAbbreviatedMessage(message.data(), message.size()); } - // Return a string dump of a WebSocket frame: Its opcode, length, first line (if present), + // Return a string dump of a LOOLWebSocket frame: Its opcode, length, first line (if present), // flags. For human-readable logging purposes. Format not guaranteed to be stable. Not to be // inspected programmatically. inline diff --git a/loolwsd/LOOLSession.cpp b/loolwsd/LOOLSession.cpp index db091f5..97ae19e 100644 --- a/loolwsd/LOOLSession.cpp +++ b/loolwsd/LOOLSession.cpp @@ -27,7 +27,6 @@ #include <Poco/Exception.h> #include <Poco/Net/Socket.h> -#include <Poco/Net/WebSocket.h> #include <Poco/Path.h> #include <Poco/String.h> #include <Poco/StringTokenizer.h> @@ -36,6 +35,7 @@ #include "Common.hpp" #include "IoUtil.hpp" #include "LOOLProtocol.hpp" +#include <LOOLWebSocket.hpp> #include "Log.hpp" #include "TileCache.hpp" #include "Util.hpp" @@ -49,7 +49,7 @@ using Poco::Net::WebSocket; using Poco::StringTokenizer; LOOLSession::LOOLSession(const std::string& id, const Kind kind, - std::shared_ptr<WebSocket> ws) : + std::shared_ptr<LOOLWebSocket> ws) : _id(id), _kind(kind), _kindString(kind == Kind::ToClient ? "ToClient" : @@ -84,7 +84,7 @@ bool LOOLSession::sendTextFrame(const char* buffer, const int length) return false; } - IoUtil::sendLargeFrame(_ws, buffer, length); + _ws->sendFrame(buffer, length); return true; } catch (const Exception& exc) @@ -109,7 +109,7 @@ bool LOOLSession::sendBinaryFrame(const char *buffer, int length) return false; } - IoUtil::sendLargeFrame(_ws, buffer, length, WebSocket::FRAME_BINARY); + _ws->sendFrame(buffer, length, WebSocket::FRAME_BINARY); return true; } catch (const Exception& exc) @@ -213,7 +213,7 @@ void LOOLSession::shutdown(Poco::UInt16 statusCode, const std::string& statusMes } catch (const Poco::Exception &exc) { - LOG_WRN("LOOLSession::shutdown WebSocket: Exception: " << + LOG_WRN("LOOLSession::shutdown LOOLWebSocket: Exception: " << exc.displayText() << (exc.nested() ? " (" + exc.nested()->displayText() + ")" : "")); } } diff --git a/loolwsd/LOOLSession.hpp b/loolwsd/LOOLSession.hpp index cd6b9fe..736e63d 100644 --- a/loolwsd/LOOLSession.hpp +++ b/loolwsd/LOOLSession.hpp @@ -17,18 +17,18 @@ #include <ostream> #include <Poco/Buffer.h> -#include <Poco/Net/WebSocket.h> #include <Poco/Path.h> #include <Poco/Process.h> #include <Poco/StringTokenizer.h> #include <Poco/Types.h> #include "LOOLProtocol.hpp" +#include <LOOLWebSocket.hpp> #include "Log.hpp" #include "MessageQueue.hpp" #include "TileCache.hpp" -/// Base class of a WebSocket session. +/// Base class of a LOOLWebSocket session. class LOOLSession { public: @@ -83,7 +83,7 @@ public: protected: LOOLSession(const std::string& id, const Kind kind, - std::shared_ptr<Poco::Net::WebSocket> ws); + std::shared_ptr<LOOLWebSocket> ws); virtual ~LOOLSession(); /// Parses the options of the "load" command, shared between MasterProcessSession::loadDocument() and ChildProcessSession::loadDocument(). @@ -146,7 +146,7 @@ private: // In the master process, the websocket to the LOOL client or the jailed child process. In a // jailed process, the websocket to the parent. - std::shared_ptr<Poco::Net::WebSocket> _ws; + std::shared_ptr<LOOLWebSocket> _ws; /// True if we have been disconnected. std::atomic<bool> _disconnected; diff --git a/loolwsd/LOOLStress.cpp b/loolwsd/LOOLStress.cpp index 484d3fb..7dbe7a6 100644 --- a/loolwsd/LOOLStress.cpp +++ b/loolwsd/LOOLStress.cpp @@ -121,7 +121,7 @@ public: } const std::string& getName() const { return _name; } - std::shared_ptr<Poco::Net::WebSocket> getWS() const { return _ws; }; + std::shared_ptr<LOOLWebSocket> getWS() const { return _ws; }; /// Send a command to the server. void send(const std::string& data) const @@ -143,7 +143,7 @@ public: } private: - Connection(const std::string& documentURL, const std::string& sessionId, std::shared_ptr<Poco::Net::WebSocket>& ws) : + Connection(const std::string& documentURL, const std::string& sessionId, std::shared_ptr<LOOLWebSocket>& ws) : _documentURL(documentURL), _sessionId(sessionId), _name(sessionId + ' '), @@ -155,7 +155,7 @@ private: const std::string _documentURL; const std::string _sessionId; const std::string _name; - std::shared_ptr<Poco::Net::WebSocket> _ws; + std::shared_ptr<LOOLWebSocket> _ws; static std::mutex Mutex; }; diff --git a/loolwsd/LOOLWSD.cpp b/loolwsd/LOOLWSD.cpp index 40876de..87cf4a6 100644 --- a/loolwsd/LOOLWSD.cpp +++ b/loolwsd/LOOLWSD.cpp @@ -77,7 +77,6 @@ #include <Poco/Net/SecureServerSocket.h> #include <Poco/Net/ServerSocket.h> #include <Poco/Net/SocketAddress.h> -#include <Poco/Net/WebSocket.h> #include <Poco/Path.h> #include <Poco/Pipe.h> #include <Poco/Process.h> @@ -103,6 +102,7 @@ #include "IoUtil.hpp" #include "LOOLProtocol.hpp" #include "LOOLSession.hpp" +#include <LOOLWebSocket.hpp> #include "Log.hpp" #include "PrisonerSession.hpp" #include "QueueHandler.hpp" @@ -180,7 +180,7 @@ namespace { static inline -void shutdownLimitReached(WebSocket& ws) +void shutdownLimitReached(LOOLWebSocket& ws) { const std::string error = Poco::format(PAYLOAD_UNAVAILABLE_LIMIT_REACHED, MAX_DOCUMENTS, MAX_CONNECTIONS); @@ -519,7 +519,7 @@ private: DocBrokers.emplace(docKey, docBroker); // Load the document. - std::shared_ptr<WebSocket> ws; + std::shared_ptr<LOOLWebSocket> ws; auto session = std::make_shared<ClientSession>(id, ws, docBroker, uriPublic); auto sessionsCount = docBroker->addSession(session); @@ -704,7 +704,7 @@ private: } /// Handle GET requests. - static void handleGetRequest(const std::string& uri, std::shared_ptr<WebSocket>& ws, const std::string& id) + static void handleGetRequest(const std::string& uri, std::shared_ptr<LOOLWebSocket>& ws, const std::string& id) { LOG_INF("Starting GET request handler for session [" << id << "]."); @@ -1049,7 +1049,7 @@ public: --LOOLWSD::NumConnections; LOG_ERR("Limit on maximum number of connections of " << MAX_CONNECTIONS << " reached."); // accept hand shake - WebSocket ws(request, response); + LOOLWebSocket ws(request, response); shutdownLimitReached(ws); return; } @@ -1118,7 +1118,7 @@ public: } else if (reqPathTokens.count() > 2 && reqPathTokens[0] == "lool" && reqPathTokens[2] == "ws") { - auto ws = std::make_shared<WebSocket>(request, response); + auto ws = std::make_shared<LOOLWebSocket>(request, response); responded = true; // After upgrading to WS we should not set HTTP response. try { @@ -1233,7 +1233,7 @@ public: } LOG_INF("New child [" << pid << "]."); - auto ws = std::make_shared<WebSocket>(request, response); + auto ws = std::make_shared<LOOLWebSocket>(request, response); UnitWSD::get().newChild(ws); addNewChild(std::make_shared<ChildProcess>(pid, ws)); @@ -1276,7 +1276,7 @@ public: { requestHandler = FileServer::createRequestHandler(); } - // Admin WebSocket Connections + // Admin LOOLWebSocket Connections else if (reqPathSegs.size() >= 2 && reqPathSegs[0] == "lool" && reqPathSegs[1] == "adminws") { requestHandler = Admin::createRequestHandler(); diff --git a/loolwsd/LOOLWebSocket.hpp b/loolwsd/LOOLWebSocket.hpp new file mode 100644 index 0000000..ffd4887 --- /dev/null +++ b/loolwsd/LOOLWebSocket.hpp @@ -0,0 +1,86 @@ +/* -*- 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/. + */ + +#ifndef INCLUDED_LOOLWEBSOCKET_HPP +#define INCLUDED_LOOLWEBSOCKET_HPP + +#include <mutex> + +#include <Poco/Net/WebSocket.h> + +#include <Common.hpp> +#include <LOOLProtocol.hpp> +#include <Log.hpp> + +/// WebSocket that is thread safe, and handles large frames transparently. +class LOOLWebSocket : public Poco::Net::WebSocket +{ + std::mutex _mutex; + +public: + LOOLWebSocket(const Socket & socket) : + Poco::Net::WebSocket(socket), + _mutex() + { + } + + LOOLWebSocket(Poco::Net::HTTPServerRequest & request, Poco::Net::HTTPServerResponse & response) : + Poco::Net::WebSocket(request, response), + _mutex() + { + } + + LOOLWebSocket(Poco::Net::HTTPClientSession & cs, Poco::Net::HTTPRequest & request, Poco::Net::HTTPResponse & response) : + Poco::Net::WebSocket(cs, request, response), + _mutex() + { + } + + LOOLWebSocket(Poco::Net::HTTPClientSession & cs, Poco::Net::HTTPRequest & request, Poco::Net::HTTPResponse & response, Poco::Net::HTTPCredentials & credentials) : + Poco::Net::WebSocket(cs, request, response, credentials), + _mutex() + { + } + + /// Careful - sendFrame is _not_ virtual, we need to make sure that we use + /// LOOLWebSocket all over the place + /// It would be a kind of more natural to encapsulate Poco::Net::WebSocket + /// instead of inheriting (from that reason), but that would requite much + /// larger code changes. + int sendFrame(const void * buffer, int length, int flags = FRAME_TEXT) + { + std::lock_guard<std::mutex> lock(_mutex); + + // Size after which messages will be sent preceded with + // 'nextmessage' frame to let the receiver know in advance + // the size of larger coming message. All messages up to this + // size are considered small messages. + constexpr int SMALL_MESSAGE_SIZE = READ_BUFFER_SIZE / 2; + + if (length > SMALL_MESSAGE_SIZE) + { + const std::string nextmessage = "nextmessage: size=" + std::to_string(length); + Poco::Net::WebSocket::sendFrame(nextmessage.data(), nextmessage.size()); + Log::debug("Message is long, sent " + nextmessage); + } + + int result = Poco::Net::WebSocket::sendFrame(buffer, length, flags); + // FIXME we want an abbreviated message here, but we'd have a circular + // dependency with LOOLProtocol, so use the full message here before + // we move getAbbreviatedMessage() to Log (where it belongs anyway). + //Log::debug("Sent frame: " + LOOLProtocol::getAbbreviatedMessage(static_cast<const char*>(buffer), length)); + Log::debug("Sent frame: " + std::string(static_cast<const char*>(buffer), length)); + + return result; + } +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/loolwsd/Makefile.am b/loolwsd/Makefile.am index 1f47750..cb4a7a9 100644 --- a/loolwsd/Makefile.am +++ b/loolwsd/Makefile.am @@ -82,7 +82,8 @@ looltool_SOURCES = LOOLTool.cpp loolstress_CPPFLAGS = -DTDOC=\"$(abs_top_srcdir)/test/data\" loolstress_SOURCES = LOOLStress.cpp \ - LOOLProtocol.cpp + LOOLProtocol.cpp \ + Log.cpp noinst_HEADERS = Admin.hpp \ AdminModel.hpp \ diff --git a/loolwsd/Unit.hpp b/loolwsd/Unit.hpp index 97b7103..7b6c6f8 100644 --- a/loolwsd/Unit.hpp +++ b/loolwsd/Unit.hpp @@ -14,7 +14,7 @@ #include <memory> #include <string> -#include <Poco/Net/WebSocket.h> +#include <LOOLWebSocket.hpp> class UnitBase; class UnitWSD; @@ -139,7 +139,7 @@ public: /// Tweak the count of pre-spawned kits. virtual void preSpawnCount(int& /* numPrefork */) {} /// When a new child kit process reports - virtual void newChild(const std::shared_ptr<Poco::Net::WebSocket>& /* socket */) {} + virtual void newChild(const std::shared_ptr<LOOLWebSocket>& /* socket */) {} /// Intercept createStorage virtual bool createStorage(const Poco::URI& /* uri */, const std::string& /* jailRoot */, @@ -221,7 +221,7 @@ public: virtual void postFork() {} /// Kit got a message - virtual bool filterKitMessage(const std::shared_ptr<Poco::Net::WebSocket>& /* ws */, + virtual bool filterKitMessage(const std::shared_ptr<LOOLWebSocket>& /* ws */, std::string& /* message */) { return false; diff --git a/loolwsd/UnitHTTP.cpp b/loolwsd/UnitHTTP.cpp index d42aea0..6775695 100644 --- a/loolwsd/UnitHTTP.cpp +++ b/loolwsd/UnitHTTP.cpp @@ -26,7 +26,7 @@ UnitWebSocket::UnitWebSocket(const std::string &docURL) _session = UnitHTTP::createSession(); // FIXME: leaking the session - hey ho ... do we need a UnitSocket ? - _socket = new Poco::Net::WebSocket(*_session, request, response); + _socket = new LOOLWebSocket(*_session, request, response); } catch (const Poco::Exception &ex) { std::cerr << "Exception creating websocket " << ex.displayText() << std::endl; throw; diff --git a/loolwsd/UnitHTTP.hpp b/loolwsd/UnitHTTP.hpp index 3c28613..7765e47 100644 --- a/loolwsd/UnitHTTP.hpp +++ b/loolwsd/UnitHTTP.hpp @@ -18,10 +18,10 @@ #include <Poco/Net/HTTPServerRequest.h> #include <Poco/Net/HTTPServerResponse.h> #include <Poco/Net/SocketAddress.h> -#include <Poco/Net/WebSocket.h> #include <Poco/Version.h> #include "Common.hpp" +#include <LOOLWebSocket.hpp> using Poco::Net::SocketAddress; using Poco::Net::HTTPServerParams; @@ -121,7 +121,7 @@ namespace UnitHTTP class UnitWebSocket { Poco::Net::HTTPClientSession* _session; - Poco::Net::WebSocket* _socket; + LOOLWebSocket* _socket; public: /// Get a websocket connected for a given URL diff --git a/loolwsd/Util.hpp b/loolwsd/Util.hpp index cde7828..ae4c3cd 100644 --- a/loolwsd/Util.hpp +++ b/loolwsd/Util.hpp @@ -20,7 +20,6 @@ #include <string> #include <Poco/File.h> -#include <Poco/Net/WebSocket.h> #include <Poco/Path.h> #include <Poco/Process.h> #include <Poco/RegularExpression.h> diff --git a/loolwsd/test/TileCacheTests.cpp b/loolwsd/test/TileCacheTests.cpp index ade2ae0..5343092 100644 --- a/loolwsd/test/TileCacheTests.cpp +++ b/loolwsd/test/TileCacheTests.cpp @@ -9,11 +9,11 @@ #include "config.h" -#include <Poco/Net/WebSocket.h> #include <cppunit/extensions/HelperMacros.h> #include "Common.hpp" #include "LOOLProtocol.hpp" +#include <LOOLWebSocket.hpp> #include "MessageQueue.hpp" #include "Png.hpp" #include "TileCache.hpp" @@ -94,17 +94,17 @@ class TileCacheTests : public CPPUNIT_NS::TestFixture void tileInvalidatePart(const std::string& filename, const std::string& testname); - void checkTiles(Poco::Net::WebSocket& socket, + void checkTiles(std::shared_ptr<LOOLWebSocket>& socket, const std::string& type, const std::string& name = "checkTiles "); - void requestTiles(Poco::Net::WebSocket& socket, + void requestTiles(std::shared_ptr<LOOLWebSocket>& socket, const int part, const int docWidth, const int docHeight, const std::string& name = "requestTiles "); - void checkBlackTiles(Poco::Net::WebSocket& socket, + void checkBlackTiles(std::shared_ptr<LOOLWebSocket>& socket, const int part, const int docWidth, const int docHeight, @@ -212,7 +212,7 @@ void TileCacheTests::testSimpleCombine() void TileCacheTests::testPerformance() { - auto socket = *loadDocAndGetSocket("hello.odt", _uri, "performance "); + auto socket = loadDocAndGetSocket("hello.odt", _uri, "performance "); Poco::Timestamp timestamp; for (auto x = 0; x < 5; ++x) @@ -230,13 +230,13 @@ void TileCacheTests::testPerformance() << " ms. Per-tile: " << timestamp.elapsed() / (1000. * 5 * 8) << "ms." << std::endl; - socket.shutdown(); + socket->shutdown(); } void TileCacheTests::testCancelTiles() { const auto testName = "cancelTiles "; - auto socket = *loadDocAndGetSocket("setclientpart.ods", _uri, testName); + auto socket = loadDocAndGetSocket("setclientpart.ods", _uri, testName); // Request a huge tile, and cancel immediately. sendTextFrame(socket, "tilecombine part=0 width=2560 height=2560 tileposx=0 tileposy=0 tilewidth=38400 tileheight=38400"); @@ -322,10 +322,10 @@ void TileCacheTests::testImpressTiles() try { const std::string testName = "impressTiles "; - auto socket = *loadDocAndGetSocket("setclientpart.odp", _uri, testName); + auto socket = loadDocAndGetSocket("setclientpart.odp", _uri, testName); sendTextFrame(socket, "tile part=0 width=180 height=135 tileposx=0 tileposy=0 tilewidth=15875 tileheight=11906 id=0", testName); - getTileMessage(socket, testName); + getTileMessage(*socket, testName); } catch (const Poco::Exception& exc) { @@ -338,11 +338,11 @@ void TileCacheTests::testClientPartImpress() try { const std::string testName = "clientPartImpress "; - auto socket = *loadDocAndGetSocket("setclientpart.odp", _uri, testName); + auto socket = loadDocAndGetSocket("setclientpart.odp", _uri, testName); checkTiles(socket, "presentation", testName); - socket.shutdown(); + socket->shutdown(); } catch (const Poco::Exception& exc) { @@ -355,11 +355,11 @@ void TileCacheTests::testClientPartCalc() try { const std::string testName = "clientPartCalc "; - auto socket = *loadDocAndGetSocket("setclientpart.ods", _uri, testName); + auto socket = loadDocAndGetSocket("setclientpart.ods", _uri, testName); checkTiles(socket, "spreadsheet", testName); - socket.shutdown(); + socket->shutdown(); } catch (const Poco::Exception& exc) { @@ -371,7 +371,7 @@ void TileCacheTests::testTilesRenderedJustOnce() { const auto testname = "tilesRenderdJustOnce "; - auto socket = *loadDocAndGetSocket("with_comment.odt", _uri, testname); + auto socket = loadDocAndGetSocket("with_comment.odt", _uri, testname); assertResponseString(socket, "statechanged: .uno:AcceptTrackedChange=", testname); @@ -439,13 +439,13 @@ void TileCacheTests::testTilesRenderedJustOnceMultiClient() getDocumentPathAndURL("with_comment.odt", documentPath, documentURL); std::cerr << "Connecting first client." << std::endl; - auto socket = *loadDocAndGetSocket(_uri, documentURL, testname1); + auto socket = loadDocAndGetSocket(_uri, documentURL, testname1); std::cerr << "Connecting second client." << std::endl; - auto socket2 = *loadDocAndGetSocket(_uri, documentURL, testname2); + auto socket2 = loadDocAndGetSocket(_uri, documentURL, testname2); std::cerr << "Connecting third client." << std::endl; - auto socket3 = *loadDocAndGetSocket(_uri, documentURL, testname3); + auto socket3 = loadDocAndGetSocket(_uri, documentURL, testname3); std::cerr << "Connecting fourth client." << std::endl; - auto socket4 = *loadDocAndGetSocket(_uri, documentURL, "tilesRenderdJustOnce-4 "); + auto socket4 = loadDocAndGetSocket(_uri, documentURL, "tilesRenderdJustOnce-4 "); for (int i = 0; i < 10; ++i) { @@ -562,7 +562,7 @@ void TileCacheTests::testLoad12ods() try { const auto testName = "load12ods "; - auto socket = *loadDocAndGetSocket("load12.ods", _uri, testName); + auto socket = loadDocAndGetSocket("load12.ods", _uri, testName); int docSheet = -1; int docSheets = 0; @@ -616,7 +616,7 @@ void TileCacheTests::checkBlackTile(std::stringstream& tile) CPPUNIT_ASSERT_MESSAGE("The tile is 90% black", (black * 100) / (height * width) < 90); } -void TileCacheTests::checkBlackTiles(Poco::Net::WebSocket& socket, const int /*part*/, const int /*docWidth*/, const int /*docHeight*/, const std::string& name) +void TileCacheTests::checkBlackTiles(std::shared_ptr<LOOLWebSocket>& socket, const int /*part*/, const int /*docWidth*/, const int /*docHeight*/, const std::string& name) { // Check the last row of tiles to verify that the tiles // render correctly and there are no black tiles. @@ -645,7 +645,7 @@ void TileCacheTests::testTileInvalidateWriter() getDocumentPathAndURL("empty.odt", documentPath, documentURL); Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, documentURL); - auto socket = *loadDocAndGetSocket(_uri, documentURL); + auto socket = loadDocAndGetSocket(_uri, documentURL); std::string text = "Test. Now go 3 \"Enters\":\n\n\nNow after the enters, goes this text"; for (char ch : text) @@ -682,7 +682,7 @@ void TileCacheTests::testTileInvalidateWriterPage() getDocumentPathAndURL("empty.odt", documentPath, documentURL); Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, documentURL); - auto socket = *loadDocAndGetSocket(_uri, documentURL, testname); + auto socket = loadDocAndGetSocket(_uri, documentURL, testname); sendChar(socket, '\n', skCtrl, testname); // Send Ctrl+Enter (page break). assertResponseString(socket, "invalidatetiles:", testname); @@ -703,7 +703,7 @@ void TileCacheTests::testWriterAnyKey() getDocumentPathAndURL("empty.odt", documentPath, documentURL); Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, documentURL); - auto socket = *loadDocAndGetSocket(_uri, documentURL); + auto socket = loadDocAndGetSocket(_uri, documentURL); // Now test "usual" keycodes (TODO: whole 32-bit range) for (int i=0; i<0x1000; ++i) @@ -783,7 +783,7 @@ void TileCacheTests::testWriterAnyKey() void TileCacheTests::testTileInvalidateCalc() { const std::string testname = "tileInvalidateCalc "; - auto socket = *loadDocAndGetSocket("empty.ods", _uri, testname); + auto socket = loadDocAndGetSocket("empty.ods", _uri, testname); std::string text = "Test. Now go 3 \"Enters\": Now after the enters, goes this text"; for (char ch : text) @@ -815,13 +815,13 @@ void TileCacheTests::tileInvalidatePart(const std::string& filename, const std:: std::string documentPath, documentURL; getDocumentPathAndURL(filename, documentPath, documentURL); - auto socket1 = *loadDocAndGetSocket(_uri, documentURL); + auto socket1 = loadDocAndGetSocket(_uri, documentURL); sendTextFrame(socket1, "setclientpart part=2", testname1); assertResponseString(socket1, "setpart:", testname1); sendTextFrame(socket1, "mouse type=buttondown x=7886 y=8929 count=1 buttons=1 modifier=0", testname1); - auto socket2 = *loadDocAndGetSocket(_uri, documentURL); + auto socket2 = loadDocAndGetSocket(_uri, documentURL); sendTextFrame(socket2, "setclientpart part=5", testname2); assertResponseString(socket2, "setpart:", testname2); sendTextFrame(socket2, "mouse type=buttondown x=7886 y=8929 count=1 buttons=1 modifier=0", testname2); @@ -855,7 +855,7 @@ void TileCacheTests::testTileInvalidatePartImpress() tileInvalidatePart("setclientpart.odp", "tileInvalidatePartImpress"); } -void TileCacheTests::checkTiles(Poco::Net::WebSocket& socket, const std::string& docType, const std::string& name) +void TileCacheTests::checkTiles(std::shared_ptr<LOOLWebSocket>& socket, const std::string& docType, const std::string& name) { const std::string current = "current="; const std::string height = "height="; @@ -922,7 +922,7 @@ void TileCacheTests::checkTiles(Poco::Net::WebSocket& socket, const std::string& } } -void TileCacheTests::requestTiles(Poco::Net::WebSocket& socket, const int part, const int docWidth, const int docHeight, const std::string& name) +void TileCacheTests::requestTiles(std::shared_ptr<LOOLWebSocket>& socket, const int part, const int docWidth, const int docHeight, const std::string& name) { // twips const int tileSize = 3840; diff --git a/loolwsd/test/UnitAdmin.cpp b/loolwsd/test/UnitAdmin.cpp index 9f704c1..96ccee8 100644 --- a/loolwsd/test/UnitAdmin.cpp +++ b/loolwsd/test/UnitAdmin.cpp @@ -45,14 +45,14 @@ private: std::string _jwtCookie; bool _isTestRunning = false; const Poco::URI _uri; - std::shared_ptr<Poco::Net::WebSocket> _adminWs; + std::shared_ptr<LOOLWebSocket> _adminWs; typedef TestResult (UnitAdmin::*AdminTest)(void); std::vector<AdminTest> _tests; - std::shared_ptr<Poco::Net::WebSocket> _docWs1; - std::shared_ptr<Poco::Net::WebSocket> _docWs2; - std::shared_ptr<Poco::Net::WebSocket> _docWs3; + std::shared_ptr<LOOLWebSocket> _docWs1; + std::shared_ptr<LOOLWebSocket> _docWs2; + std::shared_ptr<LOOLWebSocket> _docWs3; int _docPid1; int _docPid2; int _docPid3; @@ -131,7 +131,7 @@ private: HTTPRequest request(HTTPRequest::HTTP_GET, "/lool/adminws/"); std::unique_ptr<HTTPClientSession> session(UnitHTTP::createSession()); - _adminWs = std::make_shared<Poco::Net::WebSocket>(*session, request, response); + _adminWs = std::make_shared<LOOLWebSocket>(*session, request, response); const std::string testMessage = "documents"; std::unique_lock<std::mutex> lock(_messageReceivedMutex); _messageReceived.clear(); @@ -162,7 +162,7 @@ private: HTTPRequest request(HTTPRequest::HTTP_GET, "/lool/adminws/"); std::unique_ptr<HTTPClientSession> session(UnitHTTP::createSession()); - _adminWs = std::make_shared<Poco::Net::WebSocket>(*session, request, response); + _adminWs = std::make_shared<LOOLWebSocket>(*session, request, response); const std::string testMessage = "auth jwt=incorrectJWT"; std::unique_lock<std::mutex> lock(_messageReceivedMutex); _messageReceived.clear(); @@ -193,7 +193,7 @@ private: HTTPRequest request(HTTPRequest::HTTP_GET, "/lool/adminws/"); std::unique_ptr<HTTPClientSession> session(UnitHTTP::createSession()); - _adminWs = std::make_shared<Poco::Net::WebSocket>(*session, request, response); + _adminWs = std::make_shared<LOOLWebSocket>(*session, request, response); const std::string authMessage = "auth jwt=" + _jwtCookie; _adminWs->sendFrame(authMessage.data(), authMessage.size()); @@ -216,7 +216,7 @@ private: std::unique_lock<std::mutex> lock(_messageReceivedMutex); _messageReceived.clear(); - _docWs1 = std::make_shared<Poco::Net::WebSocket>(*session1, request1, response1); + _docWs1 = std::make_shared<LOOLWebSocket>(*session1, request1, response1); _docWs1->sendFrame(loadMessage1.data(), loadMessage1.size()); if (_messageReceivedCV.wait_for(lock, std::chrono::milliseconds(_messageTimeoutMilliSeconds)) == std::cv_status::timeout) { @@ -244,7 +244,7 @@ private: // Open another view of same document lock.lock(); // lock _messageReceivedMutex _messageReceived.clear(); - _docWs2 = std::make_shared<Poco::Net::WebSocket>(*session2, request1, response1); + _docWs2 = std::make_shared<LOOLWebSocket>(*session2, request1, response1); _docWs2->sendFrame(loadMessage1.data(), loadMessage1.size()); if (_messageReceivedCV.wait_for(lock, std::chrono::milliseconds(_messageTimeoutMilliSeconds)) == std::cv_status::timeout) { @@ -279,7 +279,7 @@ private: lock.lock(); // lock _messageReceivedMutex _messageReceived.clear(); - _docWs3 = std::make_shared<Poco::Net::WebSocket>(*session3, request2, response2); + _docWs3 = std::make_shared<LOOLWebSocket>(*session3, request2, response2); _docWs3->sendFrame(loadMessage2.data(), loadMessage2.size()); if (_messageReceivedCV.wait_for(lock, std::chrono::milliseconds(_messageTimeoutMilliSeconds)) == std::cv_status::timeout) { diff --git a/loolwsd/test/UnitFonts.cpp b/loolwsd/test/UnitFonts.cpp index c82dcbb..60312d4 100644 --- a/loolwsd/test/UnitFonts.cpp +++ b/loolwsd/test/UnitFonts.cpp @@ -41,7 +41,7 @@ namespace { return std::string("can't find unit_online_get_fonts hook"); } - std::string readFontList(const std::shared_ptr< Poco::Net::WebSocket > &socket) + std::string readFontList(const std::shared_ptr<LOOLWebSocket> &socket) { int flags; char buffer[100 * 1000]; @@ -89,7 +89,7 @@ public: } } - virtual void newChild(const std::shared_ptr<Poco::Net::WebSocket> &socket) override + virtual void newChild(const std::shared_ptr<LOOLWebSocket> &socket) override { Log::info("Fetching font list from kit"); socket->sendFrame("unit-getfontlist: \n", @@ -106,7 +106,7 @@ public: if (type == UnitWSD::TestRequest::TEST_REQ_PRISONER && request.getURI().find(UNIT_URI) == 0) { - auto ws = std::make_shared<Poco::Net::WebSocket>(request, response); + auto ws = std::make_shared<LOOLWebSocket>(request, response); _fontsBroker = readFontList(ws); check(); return true; @@ -133,7 +133,7 @@ public: Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, std::string(UNIT_URI)); Poco::Net::HTTPResponse response; - auto ws = std::make_shared<Poco::Net::WebSocket>(cs, request, response); + auto ws = std::make_shared<LOOLWebSocket>(cs, request, response); ws->setReceiveTimeout(0); Log::info("Fetching font list from forkit"); std::string fontListMsg = getFontList() + "\n"; @@ -141,7 +141,7 @@ public: } // Called from WSD and handled inside the kit. - virtual bool filterKitMessage(const std::shared_ptr<Poco::Net::WebSocket> &ws, + virtual bool filterKitMessage(const std::shared_ptr<LOOLWebSocket> &ws, std::string &message) override { const std::string token = LOOLProtocol::getFirstToken(message); diff --git a/loolwsd/test/UnitFuzz.cpp b/loolwsd/test/UnitFuzz.cpp index 57622b3..7454aa4 100644 --- a/loolwsd/test/UnitFuzz.cpp +++ b/loolwsd/test/UnitFuzz.cpp @@ -17,12 +17,12 @@ #include "Common.hpp" #include "IoUtil.hpp" #include "LOOLProtocol.hpp" +#include <LOOLWebSocket.hpp> #include "Unit.hpp" #include "Util.hpp" #include <Poco/Timestamp.h> #include <Poco/StringTokenizer.h> -#include <Poco/Net/WebSocket.h> // Inside the WSD process class UnitFuzz : public UnitWSD @@ -55,7 +55,7 @@ public: { } - virtual bool filterKitMessage(const std::shared_ptr<Poco::Net::WebSocket> & /* ws */, + virtual bool filterKitMessage(const std::shared_ptr<LOOLWebSocket> & /* ws */, std::string & /* message */) override { return false; diff --git a/loolwsd/test/UnitPrefork.cpp b/loolwsd/test/UnitPrefork.cpp index e6837f5..9f5463b 100644 --- a/loolwsd/test/UnitPrefork.cpp +++ b/loolwsd/test/UnitPrefork.cpp @@ -21,11 +21,11 @@ #include <Poco/Timestamp.h> #include <Poco/StringTokenizer.h> -#include <Poco/Net/WebSocket.h> #include "Common.hpp" #include "IoUtil.hpp" #include "LOOLProtocol.hpp" +#include <LOOLWebSocket.hpp> #include "Log.hpp" #include "Unit.hpp" #include "Util.hpp" @@ -41,7 +41,7 @@ class UnitPrefork : public UnitWSD size_t _childDirty; std::mutex _mutex; std::condition_variable _cv; - std::vector< std::shared_ptr<Poco::Net::WebSocket> > _childSockets; + std::vector< std::shared_ptr<LOOLWebSocket> > _childSockets; public: UnitPrefork() @@ -81,7 +81,7 @@ public: return true; } - virtual void newChild(const std::shared_ptr<Poco::Net::WebSocket> &socket) override + virtual void newChild(const std::shared_ptr<LOOLWebSocket> &socket) override { std::unique_lock<std::mutex> lock(_mutex); @@ -286,7 +286,7 @@ public: } } - virtual bool filterKitMessage(const std::shared_ptr<Poco::Net::WebSocket> &ws, + virtual bool filterKitMessage(const std::shared_ptr<LOOLWebSocket> &ws, std::string &message) override { const auto token = LOOLProtocol::getFirstToken(message); diff --git a/loolwsd/test/helpers.hpp b/loolwsd/test/helpers.hpp index b6d6d78..4f12c2e 100644 --- a/loolwsd/test/helpers.hpp +++ b/loolwsd/test/helpers.hpp @@ -32,7 +32,6 @@ #include <Poco/Net/PrivateKeyPassphraseHandler.h> #include <Poco/Net/SSLManager.h> #include <Poco/Net/Socket.h> -#include <Poco/Net/WebSocket.h> #include <Poco/Path.h> #include <Poco/StreamCopier.h> #include <Poco/StringTokenizer.h> @@ -42,6 +41,7 @@ #include <Common.hpp> #include <LOOLProtocol.hpp> +#include <LOOLWebSocket.hpp> #include <UserMessages.hpp> #include <Util.hpp> @@ -121,14 +121,14 @@ void getDocumentPathAndURL(const std::string& docFilename, std::string& document } inline -void sendTextFrame(Poco::Net::WebSocket& socket, const std::string& string, const std::string& name = "") +void sendTextFrame(LOOLWebSocket& socket, const std::string& string, const std::string& name = "") { std::cerr << name << "Sending " << string.size() << " bytes: " << LOOLProtocol::getAbbreviatedMessage(string) << std::endl; socket.sendFrame(string.data(), string.size()); } inline -void sendTextFrame(const std::shared_ptr<Poco::Net::WebSocket>& socket, const std::string& string, const std::string& name = "") +void sendTextFrame(const std::shared_ptr<LOOLWebSocket>& socket, const std::string& string, const std::string& name = "") { sendTextFrame(*socket, string, name); } @@ -160,7 +160,7 @@ std::string getTestServerURI() } inline -int getErrorCode(Poco::Net::WebSocket& ws, std::string& message) +int getErrorCode(LOOLWebSocket& ws, std::string& message) { int flags = 0; int bytes = 0; @@ -187,7 +187,7 @@ int getErrorCode(Poco::Net::WebSocket& ws, std::string& message) } inline -std::vector<char> getResponseMessage(Poco::Net::WebSocket& ws, const std::string& prefix, std::string name = "", const size_t timeoutMs = 10000) +std::vector<char> getResponseMessage(LOOLWebSocket& ws, const std::string& prefix, std::string name = "", const size_t timeoutMs = 10000) { name = name + '[' + prefix + "] "; try @@ -289,7 +289,7 @@ std::vector<char> getResponseMessage(Poco::Net::WebSocket& ws, const std::string } inline -std::vector<char> getResponseMessage(const std::shared_ptr<Poco::Net::WebSocket>& ws, const std::string& prefix, const std::string& name = "", const size_t timeoutMs = 10000) +std::vector<char> getResponseMessage(const std::shared_ptr<LOOLWebSocket>& ws, const std::string& prefix, const std::string& name = "", const size_t timeoutMs = 10000) { return getResponseMessage(*ws, prefix, name, timeoutMs); } @@ -319,7 +319,7 @@ std::string assertNotInResponse(T& ws, const std::string& prefix, const std::str } inline -bool isDocumentLoaded(Poco::Net::WebSocket& ws, const std::string& name = "", bool isView = true) +bool isDocumentLoaded(LOOLWebSocket& ws, const std::string& name = "", bool isView = true) { const std::string prefix = isView ? "status:" : "statusindicatorfinish:"; const auto message = getResponseString(ws, prefix, name); @@ -327,7 +327,7 @@ bool isDocumentLoaded(Poco::Net::WebSocket& ws, const std::string& name = "", bo } inline -bool isDocumentLoaded(std::shared_ptr<Poco::Net::WebSocket>& ws, const std::string& name = "", bool isView = true) +bool isDocumentLoaded(std::shared_ptr<LOOLWebSocket>& ws, const std::string& name = "", bool isView = true) { return isDocumentLoaded(*ws, name, isView); } @@ -337,7 +337,7 @@ bool isDocumentLoaded(std::shared_ptr<Poco::Net::WebSocket>& ws, const std::stri // The result, it is mostly time outs to get messages in the unit test and it could fail. // connectLOKit ensures the websocket is connected to a kit process. inline -std::shared_ptr<Poco::Net::WebSocket> +std::shared_ptr<LOOLWebSocket> connectLOKit(const Poco::URI& uri, Poco::Net::HTTPRequest& request, Poco::Net::HTTPResponse& response, @@ -349,7 +349,7 @@ connectLOKit(const Poco::URI& uri, std::unique_ptr<Poco::Net::HTTPClientSession> session(createSession(uri)); std::cerr << name << "Connecting... " << std::endl; - auto ws = std::make_shared<Poco::Net::WebSocket>(*session, request, response); + auto ws = std::make_shared<LOOLWebSocket>(*session, request, response); getResponseMessage(ws, "statusindicator: ready", name); return ws; @@ -360,7 +360,7 @@ connectLOKit(const Poco::URI& uri, } inline -std::shared_ptr<Poco::Net::WebSocket> loadDocAndGetSocket(const Poco::URI& uri, const std::string& documentURL, const std::string& name = "", bool isView = true) +std::shared_ptr<LOOLWebSocket> loadDocAndGetSocket(const Poco::URI& uri, const std::string& documentURL, const std::string& name = "", bool isView = true) { try { @@ -385,7 +385,7 @@ std::shared_ptr<Poco::Net::WebSocket> loadDocAndGetSocket(const Poco::URI& uri, } inline -std::shared_ptr<Poco::Net::WebSocket> loadDocAndGetSocket(const std::string& docFilename, const Poco::URI& uri, const std::string& name = "", bool isView = true) +std::shared_ptr<LOOLWebSocket> loadDocAndGetSocket(const std::string& docFilename, const Poco::URI& uri, const std::string& name = "", bool isView = true) { try { @@ -404,7 +404,7 @@ std::shared_ptr<Poco::Net::WebSocket> loadDocAndGetSocket(const std::string& doc inline void SocketProcessor(const std::string& name, - const std::shared_ptr<Poco::Net::WebSocket>& socket, + const std::shared_ptr<LOOLWebSocket>& socket, const std::function<bool(const std::string& msg)>& handler, const size_t timeoutMs = 10000) { @@ -457,13 +457,13 @@ void parseDocSize(const std::string& message, const std::string& type, } inline -std::vector<char> getTileMessage(Poco::Net::WebSocket& ws, const std::string& name = "") +std::vector<char> getTileMessage(LOOLWebSocket& ws, const std::string& name = "") { return getResponseMessage(ws, "tile", name); } inline -std::vector<char> assertTileMessage(Poco::Net::WebSocket& ws, const std::string& name = "") +std::vector<char> assertTileMessage(LOOLWebSocket& ws, const std::string& name = "") { const auto response = getTileMessage(ws, name); @@ -482,7 +482,7 @@ std::vector<char> assertTileMessage(Poco::Net::WebSocket& ws, const std::string& } inline -std::vector<char> assertTileMessage(const std::shared_ptr<Poco::Net::WebSocket>& ws, const std::string& name = "") +std::vector<char> assertTileMessage(const std::shared_ptr<LOOLWebSocket>& ws, const std::string& name = "") { return assertTileMessage(*ws, name); } @@ -521,25 +521,25 @@ inline int getCharKey(char ch, SpecialKey specialKeys) return result | specialKeys; } -inline void sendKeyEvent(Poco::Net::WebSocket& socket, const char* type, int chr, int key, const std::string& testname = "") +inline void sendKeyEvent(std::shared_ptr<LOOLWebSocket>& socket, const char* type, int chr, int key, const std::string& testname = "") { std::ostringstream ssIn; ssIn << "key type=" << type << " char=" << chr << " key=" << key; sendTextFrame(socket, ssIn.str(), testname); } -inline void sendKeyPress(Poco::Net::WebSocket& socket, int chr, int key, const std::string& testname) +inline void sendKeyPress(std::shared_ptr<LOOLWebSocket>& socket, int chr, int key, const std::string& testname) { sendKeyEvent(socket, "input", chr, key, testname); sendKeyEvent(socket, "up", chr, key, testname); } -inline void sendChar(Poco::Net::WebSocket& socket, char ch, SpecialKey specialKeys=skNone, const std::string& testname = "") +inline void sendChar(std::shared_ptr<LOOLWebSocket>& socket, char ch, SpecialKey specialKeys=skNone, const std::string& testname = "") { sendKeyPress(socket, getCharChar(ch, specialKeys), getCharKey(ch, specialKeys), testname); } -inline void sendText(Poco::Net::WebSocket& socket, const std::string& text, const std::string& testname = "") +inline void sendText(std::shared_ptr<LOOLWebSocket>& socket, const std::string& text, const std::string& testname = "") { for (char ch : text) { diff --git a/loolwsd/test/httpcrashtest.cpp b/loolwsd/test/httpcrashtest.cpp index ecaf4af..3bd4bcd 100644 --- a/loolwsd/test/httpcrashtest.cpp +++ b/loolwsd/test/httpcrashtest.cpp @@ -30,7 +30,6 @@ #include <Poco/Net/PrivateKeyPassphraseHandler.h> #include <Poco/Net/SSLManager.h> #include <Poco/Net/Socket.h> -#include <Poco/Net/WebSocket.h> #include <Poco/Path.h> #include <Poco/StreamCopier.h> #include <Poco/StringTokenizer.h> @@ -42,6 +41,7 @@ #include <UserMessages.hpp> #include <Util.hpp> #include <LOOLProtocol.hpp> +#include <LOOLWebSocket.hpp> #include "helpers.hpp" #include "countloolkits.hpp" @@ -144,7 +144,7 @@ void HTTPCrashTest::testCrashKit() const auto testname = "crashKit "; try { - auto socket = *loadDocAndGetSocket("empty.odt", _uri, testname); + auto socket = loadDocAndGetSocket("empty.odt", _uri, testname); killLoKitProcesses(); @@ -156,7 +156,7 @@ void HTTPCrashTest::testCrashKit() getResponseMessage(socket, "", testname, 1000); // 5 seconds timeout - socket.setReceiveTimeout(5000000); + socket->setReceiveTimeout(5000000); // receive close frame handshake int bytes; @@ -164,16 +164,16 @@ void HTTPCrashTest::testCrashKit() char buffer[READ_BUFFER_SIZE]; do { - bytes = socket.receiveFrame(buffer, sizeof(buffer), flags); + bytes = socket->receiveFrame(buffer, sizeof(buffer), flags); std::cerr << testname << "Got " << LOOLProtocol::getAbbreviatedFrameDump(buffer, bytes, flags) << std::endl; } while ((flags & Poco::Net::WebSocket::FRAME_OP_BITMASK) != Poco::Net::WebSocket::FRAME_OP_CLOSE); // respond close frame - socket.shutdown(); + socket->shutdown(); // no more messages is received. - bytes = socket.receiveFrame(buffer, sizeof(buffer), flags); + bytes = socket->receiveFrame(buffer, sizeof(buffer), flags); CPPUNIT_ASSERT_MESSAGE("Expected no more data", bytes <= 2); // The 2-byte marker is ok. CPPUNIT_ASSERT_EQUAL(0x88, flags); } diff --git a/loolwsd/test/httpwserror.cpp b/loolwsd/test/httpwserror.cpp index 1d686e4..0bd8b65 100644 --- a/loolwsd/test/httpwserror.cpp +++ b/loolwsd/test/httpwserror.cpp @@ -17,13 +17,13 @@ #include <Poco/Net/HTTPResponse.h> #include <Poco/Net/HTTPSClientSession.h> #include <Poco/Net/NetException.h> -#include <Poco/Net/WebSocket.h> #include <Poco/URI.h> #include <cppunit/extensions/HelperMacros.h> #include "Common.hpp" #include "LOOLProtocol.hpp" +#include <LOOLWebSocket.hpp> #include "helpers.hpp" #include "countloolkits.hpp" @@ -101,7 +101,7 @@ void HTTPWSError::testMaxDocuments() try { // Load a document. - std::vector<std::shared_ptr<Poco::Net::WebSocket>> docs; + std::vector<std::shared_ptr<LOOLWebSocket>> docs; std::cerr << "Loading max number of documents: " << MAX_DOCUMENTS << std::endl; for (int it = 1; it <= MAX_DOCUMENTS; ++it) @@ -118,7 +118,7 @@ void HTTPWSError::testMaxDocuments() getDocumentPathAndURL("empty.odt", docPath, docURL); Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, docURL); std::unique_ptr<Poco::Net::HTTPClientSession> session(helpers::createSession(_uri)); - Poco::Net::WebSocket socket(*session, request, _response); + LOOLWebSocket socket(*session, request, _response); // send loolclient, load and partpagerectangles sendTextFrame(socket, "loolclient ", testname); @@ -157,11 +157,11 @@ void HTTPWSError::testMaxConnections() auto socket = loadDocAndGetSocket(_uri, docURL, testname); std::cerr << "Opened connect #1 of " << MAX_CONNECTIONS << std::endl; - std::vector<std::shared_ptr<Poco::Net::WebSocket>> views; + std::vector<std::shared_ptr<LOOLWebSocket>> views; for(int it = 1; it < MAX_CONNECTIONS; it++) { std::unique_ptr<Poco::Net::HTTPClientSession> session(createSession(_uri)); - auto ws = std::make_shared<Poco::Net::WebSocket>(*session, request, _response); + auto ws = std::make_shared<LOOLWebSocket>(*session, request, _response); views.emplace_back(ws); std::cerr << "Opened connect #" << (it+1) << " of " << MAX_CONNECTIONS << std::endl; } @@ -170,7 +170,7 @@ void HTTPWSError::testMaxConnections() // try to connect MAX_CONNECTIONS + 1 std::unique_ptr<Poco::Net::HTTPClientSession> session(createSession(_uri)); - Poco::Net::WebSocket socketN(*session, request, _response); + LOOLWebSocket socketN(*session, request, _response); // send loolclient, load and partpagerectangles sendTextFrame(socketN, "loolclient ", testname); diff --git a/loolwsd/test/httpwstest.cpp b/loolwsd/test/httpwstest.cpp index bbb4d61..93a024b 100644 --- a/loolwsd/test/httpwstest.cpp +++ b/loolwsd/test/httpwstest.cpp @@ -30,7 +30,6 @@ #include <Poco/Net/PrivateKeyPassphraseHandler.h> #include <Poco/Net/SSLManager.h> #include <Poco/Net/Socket.h> -#include <Poco/Net/WebSocket.h> #include <Poco/Path.h> #include <Poco/RegularExpression.h> #include <Poco/StreamCopier.h> @@ -42,6 +41,7 @@ #include "Common.hpp" #include "LOOLProtocol.hpp" +#include <LOOLWebSocket.hpp> #include "Png.hpp" #include "UserMessages.hpp" #include "Util.hpp" @@ -154,7 +154,7 @@ class HTTPWSTest : public CPPUNIT_NS::TestFixture int& cursorWidth, int& cursorHeight); - void limitCursor(std::function<void(const std::shared_ptr<Poco::Net::WebSocket>& socket, + void limitCursor(std::function<void(const std::shared_ptr<LOOLWebSocket>& socket, int cursorX, int cursorY, int cursorWidth, int cursorHeight, int docWidth, int docHeight)> keyhandler, @@ -165,7 +165,7 @@ class HTTPWSTest : public CPPUNIT_NS::TestFixture std::string getFontList(const std::string& message); void testStateChanged(const std::string& filename, std::vector<std::string>& vecComands); double getColRowSize(const std::string& property, const std::string& message, int index); - double getColRowSize(const std::shared_ptr<Poco::Net::WebSocket>& socket, const std::string& item, int index); + double getColRowSize(const std::shared_ptr<LOOLWebSocket>& socket, const std::string& item, int index); void testEachView(const std::string& doc, const std::string& type, const std::string& protocol, const std::string& view, const std::string& testname); public: @@ -249,7 +249,7 @@ void HTTPWSTest::testHandShake() Poco::Net::HTTPResponse response; Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, documentURL); std::unique_ptr<Poco::Net::HTTPClientSession> session(helpers::createSession(_uri)); - Poco::Net::WebSocket socket(*session, request, response); + LOOLWebSocket socket(*session, request, response); socket.setReceiveTimeout(0); int flags = 0; @@ -298,13 +298,13 @@ void HTTPWSTest::testCloseAfterClose() const auto testname = "closeAfterClose "; try { - auto socket = *loadDocAndGetSocket("hello.odt", _uri, testname); + auto socket = loadDocAndGetSocket("hello.odt", _uri, testname); // send normal socket shutdown - socket.shutdown(); + socket->shutdown(); // 5 seconds timeout - socket.setReceiveTimeout(5000000); + socket->setReceiveTimeout(5000000); // receive close frame handshake int bytes; @@ -312,12 +312,12 @@ void HTTPWSTest::testCloseAfterClose() char buffer[READ_BUFFER_SIZE]; do { - bytes = socket.receiveFrame(buffer, sizeof(buffer), flags); + bytes = socket->receiveFrame(buffer, sizeof(buffer), flags); } while (bytes && (flags & Poco::Net::WebSocket::FRAME_OP_BITMASK) != Poco::Net::WebSocket::FRAME_OP_CLOSE); // no more messages is received. - bytes = socket.receiveFrame(buffer, sizeof(buffer), flags); + bytes = socket->receiveFrame(buffer, sizeof(buffer), flags); std::cout << "Received " << bytes << " bytes, flags: "<< std::hex << flags << std::dec << std::endl; CPPUNIT_ASSERT_EQUAL(0, bytes); CPPUNIT_ASSERT_EQUAL(0, flags); @@ -387,7 +387,7 @@ void HTTPWSTest::testBadLoad() getDocumentPathAndURL("hello.odt", documentPath, documentURL); Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, documentURL); - Poco::Net::WebSocket socket = *connectLOKit(_uri, request, _response); + auto socket = connectLOKit(_uri, request, _response); // Before loading request status. sendTextFrame(socket, "status"); @@ -419,8 +419,8 @@ void HTTPWSTest::testGetTextSelection() std::string documentPath, documentURL; getDocumentPathAndURL("hello.odt", documentPath, documentURL); - auto socket = *loadDocAndGetSocket(_uri, documentURL, testname); - auto socket2 = *loadDocAndGetSocket(_uri, documentURL, testname); + auto socket = loadDocAndGetSocket(_uri, documentURL, testname); + auto socket2 = loadDocAndGetSocket(_uri, documentURL, testname); sendTextFrame(socket, "uno .uno:SelectAll", testname); sendTextFrame(socket, "gettextselection mimetype=text/plain;charset=utf-8", testname); @@ -446,9 +446,9 @@ void HTTPWSTest::testSaveOnDisconnect() int kitcount = -1; try { - auto socket = *loadDocAndGetSocket(_uri, documentURL, testname); + auto socket = loadDocAndGetSocket(_uri, documentURL, testname); - auto socket2 = *loadDocAndGetSocket(_uri, documentURL, testname); + auto socket2 = loadDocAndGetSocket(_uri, documentURL, testname); sendTextFrame(socket2, "userinactive"); sendTextFrame(socket, "uno .uno:SelectAll", testname); @@ -470,8 +470,8 @@ void HTTPWSTest::testSaveOnDisconnect() // Shutdown abruptly. std::cerr << "Closing connection after pasting." << std::endl; - socket.shutdown(); - socket2.shutdown(); + socket->shutdown(); + socket2->shutdown(); } catch (const Poco::Exception& exc) { @@ -484,7 +484,7 @@ void HTTPWSTest::testSaveOnDisconnect() try { // Load the same document and check that the last changes (pasted text) is saved. - auto socket = *loadDocAndGetSocket(_uri, documentURL, testname); + auto socket = loadDocAndGetSocket(_uri, documentURL, testname); // Should have no new instances. CPPUNIT_ASSERT_EQUAL(kitcount, countLoolKitProcesses(kitcount)); @@ -509,7 +509,7 @@ void HTTPWSTest::testReloadWhileDisconnecting() std::string documentPath, documentURL; getDocumentPathAndURL("hello.odt", documentPath, documentURL); - auto socket = *loadDocAndGetSocket(_uri, documentURL, testname); + auto socket = loadDocAndGetSocket(_uri, documentURL, testname); sendTextFrame(socket, "uno .uno:SelectAll", testname); sendTextFrame(socket, "uno .uno:Delete", testname); @@ -524,11 +524,11 @@ void HTTPWSTest::testReloadWhileDisconnecting() // Shutdown abruptly. std::cerr << "Closing connection after pasting." << std::endl; - socket.shutdown(); + socket->shutdown(); // Load the same document and check that the last changes (pasted text) is saved. std::cout << "Loading again." << std::endl; - socket = *loadDocAndGetSocket(_uri, documentURL, testname); + socket = loadDocAndGetSocket(_uri, documentURL, testname); // Should have no new instances. CPPUNIT_ASSERT_EQUAL(kitcount, countLoolKitProcesses(kitcount)); @@ -639,7 +639,7 @@ void HTTPWSTest::testRenderingOptions() const std::string options = "{\"rendering\":{\".uno:HideWhitespace\":{\"type\":\"boolean\",\"value\":\"true\"}}}"; Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, documentURL); - Poco::Net::WebSocket socket = *connectLOKit(_uri, request, _response); + auto socket = connectLOKit(_uri, request, _response); sendTextFrame(socket, "load url=" + documentURL + " options=" + options); sendTextFrame(socket, "status"); @@ -671,7 +671,7 @@ void HTTPWSTest::testPasswordProtectedDocumentWithoutPassword() getDocumentPathAndURL("password-protected.ods", documentPath, documentURL); Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, documentURL); - Poco::Net::WebSocket socket = *connectLOKit(_uri, request, _response); + auto socket = connectLOKit(_uri, request, _response); // Send a load request without password first sendTextFrame(socket, "load url=" + documentURL); @@ -702,7 +702,7 @@ void HTTPWSTest::testPasswordProtectedDocumentWithWrongPassword() getDocumentPathAndURL("password-protected.ods", documentPath, documentURL); Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, documentURL); - Poco::Net::WebSocket socket = *connectLOKit(_uri, request, _response); + auto socket = connectLOKit(_uri, request, _response); // Send a load request with incorrect password sendTextFrame(socket, "load url=" + documentURL + " password=2"); @@ -732,7 +732,7 @@ void HTTPWSTest::testPasswordProtectedDocumentWithCorrectPassword() getDocumentPathAndURL("password-protected.ods", documentPath, documentURL); Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, documentURL); - Poco::Net::WebSocket socket = *connectLOKit(_uri, request, _response); + auto socket = connectLOKit(_uri, request, _response); // Send a load request with correct password sendTextFrame(socket, "load url=" + documentURL + " password=1"); @@ -762,7 +762,7 @@ void HTTPWSTest::testInsertDelete() getDocumentPathAndURL("insert-delete.odp", documentPath, documentURL); Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, documentURL); - Poco::Net::WebSocket socket = *connectLOKit(_uri, request, _response); + auto socket = connectLOKit(_uri, request, _response); sendTextFrame(socket, "load url=" + documentURL); CPPUNIT_ASSERT_MESSAGE("cannot load the document " + documentURL, isDocumentLoaded(socket)); @@ -857,7 +857,7 @@ void HTTPWSTest::testSlideShow() getDocumentPathAndURL("setclientpart.odp", documentPath, documentURL); Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, documentURL); - Poco::Net::WebSocket socket = *connectLOKit(_uri, request, _response); + auto socket = connectLOKit(_uri, request, _response); sendTextFrame(socket, "load url=" + documentURL, testname); CPPUNIT_ASSERT_MESSAGE("cannot load the document " + documentURL, isDocumentLoaded(socket)); @@ -957,7 +957,7 @@ void HTTPWSTest::testMaxColumn() { limitCursor( // move cursor to last column - [](const std::shared_ptr<Poco::Net::WebSocket>& socket, + [](const std::shared_ptr<LOOLWebSocket>& socket, int cursorX, int cursorY, int cursorWidth, int cursorHeight, int docWidth, int docHeight) { @@ -996,7 +996,7 @@ void HTTPWSTest::testMaxRow() { limitCursor( // move cursor to last row - [](const std::shared_ptr<Poco::Net::WebSocket>& socket, + [](const std::shared_ptr<LOOLWebSocket>& socket, int cursorX, int cursorY, int cursorWidth, int cursorHeight, int docWidth, int docHeight) { @@ -1100,7 +1100,7 @@ void HTTPWSTest::getCursor(const std::string& message, CPPUNIT_ASSERT(cursorHeight >= 0); } -void HTTPWSTest::limitCursor(std::function<void(const std::shared_ptr<Poco::Net::WebSocket>& socket, +void HTTPWSTest::limitCursor(std::function<void(const std::shared_ptr<LOOLWebSocket>& socket, int cursorX, int cursorY, int cursorWidth, int cursorHeight, int docWidth, int docHeight)> keyhandler, @@ -1421,7 +1421,7 @@ void HTTPWSTest::testFontList() try { // Load a document - auto socket = *loadDocAndGetSocket("setclientpart.odp", _uri, testname); + auto socket = loadDocAndGetSocket("setclientpart.odp", _uri, testname); sendTextFrame(socket, "commandvalues command=.uno:CharFontName", testname); const auto response = getResponseMessage(socket, "commandvalues:", testname); @@ -1664,7 +1664,7 @@ double HTTPWSTest::getColRowSize(const std::string& property, const std::string& return item->getValue<double>("size"); } -double HTTPWSTest::getColRowSize(const std::shared_ptr<Poco::Net::WebSocket>& socket, const std::string& item, int index) +double HTTPWSTest::getColRowSize(const std::shared_ptr<LOOLWebSocket>& socket, const std::string& item, int index) { std::vector<char> response; response = getResponseMessage(socket, "commandvalues:", "testColumnRowResize "); @@ -1879,7 +1879,7 @@ void HTTPWSTest::testEachView(const std::string& doc, const std::string& type, getDocumentPathAndURL(doc, documentPath, documentURL); int itView = 0; - auto socket = *loadDocAndGetSocket(_uri, documentURL, Poco::format(view, itView)); + auto socket = loadDocAndGetSocket(_uri, documentURL, Poco::format(view, itView)); // Check document size sendTextFrame(socket, "status", Poco::format(view, itView)); @@ -1904,7 +1904,7 @@ void HTTPWSTest::testEachView(const std::string& doc, const std::string& type, CPPUNIT_ASSERT_MESSAGE(Poco::format(error, itView, protocol), !response.empty()); // Connect and load 0..N Views, where N<=limit - std::vector<std::shared_ptr<Poco::Net::WebSocket>> views; + std::vector<std::shared_ptr<LOOLWebSocket>> views; #if MAX_DOCUMENTS > 0 const auto limit = std::min(5, MAX_DOCUMENTS - 1); // +1 connection above #else @@ -1960,7 +1960,7 @@ void HTTPWSTest::testGraphicInvalidate() try { // Load a document. - auto socket = *loadDocAndGetSocket("shape.ods", _uri, testname); + auto socket = loadDocAndGetSocket("shape.ods", _uri, testname); // Send click message sendTextFrame(socket, "mouse type=buttondown x=1035 y=400 count=1 buttons=1 modifier=0", testname); @@ -1993,7 +1993,7 @@ void HTTPWSTest::testCursorPosition() std::string response; getDocumentPathAndURL("Example.odt", docPath, docURL); - auto socket0 = *loadDocAndGetSocket(_uri, docURL, testname); + auto socket0 = loadDocAndGetSocket(_uri, docURL, testname); // receive cursor position response = getResponseString(socket0, "invalidatecursor:", testname); @@ -2001,7 +2001,7 @@ void HTTPWSTest::testCursorPosition() CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(4), cursorTokens.count()); // Create second view - auto socket1 = *loadDocAndGetSocket(_uri, docURL, testname); + auto socket1 = loadDocAndGetSocket(_uri, docURL, testname); //receive view cursor position response = getResponseString(socket1, "invalidateviewcursor:", testname); @@ -2044,7 +2044,7 @@ void HTTPWSTest::testAlertAllUsers() for (int i = 0; i < 2; i++) request[i] = new Poco::Net::HTTPRequest(Poco::Net::HTTPRequest::HTTP_GET, docURL[i]); - std::shared_ptr<Poco::Net::WebSocket> socket[4]; + std::shared_ptr<LOOLWebSocket> socket[4]; for (int i = 0; i < 4; i++) { socket[i] = connectLOKit(_uri, *(request[i/2]), _response); @@ -2082,8 +2082,8 @@ void HTTPWSTest::testViewInfoMsg() getDocumentPathAndURL("hello.odt", docPath, docURL); Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, docURL); - Poco::Net::WebSocket socket0 = *connectLOKit(_uri, request, _response); - Poco::Net::WebSocket socket1 = *connectLOKit(_uri, request, _response); + auto socket0 = connectLOKit(_uri, request, _response); + auto socket1 = connectLOKit(_uri, request, _response); std::string response; int part, parts, width, height; _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits