xref: /AOO42X/main/ucb/source/ucp/webdav/CurlSession.cxx (revision f7ba5d5a709e464e56e5d80c5635469f9351434d)
19646dec5SDamjan Jovanovic /**************************************************************
29646dec5SDamjan Jovanovic  *
39646dec5SDamjan Jovanovic  * Licensed to the Apache Software Foundation (ASF) under one
49646dec5SDamjan Jovanovic  * or more contributor license agreements.  See the NOTICE file
59646dec5SDamjan Jovanovic  * distributed with this work for additional information
69646dec5SDamjan Jovanovic  * regarding copyright ownership.  The ASF licenses this file
79646dec5SDamjan Jovanovic  * to you under the Apache License, Version 2.0 (the
89646dec5SDamjan Jovanovic  * "License"); you may not use this file except in compliance
99646dec5SDamjan Jovanovic  * with the License.  You may obtain a copy of the License at
109646dec5SDamjan Jovanovic  *
119646dec5SDamjan Jovanovic  *   http://www.apache.org/licenses/LICENSE-2.0
129646dec5SDamjan Jovanovic  *
139646dec5SDamjan Jovanovic  * Unless required by applicable law or agreed to in writing,
149646dec5SDamjan Jovanovic  * software distributed under the License is distributed on an
159646dec5SDamjan Jovanovic  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
169646dec5SDamjan Jovanovic  * KIND, either express or implied.  See the License for the
179646dec5SDamjan Jovanovic  * specific language governing permissions and limitations
189646dec5SDamjan Jovanovic  * under the License.
199646dec5SDamjan Jovanovic  *
209646dec5SDamjan Jovanovic  *************************************************************/
219646dec5SDamjan Jovanovic 
229646dec5SDamjan Jovanovic 
239646dec5SDamjan Jovanovic 
249646dec5SDamjan Jovanovic // MARKER(update_precomp.py): autogen include statement, do not remove
259646dec5SDamjan Jovanovic #include "precompiled_webdav.hxx"
269646dec5SDamjan Jovanovic 
279646dec5SDamjan Jovanovic #include <hash_map>
289646dec5SDamjan Jovanovic #include <vector>
299646dec5SDamjan Jovanovic #include <string.h>
309646dec5SDamjan Jovanovic #include <rtl/string.h>
319646dec5SDamjan Jovanovic #include <rtl/strbuf.hxx>
329646dec5SDamjan Jovanovic #include <rtl/ustrbuf.hxx>
339646dec5SDamjan Jovanovic #include <osl/time.h>
349646dec5SDamjan Jovanovic #include "comphelper/sequence.hxx"
359646dec5SDamjan Jovanovic #include "ucbhelper/simplecertificatevalidationrequest.hxx"
369646dec5SDamjan Jovanovic 
379646dec5SDamjan Jovanovic #include "DAVAuthListener.hxx"
389646dec5SDamjan Jovanovic #include "CurlTypes.hxx"
399646dec5SDamjan Jovanovic #include "CurlSession.hxx"
409646dec5SDamjan Jovanovic #include "LockRequest.hxx"
419646dec5SDamjan Jovanovic #include "PropfindRequest.hxx"
429646dec5SDamjan Jovanovic #include "ProppatchRequest.hxx"
439646dec5SDamjan Jovanovic #include "CurlInputStream.hxx"
449646dec5SDamjan Jovanovic #include "UCBDeadPropertyValue.hxx"
459646dec5SDamjan Jovanovic #include "webdavuseragent.hxx"
469646dec5SDamjan Jovanovic #include "webdavresponseparser.hxx"
479646dec5SDamjan Jovanovic #include "webdavprovider.hxx"
489646dec5SDamjan Jovanovic 
499646dec5SDamjan Jovanovic 
509646dec5SDamjan Jovanovic #include <com/sun/star/xml/crypto/XSecurityEnvironment.hpp>
519646dec5SDamjan Jovanovic #include <com/sun/star/logging/LogLevel.hpp>
529646dec5SDamjan Jovanovic #include <com/sun/star/security/XCertificate.hpp>
539646dec5SDamjan Jovanovic #include <com/sun/star/security/CertificateValidity.hpp>
549646dec5SDamjan Jovanovic #include <com/sun/star/security/CertificateContainerStatus.hpp>
559646dec5SDamjan Jovanovic #include <com/sun/star/security/CertificateContainer.hpp>
569646dec5SDamjan Jovanovic #include <com/sun/star/security/XCertificateContainer.hpp>
579646dec5SDamjan Jovanovic #include <com/sun/star/security/CertAltNameEntry.hpp>
589646dec5SDamjan Jovanovic #include <com/sun/star/security/XSanExtension.hpp>
599646dec5SDamjan Jovanovic #include <com/sun/star/ucb/Lock.hpp>
609646dec5SDamjan Jovanovic #include <com/sun/star/xml/crypto/XSEInitializer.hpp>
619646dec5SDamjan Jovanovic 
629646dec5SDamjan Jovanovic using namespace com::sun::star;
639646dec5SDamjan Jovanovic using namespace com::sun::star::logging;
649646dec5SDamjan Jovanovic using namespace http_dav_ucp;
659646dec5SDamjan Jovanovic 
669646dec5SDamjan Jovanovic #define OID_SUBJECT_ALTERNATIVE_NAME "2.5.29.17"
679646dec5SDamjan Jovanovic 
689646dec5SDamjan Jovanovic struct CredentialsData
699646dec5SDamjan Jovanovic {
709646dec5SDamjan Jovanovic     CredentialsData( CurlSession *curlSession, CurlRequest &curlRequest, const DAVRequestEnvironment &requestEnvironment )
719646dec5SDamjan Jovanovic     : session( curlSession)
729646dec5SDamjan Jovanovic     , request( curlRequest )
739646dec5SDamjan Jovanovic     , env( requestEnvironment )
749646dec5SDamjan Jovanovic     {}
759646dec5SDamjan Jovanovic 
769646dec5SDamjan Jovanovic     CurlSession *session;
779646dec5SDamjan Jovanovic     CurlRequest &request;
789646dec5SDamjan Jovanovic     const DAVRequestEnvironment &env;
799646dec5SDamjan Jovanovic };
809646dec5SDamjan Jovanovic 
819646dec5SDamjan Jovanovic // -------------------------------------------------------------------
829646dec5SDamjan Jovanovic // static members!
839646dec5SDamjan Jovanovic CurlLockStore CurlSession::m_aCurlLockStore;
849646dec5SDamjan Jovanovic 
859646dec5SDamjan Jovanovic 
869646dec5SDamjan Jovanovic // -------------------------------------------------------------------
879646dec5SDamjan Jovanovic // Constructor
889646dec5SDamjan Jovanovic // -------------------------------------------------------------------
899646dec5SDamjan Jovanovic CurlSession::CurlSession(
909646dec5SDamjan Jovanovic         const rtl::Reference< DAVSessionFactory > & rSessionFactory,
919646dec5SDamjan Jovanovic         const rtl::OUString& inUri,
929646dec5SDamjan Jovanovic         const ucbhelper::InternetProxyDecider & rProxyDecider )
939646dec5SDamjan Jovanovic     throw ( DAVException )
949646dec5SDamjan Jovanovic     : DAVSession( rSessionFactory )
959646dec5SDamjan Jovanovic     , m_aMutex()
969646dec5SDamjan Jovanovic     , m_aContext( m_xFactory->getServiceFactory() )
979646dec5SDamjan Jovanovic     , m_aLogger( m_aContext.getUNOContext(), WEBDAV_CONTENT_PROVIDER_SERVICE_NAME )
989646dec5SDamjan Jovanovic     , m_aUri( inUri )
999646dec5SDamjan Jovanovic     , m_aProxyName()
1009646dec5SDamjan Jovanovic     , m_nProxyPort( 0 )
1019646dec5SDamjan Jovanovic     , m_aServerHeaderField()
1029646dec5SDamjan Jovanovic     , m_pCurl( 0 )
1039646dec5SDamjan Jovanovic     , m_bUseChunkedEncoding( false )
1049646dec5SDamjan Jovanovic     , m_bTransferEncodingSwitched( false )
1059646dec5SDamjan Jovanovic     , m_rProxyDecider( rProxyDecider )
1069646dec5SDamjan Jovanovic     , m_aEnv()
1079646dec5SDamjan Jovanovic {
1089646dec5SDamjan Jovanovic     m_pCurl = curl_easy_init();
1099646dec5SDamjan Jovanovic 
1109646dec5SDamjan Jovanovic     curl_easy_setopt( m_pCurl, CURLOPT_HTTPAUTH, CURLAUTH_ANY );
1119646dec5SDamjan Jovanovic     curl_easy_setopt( m_pCurl, CURLOPT_PROXYAUTH, CURLAUTH_ANY );
1129646dec5SDamjan Jovanovic 
1139646dec5SDamjan Jovanovic     curl_easy_setopt( m_pCurl, CURLOPT_SSL_CTX_FUNCTION, Curl_SSLContextCallback );
1149646dec5SDamjan Jovanovic     curl_easy_setopt( m_pCurl, CURLOPT_SSL_CTX_DATA, this );
1159646dec5SDamjan Jovanovic 
1169646dec5SDamjan Jovanovic     if ( m_aLogger.getLogLevel() == LogLevel::FINEST )
1179646dec5SDamjan Jovanovic     {
1189646dec5SDamjan Jovanovic         curl_easy_setopt( m_pCurl, CURLOPT_DEBUGFUNCTION, Curl_DebugCallback );
1199646dec5SDamjan Jovanovic         curl_easy_setopt( m_pCurl, CURLOPT_DEBUGDATA, this );
1209646dec5SDamjan Jovanovic         curl_easy_setopt( m_pCurl, CURLOPT_VERBOSE, 1L);
1219646dec5SDamjan Jovanovic     }
1229646dec5SDamjan Jovanovic     m_aLogger.log( LogLevel::INFO, "CurlSession::CurlSession with URL $1$",
1239646dec5SDamjan Jovanovic         rtl::OUStringToOString( inUri, RTL_TEXTENCODING_UTF8 ).getStr() );
1249646dec5SDamjan Jovanovic }
1259646dec5SDamjan Jovanovic 
1269646dec5SDamjan Jovanovic // -------------------------------------------------------------------
1279646dec5SDamjan Jovanovic // Destructor
1289646dec5SDamjan Jovanovic // -------------------------------------------------------------------
1299646dec5SDamjan Jovanovic CurlSession::~CurlSession( )
1309646dec5SDamjan Jovanovic {
1319646dec5SDamjan Jovanovic     if ( m_pCurl )
1329646dec5SDamjan Jovanovic     {
1339646dec5SDamjan Jovanovic         curl_easy_cleanup( m_pCurl );
1349646dec5SDamjan Jovanovic         m_pCurl = 0;
1359646dec5SDamjan Jovanovic         m_aLogger.log( LogLevel::INFO, "CurlSession::~CurlSession: closed curl session");
1369646dec5SDamjan Jovanovic     }
1379646dec5SDamjan Jovanovic }
1389646dec5SDamjan Jovanovic 
1399646dec5SDamjan Jovanovic // -------------------------------------------------------------------
1409646dec5SDamjan Jovanovic void CurlSession::Init( const DAVRequestEnvironment & rEnv )
1419646dec5SDamjan Jovanovic   throw ( DAVException )
1429646dec5SDamjan Jovanovic {
1439646dec5SDamjan Jovanovic     osl::Guard< osl::Mutex > theGuard( m_aMutex );
1449646dec5SDamjan Jovanovic     m_aEnv = rEnv;
1459646dec5SDamjan Jovanovic     Init();
1469646dec5SDamjan Jovanovic }
1479646dec5SDamjan Jovanovic 
1489646dec5SDamjan Jovanovic // -------------------------------------------------------------------
1499646dec5SDamjan Jovanovic void CurlSession::Init()
1509646dec5SDamjan Jovanovic     throw ( DAVException )
1519646dec5SDamjan Jovanovic {
1529646dec5SDamjan Jovanovic     osl::Guard< osl::Mutex > theGuard( m_aMutex );
1539646dec5SDamjan Jovanovic 
1549646dec5SDamjan Jovanovic     const sal_Char *url = rtl::OUStringToOString( m_aUri.GetURI(), RTL_TEXTENCODING_UTF8 ).getStr();
1559646dec5SDamjan Jovanovic     CURLcode rc;
1569646dec5SDamjan Jovanovic     rc = curl_easy_setopt( m_pCurl, CURLOPT_URL, url );
1579646dec5SDamjan Jovanovic     if ( rc != CURLE_OK  )
1589646dec5SDamjan Jovanovic         throw DAVException( DAVException::DAV_SESSION_CREATE,
1599646dec5SDamjan Jovanovic                             CurlUri::makeConnectionEndPointString( m_aUri.GetHost(), m_aUri.GetPort() ) );
1609646dec5SDamjan Jovanovic 
1619646dec5SDamjan Jovanovic     const ucbhelper::InternetProxyServer & rProxyCfg = getProxySettings();
1629646dec5SDamjan Jovanovic     if ( ( rProxyCfg.aName != m_aProxyName )
1639646dec5SDamjan Jovanovic         || ( rProxyCfg.nPort != m_nProxyPort ) )
1649646dec5SDamjan Jovanovic     {
1659646dec5SDamjan Jovanovic         m_aProxyName = rProxyCfg.aName;
1669646dec5SDamjan Jovanovic         m_nProxyPort = rProxyCfg.nPort;
1679646dec5SDamjan Jovanovic         if ( !m_aProxyName.isEmpty() )
1689646dec5SDamjan Jovanovic         {
1699646dec5SDamjan Jovanovic             m_aLogger.log( LogLevel::INFO, "Using $1$ proxy server at $2$:$3$",
1709646dec5SDamjan Jovanovic                 m_aUri.GetScheme(), m_aProxyName, m_nProxyPort );
1719646dec5SDamjan Jovanovic             curl_easy_setopt( m_pCurl, CURLOPT_PROXY, rtl::OUStringToOString( m_aProxyName, RTL_TEXTENCODING_UTF8 ).getStr() );
1729646dec5SDamjan Jovanovic             curl_easy_setopt( m_pCurl, CURLOPT_PROXYPORT, (long)m_nProxyPort );
1739646dec5SDamjan Jovanovic             if ( m_aUri.GetScheme().equalsAscii( "https" ) )
1749646dec5SDamjan Jovanovic                 curl_easy_setopt( m_pCurl, CURLOPT_PROXYTYPE, CURLPROXY_HTTPS );
1759646dec5SDamjan Jovanovic             else
1769646dec5SDamjan Jovanovic                 curl_easy_setopt( m_pCurl, CURLOPT_PROXYTYPE, CURLPROXY_HTTP );
1779646dec5SDamjan Jovanovic             // no other proxy types are implemented by AOO
1789646dec5SDamjan Jovanovic         }
1799646dec5SDamjan Jovanovic         else
1809646dec5SDamjan Jovanovic         {
1819646dec5SDamjan Jovanovic             // Empty string as opposed to NULL, means don't use the default curl proxy.
1829646dec5SDamjan Jovanovic             m_aLogger.log( LogLevel::INFO, "Not using a proxy server" );
1839646dec5SDamjan Jovanovic             curl_easy_setopt( m_pCurl, CURLOPT_PROXY, "" );
1849646dec5SDamjan Jovanovic         }
1859646dec5SDamjan Jovanovic         // if we change the proxy settings, clear the credentials for the previous proxy too
1869646dec5SDamjan Jovanovic         curl_easy_setopt( m_pCurl, CURLOPT_PROXYUSERNAME, "" );
1879646dec5SDamjan Jovanovic         curl_easy_setopt( m_pCurl, CURLOPT_PROXYPASSWORD, "" );
1889646dec5SDamjan Jovanovic     }
1899646dec5SDamjan Jovanovic }
1909646dec5SDamjan Jovanovic 
1919646dec5SDamjan Jovanovic bool CurlSession::isSSLNeeded()
1929646dec5SDamjan Jovanovic {
1939646dec5SDamjan Jovanovic     return m_aUri.GetScheme().equalsIgnoreAsciiCase( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "https" ) ) );
1949646dec5SDamjan Jovanovic }
1959646dec5SDamjan Jovanovic 
1969646dec5SDamjan Jovanovic // -------------------------------------------------------------------
1979646dec5SDamjan Jovanovic // helper function
1989646dec5SDamjan Jovanovic // it composes the uri for lockstore registration
1999646dec5SDamjan Jovanovic rtl::OUString CurlSession::composeCurrentUri(const rtl::OUString & inPath)
2009646dec5SDamjan Jovanovic {
2019646dec5SDamjan Jovanovic     rtl::OUString aScheme( m_aUri.GetScheme() );
2029646dec5SDamjan Jovanovic     rtl::OUStringBuffer aBuf( aScheme );
2039646dec5SDamjan Jovanovic     aBuf.appendAscii( "://" );
2049646dec5SDamjan Jovanovic     if ( m_aUri.GetUserName().getLength() > 0 )
2059646dec5SDamjan Jovanovic     {
2069646dec5SDamjan Jovanovic         aBuf.append( m_aUri.GetUserName() );
2079646dec5SDamjan Jovanovic         if ( m_aUri.GetPassword().getLength() > 0 )
2089646dec5SDamjan Jovanovic         {
2099646dec5SDamjan Jovanovic             aBuf.appendAscii( ":" );
2109646dec5SDamjan Jovanovic             aBuf.append( m_aUri.GetPassword() );
2119646dec5SDamjan Jovanovic         }
2129646dec5SDamjan Jovanovic         aBuf.appendAscii( "@" );
2139646dec5SDamjan Jovanovic     }
2149646dec5SDamjan Jovanovic     // Is host a numeric IPv6 address?
2159646dec5SDamjan Jovanovic     if ( ( m_aUri.GetHost().indexOf( ':' ) != -1 ) &&
2169646dec5SDamjan Jovanovic          ( m_aUri.GetHost()[ 0 ] != sal_Unicode( '[' ) ) )
2179646dec5SDamjan Jovanovic     {
2189646dec5SDamjan Jovanovic         aBuf.appendAscii( "[" );
2199646dec5SDamjan Jovanovic         aBuf.append( m_aUri.GetHost() );
2209646dec5SDamjan Jovanovic         aBuf.appendAscii( "]" );
2219646dec5SDamjan Jovanovic     }
2229646dec5SDamjan Jovanovic     else
2239646dec5SDamjan Jovanovic     {
2249646dec5SDamjan Jovanovic         aBuf.append( m_aUri.GetHost() );
2259646dec5SDamjan Jovanovic     }
2269646dec5SDamjan Jovanovic 
2279646dec5SDamjan Jovanovic     // append port, but only, if not default port.
2289646dec5SDamjan Jovanovic     bool bAppendPort = true;
2299646dec5SDamjan Jovanovic     sal_Int32 aPort = m_aUri.GetPort();
2309646dec5SDamjan Jovanovic     switch ( aPort )
2319646dec5SDamjan Jovanovic     {
2329646dec5SDamjan Jovanovic     case DEFAULT_HTTP_PORT:
2339646dec5SDamjan Jovanovic         bAppendPort = aScheme.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "http" ) );
2349646dec5SDamjan Jovanovic         break;
2359646dec5SDamjan Jovanovic 
2369646dec5SDamjan Jovanovic     case DEFAULT_HTTPS_PORT:
2379646dec5SDamjan Jovanovic         bAppendPort = !aScheme.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "https" ) );
2389646dec5SDamjan Jovanovic         break;
2399646dec5SDamjan Jovanovic     }
2409646dec5SDamjan Jovanovic     if ( bAppendPort )
2419646dec5SDamjan Jovanovic     {
2429646dec5SDamjan Jovanovic         aBuf.appendAscii( ":" );
2439646dec5SDamjan Jovanovic         aBuf.append( rtl::OUString::valueOf( aPort ) );
2449646dec5SDamjan Jovanovic     }
2459646dec5SDamjan Jovanovic     aBuf.append( inPath );
2469646dec5SDamjan Jovanovic 
2479646dec5SDamjan Jovanovic     rtl::OUString   aUri(aBuf.makeStringAndClear() );
2489646dec5SDamjan Jovanovic     return aUri;
2499646dec5SDamjan Jovanovic }
2509646dec5SDamjan Jovanovic 
2519646dec5SDamjan Jovanovic // -------------------------------------------------------------------
2529646dec5SDamjan Jovanovic // virtual
2539646dec5SDamjan Jovanovic sal_Bool CurlSession::CanUse( const rtl::OUString & inUri )
2549646dec5SDamjan Jovanovic {
2559646dec5SDamjan Jovanovic     try
2569646dec5SDamjan Jovanovic     {
2579646dec5SDamjan Jovanovic         CurlUri theUri( inUri );
2589646dec5SDamjan Jovanovic         if ( ( theUri.GetPort() == m_aUri.GetPort() ) &&
2599646dec5SDamjan Jovanovic              ( theUri.GetHost() == m_aUri.GetHost() ) &&
2609646dec5SDamjan Jovanovic              ( theUri.GetScheme() == m_aUri.GetScheme() ) )
2619646dec5SDamjan Jovanovic         {
2629646dec5SDamjan Jovanovic             return sal_True;
2639646dec5SDamjan Jovanovic         }
2649646dec5SDamjan Jovanovic     }
2659646dec5SDamjan Jovanovic     catch ( DAVException const & )
2669646dec5SDamjan Jovanovic     {
2679646dec5SDamjan Jovanovic         return sal_False;
2689646dec5SDamjan Jovanovic     }
2699646dec5SDamjan Jovanovic     return sal_False;
2709646dec5SDamjan Jovanovic }
2719646dec5SDamjan Jovanovic 
2729646dec5SDamjan Jovanovic // -------------------------------------------------------------------
2739646dec5SDamjan Jovanovic // virtual
2749646dec5SDamjan Jovanovic sal_Bool CurlSession::UsesProxy()
2759646dec5SDamjan Jovanovic {
2769646dec5SDamjan Jovanovic     Init();
2779646dec5SDamjan Jovanovic     return ( m_aProxyName.getLength() > 0 );
2789646dec5SDamjan Jovanovic }
2799646dec5SDamjan Jovanovic 
2809646dec5SDamjan Jovanovic int CurlSession::Curl_DebugCallback( CURL *, curl_infotype type, unsigned char *data, size_t size, void* userdata )
2819646dec5SDamjan Jovanovic {
2829646dec5SDamjan Jovanovic     CurlSession *session = static_cast< CurlSession* >( userdata );
2839646dec5SDamjan Jovanovic     return session->curlDebugOutput( type, reinterpret_cast<char*>( data ), size );
2849646dec5SDamjan Jovanovic }
2859646dec5SDamjan Jovanovic 
2869646dec5SDamjan Jovanovic int CurlSession::curlDebugOutput( curl_infotype type, char *data, int size )
2879646dec5SDamjan Jovanovic {
2889646dec5SDamjan Jovanovic     const char *prefix;
2899646dec5SDamjan Jovanovic     switch ( type )
2909646dec5SDamjan Jovanovic     {
2919646dec5SDamjan Jovanovic         case CURLINFO_TEXT:
2929646dec5SDamjan Jovanovic             prefix = "[CurlINFO  ]";
2939646dec5SDamjan Jovanovic             break;
2949646dec5SDamjan Jovanovic         case CURLINFO_HEADER_IN:
2959646dec5SDamjan Jovanovic             prefix = "[CurlHDR <-]";
2969646dec5SDamjan Jovanovic             break;
2979646dec5SDamjan Jovanovic         case CURLINFO_HEADER_OUT:
2989646dec5SDamjan Jovanovic             prefix = "[CurlHDR ->]";
2999646dec5SDamjan Jovanovic             break;
3009646dec5SDamjan Jovanovic         case CURLINFO_DATA_IN:
3019646dec5SDamjan Jovanovic             prefix = "[CurlData<-]";
3029646dec5SDamjan Jovanovic             break;
3039646dec5SDamjan Jovanovic         case CURLINFO_DATA_OUT:
3049646dec5SDamjan Jovanovic             prefix = "[CurlData->]";
3059646dec5SDamjan Jovanovic             break;
3069646dec5SDamjan Jovanovic         default:
3079646dec5SDamjan Jovanovic             return 0;
3089646dec5SDamjan Jovanovic     }
3099646dec5SDamjan Jovanovic 
3109646dec5SDamjan Jovanovic     // Trim the trailing \r\n
3119646dec5SDamjan Jovanovic     if ( size >= 1 && ( data[size - 1] == '\r' || data[size - 1] == '\n' ) )
3129646dec5SDamjan Jovanovic         --size;
3139646dec5SDamjan Jovanovic     if ( size >= 1 && ( data[size - 1] == '\r' || data[size - 1] == '\n' ) )
3149646dec5SDamjan Jovanovic         --size;
3159646dec5SDamjan Jovanovic     rtl::OString message( data, size );
3169646dec5SDamjan Jovanovic     m_aLogger.log( LogLevel::FINEST, "$1$ $2$", prefix, message );
3179646dec5SDamjan Jovanovic     return 0;
3189646dec5SDamjan Jovanovic }
3199646dec5SDamjan Jovanovic 
3209646dec5SDamjan Jovanovic CURLcode CurlSession::Curl_SSLContextCallback( CURL *, void *ssl_ctx, void *userptr )
3219646dec5SDamjan Jovanovic {
3229646dec5SDamjan Jovanovic     CurlSession *session = static_cast<CurlSession*>( userptr );
3239646dec5SDamjan Jovanovic     SSL_CTX *context = static_cast<SSL_CTX*>( ssl_ctx );
3249646dec5SDamjan Jovanovic     SSL_CTX_set_app_data( context, session );
3259646dec5SDamjan Jovanovic     SSL_CTX_set_verify( context, SSL_VERIFY_PEER, OPENSSL_ValidateServerCertificate );
3269646dec5SDamjan Jovanovic     return CURLE_OK;
3279646dec5SDamjan Jovanovic }
3289646dec5SDamjan Jovanovic 
3299646dec5SDamjan Jovanovic int CurlSession::OPENSSL_ValidateServerCertificate( int preverify_ok, X509_STORE_CTX *x509_ctx )
3309646dec5SDamjan Jovanovic {
3319646dec5SDamjan Jovanovic     SSL *ssl = static_cast<SSL*> (
3329646dec5SDamjan Jovanovic         X509_STORE_CTX_get_ex_data( x509_ctx, SSL_get_ex_data_X509_STORE_CTX_idx() ) );
3339646dec5SDamjan Jovanovic     SSL_CTX *ssl_ctx = SSL_get_SSL_CTX( ssl );
3349646dec5SDamjan Jovanovic     CurlSession *session = static_cast<CurlSession*>( SSL_CTX_get_app_data( ssl_ctx ) );
3359646dec5SDamjan Jovanovic     int verifyOk = session->validateServerX509Certificate( x509_ctx, preverify_ok );
3369646dec5SDamjan Jovanovic     // When a certificate's verification fails within OpenSSL, yet passes from the
3379646dec5SDamjan Jovanovic     // SSL_CTX_set_verify() callback (ie. this function) (by returning 1),
3389646dec5SDamjan Jovanovic     // OpenSSL allows the connection to proceed, yet stores that last verification
3399646dec5SDamjan Jovanovic     // error and allows it to be retrieved using SSL_get_verify_result(3).
3409646dec5SDamjan Jovanovic     //
3419646dec5SDamjan Jovanovic     // Unfortunately, Curl calls SSL_get_verify_result(3) internally, and treats
3429646dec5SDamjan Jovanovic     // errors as terminal, disconnecting with an error even when we return 1 here.
3439646dec5SDamjan Jovanovic     // Therefore, to approve a certificate that OpenSSL would reject, we have to
3449646dec5SDamjan Jovanovic     // both return 1, and overwrite the X509_STORE_CTX's last error with X509_V_OK:
3459646dec5SDamjan Jovanovic     if ( verifyOk )
3469646dec5SDamjan Jovanovic         X509_STORE_CTX_set_error( x509_ctx, X509_V_OK );
3479646dec5SDamjan Jovanovic     return verifyOk;
3489646dec5SDamjan Jovanovic }
3499646dec5SDamjan Jovanovic 
3509646dec5SDamjan Jovanovic static uno::Sequence< sal_Int8 > convertCertificateToAsn1Der( X509 *certificate )
3519646dec5SDamjan Jovanovic {
3529646dec5SDamjan Jovanovic     uno::Sequence< sal_Int8 > asn1DerCertificate;
3539646dec5SDamjan Jovanovic     int len = i2d_X509( certificate, NULL );
3549646dec5SDamjan Jovanovic     if ( len < 0 )
3559646dec5SDamjan Jovanovic         return asn1DerCertificate;
3569646dec5SDamjan Jovanovic     asn1DerCertificate.realloc( len );
3579646dec5SDamjan Jovanovic     unsigned char *end = reinterpret_cast< unsigned char *>( asn1DerCertificate.getArray() );
3589646dec5SDamjan Jovanovic     len = i2d_X509( certificate, &end );
3599646dec5SDamjan Jovanovic     if ( len >= 0 )
3609646dec5SDamjan Jovanovic         return asn1DerCertificate;
3619646dec5SDamjan Jovanovic     else
3629646dec5SDamjan Jovanovic         return uno::Sequence< sal_Int8 >();
3639646dec5SDamjan Jovanovic }
3649646dec5SDamjan Jovanovic 
3659646dec5SDamjan Jovanovic int CurlSession::validateServerX509Certificate( X509_STORE_CTX *x509StoreContext, int verifyOk )
3669646dec5SDamjan Jovanovic {
3679646dec5SDamjan Jovanovic     X509 *serverCertificate = X509_STORE_CTX_get_current_cert( x509StoreContext );
3689646dec5SDamjan Jovanovic     int depth = X509_STORE_CTX_get_error_depth( x509StoreContext );
3699646dec5SDamjan Jovanovic     STACK_OF(X509) *chain =
3709646dec5SDamjan Jovanovic #if OPENSSL_VERSION_NUMBER >= 0x10100000L
3719646dec5SDamjan Jovanovic          X509_STORE_CTX_get0_chain( x509StoreContext );
3729646dec5SDamjan Jovanovic #else
3739646dec5SDamjan Jovanovic          X509_STORE_CTX_get_chain( x509StoreContext );
3749646dec5SDamjan Jovanovic #endif
3759646dec5SDamjan Jovanovic 
3769646dec5SDamjan Jovanovic     std::vector< uno::Sequence< sal_Int8 > > asn1DerCertificates;
3779646dec5SDamjan Jovanovic     if ( chain != NULL ) {
3789646dec5SDamjan Jovanovic         int nCertificates = sk_X509_num( chain );
3799646dec5SDamjan Jovanovic         for ( int i = 0; i < nCertificates; i++ ) {
3809646dec5SDamjan Jovanovic             X509 *certificate = sk_X509_value( chain, i );
3819646dec5SDamjan Jovanovic             uno::Sequence< sal_Int8 > asn1DerCertificate = convertCertificateToAsn1Der( certificate );
3829646dec5SDamjan Jovanovic             if ( asn1DerCertificate.getLength() == 0 )
3839646dec5SDamjan Jovanovic                 return 0;
3849646dec5SDamjan Jovanovic             asn1DerCertificates.push_back( asn1DerCertificate );
3859646dec5SDamjan Jovanovic         }
3869646dec5SDamjan Jovanovic     } else {
3879646dec5SDamjan Jovanovic         uno::Sequence< sal_Int8 > asn1DerCertificate = convertCertificateToAsn1Der( serverCertificate );
3889646dec5SDamjan Jovanovic         if ( asn1DerCertificate.getLength() == 0 )
3899646dec5SDamjan Jovanovic             return 0;
3909646dec5SDamjan Jovanovic         asn1DerCertificates.push_back( asn1DerCertificate );
3919646dec5SDamjan Jovanovic     }
3929646dec5SDamjan Jovanovic     verifyOk = verifyCertificateChain( asn1DerCertificates );
393*f7ba5d5aSDamjan Jovanovic 
3949646dec5SDamjan Jovanovic     m_aLogger.log( LogLevel::FINE, "validateServerX509Certificate() returning $1$ at depth $2$",
3959646dec5SDamjan Jovanovic         (sal_Int32)verifyOk, (sal_Int32)depth );
3969646dec5SDamjan Jovanovic     return verifyOk;
3979646dec5SDamjan Jovanovic }
3989646dec5SDamjan Jovanovic 
3999646dec5SDamjan Jovanovic int CurlSession::verifyCertificateChain (
4009646dec5SDamjan Jovanovic     std::vector< uno::Sequence< sal_Int8 > > &asn1DerCertificates )
4019646dec5SDamjan Jovanovic {
4029646dec5SDamjan Jovanovic     // Check arguments.
4039646dec5SDamjan Jovanovic     if (asn1DerCertificates.size()<=0)
4049646dec5SDamjan Jovanovic     {
4059646dec5SDamjan Jovanovic         OSL_ASSERT(asn1DerCertificates.size()>0);
4069646dec5SDamjan Jovanovic         return 0;
4079646dec5SDamjan Jovanovic     }
4089646dec5SDamjan Jovanovic 
4099646dec5SDamjan Jovanovic     // Create some crypto objects to decode and handle the base64
4109646dec5SDamjan Jovanovic     // encoded certificate chain.
4119646dec5SDamjan Jovanovic     uno::Reference< xml::crypto::XSEInitializer > xSEInitializer;
4129646dec5SDamjan Jovanovic     uno::Reference< security::XCertificateContainer > xCertificateContainer;
4139646dec5SDamjan Jovanovic     uno::Reference< xml::crypto::XXMLSecurityContext > xSecurityContext;
4149646dec5SDamjan Jovanovic     uno::Reference< xml::crypto::XSecurityEnvironment > xSecurityEnv;
4159646dec5SDamjan Jovanovic     try
4169646dec5SDamjan Jovanovic     {
4179646dec5SDamjan Jovanovic         // Create a certificate container.
4189646dec5SDamjan Jovanovic         xCertificateContainer = uno::Reference< security::XCertificateContainer >(
4199646dec5SDamjan Jovanovic             getMSF()->createInstance(
4209646dec5SDamjan Jovanovic                 rtl::OUString::createFromAscii(
4219646dec5SDamjan Jovanovic                     "com.sun.star.security.CertificateContainer" ) ),
4229646dec5SDamjan Jovanovic             uno::UNO_QUERY_THROW);
4239646dec5SDamjan Jovanovic 
4249646dec5SDamjan Jovanovic         xSEInitializer = uno::Reference< xml::crypto::XSEInitializer >(
4259646dec5SDamjan Jovanovic             getMSF()->createInstance(
4269646dec5SDamjan Jovanovic                 rtl::OUString::createFromAscii( "com.sun.star.xml.crypto.SEInitializer" ) ),
4279646dec5SDamjan Jovanovic             uno::UNO_QUERY_THROW);
4289646dec5SDamjan Jovanovic 
4299646dec5SDamjan Jovanovic         xSecurityContext = xSEInitializer->createSecurityContext( rtl::OUString() );
4309646dec5SDamjan Jovanovic         if (xSecurityContext.is())
4319646dec5SDamjan Jovanovic             xSecurityEnv = xSecurityContext->getSecurityEnvironment();
4329646dec5SDamjan Jovanovic 
4339646dec5SDamjan Jovanovic         if ( ! xSecurityContext.is() || ! xSecurityEnv.is())
4349646dec5SDamjan Jovanovic         {
4359646dec5SDamjan Jovanovic             // Do we have to dispose xSEInitializer or xCertificateContainer?
4369646dec5SDamjan Jovanovic             m_aLogger.log( LogLevel::WARNING, "Failure creating security services for certificate verification" );
4379646dec5SDamjan Jovanovic             return 0;
4389646dec5SDamjan Jovanovic         }
4399646dec5SDamjan Jovanovic     }
4409646dec5SDamjan Jovanovic     catch ( uno::Exception const &e)
4419646dec5SDamjan Jovanovic     {
4429646dec5SDamjan Jovanovic         m_aLogger.log( LogLevel::WARNING, "Error creating security services: $1$", e.Message );
4439646dec5SDamjan Jovanovic         return 0;
4449646dec5SDamjan Jovanovic     }
4459646dec5SDamjan Jovanovic 
4469646dec5SDamjan Jovanovic     // Decode the server certificate.
4479646dec5SDamjan Jovanovic     uno::Reference< security::XCertificate > xServerCertificate(
4489646dec5SDamjan Jovanovic         xSecurityEnv->createCertificateFromRaw( asn1DerCertificates[0] ) );
4499646dec5SDamjan Jovanovic     if ( ! xServerCertificate.is())
4509646dec5SDamjan Jovanovic     {
4519646dec5SDamjan Jovanovic         m_aLogger.log( LogLevel::WARNING, "Failed to create XCertificate" );
4529646dec5SDamjan Jovanovic         return 0;
4539646dec5SDamjan Jovanovic     }
4549646dec5SDamjan Jovanovic 
4559646dec5SDamjan Jovanovic     // Get the subject from the server certificate.
4569646dec5SDamjan Jovanovic     ::rtl::OUString sServerCertificateSubject (xServerCertificate->getSubjectName());
4579646dec5SDamjan Jovanovic     sal_Int32 nIndex = 0;
4589646dec5SDamjan Jovanovic     while (nIndex >= 0)
4599646dec5SDamjan Jovanovic     {
4609646dec5SDamjan Jovanovic         const ::rtl::OUString sToken (sServerCertificateSubject.getToken(0, ',', nIndex));
4619646dec5SDamjan Jovanovic         if (sToken.compareToAscii("CN=", 3) == 0)
4629646dec5SDamjan Jovanovic         {
4639646dec5SDamjan Jovanovic             sServerCertificateSubject = sToken.copy(3);
4649646dec5SDamjan Jovanovic             break;
4659646dec5SDamjan Jovanovic         }
4669646dec5SDamjan Jovanovic         else if (sToken.compareToAscii(" CN=", 4) == 0)
4679646dec5SDamjan Jovanovic         {
4689646dec5SDamjan Jovanovic             sServerCertificateSubject = sToken.copy(4);
4699646dec5SDamjan Jovanovic             break;
4709646dec5SDamjan Jovanovic         }
4719646dec5SDamjan Jovanovic     }
4729646dec5SDamjan Jovanovic 
4739646dec5SDamjan Jovanovic     // When the certificate container already contains a (trusted)
4749646dec5SDamjan Jovanovic     // entry for the server then we do not have to authenticate any
4759646dec5SDamjan Jovanovic     // certificate.
4769646dec5SDamjan Jovanovic     const security::CertificateContainerStatus eStatus (
4779646dec5SDamjan Jovanovic         xCertificateContainer->hasCertificate(
4789646dec5SDamjan Jovanovic             getHostName(), sServerCertificateSubject ) );
4799646dec5SDamjan Jovanovic     if (eStatus != security::CertificateContainerStatus_NOCERT)
4809646dec5SDamjan Jovanovic     {
4819646dec5SDamjan Jovanovic         m_aLogger.log( LogLevel::FINER, "Cached certificate found with status=$1$",
4829646dec5SDamjan Jovanovic                 eStatus == security::CertificateContainerStatus_TRUSTED ? "trusted" : "untrusted" );
4839646dec5SDamjan Jovanovic         return eStatus == security::CertificateContainerStatus_TRUSTED
4849646dec5SDamjan Jovanovic                ? 1
4859646dec5SDamjan Jovanovic                : 0;
4869646dec5SDamjan Jovanovic     }
4879646dec5SDamjan Jovanovic 
4889646dec5SDamjan Jovanovic     // The shortcut failed, so try to verify the whole chain. This is
4899646dec5SDamjan Jovanovic     // done outside the isDomainMatch() block because the result is
4909646dec5SDamjan Jovanovic     // used by the interaction handler.
4919646dec5SDamjan Jovanovic     std::vector< uno::Reference< security::XCertificate > > aChain;
4929646dec5SDamjan Jovanovic     for (nIndex=0; nIndex < asn1DerCertificates.size(); ++nIndex)
4939646dec5SDamjan Jovanovic     {
4949646dec5SDamjan Jovanovic         uno::Reference< security::XCertificate > xCertificate(
4959646dec5SDamjan Jovanovic             xSecurityEnv->createCertificateFromRaw( asn1DerCertificates[ nIndex ] ) );
4969646dec5SDamjan Jovanovic         if ( ! xCertificate.is())
4979646dec5SDamjan Jovanovic         {
4989646dec5SDamjan Jovanovic             m_aLogger.log( LogLevel::FINE, "Failed to create XCertificate $1$", nIndex );
4999646dec5SDamjan Jovanovic             return 0;
5009646dec5SDamjan Jovanovic         }
5019646dec5SDamjan Jovanovic         aChain.push_back(xCertificate);
5029646dec5SDamjan Jovanovic     }
5039646dec5SDamjan Jovanovic     const sal_Int64 nVerificationResult (xSecurityEnv->verifyCertificate(
5049646dec5SDamjan Jovanovic             xServerCertificate,
5059646dec5SDamjan Jovanovic             ::comphelper::containerToSequence(aChain)));
5069646dec5SDamjan Jovanovic 
5079646dec5SDamjan Jovanovic     // When the certificate matches the host name then we can use the
5089646dec5SDamjan Jovanovic     // result of the verification.
5099646dec5SDamjan Jovanovic     bool bHostnameMatchesCertHostnames = false;
5109646dec5SDamjan Jovanovic     {
5119646dec5SDamjan Jovanovic         uno::Sequence< uno::Reference< security::XCertificateExtension > > extensions = xServerCertificate->getExtensions();
5129646dec5SDamjan Jovanovic         uno::Sequence< security::CertAltNameEntry > altNames;
5139646dec5SDamjan Jovanovic         for (sal_Int32 i = 0 ; i < extensions.getLength(); ++i)
5149646dec5SDamjan Jovanovic         {
5159646dec5SDamjan Jovanovic             uno::Reference< security::XCertificateExtension >element = extensions[i];
5169646dec5SDamjan Jovanovic 
5179646dec5SDamjan Jovanovic             const rtl::OString aId ( (const sal_Char *)element->getExtensionId().getArray(), element->getExtensionId().getLength());
5189646dec5SDamjan Jovanovic             if ( aId.equals( OID_SUBJECT_ALTERNATIVE_NAME ) )
5199646dec5SDamjan Jovanovic             {
5209646dec5SDamjan Jovanovic                 uno::Reference< security::XSanExtension > sanExtension ( element, uno::UNO_QUERY );
5219646dec5SDamjan Jovanovic                 altNames = sanExtension->getAlternativeNames();
5229646dec5SDamjan Jovanovic                 break;
5239646dec5SDamjan Jovanovic             }
5249646dec5SDamjan Jovanovic         }
5259646dec5SDamjan Jovanovic 
5269646dec5SDamjan Jovanovic         uno::Sequence< ::rtl::OUString > certHostNames(altNames.getLength() + 1);
5279646dec5SDamjan Jovanovic         certHostNames[0] = sServerCertificateSubject;
5289646dec5SDamjan Jovanovic         for( int n = 0; n < altNames.getLength(); ++n )
5299646dec5SDamjan Jovanovic         {
5309646dec5SDamjan Jovanovic             if (altNames[n].Type == security::ExtAltNameType_DNS_NAME)
5319646dec5SDamjan Jovanovic             {
5329646dec5SDamjan Jovanovic                 altNames[n].Value >>= certHostNames[n+1];
5339646dec5SDamjan Jovanovic             }
5349646dec5SDamjan Jovanovic         }
5359646dec5SDamjan Jovanovic 
5369646dec5SDamjan Jovanovic         for ( int i = 0; i < certHostNames.getLength() && !bHostnameMatchesCertHostnames; ++i )
5379646dec5SDamjan Jovanovic         {
5389646dec5SDamjan Jovanovic             bHostnameMatchesCertHostnames = isDomainMatch( certHostNames[i] );
5399646dec5SDamjan Jovanovic         }
5409646dec5SDamjan Jovanovic 
5419646dec5SDamjan Jovanovic     }
5429646dec5SDamjan Jovanovic     m_aLogger.log( LogLevel::FINE, "URL hostname $1$ certificate hostname",
5439646dec5SDamjan Jovanovic         bHostnameMatchesCertHostnames ? "matches" : "DOESN'T MATCH" );
5449646dec5SDamjan Jovanovic     if ( bHostnameMatchesCertHostnames )
5459646dec5SDamjan Jovanovic     {
5469646dec5SDamjan Jovanovic         if (nVerificationResult == 0)
5479646dec5SDamjan Jovanovic         {
5489646dec5SDamjan Jovanovic             m_aLogger.log( LogLevel::FINE, "Certificate (chain) is valid" );
5499646dec5SDamjan Jovanovic             xCertificateContainer->addCertificate(getHostName(), sServerCertificateSubject, sal_True);
5509646dec5SDamjan Jovanovic             return 1;
5519646dec5SDamjan Jovanovic         }
5529646dec5SDamjan Jovanovic         else if ((nVerificationResult & security::CertificateValidity::CHAIN_INCOMPLETE) != 0)
5539646dec5SDamjan Jovanovic         {
5549646dec5SDamjan Jovanovic             // We do not have enough information for verification,
5559646dec5SDamjan Jovanovic             // neither automatically (as we just discovered) nor
5569646dec5SDamjan Jovanovic             // manually (so there is no point in showing any dialog.)
5579646dec5SDamjan Jovanovic             m_aLogger.log( LogLevel::WARNING, "Certificate (chain) is incomplete" );
5589646dec5SDamjan Jovanovic             return 0;
5599646dec5SDamjan Jovanovic         }
5609646dec5SDamjan Jovanovic         else if ((nVerificationResult & security::CertificateValidity::REVOKED) != 0)
5619646dec5SDamjan Jovanovic         {
5629646dec5SDamjan Jovanovic             // Certificate (chain) is invalid.
5639646dec5SDamjan Jovanovic             m_aLogger.log( LogLevel::WARNING, "Certificate (chain) is revoked" );
5649646dec5SDamjan Jovanovic             xCertificateContainer->addCertificate(getHostName(), sServerCertificateSubject,  sal_False);
5659646dec5SDamjan Jovanovic             return 0;
5669646dec5SDamjan Jovanovic         }
5679646dec5SDamjan Jovanovic         else
5689646dec5SDamjan Jovanovic         {
5699646dec5SDamjan Jovanovic             // For all other we have to ask the user.
5709646dec5SDamjan Jovanovic             m_aLogger.log( LogLevel::FINE, "Promping user to validate the certificate" );
5719646dec5SDamjan Jovanovic         }
5729646dec5SDamjan Jovanovic     }
5739646dec5SDamjan Jovanovic 
5749646dec5SDamjan Jovanovic     // We have not been able to automatically verify (or falsify) the
5759646dec5SDamjan Jovanovic     // certificate chain. To resolve this we have to ask the user.
5769646dec5SDamjan Jovanovic     const uno::Reference< ucb::XCommandEnvironment > xEnv( getRequestEnvironment().m_xEnv );
5779646dec5SDamjan Jovanovic     if ( xEnv.is() )
5789646dec5SDamjan Jovanovic     {
5799646dec5SDamjan Jovanovic         uno::Reference< task::XInteractionHandler > xIH( xEnv->getInteractionHandler() );
5809646dec5SDamjan Jovanovic         if ( xIH.is() )
5819646dec5SDamjan Jovanovic         {
5829646dec5SDamjan Jovanovic             rtl::Reference< ucbhelper::SimpleCertificateValidationRequest >
5839646dec5SDamjan Jovanovic                 xRequest( new ucbhelper::SimpleCertificateValidationRequest(
5849646dec5SDamjan Jovanovic                         static_cast<sal_Int32>(nVerificationResult), xServerCertificate, getHostName() ) );
5859646dec5SDamjan Jovanovic             xIH->handle( xRequest.get() );
5869646dec5SDamjan Jovanovic 
5879646dec5SDamjan Jovanovic             rtl::Reference< ucbhelper::InteractionContinuation > xSelection
5889646dec5SDamjan Jovanovic                 = xRequest->getSelection();
5899646dec5SDamjan Jovanovic 
5909646dec5SDamjan Jovanovic             if ( xSelection.is() )
5919646dec5SDamjan Jovanovic             {
5929646dec5SDamjan Jovanovic                 uno::Reference< task::XInteractionApprove > xApprove( xSelection.get(), uno::UNO_QUERY );
5939646dec5SDamjan Jovanovic                 if ( xApprove.is() )
5949646dec5SDamjan Jovanovic                 {
5959646dec5SDamjan Jovanovic                     m_aLogger.log( LogLevel::FINE, "The user approved the certificate" );
5969646dec5SDamjan Jovanovic                     xCertificateContainer->addCertificate( getHostName(), sServerCertificateSubject, sal_True );
5979646dec5SDamjan Jovanovic                     return 1;
5989646dec5SDamjan Jovanovic                 }
5999646dec5SDamjan Jovanovic                 else
6009646dec5SDamjan Jovanovic                 {
6019646dec5SDamjan Jovanovic                     // Don't trust cert
6029646dec5SDamjan Jovanovic                     m_aLogger.log( LogLevel::FINE, "The user REJECTED the certificate" );
6039646dec5SDamjan Jovanovic                     xCertificateContainer->addCertificate( getHostName(), sServerCertificateSubject, sal_False );
6049646dec5SDamjan Jovanovic                     return 0;
6059646dec5SDamjan Jovanovic                 }
6069646dec5SDamjan Jovanovic             }
6079646dec5SDamjan Jovanovic         }
6089646dec5SDamjan Jovanovic         else
6099646dec5SDamjan Jovanovic         {
6109646dec5SDamjan Jovanovic             // Don't trust cert
6119646dec5SDamjan Jovanovic             m_aLogger.log( LogLevel::WARNING, "Couldn't create the interaction handler for user feedback, rejecting the certificate" );
6129646dec5SDamjan Jovanovic             xCertificateContainer->addCertificate( getHostName(), sServerCertificateSubject, sal_False );
6139646dec5SDamjan Jovanovic             return 0;
6149646dec5SDamjan Jovanovic         }
6159646dec5SDamjan Jovanovic     }
6169646dec5SDamjan Jovanovic     m_aLogger.log( LogLevel::WARNING, "No XCommandEnvironment, rejecting the certificate" );
6179646dec5SDamjan Jovanovic 
6189646dec5SDamjan Jovanovic     return 0;
6199646dec5SDamjan Jovanovic }
6209646dec5SDamjan Jovanovic 
6219646dec5SDamjan Jovanovic bool CurlSession::Curl_ProvideCredentials( long statusCode, void *userdata ) throw (DAVException)
6229646dec5SDamjan Jovanovic {
6239646dec5SDamjan Jovanovic     CredentialsData *credentialsData = (CredentialsData*)userdata;
6249646dec5SDamjan Jovanovic     return credentialsData->session->provideCredentials( credentialsData->env, credentialsData->request, statusCode );
6259646dec5SDamjan Jovanovic }
6269646dec5SDamjan Jovanovic 
6279646dec5SDamjan Jovanovic bool CurlSession::provideCredentials( const DAVRequestEnvironment &env, CurlRequest &request, long statusCode ) throw (DAVException)
6289646dec5SDamjan Jovanovic {
6299646dec5SDamjan Jovanovic     DAVAuthListener * pListener = env.m_xAuthListener.get();
6309646dec5SDamjan Jovanovic     if ( !pListener )
6319646dec5SDamjan Jovanovic     {
6329646dec5SDamjan Jovanovic         // abort
6339646dec5SDamjan Jovanovic         m_aLogger.log( LogLevel::FINE, "No DAVAuthListener found, failing credentials entry" );
6349646dec5SDamjan Jovanovic         return false;
6359646dec5SDamjan Jovanovic     }
6369646dec5SDamjan Jovanovic 
6379646dec5SDamjan Jovanovic     rtl::OUString theUserName;
6389646dec5SDamjan Jovanovic     rtl::OUString thePassWord;
6399646dec5SDamjan Jovanovic     try
6409646dec5SDamjan Jovanovic     {
6419646dec5SDamjan Jovanovic         CurlUri uri( env.m_aRequestURI );
6429646dec5SDamjan Jovanovic         theUserName = uri.GetUserName();
6439646dec5SDamjan Jovanovic         thePassWord = uri.GetPassword();
6449646dec5SDamjan Jovanovic     }
6459646dec5SDamjan Jovanovic     catch ( DAVException const &e )
6469646dec5SDamjan Jovanovic     {
6479646dec5SDamjan Jovanovic         // abort
6489646dec5SDamjan Jovanovic         m_aLogger.log(
6499646dec5SDamjan Jovanovic             LogLevel::WARNING,
6509646dec5SDamjan Jovanovic             "Error extracing userinfo from URI: exceptionCode=$1$, status=$2$, data=$3$, owner=$4$, extendedError=$5%",
6519646dec5SDamjan Jovanovic             (sal_Int32)e.getError(), e.getStatus(), e.getData(), e.getOwner(), e.getExtendedError()
6529646dec5SDamjan Jovanovic         );
6539646dec5SDamjan Jovanovic         return false;
6549646dec5SDamjan Jovanovic     }
6559646dec5SDamjan Jovanovic 
6569646dec5SDamjan Jovanovic     bool canUseSystemCreds = false;
6579646dec5SDamjan Jovanovic     long authMethods = 0;
6589646dec5SDamjan Jovanovic     CURLcode rc = CURLE_OK;
6599646dec5SDamjan Jovanovic     if ( statusCode == 401 )
6609646dec5SDamjan Jovanovic         rc = curl_easy_getinfo( m_pCurl, CURLINFO_HTTPAUTH_AVAIL, &authMethods );
6619646dec5SDamjan Jovanovic     else if ( statusCode == 407 )
6629646dec5SDamjan Jovanovic         rc = curl_easy_getinfo( m_pCurl, CURLINFO_PROXYAUTH_AVAIL, &authMethods );
6639646dec5SDamjan Jovanovic     if ( rc == 0 )
6649646dec5SDamjan Jovanovic         canUseSystemCreds = (authMethods & CURLAUTH_NEGOTIATE) || (authMethods & CURLAUTH_NTLM);
6659646dec5SDamjan Jovanovic     m_aLogger.log( LogLevel::FINE, "authMethods=$1$, canUseSystemCreds=$2$",
6669646dec5SDamjan Jovanovic         (sal_Int64)authMethods, (sal_Int32)canUseSystemCreds );
6679646dec5SDamjan Jovanovic 
6689646dec5SDamjan Jovanovic     const CurlRequest::Header *authHeader = NULL;
6699646dec5SDamjan Jovanovic     if ( statusCode == 401 )
6709646dec5SDamjan Jovanovic         authHeader = request.findResponseHeader( "WWW-Authenticate" );
6719646dec5SDamjan Jovanovic     else if ( statusCode == 407 )
6729646dec5SDamjan Jovanovic         authHeader = request.findResponseHeader( "Proxy-Authenticate" );
6739646dec5SDamjan Jovanovic     rtl::OUString realm;
6749646dec5SDamjan Jovanovic     if ( authHeader != NULL )
6759646dec5SDamjan Jovanovic     {
6769646dec5SDamjan Jovanovic         int realmStart = authHeader->value.indexOf( "realm=\"" );
6779646dec5SDamjan Jovanovic         if ( realmStart >= 0 )
6789646dec5SDamjan Jovanovic         {
6799646dec5SDamjan Jovanovic             realmStart += 7;
6809646dec5SDamjan Jovanovic             int realmEnd = authHeader->value.indexOf( "\"", realmStart );
6819646dec5SDamjan Jovanovic             if ( realmEnd > 0 )
6829646dec5SDamjan Jovanovic                 realm = rtl::OStringToOUString( authHeader->value.copy( realmStart, realmEnd - realmStart ), RTL_TEXTENCODING_UTF8 );
6839646dec5SDamjan Jovanovic         }
6849646dec5SDamjan Jovanovic     }
6859646dec5SDamjan Jovanovic 
6869646dec5SDamjan Jovanovic     int theRetVal = pListener->authenticate( realm,
6879646dec5SDamjan Jovanovic                                              getHostName(),
6889646dec5SDamjan Jovanovic                                              theUserName,
6899646dec5SDamjan Jovanovic                                              thePassWord,
6909646dec5SDamjan Jovanovic                                              canUseSystemCreds,
6919646dec5SDamjan Jovanovic                                              // Authenticating with both the proxy
6929646dec5SDamjan Jovanovic                                              // and the destination server requires sal_True here,
6939646dec5SDamjan Jovanovic                                              // and needs filling out 2 x password dialogs.
6949646dec5SDamjan Jovanovic                                              sal_True );
6959646dec5SDamjan Jovanovic 
6969646dec5SDamjan Jovanovic     if ( theRetVal == 0 )
6979646dec5SDamjan Jovanovic     {
6989646dec5SDamjan Jovanovic         m_aLogger.log( LogLevel::FINEST, "got credentials for user=$1$ on realm=$2$", theUserName, realm );
6999646dec5SDamjan Jovanovic         // "System credentials" means username and password are empty
7009646dec5SDamjan Jovanovic         const char *curlUsername = NULL;
7019646dec5SDamjan Jovanovic         const char *curlPassword = NULL;
7029646dec5SDamjan Jovanovic         if ( !theUserName.isEmpty() )
7039646dec5SDamjan Jovanovic             curlUsername = rtl::OUStringToOString( theUserName, RTL_TEXTENCODING_UTF8 ).getStr();
7049646dec5SDamjan Jovanovic         if ( !thePassWord.isEmpty() )
7059646dec5SDamjan Jovanovic             curlPassword = rtl::OUStringToOString( thePassWord, RTL_TEXTENCODING_UTF8 ).getStr();
7069646dec5SDamjan Jovanovic         if ( statusCode == 401 )
7079646dec5SDamjan Jovanovic         {
7089646dec5SDamjan Jovanovic             curl_easy_setopt( m_pCurl, CURLOPT_USERNAME, curlUsername );
7099646dec5SDamjan Jovanovic             curl_easy_setopt( m_pCurl, CURLOPT_PASSWORD, curlPassword );
7109646dec5SDamjan Jovanovic         }
7119646dec5SDamjan Jovanovic         else
7129646dec5SDamjan Jovanovic         {
7139646dec5SDamjan Jovanovic             curl_easy_setopt( m_pCurl, CURLOPT_PROXYUSERNAME, curlUsername );
7149646dec5SDamjan Jovanovic             curl_easy_setopt( m_pCurl, CURLOPT_PROXYPASSWORD, curlPassword );
7159646dec5SDamjan Jovanovic         }
7169646dec5SDamjan Jovanovic         return true;
7179646dec5SDamjan Jovanovic     }
7189646dec5SDamjan Jovanovic     m_aLogger.log( LogLevel::WARNING, "credentials entry cancelled or failed" );
7199646dec5SDamjan Jovanovic 
7209646dec5SDamjan Jovanovic     return false;
7219646dec5SDamjan Jovanovic }
7229646dec5SDamjan Jovanovic 
7239646dec5SDamjan Jovanovic void CurlSession::addEnvironmentRequestHeaders( CurlRequest &curlRequest, const DAVRequestEnvironment &env )
7249646dec5SDamjan Jovanovic     throw ( DAVException )
7259646dec5SDamjan Jovanovic {
7269646dec5SDamjan Jovanovic     bool bHasUserAgent( false );
7279646dec5SDamjan Jovanovic     DAVRequestHeaders::const_iterator aHeaderIter( env.m_aRequestHeaders.begin() );
7289646dec5SDamjan Jovanovic     const DAVRequestHeaders::const_iterator aEnd( env.m_aRequestHeaders.end() );
7299646dec5SDamjan Jovanovic 
7309646dec5SDamjan Jovanovic     while ( aHeaderIter != aEnd )
7319646dec5SDamjan Jovanovic     {
7329646dec5SDamjan Jovanovic         const rtl::OString aHeader = rtl::OUStringToOString( aHeaderIter->first,
7339646dec5SDamjan Jovanovic                                                              RTL_TEXTENCODING_UTF8 );
7349646dec5SDamjan Jovanovic         const rtl::OString aValue = rtl::OUStringToOString( aHeaderIter->second,
7359646dec5SDamjan Jovanovic                                                             RTL_TEXTENCODING_UTF8 );
7369646dec5SDamjan Jovanovic 
7379646dec5SDamjan Jovanovic         if ( !bHasUserAgent )
7389646dec5SDamjan Jovanovic             bHasUserAgent = aHeaderIter->first.equalsAsciiL(
7399646dec5SDamjan Jovanovic                 RTL_CONSTASCII_STRINGPARAM( "User-Agent" ) );
7409646dec5SDamjan Jovanovic 
7419646dec5SDamjan Jovanovic         curlRequest.addHeader( aHeader, aValue );
7429646dec5SDamjan Jovanovic 
7439646dec5SDamjan Jovanovic         ++aHeaderIter;
7449646dec5SDamjan Jovanovic     }
7459646dec5SDamjan Jovanovic 
7469646dec5SDamjan Jovanovic     if ( !bHasUserAgent )
7479646dec5SDamjan Jovanovic     {
7489646dec5SDamjan Jovanovic         const rtl::OUString &rUserAgent = WebDAVUserAgent::get();
7499646dec5SDamjan Jovanovic         curlRequest.addHeader( "User-Agent", rtl::OUStringToOString( rUserAgent, RTL_TEXTENCODING_UTF8 ) );
7509646dec5SDamjan Jovanovic     }
7519646dec5SDamjan Jovanovic }
7529646dec5SDamjan Jovanovic 
7539646dec5SDamjan Jovanovic void CurlSession::processResponse( CurlRequest &curlRequest, CURLcode curlCode )
7549646dec5SDamjan Jovanovic     throw( DAVException )
7559646dec5SDamjan Jovanovic {
7569646dec5SDamjan Jovanovic     long statusCode = 0;
7579646dec5SDamjan Jovanovic     CURLcode curlRes;
7589646dec5SDamjan Jovanovic     curlRes = curl_easy_getinfo( m_pCurl, CURLINFO_RESPONSE_CODE, &statusCode );
7599646dec5SDamjan Jovanovic     if ( curlRes != 0 || statusCode == 0 )
7609646dec5SDamjan Jovanovic         statusCode = curlRequest.getStatusCode();
7619646dec5SDamjan Jovanovic 
7629646dec5SDamjan Jovanovic     // check header according:
7639646dec5SDamjan Jovanovic     // http://tools.ietf.org/html/rfc7231#section-7.4.2
7649646dec5SDamjan Jovanovic     // need to do this so we can adjust the protocol accordingly
7659646dec5SDamjan Jovanovic     const CurlRequest::Header *server = curlRequest.findResponseHeader( "server" );
7669646dec5SDamjan Jovanovic     if ( server != NULL )
7679646dec5SDamjan Jovanovic         m_aServerHeaderField = server->value;
7689646dec5SDamjan Jovanovic 
7699646dec5SDamjan Jovanovic     if ( curlCode != 0 )
7709646dec5SDamjan Jovanovic     {
7719646dec5SDamjan Jovanovic         m_aLogger.log( LogLevel::WARNING, "Curl request failed with CURLcode $1$", (sal_Int64)curlCode );
7725f005af5SArrigo Marchiori         DAVException::ExceptionCode exCode = DAVException::DAV_HTTP_ERROR;
7735f005af5SArrigo Marchiori         rtl::OUString exData;
7745f005af5SArrigo Marchiori         switch (curlCode) {
7755f005af5SArrigo Marchiori         case CURLE_COULDNT_RESOLVE_HOST:
7765f005af5SArrigo Marchiori             exCode = DAVException::DAV_HTTP_LOOKUP;
7775f005af5SArrigo Marchiori             exData = CurlUri::makeConnectionEndPointString( getHostName(),
7785f005af5SArrigo Marchiori                                                             getPort() );
7795f005af5SArrigo Marchiori             break;
7805f005af5SArrigo Marchiori         case CURLE_COULDNT_CONNECT:
7815f005af5SArrigo Marchiori             exCode = DAVException::DAV_HTTP_CONNECT;
7825f005af5SArrigo Marchiori             exData = CurlUri::makeConnectionEndPointString( getHostName(),
7835f005af5SArrigo Marchiori                                                             getPort() );
7845f005af5SArrigo Marchiori             break;
7855f005af5SArrigo Marchiori         case CURLE_OPERATION_TIMEDOUT:
7865f005af5SArrigo Marchiori             exCode = DAVException::DAV_HTTP_TIMEOUT;
7875f005af5SArrigo Marchiori             exData = CurlUri::makeConnectionEndPointString( getHostName(),
7885f005af5SArrigo Marchiori                                                             getPort() );
7895f005af5SArrigo Marchiori             break;
7905f005af5SArrigo Marchiori         case CURLE_LOGIN_DENIED:
7915f005af5SArrigo Marchiori         case CURLE_AUTH_ERROR:
7925f005af5SArrigo Marchiori             exCode = DAVException::DAV_HTTP_AUTH;
7935f005af5SArrigo Marchiori             exData = CurlUri::makeConnectionEndPointString( getHostName(),
7945f005af5SArrigo Marchiori                                                             getPort() );
7955f005af5SArrigo Marchiori             break;
7965f005af5SArrigo Marchiori         default:
7975f005af5SArrigo Marchiori             {
7985f005af5SArrigo Marchiori                 const char *s = curl_easy_strerror(curlCode);
7995f005af5SArrigo Marchiori                 exCode = DAVException::DAV_HTTP_ERROR;
8005f005af5SArrigo Marchiori                 exData = ::rtl::OUString(s, strlen(s),
8015f005af5SArrigo Marchiori                                          RTL_TEXTENCODING_UTF8);
8025f005af5SArrigo Marchiori                 break;
8035f005af5SArrigo Marchiori             }
8045f005af5SArrigo Marchiori         }
8055f005af5SArrigo Marchiori         throw DAVException( exCode, exData );
8069646dec5SDamjan Jovanovic     }
8079646dec5SDamjan Jovanovic 
8089646dec5SDamjan Jovanovic     rtl::OUString reasonPhrase = rtl::OStringToOUString( curlRequest.getReasonPhrase(), RTL_TEXTENCODING_UTF8 );
8099646dec5SDamjan Jovanovic     if ( statusCode != 0 && statusCode / 100 != 2 )
8109646dec5SDamjan Jovanovic     {
8119646dec5SDamjan Jovanovic         switch (statusCode)
8129646dec5SDamjan Jovanovic         {
8139646dec5SDamjan Jovanovic             case SC_MOVED_PERMANENTLY:             // 301
8149646dec5SDamjan Jovanovic             case SC_MOVED_TEMPORARILY:             // 302
8159646dec5SDamjan Jovanovic             case SC_SEE_OTHER:                     // 303
8169646dec5SDamjan Jovanovic             case SC_TEMPORARY_REDIRECT:            // 307
8179646dec5SDamjan Jovanovic             {
8189646dec5SDamjan Jovanovic                 // new location for certain redirections
8199646dec5SDamjan Jovanovic 
8209646dec5SDamjan Jovanovic                 const CurlRequest::Header *location = curlRequest.findResponseHeader( "location" );
8219646dec5SDamjan Jovanovic                 if ( location != NULL )
8229646dec5SDamjan Jovanovic                 {
8239646dec5SDamjan Jovanovic                     m_aLogger.log( LogLevel::FINE, "HTTP $1$ response with new location = $2$",
8249646dec5SDamjan Jovanovic                         statusCode, location->value );
8259646dec5SDamjan Jovanovic                     throw DAVException( DAVException::DAV_HTTP_REDIRECT,
8269646dec5SDamjan Jovanovic                                         rtl::OStringToOUString( location->value, RTL_TEXTENCODING_UTF8 ) );
8279646dec5SDamjan Jovanovic                 }
8289646dec5SDamjan Jovanovic                 break;
8299646dec5SDamjan Jovanovic             }
8309646dec5SDamjan Jovanovic             case SC_UNAUTHORIZED:                  // 401
8319646dec5SDamjan Jovanovic             case SC_PROXY_AUTHENTICATION_REQUIRED: // 407
8329646dec5SDamjan Jovanovic             {
8339646dec5SDamjan Jovanovic                 throw DAVException( DAVException::DAV_HTTP_ERROR,
8349646dec5SDamjan Jovanovic                                     reasonPhrase,
8359646dec5SDamjan Jovanovic                                     statusCode );
8369646dec5SDamjan Jovanovic                 break;
8379646dec5SDamjan Jovanovic             }
8389646dec5SDamjan Jovanovic             case SC_REQUEST_ENTITY_TOO_LARGE:      // 413
8399646dec5SDamjan Jovanovic             {
8409646dec5SDamjan Jovanovic                 if ( m_bTransferEncodingSwitched )
8419646dec5SDamjan Jovanovic                     throw DAVException( DAVException::DAV_HTTP_ERROR,
8429646dec5SDamjan Jovanovic                                         reasonPhrase,
8439646dec5SDamjan Jovanovic                                         statusCode );
8449646dec5SDamjan Jovanovic                 m_bTransferEncodingSwitched = true;
8459646dec5SDamjan Jovanovic                 curlRequest.setChunkedEncoding( !curlRequest.isChunkedEncoding() );
8469646dec5SDamjan Jovanovic                 break;
8479646dec5SDamjan Jovanovic             }
8489646dec5SDamjan Jovanovic             case SC_LOCKED:                        // 423
8499646dec5SDamjan Jovanovic                 throw DAVException( DAVException::DAV_LOCKED,
8509646dec5SDamjan Jovanovic                                     reasonPhrase,
8519646dec5SDamjan Jovanovic                                     statusCode );
8529646dec5SDamjan Jovanovic             default:
8539646dec5SDamjan Jovanovic                 throw DAVException( DAVException::DAV_HTTP_ERROR,
8549646dec5SDamjan Jovanovic                                     reasonPhrase,
8559646dec5SDamjan Jovanovic                                     statusCode );
8569646dec5SDamjan Jovanovic         }
8579646dec5SDamjan Jovanovic     }
8589646dec5SDamjan Jovanovic }
8599646dec5SDamjan Jovanovic 
8609646dec5SDamjan Jovanovic static void responseHeadersToDAVResource( const std::vector< CurlRequest::Header> &responseHeaders,
8619646dec5SDamjan Jovanovic                                           const std::vector< ::rtl::OUString > &inHeaderNames,
8629646dec5SDamjan Jovanovic                                           DAVResource &ioResource )
8639646dec5SDamjan Jovanovic {
8649646dec5SDamjan Jovanovic     std::vector< CurlRequest::Header >::const_iterator it( responseHeaders.begin() );
8659646dec5SDamjan Jovanovic     const std::vector< CurlRequest::Header >::const_iterator end( responseHeaders.end() );
8669646dec5SDamjan Jovanovic     while ( it != end )
8679646dec5SDamjan Jovanovic     {
8689646dec5SDamjan Jovanovic         bool storeHeader = false;
8699646dec5SDamjan Jovanovic         if ( inHeaderNames.size() == 0 )
8709646dec5SDamjan Jovanovic             storeHeader = true;
8719646dec5SDamjan Jovanovic         else
8729646dec5SDamjan Jovanovic         {
8739646dec5SDamjan Jovanovic             std::vector< ::rtl::OUString >::const_iterator reqIt( inHeaderNames.begin() );
8749646dec5SDamjan Jovanovic             const std::vector< ::rtl::OUString >::const_iterator reqEnd( inHeaderNames.end() );
8759646dec5SDamjan Jovanovic             while ( reqIt != reqEnd )
8769646dec5SDamjan Jovanovic             {
8779646dec5SDamjan Jovanovic                 // header names are case insensitive
8789646dec5SDamjan Jovanovic                 if ( (*reqIt).equalsIgnoreAsciiCase( rtl::OStringToOUString( (*it).name, RTL_TEXTENCODING_UTF8 ) ) )
8799646dec5SDamjan Jovanovic                 {
8809646dec5SDamjan Jovanovic                     storeHeader = true;
8819646dec5SDamjan Jovanovic                     break;
8829646dec5SDamjan Jovanovic                 }
8839646dec5SDamjan Jovanovic                 else
8849646dec5SDamjan Jovanovic                 {
8859646dec5SDamjan Jovanovic                     ++reqIt;
8869646dec5SDamjan Jovanovic                 }
8879646dec5SDamjan Jovanovic             }
8889646dec5SDamjan Jovanovic         }
8899646dec5SDamjan Jovanovic 
8909646dec5SDamjan Jovanovic         if ( storeHeader )
8919646dec5SDamjan Jovanovic         {
8929646dec5SDamjan Jovanovic             DAVPropertyValue thePropertyValue;
8939646dec5SDamjan Jovanovic             thePropertyValue.IsCaseSensitive = false;
8949646dec5SDamjan Jovanovic             thePropertyValue.Name = rtl::OStringToOUString( (*it).name, RTL_TEXTENCODING_UTF8 );
8959646dec5SDamjan Jovanovic             thePropertyValue.Value <<= rtl::OStringToOUString( (*it).value, RTL_TEXTENCODING_UTF8 );
8969646dec5SDamjan Jovanovic             ioResource.properties.push_back( thePropertyValue );
8979646dec5SDamjan Jovanovic         }
8989646dec5SDamjan Jovanovic 
8999646dec5SDamjan Jovanovic         it++;
9009646dec5SDamjan Jovanovic     }
9019646dec5SDamjan Jovanovic }
9029646dec5SDamjan Jovanovic 
9039646dec5SDamjan Jovanovic // -------------------------------------------------------------------
9049646dec5SDamjan Jovanovic // PROPFIND - allprop & named
9059646dec5SDamjan Jovanovic // -------------------------------------------------------------------
9069646dec5SDamjan Jovanovic 
9079646dec5SDamjan Jovanovic void CurlSession::propfind( CurlRequest &curlRequest,
9089646dec5SDamjan Jovanovic                             const rtl::OUString &inPath,
9099646dec5SDamjan Jovanovic                             const Depth inDepth,
9109646dec5SDamjan Jovanovic                             const std::vector< ::rtl::OUString > * inPropNames,
9119646dec5SDamjan Jovanovic                             const bool onlyPropertyNames,
9129646dec5SDamjan Jovanovic                             const DAVRequestEnvironment & rEnv )
9139646dec5SDamjan Jovanovic {
9149646dec5SDamjan Jovanovic     addEnvironmentRequestHeaders( curlRequest, rEnv );
9159646dec5SDamjan Jovanovic 
9169646dec5SDamjan Jovanovic     if ( inDepth == DAVZERO )
9179646dec5SDamjan Jovanovic         curlRequest.addHeader( "Depth", "0" );
9189646dec5SDamjan Jovanovic     else if ( inDepth == DAVONE )
9199646dec5SDamjan Jovanovic         curlRequest.addHeader( "Depth", "1" );
9209646dec5SDamjan Jovanovic     else if ( inDepth == DAVINFINITY )
9219646dec5SDamjan Jovanovic         curlRequest.addHeader( "Depth", "infinity" );
9229646dec5SDamjan Jovanovic 
9239646dec5SDamjan Jovanovic     rtl::OString xml = PropfindRequest::generatePROPFINDRequestBody( inPropNames, onlyPropertyNames );
9249646dec5SDamjan Jovanovic     if ( xml.getLength() > 0 )
9259646dec5SDamjan Jovanovic     {
9269646dec5SDamjan Jovanovic         curlRequest.addHeader( "Content-Type", "application/xml" );
9279646dec5SDamjan Jovanovic         curlRequest.setRequestBody( xml.getStr(), xml.getLength() );
9289646dec5SDamjan Jovanovic     }
9299646dec5SDamjan Jovanovic 
9309646dec5SDamjan Jovanovic     CredentialsData credsData( this, curlRequest, rEnv );
9319646dec5SDamjan Jovanovic     curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData );
9329646dec5SDamjan Jovanovic 
9339646dec5SDamjan Jovanovic     CURLcode rc = curlRequest.propfind( m_aUri, inPath );
9349646dec5SDamjan Jovanovic     processResponse( curlRequest, rc );
9359646dec5SDamjan Jovanovic }
9369646dec5SDamjan Jovanovic 
9379646dec5SDamjan Jovanovic void CurlSession::PROPFIND( const rtl::OUString & inPath,
9389646dec5SDamjan Jovanovic                             const Depth inDepth,
9399646dec5SDamjan Jovanovic                             const std::vector< rtl::OUString > & inPropNames,
9409646dec5SDamjan Jovanovic                             std::vector< DAVResource > & ioResources,
9419646dec5SDamjan Jovanovic                             const DAVRequestEnvironment & rEnv )
9429646dec5SDamjan Jovanovic     throw ( DAVException )
9439646dec5SDamjan Jovanovic {
9449646dec5SDamjan Jovanovic     m_aLogger.log( LogLevel::INFO, "PROPFIND line $1$", (sal_Int32)__LINE__ );
9459646dec5SDamjan Jovanovic 
9469646dec5SDamjan Jovanovic     osl::Guard< osl::Mutex > theGuard( m_aMutex );
9479646dec5SDamjan Jovanovic 
9489646dec5SDamjan Jovanovic     Init( rEnv );
9499646dec5SDamjan Jovanovic     CurlRequest curlRequest( m_pCurl );
9509646dec5SDamjan Jovanovic 
9519646dec5SDamjan Jovanovic     propfind( curlRequest, inPath, inDepth, &inPropNames, false, rEnv );
9529646dec5SDamjan Jovanovic 
9539646dec5SDamjan Jovanovic     const std::vector< DAVResource > rResources( parseWebDAVPropFindResponse( curlRequest.getResponseBody().get() ) );
9549646dec5SDamjan Jovanovic     std::vector< DAVResource > *pIoResources = &ioResources;
9559646dec5SDamjan Jovanovic     *pIoResources = rResources;
9569646dec5SDamjan Jovanovic }
9579646dec5SDamjan Jovanovic 
9589646dec5SDamjan Jovanovic // -------------------------------------------------------------------
9599646dec5SDamjan Jovanovic // PROPFIND - propnames
9609646dec5SDamjan Jovanovic // -------------------------------------------------------------------
9619646dec5SDamjan Jovanovic void CurlSession::PROPFIND( const rtl::OUString & inPath,
9629646dec5SDamjan Jovanovic                             const Depth inDepth,
9639646dec5SDamjan Jovanovic                             std::vector< DAVResourceInfo > & ioResInfo,
9649646dec5SDamjan Jovanovic                             const DAVRequestEnvironment & rEnv )
9659646dec5SDamjan Jovanovic     throw( DAVException )
9669646dec5SDamjan Jovanovic {
9679646dec5SDamjan Jovanovic     m_aLogger.log( LogLevel::INFO, "PROPFIND line $1$", (sal_Int32)__LINE__ );
9689646dec5SDamjan Jovanovic 
9699646dec5SDamjan Jovanovic     osl::Guard< osl::Mutex > theGuard( m_aMutex );
9709646dec5SDamjan Jovanovic 
9719646dec5SDamjan Jovanovic     Init( rEnv );
9729646dec5SDamjan Jovanovic     CurlRequest curlRequest( m_pCurl );
9739646dec5SDamjan Jovanovic 
9749646dec5SDamjan Jovanovic     propfind( curlRequest, inPath, inDepth, NULL, true, rEnv );
9759646dec5SDamjan Jovanovic 
9769646dec5SDamjan Jovanovic     const std::vector< DAVResourceInfo > rResInfo( parseWebDAVPropNameResponse( curlRequest.getResponseBody().get() ) );
9779646dec5SDamjan Jovanovic     std::vector< DAVResourceInfo > *pIoResInfo = &ioResInfo;
9789646dec5SDamjan Jovanovic     *pIoResInfo = rResInfo;
9799646dec5SDamjan Jovanovic }
9809646dec5SDamjan Jovanovic 
9819646dec5SDamjan Jovanovic // -------------------------------------------------------------------
9829646dec5SDamjan Jovanovic // PROPPATCH
9839646dec5SDamjan Jovanovic // -------------------------------------------------------------------
9849646dec5SDamjan Jovanovic void CurlSession::PROPPATCH( const rtl::OUString & inPath,
9859646dec5SDamjan Jovanovic                              const std::vector< ProppatchValue > & inValues,
9869646dec5SDamjan Jovanovic                              const DAVRequestEnvironment & rEnv )
9879646dec5SDamjan Jovanovic     throw( DAVException )
9889646dec5SDamjan Jovanovic {
9899646dec5SDamjan Jovanovic     m_aLogger.log( LogLevel::INFO, "PROPPATCH line $1$", (sal_Int32)__LINE__ );
9909646dec5SDamjan Jovanovic 
9919646dec5SDamjan Jovanovic     osl::Guard< osl::Mutex > theGuard( m_aMutex );
9929646dec5SDamjan Jovanovic 
9939646dec5SDamjan Jovanovic     Init( rEnv );
9949646dec5SDamjan Jovanovic     CurlRequest curlRequest( m_pCurl );
9959646dec5SDamjan Jovanovic 
9969646dec5SDamjan Jovanovic     addEnvironmentRequestHeaders( curlRequest, rEnv );
9979646dec5SDamjan Jovanovic 
9989646dec5SDamjan Jovanovic     // check whether a lock on this resource is already owned
9999646dec5SDamjan Jovanovic     rtl::OUString aUri( composeCurrentUri( inPath ) );
10009646dec5SDamjan Jovanovic     ucb::Lock inLock;
10019646dec5SDamjan Jovanovic     CurlLock * pLock = m_aCurlLockStore.findByUri( aUri );
10029646dec5SDamjan Jovanovic     if ( pLock )
10039646dec5SDamjan Jovanovic     {
10049646dec5SDamjan Jovanovic         inLock = pLock->getLock();
10059646dec5SDamjan Jovanovic     }
10069646dec5SDamjan Jovanovic     if ( inLock.LockTokens.getLength() > 0 )
10079646dec5SDamjan Jovanovic     {
10089646dec5SDamjan Jovanovic         curlRequest.addHeader( "If",
10099646dec5SDamjan Jovanovic             ( "(<" + rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ) + ">)" ).getStr() );
10109646dec5SDamjan Jovanovic     }
10119646dec5SDamjan Jovanovic 
10129646dec5SDamjan Jovanovic     rtl::OString xml = ProppatchRequest::generatePROPPATCHRequestBody( inValues );
10139646dec5SDamjan Jovanovic     if ( xml.getLength() > 0 )
10149646dec5SDamjan Jovanovic     {
10159646dec5SDamjan Jovanovic         curlRequest.addHeader( "Content-Type", "application/xml" );
10169646dec5SDamjan Jovanovic         curlRequest.setRequestBody( xml.getStr(), xml.getLength() );
10179646dec5SDamjan Jovanovic     }
10189646dec5SDamjan Jovanovic 
10199646dec5SDamjan Jovanovic     CredentialsData credsData( this, curlRequest, rEnv );
10209646dec5SDamjan Jovanovic     curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData );
10219646dec5SDamjan Jovanovic 
10229646dec5SDamjan Jovanovic     CURLcode rc = curlRequest.proppatch( m_aUri, inPath );
10239646dec5SDamjan Jovanovic     processResponse( curlRequest, rc );
10249646dec5SDamjan Jovanovic }
10259646dec5SDamjan Jovanovic 
10269646dec5SDamjan Jovanovic // -------------------------------------------------------------------
10279646dec5SDamjan Jovanovic // HEAD
10289646dec5SDamjan Jovanovic // -------------------------------------------------------------------
10299646dec5SDamjan Jovanovic void CurlSession::HEAD( const ::rtl::OUString & inPath,
10309646dec5SDamjan Jovanovic                         const std::vector< ::rtl::OUString > & inHeaderNames,
10319646dec5SDamjan Jovanovic                         DAVResource & ioResource,
10329646dec5SDamjan Jovanovic                         const DAVRequestEnvironment & rEnv )
10339646dec5SDamjan Jovanovic     throw( DAVException )
10349646dec5SDamjan Jovanovic {
10359646dec5SDamjan Jovanovic     m_aLogger.log( LogLevel::INFO, "HEAD line $1$", (sal_Int32)__LINE__ );
10369646dec5SDamjan Jovanovic 
10379646dec5SDamjan Jovanovic     osl::Guard< osl::Mutex > theGuard( m_aMutex );
10389646dec5SDamjan Jovanovic 
10399646dec5SDamjan Jovanovic     Init(rEnv );
10409646dec5SDamjan Jovanovic     CurlRequest curlRequest( m_pCurl );
10419646dec5SDamjan Jovanovic 
10429646dec5SDamjan Jovanovic     addEnvironmentRequestHeaders( curlRequest, rEnv );
10439646dec5SDamjan Jovanovic 
10449646dec5SDamjan Jovanovic     ioResource.uri = inPath;
10459646dec5SDamjan Jovanovic     ioResource.properties.clear();
10469646dec5SDamjan Jovanovic 
10479646dec5SDamjan Jovanovic     CredentialsData credsData( this, curlRequest, rEnv );
10489646dec5SDamjan Jovanovic     curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData );
10499646dec5SDamjan Jovanovic 
10509646dec5SDamjan Jovanovic     CURLcode rc = curlRequest.head( m_aUri, inPath );
10519646dec5SDamjan Jovanovic     processResponse( curlRequest, rc );
10529646dec5SDamjan Jovanovic     responseHeadersToDAVResource( curlRequest.getResponseHeaders(), inHeaderNames, ioResource );
10539646dec5SDamjan Jovanovic }
10549646dec5SDamjan Jovanovic 
10559646dec5SDamjan Jovanovic // -------------------------------------------------------------------
10569646dec5SDamjan Jovanovic // GET
10579646dec5SDamjan Jovanovic // -------------------------------------------------------------------
10589646dec5SDamjan Jovanovic uno::Reference< io::XInputStream >
10599646dec5SDamjan Jovanovic CurlSession::GET( const rtl::OUString & inPath,
10609646dec5SDamjan Jovanovic                   const DAVRequestEnvironment & rEnv )
10619646dec5SDamjan Jovanovic     throw ( DAVException )
10629646dec5SDamjan Jovanovic {
10639646dec5SDamjan Jovanovic     m_aLogger.log( LogLevel::INFO, "GET line $1$", (sal_Int32)__LINE__ );
10649646dec5SDamjan Jovanovic 
10659646dec5SDamjan Jovanovic     osl::Guard< osl::Mutex > theGuard( m_aMutex );
10669646dec5SDamjan Jovanovic 
10679646dec5SDamjan Jovanovic     Init( rEnv );
10689646dec5SDamjan Jovanovic     CurlRequest curlRequest( m_pCurl );
10699646dec5SDamjan Jovanovic 
10709646dec5SDamjan Jovanovic     addEnvironmentRequestHeaders( curlRequest, rEnv );
10719646dec5SDamjan Jovanovic 
10729646dec5SDamjan Jovanovic     CredentialsData credsData( this, curlRequest, rEnv );
10739646dec5SDamjan Jovanovic     curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData );
10749646dec5SDamjan Jovanovic 
10759646dec5SDamjan Jovanovic     CURLcode rc = curlRequest.get( m_aUri, inPath );
10769646dec5SDamjan Jovanovic     processResponse( curlRequest, rc );
10779646dec5SDamjan Jovanovic 
10789646dec5SDamjan Jovanovic     return uno::Reference< io::XInputStream >( curlRequest.getResponseBody().get() );
10799646dec5SDamjan Jovanovic }
10809646dec5SDamjan Jovanovic 
10819646dec5SDamjan Jovanovic // -------------------------------------------------------------------
10829646dec5SDamjan Jovanovic // GET
10839646dec5SDamjan Jovanovic // -------------------------------------------------------------------
10849646dec5SDamjan Jovanovic void CurlSession::GET( const rtl::OUString & inPath,
10859646dec5SDamjan Jovanovic                        uno::Reference< io::XOutputStream > & ioOutputStream,
10869646dec5SDamjan Jovanovic                        const DAVRequestEnvironment & rEnv )
10879646dec5SDamjan Jovanovic     throw ( DAVException )
10889646dec5SDamjan Jovanovic {
10899646dec5SDamjan Jovanovic     m_aLogger.log( LogLevel::INFO, "GET line $1$", (sal_Int32)__LINE__ );
10909646dec5SDamjan Jovanovic 
10919646dec5SDamjan Jovanovic     osl::Guard< osl::Mutex > theGuard( m_aMutex );
10929646dec5SDamjan Jovanovic 
10939646dec5SDamjan Jovanovic     Init( rEnv );
10949646dec5SDamjan Jovanovic     CurlRequest curlRequest( m_pCurl );
10959646dec5SDamjan Jovanovic 
10969646dec5SDamjan Jovanovic     addEnvironmentRequestHeaders( curlRequest, rEnv );
10979646dec5SDamjan Jovanovic 
10989646dec5SDamjan Jovanovic     CredentialsData credsData( this, curlRequest, rEnv );
10999646dec5SDamjan Jovanovic     curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData );
11009646dec5SDamjan Jovanovic 
11019646dec5SDamjan Jovanovic     curlRequest.saveResponseBodyTo( ioOutputStream );
11029646dec5SDamjan Jovanovic     CURLcode rc = curlRequest.get( m_aUri, inPath );
11039646dec5SDamjan Jovanovic     processResponse( curlRequest, rc );
11049646dec5SDamjan Jovanovic }
11059646dec5SDamjan Jovanovic 
11069646dec5SDamjan Jovanovic // -------------------------------------------------------------------
11079646dec5SDamjan Jovanovic // GET
11089646dec5SDamjan Jovanovic // -------------------------------------------------------------------
11099646dec5SDamjan Jovanovic uno::Reference< io::XInputStream >
11109646dec5SDamjan Jovanovic CurlSession::GET( const rtl::OUString & inPath,
11119646dec5SDamjan Jovanovic                   const std::vector< ::rtl::OUString > & inHeaderNames,
11129646dec5SDamjan Jovanovic                   DAVResource & ioResource,
11139646dec5SDamjan Jovanovic                   const DAVRequestEnvironment & rEnv )
11149646dec5SDamjan Jovanovic     throw ( DAVException )
11159646dec5SDamjan Jovanovic {
11169646dec5SDamjan Jovanovic     m_aLogger.log( LogLevel::INFO, "GET line $1$", (sal_Int32)__LINE__ );
11179646dec5SDamjan Jovanovic 
11189646dec5SDamjan Jovanovic     osl::Guard< osl::Mutex > theGuard( m_aMutex );
11199646dec5SDamjan Jovanovic 
11209646dec5SDamjan Jovanovic     Init( rEnv );
11219646dec5SDamjan Jovanovic     CurlRequest curlRequest( m_pCurl );
11229646dec5SDamjan Jovanovic 
11239646dec5SDamjan Jovanovic     addEnvironmentRequestHeaders( curlRequest, rEnv );
11249646dec5SDamjan Jovanovic 
11259646dec5SDamjan Jovanovic     CredentialsData credsData( this, curlRequest, rEnv );
11269646dec5SDamjan Jovanovic     curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData );
11279646dec5SDamjan Jovanovic 
11289646dec5SDamjan Jovanovic     CURLcode rc = curlRequest.get( m_aUri, inPath );
11299646dec5SDamjan Jovanovic     processResponse( curlRequest, rc );
11309646dec5SDamjan Jovanovic     responseHeadersToDAVResource( curlRequest.getResponseHeaders(), inHeaderNames, ioResource );
11319646dec5SDamjan Jovanovic 
11329646dec5SDamjan Jovanovic     return uno::Reference< io::XInputStream >( curlRequest.getResponseBody().get() );
11339646dec5SDamjan Jovanovic }
11349646dec5SDamjan Jovanovic 
11359646dec5SDamjan Jovanovic 
11369646dec5SDamjan Jovanovic // -------------------------------------------------------------------
11379646dec5SDamjan Jovanovic // GET
11389646dec5SDamjan Jovanovic // -------------------------------------------------------------------
11399646dec5SDamjan Jovanovic void CurlSession::GET( const rtl::OUString & inPath,
11409646dec5SDamjan Jovanovic                        uno::Reference< io::XOutputStream > & ioOutputStream,
11419646dec5SDamjan Jovanovic                        const std::vector< ::rtl::OUString > & inHeaderNames,
11429646dec5SDamjan Jovanovic                        DAVResource & ioResource,
11439646dec5SDamjan Jovanovic                        const DAVRequestEnvironment & rEnv )
11449646dec5SDamjan Jovanovic     throw ( DAVException )
11459646dec5SDamjan Jovanovic {
11469646dec5SDamjan Jovanovic     m_aLogger.log( LogLevel::INFO, "GET line $1$", (sal_Int32)__LINE__ );
11479646dec5SDamjan Jovanovic 
11489646dec5SDamjan Jovanovic     osl::Guard< osl::Mutex > theGuard( m_aMutex );
11499646dec5SDamjan Jovanovic 
11509646dec5SDamjan Jovanovic     Init( rEnv );
11519646dec5SDamjan Jovanovic     CurlRequest curlRequest( m_pCurl );
11529646dec5SDamjan Jovanovic 
11539646dec5SDamjan Jovanovic     addEnvironmentRequestHeaders( curlRequest, rEnv );
11549646dec5SDamjan Jovanovic 
11559646dec5SDamjan Jovanovic     CredentialsData credsData( this, curlRequest, rEnv );
11569646dec5SDamjan Jovanovic     curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData );
11579646dec5SDamjan Jovanovic 
11589646dec5SDamjan Jovanovic     curlRequest.saveResponseBodyTo( ioOutputStream );
11599646dec5SDamjan Jovanovic     CURLcode rc = curlRequest.get( m_aUri, inPath );
11609646dec5SDamjan Jovanovic     processResponse( curlRequest, rc );
11619646dec5SDamjan Jovanovic     responseHeadersToDAVResource( curlRequest.getResponseHeaders(), inHeaderNames, ioResource );
11629646dec5SDamjan Jovanovic }
11639646dec5SDamjan Jovanovic 
11649646dec5SDamjan Jovanovic // -------------------------------------------------------------------
11659646dec5SDamjan Jovanovic // PUT
11669646dec5SDamjan Jovanovic // -------------------------------------------------------------------
11679646dec5SDamjan Jovanovic void CurlSession::PUT( const rtl::OUString & inPath,
11689646dec5SDamjan Jovanovic                        const uno::Reference< io::XInputStream > & inInputStream,
11699646dec5SDamjan Jovanovic                        const DAVRequestEnvironment & rEnv )
11709646dec5SDamjan Jovanovic     throw ( DAVException )
11719646dec5SDamjan Jovanovic {
11729646dec5SDamjan Jovanovic     m_aLogger.log( LogLevel::INFO, "PUT line $1$", (sal_Int32)__LINE__ );
11739646dec5SDamjan Jovanovic 
11749646dec5SDamjan Jovanovic     osl::Guard< osl::Mutex > theGuard( m_aMutex );
11759646dec5SDamjan Jovanovic 
11769646dec5SDamjan Jovanovic     Init( rEnv );
11779646dec5SDamjan Jovanovic     CurlRequest curlRequest( m_pCurl );
11789646dec5SDamjan Jovanovic 
11799646dec5SDamjan Jovanovic     addEnvironmentRequestHeaders( curlRequest, rEnv );
11809646dec5SDamjan Jovanovic 
11819646dec5SDamjan Jovanovic     uno::Sequence< sal_Int8 > aDataToSend;
11829646dec5SDamjan Jovanovic     if ( !getDataFromInputStream( inInputStream, aDataToSend, false ) )
11839646dec5SDamjan Jovanovic         throw DAVException( DAVException::DAV_INVALID_ARG );
11849646dec5SDamjan Jovanovic     curlRequest.setRequestBody( reinterpret_cast< const char * >( aDataToSend.getConstArray() ),
11859646dec5SDamjan Jovanovic                                 aDataToSend.getLength() );
11869646dec5SDamjan Jovanovic 
11879646dec5SDamjan Jovanovic     CredentialsData credsData( this, curlRequest, rEnv );
11889646dec5SDamjan Jovanovic     curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData );
11899646dec5SDamjan Jovanovic 
11909646dec5SDamjan Jovanovic     // check whether a lock on this resource is already owned
11919646dec5SDamjan Jovanovic     rtl::OUString aUri( composeCurrentUri( inPath ) );
11929646dec5SDamjan Jovanovic     ucb::Lock inLock;
11939646dec5SDamjan Jovanovic     CurlLock * pLock = m_aCurlLockStore.findByUri( aUri );
11949646dec5SDamjan Jovanovic     if ( pLock )
11959646dec5SDamjan Jovanovic     {
11969646dec5SDamjan Jovanovic         inLock = pLock->getLock();
11979646dec5SDamjan Jovanovic     }
11989646dec5SDamjan Jovanovic     if ( inLock.LockTokens.getLength() > 0 )
11999646dec5SDamjan Jovanovic     {
12009646dec5SDamjan Jovanovic         curlRequest.addHeader( "If",
12019646dec5SDamjan Jovanovic             ( "(<" + rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ) + ">)" ).getStr() );
12029646dec5SDamjan Jovanovic     }
12039646dec5SDamjan Jovanovic 
12049646dec5SDamjan Jovanovic     CURLcode rc = curlRequest.put( m_aUri, inPath );
12059646dec5SDamjan Jovanovic     processResponse( curlRequest, rc );
12069646dec5SDamjan Jovanovic }
12079646dec5SDamjan Jovanovic 
12089646dec5SDamjan Jovanovic // -------------------------------------------------------------------
12099646dec5SDamjan Jovanovic // POST
12109646dec5SDamjan Jovanovic // -------------------------------------------------------------------
12119646dec5SDamjan Jovanovic uno::Reference< io::XInputStream >
12129646dec5SDamjan Jovanovic CurlSession::POST( const rtl::OUString & inPath,
12139646dec5SDamjan Jovanovic                    const rtl::OUString & rContentType,
12149646dec5SDamjan Jovanovic                    const rtl::OUString & rReferer,
12159646dec5SDamjan Jovanovic                    const uno::Reference< io::XInputStream > & inInputStream,
12169646dec5SDamjan Jovanovic                    const DAVRequestEnvironment & rEnv )
12179646dec5SDamjan Jovanovic     throw ( DAVException )
12189646dec5SDamjan Jovanovic {
12199646dec5SDamjan Jovanovic     m_aLogger.log( LogLevel::INFO, "POST line $1$", (sal_Int32)__LINE__ );
12209646dec5SDamjan Jovanovic 
12219646dec5SDamjan Jovanovic     osl::Guard< osl::Mutex > theGuard( m_aMutex );
12229646dec5SDamjan Jovanovic 
12239646dec5SDamjan Jovanovic     Init( rEnv );
12249646dec5SDamjan Jovanovic     CurlRequest curlRequest( m_pCurl );
12259646dec5SDamjan Jovanovic 
12269646dec5SDamjan Jovanovic     addEnvironmentRequestHeaders( curlRequest, rEnv );
12279646dec5SDamjan Jovanovic 
12289646dec5SDamjan Jovanovic     uno::Sequence< sal_Int8 > aDataToSend;
12299646dec5SDamjan Jovanovic     if ( !getDataFromInputStream( inInputStream, aDataToSend, false ) )
12309646dec5SDamjan Jovanovic         throw DAVException( DAVException::DAV_INVALID_ARG );
12319646dec5SDamjan Jovanovic     curlRequest.setRequestBody( reinterpret_cast< const char * >( aDataToSend.getConstArray() ),
12329646dec5SDamjan Jovanovic                                 aDataToSend.getLength() );
12339646dec5SDamjan Jovanovic 
12349646dec5SDamjan Jovanovic     CredentialsData credsData( this, curlRequest, rEnv );
12359646dec5SDamjan Jovanovic     curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData );
12369646dec5SDamjan Jovanovic 
12379646dec5SDamjan Jovanovic     if ( !rContentType.isEmpty() )
12389646dec5SDamjan Jovanovic         curlRequest.addHeader( "Content-Type", rtl::OUStringToOString( rContentType, RTL_TEXTENCODING_UTF8 ).getStr() );
12399646dec5SDamjan Jovanovic     if ( !rReferer.isEmpty() )
12409646dec5SDamjan Jovanovic         curlRequest.addHeader( "Referer", rtl::OUStringToOString( rReferer, RTL_TEXTENCODING_UTF8 ).getStr() );
12419646dec5SDamjan Jovanovic 
12429646dec5SDamjan Jovanovic     // check whether a lock on this resource is already owned
12439646dec5SDamjan Jovanovic     rtl::OUString aUri( composeCurrentUri( inPath ) );
12449646dec5SDamjan Jovanovic     ucb::Lock inLock;
12459646dec5SDamjan Jovanovic     CurlLock * pLock = m_aCurlLockStore.findByUri( aUri );
12469646dec5SDamjan Jovanovic     if ( pLock )
12479646dec5SDamjan Jovanovic     {
12489646dec5SDamjan Jovanovic         inLock = pLock->getLock();
12499646dec5SDamjan Jovanovic     }
12509646dec5SDamjan Jovanovic     if ( inLock.LockTokens.getLength() > 0 )
12519646dec5SDamjan Jovanovic     {
12529646dec5SDamjan Jovanovic         curlRequest.addHeader( "If",
12539646dec5SDamjan Jovanovic             ( "(<" + rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ) + ">)" ).getStr() );
12549646dec5SDamjan Jovanovic     }
12559646dec5SDamjan Jovanovic 
12569646dec5SDamjan Jovanovic     CURLcode rc = curlRequest.post( m_aUri, inPath );
12579646dec5SDamjan Jovanovic     processResponse( curlRequest, rc );
12589646dec5SDamjan Jovanovic     return uno::Reference< io::XInputStream >( curlRequest.getResponseBody().get() );
12599646dec5SDamjan Jovanovic }
12609646dec5SDamjan Jovanovic 
12619646dec5SDamjan Jovanovic // -------------------------------------------------------------------
12629646dec5SDamjan Jovanovic // POST
12639646dec5SDamjan Jovanovic // -------------------------------------------------------------------
12649646dec5SDamjan Jovanovic void CurlSession::POST( const rtl::OUString & inPath,
12659646dec5SDamjan Jovanovic                         const rtl::OUString & rContentType,
12669646dec5SDamjan Jovanovic                         const rtl::OUString & rReferer,
12679646dec5SDamjan Jovanovic                         const uno::Reference< io::XInputStream > & inInputStream,
12689646dec5SDamjan Jovanovic                         uno::Reference< io::XOutputStream > & oOutputStream,
12699646dec5SDamjan Jovanovic                         const DAVRequestEnvironment & rEnv )
12709646dec5SDamjan Jovanovic     throw ( DAVException )
12719646dec5SDamjan Jovanovic {
12729646dec5SDamjan Jovanovic     m_aLogger.log( LogLevel::INFO, "POST line $1$", (sal_Int32)__LINE__ );
12739646dec5SDamjan Jovanovic 
12749646dec5SDamjan Jovanovic     osl::Guard< osl::Mutex > theGuard( m_aMutex );
12759646dec5SDamjan Jovanovic 
12769646dec5SDamjan Jovanovic     Init( rEnv );
12779646dec5SDamjan Jovanovic     CurlRequest curlRequest( m_pCurl );
12789646dec5SDamjan Jovanovic 
12799646dec5SDamjan Jovanovic     addEnvironmentRequestHeaders( curlRequest, rEnv );
12809646dec5SDamjan Jovanovic 
12819646dec5SDamjan Jovanovic     uno::Sequence< sal_Int8 > aDataToSend;
12829646dec5SDamjan Jovanovic     if ( !getDataFromInputStream( inInputStream, aDataToSend, false ) )
12839646dec5SDamjan Jovanovic         throw DAVException( DAVException::DAV_INVALID_ARG );
12849646dec5SDamjan Jovanovic     curlRequest.setRequestBody( reinterpret_cast< const char * >( aDataToSend.getConstArray() ),
12859646dec5SDamjan Jovanovic                                 aDataToSend.getLength() );
12869646dec5SDamjan Jovanovic 
12879646dec5SDamjan Jovanovic     CredentialsData credsData( this, curlRequest, rEnv );
12889646dec5SDamjan Jovanovic     curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData );
12899646dec5SDamjan Jovanovic 
12909646dec5SDamjan Jovanovic     if ( !rContentType.isEmpty() )
12919646dec5SDamjan Jovanovic         curlRequest.addHeader( "Content-Type", rtl::OUStringToOString( rContentType, RTL_TEXTENCODING_UTF8 ).getStr() );
12929646dec5SDamjan Jovanovic     if ( !rReferer.isEmpty() )
12939646dec5SDamjan Jovanovic         curlRequest.addHeader( "Referer", rtl::OUStringToOString( rReferer, RTL_TEXTENCODING_UTF8 ).getStr() );
12949646dec5SDamjan Jovanovic 
12959646dec5SDamjan Jovanovic     // check whether a lock on this resource is already owned
12969646dec5SDamjan Jovanovic     rtl::OUString aUri( composeCurrentUri( inPath ) );
12979646dec5SDamjan Jovanovic     ucb::Lock inLock;
12989646dec5SDamjan Jovanovic     CurlLock * pLock = m_aCurlLockStore.findByUri( aUri );
12999646dec5SDamjan Jovanovic     if ( pLock )
13009646dec5SDamjan Jovanovic     {
13019646dec5SDamjan Jovanovic         inLock = pLock->getLock();
13029646dec5SDamjan Jovanovic     }
13039646dec5SDamjan Jovanovic     if ( inLock.LockTokens.getLength() > 0 )
13049646dec5SDamjan Jovanovic     {
13059646dec5SDamjan Jovanovic         curlRequest.addHeader( "If",
13069646dec5SDamjan Jovanovic             ( "(<" + rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ) + ">)" ).getStr() );
13079646dec5SDamjan Jovanovic     }
13089646dec5SDamjan Jovanovic 
13099646dec5SDamjan Jovanovic     curlRequest.saveResponseBodyTo( oOutputStream );
13109646dec5SDamjan Jovanovic     CURLcode rc = curlRequest.post( m_aUri, inPath );
13119646dec5SDamjan Jovanovic     processResponse( curlRequest, rc );
13129646dec5SDamjan Jovanovic }
13139646dec5SDamjan Jovanovic 
13149646dec5SDamjan Jovanovic // -------------------------------------------------------------------
13159646dec5SDamjan Jovanovic // MKCOL
13169646dec5SDamjan Jovanovic // -------------------------------------------------------------------
13179646dec5SDamjan Jovanovic void CurlSession::MKCOL( const rtl::OUString & inPath,
13189646dec5SDamjan Jovanovic                          const DAVRequestEnvironment & rEnv )
13199646dec5SDamjan Jovanovic     throw ( DAVException )
13209646dec5SDamjan Jovanovic {
13219646dec5SDamjan Jovanovic     m_aLogger.log( LogLevel::INFO, "MKCOL line $1$", (sal_Int32)__LINE__ );
13229646dec5SDamjan Jovanovic 
13239646dec5SDamjan Jovanovic     osl::Guard< osl::Mutex > theGuard( m_aMutex );
13249646dec5SDamjan Jovanovic 
13259646dec5SDamjan Jovanovic     Init( rEnv );
13269646dec5SDamjan Jovanovic     CurlRequest curlRequest( m_pCurl );
13279646dec5SDamjan Jovanovic 
13289646dec5SDamjan Jovanovic     addEnvironmentRequestHeaders( curlRequest, rEnv );
13299646dec5SDamjan Jovanovic 
13309646dec5SDamjan Jovanovic     CredentialsData credsData( this, curlRequest, rEnv );
13319646dec5SDamjan Jovanovic     curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData );
13329646dec5SDamjan Jovanovic 
13339646dec5SDamjan Jovanovic     // check whether a lock on this resource is already owned
13349646dec5SDamjan Jovanovic     rtl::OUString aUri( composeCurrentUri( inPath ) );
13359646dec5SDamjan Jovanovic     ucb::Lock inLock;
13369646dec5SDamjan Jovanovic     CurlLock * pLock = m_aCurlLockStore.findByUri( aUri );
13379646dec5SDamjan Jovanovic     if ( pLock )
13389646dec5SDamjan Jovanovic     {
13399646dec5SDamjan Jovanovic         inLock = pLock->getLock();
13409646dec5SDamjan Jovanovic     }
13419646dec5SDamjan Jovanovic     if ( inLock.LockTokens.getLength() > 0 )
13429646dec5SDamjan Jovanovic     {
13439646dec5SDamjan Jovanovic         curlRequest.addHeader( "If",
13449646dec5SDamjan Jovanovic             ( "(<" + rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ) + ">)" ).getStr() );
13459646dec5SDamjan Jovanovic     }
13469646dec5SDamjan Jovanovic 
13479646dec5SDamjan Jovanovic     CURLcode rc = curlRequest.mkcol( m_aUri, inPath );
13489646dec5SDamjan Jovanovic     processResponse( curlRequest, rc );
13499646dec5SDamjan Jovanovic }
13509646dec5SDamjan Jovanovic 
13519646dec5SDamjan Jovanovic // -------------------------------------------------------------------
13529646dec5SDamjan Jovanovic // COPY
13539646dec5SDamjan Jovanovic // -------------------------------------------------------------------
13549646dec5SDamjan Jovanovic void CurlSession::COPY( const rtl::OUString & inSourceURL,
13559646dec5SDamjan Jovanovic                         const rtl::OUString & inDestinationURL,
13569646dec5SDamjan Jovanovic                         const DAVRequestEnvironment & rEnv,
13579646dec5SDamjan Jovanovic                         sal_Bool inOverWrite )
13589646dec5SDamjan Jovanovic     throw ( DAVException )
13599646dec5SDamjan Jovanovic {
13609646dec5SDamjan Jovanovic     m_aLogger.log( LogLevel::INFO, "COPY line $1$", (sal_Int32)__LINE__ );
13619646dec5SDamjan Jovanovic 
13629646dec5SDamjan Jovanovic     osl::Guard< osl::Mutex > theGuard( m_aMutex );
13639646dec5SDamjan Jovanovic 
13649646dec5SDamjan Jovanovic     Init( rEnv );
13659646dec5SDamjan Jovanovic     CurlRequest curlRequest( m_pCurl );
13669646dec5SDamjan Jovanovic 
13679646dec5SDamjan Jovanovic     addEnvironmentRequestHeaders( curlRequest, rEnv );
13689646dec5SDamjan Jovanovic 
13699646dec5SDamjan Jovanovic     CredentialsData credsData( this, curlRequest, rEnv );
13709646dec5SDamjan Jovanovic     curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData );
13719646dec5SDamjan Jovanovic 
13729646dec5SDamjan Jovanovic     curlRequest.addHeader( "Destination", rtl::OUStringToOString( inDestinationURL, RTL_TEXTENCODING_UTF8 ).getStr() );
13739646dec5SDamjan Jovanovic     curlRequest.addHeader( "Overwrite", inOverWrite? "T" : "F" );
13749646dec5SDamjan Jovanovic 
13759646dec5SDamjan Jovanovic     // check whether a lock on the destination resource is already owned
13769646dec5SDamjan Jovanovic     rtl::OUString aUri( composeCurrentUri( inDestinationURL ) );
13779646dec5SDamjan Jovanovic     ucb::Lock inLock;
13789646dec5SDamjan Jovanovic     CurlLock * pLock = m_aCurlLockStore.findByUri( aUri );
13799646dec5SDamjan Jovanovic     if ( pLock )
13809646dec5SDamjan Jovanovic     {
13819646dec5SDamjan Jovanovic         inLock = pLock->getLock();
13829646dec5SDamjan Jovanovic     }
13839646dec5SDamjan Jovanovic     if ( inLock.LockTokens.getLength() > 0 )
13849646dec5SDamjan Jovanovic     {
13859646dec5SDamjan Jovanovic         curlRequest.addHeader( "If",
13869646dec5SDamjan Jovanovic             ( "(<" + rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ) + ">)" ).getStr() );
13879646dec5SDamjan Jovanovic     }
13889646dec5SDamjan Jovanovic 
13899646dec5SDamjan Jovanovic     CURLcode rc = curlRequest.copy( m_aUri, CurlUri( inSourceURL ).GetPath() );
13909646dec5SDamjan Jovanovic     processResponse( curlRequest, rc );
13919646dec5SDamjan Jovanovic }
13929646dec5SDamjan Jovanovic 
13939646dec5SDamjan Jovanovic // -------------------------------------------------------------------
13949646dec5SDamjan Jovanovic // MOVE
13959646dec5SDamjan Jovanovic // -------------------------------------------------------------------
13969646dec5SDamjan Jovanovic void CurlSession::MOVE( const rtl::OUString & inSourceURL,
13979646dec5SDamjan Jovanovic                         const rtl::OUString & inDestinationURL,
13989646dec5SDamjan Jovanovic                         const DAVRequestEnvironment & rEnv,
13999646dec5SDamjan Jovanovic                         sal_Bool inOverWrite )
14009646dec5SDamjan Jovanovic     throw ( DAVException )
14019646dec5SDamjan Jovanovic {
14029646dec5SDamjan Jovanovic     m_aLogger.log( LogLevel::INFO, "MOVE line $1$", (sal_Int32)__LINE__ );
14039646dec5SDamjan Jovanovic 
14049646dec5SDamjan Jovanovic     osl::Guard< osl::Mutex > theGuard( m_aMutex );
14059646dec5SDamjan Jovanovic 
14069646dec5SDamjan Jovanovic     Init( rEnv );
14079646dec5SDamjan Jovanovic     CurlRequest curlRequest( m_pCurl );
14089646dec5SDamjan Jovanovic 
14099646dec5SDamjan Jovanovic     addEnvironmentRequestHeaders( curlRequest, rEnv );
14109646dec5SDamjan Jovanovic 
14119646dec5SDamjan Jovanovic     CredentialsData credsData( this, curlRequest, rEnv );
14129646dec5SDamjan Jovanovic     curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData );
14139646dec5SDamjan Jovanovic 
14149646dec5SDamjan Jovanovic     curlRequest.addHeader( "Destination", rtl::OUStringToOString( inDestinationURL, RTL_TEXTENCODING_UTF8 ).getStr() );
14159646dec5SDamjan Jovanovic     curlRequest.addHeader( "Overwrite", inOverWrite? "T" : "F" );
14169646dec5SDamjan Jovanovic 
14179646dec5SDamjan Jovanovic     // check whether a lock on the destination resource is already owned
14189646dec5SDamjan Jovanovic     rtl::OUString aUri( composeCurrentUri( inDestinationURL ) );
14199646dec5SDamjan Jovanovic     ucb::Lock inLock;
14209646dec5SDamjan Jovanovic     CurlLock * pLock = m_aCurlLockStore.findByUri( aUri );
14219646dec5SDamjan Jovanovic     if ( pLock )
14229646dec5SDamjan Jovanovic     {
14239646dec5SDamjan Jovanovic         inLock = pLock->getLock();
14249646dec5SDamjan Jovanovic     }
14259646dec5SDamjan Jovanovic     if ( inLock.LockTokens.getLength() > 0 )
14269646dec5SDamjan Jovanovic     {
14279646dec5SDamjan Jovanovic         curlRequest.addHeader( "If",
14289646dec5SDamjan Jovanovic             ( "(<" + rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ) + ">)" ).getStr() );
14299646dec5SDamjan Jovanovic     }
14309646dec5SDamjan Jovanovic 
14319646dec5SDamjan Jovanovic     CURLcode rc = curlRequest.copy( m_aUri, CurlUri( inSourceURL ).GetPath() );
14329646dec5SDamjan Jovanovic     processResponse( curlRequest, rc );
14339646dec5SDamjan Jovanovic }
14349646dec5SDamjan Jovanovic 
14359646dec5SDamjan Jovanovic // -------------------------------------------------------------------
14369646dec5SDamjan Jovanovic // DESTROY
14379646dec5SDamjan Jovanovic // -------------------------------------------------------------------
14389646dec5SDamjan Jovanovic void CurlSession::DESTROY( const rtl::OUString & inPath,
14399646dec5SDamjan Jovanovic                            const DAVRequestEnvironment & rEnv )
14409646dec5SDamjan Jovanovic     throw ( DAVException )
14419646dec5SDamjan Jovanovic {
14429646dec5SDamjan Jovanovic     m_aLogger.log( LogLevel::INFO, "DESTROY line $1$", (sal_Int32)__LINE__ );
14439646dec5SDamjan Jovanovic 
14449646dec5SDamjan Jovanovic     osl::Guard< osl::Mutex > theGuard( m_aMutex );
14459646dec5SDamjan Jovanovic 
14469646dec5SDamjan Jovanovic     Init( rEnv );
14479646dec5SDamjan Jovanovic     CurlRequest curlRequest( m_pCurl );
14489646dec5SDamjan Jovanovic 
14499646dec5SDamjan Jovanovic     addEnvironmentRequestHeaders( curlRequest, rEnv );
14509646dec5SDamjan Jovanovic 
14519646dec5SDamjan Jovanovic     CredentialsData credsData( this, curlRequest, rEnv );
14529646dec5SDamjan Jovanovic     curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData );
14539646dec5SDamjan Jovanovic 
14549646dec5SDamjan Jovanovic     // check whether a lock on this resource is already owned
14559646dec5SDamjan Jovanovic     rtl::OUString aUri( composeCurrentUri( inPath ) );
14569646dec5SDamjan Jovanovic     ucb::Lock inLock;
14579646dec5SDamjan Jovanovic     CurlLock * pLock = m_aCurlLockStore.findByUri( aUri );
14589646dec5SDamjan Jovanovic     if ( pLock )
14599646dec5SDamjan Jovanovic     {
14609646dec5SDamjan Jovanovic         inLock = pLock->getLock();
14619646dec5SDamjan Jovanovic     }
14629646dec5SDamjan Jovanovic     if ( inLock.LockTokens.getLength() > 0 )
14639646dec5SDamjan Jovanovic     {
14649646dec5SDamjan Jovanovic         curlRequest.addHeader( "If",
14659646dec5SDamjan Jovanovic             ( "(<" + rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ) + ">)" ).getStr() );
14669646dec5SDamjan Jovanovic     }
14679646dec5SDamjan Jovanovic 
14689646dec5SDamjan Jovanovic     CURLcode rc = curlRequest.delete_( m_aUri, inPath );
14699646dec5SDamjan Jovanovic     processResponse( curlRequest, rc );
14709646dec5SDamjan Jovanovic }
14719646dec5SDamjan Jovanovic 
14729646dec5SDamjan Jovanovic // -------------------------------------------------------------------
14739646dec5SDamjan Jovanovic 
14749646dec5SDamjan Jovanovic namespace
14759646dec5SDamjan Jovanovic {
14769646dec5SDamjan Jovanovic     sal_Int32 lastChanceToSendRefreshRequest( TimeValue const & rStart,
14779646dec5SDamjan Jovanovic                                               sal_Int32 timeout )
14789646dec5SDamjan Jovanovic     {
14799646dec5SDamjan Jovanovic         TimeValue aEnd;
14809646dec5SDamjan Jovanovic         osl_getSystemTime( &aEnd );
14819646dec5SDamjan Jovanovic 
14829646dec5SDamjan Jovanovic         // Try to estimate a safe absolute time for sending the
14839646dec5SDamjan Jovanovic         // lock refresh request.
14849646dec5SDamjan Jovanovic         sal_Int32 lastChanceToSendRefreshRequest = DAVINFINITY;
14859646dec5SDamjan Jovanovic         if ( timeout != DAVINFINITY )
14869646dec5SDamjan Jovanovic         {
14879646dec5SDamjan Jovanovic             sal_Int32 calltime = aEnd.Seconds - rStart.Seconds;
14889646dec5SDamjan Jovanovic             if ( calltime <= timeout )
14899646dec5SDamjan Jovanovic             {
14909646dec5SDamjan Jovanovic                 lastChanceToSendRefreshRequest
14919646dec5SDamjan Jovanovic                     = aEnd.Seconds + timeout - calltime;
14929646dec5SDamjan Jovanovic             }
14939646dec5SDamjan Jovanovic             else
14949646dec5SDamjan Jovanovic             {
14959646dec5SDamjan Jovanovic                 OSL_TRACE( "No chance to refresh lock before timeout!" );
14969646dec5SDamjan Jovanovic             }
14979646dec5SDamjan Jovanovic         }
14989646dec5SDamjan Jovanovic         return lastChanceToSendRefreshRequest;
14999646dec5SDamjan Jovanovic     }
15009646dec5SDamjan Jovanovic 
15019646dec5SDamjan Jovanovic } // namespace
15029646dec5SDamjan Jovanovic 
15039646dec5SDamjan Jovanovic // -------------------------------------------------------------------
15049646dec5SDamjan Jovanovic // LOCK (set new lock)
15059646dec5SDamjan Jovanovic // -------------------------------------------------------------------
15069646dec5SDamjan Jovanovic void CurlSession::LOCK( const ::rtl::OUString & inPath,
15079646dec5SDamjan Jovanovic                         ucb::Lock & inLock,
15089646dec5SDamjan Jovanovic                         const DAVRequestEnvironment & rEnv )
15099646dec5SDamjan Jovanovic     throw ( DAVException )
15109646dec5SDamjan Jovanovic {
15119646dec5SDamjan Jovanovic     m_aLogger.log( LogLevel::INFO, "LOCK line $1$", (sal_Int32)__LINE__ );
15129646dec5SDamjan Jovanovic 
15139646dec5SDamjan Jovanovic     osl::Guard< osl::Mutex > theGuard( m_aMutex );
15149646dec5SDamjan Jovanovic 
15159646dec5SDamjan Jovanovic     // before locking, search in the lock store if we already own a lock for this resource
15169646dec5SDamjan Jovanovic     // if present, return with exception DAV_LOCKED_SELF
15179646dec5SDamjan Jovanovic     rtl::OUString   aUri( composeCurrentUri( inPath ) );
15189646dec5SDamjan Jovanovic     CurlLock * pLock = m_aCurlLockStore.findByUri( aUri );
15199646dec5SDamjan Jovanovic     if ( pLock )
15209646dec5SDamjan Jovanovic     {
15219646dec5SDamjan Jovanovic // already present, meaning already locked by the same AOO session and already in the lockstore
15229646dec5SDamjan Jovanovic // just return, nothing to do
15239646dec5SDamjan Jovanovic         return;
15249646dec5SDamjan Jovanovic     }
15259646dec5SDamjan Jovanovic 
15269646dec5SDamjan Jovanovic     Init( rEnv );
15279646dec5SDamjan Jovanovic     CurlRequest curlRequest( m_pCurl );
15289646dec5SDamjan Jovanovic 
15299646dec5SDamjan Jovanovic     addEnvironmentRequestHeaders( curlRequest, rEnv );
15309646dec5SDamjan Jovanovic 
15319646dec5SDamjan Jovanovic     CredentialsData credsData( this, curlRequest, rEnv );
15329646dec5SDamjan Jovanovic     curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData );
15339646dec5SDamjan Jovanovic 
15349646dec5SDamjan Jovanovic     if ( inLock.Timeout == -1 )
15359646dec5SDamjan Jovanovic         curlRequest.addHeader( "Timeout", "Infinite" );
15369646dec5SDamjan Jovanovic     else
15379646dec5SDamjan Jovanovic         curlRequest.addHeader( "Timeout", "Second-" + rtl::OString::valueOf( inLock.Timeout ) );
15389646dec5SDamjan Jovanovic 
15399646dec5SDamjan Jovanovic     switch ( inLock.Depth )
15409646dec5SDamjan Jovanovic     {
15419646dec5SDamjan Jovanovic         //i126305 TODO investigate on this case...
15429646dec5SDamjan Jovanovic     case ucb::LockDepth_MAKE_FIXED_SIZE:
15439646dec5SDamjan Jovanovic 
15449646dec5SDamjan Jovanovic     case ucb::LockDepth_ZERO:
15459646dec5SDamjan Jovanovic         curlRequest.addHeader( "Depth", "0" );
15469646dec5SDamjan Jovanovic         break;
15479646dec5SDamjan Jovanovic     case ucb::LockDepth_ONE:
15489646dec5SDamjan Jovanovic         curlRequest.addHeader( "Depth", "1" );
15499646dec5SDamjan Jovanovic         break;
15509646dec5SDamjan Jovanovic     case ucb::LockDepth_INFINITY:
15519646dec5SDamjan Jovanovic         curlRequest.addHeader( "Depth", "infinity" );
15529646dec5SDamjan Jovanovic         break;
15539646dec5SDamjan Jovanovic     }
15549646dec5SDamjan Jovanovic 
15559646dec5SDamjan Jovanovic     rtl::OString xml = LockRequest::generateRequestBody( inLock );
15569646dec5SDamjan Jovanovic     curlRequest.addHeader( "Content-Type", "application/xml" );
15579646dec5SDamjan Jovanovic     curlRequest.setRequestBody( xml.getStr(), xml.getLength() );
15589646dec5SDamjan Jovanovic 
15599646dec5SDamjan Jovanovic     TimeValue startCall;
15609646dec5SDamjan Jovanovic     osl_getSystemTime( &startCall );
15619646dec5SDamjan Jovanovic 
15629646dec5SDamjan Jovanovic     CURLcode rc = curlRequest.lock( m_aUri, inPath );
15639646dec5SDamjan Jovanovic     processResponse( curlRequest, rc );
15649646dec5SDamjan Jovanovic 
15659646dec5SDamjan Jovanovic     // the returned property, a sequence of locks
15669646dec5SDamjan Jovanovic     // only the first is used
15679646dec5SDamjan Jovanovic     const DAVPropertyValue outLock( parseWebDAVLockResponse( curlRequest.getResponseBody().get() ) );
15689646dec5SDamjan Jovanovic     if(outLock.Name.compareToAscii(RTL_CONSTASCII_STRINGPARAM( "DAV:lockdiscovery" )) == 0 )
15699646dec5SDamjan Jovanovic     {
15709646dec5SDamjan Jovanovic         // got a lock, use only the first returned
15719646dec5SDamjan Jovanovic         uno::Sequence< ucb::Lock >      aLocks;
15729646dec5SDamjan Jovanovic         outLock.Value >>= aLocks;
15739646dec5SDamjan Jovanovic         ucb::Lock aLock = aLocks[0];
15749646dec5SDamjan Jovanovic 
15759646dec5SDamjan Jovanovic         CurlLock* aNewLock = new CurlLock( aLock, aUri, inPath );
15769646dec5SDamjan Jovanovic         // add the store the new lock
15779646dec5SDamjan Jovanovic         m_aCurlLockStore.addLock(aNewLock,this,
15789646dec5SDamjan Jovanovic                                  lastChanceToSendRefreshRequest(
15799646dec5SDamjan Jovanovic                                      startCall, static_cast< sal_Int32 >(aLock.Timeout) ) );
15809646dec5SDamjan Jovanovic     }
15819646dec5SDamjan Jovanovic }
15829646dec5SDamjan Jovanovic 
15839646dec5SDamjan Jovanovic // -------------------------------------------------------------------
15849646dec5SDamjan Jovanovic // LOCK (refresh existing lock from DAVResourceAccess)
15859646dec5SDamjan Jovanovic // -------------------------------------------------------------------
15869646dec5SDamjan Jovanovic sal_Int64 CurlSession::LOCK( const ::rtl::OUString & /*inPath*/,
15879646dec5SDamjan Jovanovic                              sal_Int64 nTimeout,
15889646dec5SDamjan Jovanovic                              const DAVRequestEnvironment & /*rEnv*/ )
15899646dec5SDamjan Jovanovic     throw ( DAVException )
15909646dec5SDamjan Jovanovic {
15919646dec5SDamjan Jovanovic     m_aLogger.log( LogLevel::INFO, "LOCK line $1$", (sal_Int32)__LINE__ );
15929646dec5SDamjan Jovanovic 
15939646dec5SDamjan Jovanovic     osl::Guard< osl::Mutex > theGuard( m_aMutex );
15949646dec5SDamjan Jovanovic 
15959646dec5SDamjan Jovanovic     return nTimeout;
15969646dec5SDamjan Jovanovic     /*
15979646dec5SDamjan Jovanovic     // Try to get the neon lock from lock store
15989646dec5SDamjan Jovanovic     CurlLock * theLock
15999646dec5SDamjan Jovanovic         = m_aCurlLockStore.findByUri( makeAbsoluteURL( inPath ) );
16009646dec5SDamjan Jovanovic     if ( !theLock )
16019646dec5SDamjan Jovanovic          throw DAVException( DAVException::DAV_NOT_LOCKED );
16029646dec5SDamjan Jovanovic 
16039646dec5SDamjan Jovanovic     Init( rEnv );
16049646dec5SDamjan Jovanovic 
16059646dec5SDamjan Jovanovic     // refresh existing lock.
16069646dec5SDamjan Jovanovic     theLock->timeout = static_cast< long >( nTimeout );
16079646dec5SDamjan Jovanovic 
16089646dec5SDamjan Jovanovic     TimeValue startCall;
16099646dec5SDamjan Jovanovic     osl_getSystemTime( &startCall );
16109646dec5SDamjan Jovanovic 
16119646dec5SDamjan Jovanovic     int theRetVal = ne_lock_refresh( m_pHttpSession, theLock );
16129646dec5SDamjan Jovanovic 
16139646dec5SDamjan Jovanovic     if ( theRetVal == NE_OK )
16149646dec5SDamjan Jovanovic     {
16159646dec5SDamjan Jovanovic         m_aCurlLockStore.updateLock( theLock,
16169646dec5SDamjan Jovanovic                                      lastChanceToSendRefreshRequest(
16179646dec5SDamjan Jovanovic                                          startCall, theLock->timeout ) );
16189646dec5SDamjan Jovanovic     }
16199646dec5SDamjan Jovanovic 
16209646dec5SDamjan Jovanovic     HandleError( theRetVal, inPath, rEnv );
16219646dec5SDamjan Jovanovic 
16229646dec5SDamjan Jovanovic     return theLock->timeout;
16239646dec5SDamjan Jovanovic     */
16249646dec5SDamjan Jovanovic }
16259646dec5SDamjan Jovanovic 
16269646dec5SDamjan Jovanovic // -------------------------------------------------------------------
16279646dec5SDamjan Jovanovic // LOCK (refresh existing lock from CurlLockStore)
16289646dec5SDamjan Jovanovic // -------------------------------------------------------------------
16299646dec5SDamjan Jovanovic bool CurlSession::LOCK( CurlLock * pLock,
16309646dec5SDamjan Jovanovic                         sal_Int32 & rlastChanceToSendRefreshRequest )
16319646dec5SDamjan Jovanovic {
16329646dec5SDamjan Jovanovic     m_aLogger.log( LogLevel::INFO, "LOCK line $1$", (sal_Int32)__LINE__ );
16339646dec5SDamjan Jovanovic 
16349646dec5SDamjan Jovanovic     osl::Guard< osl::Mutex > theGuard( m_aMutex );
16359646dec5SDamjan Jovanovic 
16369646dec5SDamjan Jovanovic     Init();
16379646dec5SDamjan Jovanovic     CurlRequest curlRequest( m_pCurl );
16389646dec5SDamjan Jovanovic 
16399646dec5SDamjan Jovanovic     const ucb::Lock & inLock = pLock->getLock();
16409646dec5SDamjan Jovanovic     rtl::OUString inPath = pLock->getResourcePath();
16419646dec5SDamjan Jovanovic 
16429646dec5SDamjan Jovanovic     if ( inLock.Timeout == -1 )
16439646dec5SDamjan Jovanovic         curlRequest.addHeader( "Timeout", "Infinite" );
16449646dec5SDamjan Jovanovic     else
16459646dec5SDamjan Jovanovic         curlRequest.addHeader( "Timeout", "Second-" + rtl::OString::valueOf( inLock.Timeout ) );
16469646dec5SDamjan Jovanovic 
16479646dec5SDamjan Jovanovic     switch ( inLock.Depth )
16489646dec5SDamjan Jovanovic     {
16499646dec5SDamjan Jovanovic         //i126305 TODO investigate on this case...
16509646dec5SDamjan Jovanovic     case ucb::LockDepth_MAKE_FIXED_SIZE:
16519646dec5SDamjan Jovanovic 
16529646dec5SDamjan Jovanovic     case ucb::LockDepth_ZERO:
16539646dec5SDamjan Jovanovic         curlRequest.addHeader( "Depth", "0" );
16549646dec5SDamjan Jovanovic         break;
16559646dec5SDamjan Jovanovic     case ucb::LockDepth_ONE:
16569646dec5SDamjan Jovanovic         curlRequest.addHeader( "Depth", "1" );
16579646dec5SDamjan Jovanovic         break;
16589646dec5SDamjan Jovanovic     case ucb::LockDepth_INFINITY:
16599646dec5SDamjan Jovanovic         curlRequest.addHeader( "Depth", "infinity" );
16609646dec5SDamjan Jovanovic         break;
16619646dec5SDamjan Jovanovic     }
16629646dec5SDamjan Jovanovic 
16639646dec5SDamjan Jovanovic     if ( inLock.LockTokens.getLength() > 0 )
16649646dec5SDamjan Jovanovic     {
16659646dec5SDamjan Jovanovic         curlRequest.addHeader( "If",
16669646dec5SDamjan Jovanovic             ( "(<" + rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ) + ">)" ).getStr() );
16679646dec5SDamjan Jovanovic     }
16689646dec5SDamjan Jovanovic 
16699646dec5SDamjan Jovanovic     rtl::OString xml = LockRequest::generateRequestBody( inLock );
16709646dec5SDamjan Jovanovic     curlRequest.addHeader( "Content-Type", "application/xml" );
16719646dec5SDamjan Jovanovic     curlRequest.setRequestBody( xml.getStr(), xml.getLength() );
16729646dec5SDamjan Jovanovic 
16739646dec5SDamjan Jovanovic     TimeValue startCall;
16749646dec5SDamjan Jovanovic     osl_getSystemTime( &startCall );
16759646dec5SDamjan Jovanovic 
16769646dec5SDamjan Jovanovic     CURLcode rc = curlRequest.lock( m_aUri, inPath );
16779646dec5SDamjan Jovanovic     processResponse( curlRequest, rc );
16789646dec5SDamjan Jovanovic 
16799646dec5SDamjan Jovanovic     // the returned property, a sequence of locks
16809646dec5SDamjan Jovanovic     // only the first is used
16819646dec5SDamjan Jovanovic     const DAVPropertyValue outLock( parseWebDAVLockResponse( curlRequest.getResponseBody().get() ) );
16829646dec5SDamjan Jovanovic     uno::Sequence< ucb::Lock >      aLocks;
16839646dec5SDamjan Jovanovic     outLock.Value >>= aLocks;
16849646dec5SDamjan Jovanovic     ucb::Lock aLock = aLocks[0];
16859646dec5SDamjan Jovanovic 
16869646dec5SDamjan Jovanovic     // if ok, update the lastchance refresh time in lock
16879646dec5SDamjan Jovanovic     rlastChanceToSendRefreshRequest
16889646dec5SDamjan Jovanovic         = lastChanceToSendRefreshRequest( startCall, static_cast< sal_Int32 >(aLock.Timeout) );
16899646dec5SDamjan Jovanovic 
16909646dec5SDamjan Jovanovic     return true;
16919646dec5SDamjan Jovanovic }
16929646dec5SDamjan Jovanovic 
16939646dec5SDamjan Jovanovic // -------------------------------------------------------------------
16949646dec5SDamjan Jovanovic // UNLOCK called from external (DAVResourceAccess)
16959646dec5SDamjan Jovanovic // -------------------------------------------------------------------
16969646dec5SDamjan Jovanovic void CurlSession::UNLOCK( const ::rtl::OUString & inPath,
16979646dec5SDamjan Jovanovic                           const DAVRequestEnvironment & rEnv )
16989646dec5SDamjan Jovanovic     throw ( DAVException )
16999646dec5SDamjan Jovanovic {
17009646dec5SDamjan Jovanovic     m_aLogger.log( LogLevel::INFO, "UNLOCK line $1$", (sal_Int32)__LINE__ );
17019646dec5SDamjan Jovanovic 
17029646dec5SDamjan Jovanovic     osl::Guard< osl::Mutex > theGuard( m_aMutex );
17039646dec5SDamjan Jovanovic 
17049646dec5SDamjan Jovanovic     rtl::OUString aUri( composeCurrentUri( inPath ) );
17059646dec5SDamjan Jovanovic     CurlLock * pLock = m_aCurlLockStore.findByUri( aUri );
17069646dec5SDamjan Jovanovic     if ( !pLock )
17079646dec5SDamjan Jovanovic     {
17089646dec5SDamjan Jovanovic         throw DAVException( DAVException::DAV_NOT_LOCKED );
17099646dec5SDamjan Jovanovic     }
17109646dec5SDamjan Jovanovic 
17119646dec5SDamjan Jovanovic     Init( rEnv );
17129646dec5SDamjan Jovanovic     CurlRequest curlRequest( m_pCurl );
17139646dec5SDamjan Jovanovic 
17149646dec5SDamjan Jovanovic     addEnvironmentRequestHeaders( curlRequest, rEnv );
17159646dec5SDamjan Jovanovic 
17169646dec5SDamjan Jovanovic     CredentialsData credsData( this, curlRequest, rEnv );
17179646dec5SDamjan Jovanovic     curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData );
17189646dec5SDamjan Jovanovic 
17199646dec5SDamjan Jovanovic     ucb::Lock inLock = pLock->getLock();
17209646dec5SDamjan Jovanovic     curlRequest.addHeader( "Lock-Token",
17219646dec5SDamjan Jovanovic             ( "<" + rtl::OUStringToOString( inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ) + ">" ).getStr() );
17229646dec5SDamjan Jovanovic 
17239646dec5SDamjan Jovanovic     // remove lock from lockstore
17249646dec5SDamjan Jovanovic     // so, if something goes wrong, we don't refresh it anymore
17259646dec5SDamjan Jovanovic     m_aCurlLockStore.removeLock( pLock );
17269646dec5SDamjan Jovanovic     delete pLock;
17279646dec5SDamjan Jovanovic 
17289646dec5SDamjan Jovanovic     CURLcode rc = curlRequest.unlock( m_aUri, inPath );
17299646dec5SDamjan Jovanovic     processResponse( curlRequest, rc );
17309646dec5SDamjan Jovanovic }
17319646dec5SDamjan Jovanovic 
17329646dec5SDamjan Jovanovic // -------------------------------------------------------------------
17339646dec5SDamjan Jovanovic // UNLOCK (called from CurlLockStore)
17349646dec5SDamjan Jovanovic // -------------------------------------------------------------------
17359646dec5SDamjan Jovanovic bool CurlSession::UNLOCK( CurlLock * pLock )
17369646dec5SDamjan Jovanovic {
17379646dec5SDamjan Jovanovic     m_aLogger.log( LogLevel::INFO, "UNLOCK line $1$", (sal_Int32)__LINE__ );
17389646dec5SDamjan Jovanovic 
17399646dec5SDamjan Jovanovic     osl::Guard< osl::Mutex > theGuard( m_aMutex );
17409646dec5SDamjan Jovanovic 
17419646dec5SDamjan Jovanovic     Init();
17429646dec5SDamjan Jovanovic     CurlRequest curlRequest( m_pCurl );
17439646dec5SDamjan Jovanovic 
17449646dec5SDamjan Jovanovic     rtl::OUString inPath = pLock->getResourcePath();
17459646dec5SDamjan Jovanovic     ucb::Lock inLock = pLock->getLock();
17469646dec5SDamjan Jovanovic     curlRequest.addHeader( "Lock-Token",
17479646dec5SDamjan Jovanovic             ( "<" + rtl::OUStringToOString( inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ) + ">" ).getStr() );
17489646dec5SDamjan Jovanovic 
17499646dec5SDamjan Jovanovic     CURLcode rc = curlRequest.unlock( m_aUri, inPath );
17509646dec5SDamjan Jovanovic     processResponse( curlRequest, rc );
17519646dec5SDamjan Jovanovic     return true;
17529646dec5SDamjan Jovanovic }
17539646dec5SDamjan Jovanovic 
17549646dec5SDamjan Jovanovic // -------------------------------------------------------------------
17559646dec5SDamjan Jovanovic void CurlSession::abort()
17569646dec5SDamjan Jovanovic     throw ( DAVException )
17579646dec5SDamjan Jovanovic {
17589646dec5SDamjan Jovanovic     // 11.11.09 (tkr): The following code lines causing crashes if
17599646dec5SDamjan Jovanovic     // closing a ongoing connection. It turned out that this existing
17609646dec5SDamjan Jovanovic     // solution doesn't work in multi-threading environments.
17619646dec5SDamjan Jovanovic     // So I disabled them in 3.2. . Issue #73893# should fix it in OOo 3.3.
17629646dec5SDamjan Jovanovic     //if ( m_pHttpSession )
17639646dec5SDamjan Jovanovic     //    ne_close_connection( m_pHttpSession );
17649646dec5SDamjan Jovanovic }
17659646dec5SDamjan Jovanovic 
17669646dec5SDamjan Jovanovic // -------------------------------------------------------------------
17679646dec5SDamjan Jovanovic const ucbhelper::InternetProxyServer & CurlSession::getProxySettings() const
17689646dec5SDamjan Jovanovic {
17699646dec5SDamjan Jovanovic     if ( m_aUri.GetScheme().equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "http" ) ) ||
17709646dec5SDamjan Jovanovic          m_aUri.GetScheme().equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "https" ) ) )
17719646dec5SDamjan Jovanovic     {
17729646dec5SDamjan Jovanovic         return m_rProxyDecider.getProxy( m_aUri.GetScheme(),
17739646dec5SDamjan Jovanovic                                          m_aUri.GetHost(),
17749646dec5SDamjan Jovanovic                                          m_aUri.GetPort() );
17759646dec5SDamjan Jovanovic     }
17769646dec5SDamjan Jovanovic     else
17779646dec5SDamjan Jovanovic     {
17789646dec5SDamjan Jovanovic         // TODO: figure out, if this case can occur
17799646dec5SDamjan Jovanovic         return m_rProxyDecider.getProxy( m_aUri.GetScheme(),
17809646dec5SDamjan Jovanovic                                          rtl::OUString() /* not used */,
17819646dec5SDamjan Jovanovic                                          -1 /* not used */ );
17829646dec5SDamjan Jovanovic     }
17839646dec5SDamjan Jovanovic }
17849646dec5SDamjan Jovanovic 
17859646dec5SDamjan Jovanovic /*
17869646dec5SDamjan Jovanovic // -------------------------------------------------------------------
17879646dec5SDamjan Jovanovic namespace {
17889646dec5SDamjan Jovanovic 
17899646dec5SDamjan Jovanovic bool containsLocktoken( const uno::Sequence< ucb::Lock > & rLocks,
17909646dec5SDamjan Jovanovic                         const char * token )
17919646dec5SDamjan Jovanovic {
17929646dec5SDamjan Jovanovic     for ( sal_Int32 n = 0; n < rLocks.getLength(); ++n )
17939646dec5SDamjan Jovanovic     {
17949646dec5SDamjan Jovanovic         const uno::Sequence< rtl::OUString > & rTokens
17959646dec5SDamjan Jovanovic             = rLocks[ n ].LockTokens;
17969646dec5SDamjan Jovanovic         for ( sal_Int32 m = 0; m < rTokens.getLength(); ++m )
17979646dec5SDamjan Jovanovic         {
17989646dec5SDamjan Jovanovic             if ( rTokens[ m ].equalsAscii( token ) )
17999646dec5SDamjan Jovanovic                 return true;
18009646dec5SDamjan Jovanovic         }
18019646dec5SDamjan Jovanovic     }
18029646dec5SDamjan Jovanovic     return false;
18039646dec5SDamjan Jovanovic }
18049646dec5SDamjan Jovanovic 
18059646dec5SDamjan Jovanovic } // namespace
18069646dec5SDamjan Jovanovic */
18079646dec5SDamjan Jovanovic 
18089646dec5SDamjan Jovanovic // -------------------------------------------------------------------
18099646dec5SDamjan Jovanovic // This method doesn't seem to be used.
18109646dec5SDamjan Jovanovic // In any case the default behavior is to ask a lock with a life of 3 minutes
18119646dec5SDamjan Jovanovic // it will then be refreshed automatically (see CurlLockStore class)
18129646dec5SDamjan Jovanovic // In case of AOO crash the lock will expire by itself
18139646dec5SDamjan Jovanovic bool CurlSession::removeExpiredLocktoken( const rtl::OUString & /*inURL*/,
18149646dec5SDamjan Jovanovic                                           const DAVRequestEnvironment & /*rEnv*/ )
18159646dec5SDamjan Jovanovic {
18169646dec5SDamjan Jovanovic     return true;
18179646dec5SDamjan Jovanovic     /*
18189646dec5SDamjan Jovanovic     CurlLock * theLock = m_aCurlLockStore.findByUri( inURL );
18199646dec5SDamjan Jovanovic     if ( !theLock )
18209646dec5SDamjan Jovanovic         return false;
18219646dec5SDamjan Jovanovic 
18229646dec5SDamjan Jovanovic     // do a lockdiscovery to check whether this lock is still valid.
18239646dec5SDamjan Jovanovic     try
18249646dec5SDamjan Jovanovic     {
18259646dec5SDamjan Jovanovic         // @@@ Alternative: use ne_lock_discover() => less overhead
18269646dec5SDamjan Jovanovic 
18279646dec5SDamjan Jovanovic         std::vector< DAVResource > aResources;
18289646dec5SDamjan Jovanovic         std::vector< rtl::OUString > aPropNames;
18299646dec5SDamjan Jovanovic         aPropNames.push_back( DAVProperties::LOCKDISCOVERY );
18309646dec5SDamjan Jovanovic 
18319646dec5SDamjan Jovanovic         PROPFIND( rEnv.m_aRequestURI, DAVZERO, aPropNames, aResources, rEnv );
18329646dec5SDamjan Jovanovic 
18339646dec5SDamjan Jovanovic         if ( aResources.size() == 0 )
18349646dec5SDamjan Jovanovic             return false;
18359646dec5SDamjan Jovanovic 
18369646dec5SDamjan Jovanovic         std::vector< DAVPropertyValue >::const_iterator it
18379646dec5SDamjan Jovanovic             = aResources[ 0 ].properties.begin();
18389646dec5SDamjan Jovanovic         std::vector< DAVPropertyValue >::const_iterator end
18399646dec5SDamjan Jovanovic             = aResources[ 0 ].properties.end();
18409646dec5SDamjan Jovanovic 
18419646dec5SDamjan Jovanovic         while ( it != end )
18429646dec5SDamjan Jovanovic         {
18439646dec5SDamjan Jovanovic             if ( (*it).Name.equals( DAVProperties::LOCKDISCOVERY ) )
18449646dec5SDamjan Jovanovic             {
18459646dec5SDamjan Jovanovic                 uno::Sequence< ucb::Lock > aLocks;
18469646dec5SDamjan Jovanovic                 if ( !( (*it).Value >>= aLocks ) )
18479646dec5SDamjan Jovanovic                     return false;
18489646dec5SDamjan Jovanovic 
18499646dec5SDamjan Jovanovic                 if ( !containsLocktoken( aLocks, theLock->token ) )
18509646dec5SDamjan Jovanovic                 {
18519646dec5SDamjan Jovanovic                     // expired!
18529646dec5SDamjan Jovanovic                     break;
18539646dec5SDamjan Jovanovic                 }
18549646dec5SDamjan Jovanovic 
18559646dec5SDamjan Jovanovic                 // still valid.
18569646dec5SDamjan Jovanovic                 return false;
18579646dec5SDamjan Jovanovic             }
18589646dec5SDamjan Jovanovic             ++it;
18599646dec5SDamjan Jovanovic         }
18609646dec5SDamjan Jovanovic 
18619646dec5SDamjan Jovanovic         // No lockdiscovery prop in propfind result / locktoken not found
18629646dec5SDamjan Jovanovic         // in propfind result -> not locked
18639646dec5SDamjan Jovanovic         OSL_TRACE( "CurlSession::removeExpiredLocktoken: Removing "
18649646dec5SDamjan Jovanovic                    " expired lock token for %s. token: %s",
18659646dec5SDamjan Jovanovic                    rtl::OUStringToOString( inURL,
18669646dec5SDamjan Jovanovic                                            RTL_TEXTENCODING_UTF8 ).getStr(),
18679646dec5SDamjan Jovanovic                    theLock->token );
18689646dec5SDamjan Jovanovic 
18699646dec5SDamjan Jovanovic         m_aCurlLockStore.removeLock( theLock );
18709646dec5SDamjan Jovanovic         ne_lock_destroy( theLock );
18719646dec5SDamjan Jovanovic         return true;
18729646dec5SDamjan Jovanovic     }
18739646dec5SDamjan Jovanovic     catch ( DAVException const & )
18749646dec5SDamjan Jovanovic     {
18759646dec5SDamjan Jovanovic     }
18769646dec5SDamjan Jovanovic     return false;
18779646dec5SDamjan Jovanovic     */
18789646dec5SDamjan Jovanovic }
18799646dec5SDamjan Jovanovic 
18809646dec5SDamjan Jovanovic // -------------------------------------------------------------------
18819646dec5SDamjan Jovanovic // static
18829646dec5SDamjan Jovanovic bool
18839646dec5SDamjan Jovanovic CurlSession::getDataFromInputStream(
18849646dec5SDamjan Jovanovic     const uno::Reference< io::XInputStream > & xStream,
18859646dec5SDamjan Jovanovic     uno::Sequence< sal_Int8 > & rData,
18869646dec5SDamjan Jovanovic     bool bAppendTrailingZeroByte )
18879646dec5SDamjan Jovanovic {
18889646dec5SDamjan Jovanovic     if ( xStream.is() )
18899646dec5SDamjan Jovanovic     {
18909646dec5SDamjan Jovanovic         uno::Reference< io::XSeekable > xSeekable( xStream, uno::UNO_QUERY );
18919646dec5SDamjan Jovanovic         if ( xSeekable.is() )
18929646dec5SDamjan Jovanovic         {
18939646dec5SDamjan Jovanovic             try
18949646dec5SDamjan Jovanovic             {
18959646dec5SDamjan Jovanovic                 sal_Int32 nSize
18969646dec5SDamjan Jovanovic                     = sal::static_int_cast<sal_Int32>(xSeekable->getLength());
18979646dec5SDamjan Jovanovic                 sal_Int32 nRead
18989646dec5SDamjan Jovanovic                     = xStream->readBytes( rData, nSize );
18999646dec5SDamjan Jovanovic 
19009646dec5SDamjan Jovanovic                 if ( nRead == nSize )
19019646dec5SDamjan Jovanovic                 {
19029646dec5SDamjan Jovanovic                     if ( bAppendTrailingZeroByte )
19039646dec5SDamjan Jovanovic                     {
19049646dec5SDamjan Jovanovic                         rData.realloc( nSize + 1 );
19059646dec5SDamjan Jovanovic                         rData[ nSize ] = sal_Int8( 0 );
19069646dec5SDamjan Jovanovic                     }
19079646dec5SDamjan Jovanovic                     return true;
19089646dec5SDamjan Jovanovic                 }
19099646dec5SDamjan Jovanovic             }
19109646dec5SDamjan Jovanovic             catch ( io::NotConnectedException const & )
19119646dec5SDamjan Jovanovic             {
19129646dec5SDamjan Jovanovic                 // readBytes
19139646dec5SDamjan Jovanovic             }
19149646dec5SDamjan Jovanovic             catch ( io::BufferSizeExceededException const & )
19159646dec5SDamjan Jovanovic             {
19169646dec5SDamjan Jovanovic                 // readBytes
19179646dec5SDamjan Jovanovic             }
19189646dec5SDamjan Jovanovic             catch ( io::IOException const & )
19199646dec5SDamjan Jovanovic             {
19209646dec5SDamjan Jovanovic                 // getLength, readBytes
19219646dec5SDamjan Jovanovic             }
19229646dec5SDamjan Jovanovic         }
19239646dec5SDamjan Jovanovic         else
19249646dec5SDamjan Jovanovic         {
19259646dec5SDamjan Jovanovic             try
19269646dec5SDamjan Jovanovic             {
19279646dec5SDamjan Jovanovic                 uno::Sequence< sal_Int8 > aBuffer;
19289646dec5SDamjan Jovanovic                 sal_Int32 nPos = 0;
19299646dec5SDamjan Jovanovic 
19309646dec5SDamjan Jovanovic                 sal_Int32 nRead = xStream->readSomeBytes( aBuffer, 65536 );
19319646dec5SDamjan Jovanovic                 while ( nRead > 0 )
19329646dec5SDamjan Jovanovic                 {
19339646dec5SDamjan Jovanovic                     if ( rData.getLength() < ( nPos + nRead ) )
19349646dec5SDamjan Jovanovic                         rData.realloc( nPos + nRead );
19359646dec5SDamjan Jovanovic 
19369646dec5SDamjan Jovanovic                     aBuffer.realloc( nRead );
19379646dec5SDamjan Jovanovic                     rtl_copyMemory( (void*)( rData.getArray() + nPos ),
19389646dec5SDamjan Jovanovic                                     (const void*)aBuffer.getConstArray(),
19399646dec5SDamjan Jovanovic                                     nRead );
19409646dec5SDamjan Jovanovic                     nPos += nRead;
19419646dec5SDamjan Jovanovic 
19429646dec5SDamjan Jovanovic                     aBuffer.realloc( 0 );
19439646dec5SDamjan Jovanovic                     nRead = xStream->readSomeBytes( aBuffer, 65536 );
19449646dec5SDamjan Jovanovic                 }
19459646dec5SDamjan Jovanovic 
19469646dec5SDamjan Jovanovic                 if ( bAppendTrailingZeroByte )
19479646dec5SDamjan Jovanovic                 {
19489646dec5SDamjan Jovanovic                     rData.realloc( nPos + 1 );
19499646dec5SDamjan Jovanovic                     rData[ nPos ] = sal_Int8( 0 );
19509646dec5SDamjan Jovanovic                 }
19519646dec5SDamjan Jovanovic                 return true;
19529646dec5SDamjan Jovanovic             }
19539646dec5SDamjan Jovanovic             catch ( io::NotConnectedException const & )
19549646dec5SDamjan Jovanovic             {
19559646dec5SDamjan Jovanovic                 // readBytes
19569646dec5SDamjan Jovanovic             }
19579646dec5SDamjan Jovanovic             catch ( io::BufferSizeExceededException const & )
19589646dec5SDamjan Jovanovic             {
19599646dec5SDamjan Jovanovic                 // readBytes
19609646dec5SDamjan Jovanovic             }
19619646dec5SDamjan Jovanovic             catch ( io::IOException const & )
19629646dec5SDamjan Jovanovic             {
19639646dec5SDamjan Jovanovic                 // readBytes
19649646dec5SDamjan Jovanovic             }
19659646dec5SDamjan Jovanovic         }
19669646dec5SDamjan Jovanovic     }
19679646dec5SDamjan Jovanovic     return false;
19689646dec5SDamjan Jovanovic }
19699646dec5SDamjan Jovanovic 
19709646dec5SDamjan Jovanovic // ---------------------------------------------------------------------
19719646dec5SDamjan Jovanovic sal_Bool
19729646dec5SDamjan Jovanovic CurlSession::isDomainMatch( rtl::OUString certHostName )
19739646dec5SDamjan Jovanovic {
19749646dec5SDamjan Jovanovic     rtl::OUString hostName = getHostName();
19759646dec5SDamjan Jovanovic 
19769646dec5SDamjan Jovanovic     if (hostName.equalsIgnoreAsciiCase( certHostName ) )
19779646dec5SDamjan Jovanovic         return sal_True;
19789646dec5SDamjan Jovanovic 
19799646dec5SDamjan Jovanovic     if ( 0 == certHostName.indexOf( rtl::OUString::createFromAscii( "*" ) ) &&
19809646dec5SDamjan Jovanovic          hostName.getLength() >= certHostName.getLength() )
19819646dec5SDamjan Jovanovic     {
19829646dec5SDamjan Jovanovic         rtl::OUString cmpStr = certHostName.copy( 1 );
19839646dec5SDamjan Jovanovic 
19849646dec5SDamjan Jovanovic         if ( hostName.matchIgnoreAsciiCase(
19859646dec5SDamjan Jovanovic                 cmpStr, hostName.getLength() - cmpStr.getLength() ) )
19869646dec5SDamjan Jovanovic             return sal_True;
19879646dec5SDamjan Jovanovic     }
19889646dec5SDamjan Jovanovic     return sal_False;
19899646dec5SDamjan Jovanovic }
1990