summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ucb/source/ucp/webdav-neon/DAVTypes.cxx29
-rw-r--r--ucb/source/ucp/webdav-neon/DAVTypes.hxx8
-rw-r--r--ucb/source/ucp/webdav-neon/webdavcontent.cxx56
-rw-r--r--ucb/source/ucp/webdav-neon/webdavcontent.hxx3
4 files changed, 88 insertions, 8 deletions
diff --git a/ucb/source/ucp/webdav-neon/DAVTypes.cxx b/ucb/source/ucp/webdav-neon/DAVTypes.cxx
index af1079ca66e6..875699418f2c 100644
--- a/ucb/source/ucp/webdav-neon/DAVTypes.cxx
+++ b/ucb/source/ucp/webdav-neon/DAVTypes.cxx
@@ -24,6 +24,7 @@ DAVOptions::DAVOptions() :
m_isClass1( false ),
m_isClass2( false ),
m_isClass3( false ),
+ m_isHeadAllowed( true ),
m_isLocked( false ),
m_aAllowedMethods(),
m_nStaleTime( 0 ),
@@ -38,6 +39,7 @@ DAVOptions::DAVOptions( const DAVOptions & rOther ) :
m_isClass1( rOther.m_isClass1 ),
m_isClass2( rOther.m_isClass2 ),
m_isClass3( rOther.m_isClass3 ),
+ m_isHeadAllowed( rOther.m_isHeadAllowed ),
m_isLocked( rOther.m_isLocked ),
m_aAllowedMethods( rOther.m_aAllowedMethods ),
m_nStaleTime( rOther.m_nStaleTime ),
@@ -173,5 +175,32 @@ bool DAVOptionsCache::isResourceFound( const OUString & rURL )
return true;
}
+bool DAVOptionsCache::isHeadAllowed( const OUString & rURL )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+ OUString aEncodedUrl( ucb_impl::urihelper::encodeURI( NeonUri::unescape( rURL ) ) );
+ normalizeURLLastChar( aEncodedUrl );
+
+ DAVOptionsMap::iterator it;
+ it = m_aTheCache.find( aEncodedUrl );
+ if ( it != m_aTheCache.end() )
+ {
+ // first check for stale
+ TimeValue t1;
+ osl_getSystemTime( &t1 );
+ if( (*it).second.getStaleTime() < t1.Seconds )
+ {
+ m_aTheCache.erase( it );
+ return true; // to force again OPTIONS method
+ }
+
+ // check if the resource was present on server
+ return (*it).second.isHeadAllowed();
+ }
+ // this value is needed because some web server don't implement
+ // OPTIONS method, so the resource is considered found,
+ // until detected otherwise
+ return true;
+}
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/ucb/source/ucp/webdav-neon/DAVTypes.hxx b/ucb/source/ucp/webdav-neon/DAVTypes.hxx
index 53bc7390d77c..037e68fec8fe 100644
--- a/ucb/source/ucp/webdav-neon/DAVTypes.hxx
+++ b/ucb/source/ucp/webdav-neon/DAVTypes.hxx
@@ -81,6 +81,8 @@ namespace webdav_ucp
bool m_isClass1;
bool m_isClass2;
bool m_isClass3;
+ // for server that do not implement it
+ bool m_isHeadAllowed;
// Internally used to maintain locked stated of the resource, only
// if it's a Class 2 resource
bool m_isLocked;
@@ -111,6 +113,9 @@ namespace webdav_ucp
bool isClass3() { return m_isClass3; };
void setClass3( bool Class3 = true ) { m_isClass3 = Class3; };
+ bool isHeadAllowed() { return m_isHeadAllowed; };
+ void setHeadAllowed( bool HeadAllowed = true ) { m_isHeadAllowed = HeadAllowed; };
+
sal_uInt32 getStaleTime() const { return m_nStaleTime ; };
void setStaleTime( const sal_uInt32 nStaleTime ) { m_nStaleTime = nStaleTime; };
@@ -133,6 +138,7 @@ namespace webdav_ucp
m_isClass1 = false;
m_isClass2 = false;
m_isClass3 = false;
+ m_isHeadAllowed = true;
m_isLocked = false;
m_aAllowedMethods.clear();
m_nStaleTime = 0;
@@ -177,6 +183,8 @@ namespace webdav_ucp
*/
bool isResourceFound( const OUString & rURL );
+ bool isHeadAllowed( const OUString & rURL );
+
private:
/// remove the last '/' in aUrl, if it exists
diff --git a/ucb/source/ucp/webdav-neon/webdavcontent.cxx b/ucb/source/ucp/webdav-neon/webdavcontent.cxx
index be3258294a51..a5d640677b96 100644
--- a/ucb/source/ucp/webdav-neon/webdavcontent.cxx
+++ b/ucb/source/ucp/webdav-neon/webdavcontent.cxx
@@ -1589,6 +1589,10 @@ uno::Reference< sdbc::XRow > Content::getPropertyValues(
// clean cached value of PROPFIND property names
// PROPPATCH can change them
removeCachedPropertyNames( xResAccess->getURL() );
+ // test if HEAD allowed, if not, throw, will be catched immediately
+ if ( !aStaticDAVOptionsCache.isHeadAllowed( xResAccess->getURL() ) )
+ throw DAVException( DAVException::DAV_HTTP_ERROR, "405 Not Implemented" );
+
xResAccess->HEAD( aHeaderNames, resource, xEnv );
m_bDidGetOrHead = true;
@@ -4075,7 +4079,7 @@ void Content::getResourceOptions(
// instead of SC_NOT_IMPLEMENTED or SC_METHOD_NOT_ALLOWED.
// So check if this is an available resource, or a real 'Not Found' event.
sal_uInt32 nLifeTime = m_nOptsCacheLifeNotFound;
- if( isResourceAvailable(xEnv, rResAccess ) )
+ if( isResourceAvailable( xEnv, rResAccess, rDAVOptions ) )
{
nLifeTime = m_nOptsCacheLifeNotImpl;
rDAVOptions.setResourceFound(); // means it exists, but it's not DAV
@@ -4134,17 +4138,54 @@ void Content::getResourceOptions(
//static
bool Content::isResourceAvailable( const css::uno::Reference< css::ucb::XCommandEnvironment >& xEnv,
- const std::unique_ptr< DAVResourceAccess > & rResAccess )
+ const std::unique_ptr< DAVResourceAccess > & rResAccess,
+ DAVOptions& rDAVOptions )
{
+ std::vector< rtl::OUString > aHeaderNames;
+ DAVResource aResource;
+
try
{
- // To check for the physical URL resource availability, using a simple HEAD command
- // if HEAD is successfull, set element found.
- std::vector< OUString > aHeaderNames;
- DAVResource resource;
- rResAccess->HEAD( aHeaderNames, resource, xEnv );
+ // To check for the physical URL resource availability, first
+ // try using a simple HEAD command
+ // if HEAD is successfull, set element found,
+ rResAccess->HEAD( aHeaderNames, aResource, xEnv );
return true;
}
+ catch ( DAVException const & e )
+ {
+ if ( e.getStatus() == SC_NOT_IMPLEMENTED ||
+ e.getStatus() == SC_METHOD_NOT_ALLOWED ||
+ e.getStatus() == SC_NOT_FOUND )
+ {
+ SAL_WARN( "ucb.ucp.webdav", "HEAD not implemented: fall back to a partial GET" );
+ // set in cached OPTIONS "HEAD not implemented"
+ // so it won't be used again on this resource
+ rDAVOptions.setHeadAllowed( false );
+ try
+ {
+ // do a GET with a payload of 0, the server does not
+ // support HEAD (or has HEAD disabled)
+ DAVRequestHeaders aPartialGet;
+ aPartialGet.push_back(
+ DAVRequestHeader(
+ OUString( "Range" ),
+ OUString( "bytes=0-0" )));
+
+ rResAccess->GET( aPartialGet,
+ aHeaderNames,
+ aResource,
+ xEnv );
+ return true;
+ }
+ catch (...)
+ {
+ return false;
+ }
+ }
+ else
+ return false;
+ }
catch ( ... )
{
// some error... so set as not found
@@ -4152,6 +4193,7 @@ bool Content::isResourceAvailable( const css::uno::Reference< css::ucb::XCommand
// in rResAccess function method.
return false;
}
+ return false;
}
diff --git a/ucb/source/ucp/webdav-neon/webdavcontent.hxx b/ucb/source/ucp/webdav-neon/webdavcontent.hxx
index 1adf196cade7..8ee5ace2322b 100644
--- a/ucb/source/ucp/webdav-neon/webdavcontent.hxx
+++ b/ucb/source/ucp/webdav-neon/webdavcontent.hxx
@@ -329,7 +329,8 @@ public:
throw ( css::uno::Exception, std::exception );
static bool isResourceAvailable( const css::uno::Reference< css::ucb::XCommandEnvironment >& xEnv,
- const std::unique_ptr< DAVResourceAccess > & rResAccess);
+ const std::unique_ptr< DAVResourceAccess > & rResAccess,
+ DAVOptions& rDAVOptions );
static void removeCachedPropertyNames( const OUString & rURL );
};