loolwsd/Admin.cpp | 79 +------ loolwsd/Admin.hpp | 3 loolwsd/AdminModel.cpp | 2 loolwsd/Unit.hpp | 6 loolwsd/test/Makefile.am | 9 loolwsd/test/UnitAdmin.cpp | 451 ++++++++++++++++++++++++++++++++++++++++++++ loolwsd/test/run_unit.sh.in | 2 7 files changed, 486 insertions(+), 66 deletions(-)
New commits: commit 3e93a212f09e51577bb787093643a0d998b20b61 Author: Pranav Kant <pran...@collabora.com> Date: Mon Apr 18 18:59:17 2016 +0530 loolwsd: Admin console unit tests Change-Id: Id0baa51c2adb14b77080b5acd2abf0658ee54b2b diff --git a/loolwsd/Admin.cpp b/loolwsd/Admin.cpp index a350ba9..e246495 100644 --- a/loolwsd/Admin.cpp +++ b/loolwsd/Admin.cpp @@ -35,6 +35,7 @@ #include "LOOLProtocol.hpp" #include "LOOLWSD.hpp" #include "IoUtil.hpp" +#include "Unit.hpp" #include "Util.hpp" using namespace LOOLProtocol; @@ -272,6 +273,7 @@ AdminRequestHandler::AdminRequestHandler(Admin* adminManager) void AdminRequestHandler::sendTextFrame(std::shared_ptr<Poco::Net::WebSocket>& socket, const std::string& message) { + UnitWSD::get().onAdminQueryMessage(message); socket->sendFrame(message.data(), message.size()); } diff --git a/loolwsd/AdminModel.cpp b/loolwsd/AdminModel.cpp index ccc342f..d9f10a0 100644 --- a/loolwsd/AdminModel.cpp +++ b/loolwsd/AdminModel.cpp @@ -17,6 +17,7 @@ #include <Poco/StringTokenizer.h> #include "AdminModel.hpp" +#include "Unit.hpp" #include "Util.hpp" using Poco::StringTokenizer; @@ -65,6 +66,7 @@ bool Subscriber::notify(const std::string& message) auto webSocket = _ws.lock(); if (webSocket) { + UnitWSD::get().onAdminNotifyMessage(message); webSocket->sendFrame(message.data(), message.length()); return true; } diff --git a/loolwsd/Unit.hpp b/loolwsd/Unit.hpp index c9a7a6d..05d5696 100644 --- a/loolwsd/Unit.hpp +++ b/loolwsd/Unit.hpp @@ -14,6 +14,8 @@ #include <atomic> #include <assert.h> +#include <Poco/Net/WebSocket.h> + class UnitBase; class UnitWSD; class UnitKit; @@ -133,6 +135,10 @@ public: // ---------------- WSD events ---------------- virtual void onChildConnected(const int /* pid */, const std::string& /* sessionId */) {} + /// When admin notify message is sent + virtual void onAdminNotifyMessage(const std::string& /* message */) {} + /// When admin message is sent in response to a query + virtual void onAdminQueryMessage(const std::string& /* message */) {} }; /// Derive your Kit unit test / hooks from me. diff --git a/loolwsd/test/Makefile.am b/loolwsd/test/Makefile.am index 0a40ef3..98d3f3f 100644 --- a/loolwsd/test/Makefile.am +++ b/loolwsd/test/Makefile.am @@ -5,8 +5,9 @@ check_PROGRAMS = test AM_CXXFLAGS = $(CPPUNIT_CFLAGS) noinst_LTLIBRARIES = \ - unit-timeout.la unit-prefork.la \ - unit-storage.la unit-fonts.la + unit-timeout.la unit-prefork.la \ + unit-storage.la unit-fonts.la \ + unit-admin.la MAGIC_TO_FORCE_SHLIB_CREATION = -rpath /dummy AM_LDFLAGS = -module $(MAGIC_TO_FORCE_SHLIB_CREATION) @@ -17,6 +18,8 @@ test_SOURCES = WhiteBoxTests.cpp httpposttest.cpp httpwstest.cpp test.cpp ../LOO test_LDADD = $(CPPUNIT_LIBS) # unit test modules: +unit_admin_la_SOURCES = UnitAdmin.cpp +unit_admin_la_CPPFLAGS = -DTDOC=\"$(top_srcdir)/test/data\" unit_fonts_la_SOURCES = UnitFonts.cpp unit_timeout_la_SOURCES = UnitTimeout.cpp unit_prefork_la_SOURCES = UnitPrefork.cpp @@ -29,7 +32,7 @@ SYSTEM_STAMP = endif if HAVE_LO_PATH -TESTS = unit-timeout.la unit-fonts.la unit-storage.la unit-prefork.la run_test.sh +TESTS = unit-admin.la unit-timeout.la unit-fonts.la unit-storage.la unit-prefork.la run_test.sh else TESTS = ${top_builddir}/test/test endif diff --git a/loolwsd/test/UnitAdmin.cpp b/loolwsd/test/UnitAdmin.cpp new file mode 100644 index 0000000..e4b2bb6 --- /dev/null +++ b/loolwsd/test/UnitAdmin.cpp @@ -0,0 +1,451 @@ +/* -*- 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 "config.h" + +#include <cassert> +#include <condition_variable> +#include <mutex> + +#include "Common.hpp" +#include "Unit.hpp" +#include "Util.hpp" +#include "Log.hpp" + +#include <Poco/StringTokenizer.h> +#include <Poco/Net/HTTPBasicCredentials.h> +#include <Poco/Net/HTTPCookie.h> +#include <Poco/Net/HTTPResponse.h> +#include <Poco/Net/HTTPClientSession.h> +#include <Poco/Net/HTTPSClientSession.h> +#include <Poco/Net/HTTPServerRequest.h> +#include <Poco/Net/NameValueCollection.h> +#include <Poco/Net/NetException.h> +#include <Poco/Net/WebSocket.h> +#include <Poco/StringTokenizer.h> +#include <Poco/URI.h> + +#define UNIT_URI "/loolwsd/unit-admin" + +using Poco::Net::HTTPBasicCredentials; +using Poco::Net::HTTPCookie; +using Poco::Net::HTTPRequest; +using Poco::Net::HTTPResponse; +using Poco::Net::HTTPSClientSession; +using Poco::StringTokenizer; + +// Inside the WSD process +class UnitAdmin : public UnitWSD +{ +private: + unsigned _testCounter = 0; + std::string _jwtCookie; + bool _isTestRunning = false; + const Poco::URI _uri; + std::shared_ptr<Poco::Net::WebSocket> _adminWs; + + typedef TestResult (UnitAdmin::*AdminTest)(void); + std::vector<AdminTest> _tests; + + std::shared_ptr<Poco::Net::WebSocket> _docWs1; + std::shared_ptr<Poco::Net::WebSocket> _docWs2; + std::shared_ptr<Poco::Net::WebSocket> _docWs3; + int _docPid1; + int _docPid2; + int _docPid3; + int _usersCount = 0; + int _docsCount = 0; + + int _messageTimeoutMilliSeconds = 5000; + std::condition_variable _messageReceivedCV; + std::mutex _messageReceivedMutex; + std::string _messageReceived; + +// Tests +private: + TestResult testIncorrectPassword() + { + HTTPResponse response; + std::string path(_uri.getPathAndQuery()); + HTTPRequest request(HTTPRequest::HTTP_GET, path); + HTTPSClientSession session(_uri.getHost(), _uri.getPort()); + + session.sendRequest(request); + session.receiveResponse(response); + TestResult res = TestResult::TEST_FAILED; + if (response.getStatus() == HTTPResponse::HTTP_UNAUTHORIZED) + res = TestResult::TEST_OK; + + Log::info("testIncorrectPassword: " + (res == TestResult::TEST_OK) ? "OK" : "FAIL"); + return res; + } + + TestResult testCorrectPassword() + { + HTTPResponse response; + std::string path(_uri.getPathAndQuery()); + HTTPRequest request(HTTPRequest::HTTP_GET, path); + HTTPSClientSession session(_uri.getHost(), _uri.getPort()); + HTTPBasicCredentials credentials("admin", "admin"); + credentials.authenticate(request); + + session.sendRequest(request); + session.receiveResponse(response); + std::vector<HTTPCookie> cookies; + response.getCookies(cookies); + + // For now we only set one cookie + assert(cookies.size() == 1); + // and it is jwt= + assert(cookies[0].getName() == "jwt"); + + // Check cookie properties + std::string cookiePath = cookies[0].getPath(); + bool secure = cookies[0].getSecure(); + bool httpOnly = cookies[0].getHttpOnly(); + std::string value = cookies[0].getValue(); + TestResult res = TestResult::TEST_FAILED; + if (cookiePath.find_first_of("/adminws/") == 0 && + secure && + httpOnly && + value != "") + { + // Set JWT cookie to be used for subsequent tests + _jwtCookie = value; + res = TestResult::TEST_OK; + } + + Log::info("testCorrectPassword: " + (res == TestResult::TEST_OK) ? "OK" : "FAIL"); + return res; + } + + TestResult testWebSocketWithoutCookie() + { + // try connecting without cookie; should result in exception + HTTPResponse response; + HTTPRequest request(HTTPRequest::HTTP_GET, "/adminws/"); + HTTPSClientSession session(_uri.getHost(), _uri.getPort()); + bool authorized = true; + try + { + _adminWs = std::make_shared<Poco::Net::WebSocket>(session, request, response); + } + catch (const Poco::Net::WebSocketException& exc) + { + Log::info() << "Admin websocket: Not authorized " << Log::end; + authorized = false; + } + + // no cookie -> should result in not authorized exception + TestResult res = TestResult::TEST_FAILED; + if (!authorized) + res = TestResult::TEST_OK; + + Log::info("testWebSocketWithoutCookie: " + (res == TestResult::TEST_OK) ? "OK" : "FAIL"); + return res; + } + + TestResult testWebSocketWithCookie() + { + HTTPResponse response; + HTTPRequest request(HTTPRequest::HTTP_GET, "/adminws/"); + HTTPSClientSession session(_uri.getHost(), _uri.getPort()); + + // set cookie + assert(_jwtCookie != ""); + HTTPCookie cookie("jwt", _jwtCookie); + Poco::Net::NameValueCollection nvc; + nvc.add("jwt", _jwtCookie); + request.setCookies(nvc); + + bool authorized = true; + try + { + _adminWs = std::make_shared<Poco::Net::WebSocket>(session, request, response); + } + catch (const Poco::Net::WebSocketException& exc) + { + Log::info() << "Admin websocket: Not authorized " << Log::end; + authorized = false; + } + + TestResult res = TestResult::TEST_FAILED; + if (authorized) + res = TestResult::TEST_OK; + + Log::info("testWebSocketWithCookie: " + (res == TestResult::TEST_OK) ? "OK" : "FAIL"); + return res; + } + + TestResult testAddDocNotify() + { + // subscribe notification on admin websocket + const std::string subscribeMessage = "subscribe adddoc"; + _adminWs->sendFrame(subscribeMessage.data(), subscribeMessage.size()); + + const std::string documentPath1 = Util::getTempFilePath(TDOC, "hello.odt"); + const std::string documentURL1 = "file://" + Poco::Path(documentPath1).makeAbsolute().toString(); + HTTPRequest request1(HTTPRequest::HTTP_GET, documentURL1); + HTTPResponse response1; + const Poco::URI docUri1("https://127.0.0.1:" + std::to_string(DEFAULT_CLIENT_PORT_NUMBER)); + const std::string loadMessage1 = "load url=" + documentURL1; + HTTPSClientSession session1(docUri1.getHost(), docUri1.getPort()); + HTTPSClientSession session2(docUri1.getHost(), docUri1.getPort()); + _docWs1 = std::make_shared<Poco::Net::WebSocket>(session1, request1, response1); + _docWs2 = std::make_shared<Poco::Net::WebSocket>(session2, request1, response1); + + { + _messageReceived.clear(); + _docWs1->sendFrame(loadMessage1.data(), loadMessage1.size()); + + std::unique_lock<std::mutex> lock(_messageReceivedMutex); + if (_messageReceived.empty() && + _messageReceivedCV.wait_for(lock, std::chrono::milliseconds(_messageTimeoutMilliSeconds)) == std::cv_status::timeout) + { + Log::info("testAddDocNotify: Timed out waiting for admin console message"); + return TestResult::TEST_TIMED_OUT; + } + lock.unlock(); + + StringTokenizer tokens(_messageReceived, " ", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM); + if (tokens.count() != 5 || + tokens[0] != "adddoc" || + tokens[2] != documentPath1.substr(documentPath1.find_last_of("/") + 1) ) + { + Log::info("testAddDocNotify: Unrecognized message format"); + return TestResult::TEST_FAILED; + } + + // store document pid + _docPid1 = std::stoi(tokens[1]); + _usersCount++; + } + _docsCount++; + + + // Open another view of same document + { + // Send another load request for same document + _messageReceived.clear(); + _docWs2->sendFrame(loadMessage1.data(), loadMessage1.size()); + + std::unique_lock<std::mutex> lock(_messageReceivedMutex); + if (_messageReceived.empty() && + _messageReceivedCV.wait_for(lock, std::chrono::milliseconds(_messageTimeoutMilliSeconds)) == std::cv_status::timeout) + { + Log::info("testAddDocNotify: Timed out waiting for admin console message"); + return TestResult::TEST_TIMED_OUT; + } + lock.unlock(); + + StringTokenizer tokens(_messageReceived, " ", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM); + if (tokens.count() != 5 || + tokens[0] != "adddoc" || + tokens[2] != documentPath1.substr(documentPath1.find_last_of("/") + 1) ) + { + Log::info("testAddDocNotify: Unrecognized message format"); + return TestResult::TEST_FAILED; + } + + // store document pid + _docPid2 = std::stoi(tokens[1]); + _usersCount++; + } + + // Open another document (different) + const std::string documentPath2 = Util::getTempFilePath(TDOC, "insert-delete.odp"); + const std::string documentURL2 = "file://" + Poco::Path(documentPath2).makeAbsolute().toString(); + HTTPRequest request2(HTTPRequest::HTTP_GET, documentURL2); + HTTPResponse response2; + const Poco::URI docUri2("https://127.0.0.1:" + std::to_string(DEFAULT_CLIENT_PORT_NUMBER)); + const std::string loadMessage2 = "load url=" + documentURL2; + HTTPSClientSession session3(docUri2.getHost(), docUri2.getPort()); + _docWs3 = std::make_shared<Poco::Net::WebSocket>(session3, request2, response2); + + { + _messageReceived.clear(); + _docWs3->sendFrame(loadMessage2.data(), loadMessage2.size()); + + std::unique_lock<std::mutex> lock(_messageReceivedMutex); + if (_messageReceived.empty() && + _messageReceivedCV.wait_for(lock, std::chrono::milliseconds(_messageTimeoutMilliSeconds)) == std::cv_status::timeout) + { + Log::info("testAddDocNotify: Timed out waiting for admin console message"); + return TestResult::TEST_TIMED_OUT; + } + lock.unlock(); + + StringTokenizer tokens(_messageReceived, " ", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM); + if (tokens.count() != 5 || + tokens[0] != "adddoc" || + tokens[2] != documentPath2.substr(documentPath2.find_last_of("/") + 1) ) + { + Log::info("testAddDocNotify: Unrecognized message format"); + return TestResult::TEST_FAILED; + } + + // store document pid + _docPid3 = std::stoi(tokens[1]); + _usersCount++; + } + _docsCount++; + + return TestResult::TEST_OK; + } + + TestResult testUsersCount() + { + _messageReceived.clear(); + + // We should have 3 users by now; lets verify + const std::string queryMessage = "active_users_count"; + _adminWs->sendFrame(queryMessage.data(), queryMessage.size()); + + std::unique_lock<std::mutex> lock(_messageReceivedMutex); + if (_messageReceived.empty() && + _messageReceivedCV.wait_for(lock, std::chrono::milliseconds(_messageTimeoutMilliSeconds)) == std::cv_status::timeout) + { + Log::info("testAddDocNotify: Timed out waiting for admin console message"); + return TestResult::TEST_TIMED_OUT; + } + lock.unlock(); + + StringTokenizer tokens(_messageReceived, " ", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM); + if (tokens.count() != 2 || + tokens[0] != "active_users_count" || + std::stoi(tokens[1]) != _usersCount) + { + Log::info("testAddDocNotify: Unrecognized message format"); + return TestResult::TEST_FAILED; + } + + return TestResult::TEST_OK; + } + + TestResult testDocCount() + { + _messageReceived.clear(); + + // We should have 2 total docs open by now; lets verify + const std::string queryMessage = "active_docs_count"; + _adminWs->sendFrame(queryMessage.data(), queryMessage.size()); + + std::unique_lock<std::mutex> lock(_messageReceivedMutex); + if (_messageReceived.empty() && + _messageReceivedCV.wait_for(lock, std::chrono::milliseconds(_messageTimeoutMilliSeconds)) == std::cv_status::timeout) + { + Log::info("testAddDocNotify: Timed out waiting for admin console message"); + return TestResult::TEST_TIMED_OUT; + } + lock.unlock(); + + StringTokenizer tokens(_messageReceived, " ", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM); + if (tokens.count() != 2 || + tokens[0] != "active_docs_count" || + std::stoi(tokens[1]) != _docsCount) + { + Log::info("testAddDocNotify: Unrecognized message format"); + return TestResult::TEST_FAILED; + } + + return TestResult::TEST_OK; + } + + TestResult testRmDocNotify() + { + _messageReceived.clear(); + + // subscribe to rmdoc notification on admin websocket + const std::string subscribeMessage = "subscribe rmdoc"; + _adminWs->sendFrame(subscribeMessage.data(), subscribeMessage.size()); + + _docWs1->close(); + std::unique_lock<std::mutex> lock(_messageReceivedMutex); + if (_messageReceived.empty() && + _messageReceivedCV.wait_for(lock, std::chrono::milliseconds(_messageTimeoutMilliSeconds)) == std::cv_status::timeout) + { + Log::info("testRmDocNotify: Timed out waiting for admin console message"); + return TestResult::TEST_TIMED_OUT; + } + lock.unlock(); + + StringTokenizer tokens(_messageReceived, " ", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM); + if (tokens.count() != 3 || + tokens[0] != "rmdoc" || + stoi(tokens[1]) != _docPid1) + { + Log::info("testRmDocNotify: Invalid message format"); + return TestResult::TEST_FAILED; + } + _usersCount--; + + return TestResult::TEST_OK; + } + + +public: + UnitAdmin() + : _uri("https://127.0.0.1:" + std::to_string(DEFAULT_CLIENT_PORT_NUMBER) + "/loleaflet/dist/admin/admin.html") + { + // Register tests here. + _tests.push_back(&UnitAdmin::testIncorrectPassword); + _tests.push_back(&UnitAdmin::testCorrectPassword); + _tests.push_back(&UnitAdmin::testWebSocketWithoutCookie); + _tests.push_back(&UnitAdmin::testWebSocketWithCookie); + _tests.push_back(&UnitAdmin::testAddDocNotify); + _tests.push_back(&UnitAdmin::testUsersCount); + _tests.push_back(&UnitAdmin::testDocCount); + _tests.push_back(&UnitAdmin::testRmDocNotify); + _tests.push_back(&UnitAdmin::testUsersCount); + _tests.push_back(&UnitAdmin::testDocCount); + } + + // Runs tests sequentially in _tests + virtual void invokeTest() + { + if (!_isTestRunning) + { + _isTestRunning = true; + AdminTest test = _tests[_testCounter++]; + TestResult res = ((*this).*(test))(); + if (res != TestResult::TEST_OK) + { + exitTest(res); + return; + } + + // End this when all tests are finished + if (_tests.size() == _testCounter) + exitTest(TestResult::TEST_OK); + + _isTestRunning = false; + } + } + + virtual void onAdminNotifyMessage(const std::string& message) + { + std::unique_lock<std::mutex> lock(_messageReceivedMutex); + _messageReceivedCV.notify_all(); + _messageReceived = message; + } + + virtual void onAdminQueryMessage(const std::string& message) + { + std::unique_lock<std::mutex> lock(_messageReceivedMutex); + _messageReceivedCV.notify_all(); + _messageReceived = message; + } +}; + +UnitBase *unit_create_wsd(void) +{ + return new UnitAdmin(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/loolwsd/test/run_unit.sh.in b/loolwsd/test/run_unit.sh.in index 1af8b86..acfac8e 100755 --- a/loolwsd/test/run_unit.sh.in +++ b/loolwsd/test/run_unit.sh.in @@ -76,6 +76,8 @@ else # newer unit tests. if ${abs_top_builddir}/loolwsd --systemplate="$systemplate_path" \ --lotemplate="$lo_path" \ --childroot="$jails_path" \ + --allowlocalstorage \ + --admincreds=admin/admin \ --unitlib=".libs/$tst.so" 2> "$tst_log"; then echo "Test $tst passed." echo ":test-result: PASS $tst" >> $test_output commit 3111c5c6d162cffa1df86b642891eb840e086ea6 Author: Pranav Kant <pran...@collabora.com> Date: Tue Apr 19 12:57:28 2016 +0530 loolwsd: Use common method to send websocket messages Will help in placing unit test hooks to better test the admin console Change-Id: Ic4daae685a8fe493a0395d94e40112bf119c93e3 diff --git a/loolwsd/Admin.cpp b/loolwsd/Admin.cpp index b1a4fc7..a350ba9 100644 --- a/loolwsd/Admin.cpp +++ b/loolwsd/Admin.cpp @@ -117,7 +117,16 @@ void AdminRequestHandler::handleWSRequests(HTTPServerRequest& request, HTTPServe std::unique_lock<std::mutex> modelLock(_admin->getLock()); AdminModel& model = _admin->getModel(); - if (tokens[0] == "subscribe" && tokens.count() > 1) + if (tokens[0] == "documents" || + tokens[0] == "active_users_count" || + tokens[0] == "active_docs_count" || + tokens[0] == "mem_stats" || + tokens[0] == "cpu_stats" ) + { + const std::string responseFrame = tokens[0] + " " + model.query(tokens[0]); + sendTextFrame(ws, responseFrame); + } + else if (tokens[0] == "subscribe" && tokens.count() > 1) { for (unsigned i = 0; i < tokens.count() - 1; i++) { @@ -131,26 +140,11 @@ void AdminRequestHandler::handleWSRequests(HTTPServerRequest& request, HTTPServe model.unsubscribe(nSessionId, tokens[i + 1]); } } - else if (tokens[0] == "documents") - { - std::string responseString = "documents " + model.query("documents"); - ws->sendFrame(responseString.data(), responseString.size()); - } else if (tokens[0] == "total_mem") { unsigned totalMem = _admin->getTotalMemoryUsage(model); std::string responseFrame = "total_mem " + std::to_string(totalMem); - ws->sendFrame(responseFrame.data(), responseFrame.size()); - } - else if (tokens[0] == "active_users_count") - { - std::string responseFrame = tokens[0] + " " + model.query(tokens[0]); - ws->sendFrame(responseFrame.data(), responseFrame.size()); - } - else if (tokens[0] == "active_docs_count") - { - std::string responseFrame = tokens[0] + " " + model.query(tokens[0]); - ws->sendFrame(responseFrame.data(), responseFrame.size()); + sendTextFrame(ws, responseFrame); } else if (tokens[0] == "kill" && tokens.count() == 2) { @@ -167,24 +161,6 @@ void AdminRequestHandler::handleWSRequests(HTTPServerRequest& request, HTTPServe Log::warn() << "Invalid PID to kill: " << tokens[0] << Log::end; } } - else if (tokens[0] == "mem_stats") - { - std::ostringstream oss; - oss << tokens[0] << " " - << model.query(tokens[0]); - - std::string responseFrame = oss.str(); - ws->sendFrame(responseFrame.data(), responseFrame.size()); - } - else if (tokens[0] == "cpu_stats") - { - std::ostringstream oss; - oss << tokens[0] << " " - << model.query(tokens[0]); - - std::string responseFrame = oss.str(); - ws->sendFrame(responseFrame.data(), responseFrame.size()); - } else if (tokens[0] == "settings") { // for now, we have only these settings @@ -196,7 +172,7 @@ void AdminRequestHandler::handleWSRequests(HTTPServerRequest& request, HTTPServe << "cpu_stats_interval=" << std::to_string(_admin->getCpuStatsInterval()); std::string responseFrame = oss.str(); - ws->sendFrame(responseFrame.data(), responseFrame.size()); + sendTextFrame(ws, responseFrame); } else if (tokens[0] == "set" && tokens.count() > 1) { @@ -294,6 +270,11 @@ AdminRequestHandler::AdminRequestHandler(Admin* adminManager) : _admin(adminManager) { } +void AdminRequestHandler::sendTextFrame(std::shared_ptr<Poco::Net::WebSocket>& socket, const std::string& message) +{ + socket->sendFrame(message.data(), message.size()); +} + void AdminRequestHandler::handleRequest(HTTPServerRequest& request, HTTPServerResponse& response) { // Different session id pool for admin sessions (?) diff --git a/loolwsd/Admin.hpp b/loolwsd/Admin.hpp index 3e66b17..f315efa 100644 --- a/loolwsd/Admin.hpp +++ b/loolwsd/Admin.hpp @@ -13,6 +13,7 @@ #include <Poco/Net/HTTPRequest.h> #include <Poco/Net/HTTPRequestHandler.h> #include <Poco/Net/HTTPServer.h> +#include <Poco/Net/WebSocket.h> #include <Poco/Runnable.h> #include <Poco/Types.h> #include <Poco/Util/Timer.h> @@ -32,6 +33,8 @@ public: private: void handleWSRequests(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response, int nSessionId); + void sendTextFrame(std::shared_ptr<Poco::Net::WebSocket>& socket, const std::string& message); + private: Admin* _admin; }; commit 56d18909d531f7c819954e503b71911349f4eab7 Author: Pranav Kant <pran...@collabora.com> Date: Tue Apr 19 12:37:07 2016 +0530 loolwsd: Remove unused code Change-Id: I7edf6b8d4f83f2cf9f85a2075d1dca216cda3d34 diff --git a/loolwsd/Admin.cpp b/loolwsd/Admin.cpp index dcd9ad4..b1a4fc7 100644 --- a/loolwsd/Admin.cpp +++ b/loolwsd/Admin.cpp @@ -117,36 +117,7 @@ void AdminRequestHandler::handleWSRequests(HTTPServerRequest& request, HTTPServe std::unique_lock<std::mutex> modelLock(_admin->getLock()); AdminModel& model = _admin->getModel(); - if (tokens[0] == "stats") - { - //TODO: Collect stats and reply back to admin. - // We need to ask ForKit to give us some numbers on docs/clients/etc. - // But we can also collect some memory info using system calls. - - std::string statsResponse; - - const auto cmd = "pstree -a -c -h -A -p " + std::to_string(getpid()); - FILE* fp = popen(cmd.c_str(), "r"); - if (fp == nullptr) - { - statsResponse = "error: failed to collect stats."; - ws->sendFrame(statsResponse.data(), statsResponse.size()); - continue; - } - - char treeBuffer[1024]; - while (fgets(treeBuffer, sizeof(treeBuffer)-1, fp) != nullptr && - !TerminationFlag) - { - statsResponse += treeBuffer; - statsResponse += "</ BR>\n"; - } - - pclose(fp); - - ws->sendFrame(statsResponse.data(), statsResponse.size()); - } - else if (tokens[0] == "subscribe" && tokens.count() > 1) + if (tokens[0] == "subscribe" && tokens.count() > 1) { for (unsigned i = 0; i < tokens.count() - 1; i++) { @@ -162,7 +133,6 @@ void AdminRequestHandler::handleWSRequests(HTTPServerRequest& request, HTTPServe } else if (tokens[0] == "documents") { - std::string responseString = "documents " + model.query("documents"); ws->sendFrame(responseString.data(), responseString.size()); } _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits