[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-5.1' - ucb/source

Mike Kaganski mike.kaganski at collabora.com
Wed Apr 5 13:03:55 UTC 2017


 ucb/source/ucp/webdav-neon/webdavcontent.cxx |   90 ++++++++++++++++++++++++++-
 1 file changed, 87 insertions(+), 3 deletions(-)

New commits:
commit 8b23a7d1de1fa8d80918874401febde6f25b0b9e
Author: Mike Kaganski <mike.kaganski at collabora.com>
Date:   Tue Apr 4 18:42:51 2017 +0300

    tdf#106955: Open WebDAV resources on which PROPFIND fails
    
    When PROPFIND fails on a WebDAV resource, its IsDocument property
    stays undefined, and so stream creation fails. Proposed solution
    is to default to IsDocument=true for all WebDAV documents where
    we cannot get the property from server.
    
    Such resources also fail to return their locking options, so
    defaulting to server properties. When later locking is attempted
    on it, the attempt fails with user notification (a dialog saying
    that getting information from server failed). Proposed solution
    is to check Content-Disposition header in such resources, and in
    case it's attachment, disable lock on this resource. The rationale
    for this is that "In a regular HTTP response, the Content-Disposition
    response header is a header indicating if the content is expected
    to be displayed ... as an attachment, that is downloaded and saved
    locally" (see MDN:
    https://developer.mozilla.org/en/docs/Web/HTTP/Headers/Content-Disposition
    
    Reviewed-on: https://gerrit.libreoffice.org/36090
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Mike Kaganski <mike.kaganski at collabora.com>
    (cherry picked from commit fbc04c97231d629c1b5e9e57203dbe8d8eb06714)
    
    Change-Id: I91dbffa8bdf0fe900c11d2f8c9c9394d2104bb49
    Reviewed-on: https://gerrit.libreoffice.org/36141
    Reviewed-by: Mike Kaganski <mike.kaganski at collabora.com>
    Tested-by: Mike Kaganski <mike.kaganski at collabora.com>

diff --git a/ucb/source/ucp/webdav-neon/webdavcontent.cxx b/ucb/source/ucp/webdav-neon/webdavcontent.cxx
index 702e57e47c60..ec4f4395dc1f 100644
--- a/ucb/source/ucp/webdav-neon/webdavcontent.cxx
+++ b/ucb/source/ucp/webdav-neon/webdavcontent.cxx
@@ -1203,6 +1203,18 @@ uno::Reference< sdbc::XRow > Content::getPropertyValues(
     return uno::Reference< sdbc::XRow >( xRow.get() );
 }
 
+namespace {
+void GetPropsUsingHeadRequest(DAVResource& resource,
+                              const std::unique_ptr< DAVResourceAccess >& xResAccess,
+                              const std::vector< OUString >& aHTTPNames,
+                              const uno::Reference< ucb::XCommandEnvironment >& xEnv)
+{
+    if (!aHTTPNames.empty())
+    {
+        xResAccess->HEAD(aHTTPNames, resource, xEnv);
+    }
+}
+}
 
 uno::Reference< sdbc::XRow > Content::getPropertyValues(
                 const uno::Sequence< beans::Property >& rProperties,
@@ -1387,7 +1399,7 @@ uno::Reference< sdbc::XRow > Content::getPropertyValues(
                     try
                     {
                         DAVResource resource;
-                        xResAccess->HEAD( aHeaderNames, resource, xEnv );
+                        GetPropsUsingHeadRequest( resource, xResAccess, aHeaderNames, xEnv );
                         m_bDidGetOrHead = true;
 
                         if ( xProps.get() )
@@ -1469,6 +1481,46 @@ uno::Reference< sdbc::XRow > Content::getPropertyValues(
                                                  m_bCollection ) );
     }
 
+    // Add a default for the properties requested but not found.
+    // Determine still missing properties, add a default.
+    // Some client function doesn't expect a void uno::Any,
+    // but instead wants some sort of default.
+    std::vector< OUString > aMissingProps;
+    if ( !xProps->containsAllNames(
+                rProperties, aMissingProps ) )
+    {
+        //
+        for ( std::vector< rtl::OUString >::const_iterator it = aMissingProps.begin();
+              it != aMissingProps.end(); ++it )
+        {
+            // For the time being only a couple of properties need to be added
+            if ( (*it) == "DateModified"  || (*it) == "DateCreated" )
+            {
+                util::DateTime aDate;
+                xProps->addProperty(
+                    (*it),
+                    uno::makeAny( aDate ),
+                    true );
+            }
+            // If WebDAV didn't return the resource type, assume default
+            // This happens e.g. for lists exported by SharePoint
+            else if ( (*it) == "IsFolder" )
+            {
+                xProps->addProperty(
+                    (*it),
+                    uno::makeAny( false ),
+                    true );
+            }
+            else if ( (*it) == "IsDocument" )
+            {
+                xProps->addProperty(
+                    (*it),
+                    uno::makeAny( true ),
+                    true );
+            }
+        }
+    }
+
     sal_Int32 nCount = rProperties.getLength();
     for ( sal_Int32 n = 0; n < nCount; ++n )
     {
@@ -2756,8 +2808,6 @@ Content::ResourceType Content::resourceTypeForLocks(
         std::unique_ptr< ContentProperties > xProps;
         if ( m_xCachedProps.get() )
         {
-            std::unique_ptr< ContentProperties > xCachedProps;
-            xCachedProps.reset( new ContentProperties( *m_xCachedProps.get() ) );
             uno::Sequence< ucb::LockEntry > aSupportedLocks;
             if ( m_xCachedProps->getValue( DAVProperties::SUPPORTEDLOCK )
                  >>= aSupportedLocks )            //get the cached value for supportedlock
@@ -2844,6 +2894,40 @@ Content::ResourceType Content::resourceTypeForLocks(
                         }
                     }
                 }
+                else
+                {
+                    // PROPFIND failed; check if HEAD contains Content-Disposition: attachment (RFC1806, HTTP/1.1 19.5.1),
+                    // which supposedly means no lock for the resource (happens e.g. with SharePoint exported lists)
+                    OUString sContentDisposition;
+                    // First, check cached properties
+                    if (m_xCachedProps.get())
+                    {
+                        if ((m_xCachedProps->getValue("Content-Disposition") >>= sContentDisposition)
+                            && sContentDisposition.startsWithIgnoreAsciiCase("attachment"))
+                        {
+                            eResourceTypeForLocks = DAV_NOLOCK;
+                        }
+                    }
+                    // If no data in cache, try HEAD request
+                    if (sContentDisposition.isEmpty() && !m_bDidGetOrHead) try
+                    {
+                        DAVResource resource;
+                        GetPropsUsingHeadRequest(resource, xResAccess, {"Content-Disposition"}, Environment);
+                        m_bDidGetOrHead = true;
+                        for (const auto& it : resource.properties)
+                        {
+                            if (it.Name.equalsIgnoreAsciiCase("Content-Disposition"))
+                            {
+                                if ((it.Value >>= sContentDisposition) && sContentDisposition.equalsIgnoreAsciiCase("attachment"))
+                                {
+                                    eResourceTypeForLocks = DAV_NOLOCK;
+                                }
+                                break;
+                            }
+                        }
+                    }
+                    catch (...){}
+                }
             }
             catch ( DAVException const & e )
             {


More information about the Libreoffice-commits mailing list