net/Socket.hpp | 21 ++++++++++- net/SslSocket.hpp | 2 - wsd/FileServer.cpp | 94 ++++++++++++++++++++++++++++++++++------------------- wsd/FileServer.hpp | 32 +++--------------- wsd/LOOLWSD.cpp | 15 +++++--- 5 files changed, 97 insertions(+), 67 deletions(-)
New commits: commit 5244650ca327b8803a5469715ffdd0ac339d1aab Author: Ashod Nakashian <[email protected]> Date: Mon Feb 27 08:55:42 2017 -0500 nb: shutdown socket after file-serving Change-Id: Ibe0b33f371d46e62637f570265fcdf9c8bf60b2d diff --git a/net/Socket.hpp b/net/Socket.hpp index 78cfb66..a5966aa 100644 --- a/net/Socket.hpp +++ b/net/Socket.hpp @@ -55,6 +55,13 @@ public: /// Returns the OS native socket fd. int getFD() const { return _fd; } + /// Shutdown the socket. + /// TODO: Support separate read/write shutdown. + virtual void shutdown() + { + ::shutdown(_fd, SHUT_RDWR); + } + /// Return a mask of events we should be polling for virtual int getPollEvents() = 0; diff --git a/net/SslSocket.hpp b/net/SslSocket.hpp index 0f43869..ada6568 100644 --- a/net/SslSocket.hpp +++ b/net/SslSocket.hpp @@ -55,7 +55,7 @@ public: } /// Shutdown the TLS/SSL connection properly. - void shutdown() + void shutdown() override { if (SSL_shutdown(_ssl) == 0) { diff --git a/wsd/LOOLWSD.cpp b/wsd/LOOLWSD.cpp index 617e0db..19ac013 100644 --- a/wsd/LOOLWSD.cpp +++ b/wsd/LOOLWSD.cpp @@ -2760,6 +2760,7 @@ private: LOG_DBG("FileServer request: " << request.getURI()); auto socket = _socket.lock(); FileServerRequestHandler::handleRequest(request, socket); + socket->shutdown(); } void handleAdminRequest(const Poco::Net::HTTPRequest& request) @@ -2789,6 +2790,7 @@ private: auto socket = _socket.lock(); socket->send(oss.str()); + socket->shutdown(); LOG_INF("Sent discovery.xml successfully."); } @@ -2804,6 +2806,7 @@ private: auto socket = _socket.lock(); HttpHelper::sendFile(socket, faviconPath, mimeType); + socket->shutdown(); } void handleWopiDiscoveryRequest(const Poco::Net::HTTPRequest& request) @@ -2853,6 +2856,7 @@ private: auto socket = _socket.lock(); socket->send(oss.str()); + socket->shutdown(); LOG_INF("Sent discovery.xml successfully."); } commit 8b753ecfae4d57ce490abc1f4aa40d6b57b10234 Author: Ashod Nakashian <[email protected]> Date: Mon Feb 27 08:55:10 2017 -0500 nb: handle socket poll exceptions and remove socket Change-Id: Ibdee316f102d6606c38470e5ccacd2a7bd7ea7ce diff --git a/net/Socket.hpp b/net/Socket.hpp index 6542448..78cfb66 100644 --- a/net/Socket.hpp +++ b/net/Socket.hpp @@ -207,8 +207,18 @@ public: { if (_pollFds[i].revents) { - if (_pollSockets[i]->handlePoll(newNow, _pollFds[i].revents) == - Socket::HandleResult::SOCKET_CLOSED) + Socket::HandleResult res = Socket::HandleResult::SOCKET_CLOSED; + try + { + res = _pollSockets[i]->handlePoll(newNow, _pollFds[i].revents); + } + catch (const std::exception& exc) + { + LOG_ERR("Error while handling poll for socket #" << + _pollFds[i].fd << ": " << exc.what()); + } + + if (res == Socket::HandleResult::SOCKET_CLOSED) { LOG_DBG("Removing client #" << _pollFds[i].fd); _pollSockets.erase(_pollSockets.begin() + i); commit bf45b86f8236c7399d481ee4862f9143617b126a Author: Ashod Nakashian <[email protected]> Date: Mon Feb 27 08:40:44 2017 -0500 nb: set the Date in http header Change-Id: I71e3388c1f204135c6dc72ad27890bffe53792b3 diff --git a/wsd/FileServer.cpp b/wsd/FileServer.cpp index 563ffe3..01d2473 100644 --- a/wsd/FileServer.cpp +++ b/wsd/FileServer.cpp @@ -180,7 +180,7 @@ void FileServerRequestHandler::handleRequest(const HTTPRequest& request, const s // Unauthorized. std::ostringstream oss; oss << "HTTP/1.1 401\r\n" - << "Last-Modified: " << Poco::DateTimeFormatter::format(Poco::Timestamp(), Poco::DateTimeFormat::HTTP_FORMAT) << "\r\n" + << "Date: " << Poco::DateTimeFormatter::format(Poco::Timestamp(), Poco::DateTimeFormat::HTTP_FORMAT) << "\r\n" << "User-Agent: LOOLWSD WOPI Agent\r\n" << "Content-Length: 0\r\n" << "WWW-Authenticate: Basic realm=\"online\"\r\n" @@ -194,7 +194,7 @@ void FileServerRequestHandler::handleRequest(const HTTPRequest& request, const s // TODO return some 403 page? std::ostringstream oss; oss << "HTTP/1.1 403\r\n" - << "Last-Modified: " << Poco::DateTimeFormatter::format(Poco::Timestamp(), Poco::DateTimeFormat::HTTP_FORMAT) << "\r\n" + << "Date: " << Poco::DateTimeFormatter::format(Poco::Timestamp(), Poco::DateTimeFormat::HTTP_FORMAT) << "\r\n" << "User-Agent: LOOLWSD WOPI Agent\r\n" << "Content-Length: 0\r\n" << "\r\n"; @@ -207,7 +207,7 @@ void FileServerRequestHandler::handleRequest(const HTTPRequest& request, const s // 404 not found std::ostringstream oss; oss << "HTTP/1.1 404\r\n" - << "Last-Modified: " << Poco::DateTimeFormatter::format(Poco::Timestamp(), Poco::DateTimeFormat::HTTP_FORMAT) << "\r\n" + << "Date: " << Poco::DateTimeFormatter::format(Poco::Timestamp(), Poco::DateTimeFormat::HTTP_FORMAT) << "\r\n" << "User-Agent: LOOLWSD WOPI Agent\r\n" << "Content-Length: 0\r\n" << "\r\n"; @@ -242,7 +242,7 @@ void FileServerRequestHandler::preprocessFile(const HTTPRequest& request, const // 404 not found std::ostringstream oss; oss << "HTTP/1.1 404\r\n" - << "Last-Modified: " << Poco::DateTimeFormatter::format(Poco::Timestamp(), Poco::DateTimeFormat::HTTP_FORMAT) << "\r\n" + << "Date: " << Poco::DateTimeFormatter::format(Poco::Timestamp(), Poco::DateTimeFormat::HTTP_FORMAT) << "\r\n" << "User-Agent: LOOLWSD WOPI Agent\r\n" << "Content-Length: 0\r\n" << "\r\n"; @@ -298,6 +298,7 @@ void FileServerRequestHandler::preprocessFile(const HTTPRequest& request, const std::ostringstream oss; oss << "HTTP/1.1 200 OK\r\n" + << "Date: " << Poco::DateTimeFormatter::format(Poco::Timestamp(), Poco::DateTimeFormat::HTTP_FORMAT) << "\r\n" << "Last-Modified: " << Poco::DateTimeFormatter::format(Poco::Timestamp(), Poco::DateTimeFormat::HTTP_FORMAT) << "\r\n" << "User-Agent: LOOLWSD WOPI Agent\r\n" << "Content-Length: " << preprocess.size() << "\r\n" commit dff26f9b57a90429e5958f7340e0769c9357418f Author: Ashod Nakashian <[email protected]> Date: Mon Feb 27 08:37:48 2017 -0500 nb: http error cases in file server Change-Id: I81b0ef3f080ba61836d99fbdde0fb94e1a44a625 diff --git a/wsd/FileServer.cpp b/wsd/FileServer.cpp index 35e0a8d..563ffe3 100644 --- a/wsd/FileServer.cpp +++ b/wsd/FileServer.cpp @@ -176,24 +176,42 @@ void FileServerRequestHandler::handleRequest(const HTTPRequest& request, const s catch (const Poco::Net::NotAuthenticatedException& exc) { LOG_ERR("FileServerRequestHandler::NotAuthenticated: " << exc.displayText()); - // response.set("WWW-Authenticate", "Basic realm=\"online\""); - // response.setStatusAndReason(HTTPResponse::HTTP_UNAUTHORIZED); - // response.setContentLength(0); - // response.send(); + + // Unauthorized. + std::ostringstream oss; + oss << "HTTP/1.1 401\r\n" + << "Last-Modified: " << Poco::DateTimeFormatter::format(Poco::Timestamp(), Poco::DateTimeFormat::HTTP_FORMAT) << "\r\n" + << "User-Agent: LOOLWSD WOPI Agent\r\n" + << "Content-Length: 0\r\n" + << "WWW-Authenticate: Basic realm=\"online\"\r\n" + << "\r\n"; + socket->send(oss.str()); } catch (const Poco::FileAccessDeniedException& exc) { LOG_ERR("FileServerRequestHandler: " << exc.displayText()); - // response.setStatusAndReason(HTTPResponse::HTTP_FORBIDDEN); - // response.setContentLength(0); // TODO return some 403 page? - // response.send(); + + // TODO return some 403 page? + std::ostringstream oss; + oss << "HTTP/1.1 403\r\n" + << "Last-Modified: " << Poco::DateTimeFormatter::format(Poco::Timestamp(), Poco::DateTimeFormat::HTTP_FORMAT) << "\r\n" + << "User-Agent: LOOLWSD WOPI Agent\r\n" + << "Content-Length: 0\r\n" + << "\r\n"; + socket->send(oss.str()); } catch (const Poco::FileNotFoundException& exc) { LOG_ERR("FileServerRequestHandler: " << exc.displayText()); - // response.setStatusAndReason(HTTPResponse::HTTP_NOT_FOUND); - // response.setContentLength(0); // TODO return some 404 page? - // response.send(); + + // 404 not found + std::ostringstream oss; + oss << "HTTP/1.1 404\r\n" + << "Last-Modified: " << Poco::DateTimeFormatter::format(Poco::Timestamp(), Poco::DateTimeFormat::HTTP_FORMAT) << "\r\n" + << "User-Agent: LOOLWSD WOPI Agent\r\n" + << "Content-Length: 0\r\n" + << "\r\n"; + socket->send(oss.str()); } } @@ -220,9 +238,15 @@ void FileServerRequestHandler::preprocessFile(const HTTPRequest& request, const if (!Poco::File(path).exists()) { LOG_ERR("File [" << path.toString() << "] does not exist."); - // response.setStatusAndReason(HTTPResponse::HTTP_NOT_FOUND); - // response.setContentLength(0); // TODO return some 404 page? - // response.send(); + + // 404 not found + std::ostringstream oss; + oss << "HTTP/1.1 404\r\n" + << "Last-Modified: " << Poco::DateTimeFormatter::format(Poco::Timestamp(), Poco::DateTimeFormat::HTTP_FORMAT) << "\r\n" + << "User-Agent: LOOLWSD WOPI Agent\r\n" + << "Content-Length: 0\r\n" + << "\r\n"; + socket->send(oss.str()); return; } @@ -231,6 +255,7 @@ void FileServerRequestHandler::preprocessFile(const HTTPRequest& request, const StreamCopier::copyToString(file, preprocess); file.close(); + //TODO: FIXME: Is this the correct way to get these values? Used to be done using HTTPForm. const std::string& accessToken = request.get("access_token", ""); const std::string& accessTokenTtl = request.get("access_token_ttl", ""); diff --git a/wsd/LOOLWSD.cpp b/wsd/LOOLWSD.cpp index cb6390f..617e0db 100644 --- a/wsd/LOOLWSD.cpp +++ b/wsd/LOOLWSD.cpp @@ -2757,7 +2757,7 @@ private: void handleFileServerRequest(const Poco::Net::HTTPRequest& request) { - LOG_ERR("FileServer request: " << request.getURI()); + LOG_DBG("FileServer request: " << request.getURI()); auto socket = _socket.lock(); FileServerRequestHandler::handleRequest(request, socket); } commit 9469b12accb27ab4e243542467bfc04407e82ff5 Author: Ashod Nakashian <[email protected]> Date: Mon Feb 27 08:28:04 2017 -0500 nb: serve files using non-blocking sockets Change-Id: I254288980f72f197d29b7b57ec9c88a01a5a1d03 diff --git a/wsd/FileServer.cpp b/wsd/FileServer.cpp index c91fdf1..35e0a8d 100644 --- a/wsd/FileServer.cpp +++ b/wsd/FileServer.cpp @@ -12,6 +12,8 @@ #include <string> #include <vector> +#include <Poco/DateTimeFormat.h> +#include <Poco/DateTimeFormatter.h> #include <Poco/Exception.h> #include <Poco/FileStream.h> #include <Poco/Net/HTTPCookie.h> @@ -106,7 +108,7 @@ bool FileServerRequestHandler::isAdminLoggedIn(HTTPServerRequest& request, HTTPS return false; } -void FileServerRequestHandler::handleRequest(HTTPServerRequest& request, HTTPServerResponse& response) +void FileServerRequestHandler::handleRequest(const HTTPRequest& request, const std::shared_ptr<StreamSocket>& socket) { try { @@ -126,7 +128,7 @@ void FileServerRequestHandler::handleRequest(HTTPServerRequest& request, HTTPSer const std::string endPoint = requestSegments[requestSegments.size() - 1]; if (endPoint == loleafletHtml) { - preprocessFile(request, response); + preprocessFile(request, socket); return; } @@ -136,7 +138,8 @@ void FileServerRequestHandler::handleRequest(HTTPServerRequest& request, HTTPSer endPoint == "adminSettings.html" || endPoint == "adminAnalytics.html") { - if (!FileServerRequestHandler::isAdminLoggedIn(request, response)) + // FIXME: support admin console. + //if (!FileServerRequestHandler::isAdminLoggedIn(request, response)) throw Poco::Net::NotAuthenticatedException("Invalid admin login"); } @@ -167,35 +170,34 @@ void FileServerRequestHandler::handleRequest(HTTPServerRequest& request, HTTPSer else mimeType = "text/plain"; - response.setContentType(mimeType); - response.sendFile(filepath, mimeType); + HttpHelper::sendFile(socket, filepath, mimeType); } } catch (const Poco::Net::NotAuthenticatedException& exc) { LOG_ERR("FileServerRequestHandler::NotAuthenticated: " << exc.displayText()); - response.set("WWW-Authenticate", "Basic realm=\"online\""); - response.setStatusAndReason(HTTPResponse::HTTP_UNAUTHORIZED); - response.setContentLength(0); - response.send(); + // response.set("WWW-Authenticate", "Basic realm=\"online\""); + // response.setStatusAndReason(HTTPResponse::HTTP_UNAUTHORIZED); + // response.setContentLength(0); + // response.send(); } catch (const Poco::FileAccessDeniedException& exc) { LOG_ERR("FileServerRequestHandler: " << exc.displayText()); - response.setStatusAndReason(HTTPResponse::HTTP_FORBIDDEN); - response.setContentLength(0); // TODO return some 403 page? - response.send(); + // response.setStatusAndReason(HTTPResponse::HTTP_FORBIDDEN); + // response.setContentLength(0); // TODO return some 403 page? + // response.send(); } catch (const Poco::FileNotFoundException& exc) { LOG_ERR("FileServerRequestHandler: " << exc.displayText()); - response.setStatusAndReason(HTTPResponse::HTTP_NOT_FOUND); - response.setContentLength(0); // TODO return some 404 page? - response.send(); + // response.setStatusAndReason(HTTPResponse::HTTP_NOT_FOUND); + // response.setContentLength(0); // TODO return some 404 page? + // response.send(); } } -std::string FileServerRequestHandler::getRequestPathname(const HTTPServerRequest& request) +std::string FileServerRequestHandler::getRequestPathname(const HTTPRequest& request) { Poco::URI requestUri(request.getURI()); // avoid .'s and ..'s @@ -209,10 +211,8 @@ std::string FileServerRequestHandler::getRequestPathname(const HTTPServerRequest return path; } -void FileServerRequestHandler::preprocessFile(HTTPServerRequest& request, HTTPServerResponse& response) throw(Poco::FileAccessDeniedException) +void FileServerRequestHandler::preprocessFile(const HTTPRequest& request, const std::shared_ptr<StreamSocket>& socket) { - HTMLForm form(request, request.stream()); - const auto host = ((LOOLWSD::isSSLEnabled() || LOOLWSD::isSSLTermination()) ? "wss://" : "ws://") + (LOOLWSD::ServerName.empty() ? request.getHost() : LOOLWSD::ServerName); const auto path = Poco::Path(LOOLWSD::FileServerRoot, getRequestPathname(request)); LOG_DBG("Preprocessing file: " << path.toString()); @@ -220,9 +220,9 @@ void FileServerRequestHandler::preprocessFile(HTTPServerRequest& request, HTTPSe if (!Poco::File(path).exists()) { LOG_ERR("File [" << path.toString() << "] does not exist."); - response.setStatusAndReason(HTTPResponse::HTTP_NOT_FOUND); - response.setContentLength(0); // TODO return some 404 page? - response.send(); + // response.setStatusAndReason(HTTPResponse::HTTP_NOT_FOUND); + // response.setContentLength(0); // TODO return some 404 page? + // response.send(); return; } @@ -231,8 +231,8 @@ void FileServerRequestHandler::preprocessFile(HTTPServerRequest& request, HTTPSe StreamCopier::copyToString(file, preprocess); file.close(); - const std::string& accessToken = form.get("access_token", ""); - const std::string& accessTokenTtl = form.get("access_token_ttl", ""); + const std::string& accessToken = request.get("access_token", ""); + const std::string& accessTokenTtl = request.get("access_token_ttl", ""); // Escape bad characters in access token. // This is placed directly in javascript in loleaflet.html, we need to make sure @@ -269,17 +269,19 @@ void FileServerRequestHandler::preprocessFile(HTTPServerRequest& request, HTTPSe const auto loleafletLogging = config.getString("loleaflet_logging", "false"); Poco::replaceInPlace(preprocess, std::string("%LOLEAFLET_LOGGING%"), loleafletLogging); - response.setContentType("text/html"); - response.setContentLength(preprocess.length()); - response.setChunkedTransferEncoding(false); + const std::string mimeType = "text/html"; - std::ostream& ostr = response.send(); - ostr << preprocess; -} + std::ostringstream oss; + oss << "HTTP/1.1 200 OK\r\n" + << "Last-Modified: " << Poco::DateTimeFormatter::format(Poco::Timestamp(), Poco::DateTimeFormat::HTTP_FORMAT) << "\r\n" + << "User-Agent: LOOLWSD WOPI Agent\r\n" + << "Content-Length: " << preprocess.size() << "\r\n" + << "Content-Type: " << mimeType << "\r\n" + << "\r\n" + << preprocess; -FileServer::FileServer() -{ - LOG_INF("FileServer ctor."); + socket->send(oss.str()); + LOG_DBG("Sent file: " << path.toString()); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/wsd/FileServer.hpp b/wsd/FileServer.hpp index a9f56cd..7738968 100644 --- a/wsd/FileServer.hpp +++ b/wsd/FileServer.hpp @@ -18,40 +18,20 @@ #include <Poco/Net/HTTPServerRequest.h> #include <Poco/Net/HTTPServerResponse.h> +#include "Socket.hpp" + /// Handles file requests over HTTP(S). -class FileServerRequestHandler : public Poco::Net::HTTPRequestHandler +class FileServerRequestHandler { - static std::string getRequestPathname(const Poco::Net::HTTPServerRequest& request); + static std::string getRequestPathname(const Poco::Net::HTTPRequest& request); - static void preprocessFile(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response) throw(Poco::FileAccessDeniedException); + static void preprocessFile(const Poco::Net::HTTPRequest& request, const std::shared_ptr<StreamSocket>& socket); public: /// Evaluate if the cookie exists, and if not, ask for the credentials. static bool isAdminLoggedIn(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response); - void handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response) override; -}; - -/// Singleton class to serve files over HTTP(S). -class FileServer -{ -public: - static FileServer& instance() - { - static FileServer fileServer; - return fileServer; - } - - static FileServerRequestHandler* createRequestHandler() - { - return new FileServerRequestHandler(); - } - - FileServer(FileServer const&) = delete; - void operator=(FileServer const&) = delete; - -private: - FileServer(); + static void handleRequest(const Poco::Net::HTTPRequest& request, const std::shared_ptr<StreamSocket>& socket); }; #endif diff --git a/wsd/LOOLWSD.cpp b/wsd/LOOLWSD.cpp index 58a2c9b..cb6390f 100644 --- a/wsd/LOOLWSD.cpp +++ b/wsd/LOOLWSD.cpp @@ -2758,7 +2758,8 @@ private: void handleFileServerRequest(const Poco::Net::HTTPRequest& request) { LOG_ERR("FileServer request: " << request.getURI()); - // requestHandler = FileServer::createRequestHandler(); + auto socket = _socket.lock(); + FileServerRequestHandler::handleRequest(request, socket); } void handleAdminRequest(const Poco::Net::HTTPRequest& request) commit f64e78978ee0ffdad06a73a7a1fbba04f3d47826 Author: Ashod Nakashian <[email protected]> Date: Mon Feb 27 08:27:36 2017 -0500 nb: log requests as debug and not error Change-Id: Ic3ec3257f98c80e959c9d980fe6b1d8d6f40f604 diff --git a/wsd/LOOLWSD.cpp b/wsd/LOOLWSD.cpp index d32699a..58a2c9b 100644 --- a/wsd/LOOLWSD.cpp +++ b/wsd/LOOLWSD.cpp @@ -2769,7 +2769,7 @@ private: void handleRootRequest(const Poco::Net::HTTPRequest& request) { - LOG_ERR("HTTP request: " << request.getURI()); + LOG_DBG("HTTP request: " << request.getURI()); const std::string mimeType = "text/plain"; const std::string responseString = "OK"; @@ -2793,7 +2793,7 @@ private: void handleFaviconRequest(const Poco::Net::HTTPRequest& request) { - LOG_ERR("Favicon request: " << request.getURI()); + LOG_DBG("Favicon request: " << request.getURI()); std::string mimeType = "image/vnd.microsoft.icon"; std::string faviconPath = Path(Application::instance().commandPath()).parent().toString() + "favicon.ico"; if (!File(faviconPath).exists()) @@ -2807,7 +2807,7 @@ private: void handleWopiDiscoveryRequest(const Poco::Net::HTTPRequest& request) { - LOG_ERR("Wopi discovery request: " << request.getURI()); + LOG_DBG("Wopi discovery request: " << request.getURI()); // http://server/hosting/discovery std::string discoveryPath = Path(Application::instance().commandPath()).parent().toString() + "discovery.xml"; _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
