ucb: webdav-curl: tdf#101094 (4) OPTIONS: Add member function getResourceOptions

[ port of commit 2777b6380c17bad8a966454947b9d991f9592224 ]

Change-Id: I8c54b564a8c92dcd395e104976f7a7071b5264eb
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/123285
Tested-by: Michael Stahl <michael.stahl@allotropia.de>
Reviewed-by: Michael Stahl <michael.stahl@allotropia.de>
diff --git a/ucb/source/ucp/webdav-curl/webdavcontent.cxx b/ucb/source/ucp/webdav-curl/webdavcontent.cxx
index ec16224..a90f197 100644
--- a/ucb/source/ucp/webdav-curl/webdavcontent.cxx
+++ b/ucb/source/ucp/webdav-curl/webdavcontent.cxx
@@ -3565,4 +3565,103 @@ Content::ResourceType Content::getResourceType(
    return ret;
}


void Content::getResourceOptions(
                    const css::uno::Reference< css::ucb::XCommandEnvironment >& xEnv,
                    DAVOptions& rDAVOptions,
                    const std::unique_ptr< DAVResourceAccess > & rResAccess )
{
    try
    {
        rResAccess->OPTIONS( rDAVOptions, xEnv );
        // IMPORTANT:the correctly implemented server will answer without errors, even if the resource is not present
    }
    catch ( DAVException const & e )
    {
        rResAccess->resetUri();

        switch( e.getError() )
        {
            case DAVException::DAV_HTTP_TIMEOUT:
            case DAVException::DAV_HTTP_CONNECT:
            {
                // something bad happened to the connection
                // not same as not found, this instead happens when the server does'n exist or does'n aswer at all
                // probably a new bit stating 'timed out' should be added to opts var?
                // in any case abort the command
                cancelCommandExecution( e, xEnv );
                // unreachable
            }
            break;
            case DAVException::DAV_HTTP_AUTH:
            {
                SAL_WARN( "ucb.ucp.webdav", "OPTIONS - DAVException Authentication error for URL <" << m_xIdentifier->getContentIdentifier() << ">" );
                // - the remote site is a WebDAV with special configuration: read/only for read operations
                //   and read/write for write operations, the user is not allowed to lock/write and
                //   she cancelled the credentials request.
                //   this is not actually an error, it means only that for current user this is a standard web,
                //   though possibly DAV enabled
            }
            break;
            case DAVException::DAV_HTTP_ERROR:
            {
                switch( e.getStatus() )
                {
                    case SC_FORBIDDEN:
                    {
                        SAL_WARN( "ucb.ucp.webdav","OPTIONS - Forbidden for URL <" << m_xIdentifier->getContentIdentifier() << ">" );
                        rDAVOptions.setResourceFound(); // means it exists, but it's not DAV
                    }
                    break;
                    case SC_BAD_REQUEST:
                    {
                        SAL_WARN( "ucb.ucp.webdav","OPTIONS - Bad request for URL <" << m_xIdentifier->getContentIdentifier() << ">" );
                        rDAVOptions.setResourceFound(); // means it exists, but it's not DAV
                    }
                    break;
                    case SC_NOT_IMPLEMENTED:
                    case SC_METHOD_NOT_ALLOWED:
                    {
                        // OPTIONS method must be implemented in DAV
                        // resource is NON_DAV, or not advertising it
                        SAL_WARN( "ucb.ucp.webdav","OPTIONS - Method not implemented or not allowed for URL <" << m_xIdentifier->getContentIdentifier() << ">" );
                        rDAVOptions.setResourceFound(); // means it exists, but it's not DAV
                    }
                    break;
                    case SC_NOT_FOUND:
                    {
                        SAL_WARN( "ucb.ucp.webdav", "OPTIONS - Resource not found for URL <" << m_xIdentifier->getContentIdentifier() << ">" );
                    }
                    break;
                    default:
                        break;
                }
            }
            break;
            default: // leave the resource type as UNKNOWN, for now
                // it means this will be managed as a standard http site
                SAL_WARN( "ucb.ucp.webdav","OPTIONS - DAVException for URL <" << m_xIdentifier->getContentIdentifier() << ">, DAV error: "
                          << e.getError() << ", HTTP error: "<<e.getStatus() );
                break;
        }
    }
}

void Content::getResourceOptions(
                    const uno::Reference< ucb::XCommandEnvironment >& xEnv,
                    DAVOptions& rDAVOptions )
{
    std::unique_ptr< DAVResourceAccess > xResAccess;
    {
        osl::MutexGuard aGuard( m_aMutex );
        xResAccess.reset( new DAVResourceAccess( *m_xResAccess ) );
    }
    getResourceOptions( xEnv, rDAVOptions, xResAccess );
    {
        osl::Guard< osl::Mutex > aGuard( m_aMutex );
        m_xResAccess.reset( new DAVResourceAccess( *xResAccess ) );
    }
}


/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/ucb/source/ucp/webdav-curl/webdavcontent.hxx b/ucb/source/ucp/webdav-curl/webdavcontent.hxx
index bdfe0a11..f5a74bd 100644
--- a/ucb/source/ucp/webdav-curl/webdavcontent.hxx
+++ b/ucb/source/ucp/webdav-curl/webdavcontent.hxx
@@ -76,7 +76,9 @@ class Content : public ::ucbhelper::ContentImplHelper,
    std::unique_ptr< DAVResourceAccess > m_xResAccess;
    std::unique_ptr< CachableContentProperties > m_xCachedProps; // locally cached props
    OUString     m_aEscapedTitle;
    // resource type for general DAV methods
    ResourceType      m_eResourceType;
    // resource type for general LOCK method only
    ResourceType      m_eResourceTypeForLocks;
    ContentProvider*  m_pProvider; // No need for a ref, base class holds object
    rtl::Reference< DAVSessionFactory > m_rSessionFactory;
@@ -262,6 +264,17 @@ public:
                       const ContentProperties& rData,
                       const rtl::Reference< ::ucbhelper::ContentProviderImplHelper >& rProvider,
                       const OUString& rContentId );

    /// Use OPTIONS method to retrieve the type of the Web resource
    /// @throws css::uno::Exception
    void getResourceOptions( const css::uno::Reference< css::ucb::XCommandEnvironment >& xEnv,
                             DAVOptions& rDAVOptions,
                             const std::unique_ptr< DAVResourceAccess > & rResAccess );

    /// @throws css::uno::Exception
    void getResourceOptions( const css::uno::Reference< css::ucb::XCommandEnvironment >& xEnv,
                             DAVOptions& rDAVOptions );

};

}