From 3a9e536dfab71f6999a39d7371a9dd8844815ae7 Mon Sep 17 00:00:00 2001 From: Tor Lillqvist Date: Thu, 12 Jul 2018 17:46:03 +0300 Subject: [PATCH] When asked to convert to PNG, look for an embedded ODF thumbnail first Change-Id: Ib777572fe5f79b1cfdd95ec3a7f84484a13ae145 --- configure.ac | 2 +- wsd/LOOLWSD.cpp | 48 ++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 43 insertions(+), 7 deletions(-) diff --git a/configure.ac b/configure.ac index 421fdd686d..823378d6e4 100644 --- a/configure.ac +++ b/configure.ac @@ -332,7 +332,7 @@ else fi AC_SUBST(ENABLE_SUPPORT_KEY) -LIBS="$LIBS -lPocoNet${POCO_DEBUG_SUFFIX} -lPocoUtil${POCO_DEBUG_SUFFIX} -lPocoJSON${POCO_DEBUG_SUFFIX} -lPocoFoundation${POCO_DEBUG_SUFFIX} -lPocoXML${POCO_DEBUG_SUFFIX} -lPocoNetSSL${POCO_DEBUG_SUFFIX} -lPocoCrypto${POCO_DEBUG_SUFFIX}" +LIBS="$LIBS -lPocoNet${POCO_DEBUG_SUFFIX} -lPocoUtil${POCO_DEBUG_SUFFIX} -lPocoJSON${POCO_DEBUG_SUFFIX} -lPocoFoundation${POCO_DEBUG_SUFFIX} -lPocoXML${POCO_DEBUG_SUFFIX} -lPocoNetSSL${POCO_DEBUG_SUFFIX} -lPocoCrypto${POCO_DEBUG_SUFFIX} -lPocoZip${POCO_DEBUG_SUFFIX}" AC_CHECK_HEADERS([LibreOfficeKit/LibreOfficeKit.h], [], diff --git a/wsd/LOOLWSD.cpp b/wsd/LOOLWSD.cpp index 1854d8cc2f..3b47fac4e7 100644 --- a/wsd/LOOLWSD.cpp +++ b/wsd/LOOLWSD.cpp @@ -91,6 +91,8 @@ #include #include #include +#include +#include #include "Admin.hpp" #include "Auth.hpp" @@ -2058,15 +2060,49 @@ class ClientRequestDispatcher : public SocketHandlerInterface std::string thumbnailFile; if (format == "png") { - // Check whether we already have a cached "thumbnail" for this document. - - // FIXME: We could here check if the document is such that already contains an - // easily extractable thumbnail, like Thubnails/thumbnail.png in ODF documents, - // and extract and return that. - std::ifstream istr(fromPath, std::ios::binary); if (istr.is_open() && istr.good()) { + // Check whether it is an ODF document with an embedded PNG thumbnail. + + try + { + Poco::Zip::ZipArchive zip(istr); + auto thumbnailHeader = zip.findHeader("Thumbnails/thumbnail.png"); + if (thumbnailHeader != zip.headerEnd() && thumbnailHeader->second.isFile()) + { + Poco::Zip::ZipStreamBuf thumbnailStreamBuf(istr, thumbnailHeader->second, true); + std::istream thumbnailStream(&thumbnailStreamBuf); + if (thumbnailStream.good()) + { + std::string png; + Poco::StreamCopier::copyToString(thumbnailStream, png); + if (!thumbnailStream.bad()) + { + LOG_TRC("Extracted thumbnail from ODF document"); + + response.set("Content-Disposition", "attachment; filename=\"thumbnail.png\""); + response.setContentType("image/png"); + response.setContentLength(png.size()); + socket->send(response); + socket->send(png.data(), png.size(), true); + + return; + } + } + } + } + catch (Poco::Exception&) + { + } + + // Close and re-open istr after the Zip stuff above to get it into a known + // good state. + istr.close(); + istr.open(fromPath, std::ios::binary); + + // Look for cached thumbnail. + Poco::SHA1Engine sha1; Poco::DigestOutputStream dos(sha1); Poco::StreamCopier::copyStream(istr, dos);