diff --git a/Makefile.am b/Makefile.am index 3ce60690d..bc2aa55ba 100644 --- a/Makefile.am +++ b/Makefile.am @@ -89,7 +89,6 @@ AM_ETAGSFLAGS = --c++-kinds=+p --fields=+iaS --extra=+q -R --totals=yes --exclud AM_CTAGSFLAGS = $(AM_ETAGSFLAGS) shared_sources = common/FileUtil.cpp \ - common/IoUtil.cpp \ common/Log.cpp \ common/Protocol.cpp \ common/StringVector.cpp \ @@ -144,8 +143,7 @@ connect_SOURCES = tools/Connect.cpp \ common/StringVector.cpp \ common/Util.cpp -lokitclient_SOURCES = common/IoUtil.cpp \ - common/Log.cpp \ +lokitclient_SOURCES = common/Log.cpp \ tools/KitClient.cpp \ common/Protocol.cpp \ common/StringVector.cpp \ @@ -231,7 +229,6 @@ shared_headers = common/Common.hpp \ common/Clipboard.hpp \ common/Crypto.hpp \ common/JsonUtil.hpp \ - common/IoUtil.hpp \ common/FileUtil.hpp \ common/Log.hpp \ common/LOOLWebSocket.hpp \ diff --git a/common/IoUtil.cpp b/common/IoUtil.cpp deleted file mode 100644 index f7ea25225..000000000 --- a/common/IoUtil.cpp +++ /dev/null @@ -1,318 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -#include - -#include "IoUtil.hpp" - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "Common.hpp" -#include "Protocol.hpp" -#include "LOOLWebSocket.hpp" -#include "Log.hpp" -#include "Util.hpp" - -using Poco::Net::Socket; -using Poco::Net::WebSocket; - -namespace IoUtil -{ - -// Synchronously process LOOLWebSocket requests and dispatch to handler. -// Handler returns false to end. -void SocketProcessor(const std::shared_ptr& ws, - const std::string& name, - const std::function&)>& handler, - const std::function& closeFrame, - const std::function& stopPredicate) -{ - LOG_INF("SocketProcessor [" << name << "] starting."); - - // Timeout given is in microseconds. - static const Poco::Timespan waitTime(POLL_TIMEOUT_MICRO_S); - int flags = 0; - int n = -1; - bool stop = false; - std::vector payload(READ_BUFFER_SIZE); - payload.resize(0); - try - { - // We poll, no need for timeout. - ws->setReceiveTimeout(0); - - for (;;) - { - stop = stopPredicate(); - if (stop) - { - LOG_INF("SocketProcessor [" << name << "]: Stop flagged."); - break; - } - - if (!ws->poll(waitTime, Poco::Net::Socket::SELECT_READ) || - stopPredicate()) - { - // If SELECT_READ fails, it might mean the socket is in error. - if (ws->poll(Poco::Timespan(0), Poco::Net::Socket::SELECT_ERROR)) - { - LOG_WRN("SocketProcessor [" << name << "]: Socket error."); - closeFrame(); - break; - } - - // Wait some more. - continue; - } - - try - { - payload.resize(payload.capacity()); - n = -1; // In case receiveFrame throws we log dropped data below. - (void)n; - n = ws->receiveFrame(payload.data(), payload.size(), flags); - payload.resize(std::max(n, 0)); - } - catch (const Poco::TimeoutException&) - { - LOG_DBG("SocketProcessor [" << name << "]: Spurious TimeoutException, ignored"); - continue; - } - - if (n == 0 || ((flags & WebSocket::FRAME_OP_BITMASK) == WebSocket::FRAME_OP_CLOSE)) - { - LOG_WRN("SocketProcessor [" << name << "]: Connection closed."); - closeFrame(); - break; - } - else if (n < 0) - { - LOG_DBG("SocketProcessor [" << name << "]: was not an interesting frame, nothing to do here"); - continue; - } - - LOG_CHECK(n > 0); - - if ((flags & WebSocket::FrameFlags::FRAME_FLAG_FIN) != WebSocket::FrameFlags::FRAME_FLAG_FIN) - { - // One WS message split into multiple frames. - // TODO: Is this even possible with Poco if we never construct such messages ourselves? - LOG_WRN("SocketProcessor [" << name << "]: Receiving multi-part frame."); - while (true) - { - char buffer[READ_BUFFER_SIZE]; - n = ws->receiveFrame(buffer, sizeof(buffer), flags); - if (n == 0 || (flags & WebSocket::FRAME_OP_BITMASK) == WebSocket::FRAME_OP_CLOSE) - { - LOG_WRN("SocketProcessor [" << name << "]: Connection closed while reading multiframe message."); - closeFrame(); - break; - } - else if (n < 0) - { - LOG_DBG("SocketProcessor [" << name << "]: was not an interesting frame, nothing to do here"); - continue; - } - - payload.insert(payload.end(), buffer, buffer + n); - if ((flags & WebSocket::FrameFlags::FRAME_FLAG_FIN) == WebSocket::FrameFlags::FRAME_FLAG_FIN) - { - // No more frames. - break; - } - } - } - - LOG_CHECK(n > 0); - - // Call the handler. - const bool success = handler(payload); - payload.resize(0); - - if (!success) - { - LOG_INF("SocketProcessor [" << name << "]: Handler flagged to finish."); - break; - } - - if (payload.capacity() > READ_BUFFER_SIZE * 4) - { - LOG_INF("Compacting buffer of SocketProcessor [" << name << "] from " << - payload.capacity() / 1024 << "KB to " << READ_BUFFER_SIZE / 1024 << "KB."); - payload = std::vector(READ_BUFFER_SIZE); - payload.resize(0); - } - } - } - catch (const std::exception& exc) - { - LOG_ERR("SocketProcessor [" << name << "]: Exception: " << exc.what()); - } - - if ((flags & WebSocket::FRAME_OP_BITMASK) != WebSocket::FRAME_OP_CLOSE && n > 0 && payload.size() > 0) - { - std::string msg; - Poco::URI::encode(std::string(payload.data(), payload.size()), "", msg); - LOG_WRN("SocketProcessor [" << name << "]: Last message (" << payload.size() << - " bytes) will not be processed: [" << msg << "]."); - } - - LOG_INF("SocketProcessor [" << name << "] finished. stop: " << (stop ? "true" : "false") << - ", n: " << n << ", payload size: " << payload.size() << - ", flags: " << std::hex << flags); -} - -ssize_t writeToPipe(int pipe, const char* buffer, ssize_t size) -{ - ssize_t count = 0; - for (;;) - { - LOG_TRC("Writing to pipe. Data: [" << Util::formatLinesForLog(std::string(buffer, size)) << "]."); - const ssize_t bytes = write(pipe, buffer + count, size - count); - if (bytes < 0) - { - if (errno == EINTR || errno == EAGAIN) - { - continue; - } - - LOG_SYS("Failed to write to pipe. Data: [" << std::string(buffer, size) << "]."); - count = -1; - break; - } - else if (count + bytes < size) - { - count += bytes; - } - else - { - count += bytes; - break; - } - } - - return count; -} - -ssize_t readFromPipe(int pipe, char* buffer, ssize_t size) -{ - ssize_t bytes; - do - { - bytes = read(pipe, buffer, size); - } - while (bytes < 0 && errno == EINTR); - - return bytes; -} - -/// 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. -int PipeReader::readLine(std::string& line, - const std::function& stopPredicate) -{ - const char *endOfLine = static_cast(std::memchr(_data.data(), '\n', _data.size())); - if (endOfLine != nullptr) - { - // We have a line cached, return it. - line += std::string(_data.data(), endOfLine); - _data.erase(0, endOfLine - _data.data() + 1); // Including the '\n'. - LOG_TRC("Read existing line from pipe: " << _name << ", line: [" << - line << "], data: [" << Util::formatLinesForLog(_data) << "]."); - return 1; - } - - // Poll in short intervals to check for stop condition. - const int pollTimeoutMs = 500; - int maxPollCount = std::max((POLL_TIMEOUT_MICRO_S / 1000) / pollTimeoutMs, 1); - while (maxPollCount-- > 0) - { - if (stopPredicate()) - { - LOG_INF("Stop requested for pipe: " << _name << '.'); - return -1; - } - - struct pollfd pipe; - pipe.fd = _pipe; - pipe.events = POLLIN; - pipe.revents = 0; - const int ready = poll(&pipe, 1, pollTimeoutMs); - if (ready == 0) - { - // Timeout. - continue; - } - else if (ready < 0) - { - // error. - if (errno != EINTR) - { - LOG_SYS("Pipe polling failed."); - } - - return ready; - } - else if (pipe.revents & (POLLIN | POLLPRI)) - { - char buffer[READ_BUFFER_SIZE]; - const ssize_t bytes = readFromPipe(_pipe, buffer, sizeof(buffer)); - LOG_TRC("readFromPipe for pipe: " << _name << " returned: " << bytes); - if (bytes < 0) - { - return -1; - } - - endOfLine = static_cast(std::memchr(buffer, '\n', bytes)); - if (endOfLine != nullptr) - { - // Got end of line. - line = _data; - const std::string tail(static_cast(buffer), endOfLine); - line += tail; - _data = std::string(endOfLine + 1, bytes - tail.size() - 1); // Exclude the '\n'. - LOG_TRC("Read line from pipe: " << _name << ", line: [" << line << - "], data: [" << Util::formatLinesForLog(_data) << "]."); - return 1; - } - else - { - // More data, keep going. - _data += std::string(buffer, bytes); - LOG_TRC("data appended to pipe: " << _name << ", data: " << _data); - } - } - else if (pipe.revents & (POLLERR | POLLHUP | POLLNVAL)) - { - LOG_FTL("Pipe closed."); - return -1; - } - } - - // Timeout. - return 0; -} - -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/common/IoUtil.hpp b/common/IoUtil.hpp deleted file mode 100644 index 8dc2f326a..000000000 --- a/common/IoUtil.hpp +++ /dev/null @@ -1,64 +0,0 @@ -/* -*- 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_IOUTIL_HPP -#define INCLUDED_IOUTIL_HPP - -#include -#include -#include - -#include - -namespace IoUtil -{ - /// Synchronously process LOOLWebSocket requests and dispatch to handler. - /// Handler returns false to end. - void SocketProcessor(const std::shared_ptr& ws, - const std::string& name, - const std::function&)>& handler, - const std::function& closeFrame, - const std::function& stopPredicate); - - ssize_t writeToPipe(int pipe, const char* buffer, ssize_t size); - inline ssize_t writeToPipe(int pipe, const std::string& message) - { - return writeToPipe(pipe, message.c_str(), message.size()); - } - - ssize_t readFromPipe(int pipe, char* buffer, ssize_t size); - - /// Helper class to handle reading from a pipe. - class PipeReader - { - public: - PipeReader(const std::string& name, const int pipe) : - _name(name), - _pipe(pipe) - { - } - - const std::string& getName() const { return _name; } - - /// Reads a single line from the pipe. - /// Returns 0 for timeout, <0 for error, and >0 on success. - /// On success, line will contain the read message. - int readLine(std::string& line, - const std::function& stopPredicate); - - private: - const std::string _name; - const int _pipe; - std::string _data; - }; -} - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/common/Session.cpp b/common/Session.cpp index 859cd011e..e7f551979 100644 --- a/common/Session.cpp +++ b/common/Session.cpp @@ -32,7 +32,6 @@ #include #include "Common.hpp" -#include "IoUtil.hpp" #include "Protocol.hpp" #include "Log.hpp" #include diff --git a/configure.ac b/configure.ac index 7d795bce8..c605c87a4 100644 --- a/configure.ac +++ b/configure.ac @@ -855,7 +855,7 @@ else fi AC_SUBST(ENABLE_SUPPORT_KEY) -LIBS="$LIBS -lPocoNet${POCO_DEBUG_SUFFIX} -lPocoNetSSL${POCO_DEBUG_SUFFIX} -lPocoUtil${POCO_DEBUG_SUFFIX} -lPocoJSON${POCO_DEBUG_SUFFIX} -lPocoXML${POCO_DEBUG_SUFFIX} -lPocoFoundation${POCO_DEBUG_SUFFIX} -lPocoCrypto${POCO_DEBUG_SUFFIX}" +LIBS="$LIBS -lPocoNetSSL${POCO_DEBUG_SUFFIX} -lPocoNet${POCO_DEBUG_SUFFIX} -lPocoUtil${POCO_DEBUG_SUFFIX} -lPocoJSON${POCO_DEBUG_SUFFIX} -lPocoXML${POCO_DEBUG_SUFFIX} -lPocoFoundation${POCO_DEBUG_SUFFIX} -lPocoCrypto${POCO_DEBUG_SUFFIX}" AS_IF([test "$ENABLE_SSL" = "true"], [LIBS="$LIBS -lssl -lcrypto"]) diff --git a/kit/ChildSession.hpp b/kit/ChildSession.hpp index da44a5f94..f28c132a9 100644 --- a/kit/ChildSession.hpp +++ b/kit/ChildSession.hpp @@ -17,8 +17,6 @@ #define LOK_USE_UNSTABLE_API #include -#include - #include "Common.hpp" #include "Kit.hpp" #include "Session.hpp" diff --git a/kit/ForKit.cpp b/kit/ForKit.cpp index 1c763f8a3..993794bc7 100644 --- a/kit/ForKit.cpp +++ b/kit/ForKit.cpp @@ -30,7 +30,6 @@ #include #include -#include #include "Kit.hpp" #include #include diff --git a/kit/Kit.cpp b/kit/Kit.cpp index bb7933c93..77c3d9e2b 100644 --- a/kit/Kit.cpp +++ b/kit/Kit.cpp @@ -55,7 +55,6 @@ #include "ChildSession.hpp" #include #include -#include #include "KitHelper.hpp" #include "Kit.hpp" #include diff --git a/test/Makefile.am b/test/Makefile.am index ece956950..c3614c1d5 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -58,7 +58,6 @@ AM_CPPFLAGS = -pthread -I$(top_srcdir) -DBUILDING_TESTS -DLOK_ABORT_ON_ASSERTION wsd_sources = \ ../common/FileUtil.cpp \ - ../common/IoUtil.cpp \ ../common/Protocol.cpp \ ../common/SpookyV2.cpp \ ../common/Util.cpp \ diff --git a/test/UnitConvert.cpp b/test/UnitConvert.cpp index 61253cdda..4f281ad20 100644 --- a/test/UnitConvert.cpp +++ b/test/UnitConvert.cpp @@ -14,7 +14,6 @@ #include #include -#include #include #include #include diff --git a/test/UnitFuzz.cpp b/test/UnitFuzz.cpp index fe585eaa5..f9ab00a1d 100644 --- a/test/UnitFuzz.cpp +++ b/test/UnitFuzz.cpp @@ -14,7 +14,6 @@ #include #include -#include #include #include #include diff --git a/test/UnitOOB.cpp b/test/UnitOOB.cpp index 19cb7b599..4273ee06e 100644 --- a/test/UnitOOB.cpp +++ b/test/UnitOOB.cpp @@ -15,7 +15,6 @@ #include #include -#include #include #include #include diff --git a/wsd/Admin.cpp b/wsd/Admin.cpp index b439a9ee8..27dc596b9 100644 --- a/wsd/Admin.cpp +++ b/wsd/Admin.cpp @@ -23,7 +23,6 @@ #include "Auth.hpp" #include #include "FileServer.hpp" -#include #include #include #include "Storage.hpp" diff --git a/wsd/DocumentBroker.hpp b/wsd/DocumentBroker.hpp index 136167f15..d270f53b0 100644 --- a/wsd/DocumentBroker.hpp +++ b/wsd/DocumentBroker.hpp @@ -24,7 +24,6 @@ #include -#include "IoUtil.hpp" #include "Log.hpp" #include "TileDesc.hpp" #include "Util.hpp" diff --git a/wsd/LOOLWSD.cpp b/wsd/LOOLWSD.cpp index 92aae506a..2c7ac0c11 100644 --- a/wsd/LOOLWSD.cpp +++ b/wsd/LOOLWSD.cpp @@ -117,7 +117,6 @@ using Poco::Net::PartHandler; #include "Exceptions.hpp" #include "FileServer.hpp" #include -#include #if defined KIT_IN_PROCESS || MOBILEAPP # include #endif