summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiuseppe Castagno <giuseppe.castagno@acca-esse.eu>2016-01-10 16:46:19 +0100
committerGiuseppe Castagno <giuseppe.castagno@acca-esse.eu>2016-07-29 07:10:23 +0000
commit6ab2cabeae02b6beb3c33238773ba075f41c4bb9 (patch)
treeacb730f6eb03984f7d99822cd13031a39f39178f
parent73cd9c480c681d076e837aa7ba1ea706de3f3d0e (diff)
tdf#101094 (8) OPTIONS: Add options check in Content::resourceTypeForLocks
Change-Id: Ia1bcc1be9e61626da2d60ea679d4b6e7e114ac9f Reviewed-on: https://gerrit.libreoffice.org/27661 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Giuseppe Castagno <giuseppe.castagno@acca-esse.eu>
-rw-r--r--ucb/source/ucp/webdav-neon/webdavcontent.cxx196
-rw-r--r--ucb/source/ucp/webdav-neon/webdavcontent.hxx6
2 files changed, 126 insertions, 76 deletions
diff --git a/ucb/source/ucp/webdav-neon/webdavcontent.cxx b/ucb/source/ucp/webdav-neon/webdavcontent.cxx
index f91a50cc64ef..3c40ad856656 100644
--- a/ucb/source/ucp/webdav-neon/webdavcontent.cxx
+++ b/ucb/source/ucp/webdav-neon/webdavcontent.cxx
@@ -2782,7 +2782,8 @@ void Content::destroy( bool bDeletePhysical )
// returns the resource type, to be checked for locks
Content::ResourceType Content::resourceTypeForLocks(
- const uno::Reference< ucb::XCommandEnvironment >& Environment )
+ const uno::Reference< ucb::XCommandEnvironment >& Environment,
+ const std::unique_ptr< DAVResourceAccess > & rResAccess)
{
ResourceType eResourceTypeForLocks = UNKNOWN;
{
@@ -2814,12 +2815,6 @@ Content::ResourceType Content::resourceTypeForLocks(
if ( eResourceTypeForLocks == UNKNOWN )
{
// resource type for lock/unlock operations still unknown, need to ask the server
- std::unique_ptr< DAVResourceAccess > xResAccess;
-
- xResAccess.reset( new DAVResourceAccess(
- m_xContext,
- m_rSessionFactory,
- rURL ) );
const OUString aScheme(
rURL.copy( 0, rURL.indexOf( ':' ) ).toAsciiLowerCase() );
@@ -2830,89 +2825,125 @@ Content::ResourceType Content::resourceTypeForLocks(
}
else
{
- try
+ DAVOptions aDAVOptions;
+ getResourceOptions( Environment, aDAVOptions, rResAccess );
+ if( aDAVOptions.isClass1() ||
+ aDAVOptions.isClass2() ||
+ aDAVOptions.isClass3() )
{
- // we need only DAV:supportedlock
- std::vector< DAVResource > resources;
- std::vector< OUString > aPropNames;
- uno::Sequence< beans::Property > aProperties( 1 );
- aProperties[ 0 ].Name = DAVProperties::SUPPORTEDLOCK;
-
- ContentProperties::UCBNamesToDAVNames( aProperties, aPropNames );
- xResAccess->PROPFIND( DAVZERO, aPropNames, resources, Environment );
-
- // only one resource should be returned
- if ( resources.size() == 1 )
+ // this is at least a DAV, lock to be confirmed
+ // class 2 is needed for full lock support
+ // see
+ // <https://tools.ietf.org/html/rfc4918#section-18.2>
+ eResourceTypeForLocks = DAV_NOLOCK;
+ if( aDAVOptions.isClass2() )
{
- // we may have received a bunch of other properties
- // (some servers seems to do so)
- // but we need only supported lock for this check
- // all returned properties are in
- // resources.properties[n].Name/.Value
+ // ok, possible lock, check for it
+ try
+ {
+ // we need only DAV:supportedlock
+ std::vector< DAVResource > resources;
+ std::vector< OUString > aPropNames;
+ uno::Sequence< beans::Property > aProperties( 1 );
+ aProperties[ 0 ].Name = DAVProperties::SUPPORTEDLOCK;
- std::vector< DAVPropertyValue >::iterator it;
+ ContentProperties::UCBNamesToDAVNames( aProperties, aPropNames );
+ rResAccess->PROPFIND( DAVZERO, aPropNames, resources, Environment );
- for ( it = resources[0].properties.begin();
- it != resources[0].properties.end(); ++it)
- {
- if ( (*it).Name == DAVProperties::SUPPORTEDLOCK )
+ bool wasSupportedlockFound = false;
+
+ // only one resource should be returned
+ if ( resources.size() == 1 )
{
- uno::Sequence< ucb::LockEntry > aSupportedLocks;
- if ( (*it).Value >>= aSupportedLocks )
+ // we may have received a bunch of other properties
+ // (some servers seems to do so)
+ // but we need only supported lock for this check
+ // all returned properties are in
+ // resources.properties[n].Name/.Value
+
+ std::vector< DAVPropertyValue >::iterator it;
+
+ for ( it = resources[0].properties.begin();
+ it != resources[0].properties.end(); ++it)
{
- // this is at least a DAV, no lock confirmed yet
- eResourceTypeForLocks = DAV_NOLOCK;
- for ( sal_Int32 n = 0; n < aSupportedLocks.getLength(); ++n )
+ if ( (*it).Name == DAVProperties::SUPPORTEDLOCK )
{
- if ( aSupportedLocks[ n ].Scope == ucb::LockScope_EXCLUSIVE &&
- aSupportedLocks[ n ].Type == ucb::LockType_WRITE )
+ wasSupportedlockFound = true;
+ uno::Sequence< ucb::LockEntry > aSupportedLocks;
+ if ( (*it).Value >>= aSupportedLocks )
{
- // requested locking mode is supported
- eResourceTypeForLocks = DAV;
- SAL_INFO( "ucb.ucp.webdav", "resourceTypeForLocks - URL: <"
- << m_xIdentifier->getContentIdentifier() << ">, DAV lock/unlock supported");
+ for ( sal_Int32 n = 0; n < aSupportedLocks.getLength(); ++n )
+ {
+ // TODO: if the lock type is changed from 'exclusive write' to 'shared write'
+ // e.g. to implement 'Calc shared file feature', the ucb::LockScope_EXCLUSIVE
+ // value should be checked as well, adaptation the code may be needed
+ if ( aSupportedLocks[ n ].Scope == ucb::LockScope_EXCLUSIVE &&
+ aSupportedLocks[ n ].Type == ucb::LockType_WRITE )
+ {
+ // requested locking mode is supported
+ eResourceTypeForLocks = DAV;
+ SAL_INFO( "ucb.ucp.webdav", "resourceTypeForLocks - URL: <"
+ << m_xIdentifier->getContentIdentifier() << ">, DAV lock/unlock supported");
+ break;
+ }
+ }
break;
}
}
- break;
}
}
+ // check if this is still only a DAV_NOLOCK
+ // a fallback for resources that do not have DAVProperties::SUPPORTEDLOCK property
+ // we check for the returned OPTION if LOCK is allowed on the resource
+ if ( !wasSupportedlockFound && eResourceTypeForLocks == DAV_NOLOCK )
+ {
+ SAL_INFO( "ucb.ucp.webdav", "This WebDAV server has no supportedlock property, check for allowed LOCK method in OPTIONS" );
+ // ATTENTION: if the lock type is changed from 'exclusive write' to 'shared write'
+ // e.g. to implement 'Calc shared file feature' on WebDAV directly, and we arrive to this fallback
+ // and the LOCK is allowed, we should assume that only exclusive write lock is available
+ // this is just a reminder...
+ if ( aDAVOptions.isLockAllowed() )
+ eResourceTypeForLocks = DAV;
+ }
+ }
+ catch ( DAVException const & e )
+ {
+ rResAccess->resetUri();
+ //grab the error code
+ switch( e.getStatus() )
+ {
+ case SC_NOT_FOUND:
+ SAL_WARN( "ucb.ucp.webdav", "resourceTypeForLocks() - URL: <"
+ << m_xIdentifier->getContentIdentifier() << "> was not found. ");
+ eResourceTypeForLocks = NOT_FOUND;
+ break;
+ // some servers returns SC_FORBIDDEN, instead
+ // TODO: probably remove it, when OPTIONS implemented
+ // the meaning of SC_FORBIDDEN is, according to <http://tools.ietf.org/html/rfc7231#section-6.5.3>:
+ // The 403 (Forbidden) status code indicates that the server understood
+ // the request but refuses to authorize it
+ case SC_FORBIDDEN:
+ // Errors SC_NOT_IMPLEMENTED and SC_METHOD_NOT_ALLOWED are
+ // part of base http 1.1 RFCs
+ case SC_NOT_IMPLEMENTED: // <http://tools.ietf.org/html/rfc7231#section-6.6.2>
+ case SC_METHOD_NOT_ALLOWED: // <http://tools.ietf.org/html/rfc7231#section-6.5.5>
+ // they all mean the resource is NON_DAV
+ SAL_WARN( "ucb.ucp.webdav", "resourceTypeForLocks() DAVException (SC_FORBIDDEN, SC_NOT_IMPLEMENTED or SC_METHOD_NOT_ALLOWED) - URL: <"
+ << m_xIdentifier->getContentIdentifier() << ">, DAV error: " << e.getError() << ", HTTP error: " << e.getStatus() );
+ eResourceTypeForLocks = NON_DAV;
+ break;
+ default:
+ //fallthrough
+ SAL_WARN( "ucb.ucp.webdav", "resourceTypeForLocks() DAVException - URL: <"
+ << m_xIdentifier->getContentIdentifier() << ">, DAV error: " << e.getError() << ", HTTP error: " << e.getStatus() );
+ eResourceTypeForLocks = UNKNOWN;
+ }
}
}
}
- catch ( DAVException const & e )
- {
- xResAccess->resetUri();
- //grab the error code
- switch( e.getStatus() )
- {
- case SC_NOT_FOUND:
- SAL_WARN( "ucb.ucp.webdav", "resourceTypeForLocks() - URL: <"
- << m_xIdentifier->getContentIdentifier() << "> was not found. ");
- eResourceTypeForLocks = NOT_FOUND;
- break;
- // some servers returns SC_FORBIDDEN, instead
- // TODO: probably remove it, when OPTIONS implemented
- // the meaning of SC_FORBIDDEN is, according to <http://tools.ietf.org/html/rfc7231#section-6.5.3>:
- // The 403 (Forbidden) status code indicates that the server understood
- // the request but refuses to authorize it
- case SC_FORBIDDEN:
- // Errors SC_NOT_IMPLEMENTED and SC_METHOD_NOT_ALLOWED are
- // part of base http 1.1 RFCs
- case SC_NOT_IMPLEMENTED: // <http://tools.ietf.org/html/rfc7231#section-6.6.2>
- case SC_METHOD_NOT_ALLOWED: // <http://tools.ietf.org/html/rfc7231#section-6.5.5>
- // they all mean the resource is NON_DAV
- SAL_WARN( "ucb.ucp.webdav", "resourceTypeForLocks() DAVException (SC_FORBIDDEN, SC_NOT_IMPLEMENTED or SC_METHOD_NOT_ALLOWED) - URL: <"
- << m_xIdentifier->getContentIdentifier() << ">, DAV error: " << e.getError() << ", HTTP error: " << e.getStatus() );
- eResourceTypeForLocks = NON_DAV;
- break;
- default:
- //fallthrough
- SAL_WARN( "ucb.ucp.webdav", "resourceTypeForLocks() DAVException - URL: <"
- << m_xIdentifier->getContentIdentifier() << ">, DAV error: " << e.getError() << ", HTTP error: " << e.getStatus() );
- eResourceTypeForLocks = UNKNOWN;
- }
- }
+ else
+ eResourceTypeForLocks = NON_DAV;
+
}
}
osl::MutexGuard g(m_aMutex);
@@ -2932,6 +2963,21 @@ Content::ResourceType Content::resourceTypeForLocks(
return m_eResourceTypeForLocks;
}
+Content::ResourceType Content::resourceTypeForLocks(
+ const uno::Reference< ucb::XCommandEnvironment >& Environment )
+{
+ std::unique_ptr< DAVResourceAccess > xResAccess;
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+ xResAccess.reset( new DAVResourceAccess( *m_xResAccess.get() ) );
+ }
+ Content::ResourceType ret = resourceTypeForLocks( Environment, xResAccess );
+ {
+ osl::Guard< osl::Mutex > aGuard( m_aMutex );
+ m_xResAccess.reset( new DAVResourceAccess( *xResAccess.get() ) );
+ }
+ return ret;
+}
void Content::lock(
const uno::Reference< ucb::XCommandEnvironment >& Environment )
@@ -2986,7 +3032,7 @@ void Content::lock(
// this exception is mapped directly to the ucb correct one, without
// going into the cancelCommandExecution() user interaction
// this exception should be managed by the issuer of 'lock' command
- switch(e.getError())
+ switch( e.getError() )
{
case DAVException::DAV_LOCKED:
{
diff --git a/ucb/source/ucp/webdav-neon/webdavcontent.hxx b/ucb/source/ucp/webdav-neon/webdavcontent.hxx
index 016f93cb3bf4..a6cb37805a43 100644
--- a/ucb/source/ucp/webdav-neon/webdavcontent.hxx
+++ b/ucb/source/ucp/webdav-neon/webdavcontent.hxx
@@ -184,7 +184,11 @@ private:
static bool shouldAccessNetworkAfterException( const DAVException & e );
ResourceType resourceTypeForLocks(
- const css::uno::Reference< css::ucb::XCommandEnvironment >& Environment );
+ const css::uno::Reference< css::ucb::XCommandEnvironment >& rEnvironment,
+ const std::unique_ptr< DAVResourceAccess > & rResAccess );
+
+ ResourceType resourceTypeForLocks(
+ const css::uno::Reference< css::ucb::XCommandEnvironment >& rEnvironment );
void addProperty( const css::ucb::PropertyCommandArgument &aCmdArg,
const css::uno::Reference< css::ucb::XCommandEnvironment >& Environment )