[Libreoffice-commits] online.git: 2 commits - loleaflet/js net/WebSocketHandler.hpp tools/WebSocketDump.cpp wsd/Admin.cpp wsd/ClientSession.cpp wsd/LOOLWSD.cpp wsd/TileCache.cpp
Michael Meeks (via logerrit)
logerrit at kemper.freedesktop.org
Fri Apr 24 13:39:36 UTC 2020
loleaflet/js/global.js | 27 ++++++++++++
net/WebSocketHandler.hpp | 19 ++++----
tools/WebSocketDump.cpp | 6 ++
wsd/Admin.cpp | 5 ++
wsd/ClientSession.cpp | 4 +
wsd/LOOLWSD.cpp | 100 +++++++++++++++++++++++++++++------------------
wsd/TileCache.cpp | 4 +
7 files changed, 116 insertions(+), 49 deletions(-)
New commits:
commit 5b9f0927488243b6af8a6d9e0f88c1dcc100b41e
Author: Michael Meeks <michael.meeks at collabora.com>
AuthorDate: Fri Mar 20 19:05:48 2020 +0000
Commit: Jan Holesovsky <kendy at collabora.com>
CommitDate: Fri Apr 24 15:39:25 2020 +0200
Proxy: re-write css image URLs to handle the proxy.
Change-Id: I09f3dea2f5e3a51869d5b0aa3f473d8f3ba75f44
Reviewed-on: https://gerrit.libreoffice.org/c/online/+/92808
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
Reviewed-by: Jan Holesovsky <kendy at collabora.com>
diff --git a/loleaflet/js/global.js b/loleaflet/js/global.js
index f5c038b91..023a8bf7c 100644
--- a/loleaflet/js/global.js
+++ b/loleaflet/js/global.js
@@ -335,6 +335,33 @@
}, 250);
};
+ if (global.socketProxy)
+ {
+ // re-write relative URLs in CSS - somewhat grim.
+ window.addEventListener('load', function() {
+ var sheets = document.styleSheets;
+ for (var i = 0; i < sheets.length; ++i) {
+ var relBases = sheets[i].href.split('/');
+ relBases.pop(); // bin last - css name.
+ var replaceBase = 'url("' + relBases.join('/') + '/images/';
+
+ var rules = sheets[i].cssRules || sheets[i].rules;
+ for (var r = 0; r < rules.length; ++r) {
+ if (!rules[r] || !rules[r].style)
+ continue;
+ var img = rules[r].style.backgroundImage;
+ if (img === '' || img === undefined)
+ continue;
+ if (img.startsWith('url("images/'))
+ {
+ rules[r].style.backgroundImage =
+ img.replace('url("images/', replaceBase);
+ }
+ }
+ }
+ }, false);
+ }
+
global.createWebSocket = function(uri) {
if (global.socketProxy) {
return new global.ProxySocket(uri);
commit df6d942d08dfb5e8fffed015edf4c0eb5ce6f65e
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
AuthorDate: Sun Apr 19 14:46:01 2020 -0400
Commit: Ashod Nakashian <ashnakash at gmail.com>
CommitDate: Fri Apr 24 15:39:17 2020 +0200
wsd: harden socket weakptr
Weak pointers can be null and must be
checked before using. This fixes at least
one segfault and prevents a number of others.
Also, minimizes locking of weak pointers
in the message handlers.
Change-Id: I306501c26c3441d7bd6812d51fa17e7356126f32
Reviewed-on: https://gerrit.libreoffice.org/c/online/+/92828
Reviewed-by: Michael Meeks <michael.meeks at collabora.com>
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
diff --git a/net/WebSocketHandler.hpp b/net/WebSocketHandler.hpp
index 46a2916a7..a329e7711 100644
--- a/net/WebSocketHandler.hpp
+++ b/net/WebSocketHandler.hpp
@@ -122,7 +122,7 @@ public:
void sendCloseFrame(const StatusCodes statusCode = StatusCodes::NORMAL_CLOSE, const std::string& statusMessage = "")
{
std::shared_ptr<StreamSocket> socket = _socket.lock();
- if (socket == nullptr)
+ if (!socket)
{
LOG_ERR("No socket associated with WebSocketHandler " << this);
return;
@@ -404,23 +404,21 @@ public:
/// Implementation of the ProtocolHandlerInterface.
virtual void handleIncomingMessage(SocketDisposition&) override
{
- // LOG_TRC("***** WebSocketHandler::handleIncomingMessage()");
-
std::shared_ptr<StreamSocket> socket = _socket.lock();
#if MOBILEAPP
// No separate "upgrade" is going on
- if (socket != nullptr && !socket->isWebSocket())
+ if (socket && !socket->isWebSocket())
socket->setWebSocket();
#endif
- if (socket == nullptr)
+ if (!socket)
{
LOG_ERR("No socket associated with WebSocketHandler " << this);
}
#if !MOBILEAPP
else if (_isClient && !socket->isWebSocket())
- handleClientUpgrade();
+ handleClientUpgrade(socket);
#endif
else
{
@@ -694,7 +692,7 @@ protected:
void upgradeToWebSocket(const Poco::Net::HTTPRequest& req)
{
std::shared_ptr<StreamSocket> socket = _socket.lock();
- if (socket == nullptr)
+ if (!socket)
throw std::runtime_error("Invalid socket while upgrading to WebSocket. Request: " + req.getURI());
LOG_TRC("#" << socket->getFD() << ": Upgrading to WebSocket.");
@@ -730,9 +728,9 @@ protected:
#if !MOBILEAPP
// Handle incoming upgrade to full socket as client WS.
- void handleClientUpgrade()
+ void handleClientUpgrade(const std::shared_ptr<StreamSocket>& socket)
{
- std::shared_ptr<StreamSocket> socket = _socket.lock();
+ assert(socket && "socket must be valid");
LOG_TRC("Incoming client websocket upgrade response: "
<< std::string(&socket->getInBuffer()[0], socket->getInBuffer().size()));
@@ -800,7 +798,8 @@ protected:
void setWebSocket()
{
std::shared_ptr<StreamSocket> socket = _socket.lock();
- socket->setWebSocket();
+ if (socket)
+ socket->setWebSocket();
// No need to ping right upon connection/upgrade,
// but do reset the time to avoid pinging immediately after.
diff --git a/tools/WebSocketDump.cpp b/tools/WebSocketDump.cpp
index 81e034a67..711cbaca9 100644
--- a/tools/WebSocketDump.cpp
+++ b/tools/WebSocketDump.cpp
@@ -70,6 +70,12 @@ private:
void handleIncomingMessage(SocketDisposition &disposition) override
{
std::shared_ptr<StreamSocket> socket = _socket.lock();
+ if (!socket)
+ {
+ LOG_ERR("Invalid socket while reading client message.");
+ return;
+ }
+
std::vector<char>& in = socket->getInBuffer();
LOG_TRC("#" << socket->getFD() << " handling incoming " << in.size() << " bytes.");
diff --git a/wsd/Admin.cpp b/wsd/Admin.cpp
index ca84c5c6c..8f98cce64 100644
--- a/wsd/Admin.cpp
+++ b/wsd/Admin.cpp
@@ -330,6 +330,11 @@ bool AdminSocketHandler::handleInitialRequest(
}
std::shared_ptr<StreamSocket> socket = socketWeak.lock();
+ if (!socket)
+ {
+ LOG_ERR("Invalid socket while reading initial request.");
+ return false;
+ }
const std::string& requestURI = request.getURI();
StringVector pathTokens(LOOLProtocol::tokenize(requestURI, '/'));
diff --git a/wsd/ClientSession.cpp b/wsd/ClientSession.cpp
index c9dc7827a..a73749352 100644
--- a/wsd/ClientSession.cpp
+++ b/wsd/ClientSession.cpp
@@ -1358,12 +1358,16 @@ bool ClientSession::handleKitToClientMessage(const char* buffer, const int lengt
<< "X-Content-Type-Options: nosniff\r\n"
<< "\r\n";
auto socket = it.lock();
+ if (!socket)
+ continue;
+
if (!empty)
{
oss.write(&payload->data()[header], payload->size() - header);
socket->setSocketBufferSize(std::min(payload->size() + 256,
size_t(Socket::MaximumSendBufferSize)));
}
+
socket->send(oss.str());
socket->shutdown();
LOG_INF("Queued " << (empty?"empty":"clipboard") << " response for send.");
diff --git a/wsd/LOOLWSD.cpp b/wsd/LOOLWSD.cpp
index c58430509..7607facef 100644
--- a/wsd/LOOLWSD.cpp
+++ b/wsd/LOOLWSD.cpp
@@ -1937,7 +1937,6 @@ private:
/// Called after successful socket reads.
void handleIncomingMessage(SocketDisposition &disposition) override
{
- // LOG_TRC("***** PrisonerRequestDispatcher::handleIncomingMessage()");
if (_childProcess.lock())
{
// FIXME: inelegant etc. - derogate to websocket code
@@ -1946,6 +1945,11 @@ private:
}
std::shared_ptr<StreamSocket> socket = getSocket().lock();
+ if (!socket)
+ {
+ LOG_ERR("Invalid socket while reading incoming message.");
+ return;
+ }
Poco::MemoryInputStream message(&socket->getInBuffer()[0],
socket->getInBuffer().size());;
@@ -2194,6 +2198,11 @@ private:
void handleIncomingMessage(SocketDisposition &disposition) override
{
std::shared_ptr<StreamSocket> socket = _socket.lock();
+ if (!socket)
+ {
+ LOG_ERR("Invalid socket while handling incoming client request");
+ return;
+ }
#if !MOBILEAPP
if (!LOOLWSD::isSSLEnabled() && socket->sniffSSL())
@@ -2247,7 +2256,7 @@ private:
else if (reqPathSegs.size() >= 1 && reqPathSegs[0] == "loleaflet")
{
// File server
- handleFileServerRequest(request, message);
+ handleFileServerRequest(request, message, socket);
}
else if (reqPathSegs.size() >= 2 && reqPathSegs[0] == "lool" && reqPathSegs[1] == "adminws")
{
@@ -2308,23 +2317,23 @@ private:
request.getMethod() == HTTPRequest::HTTP_HEAD) &&
request.getURI() == "/")
{
- handleRootRequest(request);
+ handleRootRequest(request, socket);
}
else if (request.getMethod() == HTTPRequest::HTTP_GET && request.getURI() == "/favicon.ico")
{
- handleFaviconRequest(request);
+ handleFaviconRequest(request, socket);
}
else if (request.getMethod() == HTTPRequest::HTTP_GET && (request.getURI() == "/hosting/discovery" || request.getURI() == "/hosting/discovery/"))
{
- handleWopiDiscoveryRequest(request);
+ handleWopiDiscoveryRequest(request, socket);
}
else if (request.getMethod() == HTTPRequest::HTTP_GET && request.getURI() == CAPABILITIES_END_POINT)
{
- handleCapabilitiesRequest(request);
+ handleCapabilitiesRequest(request, socket);
}
else if (request.getMethod() == HTTPRequest::HTTP_GET && request.getURI() == "/robots.txt")
{
- handleRobotsTxtRequest(request);
+ handleRobotsTxtRequest(request, socket);
}
else
{
@@ -2332,7 +2341,7 @@ private:
if (reqPathTokens.count() > 1 && reqPathTokens[0] == "lool" && reqPathTokens[1] == "clipboard")
{
// Util::dumpHex(std::cerr, "clipboard:\n", "", socket->getInBuffer()); // lots of data ...
- handleClipboardRequest(request, message, disposition);
+ handleClipboardRequest(request, message, disposition, socket);
}
else if (request.has("ProxyPrefix") && reqPathTokens.count() > 2 &&
(reqPathTokens[reqPathTokens.count()-2] == "ws"))
@@ -2345,14 +2354,14 @@ private:
reqPathTokens.count() > 0 && reqPathTokens[0] == "lool")
{
// All post requests have url prefix 'lool'.
- handlePostRequest(request, message, disposition);
+ handlePostRequest(request, message, disposition, socket);
}
else if (reqPathTokens.count() > 2 && reqPathTokens[0] == "lool" && reqPathTokens[2] == "ws" &&
request.find("Upgrade") != request.end() && Poco::icompare(request["Upgrade"], "websocket") == 0)
{
std::string decodedUri; // WOPISrc
Poco::URI::decode(reqPathTokens[1], decodedUri);
- handleClientWsUpgrade(request, decodedUri, disposition);
+ handleClientWsUpgrade(request, decodedUri, disposition, socket);
}
else
{
@@ -2396,7 +2405,9 @@ private:
Poco::Net::HTTPRequest request;
// The 2nd parameter is the response to the HULLO message (which we
// respond with the path of the document)
- handleClientWsUpgrade(request, std::string(socket->getInBuffer().data(), socket->getInBuffer().size()), disposition);
+ handleClientWsUpgrade(
+ request, std::string(socket->getInBuffer().data(), socket->getInBuffer().size()),
+ disposition, socket);
socket->getInBuffer().clear();
#endif
}
@@ -2412,15 +2423,20 @@ private:
}
#if !MOBILEAPP
- void handleFileServerRequest(const Poco::Net::HTTPRequest& request, Poco::MemoryInputStream& message)
+ void handleFileServerRequest(const Poco::Net::HTTPRequest& request,
+ Poco::MemoryInputStream& message,
+ const std::shared_ptr<StreamSocket>& socket)
{
- std::shared_ptr<StreamSocket> socket = _socket.lock();
+ assert(socket && "Must have a valid socket");
FileServerRequestHandler::handleRequest(request, message, socket);
socket->shutdown();
}
- void handleRootRequest(const Poco::Net::HTTPRequest& request)
+ void handleRootRequest(const Poco::Net::HTTPRequest& request,
+ const std::shared_ptr<StreamSocket>& socket)
{
+ assert(socket && "Must have a valid socket");
+
LOG_DBG("HTTP request: " << request.getURI());
const std::string mimeType = "text/plain";
const std::string responseString = "OK";
@@ -2438,14 +2454,16 @@ private:
oss << responseString;
}
- std::shared_ptr<StreamSocket> socket = _socket.lock();
socket->send(oss.str());
socket->shutdown();
LOG_INF("Sent / response successfully.");
}
- void handleFaviconRequest(const Poco::Net::HTTPRequest& request)
+ void handleFaviconRequest(const Poco::Net::HTTPRequest& request,
+ const std::shared_ptr<StreamSocket>& socket)
{
+ assert(socket && "Must have a valid socket");
+
LOG_DBG("Favicon request: " << request.getURI());
std::string mimeType = "image/vnd.microsoft.icon";
std::string faviconPath = Path(Application::instance().commandPath()).parent().toString() + "favicon.ico";
@@ -2454,14 +2472,16 @@ private:
faviconPath = LOOLWSD::FileServerRoot + "/favicon.ico";
}
- std::shared_ptr<StreamSocket> socket = _socket.lock();
Poco::Net::HTTPResponse response;
HttpHelper::sendFile(socket, faviconPath, mimeType, response);
socket->shutdown();
}
- void handleWopiDiscoveryRequest(const Poco::Net::HTTPRequest& request)
+ void handleWopiDiscoveryRequest(const Poco::Net::HTTPRequest& request,
+ const std::shared_ptr<StreamSocket>& socket)
{
+ assert(socket && "Must have a valid socket");
+
LOG_DBG("Wopi discovery request: " << request.getURI());
std::string xml = getFileContent("discovery.xml");
@@ -2479,17 +2499,19 @@ private:
"\r\n"
<< xml;
- std::shared_ptr<StreamSocket> socket = _socket.lock();
socket->send(oss.str());
socket->shutdown();
LOG_INF("Sent discovery.xml successfully.");
}
- void handleCapabilitiesRequest(const Poco::Net::HTTPRequest& request)
+ void handleCapabilitiesRequest(const Poco::Net::HTTPRequest& request,
+ const std::shared_ptr<StreamSocket>& socket)
{
+ assert(socket && "Must have a valid socket");
+
LOG_DBG("Wopi capabilities request: " << request.getURI());
- std::string capabilities = getCapabilitiesJson(request);
+ const std::string capabilities = getCapabilitiesJson(request, socket);
std::ostringstream oss;
oss << "HTTP/1.1 200 OK\r\n"
@@ -2501,7 +2523,6 @@ private:
"\r\n"
<< capabilities;
- auto socket = _socket.lock();
socket->send(oss.str());
socket->shutdown();
LOG_INF("Sent capabilities.json successfully.");
@@ -2509,8 +2530,11 @@ private:
void handleClipboardRequest(const Poco::Net::HTTPRequest& request,
Poco::MemoryInputStream& message,
- SocketDisposition &disposition)
+ SocketDisposition &disposition,
+ const std::shared_ptr<StreamSocket>& socket)
{
+ assert(socket && "Must have a valid socket");
+
LOG_DBG("Clipboard " << ((request.getMethod() == HTTPRequest::HTTP_GET) ? "GET" : "POST") <<
" request: " << request.getURI());
@@ -2579,7 +2603,7 @@ private:
LOG_TRC("queued clipboard command " << type << " on docBroker fetch");
}
// fallback to persistent clipboards if we can
- else if (!DocumentBroker::lookupSendClipboardTag(_socket.lock(), tag, false))
+ else if (!DocumentBroker::lookupSendClipboardTag(socket, tag, false))
{
LOG_ERR("Invalid clipboard request: " << serverId << " with tag " << tag <<
" and broker: " << (docBroker ? "" : "not ") << "found");
@@ -2598,14 +2622,16 @@ private:
<< "Content-Length: 0\r\n"
<< "\r\n"
<< errMsg;
- auto socket = _socket.lock();
socket->send(oss.str());
socket->shutdown();
}
}
- void handleRobotsTxtRequest(const Poco::Net::HTTPRequest& request)
+ void handleRobotsTxtRequest(const Poco::Net::HTTPRequest& request,
+ const std::shared_ptr<StreamSocket>& socket)
{
+ assert(socket && "Must have a valid socket");
+
LOG_DBG("HTTP request: " << request.getURI());
const std::string mimeType = "text/plain";
const std::string responseString = "User-agent: *\nDisallow: /\n";
@@ -2623,7 +2649,6 @@ private:
oss << responseString;
}
- std::shared_ptr<StreamSocket> socket = _socket.lock();
socket->send(oss.str());
socket->shutdown();
LOG_INF("Sent robots.txt response successfully.");
@@ -2669,12 +2694,14 @@ private:
void handlePostRequest(const Poco::Net::HTTPRequest& request,
Poco::MemoryInputStream& message,
- SocketDisposition &disposition)
+ SocketDisposition& disposition,
+ const std::shared_ptr<StreamSocket>& socket)
{
+ assert(socket && "Must have a valid socket");
+
LOG_INF("Post request: [" << LOOLWSD::anonymizeUrl(request.getURI()) << "]");
Poco::Net::HTTPResponse response;
- std::shared_ptr<StreamSocket> socket = _socket.lock();
StringTokenizer tokens(request.getURI(), "/?");
if (tokens.count() > 2 && tokens[2] == "convert-to")
@@ -2968,14 +2995,10 @@ private:
}
void handleClientWsUpgrade(const Poco::Net::HTTPRequest& request, const std::string& url,
- SocketDisposition &disposition)
+ SocketDisposition& disposition,
+ const std::shared_ptr<StreamSocket>& socket)
{
- std::shared_ptr<StreamSocket> socket = _socket.lock();
- if (!socket)
- {
- LOG_WRN("No socket to handle client WS upgrade for request: " << LOOLWSD::anonymizeUrl(request.getURI()) << ", url: " << url);
- return;
- }
+ assert(socket && "Must have a valid socket");
// must be trace for anonymization
LOG_TRC("Client WS request: " << request.getURI() << ", url: " << url << ", socket #" << socket->getFD());
@@ -3197,9 +3220,10 @@ private:
}
/// Create the /hosting/capabilities JSON and return as string.
- std::string getCapabilitiesJson(const Poco::Net::HTTPRequest& request)
+ std::string getCapabilitiesJson(const Poco::Net::HTTPRequest& request,
+ const std::shared_ptr<StreamSocket>& socket)
{
- std::shared_ptr<StreamSocket> socket = _socket.lock();
+ assert(socket && "Must have a valid socket");
// Can the convert-to be used?
Poco::JSON::Object::Ptr convert_to = new Poco::JSON::Object;
diff --git a/wsd/TileCache.cpp b/wsd/TileCache.cpp
index 5ef10804f..15f24b92f 100644
--- a/wsd/TileCache.cpp
+++ b/wsd/TileCache.cpp
@@ -656,7 +656,9 @@ void TileCache::TileBeingRendered::dumpState(std::ostream& os)
for (const auto& it : _subscribers)
{
std::shared_ptr<ClientSession> session = it.lock();
- os << " " << session->getId() << " " << session->getUserId() << " " << session->getName() << "\n";
+ if (session)
+ os << " " << session->getId() << ' ' << session->getUserId() << ' '
+ << session->getName() << '\n';
}
}
More information about the Libreoffice-commits
mailing list