diff options
author | Michael Stahl <michael.stahl@allotropia.de> | 2021-10-12 13:37:08 +0200 |
---|---|---|
committer | Michael Stahl <michael.stahl@allotropia.de> | 2021-11-01 18:50:55 +0100 |
commit | e3c2294c351892ca864f7dd5827dbe04cfcc8021 (patch) | |
tree | 8cc553a4f47d4ec23e553fa6f66fb0d7d9d27e9c /ucb/source | |
parent | acc8ba867692c4ab426daed5414f1e9fdd90ba4a (diff) |
ucb: webdav-curl: tdf#102499 (3): Change caching model for HTTP response status code
Instead of caching only a single status flag, now both the HTTP
response status code and the message accompanying it are cached.
[ port of commit f423a9d695814b1babf5f2c3f42821190adc7e53 ]
Change-Id: Ia77dc1d7575fc9d5517733687b8d3a1fdf9429dc
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/123496
Tested-by: Michael Stahl <michael.stahl@allotropia.de>
Reviewed-by: Michael Stahl <michael.stahl@allotropia.de>
Diffstat (limited to 'ucb/source')
-rw-r--r-- | ucb/source/ucp/webdav-curl/CurlSession.cxx | 1 | ||||
-rw-r--r-- | ucb/source/ucp/webdav-curl/DAVTypes.cxx | 30 | ||||
-rw-r--r-- | ucb/source/ucp/webdav-curl/DAVTypes.hxx | 38 | ||||
-rw-r--r-- | ucb/source/ucp/webdav-curl/webdavcontent.cxx | 240 |
4 files changed, 156 insertions, 153 deletions
diff --git a/ucb/source/ucp/webdav-curl/CurlSession.cxx b/ucb/source/ucp/webdav-curl/CurlSession.cxx index 9700540d6565..b0c1c4c7e2ac 100644 --- a/ucb/source/ucp/webdav-curl/CurlSession.cxx +++ b/ucb/source/ucp/webdav-curl/CurlSession.cxx @@ -1178,7 +1178,6 @@ auto CurlSession::OPTIONS(OUString const& rURIReference, } } } - rOptions.setResourceFound(); if (rOptions.isClass2() || rOptions.isClass3()) { if (g_Init.LockStore.getLockTokenForURI(rURIReference, nullptr)) diff --git a/ucb/source/ucp/webdav-curl/DAVTypes.cxx b/ucb/source/ucp/webdav-curl/DAVTypes.cxx index 39543c3dcf98..ad39d0d46095 100644 --- a/ucb/source/ucp/webdav-curl/DAVTypes.cxx +++ b/ucb/source/ucp/webdav-curl/DAVTypes.cxx @@ -22,7 +22,6 @@ using namespace com::sun::star; // DAVOptions implementation DAVOptions::DAVOptions() : - m_isResourceFound( false ), m_isClass1( false ), m_isClass2( false ), m_isClass3( false ), @@ -31,13 +30,14 @@ DAVOptions::DAVOptions() : m_aAllowedMethods(), m_nStaleTime( 0 ), m_sURL(), - m_sRedirectedURL() + m_sRedirectedURL(), + m_nHttpResponseStatusCode( 0 ), + m_sHttpResponseStatusText() { } DAVOptions::DAVOptions( const DAVOptions & rOther ) : - m_isResourceFound( rOther.m_isResourceFound ), m_isClass1( rOther.m_isClass1 ), m_isClass2( rOther.m_isClass2 ), m_isClass3( rOther.m_isClass3 ), @@ -46,7 +46,9 @@ DAVOptions::DAVOptions( const DAVOptions & rOther ) : m_aAllowedMethods( rOther.m_aAllowedMethods ), m_nStaleTime( rOther.m_nStaleTime ), m_sURL( rOther.m_sURL ), - m_sRedirectedURL( rOther.m_sRedirectedURL) + m_sRedirectedURL( rOther.m_sRedirectedURL), + m_nHttpResponseStatusCode( rOther.m_nHttpResponseStatusCode ), + m_sHttpResponseStatusText( rOther.m_sHttpResponseStatusText ) { } @@ -59,7 +61,6 @@ DAVOptions::~DAVOptions() bool DAVOptions::operator==( const DAVOptions& rOpts ) const { return - m_isResourceFound == rOpts.m_isResourceFound && m_isClass1 == rOpts.m_isClass1 && m_isClass2 == rOpts.m_isClass2 && m_isClass3 == rOpts.m_isClass3 && @@ -68,7 +69,9 @@ bool DAVOptions::operator==( const DAVOptions& rOpts ) const m_aAllowedMethods == rOpts.m_aAllowedMethods && m_nStaleTime == rOpts.m_nStaleTime && m_sURL == rOpts.m_sURL && - m_sRedirectedURL == rOpts.m_sRedirectedURL; + m_sRedirectedURL == rOpts.m_sRedirectedURL && + m_nHttpResponseStatusCode == rOpts.m_nHttpResponseStatusCode && + m_sHttpResponseStatusText == rOpts.m_sHttpResponseStatusText; } @@ -131,7 +134,6 @@ void DAVOptionsCache::removeDAVOptions( const OUString & rURL ) void DAVOptionsCache::addDAVOptions( DAVOptions & rDAVOptions, const sal_uInt32 nLifeTime ) { osl::MutexGuard aGuard( m_aMutex ); - OUString aURL( rDAVOptions.getURL() ); OUString aEncodedUrl( ucb_impl::urihelper::encodeURI( DecodeURI(aURL) ) ); @@ -149,8 +151,7 @@ void DAVOptionsCache::addDAVOptions( DAVOptions & rDAVOptions, const sal_uInt32 m_aTheCache[ aEncodedUrl ] = rDAVOptions; } - -bool DAVOptionsCache::isResourceFound( const OUString & rURL ) +sal_uInt16 DAVOptionsCache::getHttpResponseStatusCode( const OUString & rURL, OUString & rHttpResponseStatusText ) { osl::MutexGuard aGuard( m_aMutex ); OUString aEncodedUrl( ucb_impl::urihelper::encodeURI( DecodeURI(rURL) ) ); @@ -166,16 +167,13 @@ bool DAVOptionsCache::isResourceFound( const OUString & rURL ) if( (*it).second.getStaleTime() < t1.Seconds ) { m_aTheCache.erase( it ); - return true; // to force again OPTIONS method + return 0; } - // check if the resource was present on server - return (*it).second.isResourceFound(); + rHttpResponseStatusText = (*it).second.getHttpResponseStatusText(); + return (*it).second.getHttpResponseStatusCode(); } - // this value is needed because some web server don't implement - // OPTIONS method, so the resource is considered found, - // until detected otherwise - return true; + return 0; } bool DAVOptionsCache::isHeadAllowed( const OUString & rURL ) diff --git a/ucb/source/ucp/webdav-curl/DAVTypes.hxx b/ucb/source/ucp/webdav-curl/DAVTypes.hxx index 7959cf150bce..6db2d2d6e048 100644 --- a/ucb/source/ucp/webdav-curl/DAVTypes.hxx +++ b/ucb/source/ucp/webdav-curl/DAVTypes.hxx @@ -67,16 +67,14 @@ namespace http_dav_ucp class DAVOptions { private: - bool m_isResourceFound; // true if the resource was found, else false bool m_isClass1; bool m_isClass2; bool m_isClass3; - // for server that do not implement it + /// 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 + /// Internally used to maintain the locked state of the resource, only if it's a Class 2 resource bool m_isLocked; - // contains the methods allowed on this resource + /// contains the methods allowed on this resource OUString m_aAllowedMethods; /// target time when this capability becomes stale @@ -84,6 +82,11 @@ namespace http_dav_ucp OUString m_sURL; OUString m_sRedirectedURL; + /// The cached HTT response status code. It's 0 if the code was dealt with and there is no need to cache it + sal_uInt16 m_nHttpResponseStatusCode; + /// The cached string with the server returned HTTP response status code string, corresponds to m_nHttpResponseStatusCode. + OUString m_sHttpResponseStatusText; + public: DAVOptions(); @@ -91,9 +94,6 @@ namespace http_dav_ucp virtual ~DAVOptions(); - bool isResourceFound() { return m_isResourceFound; }; - void setResourceFound( bool ResourceFound = true ) { m_isResourceFound = ResourceFound; }; - bool isClass1() { return m_isClass1; }; void setClass1( bool Class1 = true ) { m_isClass1 = Class1; }; @@ -106,7 +106,7 @@ namespace http_dav_ucp bool isHeadAllowed() { return m_isHeadAllowed; }; void setHeadAllowed( bool HeadAllowed = true ) { m_isHeadAllowed = HeadAllowed; }; - sal_uInt32 getStaleTime() const { return m_nStaleTime ; }; + sal_uInt32 getStaleTime() { return m_nStaleTime ; }; void setStaleTime( const sal_uInt32 nStaleTime ) { m_nStaleTime = nStaleTime; }; const OUString & getURL() { return m_sURL; }; @@ -122,8 +122,13 @@ namespace http_dav_ucp void setLocked( bool locked = true ) { m_isLocked = locked; } ; bool isLocked() { return m_isLocked; }; + sal_uInt16 getHttpResponseStatusCode() { return m_nHttpResponseStatusCode; }; + void setHttpResponseStatusCode( const sal_uInt16 nHttpResponseStatusCode ) { m_nHttpResponseStatusCode = nHttpResponseStatusCode; }; + + const OUString & getHttpResponseStatusText() { return m_sHttpResponseStatusText; }; + void setHttpResponseStatusText( const OUString & rHttpResponseStatusText ) { m_sHttpResponseStatusText = rHttpResponseStatusText; }; + void init() { - m_isResourceFound = false; m_isClass1 = false; m_isClass2 = false; m_isClass3 = false; @@ -133,6 +138,8 @@ namespace http_dav_ucp m_nStaleTime = 0; m_sURL.clear(); m_sRedirectedURL.clear(); + m_nHttpResponseStatusCode = 0; + m_sHttpResponseStatusText.clear(); }; DAVOptions & operator=( const DAVOptions& rOpts ) = default; //TODO -Werror=deprecated-copy @@ -158,20 +165,19 @@ namespace http_dav_ucp void removeDAVOptions( const OUString & rURL ); void addDAVOptions( DAVOptions & rDAVOptions, const sal_uInt32 nLifeTime ); - /** Check if the DAV options cached value was found - by the last OPTIONS method call. + /** return the cached value of HTTP response status code If the cached value is found stale, it is removed. - @param OUString + @param (in) OUString the resource URL - @return bool - true if resource was found or if the Web resource DAV options + @return int + the cached are not present (meaning the resource should be checked for presence anyway) false if resource was not found */ - bool isResourceFound( const OUString & rURL ); + sal_uInt16 getHttpResponseStatusCode( const OUString & rURL, OUString & rHttpResponseStatusText ); bool isHeadAllowed( const OUString & rURL ); diff --git a/ucb/source/ucp/webdav-curl/webdavcontent.cxx b/ucb/source/ucp/webdav-curl/webdavcontent.cxx index 4698f7078166..b541f2af5955 100644 --- a/ucb/source/ucp/webdav-curl/webdavcontent.cxx +++ b/ucb/source/ucp/webdav-curl/webdavcontent.cxx @@ -1451,15 +1451,29 @@ uno::Reference< sdbc::XRow > Content::getPropertyValues( if ( !aHeaderNames.empty() ) { + DAVOptions aDAVOptions; + OUString aTargetURL = xResAccess->getURL(); + // retrieve the cached options if any + aStaticDAVOptionsCache.getDAVOptions( aTargetURL, aDAVOptions ); try { DAVResource resource; // clean cached value of PROPFIND property names // PROPPATCH can change them - removeCachedPropertyNames( xResAccess->getURL() ); + removeCachedPropertyNames( aTargetURL ); // test if HEAD allowed, if not, throw, will be catched immediately - if ( !aStaticDAVOptionsCache.isHeadAllowed( xResAccess->getURL() ) ) + if ( !aDAVOptions.isHeadAllowed() ) throw DAVException( DAVException::DAV_HTTP_ERROR, "405 Not Implemented", 405 ); + // if HEAD is enabled on this site + // check if there is a relevant HTTP response status code cached + if ( aDAVOptions.getHttpResponseStatusCode() != SC_NONE ) + { + // throws exception as if there was a server error, a DAV exception + throw DAVException( DAVException::DAV_HTTP_ERROR, + aDAVOptions.getHttpResponseStatusText(), + aDAVOptions.getHttpResponseStatusCode() ); + // Unreachable + } xResAccess->HEAD( aHeaderNames, resource, xEnv ); m_bDidGetOrHead = true; @@ -1488,31 +1502,38 @@ uno::Reference< sdbc::XRow > Content::getPropertyValues( bool bError = true; DAVException aLastException = e; - // According to the spec. the origin server SHOULD return - // * 405 (Method Not Allowed): - // the method is known but not allowed for the requested resource - // * 501 (Not Implemented): - // the method is unrecognized or not implemented - // TODO SC_NOT_FOUND is only for google-code server - if ( aLastException.getStatus() == SC_NOT_IMPLEMENTED || - aLastException.getStatus() == SC_METHOD_NOT_ALLOWED || - aLastException.getStatus() == SC_NOT_FOUND ) + if ( e.getError() == DAVException::DAV_HTTP_ERROR ) { - SAL_WARN( "ucb.ucp.webdav", "HEAD not implemented: fall back to a partial GET" ); - lcl_sendPartialGETRequest( bError, - aLastException, - aMissingProps, - aHeaderNames, - xResAccess, - xProps, - xEnv ); - m_bDidGetOrHead = !bError; + // According to the spec. the origin server SHOULD return + // * 405 (Method Not Allowed): + // the method is known but not allowed for the requested resource + // * 501 (Not Implemented): + // the method is unrecognized or not implemented + // * 404 (SC_NOT_FOUND) + // is for google-code server and for MS IIS 10.0 Web server + // when only GET is enabled + if ( aLastException.getStatus() == SC_NOT_IMPLEMENTED || + aLastException.getStatus() == SC_METHOD_NOT_ALLOWED || + aLastException.getStatus() == SC_NOT_FOUND ) + { + SAL_WARN( "ucb.ucp.webdav", "HEAD probably not implemented: fall back to a partial GET" ); + lcl_sendPartialGETRequest( bError, + aLastException, + aMissingProps, + aHeaderNames, + xResAccess, + xProps, + xEnv ); + m_bDidGetOrHead = !bError; + } } if ( bError ) { if ( !shouldAccessNetworkAfterException( aLastException ) ) { + // remove the cached OPTIONS and errors + aStaticDAVOptionsCache.removeDAVOptions( aTargetURL ); cancelCommandExecution( aLastException, xEnv ); // unreachable } @@ -2151,14 +2172,14 @@ uno::Any Content::open( xResAccess.reset( new DAVResourceAccess( *m_xResAccess ) ); } - xResAccess->setFlags( rArg.OpeningFlags ); // fill inputstream sync; return if all data present DAVResource aResource; std::vector< OUString > aHeaders; - removeCachedPropertyNames( xResAccess->getURL() ); + aTargetURL = xResAccess->getURL(); + removeCachedPropertyNames( aTargetURL ); // check if the resource was present on the server // first update it, if necessary // if the open is called directly, without the default open sequence, @@ -2168,68 +2189,36 @@ uno::Any Content::open( DAVOptions aDAVOptions; getResourceOptions( xEnv, aDAVOptions, xResAccess ); - if( aDAVOptions.isResourceFound() ) + if ( aDAVOptions.getHttpResponseStatusCode() != SC_NONE ) { - uno::Reference< io::XInputStream > xIn - = xResAccess->GET( aHeaders, aResource, xEnv ); - m_bDidGetOrHead = true; - - { - osl::MutexGuard aGuard( m_aMutex ); - - // cache headers. - if (!m_xCachedProps) - m_xCachedProps.reset( - new CachableContentProperties( ContentProperties( aResource ) ) ); - else - m_xCachedProps->addProperties( - aResource.properties ); + // throws exception as if there was a server error, a DAV exception + throw DAVException( DAVException::DAV_HTTP_ERROR, + aDAVOptions.getHttpResponseStatusText(), + aDAVOptions.getHttpResponseStatusCode() ); + } + uno::Reference< io::XInputStream > xIn + = xResAccess->GET( aHeaders, aResource, xEnv ); + m_bDidGetOrHead = true; - m_xResAccess.reset( - new DAVResourceAccess( *xResAccess ) ); + { + osl::MutexGuard aGuard( m_aMutex ); - } + // cache headers. + if (!m_xCachedProps) + m_xCachedProps.reset( + new CachableContentProperties( ContentProperties( aResource ) ) ); + else + m_xCachedProps->addProperties( + aResource.properties ); - xDataSink->setInputStream( xIn ); + m_xResAccess.reset( + new DAVResourceAccess( *xResAccess ) ); } - else - { - // return exception as if the resource was not found - uno::Sequence< uno::Any > aArgs( 1 ); - aArgs[ 0 ] <<= beans::PropertyValue( - "Uri", -1, - uno::makeAny(aTargetURL), - beans::PropertyState_DIRECT_VALUE); - ucbhelper::cancelCommandExecution( - uno::makeAny( - ucb::InteractiveAugmentedIOException( - "Not found!", - static_cast< cppu::OWeakObject * >( this ), - task::InteractionClassification_ERROR, - ucb::IOErrorCode_NOT_EXISTING, - aArgs ) ), - xEnv ); - // Unreachable - } + xDataSink->setInputStream( xIn ); } catch ( DAVException const & e ) { - // check if error is SC_NOT_FOUND - // if URL resource not found, set the corresponding resource - // element in option cache and update the cache lifetime accordingly - if( e.getStatus() == SC_NOT_FOUND ) - { - DAVOptions aDAVOptions; - if( aStaticDAVOptionsCache.getDAVOptions( aTargetURL, aDAVOptions ) ) - { - // get redirected url - aDAVOptions.setResourceFound( false ); - aStaticDAVOptionsCache.addDAVOptions( aDAVOptions, - m_nOptsCacheLifeNotFound ); - } - } - cancelCommandExecution( e, xEnv ); // Unreachable } @@ -3772,8 +3761,9 @@ Content::ResourceType Content::getResourceType( DAVOptions aDAVOptionsInner; if (aStaticDAVOptionsCache.getDAVOptions(rResAccess->getURL(), aDAVOptionsInner)) { - // get redirected url - aDAVOptionsInner.setResourceFound( false ); + // TODO? get redirected url + aDAVOptionsInner.setHttpResponseStatusCode( e.getStatus() ); + aDAVOptionsInner.setHttpResponseStatusText( e.getData() ); aStaticDAVOptionsCache.addDAVOptions( aDAVOptionsInner, m_nOptsCacheLifeNotFound ); } @@ -3798,7 +3788,7 @@ Content::ResourceType Content::getResourceType( { rResAccess->resetUri(); - if ( aDAVOptions.isResourceFound() ) + if ( aDAVOptions.getHttpResponseStatusCode() != SC_NOT_FOUND ) { eResourceType = NON_DAV; } @@ -3946,7 +3936,6 @@ void Content::getResourceOptions( case SC_FORBIDDEN: { SAL_WARN( "ucb.ucp.webdav","OPTIONS - SC_FORBIDDEN for URL <" << m_xIdentifier->getContentIdentifier() << ">" ); - rDAVOptions.setResourceFound(); // it may exists, will be checked by HEAD or GET method, surely it's not DAV // cache it, so OPTIONS won't be called again, this URL does not support it aStaticDAVOptionsCache.addDAVOptions( rDAVOptions, m_nOptsCacheLifeNotImpl ); @@ -3955,7 +3944,6 @@ void Content::getResourceOptions( case SC_BAD_REQUEST: { SAL_WARN( "ucb.ucp.webdav","OPTIONS - SC_BAD_REQUEST for URL <" << m_xIdentifier->getContentIdentifier() << ">" ); - rDAVOptions.setResourceFound(); // it may exists, will be checked by HEAD or GET method, surely it's not DAV // cache it, so OPTIONS won't be called again, this URL does not support it aStaticDAVOptionsCache.addDAVOptions( rDAVOptions, m_nOptsCacheLifeNotImpl ); @@ -3967,7 +3955,6 @@ void Content::getResourceOptions( // OPTIONS method must be implemented in DAV // resource is NON_DAV, or not advertising it SAL_WARN( "ucb.ucp.webdav","OPTIONS - SC_NOT_IMPLEMENTED or SC_METHOD_NOT_ALLOWED for URL <" << m_xIdentifier->getContentIdentifier() << ">" ); - rDAVOptions.setResourceFound(); // means it exists, but it's not DAV // cache it, so OPTIONS won't be called again, this URL does not support it aStaticDAVOptionsCache.addDAVOptions( rDAVOptions, m_nOptsCacheLifeNotImpl ); @@ -3982,7 +3969,6 @@ void Content::getResourceOptions( if( isResourceAvailable( xEnv, rResAccess, rDAVOptions ) ) { nLifeTime = m_nOptsCacheLifeNotImpl; - rDAVOptions.setResourceFound(); // means it exists, but it's not DAV } aStaticDAVOptionsCache.addDAVOptions( rDAVOptions, nLifeTime ); @@ -3990,12 +3976,15 @@ void Content::getResourceOptions( } break; default: - SAL_WARN( "ucb.ucp.webdav", "OPTIONS - DAV_HTTP_ERROR, HTTP error: " << e.getError() << " for URL <" << m_xIdentifier->getContentIdentifier() << ">" ); - rDAVOptions.setResourceFound(); // it may exists, will be checked by HEAD or GET method, surely it's not DAV + { + SAL_WARN( "ucb.ucp.webdav", "OPTIONS - DAV_HTTP_ERROR, for URL <" << m_xIdentifier->getContentIdentifier() << ">, HTTP error: "<< e.getStatus() ); + rDAVOptions.setHttpResponseStatusCode( e.getStatus() ); + rDAVOptions.setHttpResponseStatusText( e.getData() ); // cache it, so OPTIONS won't be called again, this URL does not support it aStaticDAVOptionsCache.addDAVOptions( rDAVOptions, m_nOptsCacheLifeNotImpl ); - break; + } + break; } } break; @@ -4003,15 +3992,14 @@ void Content::getResourceOptions( // number of redirections, consider the resource type as UNKNOWN // possibly a normal web site, not DAV case DAVException::DAV_HTTP_REDIRECT: - default: // leave the resource type as UNKNOWN, for now - // it means this will be managed as a standard http site + default: + { SAL_WARN( "ucb.ucp.webdav","OPTIONS - General DAVException (or max DAV_HTTP_REDIRECT reached) for URL <" << m_xIdentifier->getContentIdentifier() << ">, DAV ExceptionCode: " - << e.getError() << ", HTTP error: "<<e.getStatus() ); - rDAVOptions.setResourceFound(); // it may exists, will be checked by HEAD or GET method, surely it's not DAV - // cache it, so OPTIONS won't be called again, this URL does not support it + << e.getError() << ", HTTP error: "<< e.getStatus() ); aStaticDAVOptionsCache.addDAVOptions( rDAVOptions, m_nOptsCacheLifeNotImpl ); - break; + } + break; } } } @@ -4031,49 +4019,61 @@ bool Content::isResourceAvailable( const css::uno::Reference< css::ucb::XCommand // try using a simple HEAD command // if HEAD is successful, set element found. rResAccess->HEAD( aHeaderNames, aResource, xEnv ); + rDAVOptions.setHttpResponseStatusCode( 0 ); + rDAVOptions.setHttpResponseStatusText(""); return true; } catch ( DAVException const & e ) { - if ( e.getStatus() == SC_NOT_IMPLEMENTED || - e.getStatus() == SC_METHOD_NOT_ALLOWED || - e.getStatus() == SC_NOT_FOUND ) + if ( e.getError() == DAVException::DAV_HTTP_ERROR ) { - 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 + if ( e.getStatus() == SC_NOT_IMPLEMENTED || + e.getStatus() == SC_METHOD_NOT_ALLOWED || + e.getStatus() == SC_NOT_FOUND ) { - // 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->GET0( aPartialGet, - aHeaderNames, - aResource, - xEnv ); - return true; + SAL_WARN( "ucb.ucp.webdav", "HEAD probably 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->GET0( aPartialGet, + aHeaderNames, + aResource, + xEnv ); + return true; + } + catch ( DAVException const & ex ) + { + if ( ex.getError() == DAVException::DAV_HTTP_ERROR ) + { + rDAVOptions.setHttpResponseStatusCode( ex.getStatus() ); + rDAVOptions.setHttpResponseStatusText( ex.getData() ); + } + } } - catch (...) + else { - return false; + rDAVOptions.setHttpResponseStatusCode( e.getStatus() ); + rDAVOptions.setHttpResponseStatusText( e.getData() ); } } - else - return false; + return false; } catch ( ... ) { - // some error... so set as not found - // retry errors are taken care of - // in rResAccess function method. - return false; } + // set SC_NOT_IMPLEMENTED since at a minimum GET must be implemented in a basic Web server + rDAVOptions.setHttpResponseStatusCode( SC_NOT_IMPLEMENTED ); + rDAVOptions.setHttpResponseStatusText(""); return false; } |