ucb/source/ucp/webdav-curl/CurlSession.cxx   |    1 
 ucb/source/ucp/webdav-curl/DAVTypes.cxx      |   30 +--
 ucb/source/ucp/webdav-curl/DAVTypes.hxx      |   38 ++--
 ucb/source/ucp/webdav-curl/webdavcontent.cxx |  240 +++++++++++++--------------
 4 files changed, 156 insertions(+), 153 deletions(-)

New commits:
commit e3c2294c351892ca864f7dd5827dbe04cfcc8021
Author:     Michael Stahl <michael.st...@allotropia.de>
AuthorDate: Tue Oct 12 13:37:08 2021 +0200
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Mon Nov 1 18:50:55 2021 +0100

    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.st...@allotropia.de>
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>

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;
 }
 

Reply via email to