diff options
author | Mike Kaganski <mike.kaganski@collabora.com> | 2019-01-09 10:54:10 +0300 |
---|---|---|
committer | Mike Kaganski <mike.kaganski@collabora.com> | 2019-06-28 08:33:46 +0200 |
commit | 20b1e6440aacab043753e93be4499e939a80b05b (patch) | |
tree | 1ac64459d876a7b2bf24afc70f115ad40b685e90 | |
parent | 80eb3fd393dd6d67f931c03b261b2558c7198da2 (diff) |
tdf#126121: WebDAV redirection detection
This rewrites URI of a document opened from a WebDAV mapped UNC path
on Windows (like "file://server/DavWWWRoot/Dir/Doc.odt") into HTTP URI
(like "http://server/Dir/Doc.odt"). This allows using WebDAV protocol
for these files, and e.g. get information about other user who locked
the document to show when asking if open read-only or a copy.
Change-Id: I643fa8df30d4b163783b279b1b973304fcafff37
Reviewed-on: https://gerrit.libreoffice.org/71746
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Tested-by: Mike Kaganski <mike.kaganski@collabora.com>
-rw-r--r-- | framework/source/loadenv/loadenv.cxx | 11 | ||||
-rw-r--r-- | include/tools/fileutil.hxx | 5 | ||||
-rw-r--r-- | sfx2/source/doc/docfile.cxx | 5 | ||||
-rw-r--r-- | tools/Library_tl.mk | 1 | ||||
-rw-r--r-- | tools/source/fsys/fileutil.cxx | 34 |
5 files changed, 40 insertions, 16 deletions
diff --git a/framework/source/loadenv/loadenv.cxx b/framework/source/loadenv/loadenv.cxx index ea048f75afab..412ffef4d8ac 100644 --- a/framework/source/loadenv/loadenv.cxx +++ b/framework/source/loadenv/loadenv.cxx @@ -90,6 +90,7 @@ #include <cppuhelper/implbase.hxx> #include <comphelper/profilezone.hxx> #include <classes/taskcreator.hxx> +#include <tools/fileutil.hxx> const char PROP_TYPES[] = "Types"; const char PROP_NAME[] = "Name"; @@ -247,21 +248,25 @@ void LoadEnv::initializeLoading(const OUString& sURL, const uno::Sequence<beans: m_bReactivateControllerOnError = false; m_bLoaded = false; + OUString aRealURL; + if (!tools::IsMappedWebDAVPath(sURL, &aRealURL)) + aRealURL = sURL; + // try to find out, if its really a content, which can be loaded or must be "handled" // We use a default value for this in-parameter. Then we have to start a complex check method // internally. But if this check was already done outside it can be suppressed to perform // the load request. We take over the result then! - m_eContentType = LoadEnv::classifyContent(sURL, lMediaDescriptor); + m_eContentType = LoadEnv::classifyContent(aRealURL, lMediaDescriptor); if (m_eContentType == E_UNSUPPORTED_CONTENT) throw LoadEnvException(LoadEnvException::ID_UNSUPPORTED_CONTENT, "from LoadEnv::initializeLoading"); // make URL part of the MediaDescriptor // It doesn't matter if it is already an item of it. // It must be the same value... so we can overwrite it :-) - m_lMediaDescriptor[utl::MediaDescriptor::PROP_URL()] <<= sURL; + m_lMediaDescriptor[utl::MediaDescriptor::PROP_URL()] <<= aRealURL; // parse it - because some following code require that - m_aURL.Complete = sURL; + m_aURL.Complete = aRealURL; uno::Reference<util::XURLTransformer> xParser(util::URLTransformer::create(m_xContext)); xParser->parseStrict(m_aURL); diff --git a/include/tools/fileutil.hxx b/include/tools/fileutil.hxx index 06e7bf820992..d2ed87a6dff6 100644 --- a/include/tools/fileutil.hxx +++ b/include/tools/fileutil.hxx @@ -11,15 +11,14 @@ #define INCLUDED_TOOLS_FILEUTIL_HXX #include <tools/toolsdllapi.h> - -class INetURLObject; +#include <rtl/ustring.hxx> namespace tools { // Tests if the path is a UNC or local (drive-based) path that redirects to // a WebDAV resource (e.g., using redirectors on Windows). // Currently only implemented for Windows; on other platforms, returns false. -TOOLS_DLLPUBLIC bool IsMappedWebDAVPath(const INetURLObject& aURL); +TOOLS_DLLPUBLIC bool IsMappedWebDAVPath(const OUString& rURL, OUString* pRealURL = nullptr); } #endif // INCLUDED_TOOLS_FILEUTIL_HXX diff --git a/sfx2/source/doc/docfile.cxx b/sfx2/source/doc/docfile.cxx index 46d75db945c3..da295c476991 100644 --- a/sfx2/source/doc/docfile.cxx +++ b/sfx2/source/doc/docfile.cxx @@ -242,7 +242,7 @@ bool IsFileMovable(const INetURLObject& rURL) if (buf.st_nlink > 1 || S_ISLNK(buf.st_mode)) return false; #elif defined _WIN32 - if (tools::IsMappedWebDAVPath(rURL)) + if (tools::IsMappedWebDAVPath(rURL.GetMainURL(INetURLObject::DecodeMechanism::NONE))) return false; #endif @@ -1382,7 +1382,8 @@ SfxMedium::LockFileResult SfxMedium::LockOrigFileOnDemand( bool bLoading, bool b } catch (const uno::Exception&) { - if (tools::IsMappedWebDAVPath(GetURLObject())) + if (tools::IsMappedWebDAVPath(GetURLObject().GetMainURL( + INetURLObject::DecodeMechanism::NONE))) { // This is a path that redirects to a WebDAV resource; // so failure creating lockfile is not an error here. diff --git a/tools/Library_tl.mk b/tools/Library_tl.mk index 9f3df2dc825f..54f200e5dbb5 100644 --- a/tools/Library_tl.mk +++ b/tools/Library_tl.mk @@ -110,6 +110,7 @@ ifeq ($(OS),WNT) $(eval $(call gb_Library_use_system_win32_libs,tl,\ mpr \ + netapi32 \ ole32 \ shell32 \ uuid \ diff --git a/tools/source/fsys/fileutil.cxx b/tools/source/fsys/fileutil.cxx index 731afa58e63e..9470fabd2fee 100644 --- a/tools/source/fsys/fileutil.cxx +++ b/tools/source/fsys/fileutil.cxx @@ -9,24 +9,40 @@ #include <tools/fileutil.hxx> #if defined _WIN32 -#include <tools/urlobj.hxx> #include <osl/file.hxx> -#include <string.h> #include <o3tl/char16_t2wchar_t.hxx> #define WIN32_LEAN_AND_MEAN #include <Windows.h> +#include <davclnt.h> #endif +namespace +{ +#if defined _WIN32 +OUString UNCToDavURL(LPCWSTR sUNC) +{ + DWORD nSize = 1024; + auto bufURL(std::make_unique<wchar_t[]>(nSize)); + DWORD nResult = DavGetHTTPFromUNCPath(sUNC, bufURL.get(), &nSize); + if (nResult == ERROR_INSUFFICIENT_BUFFER) + { + bufURL = std::make_unique<wchar_t[]>(nSize); + nResult = DavGetHTTPFromUNCPath(sUNC, bufURL.get(), &nSize); + } + return nResult == ERROR_SUCCESS ? o3tl::toU(bufURL.get()) : OUString(); +} +#endif +} + namespace tools { -bool IsMappedWebDAVPath(const INetURLObject& aURL) +bool IsMappedWebDAVPath([[maybe_unused]] const OUString& rURL, [[maybe_unused]] OUString* pRealURL) { #if defined _WIN32 - if (aURL.GetProtocol() == INetProtocol::File) + if (rURL.startsWithIgnoreAsciiCase("file:")) { - OUString sURL = aURL.GetMainURL(INetURLObject::DecodeMechanism::NONE); OUString aSystemPath; - if (osl::FileBase::getSystemPathFromFileURL(sURL, aSystemPath) == osl::FileBase::E_None) + if (osl::FileBase::getSystemPathFromFileURL(rURL, aSystemPath) == osl::FileBase::E_None) { DWORD nSize = MAX_PATH; auto bufUNC(std::make_unique<char[]>(nSize)); @@ -61,13 +77,15 @@ bool IsMappedWebDAVPath(const INetURLObject& aURL) { LPNETRESOURCEW pInfo = reinterpret_cast<LPNETRESOURCEW>(bufInfo.get()); if (wcscmp(pInfo->lpProvider, L"Web Client Network") == 0) + { + if (pRealURL) + *pRealURL = UNCToDavURL(aReq.lpRemoteName); return true; + } } } } } -#else - (void)aURL; #endif return false; } |