net/Socket.cpp | 112 ++++++++++++++++++++++++++++++--------------------------- net/Socket.hpp | 9 +++- 2 files changed, 66 insertions(+), 55 deletions(-)
New commits: commit 988ddaf7be50c556618685a52f0c0f724947274d Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> Date: Sat Apr 22 21:10:54 2017 -0400 wsd: cleanup sendFile to allow header-only response HTTP HEAD verb requires sending back NO content. Currently we don't support HEAD and that harms the browser from using its cache where possible. Change-Id: I3c67dc106df95312c73f6ae786b7b1657a4167fb Reviewed-on: https://gerrit.libreoffice.org/36871 Reviewed-by: Ashod Nakashian <ashnak...@gmail.com> Tested-by: Ashod Nakashian <ashnak...@gmail.com> diff --git a/net/Socket.cpp b/net/Socket.cpp index b38dd3fe..c8780327 100644 --- a/net/Socket.cpp +++ b/net/Socket.cpp @@ -187,19 +187,64 @@ void SocketPoll::dumpState(std::ostream& os) namespace HttpHelper { - void sendFile(const std::shared_ptr<StreamSocket>& socket, const std::string& path, const std::string& mediaType, - Poco::Net::HTTPResponse& response, bool noCache, bool deflate) + void sendUncompressedFileContent(const std::shared_ptr<StreamSocket>& socket, + const std::string& path, + const int bufferSize) + { + std::ifstream file(path, std::ios::binary); + std::unique_ptr<char[]> buf(new char[bufferSize]); + do + { + file.read(&buf[0], bufferSize); + const int size = file.gcount(); + if (size > 0) + socket->send(&buf[0], size, true); + else + break; + } + while (file); + } + + void sendDeflatedFileContent(const std::shared_ptr<StreamSocket>& socket, + const std::string& path, + const int fileSize) + { + // FIXME: Should compress once ahead of time + // compression of bundle.js takes significant time: + // 200's ms for level 9 (468k), 72ms for level 1(587k) + // down from 2Mb. + if (fileSize > 0) + { + std::ifstream file(path, std::ios::binary); + std::unique_ptr<char[]> buf(new char[fileSize]); + file.read(&buf[0], fileSize); + + static const unsigned int Level = 1; + const long unsigned int size = file.gcount(); + long unsigned int compSize = compressBound(size); + std::unique_ptr<char[]> cbuf(new char[compSize]); + compress2((Bytef *)&cbuf[0], &compSize, (Bytef *)&buf[0], size, Level); + + if (size > 0) + socket->send(&cbuf[0], compSize, true); + } + } + + void sendFile(const std::shared_ptr<StreamSocket>& socket, + const std::string& path, + const std::string& mediaType, + Poco::Net::HTTPResponse& response, + const bool noCache, + const bool deflate, + const bool headerOnly) { 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; } - 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 @@ -223,59 +268,22 @@ namespace HttpHelper if (!deflate || true) { response.setContentLength(st.st_size); - std::ostringstream oss; - response.write(oss); - const std::string header = oss.str(); - LOG_TRC("#" << socket->getFD() << ": Sending file [" << path << "]: " << header); - socket->send(header); + LOG_TRC("#" << socket->getFD() << ": Sending " << + (headerOnly ? "header for " : "") << " file [" << path << "]."); + socket->send(response); - std::ifstream file(path, std::ios::binary); - bool flush = true; - std::unique_ptr<char[]> buf(new char[bufferSize]); - do - { - file.read(&buf[0], bufferSize); - const int size = file.gcount(); - if (size > 0) - socket->send(&buf[0], size, flush); - else - break; - flush = false; - } - while (file); + if (!headerOnly) + sendUncompressedFileContent(socket, path, bufferSize); } else { response.set("Content-Encoding", "deflate"); - std::ostringstream oss; - response.write(oss); - const std::string header = oss.str(); - LOG_TRC("#" << socket->getFD() << ": Sending file [" << path << "]: " << header); - socket->send(header); + LOG_TRC("#" << socket->getFD() << ": Sending " << + (headerOnly ? "header for " : "") << " file [" << path << "]."); + socket->send(response); - std::ifstream file(path, std::ios::binary); - bool flush = true; - - // FIXME: Should compress once ahead of time - // compression of bundle.js takes significant time: - // 200's ms for level 9 (468k), 72ms for level 1(587k) - // down from 2Mb. - std::unique_ptr<char[]> buf(new char[st.st_size]); - do - { - static const unsigned int level = 1; - file.read(&buf[0], st.st_size); - const long unsigned int size = file.gcount(); - long unsigned int compSize = compressBound(size); - std::unique_ptr<char[]> cbuf(new char[compSize]); - compress2((Bytef *)&cbuf[0], &compSize, (Bytef *)&buf[0], size, level); - if (size > 0) - socket->send(&cbuf[0], compSize, flush); - else - break; - flush = false; - } - while(file); + if (!headerOnly) + sendDeflatedFileContent(socket, path, st.st_size); } } } diff --git a/net/Socket.hpp b/net/Socket.hpp index 0e616ddf..6f1397f0 100644 --- a/net/Socket.hpp +++ b/net/Socket.hpp @@ -915,13 +915,16 @@ protected: namespace HttpHelper { void sendFile(const std::shared_ptr<StreamSocket>& socket, const std::string& path, const std::string& mediaType, - Poco::Net::HTTPResponse& response, bool noCache = false, bool deflate = false); + Poco::Net::HTTPResponse& response, bool noCache = false, bool deflate = false, + const bool headerOnly = false); inline void sendFile(const std::shared_ptr<StreamSocket>& socket, const std::string& path, - const std::string& mediaType, bool noCache = false, bool deflate = false) + const std::string& mediaType, bool noCache = false, bool deflate = false, + const bool headerOnly = false) + { Poco::Net::HTTPResponse response; - sendFile(socket, path, mediaType, response, noCache, deflate); + sendFile(socket, path, mediaType, response, noCache, deflate, headerOnly); } }; _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits