[Libreoffice-commits] online.git: net/Socket.cpp net/Socket.hpp

Ashod Nakashian ashod.nakashian at collabora.co.uk
Mon Apr 24 04:48:07 UTC 2017


 net/Socket.cpp |  112 ++++++++++++++++++++++++++++++---------------------------
 net/Socket.hpp |    9 +++-
 2 files changed, 66 insertions(+), 55 deletions(-)

New commits:
commit 988ddaf7be50c556618685a52f0c0f724947274d
Author: Ashod Nakashian <ashod.nakashian at 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 <ashnakash at gmail.com>
    Tested-by: Ashod Nakashian <ashnakash at 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);
     }
 };
 


More information about the Libreoffice-commits mailing list