diff options
Diffstat (limited to 'ucb/source/ucp/webdav-neon/webdavcontent.cxx')
-rw-r--r-- | ucb/source/ucp/webdav-neon/webdavcontent.cxx | 100 |
1 files changed, 68 insertions, 32 deletions
diff --git a/ucb/source/ucp/webdav-neon/webdavcontent.cxx b/ucb/source/ucp/webdav-neon/webdavcontent.cxx index 7cf9ee1399a4..1937c73c1ca8 100644 --- a/ucb/source/ucp/webdav-neon/webdavcontent.cxx +++ b/ucb/source/ucp/webdav-neon/webdavcontent.cxx @@ -1590,8 +1590,13 @@ uno::Reference< sdbc::XRow > Content::getPropertyValues( // PROPPATCH can change them removeCachedPropertyNames( aTargetURL ); // test if HEAD allowed, if not, throw, will be catched immediately - if ( !aDAVOptions.isHeadAllowed() ) + // SC_GONE used internally by us, see comment below + // in the catch scope + if ( aDAVOptions.getHttpResponseStatusCode() != SC_GONE && + !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 ) @@ -1645,6 +1650,7 @@ uno::Reference< sdbc::XRow > Content::getPropertyValues( aLastException.getStatus() == SC_NOT_FOUND ) { SAL_WARN( "ucb.ucp.webdav", "HEAD probably not implemented: fall back to a partial GET" ); + aStaticDAVOptionsCache.setHeadAllowed( aTargetURL, false ); lcl_sendPartialGETRequest( bError, aLastException, aMissingProps, @@ -1658,10 +1664,27 @@ uno::Reference< sdbc::XRow > Content::getPropertyValues( if ( bError ) { + DAVOptions aDAVOptionsException; + + aDAVOptionsException.setURL( aTargetURL ); + // check if the error was SC_NOT_FOUND, meaning that the + // GET fall back didn't succeeded and the element is really missing + // we will consider the resource SC_GONE (410) for some time + // we use SC_GONE because has the same meaning of SC_NOT_FOUND (404) + // see: + // <https://tools.ietf.org/html/rfc7231#section-6.5.9> (retrieved 2016-10-09) + // apparently it's not used to mark the missing HEAD method (so far...) + sal_uInt16 ResponseStatusCode = + ( aLastException.getStatus() == SC_NOT_FOUND ) ? + SC_GONE : + aLastException.getStatus(); + aDAVOptionsException.setHttpResponseStatusCode( ResponseStatusCode ); + aDAVOptionsException.setHttpResponseStatusText( aLastException.getData() ); + aStaticDAVOptionsCache.updateCachedOption( aDAVOptionsException, + m_nOptsCacheLifeNotFound ); + if ( !shouldAccessNetworkAfterException( aLastException ) ) { - // remove the cached OPTIONS and errors - aStaticDAVOptionsCache.removeDAVOptions( aTargetURL ); cancelCommandExecution( aLastException, xEnv ); // unreachable } @@ -2348,6 +2371,7 @@ uno::Any Content::open( } catch ( DAVException const & e ) { + //TODO cache the http error if not yet cached cancelCommandExecution( e, xEnv ); // Unreachable } @@ -3729,6 +3753,7 @@ uno::Any Content::MapDAVException( const DAVException & e, bool bWrite ) bool Content::shouldAccessNetworkAfterException( const DAVException & e ) { if ( ( e.getStatus() == SC_NOT_FOUND ) || + ( e.getStatus() == SC_GONE ) || ( e.getError() == DAVException::DAV_HTTP_TIMEOUT ) || ( e.getError() == DAVException::DAV_HTTP_LOOKUP ) || ( e.getError() == DAVException::DAV_HTTP_CONNECT ) || @@ -3918,7 +3943,8 @@ Content::ResourceType Content::getResourceType( { rResAccess->resetUri(); - if ( aDAVOptions.getHttpResponseStatusCode() != SC_NOT_FOUND ) + if ( aDAVOptions.getHttpResponseStatusCode() != SC_NOT_FOUND && + aDAVOptions.getHttpResponseStatusCode() != SC_GONE ) // the cached OPTIONS can have SC_GONE { eResourceType = NON_DAV; } @@ -3926,8 +3952,7 @@ Content::ResourceType Content::getResourceType( { //resource doesn't exist if ( networkAccessAllowed != nullptr ) - *networkAccessAllowed = false; - } + *networkAccessAllowed = false; } } } @@ -3971,22 +3996,23 @@ void Content::getResourceOptions( { OUString aRedirURL; OUString aTargetURL = rResAccess->getURL(); + DAVOptions aDAVOptions; // first check if in cache, if not, then send method to server - if ( !aStaticDAVOptionsCache.getDAVOptions( aTargetURL, rDAVOptions ) ) + if ( !aStaticDAVOptionsCache.getDAVOptions( aTargetURL, aDAVOptions ) ) { try { - rResAccess->OPTIONS( rDAVOptions, xEnv ); + rResAccess->OPTIONS( aDAVOptions, xEnv ); // IMPORTANT:the correctly implemented server will answer without errors, even if the resource is not present - sal_uInt32 nLifeTime = ( rDAVOptions.isClass1() || - rDAVOptions.isClass2() || - rDAVOptions.isClass3() ) ? + sal_uInt32 nLifeTime = ( aDAVOptions.isClass1() || + aDAVOptions.isClass2() || + aDAVOptions.isClass3() ) ? m_nOptsCacheLifeDAV : // a WebDAV site m_nOptsCacheLifeImplWeb; // a site implementing OPTIONS but // it's not DAV // if resource is locked, will use a // different lifetime - if( rDAVOptions.isLocked() ) + if( aDAVOptions.isLocked() ) nLifeTime = m_nOptsCacheLifeDAVLocked; // check if redirected @@ -3996,9 +4022,9 @@ void Content::getResourceOptions( aRedirURL.clear(); } // cache this URL's option - rDAVOptions.setURL( aTargetURL ); - rDAVOptions.setRedirectedURL( aRedirURL ); - aStaticDAVOptionsCache.addDAVOptions( rDAVOptions, + aDAVOptions.setURL( aTargetURL ); + aDAVOptions.setRedirectedURL( aRedirURL ); + aStaticDAVOptionsCache.addDAVOptions( aDAVOptions, nLifeTime ); } catch ( DAVException const & e ) @@ -4007,8 +4033,8 @@ void Content::getResourceOptions( aStaticDAVOptionsCache.removeDAVOptions( aTargetURL ); rResAccess->resetUri(); - rDAVOptions.setURL( aTargetURL ); - rDAVOptions.setRedirectedURL( aRedirURL ); + aDAVOptions.setURL( aTargetURL ); + aDAVOptions.setRedirectedURL( aRedirURL ); switch( e.getError() ) { case DAVException::DAV_HTTP_TIMEOUT: @@ -4041,16 +4067,20 @@ void Content::getResourceOptions( { SAL_WARN( "ucb.ucp.webdav","OPTIONS - SC_FORBIDDEN for URL <" << m_xIdentifier->getContentIdentifier() << ">" ); // cache it, so OPTIONS won't be called again, this URL does not support it - aStaticDAVOptionsCache.addDAVOptions( rDAVOptions, + aStaticDAVOptionsCache.addDAVOptions( aDAVOptions, m_nOptsCacheLifeNotImpl ); } break; case SC_BAD_REQUEST: + case SC_INTERNAL_SERVER_ERROR: { - SAL_WARN( "ucb.ucp.webdav","OPTIONS - SC_BAD_REQUEST for URL <" << m_xIdentifier->getContentIdentifier() << ">" ); - // cache it, so OPTIONS won't be called again, this URL does not support it - aStaticDAVOptionsCache.addDAVOptions( rDAVOptions, - m_nOptsCacheLifeNotImpl ); + SAL_WARN( "ucb.ucp.webdav","OPTIONS - SC_BAD_REQUEST or SC_INTERNAL_SERVER_ERROR for URL <" << m_xIdentifier->getContentIdentifier() << ">, HTTP error: "<< e.getStatus() + << ", '" << e.getData() << "'" ); + // cache it, so OPTIONS won't be called again, this URL detect some problem while answering the method + aDAVOptions.setHttpResponseStatusCode( e.getStatus() ); + aDAVOptions.setHttpResponseStatusText( e.getData() ); + aStaticDAVOptionsCache.addDAVOptions( aDAVOptions, + m_nOptsCacheLifeNotFound ); } break; case SC_NOT_IMPLEMENTED: @@ -4058,9 +4088,10 @@ 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() << ">" ); + SAL_WARN( "ucb.ucp.webdav","OPTIONS - SC_NOT_IMPLEMENTED or SC_METHOD_NOT_ALLOWED for URL <" << m_xIdentifier->getContentIdentifier() << ">, HTTP error: "<< e.getStatus() + << ", '" << e.getData() << "'" ); // cache it, so OPTIONS won't be called again, this URL does not support it - aStaticDAVOptionsCache.addDAVOptions( rDAVOptions, + aStaticDAVOptionsCache.addDAVOptions( aDAVOptions, m_nOptsCacheLifeNotImpl ); } break; @@ -4070,22 +4101,26 @@ 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, rDAVOptions ) ) + if( isResourceAvailable( xEnv, rResAccess, aDAVOptions ) ) { + SAL_WARN( "ucb.ucp.webdav", "OPTIONS - Got an SC_NOT_FOUND, but the URL <" << m_xIdentifier->getContentIdentifier() << "> resource exists" ); nLifeTime = m_nOptsCacheLifeNotImpl; } - aStaticDAVOptionsCache.addDAVOptions( rDAVOptions, + else + SAL_WARN( "ucb.ucp.webdav", "OPTIONS - SC_NOT_FOUND for URL <" << m_xIdentifier->getContentIdentifier() << ">" ); + + aStaticDAVOptionsCache.addDAVOptions( aDAVOptions, nLifeTime ); - SAL_WARN( "ucb.ucp.webdav", "OPTIONS - SC_NOT_FOUND for URL <" << m_xIdentifier->getContentIdentifier() << ">" ); } break; default: { - 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() ); + SAL_WARN( "ucb.ucp.webdav", "OPTIONS - DAV_HTTP_ERROR, for URL <" << m_xIdentifier->getContentIdentifier() << ">, HTTP error: "<< e.getStatus() + << ", '" << e.getData() << "'" ); + aDAVOptions.setHttpResponseStatusCode( e.getStatus() ); + aDAVOptions.setHttpResponseStatusText( e.getData() ); // cache it, so OPTIONS won't be called again, this URL does not support it - aStaticDAVOptionsCache.addDAVOptions( rDAVOptions, + aStaticDAVOptionsCache.addDAVOptions( aDAVOptions, m_nOptsCacheLifeNotImpl ); } break; @@ -4100,13 +4135,14 @@ void Content::getResourceOptions( { 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() ); - aStaticDAVOptionsCache.addDAVOptions( rDAVOptions, + aStaticDAVOptionsCache.addDAVOptions( aDAVOptions, m_nOptsCacheLifeNotImpl ); } break; } } } + rDAVOptions = aDAVOptions; } |