Rebased ref, commits from common ancestor: commit c06a7caf61b69ad2de74b07310570503a17c2400 Author: Michael Meeks <michael.me...@collabora.com> AuthorDate: Sat Apr 16 20:44:53 2016 +0100 Commit: Michael Meeks <michael.me...@collabora.com> CommitDate: Sat Apr 16 20:44:53 2016 +0100
Attempt at a --nocaps argument to run with no caps, ie. under valgrind. diff --git a/loolwsd/LOOLForKit.cpp b/loolwsd/LOOLForKit.cpp index ffebf5652..4d7ba5f28 100644 --- a/loolwsd/LOOLForKit.cpp +++ b/loolwsd/LOOLForKit.cpp @@ -44,6 +44,7 @@ using Poco::Thread; using Poco::Timestamp; using Poco::Util::Application; +static bool NoCapsForKit = false; static std::string UnitTestLibrary; static std::atomic<unsigned> ForkCounter( 0 ); @@ -117,7 +118,7 @@ static int createLibreOfficeKit(const std::string& childRoot, Thread::sleep(std::stoul(std::getenv("SLEEPKITFORDEBUGGER")) * 1000); } - lokit_main(childRoot, sysTemplate, loTemplate, loSubPath); + lokit_main(childRoot, sysTemplate, loTemplate, loSubPath, NoCapsForKit); } else { @@ -213,6 +214,11 @@ int main(int argc, char** argv) eq = std::strchr(cmd, '='); UnitTestLibrary = std::string(eq+1); } + // we are running in no-privilege mode - with no chroot etc. + else if (std::strstr(cmd, "--nocaps") == cmd) + { + NoCapsForKit = true; + } #endif } diff --git a/loolwsd/LOOLKit.cpp b/loolwsd/LOOLKit.cpp index 7f55ec966..1a91bb636 100644 --- a/loolwsd/LOOLKit.cpp +++ b/loolwsd/LOOLKit.cpp @@ -847,7 +847,8 @@ namespace { void lokit_main(const std::string& childRoot, const std::string& sysTemplate, const std::string& loTemplate, - const std::string& loSubPath) + const std::string& loSubPath, + bool noCapabilities) { // Reinitialize logging when forked. Log::initialize("kit"); @@ -874,102 +875,112 @@ void lokit_main(const std::string& childRoot, Util::setTerminationSignals(); Util::setFatalSignals(); - static const std::string instdir_path = "/" + loSubPath + "/program"; - LibreOfficeKit* loKit = nullptr; + std::string instdir_path; + Path jailPath; + bool bRunInsideJail = !noCapabilities; try { - const Path jailPath = Path::forDirectory(childRoot + Path::separator() + jailId); - Log::info("Jail path: " + jailPath.toString()); - File(jailPath).createDirectories(); + if (bRunInsideJail) + { + instdir_path = "/" + loSubPath + "/program"; - // Create a symlink inside the jailPath so that the absolute pathname loTemplate, when - // interpreted inside a chroot at jailPath, points to loSubPath (relative to the chroot). - symlinkPathToJail(jailPath, loTemplate, loSubPath); + jailPath = Path::forDirectory(childRoot + Path::separator() + jailId); + Log::info("Jail path: " + jailPath.toString()); + File(jailPath).createDirectories(); - // Font paths can end up as realpaths so match that too. - char *resolved = realpath(loTemplate.c_str(), NULL); - if (resolved) - { - if (strcmp(loTemplate.c_str(), resolved)) - symlinkPathToJail(jailPath, std::string(resolved), loSubPath); - free (resolved); - } + // Create a symlink inside the jailPath so that the absolute pathname loTemplate, when + // interpreted inside a chroot at jailPath, points to loSubPath (relative to the chroot). + symlinkPathToJail(jailPath, loTemplate, loSubPath); - Path jailLOInstallation(jailPath, loSubPath); - jailLOInstallation.makeDirectory(); - File(jailLOInstallation).createDirectory(); + // Font paths can end up as realpaths so match that too. + char *resolved = realpath(loTemplate.c_str(), NULL); + if (resolved) + { + if (strcmp(loTemplate.c_str(), resolved)) + symlinkPathToJail(jailPath, std::string(resolved), loSubPath); + free (resolved); + } - // Copy (link) LO installation and other necessary files into it from the template. - bool bLoopMounted = false; - if (getenv("LOOL_BIND_MOUNT")) - { - Path usrSrcPath(sysTemplate, "usr"); - Path usrDestPath(jailPath, "usr"); - File(usrDestPath).createDirectory(); - std::string mountCommand = - std::string("loolmount ") + - usrSrcPath.toString() + - std::string(" ") + - usrDestPath.toString(); - Log::debug("Initializing jail bind mount."); - bLoopMounted = !system(mountCommand.c_str()); - Log::debug("Initialized jail bind mount."); - } - linkOrCopy(sysTemplate, jailPath, - bLoopMounted ? COPY_NO_USR : COPY_ALL); - linkOrCopy(loTemplate, jailLOInstallation, COPY_LO); + Path jailLOInstallation(jailPath, loSubPath); + jailLOInstallation.makeDirectory(); + File(jailLOInstallation).createDirectory(); - // We need this because sometimes the hostname is not resolved - const auto networkFiles = {"/etc/host.conf", "/etc/hosts", "/etc/nsswitch.conf", "/etc/resolv.conf"}; - for (const auto& filename : networkFiles) - { - const auto etcPath = Path(jailPath, filename).toString(); - const File networkFile(filename); - if (networkFile.exists() && !File(etcPath).exists()) + // Copy (link) LO installation and other necessary files into it from the template. + bool bLoopMounted = false; + if (getenv("LOOL_BIND_MOUNT")) { - networkFile.copyTo(etcPath); + Path usrSrcPath(sysTemplate, "usr"); + Path usrDestPath(jailPath, "usr"); + File(usrDestPath).createDirectory(); + std::string mountCommand = + std::string("loolmount ") + + usrSrcPath.toString() + + std::string(" ") + + usrDestPath.toString(); + Log::debug("Initializing jail bind mount."); + bLoopMounted = !system(mountCommand.c_str()); + Log::debug("Initialized jail bind mount."); } - } + linkOrCopy(sysTemplate, jailPath, + bLoopMounted ? COPY_NO_USR : COPY_ALL); + linkOrCopy(loTemplate, jailLOInstallation, COPY_LO); - Log::debug("Initialized jail files."); + // We need this because sometimes the hostname is not resolved + const auto networkFiles = {"/etc/host.conf", "/etc/hosts", "/etc/nsswitch.conf", "/etc/resolv.conf"}; + for (const auto& filename : networkFiles) + { + const auto etcPath = Path(jailPath, filename).toString(); + const File networkFile(filename); + if (networkFile.exists() && !File(etcPath).exists()) + { + networkFile.copyTo(etcPath); + } + } - // Create the urandom and random devices - File(Path(jailPath, "/dev")).createDirectory(); - if (mknod((jailPath.toString() + "/dev/random").c_str(), - S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, - makedev(1, 8)) != 0) - { - Log::syserror("mknod(" + jailPath.toString() + "/dev/random) failed."); + Log::debug("Initialized jail files."); - } - if (mknod((jailPath.toString() + "/dev/urandom").c_str(), - S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, - makedev(1, 9)) != 0) - { - Log::syserror("mknod(" + jailPath.toString() + "/dev/urandom) failed."); - } + // Create the urandom and random devices + File(Path(jailPath, "/dev")).createDirectory(); + if (mknod((jailPath.toString() + "/dev/random").c_str(), + S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, + makedev(1, 8)) != 0) + { + Log::syserror("mknod(" + jailPath.toString() + "/dev/random) failed."); + } + if (mknod((jailPath.toString() + "/dev/urandom").c_str(), + S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, + makedev(1, 9)) != 0) + { + Log::syserror("mknod(" + jailPath.toString() + "/dev/urandom) failed."); + } - Log::info("chroot(\"" + jailPath.toString() + "\")"); - if (chroot(jailPath.toString().c_str()) == -1) - { - Log::syserror("chroot(\"" + jailPath.toString() + "\") failed."); - std::_Exit(Application::EXIT_SOFTWARE); - } + Log::info("chroot(\"" + jailPath.toString() + "\")"); + if (chroot(jailPath.toString().c_str()) == -1) + { + Log::syserror("chroot(\"" + jailPath.toString() + "\") failed."); + std::_Exit(Application::EXIT_SOFTWARE); + } - if (chdir("/") == -1) - { - Log::syserror("chdir(\"/\") in jail failed."); - std::_Exit(Application::EXIT_SOFTWARE); - } + if (chdir("/") == -1) + { + Log::syserror("chdir(\"/\") in jail failed."); + std::_Exit(Application::EXIT_SOFTWARE); + } - dropCapability(CAP_SYS_CHROOT); - dropCapability(CAP_MKNOD); - dropCapability(CAP_FOWNER); + dropCapability(CAP_SYS_CHROOT); + dropCapability(CAP_MKNOD); + dropCapability(CAP_FOWNER); - Log::debug("Initialized jail nodes, dropped caps."); + Log::debug("Initialized jail nodes, dropped caps."); + } + else // noCapabilities set + { + Log::info("Using template " + loTemplate + " as install subpath - skipping jail setup"); + instdir_path = "/" + loTemplate + "/program"; + } - loKit = lok_init_2(instdir_path.c_str(), "file:///user"); + LibreOfficeKit* loKit = lok_init_2(instdir_path.c_str(), "file:///user"); if (loKit == nullptr) { Log::error("LibreOfficeKit initialization failed. Exiting."); @@ -1042,8 +1053,11 @@ void lokit_main(const std::string& childRoot, return TerminationFlag; }); - // Cleanup jail. - Util::removeFile(jailPath, true); + // Cleanup a jail if we created one + if (bRunInsideJail && !jailPath.isRelative()) + { + Util::removeFile(jailPath, true); + } } catch (const Exception& exc) { diff --git a/loolwsd/LOOLKit.hpp b/loolwsd/LOOLKit.hpp index a8981662d..2f4302248 100644 --- a/loolwsd/LOOLKit.hpp +++ b/loolwsd/LOOLKit.hpp @@ -12,7 +12,8 @@ void lokit_main(const std::string& childRoot, const std::string& sysTemplate, const std::string& loTemplate, - const std::string& loSubPath); + const std::string& loSubPath, + bool noCapabilities); bool globalPreinit(const std::string &loTemplate); diff --git a/loolwsd/LOOLWSD.cpp b/loolwsd/LOOLWSD.cpp index 802850b44..0b0155cc4 100644 --- a/loolwsd/LOOLWSD.cpp +++ b/loolwsd/LOOLWSD.cpp @@ -147,6 +147,7 @@ int ClientPortNumber = DEFAULT_CLIENT_PORT_NUMBER; /// New LOK child processes ready to host documents. //TODO: Move to a more sensible namespace. static bool DisplayVersion = false; +static bool NoCapsForKit = false; static std::vector<std::shared_ptr<ChildProcess>> newChildren; static std::mutex newChildrenMutex; static std::condition_variable newChildrenCV; @@ -1216,6 +1217,11 @@ void LOOLWSD::defineOptions(OptionSet& optionSet) .repeatable(false) .argument("unitlib")); + optionSet.addOption(Option("nocaps", "", "Use a non-privileged forkit for valgrinding.") + .required(false) + .repeatable(false) + .argument("nocaps")); + optionSet.addOption(Option("careerspan", "", "How many seconds to run.") .required(false) .repeatable(false) @@ -1258,6 +1264,8 @@ void LOOLWSD::handleOption(const std::string& optionName, #if ENABLE_DEBUG else if (optionName == "unitlib") UnitTestLibrary = value; + else if (optionName == "nocaps") + NoCapsForKit = true; else if (optionName == "careerspan") careerSpanSeconds = std::stoi(value); #endif @@ -1286,7 +1294,13 @@ Process::PID LOOLWSD::createForKit() if (DisplayVersion) args.push_back("--version"); - const std::string forKitPath = Path(Application::instance().commandPath()).parent().toString() + "loolforkit"; + std::string forKitPath = Path(Application::instance().commandPath()).parent().toString() + "loolforkit"; + + if (NoCapsForKit) + { + forKitPath = forKitPath + std::string("-nocaps"); + args.push_back("--nocaps"); + } Log::info("Launching forkit process: " + forKitPath + " " + Poco::cat(std::string(" "), args.begin(), args.end())); diff --git a/loolwsd/Makefile.am b/loolwsd/Makefile.am index e3c5f7a88..39c5071ed 100644 --- a/loolwsd/Makefile.am +++ b/loolwsd/Makefile.am @@ -49,7 +49,8 @@ loolwsd_SOURCES = Admin.cpp \ noinst_PROGRAMS = connect \ loadtest \ - lokitclient + lokitclient \ + loolforkit-nocaps loadtest_SOURCES = LoadTest.cpp \ Log.cpp \ @@ -71,6 +72,9 @@ loolforkit_SOURCES = LOOLForKit.cpp \ LOOLKit.cpp \ $(shared_sources) +# build a binary with no caps to help debugging +loolforkit_nocaps_SOURCES = $(loolforkit_SOURCES) + loolmount_SOURCES = loolmount.c loolmap_SOURCES = loolmap.c commit a66e73aeb0789a87c6948e6c1e9a2fc3e13b3aa1 Author: Henry Castro <hcas...@collabora.com> AuthorDate: Sat Apr 16 13:29:00 2016 -0400 Commit: Henry Castro <hcas...@collabora.com> CommitDate: Sat Apr 16 13:32:44 2016 -0400 loolwsd: fail when document broker cannot get a child diff --git a/loolwsd/LOOLWSD.cpp b/loolwsd/LOOLWSD.cpp index a60d90d09..802850b44 100644 --- a/loolwsd/LOOLWSD.cpp +++ b/loolwsd/LOOLWSD.cpp @@ -543,10 +543,10 @@ private: if (!child) { // Let the client know we can't serve now. - response.setStatusAndReason(Poco::Net::HTTPResponse::HTTP_SERVICE_UNAVAILABLE); - response.setContentLength(0); - response.send(); - return; + status = "statusindicator: fail"; + ws->sendFrame(status.data(), (int) status.size()); + ws->shutdown(); + throw WebSocketException("Failed to get new child. Client cannot serve now.", WebSocket::WS_ENDPOINT_GOING_AWAY); } // Set one we just created. @@ -575,7 +575,6 @@ private: if (!waitBridgeCompleted(session, docBroker)) { - Log::error(session->getName() + ": Failed to connect to lokit process. Client cannot serve now."); // Let the client know we can't serve now. status = "statusindicator: fail"; ws->sendFrame(status.data(), (int) status.size()); diff --git a/loolwsd/test/httpwstest.cpp b/loolwsd/test/httpwstest.cpp index 91dfb79bf..cdaeeee82 100644 --- a/loolwsd/test/httpwstest.cpp +++ b/loolwsd/test/httpwstest.cpp @@ -209,29 +209,39 @@ void HTTPWSTest::testHandShake() CPPUNIT_ASSERT(payload.compare(0, payload.size(), buffer, 0, bytes) == 0); CPPUNIT_ASSERT(flags == Poco::Net::WebSocket::FRAME_TEXT); - // After document broker finish searching it sends editlok - // it should be at end on handshake bytes = socket.receiveFrame(buffer, sizeof(buffer), flags); - CPPUNIT_ASSERT(prefixEdit.compare(0, prefixEdit.size(), buffer, 0, prefixEdit.size()) == 0); - CPPUNIT_ASSERT(flags == Poco::Net::WebSocket::FRAME_TEXT); - - payload = "statusindicator: connect"; - bytes = socket.receiveFrame(buffer, sizeof(buffer), flags); - CPPUNIT_ASSERT_EQUAL((int) payload.size(), bytes); - CPPUNIT_ASSERT(payload.compare(0, payload.size(), buffer, 0, bytes) == 0); - CPPUNIT_ASSERT(flags == Poco::Net::WebSocket::FRAME_TEXT); - - bytes = socket.receiveFrame(buffer, sizeof(buffer), flags); - if (std::strstr(buffer, fail)) + if (!std::strstr(buffer, fail)) { - payload = "statusindicator: fail"; + // After document broker finish searching it sends editlok + // it should be at end on handshake + CPPUNIT_ASSERT(prefixEdit.compare(0, prefixEdit.size(), buffer, 0, prefixEdit.size()) == 0); + CPPUNIT_ASSERT(flags == Poco::Net::WebSocket::FRAME_TEXT); + + payload = "statusindicator: connect"; + bytes = socket.receiveFrame(buffer, sizeof(buffer), flags); CPPUNIT_ASSERT_EQUAL((int) payload.size(), bytes); CPPUNIT_ASSERT(payload.compare(0, payload.size(), buffer, 0, bytes) == 0); CPPUNIT_ASSERT(flags == Poco::Net::WebSocket::FRAME_TEXT); + + bytes = socket.receiveFrame(buffer, sizeof(buffer), flags); + if (!std::strstr(buffer, fail)) + { + payload = "statusindicator: ready"; + CPPUNIT_ASSERT_EQUAL((int) payload.size(), bytes); + CPPUNIT_ASSERT(payload.compare(0, payload.size(), buffer, 0, bytes) == 0); + CPPUNIT_ASSERT(flags == Poco::Net::WebSocket::FRAME_TEXT); + } + else + { + payload = "statusindicator: fail"; + CPPUNIT_ASSERT_EQUAL((int) payload.size(), bytes); + CPPUNIT_ASSERT(payload.compare(0, payload.size(), buffer, 0, bytes) == 0); + CPPUNIT_ASSERT(flags == Poco::Net::WebSocket::FRAME_TEXT); + } } else { - payload = "statusindicator: ready"; + payload = "statusindicator: fail"; CPPUNIT_ASSERT_EQUAL((int) payload.size(), bytes); CPPUNIT_ASSERT(payload.compare(0, payload.size(), buffer, 0, bytes) == 0); CPPUNIT_ASSERT(flags == Poco::Net::WebSocket::FRAME_TEXT); commit 4254ddad7752663915a58f5ec87213a027a6b69a Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> AuthorDate: Sat Apr 16 12:28:55 2016 -0400 Commit: Ashod Nakashian <ashnak...@gmail.com> CommitDate: Sat Apr 16 17:29:35 2016 +0000 loolwsd: consistently set HTTP status and reason everywhere Change-Id: Ie538e4907e3a3a514918000bb585d2aaf182e468 Reviewed-on: https://gerrit.libreoffice.org/24132 Reviewed-by: Ashod Nakashian <ashnak...@gmail.com> Tested-by: Ashod Nakashian <ashnak...@gmail.com> diff --git a/loolwsd/Admin.cpp b/loolwsd/Admin.cpp index e647ae74b..3ba553aee 100644 --- a/loolwsd/Admin.cpp +++ b/loolwsd/Admin.cpp @@ -310,7 +310,7 @@ void AdminRequestHandler::handleWSRequests(HTTPServerRequest& request, HTTPServe { Log::info("NotAuthenticatedException"); response.set("WWW-Authenticate", "Basic realm=\"ws-online\""); - response.setStatus(HTTPResponse::HTTP_UNAUTHORIZED); + response.setStatusAndReason(HTTPResponse::HTTP_UNAUTHORIZED); response.setContentLength(0); response.send(); } @@ -350,13 +350,13 @@ void AdminRequestHandler::handleRequest(HTTPServerRequest& request, HTTPServerRe { Log::info("Admin::NotAuthenticated"); response.set("WWW-Authenticate", "Basic realm=\"online\""); - response.setStatus(HTTPResponse::HTTP_UNAUTHORIZED); + response.setStatusAndReason(HTTPResponse::HTTP_UNAUTHORIZED); response.setContentLength(0); response.send(); } catch (const std::exception& exc) { - Log::info("Unknown Exception caught"); + Log::info(std::string("Admin::handleRequest: Exception: ") + exc.what()); response.setStatusAndReason(HTTPResponse::HTTP_BAD_REQUEST); response.setContentLength(0); response.send(); diff --git a/loolwsd/Common.hpp b/loolwsd/Common.hpp index 43a67e967..d287736cb 100644 --- a/loolwsd/Common.hpp +++ b/loolwsd/Common.hpp @@ -11,8 +11,6 @@ #ifndef INCLUDED_COMMON_HPP #define INCLUDED_COMMON_HPP -#include <string> - // The maximum number of client connections we can accept. constexpr int MAX_SESSIONS = 1024; diff --git a/loolwsd/FileServer.hpp b/loolwsd/FileServer.hpp index 293e34e25..d869e1199 100644 --- a/loolwsd/FileServer.hpp +++ b/loolwsd/FileServer.hpp @@ -171,14 +171,14 @@ public: { Log::error("FileServerRequestHandler::NotAuthenticated: " + exc.displayText()); response.set("WWW-Authenticate", "Basic realm=\"online\""); - response.setStatus(HTTPResponse::HTTP_UNAUTHORIZED); + response.setStatusAndReason(HTTPResponse::HTTP_UNAUTHORIZED); response.setContentLength(0); response.send(); } catch (const Poco::FileNotFoundException& exc) { Log::error("FileServerRequestHandler: " + exc.displayText()); - response.setStatus(HTTPResponse::HTTP_NOT_FOUND); + response.setStatusAndReason(HTTPResponse::HTTP_NOT_FOUND); response.setContentLength(0); response.send(); } commit fe952794f0a7f04d6ae7a788e1352da00fe1159a Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> AuthorDate: Sat Apr 16 12:26:26 2016 -0400 Commit: Ashod Nakashian <ashnak...@gmail.com> CommitDate: Sat Apr 16 17:29:11 2016 +0000 loolwsd: don't expose private members Change-Id: I049c92d0ddb296058fad283fffc291348b4608b1 Reviewed-on: https://gerrit.libreoffice.org/24131 Reviewed-by: Ashod Nakashian <ashnak...@gmail.com> Tested-by: Ashod Nakashian <ashnak...@gmail.com> diff --git a/loolwsd/FileServer.hpp b/loolwsd/FileServer.hpp index 6338989f2..293e34e25 100644 --- a/loolwsd/FileServer.hpp +++ b/loolwsd/FileServer.hpp @@ -54,6 +54,7 @@ using Poco::Util::Application; class FileServerRequestHandler: public HTTPRequestHandler { public: + /// Evaluate if the cookie exists, and if not, ask for the credentials. static bool isAdminLoggedIn(HTTPServerRequest& request, HTTPServerResponse& response) { @@ -108,35 +109,6 @@ public: return false; } - void preprocessFile(HTTPServerRequest& request, HTTPServerResponse& response) - { - HTMLForm form(request, request.stream()); - - std::string preprocess; - const auto host = (LOOLWSD::SSLEnabled? "wss://": "ws://") + request.getHost(); - - Poco::URI requestUri(request.getURI()); - requestUri.normalize(); // avoid .'s and ..'s - const auto path = Poco::Path(LOOLWSD::FileServerRoot, requestUri.getPath()); - - Log::debug("Preprocessing file: " + path.toString()); - - FileInputStream file(path.toString()); - StreamCopier::copyToString(file, preprocess); - file.close(); - - Poco::replaceInPlace(preprocess, std::string("%ACCESS_TOKEN%"), form.get("access_token", "")); - Poco::replaceInPlace(preprocess, std::string("%ACCESS_TOKEN_TTL%"), form.get("access_token_ttl", "")); - Poco::replaceInPlace(preprocess, std::string("%HOST%"), host); - - response.setContentType("text/html"); - response.setContentLength(preprocess.length()); - response.setChunkedTransferEncoding(false); - - std::ostream& ostr = response.send(); - ostr << preprocess; - } - void handleRequest(HTTPServerRequest& request, HTTPServerResponse& response) override { try @@ -211,6 +183,37 @@ public: response.send(); } } + +private: + + void preprocessFile(HTTPServerRequest& request, HTTPServerResponse& response) + { + HTMLForm form(request, request.stream()); + + std::string preprocess; + const auto host = (LOOLWSD::SSLEnabled? "wss://": "ws://") + request.getHost(); + + Poco::URI requestUri(request.getURI()); + requestUri.normalize(); // avoid .'s and ..'s + const auto path = Poco::Path(LOOLWSD::FileServerRoot, requestUri.getPath()); + + Log::debug("Preprocessing file: " + path.toString()); + + FileInputStream file(path.toString()); + StreamCopier::copyToString(file, preprocess); + file.close(); + + Poco::replaceInPlace(preprocess, std::string("%ACCESS_TOKEN%"), form.get("access_token", "")); + Poco::replaceInPlace(preprocess, std::string("%ACCESS_TOKEN_TTL%"), form.get("access_token_ttl", "")); + Poco::replaceInPlace(preprocess, std::string("%HOST%"), host); + + response.setContentType("text/html"); + response.setContentLength(preprocess.length()); + response.setChunkedTransferEncoding(false); + + std::ostream& ostr = response.send(); + ostr << preprocess; + } }; class FileServer commit 93d3f806e1bed9f5c43cf16f3c824a5fcb962f3d Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> AuthorDate: Sat Apr 16 08:10:52 2016 -0400 Commit: Ashod Nakashian <ashnak...@gmail.com> CommitDate: Sat Apr 16 17:28:45 2016 +0000 loolwsd: logging and cosmetics Change-Id: I413a2e40f480ba41e37c7442724c3f037528f89b Reviewed-on: https://gerrit.libreoffice.org/24130 Reviewed-by: Ashod Nakashian <ashnak...@gmail.com> Tested-by: Ashod Nakashian <ashnak...@gmail.com> diff --git a/loolwsd/Admin.cpp b/loolwsd/Admin.cpp index d5d4557e9..e647ae74b 100644 --- a/loolwsd/Admin.cpp +++ b/loolwsd/Admin.cpp @@ -403,7 +403,7 @@ void MemoryStats::run() AdminModel& model = _admin->getModel(); unsigned totalMem = _admin->getTotalMemoryUsage(model); - Log::info("Total memory used: " + std::to_string(totalMem)); + Log::trace("Total memory used: " + std::to_string(totalMem)); model.addMemStats(totalMem); } diff --git a/loolwsd/FileServer.hpp b/loolwsd/FileServer.hpp index a749f065d..6338989f2 100644 --- a/loolwsd/FileServer.hpp +++ b/loolwsd/FileServer.hpp @@ -148,7 +148,7 @@ public: requestUri.getPathSegments(requestSegments); if (requestSegments.size() < 1) { - throw Poco::FileNotFoundException("Invalid file."); + throw Poco::FileNotFoundException("Invalid URI request: [" + requestUri.toString() + "]."); } const std::string endPoint = requestSegments[requestSegments.size() - 1]; @@ -173,7 +173,7 @@ public: if (filepath.find(LOOLWSD::FileServerRoot) != 0) { // Accessing unauthorized path. - throw Poco::FileNotFoundException("Invalid file path."); + throw Poco::FileNotFoundException("Invalid or forbidden file path: [" + filepath + "]."); } const std::size_t extPoint = endPoint.find_last_of("."); @@ -195,17 +195,17 @@ public: response.sendFile(filepath, mimeType); } } - catch (Poco::Net::NotAuthenticatedException& exc) + catch (const Poco::Net::NotAuthenticatedException& exc) { - Log::error("FileServerRequestHandler::NotAuthenticated"); + Log::error("FileServerRequestHandler::NotAuthenticated: " + exc.displayText()); response.set("WWW-Authenticate", "Basic realm=\"online\""); response.setStatus(HTTPResponse::HTTP_UNAUTHORIZED); response.setContentLength(0); response.send(); } - catch (Poco::FileNotFoundException& exc) + catch (const Poco::FileNotFoundException& exc) { - Log::error("FileServerRequestHandler:: File [" + request.getURI() + "] not found."); + Log::error("FileServerRequestHandler: " + exc.displayText()); response.setStatus(HTTPResponse::HTTP_NOT_FOUND); response.setContentLength(0); response.send(); diff --git a/loolwsd/LOOLWSD.cpp b/loolwsd/LOOLWSD.cpp index db27edca1..a60d90d09 100644 --- a/loolwsd/LOOLWSD.cpp +++ b/loolwsd/LOOLWSD.cpp @@ -638,31 +638,31 @@ private: static void handleGetDiscovery(HTTPServerRequest& request, HTTPServerResponse& response) { - DOMParser parser; - DOMWriter writer; - std::string discoveryPath = Path(Application::instance().commandPath()).parent().toString() + "discovery.xml"; if (!File(discoveryPath).exists()) { discoveryPath = LOOLWSD_DATADIR "/discovery.xml"; } + const std::string mediaType = "text/xml"; const std::string action = "action"; const std::string urlsrc = "urlsrc"; - const std::string uriValue = (LOOLWSD::SSLEnabled? "https://": "http://") + - (LOOLWSD::ServerName.empty()? request.getHost(): LOOLWSD::ServerName) + + const std::string uriValue = (LOOLWSD::SSLEnabled ? "https://" : "http://") + + (LOOLWSD::ServerName.empty() ? request.getHost() : LOOLWSD::ServerName) + "/loleaflet/dist/loleaflet.html?"; InputSource inputSrc(discoveryPath); + DOMParser parser; AutoPtr<Poco::XML::Document> docXML = parser.parse(&inputSrc); AutoPtr<NodeList> listNodes = docXML->getElementsByTagName(action); - for (unsigned long it = 0; it < listNodes->length(); it++) + for (unsigned long it = 0; it < listNodes->length(); ++it) { static_cast<Element*>(listNodes->item(it))->setAttribute(urlsrc, uriValue); } std::ostringstream ostrXML; + DOMWriter writer; writer.writeNode(ostrXML, docXML); response.set("User-Agent", "LOOLWSD WOPI Agent"); @@ -672,6 +672,7 @@ private: std::ostream& ostr = response.send(); ostr << ostrXML.str(); + Log::debug("Sent discovery.xml successfully."); } public: @@ -707,7 +708,6 @@ public: } else { - //authenticate(request, response, id); handleGetRequest(request, response, id); } } diff --git a/loolwsd/LOOLWSD.hpp b/loolwsd/LOOLWSD.hpp index 556283774..1fcdac6d6 100644 --- a/loolwsd/LOOLWSD.hpp +++ b/loolwsd/LOOLWSD.hpp @@ -25,8 +25,6 @@ #include "DocumentBroker.hpp" #include "Util.hpp" -class MasterProcessSession; - class LOOLWSD: public Poco::Util::ServerApplication { public: commit c2560725db90e8d5779cfe8fd9e774691c92ad6d Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> AuthorDate: Sat Apr 16 08:02:15 2016 -0400 Commit: Ashod Nakashian <ashnak...@gmail.com> CommitDate: Sat Apr 16 17:27:43 2016 +0000 loolwsd: admin uses config for ssl key Change-Id: I38b0f59c158698a6eb89d4b671001e1d8cb61673 Reviewed-on: https://gerrit.libreoffice.org/24129 Reviewed-by: Ashod Nakashian <ashnak...@gmail.com> Tested-by: Ashod Nakashian <ashnak...@gmail.com> diff --git a/loolwsd/Common.hpp b/loolwsd/Common.hpp index 2d9db6841..43a67e967 100644 --- a/loolwsd/Common.hpp +++ b/loolwsd/Common.hpp @@ -38,7 +38,6 @@ constexpr auto FIFO_LOOLWSD = "loolwsdfifo"; constexpr auto FIFO_PATH = "pipe"; constexpr auto JAILED_DOCUMENT_ROOT = "/user/docs/"; constexpr auto NEW_CHILD_URI = "/loolws/newchild?"; -constexpr auto SSL_KEY_FILE = "key.pem"; // The client port number, both loolwsd and the kits have this. extern int ClientPortNumber; diff --git a/loolwsd/FileServer.hpp b/loolwsd/FileServer.hpp index 2941c35ec..a749f065d 100644 --- a/loolwsd/FileServer.hpp +++ b/loolwsd/FileServer.hpp @@ -57,6 +57,9 @@ public: /// Evaluate if the cookie exists, and if not, ask for the credentials. static bool isAdminLoggedIn(HTTPServerRequest& request, HTTPServerResponse& response) { + const auto& config = Application::instance().config(); + const auto sslKeyPath = config.getString("ssl.key_file_path", ""); + if (request.find("Cookie") != request.end()) { // FIXME: Handle other cookie params like '; httponly; secure' @@ -66,9 +69,7 @@ public: const std::string jwtToken = request["Cookie"].substr(pos + 1); Log::info("Verifying JWT token: " + jwtToken); - // TODO: Read key from configuration file - const std::string keyPath = "/etc/loolwsd/" + std::string(SSL_KEY_FILE); - JWTAuth authAgent(keyPath, "admin", "admin", "admin"); + JWTAuth authAgent(sslKeyPath, "admin", "admin", "admin"); if (authAgent.verify(jwtToken)) { Log::trace("JWT token is valid"); @@ -78,8 +79,8 @@ public: Log::info("Invalid JWT token, let the administrator re-login"); } - const auto user = Application::instance().config().getString("admin_console_username", ""); - const auto pass = Application::instance().config().getString("admin_console_password", ""); + const auto user = config.getString("admin_console_username", ""); + const auto pass = config.getString("admin_console_password", ""); if (user.empty() || pass.empty()) { Log::error("Admin Console credentials missing. Denying access until set."); @@ -92,9 +93,7 @@ public: { const std::string htmlMimeType = "text/html"; // generate and set the cookie - // TODO: Read key from configuration file - const std::string keyPath = "/etc/loolwsd/" + std::string(SSL_KEY_FILE); - JWTAuth authAgent(keyPath, "admin", "admin", "admin"); + JWTAuth authAgent(sslKeyPath, "admin", "admin", "admin"); const std::string jwtToken = authAgent.getAccessToken(); Poco::Net::HTTPCookie cookie("jwt", jwtToken); cookie.setPath("/adminws/"); commit 8eedd9dfd3ce9e3f46c643898b42dbe4f7721d2d Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> AuthorDate: Sat Apr 16 08:19:39 2016 -0400 Commit: Ashod Nakashian <ashnak...@gmail.com> CommitDate: Sat Apr 16 17:24:50 2016 +0000 loleaflet: gitignore branding files Change-Id: I78df82004999938e2c9b7aa9935896fd8c195318 Reviewed-on: https://gerrit.libreoffice.org/24128 Reviewed-by: Ashod Nakashian <ashnak...@gmail.com> Tested-by: Ashod Nakashian <ashnak...@gmail.com> diff --git a/loleaflet/.gitignore b/loleaflet/.gitignore index 4335c9904..5b195c2aa 100644 --- a/loleaflet/.gitignore +++ b/loleaflet/.gitignore @@ -10,6 +10,9 @@ component.json _site dist/*.js +dist/branding.css +dist/branding.js +dist/images/toolbar-bg.png dist/admin/*.js dist/plugins/ plugins/draw-0.2.4/dist/*.js commit 69816395d5a455efb7d884554788e559d8a7d5e3 Author: Michael Meeks <michael.me...@collabora.com> AuthorDate: Fri Apr 15 22:04:15 2016 +0100 Commit: Michael Meeks <michael.me...@collabora.com> CommitDate: Fri Apr 15 22:04:15 2016 +0100 Re-enable verbose tracing during unit testing. diff --git a/loolwsd/test/run_unit.sh.in b/loolwsd/test/run_unit.sh.in index 7a929e776..a53daec5a 100755 --- a/loolwsd/test/run_unit.sh.in +++ b/loolwsd/test/run_unit.sh.in @@ -28,7 +28,7 @@ else test_mode=old fi -# export LOOL_LOGLEVEL=trace +export LOOL_LOGLEVEL=trace if test "z$enable_debug" != "ztrue"; then echo "" commit 448e25f6d81f2c143878a3e6eb269d44049af389 Author: Michael Meeks <michael.me...@collabora.com> AuthorDate: Fri Apr 15 20:46:44 2016 +0100 Commit: Michael Meeks <michael.me...@collabora.com> CommitDate: Fri Apr 15 21:53:10 2016 +0100 Make logging signal safe again. snprintf: simpler, safer, faster. diff --git a/loolwsd/Log.cpp b/loolwsd/Log.cpp index 48fe800a6..fb85a4846 100644 --- a/loolwsd/Log.cpp +++ b/loolwsd/Log.cpp @@ -41,7 +41,27 @@ namespace Log }; static StaticNames Source; - std::string prefix() + // We need a signal safe means of writing messages + // $ man 7 signal + void signalLog(const char *message) + { + while (true) { + int length = strlen(message); + int written = write (STDERR_FILENO, message, length); + if (written < 0) + { + if (errno == EINTR) + continue; // ignore. + else + break; + } + message += written; + if (message[0] == '\0') + break; + } + } + + static void getPrefix(char *buffer) { Poco::Int64 usec = Poco::Timestamp().epochMicroseconds() - epochStart; @@ -53,19 +73,31 @@ namespace Log const Poco::Int64 seconds = usec / (one_s); usec %= (one_s); - std::ostringstream stream; - stream << (Source.inited ? Source.id : std::string()) - << '-' << std::setw(2) << std::setfill('0') - << (Poco::Thread::current() ? Poco::Thread::current()->id() : 0) << ' ' - << std::setw(2) << hours << ':' << std::setw(2) << minutes << ':' - << std::setw(2) << seconds << "." << std::setw(6) << usec - << ' '; + char procName[32]; // we really need only 16 + if (!prctl(PR_GET_NAME, reinterpret_cast<unsigned long>(procName), 0, 0, 0) == 0) + strcpy(procName, "<noid>"); + + const char *appName = (Source.inited ? Source.id.c_str() : "<shutdown>"); + assert(strlen(appName) + 32 + 28 < 1024 - 1); - char buf[32]; // we really need only 16 - if (prctl(PR_GET_NAME, reinterpret_cast<unsigned long>(buf), 0, 0, 0) == 0) - stream << '[' << std::setw(15) << std::setfill(' ') << std::left << buf << "] "; + snprintf(buffer, 4095, "%s-%.2d %.2d:%.2d:%.2d.%.6d [ %s ] ", appName, + (Poco::Thread::current() ? Poco::Thread::current()->id() : 0), + (int)hours, (int)minutes, (int)seconds, (int)usec, + procName); + } + + std::string prefix() + { + char buffer[1024]; + getPrefix(buffer); + return std::string(buffer); + } - return stream.str(); + void signalLogPrefix() + { + char buffer[1024]; + getPrefix(buffer); + signalLog(buffer); } void initialize(const std::string& name) diff --git a/loolwsd/Log.hpp b/loolwsd/Log.hpp index b64f7662d..cc43baa01 100644 --- a/loolwsd/Log.hpp +++ b/loolwsd/Log.hpp @@ -29,6 +29,11 @@ namespace Log void error(const std::string& msg); void syserror(const std::string& msg); + /// Signal safe prefix logging + void signalLogPrefix(); + /// Signal safe logging + void signalLog(const char *message); + /// The following is to write streaming logs. /// Log::info() << "Value: 0x" << std::hex << value /// << ", pointer: " << this << Log::end; diff --git a/loolwsd/Util.cpp b/loolwsd/Util.cpp index 895217984..d30b31a36 100644 --- a/loolwsd/Util.cpp +++ b/loolwsd/Util.cpp @@ -253,27 +253,6 @@ namespace Util } } - // We need a signal safe means of writing messages - // $ man 7 signal - static - void log_signal(const char *message) - { - while (true) { - int length = strlen(message); - int written = write (STDERR_FILENO, message, length); - if (written < 0) - { - if (errno == EINTR) - continue; // ignore. - else - break; - } - message += written; - if (message[0] == '\0') - break; - } - } - static void handleTerminationSignal(const int signal) { @@ -281,10 +260,10 @@ namespace Util { TerminationFlag = true; - log_signal(Log::prefix().c_str()); - log_signal(" Termination signal received: "); - log_signal(signalName(signal)); - log_signal("\n"); + Log::signalLogPrefix(); + Log::signalLog(" Termination signal received: "); + Log::signalLog(signalName(signal)); + Log::signalLog("\n"); } } @@ -307,14 +286,14 @@ namespace Util static void handleFatalSignal(const int signal) { - log_signal(Log::prefix().c_str()); - log_signal(" Fatal signal received: "); - log_signal(signalName(signal)); - log_signal("\n"); + Log::signalLogPrefix(); + Log::signalLog(" Fatal signal received: "); + Log::signalLog(signalName(signal)); + Log::signalLog("\n"); if (std::getenv("LOOL_DEBUG")) { - log_signal(FatalGdbString); + Log::signalLog(FatalGdbString); sleep(30); } commit 65ee749ce1c90612d04d4aea44318cb53e713031 Author: Michael Meeks <michael.me...@collabora.com> AuthorDate: Fri Apr 15 16:39:05 2016 +0100 Commit: Michael Meeks <michael.me...@collabora.com> CommitDate: Fri Apr 15 21:52:39 2016 +0100 Move new unit tests to custom test driver. Cleaner, and avoids bogus warnings during compile. Merge run_test.sh.in into a mode of run_unit.sh - gives the chance for nice debug output etc. diff --git a/loolwsd/configure.ac b/loolwsd/configure.ac index 48b253919..008308101 100644 --- a/loolwsd/configure.ac +++ b/loolwsd/configure.ac @@ -249,7 +249,6 @@ AC_CONFIG_FILES([Makefile loolwsd.spec loolwsd.xml]) AC_CONFIG_FILES([test/run_unit.sh],[chmod +x test/run_unit.sh]) -AC_CONFIG_FILES([test/run_test.sh],[chmod +x test/run_test.sh]) AC_OUTPUT diff --git a/loolwsd/test/Makefile.am b/loolwsd/test/Makefile.am index d44e78790..721ec0c04 100644 --- a/loolwsd/test/Makefile.am +++ b/loolwsd/test/Makefile.am @@ -28,19 +28,14 @@ else SYSTEM_STAMP = endif -${top_builddir}/test/run_unit.sh.log ${top_builddir}/test/run_unit.sh.trs : \ - $(SYSTEM_STAMP) @JAILS_PATH@ \ - ${top_srcdir}/test/run_unit.sh \ - ${top_builddir}/loolwsd ${top_builddir}/loolforkit \ - $(wildcard *.la) - if ${top_srcdir}/test/run_unit.sh; then \ - touch ${top_builddir}/test/run_unit.sh.log; \ - fi - if HAVE_LO_PATH -TESTS = ${top_srcdir}/test/run_unit.sh ${top_srcdir}/test/run_test.sh +TESTS = unit-timeout.la unit-fonts.la unit-storage.la unit-prefork.la run_test.sh else TESTS = ${top_builddir}/test/test endif +TEST_EXTENSIONS = .la .sh +LA_LOG_DRIVER = ${top_srcdir}/test/run_unit.sh +SH_LOG_DRIVER = ${top_srcdir}/test/run_unit.sh + EXTRA_DIST = data/hello.odt data/hello.txt $(test_SOURCES) run_unit.sh diff --git a/loolwsd/test/run_test.sh.in b/loolwsd/test/run_test.sh.in deleted file mode 100755 index f7895c73f..000000000 --- a/loolwsd/test/run_test.sh.in +++ /dev/null @@ -1,50 +0,0 @@ -#!/bin/sh -# -# DO NOT EDIT - this file is generated from run_test.sh.in. -# - -abs_top_builddir="@abs_top_builddir@" -test_build="${abs_top_builddir}/test" -test_output="$test_build/run_test.sh.trs" -test_log_output="$test_build/test_output" - -mkdir -p $test_log_output - -if test "z@ENABLE_DEBUG@" != "ztrue"; then - echo "" - echo "It is necessary to configure with --enable-debug for unit tests to pass" - echo "" - echo ":test-result: FAIL $tst" > $test_output - exit 1; -fi - -echo "Running cppunit test ..."; - -# result logging -echo > $test_output - -${abs_top_builddir}/loolwsd --systemplate="@SYSTEMPLATE_PATH@" --lotemplate="@LO_PATH@" \ - --childroot="@JAILS_PATH@" --allowlocalstorage 2>$test_log_output/run_test.log & - -echo " waiting for loolwsd to start" -sleep 1 # sad - need to add a wait to the start of test.cpp ... - -echo " executing test" - -cd $test_build -if ./test; then - echo "Test run_test.sh passed." - echo ":test-result: PASS run_test.sh" >> $test_output - retval=0 -else - cat $test_log_output/run_test.log - echo "=============================================================" - echo "Test failed on unit:" - echo "=============================================================" - echo ":test-result: FAIL run_test.sh" >> $test_output - retval=1 -fi - -kill $! - -exit $retval diff --git a/loolwsd/test/run_unit.sh.in b/loolwsd/test/run_unit.sh.in index 5491640b8..7a929e776 100755 --- a/loolwsd/test/run_unit.sh.in +++ b/loolwsd/test/run_unit.sh.in @@ -3,16 +3,34 @@ # DO NOT EDIT - this file is generated from run_unit.sh.in. # -export LOOL_LOGLEVEL=trace +# substituted variables in one place: +abs_top_builddir="/opt/libreoffice/online/loolwsd" +systemplate_path="@SYSTEMPLATE_PATH@" +enable_debug="@ENABLE_DEBUG@" +jails_path="@JAILS_PATH@" +lo_path="@LO_PATH@" -abs_top_builddir="@abs_top_builddir@" -test_build="${abs_top_builddir}/test" -test_output="$test_build/run_unit.sh.trs" -test_log_output="$test_build/test_output" +while test $# -gt 0; do + case $1 in + --test-name) tst=$2; shift;; + --log-file) tst_log=$2; shift;; + --trs-file) test_output=$2; shift;; + -*) ;; # ignore + esac + shift +done + +test_mode= +if test "z$tst" != "zrun_test.sh"; then + # drop .la suffix + tst=`echo $tst | sed s/\.la//`; +else + test_mode=old +fi -mkdir -p $test_log_output +# export LOOL_LOGLEVEL=trace -if test "z@ENABLE_DEBUG@" != "ztrue"; then +if test "z$enable_debug" != "ztrue"; then echo "" echo "It is necessary to configure with --enable-debug for unit tests to pass" echo "" @@ -21,25 +39,52 @@ if test "z@ENABLE_DEBUG@" != "ztrue"; then fi # result logging -echo > run_unit.sh.trs - -for tst in fonts timeout storage prefork; do - tst_log="test_output/$tst.log" - echo "Running test: $tst | $tst_log ..."; - if ${abs_top_builddir}/loolwsd --systemplate="@SYSTEMPLATE_PATH@" \ - --lotemplate="@LO_PATH@" \ - --childroot="@JAILS_PATH@" \ - --unitlib=".libs/unit-$tst.so" 2> "$tst_log"; then - echo "Test $tst passed." - echo ":test-result: PASS $tst" >> $test_output +echo > $test_output + +if test "z$test_mode" == "zold"; then + echo "executing external tests" + ${abs_top_builddir}/loolwsd --systemplate="$systemplate_path" \ + --lotemplate="$lo_path" \ + --childroot="$jails_path" \ + --allowlocalstorage 2> "$tst_log" & + + echo " waiting for loolwsd to start" + sleep 1 # sad - need to add a wait to the start of test.cpp ... + echo " executing test" + + oldpath=`pwd` + cd "${abs_top_builddir}/test" + if ./test; then + echo "Test run_test.sh passed." + echo ":test-result: PASS run_test.sh" >> $oldpath/$test_output + retval=0 + else + echo "=============================================================" + echo "Test failed on unit:" + echo "=============================================================" + echo ":test-result: FAIL run_test.sh" >> $oldpath/$test_output + retval=1 + fi + + kill $! + + exit $retval + +else # newer unit tests. + echo "Running $tst | $tst_log ..."; + if ${abs_top_builddir}/loolwsd --systemplate="$systemplate_path" \ + --lotemplate="$lo_path" \ + --childroot="$jails_path" \ + --unitlib=".libs/$tst.so" 2> "$tst_log"; then + echo "Test $tst passed." + echo ":test-result: PASS $tst" >> $test_output else - cat "$tst_log" - echo "=============================================================" - echo "Test failed on unit: $tst re-run with:" - echo " $ gdb --args ../loolwsd --systemplate=\"@SYSTEMPLATE_PATH@\" --lotemplate=\"@LO_PATH@\" \\" - echo " --childroot=\"@JAILS_PATH@\" --unitlib=\".libs/unit-$tst.so\"" + cat "$tst_log" echo "=============================================================" + echo "Test failed on unit: $tst re-run with:" + echo " $ gdb --args ../loolwsd --systemplate=\"$systemplate_path\" --lotemplate=\"$lo_path\" \\" + echo " --childroot=\"$jails_path\" --unitlib=\".libs/$tst.so\"" + echo "=============================================================" echo ":test-result: FAIL $tst" >> $test_output fi -done - +fi commit ebfa339da02337274d332763b0e1ace952550f2a Author: Michael Meeks <michael.me...@collabora.com> AuthorDate: Fri Apr 15 16:16:36 2016 +0100 Commit: Michael Meeks <michael.me...@collabora.com> CommitDate: Fri Apr 15 16:17:04 2016 +0100 Cleanup symlinking and add realpath symlink if necessary. diff --git a/loolwsd/LOOLKit.cpp b/loolwsd/LOOLKit.cpp index 18b0da2e9..7f55ec966 100644 --- a/loolwsd/LOOLKit.cpp +++ b/loolwsd/LOOLKit.cpp @@ -16,6 +16,9 @@ #include <sys/capability.h> #include <unistd.h> #include <utime.h> +#include <limits.h> +#include <stdlib.h> +#include <malloc.h> #include <atomic> #include <cassert> @@ -820,6 +823,27 @@ private: std::atomic_size_t _clientViews; }; +namespace { + void symlinkPathToJail(const Path jailPath, const std::string &loTemplate, + const std::string &loSubPath) + { + Path symlinkSource(jailPath, Path(loTemplate.substr(1))); + File(symlinkSource.parent()).createDirectories(); + + std::string symlinkTarget; + for (auto i = 0; i < Path(loTemplate).depth(); i++) + symlinkTarget += "../"; + symlinkTarget += loSubPath; + + Log::debug("symlink(\"" + symlinkTarget + "\",\"" + symlinkSource.toString() + "\")"); + if (symlink(symlinkTarget.c_str(), symlinkSource.toString().c_str()) == -1) + { + Log::syserror("symlink(\"" + symlinkTarget + "\",\"" + symlinkSource.toString() + "\") failed"); + throw Exception("symlink() failed"); + } + } +} + void lokit_main(const std::string& childRoot, const std::string& sysTemplate, const std::string& loTemplate, @@ -861,19 +885,15 @@ void lokit_main(const std::string& childRoot, // Create a symlink inside the jailPath so that the absolute pathname loTemplate, when // interpreted inside a chroot at jailPath, points to loSubPath (relative to the chroot). - Path symlinkSource(jailPath, Path(loTemplate.substr(1))); - File(symlinkSource.parent()).createDirectories(); - - std::string symlinkTarget; - for (auto i = 0; i < Path(loTemplate).depth(); i++) - symlinkTarget += "../"; - symlinkTarget += loSubPath; + symlinkPathToJail(jailPath, loTemplate, loSubPath); - Log::debug("symlink(\"" + symlinkTarget + "\",\"" + symlinkSource.toString() + "\")"); - if (symlink(symlinkTarget.c_str(), symlinkSource.toString().c_str()) == -1) + // Font paths can end up as realpaths so match that too. + char *resolved = realpath(loTemplate.c_str(), NULL); + if (resolved) { - Log::syserror("symlink(\"" + symlinkTarget + "\",\"" + symlinkSource.toString() + "\") failed"); - throw Exception("symlink() failed"); + if (strcmp(loTemplate.c_str(), resolved)) + symlinkPathToJail(jailPath, std::string(resolved), loSubPath); + free (resolved); } Path jailLOInstallation(jailPath, loSubPath); diff --git a/loolwsd/LOOLWSD.cpp b/loolwsd/LOOLWSD.cpp index 31ed0d2ce..db27edca1 100644 --- a/loolwsd/LOOLWSD.cpp +++ b/loolwsd/LOOLWSD.cpp @@ -479,6 +479,7 @@ private: response.setStatus(HTTPResponse::HTTP_NOT_FOUND); response.setContentLength(0); response.send(); + Log::info("file not found."); } } else diff --git a/loolwsd/loolwsd-systemplate-setup b/loolwsd/loolwsd-systemplate-setup index d6539e33d..27c760c9c 100755 --- a/loolwsd/loolwsd-systemplate-setup +++ b/loolwsd/loolwsd-systemplate-setup @@ -87,14 +87,6 @@ if [ -h usr/share/fonts/ghostscript ]; then cp -r -p /usr/share/ghostscript/fonts usr/share/ghostscript fi -# Our Libreoffice install often comes with pre-bundled fonts. -# we need to ensure that there is a link to these with the same -# path that fontconfig found. -mkdir -p ./lo -mkdir -p ./$INSTDIR -rmdir ./$INSTDIR -ln -s /lo $CHROOT/$INSTDIR - # Debugging only hackery to avoid confusion. if test "z$ENABLE_DEBUG" != "z" -a "z$HOME" != "z"; then echo "Copying development users's fonts into systemplate" commit b1aa059bc35bc6b770bb171fe83416ad415c0893 Author: Tor Lillqvist <t...@collabora.com> AuthorDate: Fri Apr 15 17:19:04 2016 +0300 Commit: Tor Lillqvist <t...@collabora.com> CommitDate: Fri Apr 15 17:19:04 2016 +0300 I don't have any ~/.fonts diff --git a/loolwsd/loolwsd-systemplate-setup b/loolwsd/loolwsd-systemplate-setup index 54a2df02d..d6539e33d 100755 --- a/loolwsd/loolwsd-systemplate-setup +++ b/loolwsd/loolwsd-systemplate-setup @@ -99,5 +99,7 @@ ln -s /lo $CHROOT/$INSTDIR if test "z$ENABLE_DEBUG" != "z" -a "z$HOME" != "z"; then echo "Copying development users's fonts into systemplate" mkdir -p $CHROOT/$HOME - cp -r -p -L $HOME/.fonts $CHROOT/$HOME + test -d $HOME/.fonts && cp -r -p -L $HOME/.fonts $CHROOT/$HOME fi + +exit 0 commit 947f8bcf138b3eaa01daa2787069528c03defe44 Author: Tor Lillqvist <t...@collabora.com> AuthorDate: Fri Apr 15 17:01:02 2016 +0300 Commit: Tor Lillqvist <t...@collabora.com> CommitDate: Fri Apr 15 17:13:47 2016 +0300 Test number of loolkit processes also before and after the HTTPPostTest suite diff --git a/loolwsd/test/countloolkits.hpp b/loolwsd/test/countloolkits.hpp new file mode 100644 index 000000000..1fb1ba5f6 --- /dev/null +++ b/loolwsd/test/countloolkits.hpp @@ -0,0 +1,17 @@ +/* -*- 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_COUNTLOOLKITPROCESSES_HPP +#define INCLUDED_COUNTLOOLKITPROCESSES_HPP + +extern int countLoolKitProcesses(); + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/loolwsd/test/httpposttest.cpp b/loolwsd/test/httpposttest.cpp index 525583058..f7eec5554 100644 --- a/loolwsd/test/httpposttest.cpp +++ b/loolwsd/test/httpposttest.cpp @@ -26,14 +26,28 @@ #include <Common.hpp> #include <Util.hpp> +#include "countloolkits.hpp" + /// Tests the HTTP POST API of loolwsd. The server has to be started manually before running this test. class HTTPPostTest : public CPPUNIT_NS::TestFixture { + static int _initialLoolKitCount; + CPPUNIT_TEST_SUITE(HTTPPostTest); + + // This should be the first test: + CPPUNIT_TEST(testCountHowManyLoolkits); + CPPUNIT_TEST(testConvertTo); + + // This should be the last test: + CPPUNIT_TEST(testNoExtraLoolKitsLeft); + CPPUNIT_TEST_SUITE_END(); + void testCountHowManyLoolkits(); void testConvertTo(); + void testNoExtraLoolKitsLeft(); #if ENABLE_SSL public: @@ -54,6 +68,14 @@ public: #endif }; +int HTTPPostTest::_initialLoolKitCount = 0; + +void HTTPPostTest::testCountHowManyLoolkits() +{ + _initialLoolKitCount = countLoolKitProcesses(); + CPPUNIT_ASSERT(_initialLoolKitCount > 0); +} + void HTTPPostTest::testConvertTo() { const auto srcPath = Util::getTempFilePath(TDOC, "hello.odt"); @@ -96,6 +118,13 @@ void HTTPPostTest::testConvertTo() CPPUNIT_ASSERT_EQUAL(expectedStream.str(), actualString); } +void HTTPPostTest::testNoExtraLoolKitsLeft() +{ + int countNow = countLoolKitProcesses(); + + CPPUNIT_ASSERT_EQUAL(_initialLoolKitCount, countNow); +} + CPPUNIT_TEST_SUITE_REGISTRATION(HTTPPostTest); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/loolwsd/test/httpwstest.cpp b/loolwsd/test/httpwstest.cpp index 2d8ef109a..91dfb79bf 100644 --- a/loolwsd/test/httpwstest.cpp +++ b/loolwsd/test/httpwstest.cpp @@ -36,6 +36,8 @@ #include <Util.hpp> #include <LOOLProtocol.hpp> +#include "countloolkits.hpp" + /// Tests the HTTP WebSocket API of loolwsd. The server has to be started manually before running this test. class HTTPWSTest : public CPPUNIT_NS::TestFixture { @@ -103,9 +105,6 @@ class HTTPWSTest : public CPPUNIT_NS::TestFixture connectLOKit(Poco::Net::HTTPRequest& request, Poco::Net::HTTPResponse& response); - static - int countLoolKitProcesses(); - public: HTTPWSTest() #if ENABLE_SSL @@ -942,10 +941,10 @@ void HTTPWSTest::getResponseMessage(Poco::Net::WebSocket& ws, const std::string& } } -int HTTPWSTest::countLoolKitProcesses() +int countLoolKitProcesses() { - // Give polls in the lool processes time to time out - Poco::Thread::sleep(POLL_TIMEOUT_MS*3); + // Give polls in the lool processes time to time out etc + Poco::Thread::sleep(POLL_TIMEOUT_MS*5); int result = 0; commit a49f642801ba54ba3dc0692439bdbb9c8cac985a Author: Michael Meeks <michael.me...@collabora.com> AuthorDate: Fri Apr 15 15:07:24 2016 +0100 Commit: Michael Meeks <michael.me...@collabora.com> CommitDate: Fri Apr 15 15:07:24 2016 +0100 Tolerate --version, and add git hash version, print on default start. Should help diagnosing issues - to have this in our logs. diff --git a/loolwsd/LOOLForKit.cpp b/loolwsd/LOOLForKit.cpp index 256a2c3d1..ffebf5652 100644 --- a/loolwsd/LOOLForKit.cpp +++ b/loolwsd/LOOLForKit.cpp @@ -202,6 +202,10 @@ int main(int argc, char** argv) eq = std::strchr(cmd, '='); ClientPortNumber = std::stoll(std::string(eq+1)); } + else if (std::strstr(cmd, "--version") == cmd) + { + Util::displayVersionInfo("loolforkit"); + } #if ENABLE_DEBUG // this process has various privileges - don't run arbitrary code. else if (std::strstr(cmd, "--unitlib=") == cmd) diff --git a/loolwsd/LOOLWSD.cpp b/loolwsd/LOOLWSD.cpp index 9d14ca921..31ed0d2ce 100644 --- a/loolwsd/LOOLWSD.cpp +++ b/loolwsd/LOOLWSD.cpp @@ -146,6 +146,7 @@ int ClientPortNumber = DEFAULT_CLIENT_PORT_NUMBER; /// New LOK child processes ready to host documents. //TODO: Move to a more sensible namespace. +static bool DisplayVersion = false; static std::vector<std::shared_ptr<ChildProcess>> newChildren; static std::mutex newChildrenMutex; static std::condition_variable newChildrenCV; @@ -1233,10 +1234,7 @@ void LOOLWSD::handleOption(const std::string& optionName, std::exit(Application::EXIT_OK); } else if (optionName == "version") - { - displayVersion(); - std::exit(Application::EXIT_OK); - } + DisplayVersion = true; else if (optionName == "port") ClientPortNumber = std::stoi(value); else if (optionName == "cache") @@ -1274,11 +1272,6 @@ void LOOLWSD::displayHelp() helpFormatter.format(std::cout); } -void LOOLWSD::displayVersion() -{ - std::cout << LOOLWSD_VERSION << std::endl; -} - Process::PID LOOLWSD::createForKit() { Process::Args args; @@ -1290,6 +1283,8 @@ Process::PID LOOLWSD::createForKit() args.push_back("--clientport=" + std::to_string(ClientPortNumber)); if (UnitWSD::get().hasKitHooks()) args.push_back("--unitlib=" + UnitTestLibrary); + if (DisplayVersion) + args.push_back("--version"); const std::string forKitPath = Path(Application::instance().commandPath()).parent().toString() + "loolforkit"; @@ -1305,6 +1300,9 @@ int LOOLWSD::main(const std::vector<std::string>& /*args*/) { Log::initialize("wsd"); + if (DisplayVersion) + Util::displayVersionInfo("loolwsd"); + if (geteuid() == 0) { Log::error("Don't run this as root"); diff --git a/loolwsd/LOOLWSD.hpp b/loolwsd/LOOLWSD.hpp index ae290e490..556283774 100644 --- a/loolwsd/LOOLWSD.hpp +++ b/loolwsd/LOOLWSD.hpp @@ -65,7 +65,6 @@ protected: private: void initializeSSL(); void displayHelp(); - void displayVersion(); Poco::Process::PID createForKit(); /// Reads and processes path entries with the given property diff --git a/loolwsd/Util.cpp b/loolwsd/Util.cpp index 32b90720c..895217984 100644 --- a/loolwsd/Util.cpp +++ b/loolwsd/Util.cpp @@ -7,6 +7,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "config.h" + #include <execinfo.h> #include <sys/poll.h> #include <sys/prctl.h> @@ -15,6 +17,7 @@ #include <cassert> #include <cstdlib> #include <cstring> +#include <iostream> #include <iomanip> #include <mutex> #include <random> @@ -448,6 +451,13 @@ namespace Util if (prctl(PR_SET_NAME, reinterpret_cast<unsigned long>(s.c_str()), 0, 0, 0) != 0) Log::syserror("Cannot set thread name to " + s + "."); } + + void displayVersionInfo(const char *app) + { + std::string hash(LOOLWSD_VERSION_HASH); + hash.resize(std::min(8, (int)hash.length())); + std::cout << app << " " << LOOLWSD_VERSION << " - " << hash << std::endl; + } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/loolwsd/Util.hpp b/loolwsd/Util.hpp index 46b973be2..223d0fb4a 100644 --- a/loolwsd/Util.hpp +++ b/loolwsd/Util.hpp @@ -114,6 +114,9 @@ namespace Util /// Ensure that we have the correct UID unless in debug mode. bool hasCorrectUID(); + + /// Display version information + void displayVersionInfo(const char *app); }; #endif diff --git a/loolwsd/configure.ac b/loolwsd/configure.ac index 90a1a46fd..48b253919 100644 --- a/loolwsd/configure.ac +++ b/loolwsd/configure.ac @@ -22,6 +22,15 @@ AC_SUBST([LOOLWSD_VERSION]) AC_DEFINE_UNQUOTED([LOOLWSD_VERSION],[["$LOOLWSD_VERSION"]],[LibreOffice On-Line WebSocket server version]) +# try to add a git hash for a version if we're developing +LOOLWSD_VERSION_HASH=package +git_hash=`cd ${ac_srcdir} && git log -1 --format=%H 2> /dev/null` +if test "z$git_hash" != "z"; then + LOOLWSD_VERSION_HASH=$git_hash +fi + +AC_DEFINE_UNQUOTED([LOOLWSD_VERSION_HASH],[["$LOOLWSD_VERSION_HASH"]],[LibreOffice On-Line git hash if present]) + AC_CONFIG_SRCDIR([LOOLWSD.cpp]) AC_CONFIG_HEADERS([config.h]) @@ -260,3 +269,4 @@ echo " \$ make run # to start loolwsd fi dnl vim:set shiftwidth=4 softtabstop=4 expandtab: + diff --git a/loolwsd/loolwsd.service b/loolwsd/loolwsd.service index fdc32c5ec..13107c128 100644 --- a/loolwsd/loolwsd.service +++ b/loolwsd/loolwsd.service @@ -4,7 +4,7 @@ After=network.target [Service] EnvironmentFile=-/etc/sysconfig/loolwsd -ExecStart=/usr/bin/loolwsd --systemplate=/opt/lool/systemplate --lotemplate=/opt/collaboraoffice5.0 --childroot=/opt/lool/child-roots --numprespawns=5 --fileserverroot=/usr/share/loolwsd +ExecStart=/usr/bin/loolwsd --version --systemplate=/opt/lool/systemplate --lotemplate=/opt/collaboraoffice5.0 --childroot=/opt/lool/child-roots --numprespawns=5 --fileserverroot=/usr/share/loolwsd User=lool KillMode=control-group Restart=always diff --git a/loolwsd/test/run_test.sh.in b/loolwsd/test/run_test.sh.in index c52034e4d..f7895c73f 100755 --- a/loolwsd/test/run_test.sh.in +++ b/loolwsd/test/run_test.sh.in @@ -18,16 +18,19 @@ if test "z@ENABLE_DEBUG@" != "ztrue"; then exit 1; fi +echo "Running cppunit test ..."; + # result logging echo > $test_output -echo "Running cppunit test ..."; - ${abs_top_builddir}/loolwsd --systemplate="@SYSTEMPLATE_PATH@" --lotemplate="@LO_PATH@" \ --childroot="@JAILS_PATH@" --allowlocalstorage 2>$test_log_output/run_test.log & +echo " waiting for loolwsd to start" sleep 1 # sad - need to add a wait to the start of test.cpp ... +echo " executing test" + cd $test_build if ./test; then echo "Test run_test.sh passed." commit 7376b7475e0363c766058c6d4bcc29fac12dc2ac Author: Michael Meeks <michael.me...@collabora.com> AuthorDate: Fri Apr 15 14:34:23 2016 +0100 Commit: Michael Meeks <michael.me...@collabora.com> CommitDate: Fri Apr 15 14:35:57 2016 +0100 Font bits: create symlink in jail at OS instdir path, to point at /lo This ensures that bundled fonts in instdir/share end up resolved to the same path that they were in when the forkit font config was setup. It may also help locate other pre-inited resources. Also copy in ~/.fonts in debug mode - can't hurt. diff --git a/loolwsd/LOOLKit.cpp b/loolwsd/LOOLKit.cpp index 7f63ace06..18b0da2e9 100644 --- a/loolwsd/LOOLKit.cpp +++ b/loolwsd/LOOLKit.cpp @@ -117,6 +117,7 @@ namespace switch (typeflag) { case FTW_F: + case FTW_SLN: File(newPath.parent()).createDirectories(); if (link(fpath, newPath.toString().c_str()) == -1) { @@ -155,9 +156,6 @@ namespace case FTW_NS: Log::error("nftw: stat failed for '" + std::string(fpath) + "'"); return 1; - case FTW_SLN: - Log::error("nftw: symlink to nonexistent file: '" + std::string(fpath) + "', ignored."); - break; default: Log::error("nftw: unexpected type: '" + std::to_string(typeflag)); assert(false); diff --git a/loolwsd/Makefile.am b/loolwsd/Makefile.am index abf73a34d..e3c5f7a88 100644 --- a/loolwsd/Makefile.am +++ b/loolwsd/Makefile.am @@ -131,7 +131,7 @@ clean-local: if test "z@JAILS_PATH@" != "z"; then rm -rf "@JAILS_PATH@"; fi if test "z@SYSTEMPLATE_PATH@" != "z"; then rm -rf "@SYSTEMPLATE_PATH@"; fi -run: @JAILS_PATH@ @SYSTEMPLATE_PATH@/system_stamp +run: all @JAILS_PATH@ @SYSTEMPLATE_PATH@/system_stamp @echo "Launching loolwsd - launch this in your browser:" @cp $(abs_top_srcdir)/test/data/hello.odt $(abs_top_srcdir)/test/data/hello-world.odt @PROTOCOL="http" ; if test "z@ENABLE_SSL@" != "z"; then PROTOCOL="https" ; fi ; \ diff --git a/loolwsd/loolwsd-systemplate-setup b/loolwsd/loolwsd-systemplate-setup index 4e6ee2427..54a2df02d 100755 --- a/loolwsd/loolwsd-systemplate-setup +++ b/loolwsd/loolwsd-systemplate-setup @@ -88,12 +88,14 @@ if [ -h usr/share/fonts/ghostscript ]; then fi # Our Libreoffice install often comes with pre-bundled fonts. -mkdir -p $CHROOT/$INSTDIR/share -cp -r -p -L $INSTDIR/share/fonts $CHROOT/$INSTDIR/share/ - -# -# A debugging hackery to avoid confusion. -# +# we need to ensure that there is a link to these with the same +# path that fontconfig found. +mkdir -p ./lo +mkdir -p ./$INSTDIR +rmdir ./$INSTDIR +ln -s /lo $CHROOT/$INSTDIR + +# Debugging only hackery to avoid confusion. if test "z$ENABLE_DEBUG" != "z" -a "z$HOME" != "z"; then echo "Copying development users's fonts into systemplate" mkdir -p $CHROOT/$HOME commit ab6cc4135bd734d091419e5fe610fef7745fd596 Author: Michael Meeks <michael.me...@collabora.com> AuthorDate: Fri Apr 15 14:23:44 2016 +0100 Commit: Michael Meeks <michael.me...@collabora.com> CommitDate: Fri Apr 15 14:23:44 2016 +0100 Copy fonts into systemplate from libreoffice install. diff --git a/loolwsd/Makefile.am b/loolwsd/Makefile.am index a81842be0..abf73a34d 100644 --- a/loolwsd/Makefile.am +++ b/loolwsd/Makefile.am @@ -1,5 +1,7 @@ SUBDIRS = . test +export ENABLE_DEBUG + bin_PROGRAMS = loolwsd loolforkit loolmap loolmount looltool dist_bin_SCRIPTS = loolwsd-systemplate-setup @@ -118,7 +120,7 @@ if HAVE_LO_PATH SYSTEM_STAMP = @SYSTEMPLATE_PATH@/system_stamp -$(SYSTEM_STAMP) : +$(SYSTEM_STAMP) : ${top_srcdir}/loolwsd-systemplate-setup if test "z@SYSTEMPLATE_PATH@" != "z"; then rm -rf "@SYSTEMPLATE_PATH@"; fi ${top_srcdir}/loolwsd-systemplate-setup "@SYSTEMPLATE_PATH@" "@LO_PATH@" && touch $@ diff --git a/loolwsd/configure.ac b/loolwsd/configure.ac index a5cdd3a83..90a1a46fd 100644 --- a/loolwsd/configure.ac +++ b/loolwsd/configure.ac @@ -84,9 +84,7 @@ debug_msg="secure mode: product build" if test "$enable_debug" = "yes"; then AC_DEFINE([ENABLE_DEBUG],1,[Whether to compile in some extra debugging support code and disable some security pieces]) ENABLE_DEBUG=true - if test "$enable_debug" = yes; then - debug_msg="low security debugging mode" - fi + debug_msg="low security debugging mode" else AC_DEFINE([ENABLE_DEBUG],0,[Whether to compile in some extra debugging support code and disable some security pieces]) fi diff --git a/loolwsd/loolwsd-systemplate-setup b/loolwsd/loolwsd-systemplate-setup index 87af9e0f9..4e6ee2427 100755 --- a/loolwsd/loolwsd-systemplate-setup +++ b/loolwsd/loolwsd-systemplate-setup @@ -74,7 +74,7 @@ mkdir -p $CHROOT/tmp mkdir -p $CHROOT/usr/bin/ # /usr/share/fonts needs to be taken care of separately because the -# directory time stamps must be preserved are for fontconfig to trust +# directory time stamps must be preserved for fontconfig to trust # its cache. cd $CHROOT || exit 1 @@ -86,3 +86,16 @@ if [ -h usr/share/fonts/ghostscript ]; then mkdir usr/share/ghostscript || exit 1 cp -r -p /usr/share/ghostscript/fonts usr/share/ghostscript fi + +# Our Libreoffice install often comes with pre-bundled fonts. +mkdir -p $CHROOT/$INSTDIR/share +cp -r -p -L $INSTDIR/share/fonts $CHROOT/$INSTDIR/share/ + +# +# A debugging hackery to avoid confusion. +# +if test "z$ENABLE_DEBUG" != "z" -a "z$HOME" != "z"; then + echo "Copying development users's fonts into systemplate" + mkdir -p $CHROOT/$HOME + cp -r -p -L $HOME/.fonts $CHROOT/$HOME +fi commit b5e37448a8e3a8af54b9fd1f602542b84a0fd1a5 Author: Michael Meeks <michael.me...@collabora.com> AuthorDate: Fri Apr 15 13:55:34 2016 +0100 Commit: Michael Meeks <michael.me...@collabora.com> CommitDate: Fri Apr 15 13:55:34 2016 +0100 looltool: get argument array copyies right. diff --git a/loolwsd/LOOLTool.cpp b/loolwsd/LOOLTool.cpp index e2d8b4ffc..ffde699c0 100644 --- a/loolwsd/LOOLTool.cpp +++ b/loolwsd/LOOLTool.cpp @@ -239,7 +239,7 @@ int Tool::main(const std::vector<std::string>& args) if (toCopy > 0) { std::vector< std::string > files( toCopy ); - std::copy( args.begin() + offset, args.begin() + offset + chunk, files.begin() ); + std::copy( args.begin() + offset, args.begin() + offset + toCopy, files.begin() ); offset += toCopy; clients[i]->start(*(new Worker(*this, files))); } commit 7df929cb7762e8d596d30ae7f28bec5302cdd1dd Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> AuthorDate: Thu Apr 14 23:12:25 2016 -0400 Commit: Ashod Nakashian <ashnak...@gmail.com> CommitDate: Fri Apr 15 11:54:30 2016 +0000 loolwsd: use SocketProcessor in kit SocketProcessor doesn't need to take response instance, since by the time it is called we are already upgraded to WebSocket and it's too late to set a request-level status. Change-Id: Id95087e60354a50148c88427130613356679cf82 Reviewed-on: https://gerrit.libreoffice.org/24110 Reviewed-by: Ashod Nakashian <ashnak...@gmail.com> Tested-by: Ashod Nakashian <ashnak...@gmail.com> diff --git a/loolwsd/IoUtil.cpp b/loolwsd/IoUtil.cpp index 081e13e41..f024055b6 100644 --- a/loolwsd/IoUtil.cpp +++ b/loolwsd/IoUtil.cpp @@ -18,7 +18,6 @@ #include <string> #include <Poco/StringTokenizer.h> -#include <Poco/Net/HTTPServerResponse.h> #include <Poco/Net/Socket.h> #include <Poco/Net/WebSocket.h> #include <Poco/Net/NetException.h> @@ -41,7 +40,6 @@ namespace IoUtil // Synchronously process WebSocket requests and dispatch to handler. // Handler returns false to end. void SocketProcessor(std::shared_ptr<WebSocket> ws, - Poco::Net::HTTPResponse& response, std::function<bool(const std::vector<char>&)> handler, std::function<bool()> stopPredicate) { @@ -168,22 +166,6 @@ void SocketProcessor(std::shared_ptr<WebSocket> ws, " bytes) will not be processed: [" + msg + "]."); } } - catch (const WebSocketException& exc) - { - Log::error("SocketProcessor: WebSocketException: " + exc.message()); - switch (exc.code()) - { - case WebSocket::WS_ERR_HANDSHAKE_UNSUPPORTED_VERSION: - response.set("Sec-WebSocket-Version", WebSocket::WEBSOCKET_VERSION); - // fallthrough - case WebSocket::WS_ERR_NO_HANDSHAKE: - case WebSocket::WS_ERR_HANDSHAKE_NO_VERSION: - case WebSocket::WS_ERR_HANDSHAKE_NO_KEY: - response.setStatusAndReason(Poco::Net::HTTPResponse::HTTP_BAD_REQUEST); - response.setContentLength(0); - break; - } - } catch (const Poco::Exception& exc) { Log::error("SocketProcessor: Exception: " + exc.message()); diff --git a/loolwsd/IoUtil.hpp b/loolwsd/IoUtil.hpp index 10078bb59..a9ed2ef9f 100644 --- a/loolwsd/IoUtil.hpp +++ b/loolwsd/IoUtil.hpp @@ -24,7 +24,6 @@ namespace IoUtil /// Synchronously process WebSocket requests and dispatch to handler. //. Handler returns false to end. void SocketProcessor(std::shared_ptr<Poco::Net::WebSocket> ws, - Poco::Net::HTTPResponse& response, std::function<bool(const std::vector<char>&)> handler, std::function<bool()> stopPredicate); diff --git a/loolwsd/LOOLKit.cpp b/loolwsd/LOOLKit.cpp index ce32008f7..7f63ace06 100644 --- a/loolwsd/LOOLKit.cpp +++ b/loolwsd/LOOLKit.cpp @@ -266,18 +266,6 @@ public: } } - void handle(std::shared_ptr<TileQueue> queue, const std::string& firstLine, char* buffer, int n) - { - if (firstLine.find("paste") != 0) - { - // Everything else is expected to be a single line. - assert(firstLine.size() == static_cast<std::string::size_type>(n)); - queue->put(firstLine); - } - else - queue->put(std::string(buffer, n)); - } - void run() override { Util::setThreadName("kit_ws_" + _session->getId()); @@ -292,38 +280,13 @@ public: Thread queueHandlerThread; queueHandlerThread.start(handler); - int flags; - int n; - do - { - char buffer[1024]; - n = _ws->receiveFrame(buffer, sizeof(buffer), flags); - if (n > 0 && (flags & WebSocket::FRAME_OP_BITMASK) != WebSocket::FRAME_OP_CLOSE) + IoUtil::SocketProcessor(_ws, + [&queue](const std::vector<char>& payload) { - std::string firstLine = getFirstLine(buffer, n); - StringTokenizer tokens(firstLine, " ", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM); - - // Check if it is a "nextmessage:" and in that case read the large - // follow-up message separately, and handle that only. - int size; - if (tokens.count() == 2 && tokens[0] == "nextmessage:" && getTokenInteger(tokens[1], "size", size) && size > 0) - { - char largeBuffer[size]; - n = _ws->receiveFrame(largeBuffer, size, flags); - if (n > 0 && (flags & WebSocket::FRAME_OP_BITMASK) != WebSocket::FRAME_OP_CLOSE) - { - firstLine = getFirstLine(largeBuffer, n); - handle(queue, firstLine, largeBuffer, n); - } - } - else - handle(queue, firstLine, buffer, n); - } - } - while (!_stop && n > 0 && (flags & WebSocket::FRAME_OP_BITMASK) != WebSocket::FRAME_OP_CLOSE); - Log::debug() << "Finishing. stop " << _stop - << ", payload size: " << n - << ", flags: " << std::hex << flags << Log::end; + queue->put(payload); + return true; + }, + []() { return TerminationFlag; }); queue->clear(); queue->put("eof"); @@ -1006,8 +969,8 @@ void lokit_main(const std::string& childRoot, ws->setReceiveTimeout(0); const std::string socketName = "ChildControllerWS"; - IoUtil::SocketProcessor(ws, response, - [&socketName, &ws, &document, &loKit](const std::vector<char>& data) + IoUtil::SocketProcessor(ws, + [&socketName, &ws, &document, &loKit](const std::vector<char>& data) { std::string message(data.data(), data.size()); diff --git a/loolwsd/LOOLWSD.cpp b/loolwsd/LOOLWSD.cpp index cbf3cce62..9d14ca921 100644 --- a/loolwsd/LOOLWSD.cpp +++ b/loolwsd/LOOLWSD.cpp @@ -590,8 +590,8 @@ private: Thread queueHandlerThread; queueHandlerThread.start(handler); - IoUtil::SocketProcessor(ws, response, - [&session, &queue](const std::vector<char>& payload) + IoUtil::SocketProcessor(ws, + [&queue](const std::vector<char>& payload) { queue->put(payload); return true; @@ -896,7 +896,7 @@ public: // Now the bridge beetween the prison and the client is connected // Let messages flow - IoUtil::SocketProcessor(ws, response, + IoUtil::SocketProcessor(ws, [&session](const std::vector<char>& payload) { return session->handleInput(payload.data(), payload.size()); commit df47ff1b2f475ea430cd214ecf23372f3d750102 Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> AuthorDate: Thu Apr 14 23:11:39 2016 -0400 Commit: Ashod Nakashian <ashnak...@gmail.com> CommitDate: Fri Apr 15 11:53:57 2016 +0000 loolwsd: .gitignore updated Change-Id: Ica74b3f6f2fd9e3f9d75f41f2f780010b9b9bc55 Reviewed-on: https://gerrit.libreoffice.org/24109 Reviewed-by: Ashod Nakashian <ashnak...@gmail.com> Tested-by: Ashod Nakashian <ashnak...@gmail.com> diff --git a/loolwsd/.gitignore b/loolwsd/.gitignore index ca7b0e883..9190e91a6 100644 --- a/loolwsd/.gitignore +++ b/loolwsd/.gitignore @@ -45,4 +45,4 @@ loolwsd loolforkit loolmount loolmap -loolmount +looltool commit cf85f51850fbb87c4bb7f7a7493cd4021986b9e5 Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> AuthorDate: Thu Apr 14 23:09:46 2016 -0400 Commit: Ashod Nakashian <ashnak...@gmail.com> CommitDate: Fri Apr 15 11:53:42 2016 +0000 loolwsd: tabs -> spaces Change-Id: I581346970321446378ff135e0227e06a2092b39f Reviewed-on: https://gerrit.libreoffice.org/24108 Reviewed-by: Ashod Nakashian <ashnak...@gmail.com> Tested-by: Ashod Nakashian <ashnak...@gmail.com> diff --git a/loolwsd/Makefile.am b/loolwsd/Makefile.am index b11426b08..a81842be0 100644 --- a/loolwsd/Makefile.am +++ b/loolwsd/Makefile.am @@ -28,7 +28,7 @@ AM_CTAGSFLAGS = $(AM_ETAGSFLAGS) shared_sources = ChildProcessSession.cpp \ IoUtil.cpp \ - Log.cpp \ + Log.cpp \ LOOLProtocol.cpp \ LOOLSession.cpp \ MessageQueue.cpp \ @@ -84,7 +84,7 @@ noinst_HEADERS = Admin.hpp \ FileServer.hpp \ IoUtil.hpp \ LoadTest.hpp \ - Log.hpp \ + Log.hpp \ LOKitHelper.hpp \ LOOLKit.hpp \ LOOLProtocol.hpp \ commit 5782e0b04c628f2a04d54004bd90bf25a6ae2420 Author: Tor Lillqvist <t...@collabora.com> AuthorDate: Fri Apr 15 14:06:00 2016 +0300 Commit: Tor Lillqvist <t...@collabora.com> CommitDate: Fri Apr 15 14:12:35 2016 +0300 TileCache::lookupTile() already returns non-null only if the stream is open No need to test at call sites. We can assert() as a sanity check though. diff --git a/loolwsd/MasterProcessSession.cpp b/loolwsd/MasterProcessSession.cpp index 280e19c8c..63b32eb64 100644 --- a/loolwsd/MasterProcessSession.cpp +++ b/loolwsd/MasterProcessSession.cpp @@ -593,8 +593,9 @@ void MasterProcessSession::sendTile(const char *buffer, int length, StringTokeni std::memcpy(output.data(), response.data(), response.size()); std::unique_ptr<std::fstream> cachedTile = _docBroker->tileCache().lookupTile(part, width, height, tilePosX, tilePosY, tileWidth, tileHeight); - if (cachedTile && cachedTile->is_open()) + if (cachedTile) { + assert(cachedTile->is_open()); cachedTile->seekg(0, std::ios_base::end); size_t pos = output.size(); std::streamsize size = cachedTile->tellg(); @@ -674,8 +675,9 @@ void MasterProcessSession::sendCombinedTiles(const char* /*buffer*/, int /*lengt std::unique_ptr<std::fstream> cachedTile = _docBroker->tileCache().lookupTile(part, pixelWidth, pixelHeight, x, y, tileWidth, tileHeight); - if (cachedTile && cachedTile->is_open()) + if (cachedTile) { + assert(cachedTile->is_open()); std::ostringstream oss; oss << "tile: part=" << part << " width=" << pixelWidth commit ecaaab6e9085737d06842e1ddfaf0de3a884b066 Author: Tor Lillqvist <t...@collabora.com> AuthorDate: Fri Apr 15 13:17:16 2016 +0300 Commit: Tor Lillqvist <t...@collabora.com> CommitDate: Fri Apr 15 13:17:20 2016 +0300 Default values for bool parameters make the code harder to read In this case we always passed the parameter anyway. diff --git a/loolwsd/TileCache.hpp b/loolwsd/TileCache.hpp index 70beabc5a..d656da356 100644 --- a/loolwsd/TileCache.hpp +++ b/loolwsd/TileCache.hpp @@ -47,7 +47,7 @@ public: void documentSaved(); /// Notify whether we need to use the Editing cache. - void setEditing(bool editing = true); + void setEditing(bool editing); // The parameter is a message void saveTextFile(const std::string& text, std::string fileName); commit cca858732a733cd7f43850b971e02ff7d462ae42 Author: Pranav Kant <pran...@collabora.com> AuthorDate: Fri Apr 15 15:24:02 2016 +0530 Commit: Pranav Kant <pran...@collabora.com> CommitDate: Fri Apr 15 15:25:01 2016 +0530 loolwsd: Allow admin console to kill documents (again) Change-Id: I30405854e9ebdc56ab3477758e9008963d4b8efa diff --git a/loolwsd/Admin.cpp b/loolwsd/Admin.cpp index 3feec3382..d5d4557e9 100644 --- a/loolwsd/Admin.cpp +++ b/loolwsd/Admin.cpp @@ -186,14 +186,15 @@ void AdminRequestHandler::handleWSRequests(HTTPServerRequest& request, HTTPServe { try { - if (std::stoi(tokens[1])) + const auto pid = std::stoi(tokens[1]); + if (kill(pid, SIGINT) != 0 && kill(pid, 0) !=0) { - LOOLWSD::killKit(std::stoi(tokens[1])); + Log::syserror("Cannot terminate PID: " + tokens[0]); } } - catch(std::exception& e) + catch(std::invalid_argument& exc) { - Log::warn() << "Could not kill given PID" << Log::end; + Log::warn() << "Invalid PID to kill: " << tokens[0] << Log::end; } } else if (tokens[0] == "mem_stats") diff --git a/loolwsd/LOOLWSD.cpp b/loolwsd/LOOLWSD.cpp index 5d2ca8c80..cbf3cce62 100644 --- a/loolwsd/LOOLWSD.cpp +++ b/loolwsd/LOOLWSD.cpp @@ -1301,12 +1301,6 @@ Process::PID LOOLWSD::createForKit() return child.id(); } -void LOOLWSD::killKit(const Process::PID /*pid*/) -{ - std::unique_lock<std::mutex> docBrokersLock(docBrokersMutex); - // TODO -} - int LOOLWSD::main(const std::vector<std::string>& /*args*/) { Log::initialize("wsd"); diff --git a/loolwsd/LOOLWSD.hpp b/loolwsd/LOOLWSD.hpp index 33c8c9783..ae290e490 100644 --- a/loolwsd/LOOLWSD.hpp +++ b/loolwsd/LOOLWSD.hpp @@ -55,9 +55,6 @@ public: return Util::encodeId(++NextSessionId, 4); } - static - void killKit(const Poco::Process::PID pid); - protected: void initialize(Poco::Util::Application& self) override; void uninitialize() override; commit 6ca6bf0da68957b143d32c6d02a020830e7b5d76 Author: Tor Lillqvist <t...@collabora.com> AuthorDate: Fri Apr 15 12:26:56 2016 +0300 Commit: Tor Lillqvist <t...@collabora.com> CommitDate: Fri Apr 15 12:26:56 2016 +0300 Rant about over-use of variables where literals would work diff --git a/loolwsd/PROBLEMS b/loolwsd/PROBLEMS index 6f72e284c..687fae981 100644 --- a/loolwsd/PROBLEMS +++ b/loolwsd/PROBLEMS @@ -23,4 +23,11 @@ to kill it with SIGKILL. Which of course leaves all the chroot jails around. +- There are lots of places where a std::string variable is defined, + initialised with a value, that is never changed. (In many cases it + is const, so could of course not be changed.) Then the variable is + used just once or twice, passed as a parameter to a function, or + used in a comparisin expression. This is fairly pointless and just + makes the code harder to read. Use string literals instead. + - ASCII art? Seriously? commit 382da839e0fd41549ed06347c0e19faddb9b5400 Author: Pranav Kant <pran...@collabora.com> AuthorDate: Fri Apr 15 14:48:58 2016 +0530 Commit: Pranav Kant <pran...@collabora.com> CommitDate: Fri Apr 15 14:48:58 2016 +0530 Add documentation about takeedit Change-Id: I600046111d2478f1c02552d3caa60d2a50fa7c98 diff --git a/loolwsd/protocol.txt b/loolwsd/protocol.txt index a7e36c6c4..f6e1f523c 100644 --- a/loolwsd/protocol.txt +++ b/loolwsd/protocol.txt @@ -135,6 +135,13 @@ clientvisiblearea x=<x> y=<y> width=<width> height=<height> Invokes lok::Document::setClientVisibleArea(). +takeedit + + Request for an edit lock. If successful, client will receive an 'editlock: 1' + message meaning editlock is granted. + + See 'editlock:' message in server -> client. + server -> client ================ commit 91c6154fc0900331dbe075207896ae9914ad4fb0 Author: Pranav Kant <pran...@collabora.com> AuthorDate: Fri Apr 15 14:30:22 2016 +0530 Commit: Pranav Kant <pran...@collabora.com> CommitDate: Fri Apr 15 14:42:14 2016 +0530 loolwsd: Use docKey as key for Admin instead of PID Also change some variable names to be consistent with rest of the coding style. Change-Id: Icca9a9aec9bfb34c1edd5b6533d7646b05fe814f diff --git a/loolwsd/Admin.cpp b/loolwsd/Admin.cpp index 1202e95d7..3feec3382 100644 --- a/loolwsd/Admin.cpp +++ b/loolwsd/Admin.cpp @@ -188,7 +188,7 @@ void AdminRequestHandler::handleWSRequests(HTTPServerRequest& request, HTTPServe { if (std::stoi(tokens[1])) { - IoUtil::writeFIFO(LOOLWSD::ForKitWritePipe, firstLine + "\n"); + LOOLWSD::killKit(std::stoi(tokens[1])); } } catch(std::exception& e) @@ -384,16 +384,16 @@ Admin::~Admin() _cpuStatsTask->cancel(); } -void Admin::addDoc(Poco::Process::PID pid, const std::string& filename, const int sessionId) +void Admin::addDoc(const std::string& docKey, Poco::Process::PID pid, const std::string& filename, const int sessionId) { std::unique_lock<std::mutex> modelLock(_modelMutex); - _model.addDocument(pid, filename, sessionId); + _model.addDocument(docKey, pid, filename, sessionId); } -void Admin::rmDoc(Poco::Process::PID pid, const int sessionId) +void Admin::rmDoc(const std::string& docKey, const int sessionId) { std::unique_lock<std::mutex> modelLock(_modelMutex); - _model.removeDocument(pid, sessionId); + _model.removeDocument(docKey, sessionId); } void MemoryStats::run() diff --git a/loolwsd/Admin.hpp b/loolwsd/Admin.hpp index 9f4d838d8..a281ba5a7 100644 --- a/loolwsd/Admin.hpp +++ b/loolwsd/Admin.hpp @@ -54,12 +54,11 @@ public: void update(const std::string& message); /// Calls with same pid will increment view count, if pid already exists - void addDoc(Poco::Process::PID pid, const std::string& filename, const int sessionId); + void addDoc(const std::string& docKey, Poco::Process::PID pid, const std::string& filename, const int sessionId); /// Decrement view count till becomes zero after which doc is removed - void rmDoc(Poco::Process::PID pid, const int nSessionId); + void rmDoc(const std::string& docKey, const int nSessionId); - /// Set the forkit process id. void setForKitPid(const int forKitPid) { _forKitPid = forKitPid; } /// Callers must ensure that modelMutex is acquired diff --git a/loolwsd/AdminModel.cpp b/loolwsd/AdminModel.cpp index 3ff947753..fec35d95e 100644 --- a/loolwsd/AdminModel.cpp +++ b/loolwsd/AdminModel.cpp @@ -33,7 +33,7 @@ void Document::addView(int sessionId) } else { - _nActiveViews++; + _activeViews++; } } @@ -45,11 +45,11 @@ int Document::expireView(int sessionId) it->second.expire(); // If last view, expire the Document also - if (--_nActiveViews == 0) + if (--_activeViews == 0) _end = std::time(nullptr); } - return _nActiveViews; + return _activeViews; } /////////////////// @@ -243,9 +243,9 @@ void AdminModel::notify(const std::string& message) } } -void AdminModel::addDocument(Poco::Process::PID pid, const std::string& filename, const int sessionId) +void AdminModel::addDocument(const std::string& docKey, Poco::Process::PID pid, const std::string& filename, const int sessionId) { - const auto ret = _documents.emplace(pid, Document(pid, filename)); + const auto ret = _documents.emplace(docKey, Document(docKey, pid, filename)); ret.first->second.addView(sessionId); // Notify the subscribers @@ -260,15 +260,15 @@ void AdminModel::addDocument(Poco::Process::PID pid, const std::string& filename notify(oss.str()); } -void AdminModel::removeDocument(Poco::Process::PID pid, const int sessionId) +void AdminModel::removeDocument(const std::string& docKey, const int sessionId) { - auto docIt = _documents.find(pid); + auto docIt = _documents.find(docKey); if (docIt != _documents.end() && !docIt->second.isExpired()) { // Notify the subscribers std::ostringstream oss; oss << "rmdoc" << " " - << pid << " " + << docIt->second.getPid() << " " << sessionId; Log::info("Message to admin console: " + oss.str()); notify(oss.str()); diff --git a/loolwsd/AdminModel.hpp b/loolwsd/AdminModel.hpp index 843320df8..806fb5cbe 100644 --- a/loolwsd/AdminModel.hpp +++ b/loolwsd/AdminModel.hpp @@ -23,7 +23,7 @@ class View { public: View(int sessionId) - : _nSessionId(sessionId), + : _sessionId(sessionId), _start(std::time(nullptr)) { } @@ -32,7 +32,7 @@ public: bool isExpired() { return _end != 0 && std::time(nullptr) >= _end; } private: - int _nSessionId; + int _sessionId; std::time_t _start; std::time_t _end = 0; @@ -41,22 +41,23 @@ private: class Document { public: - Document(Poco::Process::PID pid, std::string filename) - : _nPid(pid), - _sFilename(filename), + Document(std::string docKey, Poco::Process::PID pid, std::string filename) + : _docKey(docKey), + _pid(pid), + _filename(filename), _start(std::time(nullptr)) { - Log::info("Document " + std::to_string(_nPid) + " ctor."); + Log::info("Document " + _docKey + " ctor."); } ~Document() { - Log::info("Document " + std::to_string(_nPid) + " dtor."); + Log::info("Document " + _docKey + " dtor."); } - Poco::Process::PID getPid() const { return _nPid; } + Poco::Process::PID getPid() const { return _pid; } - std::string getFilename() const { return _sFilename; } + std::string getFilename() const { return _filename; } bool isExpired() const { return _end != 0 && std::time(nullptr) >= _end; } @@ -66,16 +67,17 @@ public: int expireView(int sessionId); - unsigned getActiveViews() const { return _nActiveViews; } + unsigned getActiveViews() const { return _activeViews; } private: - Poco::Process::PID _nPid; + const std::string _docKey; + const Poco::Process::PID _pid; /// SessionId mapping to View object std::map<int, View> _views; /// Total number of active views - unsigned _nActiveViews = 0; + unsigned _activeViews = 0; /// Hosted filename - std::string _sFilename; + std::string _filename; std::time_t _start; std::time_t _end = 0; @@ -85,7 +87,7 @@ class Subscriber { public: Subscriber(int sessionId, std::shared_ptr<Poco::Net::WebSocket>& ws) - : _nSessionId(sessionId), + : _sessionId(sessionId), _ws(ws), _start(std::time(nullptr)) { @@ -109,7 +111,7 @@ public: private: /// Admin session Id - int _nSessionId; + int _sessionId; /// WebSocket to use to send messages to session std::weak_ptr<Poco::Net::WebSocket> _ws; @@ -156,9 +158,9 @@ public: void notify(const std::string& message); - void addDocument(Poco::Process::PID pid, const std::string& filename, const int sessionId); + void addDocument(const std::string& docKey, Poco::Process::PID pid, const std::string& filename, const int sessionId); - void removeDocument(Poco::Process::PID pid, const int sessionId); + void removeDocument(const std::string& docKey, const int sessionId); private: @@ -172,7 +174,7 @@ private: private: std::map<int, Subscriber> _subscribers; - std::map<Poco::Process::PID, Document> _documents; + std::map<std::string, Document> _documents; std::list<unsigned> _memStats; unsigned _memStatsSize = 100; diff --git a/loolwsd/DocumentBroker.hpp b/loolwsd/DocumentBroker.hpp index 998ea91c8..599fb3f1a 100644 --- a/loolwsd/DocumentBroker.hpp +++ b/loolwsd/DocumentBroker.hpp @@ -172,6 +172,8 @@ public: unsigned getWSSessionsCount() { return _wsSessions.size(); } + void kill() { _childProcess->close(true); }; + private: const Poco::URI _uriPublic; const std::string _docKey; diff --git a/loolwsd/LOOLWSD.cpp b/loolwsd/LOOLWSD.cpp index 0cf254d0f..5d2ca8c80 100644 --- a/loolwsd/LOOLWSD.cpp +++ b/loolwsd/LOOLWSD.cpp @@ -805,10 +805,10 @@ public: std::string sessionId; std::string jailId; + std::string docKey; try { const auto params = Poco::URI(request.getURI()).getQueryParameters(); - std::string docKey; for (const auto& param : params) { if (param.first == "sessionId") @@ -875,16 +875,17 @@ public: const auto uri = request.getURI(); // Jail id should be the PID, beacuse Admin need it to calculate the memory + Poco::Process::PID pid; try { - Log::info("Adding doc " + jailId + " to Admin"); - Admin::instance().addDoc(std::stoi(jailId), docBroker->getFilename(), std::stoi(sessionId)); + pid = std::stoi(jailId); } catch (std::invalid_argument& exc) { assert(false); } - + Log::info("Adding doc " + docKey + " to Admin"); + Admin::instance().addDoc(docKey, pid, docBroker->getFilename(), Util::decodeId(sessionId)); if (waitBridgeCompleted(session)) { @@ -919,15 +920,8 @@ public: if (!jailId.empty()) { - try - { - Log::info("Removing doc " + jailId + " from Admin"); - Admin::instance().rmDoc(std::stoi(jailId), std::stoi(sessionId)); - } - catch (std::invalid_argument& exc) - { - assert(false); - } + Log::info("Removing doc " + docKey + " from Admin"); + Admin::instance().rmDoc(docKey, Util::decodeId(sessionId)); } Log::debug("Thread finished."); @@ -1307,6 +1301,12 @@ Process::PID LOOLWSD::createForKit() return child.id(); } +void LOOLWSD::killKit(const Process::PID /*pid*/) +{ + std::unique_lock<std::mutex> docBrokersLock(docBrokersMutex); + // TODO +} + int LOOLWSD::main(const std::vector<std::string>& /*args*/) { Log::initialize("wsd"); diff --git a/loolwsd/LOOLWSD.hpp b/loolwsd/LOOLWSD.hpp index ae290e490..33c8c9783 100644 --- a/loolwsd/LOOLWSD.hpp +++ b/loolwsd/LOOLWSD.hpp @@ -55,6 +55,9 @@ public: return Util::encodeId(++NextSessionId, 4); } + static + void killKit(const Poco::Process::PID pid); + protected: void initialize(Poco::Util::Application& self) override; void uninitialize() override; commit 61914208bce83fcb5f7c306a9959e4cab93344b8 Author: Pranav Kant <pran...@collabora.com> AuthorDate: Fri Apr 15 02:20:05 2016 +0530 Commit: Pranav Kant <pran...@collabora.com> CommitDate: Fri Apr 15 13:28:42 2016 +0530 loleaflet: Adapt to new changes in admin console Change-Id: I0761bd6c5b3650795a318a077eb50d0a8bd161da diff --git a/loleaflet/src/admin/AdminSocketOverview.js b/loleaflet/src/admin/AdminSocketOverview.js index 5bcb54eaf..a93041580 100644 --- a/loleaflet/src/admin/AdminSocketOverview.js +++ b/loleaflet/src/admin/AdminSocketOverview.js @@ -20,7 +20,7 @@ var AdminSocketOverview = AdminSocketBase.extend({ onSocketOpen: function() { this.socket.send('documents'); - this.socket.send('subscribe document addview rmview rmdoc'); + this.socket.send('subscribe adddoc rmdoc'); this._getBasicStats(); var socketOverview = this; @@ -78,9 +78,9 @@ var AdminSocketOverview = AdminSocketBase.extend({ var tableContainer = document.getElementById('doclist'); var rowContainer; - var pidEle, urlEle, viewsEle, memEle, sDocTimeEle, docEle; + var pidEle, nameEle, viewsEle, memEle, sDocTimeEle, docEle, aEle; var nViews, nTotalViews; - var docProps, sPid, sUrl, sViews, sMem, sDocTime; + var docProps, sPid, sName, sViews, sMem, sDocTime; if (textMsg.startsWith('documents')) { var documents = textMsg.substring('documents'.length); documents = documents.trim().split('\n'); @@ -90,11 +90,11 @@ var AdminSocketOverview = AdminSocketBase.extend({ } docProps = documents[i].trim().split(' '); sPid = docProps[0]; - sUrl = docProps[1]; + sName = docProps[1]; sViews = docProps[2]; sMem = docProps[3]; sDocTime = docProps[4]; - if (sUrl === '0') { + if (sName === '0') { continue; } rowContainer = document.createElement('tr'); @@ -105,9 +105,9 @@ var AdminSocketOverview = AdminSocketBase.extend({ pidEle.innerHTML = sPid; rowContainer.appendChild(pidEle); - urlEle = document.createElement('td'); - urlEle.innerHTML = sUrl; - rowContainer.appendChild(urlEle); + nameEle = document.createElement('td'); ... etc. - the rest is truncated _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits