From f392d9e6f0103360dbcaaf99fc4768dfd9624eba Mon Sep 17 00:00:00 2001 From: Michael Meeks Date: Wed, 15 Mar 2017 18:21:59 +0000 Subject: [PATCH] Move http serving into socket impl. Avoid caching headers with parameter, and add Date: parameter. --- net/Socket.cpp | 57 ++++++++++++++++++++++++++++++++++++++++++++++ net/Socket.hpp | 51 ++++------------------------------------- wsd/FileServer.cpp | 2 +- 3 files changed, 62 insertions(+), 48 deletions(-) diff --git a/net/Socket.cpp b/net/Socket.cpp index 5f13202bd..7af876014 100644 --- a/net/Socket.cpp +++ b/net/Socket.cpp @@ -12,6 +12,10 @@ #include #include +#include +#include +#include + #include "SigUtil.hpp" #include "Socket.hpp" #include "ServerSocket.hpp" @@ -147,4 +151,57 @@ void SocketPoll::dumpState(std::ostream& os) i->dumpState(os); } +namespace HttpHelper +{ + void sendFile(const std::shared_ptr& socket, const std::string& path, + Poco::Net::HTTPResponse& response, bool noCache) + { + struct stat st; + if (stat(path.c_str(), &st) != 0) + { + LOG_WRN("#" << socket->getFD() << ": Failed to stat [" << path << "]. File will not be sent."); + throw Poco::FileNotFoundException("Failed to stat [" + path + "]. File will not be sent."); + return; + } + + int bufferSize = std::min(st.st_size, (off_t)Socket::MaximumSendBufferSize); + if (st.st_size >= socket->getSendBufferSize()) + { + socket->setSocketBufferSize(bufferSize); + bufferSize = socket->getSendBufferSize(); + } + + response.setContentLength(st.st_size); + response.set("User-Agent", HTTP_AGENT_STRING); + response.set("Date", Poco::DateTimeFormatter::format(Poco::Timestamp(), Poco::DateTimeFormat::HTTP_FORMAT)); + if (!noCache) + { + // 60 * 60 * 24 * 128 (days) = 11059200 + response.set("Cache-Control", "max-age=11059200"); + response.set("ETag", "\"" LOOLWSD_VERSION_HASH "\""); + } + + std::ostringstream oss; + response.write(oss); + const std::string header = oss.str(); + LOG_TRC("#" << socket->getFD() << ": Sending file [" << path << "]: " << header); + socket->send(header); + + std::ifstream file(path, std::ios::binary); + bool flush = true; + do + { + char buf[bufferSize]; + file.read(buf, sizeof(buf)); + const int size = file.gcount(); + if (size > 0) + socket->send(buf, size, flush); + else + break; + flush = false; + } + while (file); + } +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/net/Socket.hpp b/net/Socket.hpp index 9460c45bb..708ae39ec 100644 --- a/net/Socket.hpp +++ b/net/Socket.hpp @@ -820,58 +820,15 @@ protected: namespace HttpHelper { - inline void sendFile(const std::shared_ptr& socket, const std::string& path, - Poco::Net::HTTPResponse& response) - { - struct stat st; - if (stat(path.c_str(), &st) != 0) - { - LOG_WRN("#" << socket->getFD() << ": Failed to stat [" << path << "]. File will not be sent."); - throw Poco::FileNotFoundException("Failed to stat [" + path + "]. File will not be sent."); - return; - } - - int bufferSize = std::min(st.st_size, (off_t)Socket::MaximumSendBufferSize); - if (st.st_size >= socket->getSendBufferSize()) - { - socket->setSocketBufferSize(bufferSize); - bufferSize = socket->getSendBufferSize(); - } - - response.setContentLength(st.st_size); - response.set("User-Agent", HTTP_AGENT_STRING); - // 60 * 60 * 24 * 128 (days) = 11059200 - response.set("Cache-Control", "max-age=11059200"); - response.set("ETag", "\"" LOOLWSD_VERSION_HASH "\""); - - std::ostringstream oss; - response.write(oss); - const std::string header = oss.str(); - LOG_TRC("#" << socket->getFD() << ": Sending file [" << path << "]: " << header); - socket->send(header); - - std::ifstream file(path, std::ios::binary); - bool flush = true; - do - { - char buf[bufferSize]; - file.read(buf, sizeof(buf)); - const int size = file.gcount(); - if (size > 0) - socket->send(buf, size, flush); - else - break; - flush = false; - } - while (file); - } + void sendFile(const std::shared_ptr& socket, const std::string& path, + Poco::Net::HTTPResponse& response, bool noCache = false); inline void sendFile(const std::shared_ptr& socket, const std::string& path, - const std::string& mediaType) + const std::string& mediaType, bool noCache = false) { Poco::Net::HTTPResponse response; response.setContentType(mediaType); - sendFile(socket, path, response); + sendFile(socket, path, response, noCache); } }; diff --git a/wsd/FileServer.cpp b/wsd/FileServer.cpp index 2189205e2..bba77d5e9 100644 --- a/wsd/FileServer.cpp +++ b/wsd/FileServer.cpp @@ -197,7 +197,7 @@ void FileServerRequestHandler::handleRequest(const HTTPRequest& request, Poco::M } response.setContentType(mimeType); - HttpHelper::sendFile(socket, filepath, response); + HttpHelper::sendFile(socket, filepath, response, noCache); } } catch (const Poco::Net::NotAuthenticatedException& exc)