151ba086bSDamjan Jovanovic /************************************************************** 251ba086bSDamjan Jovanovic * 351ba086bSDamjan Jovanovic * Licensed to the Apache Software Foundation (ASF) under one 451ba086bSDamjan Jovanovic * or more contributor license agreements. See the NOTICE file 551ba086bSDamjan Jovanovic * distributed with this work for additional information 651ba086bSDamjan Jovanovic * regarding copyright ownership. The ASF licenses this file 751ba086bSDamjan Jovanovic * to you under the Apache License, Version 2.0 (the 851ba086bSDamjan Jovanovic * "License"); you may not use this file except in compliance 951ba086bSDamjan Jovanovic * with the License. You may obtain a copy of the License at 1051ba086bSDamjan Jovanovic * 1151ba086bSDamjan Jovanovic * http://www.apache.org/licenses/LICENSE-2.0 1251ba086bSDamjan Jovanovic * 1351ba086bSDamjan Jovanovic * Unless required by applicable law or agreed to in writing, 1451ba086bSDamjan Jovanovic * software distributed under the License is distributed on an 1551ba086bSDamjan Jovanovic * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 1651ba086bSDamjan Jovanovic * KIND, either express or implied. See the License for the 1751ba086bSDamjan Jovanovic * specific language governing permissions and limitations 1851ba086bSDamjan Jovanovic * under the License. 1951ba086bSDamjan Jovanovic * 2051ba086bSDamjan Jovanovic *************************************************************/ 2151ba086bSDamjan Jovanovic 2251ba086bSDamjan Jovanovic 2351ba086bSDamjan Jovanovic 2451ba086bSDamjan Jovanovic // MARKER(update_precomp.py): autogen include statement, do not remove 2551ba086bSDamjan Jovanovic #include "precompiled_webdav.hxx" 2651ba086bSDamjan Jovanovic 2751ba086bSDamjan Jovanovic #include <hash_map> 2851ba086bSDamjan Jovanovic #include <vector> 2951ba086bSDamjan Jovanovic #include <string.h> 3051ba086bSDamjan Jovanovic #include <rtl/string.h> 3151ba086bSDamjan Jovanovic #include <rtl/strbuf.hxx> 3251ba086bSDamjan Jovanovic #include <rtl/ustrbuf.hxx> 3351ba086bSDamjan Jovanovic #include <osl/time.h> 3451ba086bSDamjan Jovanovic #include "comphelper/sequence.hxx" 3551ba086bSDamjan Jovanovic #include "ucbhelper/simplecertificatevalidationrequest.hxx" 3651ba086bSDamjan Jovanovic 3751ba086bSDamjan Jovanovic #include "DAVAuthListener.hxx" 3851ba086bSDamjan Jovanovic #include "CurlTypes.hxx" 3951ba086bSDamjan Jovanovic #include "CurlSession.hxx" 4051ba086bSDamjan Jovanovic #include "LockRequest.hxx" 4151ba086bSDamjan Jovanovic #include "PropfindRequest.hxx" 4251ba086bSDamjan Jovanovic #include "ProppatchRequest.hxx" 4351ba086bSDamjan Jovanovic #include "CurlInputStream.hxx" 4451ba086bSDamjan Jovanovic #include "UCBDeadPropertyValue.hxx" 4551ba086bSDamjan Jovanovic #include "webdavuseragent.hxx" 4651ba086bSDamjan Jovanovic #include "webdavresponseparser.hxx" 4751ba086bSDamjan Jovanovic #include "webdavprovider.hxx" 4851ba086bSDamjan Jovanovic 4951ba086bSDamjan Jovanovic 5051ba086bSDamjan Jovanovic #include <com/sun/star/xml/crypto/XSecurityEnvironment.hpp> 5151ba086bSDamjan Jovanovic #include <com/sun/star/logging/LogLevel.hpp> 5251ba086bSDamjan Jovanovic #include <com/sun/star/security/XCertificate.hpp> 5351ba086bSDamjan Jovanovic #include <com/sun/star/security/CertificateValidity.hpp> 5451ba086bSDamjan Jovanovic #include <com/sun/star/security/CertificateContainerStatus.hpp> 5551ba086bSDamjan Jovanovic #include <com/sun/star/security/CertificateContainer.hpp> 5651ba086bSDamjan Jovanovic #include <com/sun/star/security/XCertificateContainer.hpp> 5751ba086bSDamjan Jovanovic #include <com/sun/star/security/CertAltNameEntry.hpp> 5851ba086bSDamjan Jovanovic #include <com/sun/star/security/XSanExtension.hpp> 5951ba086bSDamjan Jovanovic #include <com/sun/star/ucb/Lock.hpp> 6051ba086bSDamjan Jovanovic #include <com/sun/star/xml/crypto/XSEInitializer.hpp> 6151ba086bSDamjan Jovanovic 6251ba086bSDamjan Jovanovic using namespace com::sun::star; 6351ba086bSDamjan Jovanovic using namespace com::sun::star::logging; 6451ba086bSDamjan Jovanovic using namespace http_dav_ucp; 6551ba086bSDamjan Jovanovic 6651ba086bSDamjan Jovanovic #define OID_SUBJECT_ALTERNATIVE_NAME "2.5.29.17" 6751ba086bSDamjan Jovanovic 6851ba086bSDamjan Jovanovic struct CredentialsData 6951ba086bSDamjan Jovanovic { 7051ba086bSDamjan Jovanovic CredentialsData( CurlSession *curlSession, CurlRequest &curlRequest, const DAVRequestEnvironment &requestEnvironment ) 7151ba086bSDamjan Jovanovic : session( curlSession) 7251ba086bSDamjan Jovanovic , request( curlRequest ) 7351ba086bSDamjan Jovanovic , env( requestEnvironment ) 7451ba086bSDamjan Jovanovic {} 7551ba086bSDamjan Jovanovic 7651ba086bSDamjan Jovanovic CurlSession *session; 7751ba086bSDamjan Jovanovic CurlRequest &request; 7851ba086bSDamjan Jovanovic const DAVRequestEnvironment &env; 7951ba086bSDamjan Jovanovic }; 8051ba086bSDamjan Jovanovic 8151ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 8251ba086bSDamjan Jovanovic // static members! 8351ba086bSDamjan Jovanovic CurlLockStore CurlSession::m_aCurlLockStore; 8451ba086bSDamjan Jovanovic 8551ba086bSDamjan Jovanovic 8651ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 8751ba086bSDamjan Jovanovic // Constructor 8851ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 8951ba086bSDamjan Jovanovic CurlSession::CurlSession( 9051ba086bSDamjan Jovanovic const rtl::Reference< DAVSessionFactory > & rSessionFactory, 9151ba086bSDamjan Jovanovic const rtl::OUString& inUri, 9251ba086bSDamjan Jovanovic const ucbhelper::InternetProxyDecider & rProxyDecider ) 9351ba086bSDamjan Jovanovic throw ( DAVException ) 9451ba086bSDamjan Jovanovic : DAVSession( rSessionFactory ) 9551ba086bSDamjan Jovanovic , m_aMutex() 9651ba086bSDamjan Jovanovic , m_aContext( m_xFactory->getServiceFactory() ) 9751ba086bSDamjan Jovanovic , m_aLogger( m_aContext.getUNOContext(), WEBDAV_CONTENT_PROVIDER_SERVICE_NAME ) 9851ba086bSDamjan Jovanovic , m_aUri( inUri ) 9951ba086bSDamjan Jovanovic , m_aProxyName() 10051ba086bSDamjan Jovanovic , m_nProxyPort( 0 ) 10151ba086bSDamjan Jovanovic , m_aServerHeaderField() 10251ba086bSDamjan Jovanovic , m_pCurl( 0 ) 10351ba086bSDamjan Jovanovic , m_bUseChunkedEncoding( false ) 10451ba086bSDamjan Jovanovic , m_bTransferEncodingSwitched( false ) 10551ba086bSDamjan Jovanovic , m_rProxyDecider( rProxyDecider ) 10651ba086bSDamjan Jovanovic , m_aEnv() 10751ba086bSDamjan Jovanovic { 10851ba086bSDamjan Jovanovic m_pCurl = curl_easy_init(); 10951ba086bSDamjan Jovanovic 11051ba086bSDamjan Jovanovic curl_easy_setopt( m_pCurl, CURLOPT_HTTPAUTH, CURLAUTH_ANY ); 11151ba086bSDamjan Jovanovic curl_easy_setopt( m_pCurl, CURLOPT_PROXYAUTH, CURLAUTH_ANY ); 11251ba086bSDamjan Jovanovic 11351ba086bSDamjan Jovanovic curl_easy_setopt( m_pCurl, CURLOPT_SSL_CTX_FUNCTION, Curl_SSLContextCallback ); 11451ba086bSDamjan Jovanovic curl_easy_setopt( m_pCurl, CURLOPT_SSL_CTX_DATA, this ); 11551ba086bSDamjan Jovanovic 11651ba086bSDamjan Jovanovic if ( m_aLogger.getLogLevel() == LogLevel::FINEST ) 11751ba086bSDamjan Jovanovic { 11851ba086bSDamjan Jovanovic curl_easy_setopt( m_pCurl, CURLOPT_DEBUGFUNCTION, Curl_DebugCallback ); 11951ba086bSDamjan Jovanovic curl_easy_setopt( m_pCurl, CURLOPT_DEBUGDATA, this ); 12051ba086bSDamjan Jovanovic curl_easy_setopt( m_pCurl, CURLOPT_VERBOSE, 1L); 12151ba086bSDamjan Jovanovic } 12251ba086bSDamjan Jovanovic m_aLogger.log( LogLevel::INFO, "CurlSession::CurlSession with URL $1$", 12351ba086bSDamjan Jovanovic rtl::OUStringToOString( inUri, RTL_TEXTENCODING_UTF8 ).getStr() ); 12451ba086bSDamjan Jovanovic } 12551ba086bSDamjan Jovanovic 12651ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 12751ba086bSDamjan Jovanovic // Destructor 12851ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 12951ba086bSDamjan Jovanovic CurlSession::~CurlSession( ) 13051ba086bSDamjan Jovanovic { 13151ba086bSDamjan Jovanovic if ( m_pCurl ) 13251ba086bSDamjan Jovanovic { 13351ba086bSDamjan Jovanovic curl_easy_cleanup( m_pCurl ); 13451ba086bSDamjan Jovanovic m_pCurl = 0; 13551ba086bSDamjan Jovanovic m_aLogger.log( LogLevel::INFO, "CurlSession::~CurlSession: closed curl session"); 13651ba086bSDamjan Jovanovic } 13751ba086bSDamjan Jovanovic } 13851ba086bSDamjan Jovanovic 13951ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 14051ba086bSDamjan Jovanovic void CurlSession::Init( const DAVRequestEnvironment & rEnv ) 14151ba086bSDamjan Jovanovic throw ( DAVException ) 14251ba086bSDamjan Jovanovic { 14351ba086bSDamjan Jovanovic osl::Guard< osl::Mutex > theGuard( m_aMutex ); 14451ba086bSDamjan Jovanovic m_aEnv = rEnv; 14551ba086bSDamjan Jovanovic Init(); 14651ba086bSDamjan Jovanovic } 14751ba086bSDamjan Jovanovic 14851ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 14951ba086bSDamjan Jovanovic void CurlSession::Init() 15051ba086bSDamjan Jovanovic throw ( DAVException ) 15151ba086bSDamjan Jovanovic { 15251ba086bSDamjan Jovanovic osl::Guard< osl::Mutex > theGuard( m_aMutex ); 15351ba086bSDamjan Jovanovic 15451ba086bSDamjan Jovanovic const sal_Char *url = rtl::OUStringToOString( m_aUri.GetURI(), RTL_TEXTENCODING_UTF8 ).getStr(); 15551ba086bSDamjan Jovanovic CURLcode rc; 15651ba086bSDamjan Jovanovic rc = curl_easy_setopt( m_pCurl, CURLOPT_URL, url ); 15751ba086bSDamjan Jovanovic if ( rc != CURLE_OK ) 15851ba086bSDamjan Jovanovic throw DAVException( DAVException::DAV_SESSION_CREATE, 15951ba086bSDamjan Jovanovic CurlUri::makeConnectionEndPointString( m_aUri.GetHost(), m_aUri.GetPort() ) ); 16051ba086bSDamjan Jovanovic 16151ba086bSDamjan Jovanovic const ucbhelper::InternetProxyServer & rProxyCfg = getProxySettings(); 16251ba086bSDamjan Jovanovic if ( ( rProxyCfg.aName != m_aProxyName ) 16351ba086bSDamjan Jovanovic || ( rProxyCfg.nPort != m_nProxyPort ) ) 16451ba086bSDamjan Jovanovic { 16551ba086bSDamjan Jovanovic m_aProxyName = rProxyCfg.aName; 16651ba086bSDamjan Jovanovic m_nProxyPort = rProxyCfg.nPort; 16751ba086bSDamjan Jovanovic if ( !m_aProxyName.isEmpty() ) 16851ba086bSDamjan Jovanovic { 16951ba086bSDamjan Jovanovic m_aLogger.log( LogLevel::INFO, "Using $1$ proxy server at $2$:$3$", 17051ba086bSDamjan Jovanovic m_aUri.GetScheme(), m_aProxyName, m_nProxyPort ); 17151ba086bSDamjan Jovanovic curl_easy_setopt( m_pCurl, CURLOPT_PROXY, rtl::OUStringToOString( m_aProxyName, RTL_TEXTENCODING_UTF8 ).getStr() ); 17251ba086bSDamjan Jovanovic curl_easy_setopt( m_pCurl, CURLOPT_PROXYPORT, (long)m_nProxyPort ); 17351ba086bSDamjan Jovanovic if ( m_aUri.GetScheme().equalsAscii( "https" ) ) 17451ba086bSDamjan Jovanovic curl_easy_setopt( m_pCurl, CURLOPT_PROXYTYPE, CURLPROXY_HTTPS ); 17551ba086bSDamjan Jovanovic else 17651ba086bSDamjan Jovanovic curl_easy_setopt( m_pCurl, CURLOPT_PROXYTYPE, CURLPROXY_HTTP ); 17751ba086bSDamjan Jovanovic // no other proxy types are implemented by AOO 17851ba086bSDamjan Jovanovic } 17951ba086bSDamjan Jovanovic else 18051ba086bSDamjan Jovanovic { 18151ba086bSDamjan Jovanovic // Empty string as opposed to NULL, means don't use the default curl proxy. 18251ba086bSDamjan Jovanovic m_aLogger.log( LogLevel::INFO, "Not using a proxy server" ); 18351ba086bSDamjan Jovanovic curl_easy_setopt( m_pCurl, CURLOPT_PROXY, "" ); 18451ba086bSDamjan Jovanovic } 18551ba086bSDamjan Jovanovic // if we change the proxy settings, clear the credentials for the previous proxy too 18651ba086bSDamjan Jovanovic curl_easy_setopt( m_pCurl, CURLOPT_PROXYUSERNAME, "" ); 18751ba086bSDamjan Jovanovic curl_easy_setopt( m_pCurl, CURLOPT_PROXYPASSWORD, "" ); 18851ba086bSDamjan Jovanovic } 18951ba086bSDamjan Jovanovic } 19051ba086bSDamjan Jovanovic 19151ba086bSDamjan Jovanovic bool CurlSession::isSSLNeeded() 19251ba086bSDamjan Jovanovic { 19351ba086bSDamjan Jovanovic return m_aUri.GetScheme().equalsIgnoreAsciiCase( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "https" ) ) ); 19451ba086bSDamjan Jovanovic } 19551ba086bSDamjan Jovanovic 19651ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 19751ba086bSDamjan Jovanovic // helper function 19851ba086bSDamjan Jovanovic // it composes the uri for lockstore registration 19951ba086bSDamjan Jovanovic rtl::OUString CurlSession::composeCurrentUri(const rtl::OUString & inPath) 20051ba086bSDamjan Jovanovic { 20151ba086bSDamjan Jovanovic rtl::OUString aScheme( m_aUri.GetScheme() ); 20251ba086bSDamjan Jovanovic rtl::OUStringBuffer aBuf( aScheme ); 20351ba086bSDamjan Jovanovic aBuf.appendAscii( "://" ); 20451ba086bSDamjan Jovanovic if ( m_aUri.GetUserName().getLength() > 0 ) 20551ba086bSDamjan Jovanovic { 20651ba086bSDamjan Jovanovic aBuf.append( m_aUri.GetUserName() ); 20751ba086bSDamjan Jovanovic if ( m_aUri.GetPassword().getLength() > 0 ) 20851ba086bSDamjan Jovanovic { 20951ba086bSDamjan Jovanovic aBuf.appendAscii( ":" ); 21051ba086bSDamjan Jovanovic aBuf.append( m_aUri.GetPassword() ); 21151ba086bSDamjan Jovanovic } 21251ba086bSDamjan Jovanovic aBuf.appendAscii( "@" ); 21351ba086bSDamjan Jovanovic } 21451ba086bSDamjan Jovanovic // Is host a numeric IPv6 address? 21551ba086bSDamjan Jovanovic if ( ( m_aUri.GetHost().indexOf( ':' ) != -1 ) && 21651ba086bSDamjan Jovanovic ( m_aUri.GetHost()[ 0 ] != sal_Unicode( '[' ) ) ) 21751ba086bSDamjan Jovanovic { 21851ba086bSDamjan Jovanovic aBuf.appendAscii( "[" ); 21951ba086bSDamjan Jovanovic aBuf.append( m_aUri.GetHost() ); 22051ba086bSDamjan Jovanovic aBuf.appendAscii( "]" ); 22151ba086bSDamjan Jovanovic } 22251ba086bSDamjan Jovanovic else 22351ba086bSDamjan Jovanovic { 22451ba086bSDamjan Jovanovic aBuf.append( m_aUri.GetHost() ); 22551ba086bSDamjan Jovanovic } 22651ba086bSDamjan Jovanovic 22751ba086bSDamjan Jovanovic // append port, but only, if not default port. 22851ba086bSDamjan Jovanovic bool bAppendPort = true; 22951ba086bSDamjan Jovanovic sal_Int32 aPort = m_aUri.GetPort(); 23051ba086bSDamjan Jovanovic switch ( aPort ) 23151ba086bSDamjan Jovanovic { 23251ba086bSDamjan Jovanovic case DEFAULT_HTTP_PORT: 23351ba086bSDamjan Jovanovic bAppendPort = aScheme.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "http" ) ); 23451ba086bSDamjan Jovanovic break; 23551ba086bSDamjan Jovanovic 23651ba086bSDamjan Jovanovic case DEFAULT_HTTPS_PORT: 23751ba086bSDamjan Jovanovic bAppendPort = !aScheme.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "https" ) ); 23851ba086bSDamjan Jovanovic break; 23951ba086bSDamjan Jovanovic } 24051ba086bSDamjan Jovanovic if ( bAppendPort ) 24151ba086bSDamjan Jovanovic { 24251ba086bSDamjan Jovanovic aBuf.appendAscii( ":" ); 24351ba086bSDamjan Jovanovic aBuf.append( rtl::OUString::valueOf( aPort ) ); 24451ba086bSDamjan Jovanovic } 24551ba086bSDamjan Jovanovic aBuf.append( inPath ); 24651ba086bSDamjan Jovanovic 24751ba086bSDamjan Jovanovic rtl::OUString aUri(aBuf.makeStringAndClear() ); 24851ba086bSDamjan Jovanovic return aUri; 24951ba086bSDamjan Jovanovic } 25051ba086bSDamjan Jovanovic 25151ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 25251ba086bSDamjan Jovanovic // virtual 25351ba086bSDamjan Jovanovic sal_Bool CurlSession::CanUse( const rtl::OUString & inUri ) 25451ba086bSDamjan Jovanovic { 25551ba086bSDamjan Jovanovic try 25651ba086bSDamjan Jovanovic { 25751ba086bSDamjan Jovanovic CurlUri theUri( inUri ); 25851ba086bSDamjan Jovanovic if ( ( theUri.GetPort() == m_aUri.GetPort() ) && 25951ba086bSDamjan Jovanovic ( theUri.GetHost() == m_aUri.GetHost() ) && 26051ba086bSDamjan Jovanovic ( theUri.GetScheme() == m_aUri.GetScheme() ) ) 26151ba086bSDamjan Jovanovic { 26251ba086bSDamjan Jovanovic return sal_True; 26351ba086bSDamjan Jovanovic } 26451ba086bSDamjan Jovanovic } 26551ba086bSDamjan Jovanovic catch ( DAVException const & ) 26651ba086bSDamjan Jovanovic { 26751ba086bSDamjan Jovanovic return sal_False; 26851ba086bSDamjan Jovanovic } 26951ba086bSDamjan Jovanovic return sal_False; 27051ba086bSDamjan Jovanovic } 27151ba086bSDamjan Jovanovic 27251ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 27351ba086bSDamjan Jovanovic // virtual 27451ba086bSDamjan Jovanovic sal_Bool CurlSession::UsesProxy() 27551ba086bSDamjan Jovanovic { 27651ba086bSDamjan Jovanovic Init(); 27751ba086bSDamjan Jovanovic return ( m_aProxyName.getLength() > 0 ); 27851ba086bSDamjan Jovanovic } 27951ba086bSDamjan Jovanovic 28051ba086bSDamjan Jovanovic int CurlSession::Curl_DebugCallback( CURL *, curl_infotype type, unsigned char *data, size_t size, void* userdata ) 28151ba086bSDamjan Jovanovic { 28251ba086bSDamjan Jovanovic CurlSession *session = static_cast< CurlSession* >( userdata ); 28351ba086bSDamjan Jovanovic return session->curlDebugOutput( type, reinterpret_cast<char*>( data ), size ); 28451ba086bSDamjan Jovanovic } 28551ba086bSDamjan Jovanovic 28651ba086bSDamjan Jovanovic int CurlSession::curlDebugOutput( curl_infotype type, char *data, int size ) 28751ba086bSDamjan Jovanovic { 28851ba086bSDamjan Jovanovic const char *prefix; 28951ba086bSDamjan Jovanovic switch ( type ) 29051ba086bSDamjan Jovanovic { 29151ba086bSDamjan Jovanovic case CURLINFO_TEXT: 29251ba086bSDamjan Jovanovic prefix = "[CurlINFO ]"; 29351ba086bSDamjan Jovanovic break; 29451ba086bSDamjan Jovanovic case CURLINFO_HEADER_IN: 29551ba086bSDamjan Jovanovic prefix = "[CurlHDR <-]"; 29651ba086bSDamjan Jovanovic break; 29751ba086bSDamjan Jovanovic case CURLINFO_HEADER_OUT: 29851ba086bSDamjan Jovanovic prefix = "[CurlHDR ->]"; 29951ba086bSDamjan Jovanovic break; 30051ba086bSDamjan Jovanovic case CURLINFO_DATA_IN: 30151ba086bSDamjan Jovanovic prefix = "[CurlData<-]"; 30251ba086bSDamjan Jovanovic break; 30351ba086bSDamjan Jovanovic case CURLINFO_DATA_OUT: 30451ba086bSDamjan Jovanovic prefix = "[CurlData->]"; 30551ba086bSDamjan Jovanovic break; 30651ba086bSDamjan Jovanovic default: 30751ba086bSDamjan Jovanovic return 0; 30851ba086bSDamjan Jovanovic } 30951ba086bSDamjan Jovanovic 31051ba086bSDamjan Jovanovic // Trim the trailing \r\n 31151ba086bSDamjan Jovanovic if ( size >= 1 && ( data[size - 1] == '\r' || data[size - 1] == '\n' ) ) 31251ba086bSDamjan Jovanovic --size; 31351ba086bSDamjan Jovanovic if ( size >= 1 && ( data[size - 1] == '\r' || data[size - 1] == '\n' ) ) 31451ba086bSDamjan Jovanovic --size; 31551ba086bSDamjan Jovanovic rtl::OString message( data, size ); 31651ba086bSDamjan Jovanovic m_aLogger.log( LogLevel::FINEST, "$1$ $2$", prefix, message ); 31751ba086bSDamjan Jovanovic return 0; 31851ba086bSDamjan Jovanovic } 31951ba086bSDamjan Jovanovic 32051ba086bSDamjan Jovanovic CURLcode CurlSession::Curl_SSLContextCallback( CURL *, void *ssl_ctx, void *userptr ) 32151ba086bSDamjan Jovanovic { 32251ba086bSDamjan Jovanovic CurlSession *session = static_cast<CurlSession*>( userptr ); 32351ba086bSDamjan Jovanovic SSL_CTX *context = static_cast<SSL_CTX*>( ssl_ctx ); 32451ba086bSDamjan Jovanovic SSL_CTX_set_app_data( context, session ); 32551ba086bSDamjan Jovanovic SSL_CTX_set_verify( context, SSL_VERIFY_PEER, OPENSSL_ValidateServerCertificate ); 32651ba086bSDamjan Jovanovic return CURLE_OK; 32751ba086bSDamjan Jovanovic } 32851ba086bSDamjan Jovanovic 32951ba086bSDamjan Jovanovic int CurlSession::OPENSSL_ValidateServerCertificate( int preverify_ok, X509_STORE_CTX *x509_ctx ) 33051ba086bSDamjan Jovanovic { 33151ba086bSDamjan Jovanovic SSL *ssl = static_cast<SSL*> ( 33251ba086bSDamjan Jovanovic X509_STORE_CTX_get_ex_data( x509_ctx, SSL_get_ex_data_X509_STORE_CTX_idx() ) ); 33351ba086bSDamjan Jovanovic SSL_CTX *ssl_ctx = SSL_get_SSL_CTX( ssl ); 33451ba086bSDamjan Jovanovic CurlSession *session = static_cast<CurlSession*>( SSL_CTX_get_app_data( ssl_ctx ) ); 33551ba086bSDamjan Jovanovic int verifyOk = session->validateServerX509Certificate( x509_ctx, preverify_ok ); 33651ba086bSDamjan Jovanovic // When a certificate's verification fails within OpenSSL, yet passes from the 33751ba086bSDamjan Jovanovic // SSL_CTX_set_verify() callback (ie. this function) (by returning 1), 33851ba086bSDamjan Jovanovic // OpenSSL allows the connection to proceed, yet stores that last verification 33951ba086bSDamjan Jovanovic // error and allows it to be retrieved using SSL_get_verify_result(3). 34051ba086bSDamjan Jovanovic // 34151ba086bSDamjan Jovanovic // Unfortunately, Curl calls SSL_get_verify_result(3) internally, and treats 34251ba086bSDamjan Jovanovic // errors as terminal, disconnecting with an error even when we return 1 here. 34351ba086bSDamjan Jovanovic // Therefore, to approve a certificate that OpenSSL would reject, we have to 34451ba086bSDamjan Jovanovic // both return 1, and overwrite the X509_STORE_CTX's last error with X509_V_OK: 34551ba086bSDamjan Jovanovic if ( verifyOk ) 34651ba086bSDamjan Jovanovic X509_STORE_CTX_set_error( x509_ctx, X509_V_OK ); 34751ba086bSDamjan Jovanovic return verifyOk; 34851ba086bSDamjan Jovanovic } 34951ba086bSDamjan Jovanovic 35051ba086bSDamjan Jovanovic static uno::Sequence< sal_Int8 > convertCertificateToAsn1Der( X509 *certificate ) 35151ba086bSDamjan Jovanovic { 35251ba086bSDamjan Jovanovic uno::Sequence< sal_Int8 > asn1DerCertificate; 35351ba086bSDamjan Jovanovic int len = i2d_X509( certificate, NULL ); 35451ba086bSDamjan Jovanovic if ( len < 0 ) 35551ba086bSDamjan Jovanovic return asn1DerCertificate; 35651ba086bSDamjan Jovanovic asn1DerCertificate.realloc( len ); 35751ba086bSDamjan Jovanovic unsigned char *end = reinterpret_cast< unsigned char *>( asn1DerCertificate.getArray() ); 35851ba086bSDamjan Jovanovic len = i2d_X509( certificate, &end ); 35951ba086bSDamjan Jovanovic if ( len >= 0 ) 36051ba086bSDamjan Jovanovic return asn1DerCertificate; 36151ba086bSDamjan Jovanovic else 36251ba086bSDamjan Jovanovic return uno::Sequence< sal_Int8 >(); 36351ba086bSDamjan Jovanovic } 36451ba086bSDamjan Jovanovic 36551ba086bSDamjan Jovanovic int CurlSession::validateServerX509Certificate( X509_STORE_CTX *x509StoreContext, int verifyOk ) 36651ba086bSDamjan Jovanovic { 36751ba086bSDamjan Jovanovic X509 *serverCertificate = X509_STORE_CTX_get_current_cert( x509StoreContext ); 36851ba086bSDamjan Jovanovic int depth = X509_STORE_CTX_get_error_depth( x509StoreContext ); 36951ba086bSDamjan Jovanovic STACK_OF(X509) *chain = 37051ba086bSDamjan Jovanovic #if OPENSSL_VERSION_NUMBER >= 0x10100000L 37151ba086bSDamjan Jovanovic X509_STORE_CTX_get0_chain( x509StoreContext ); 37251ba086bSDamjan Jovanovic #else 37351ba086bSDamjan Jovanovic X509_STORE_CTX_get_chain( x509StoreContext ); 37451ba086bSDamjan Jovanovic #endif 37551ba086bSDamjan Jovanovic 37651ba086bSDamjan Jovanovic std::vector< uno::Sequence< sal_Int8 > > asn1DerCertificates; 37751ba086bSDamjan Jovanovic if ( chain != NULL ) { 37851ba086bSDamjan Jovanovic int nCertificates = sk_X509_num( chain ); 37951ba086bSDamjan Jovanovic for ( int i = 0; i < nCertificates; i++ ) { 38051ba086bSDamjan Jovanovic X509 *certificate = sk_X509_value( chain, i ); 38151ba086bSDamjan Jovanovic uno::Sequence< sal_Int8 > asn1DerCertificate = convertCertificateToAsn1Der( certificate ); 38251ba086bSDamjan Jovanovic if ( asn1DerCertificate.getLength() == 0 ) 38351ba086bSDamjan Jovanovic return 0; 38451ba086bSDamjan Jovanovic asn1DerCertificates.push_back( asn1DerCertificate ); 38551ba086bSDamjan Jovanovic } 38651ba086bSDamjan Jovanovic } else { 38751ba086bSDamjan Jovanovic uno::Sequence< sal_Int8 > asn1DerCertificate = convertCertificateToAsn1Der( serverCertificate ); 38851ba086bSDamjan Jovanovic if ( asn1DerCertificate.getLength() == 0 ) 38951ba086bSDamjan Jovanovic return 0; 39051ba086bSDamjan Jovanovic asn1DerCertificates.push_back( asn1DerCertificate ); 39151ba086bSDamjan Jovanovic } 39251ba086bSDamjan Jovanovic verifyOk = verifyCertificateChain( asn1DerCertificates ); 393*c464040aSDamjan Jovanovic 39451ba086bSDamjan Jovanovic m_aLogger.log( LogLevel::FINE, "validateServerX509Certificate() returning $1$ at depth $2$", 39551ba086bSDamjan Jovanovic (sal_Int32)verifyOk, (sal_Int32)depth ); 39651ba086bSDamjan Jovanovic return verifyOk; 39751ba086bSDamjan Jovanovic } 39851ba086bSDamjan Jovanovic 39951ba086bSDamjan Jovanovic int CurlSession::verifyCertificateChain ( 40051ba086bSDamjan Jovanovic std::vector< uno::Sequence< sal_Int8 > > &asn1DerCertificates ) 40151ba086bSDamjan Jovanovic { 40251ba086bSDamjan Jovanovic // Check arguments. 40351ba086bSDamjan Jovanovic if (asn1DerCertificates.size()<=0) 40451ba086bSDamjan Jovanovic { 40551ba086bSDamjan Jovanovic OSL_ASSERT(asn1DerCertificates.size()>0); 40651ba086bSDamjan Jovanovic return 0; 40751ba086bSDamjan Jovanovic } 40851ba086bSDamjan Jovanovic 40951ba086bSDamjan Jovanovic // Create some crypto objects to decode and handle the base64 41051ba086bSDamjan Jovanovic // encoded certificate chain. 41151ba086bSDamjan Jovanovic uno::Reference< xml::crypto::XSEInitializer > xSEInitializer; 41251ba086bSDamjan Jovanovic uno::Reference< security::XCertificateContainer > xCertificateContainer; 41351ba086bSDamjan Jovanovic uno::Reference< xml::crypto::XXMLSecurityContext > xSecurityContext; 41451ba086bSDamjan Jovanovic uno::Reference< xml::crypto::XSecurityEnvironment > xSecurityEnv; 41551ba086bSDamjan Jovanovic try 41651ba086bSDamjan Jovanovic { 41751ba086bSDamjan Jovanovic // Create a certificate container. 41851ba086bSDamjan Jovanovic xCertificateContainer = uno::Reference< security::XCertificateContainer >( 41951ba086bSDamjan Jovanovic getMSF()->createInstance( 42051ba086bSDamjan Jovanovic rtl::OUString::createFromAscii( 42151ba086bSDamjan Jovanovic "com.sun.star.security.CertificateContainer" ) ), 42251ba086bSDamjan Jovanovic uno::UNO_QUERY_THROW); 42351ba086bSDamjan Jovanovic 42451ba086bSDamjan Jovanovic xSEInitializer = uno::Reference< xml::crypto::XSEInitializer >( 42551ba086bSDamjan Jovanovic getMSF()->createInstance( 42651ba086bSDamjan Jovanovic rtl::OUString::createFromAscii( "com.sun.star.xml.crypto.SEInitializer" ) ), 42751ba086bSDamjan Jovanovic uno::UNO_QUERY_THROW); 42851ba086bSDamjan Jovanovic 42951ba086bSDamjan Jovanovic xSecurityContext = xSEInitializer->createSecurityContext( rtl::OUString() ); 43051ba086bSDamjan Jovanovic if (xSecurityContext.is()) 43151ba086bSDamjan Jovanovic xSecurityEnv = xSecurityContext->getSecurityEnvironment(); 43251ba086bSDamjan Jovanovic 43351ba086bSDamjan Jovanovic if ( ! xSecurityContext.is() || ! xSecurityEnv.is()) 43451ba086bSDamjan Jovanovic { 43551ba086bSDamjan Jovanovic // Do we have to dispose xSEInitializer or xCertificateContainer? 43651ba086bSDamjan Jovanovic m_aLogger.log( LogLevel::WARNING, "Failure creating security services for certificate verification" ); 43751ba086bSDamjan Jovanovic return 0; 43851ba086bSDamjan Jovanovic } 43951ba086bSDamjan Jovanovic } 44051ba086bSDamjan Jovanovic catch ( uno::Exception const &e) 44151ba086bSDamjan Jovanovic { 44251ba086bSDamjan Jovanovic m_aLogger.log( LogLevel::WARNING, "Error creating security services: $1$", e.Message ); 44351ba086bSDamjan Jovanovic return 0; 44451ba086bSDamjan Jovanovic } 44551ba086bSDamjan Jovanovic 44651ba086bSDamjan Jovanovic // Decode the server certificate. 44751ba086bSDamjan Jovanovic uno::Reference< security::XCertificate > xServerCertificate( 44851ba086bSDamjan Jovanovic xSecurityEnv->createCertificateFromRaw( asn1DerCertificates[0] ) ); 44951ba086bSDamjan Jovanovic if ( ! xServerCertificate.is()) 45051ba086bSDamjan Jovanovic { 45151ba086bSDamjan Jovanovic m_aLogger.log( LogLevel::WARNING, "Failed to create XCertificate" ); 45251ba086bSDamjan Jovanovic return 0; 45351ba086bSDamjan Jovanovic } 45451ba086bSDamjan Jovanovic 45551ba086bSDamjan Jovanovic // Get the subject from the server certificate. 45651ba086bSDamjan Jovanovic ::rtl::OUString sServerCertificateSubject (xServerCertificate->getSubjectName()); 45751ba086bSDamjan Jovanovic sal_Int32 nIndex = 0; 45851ba086bSDamjan Jovanovic while (nIndex >= 0) 45951ba086bSDamjan Jovanovic { 46051ba086bSDamjan Jovanovic const ::rtl::OUString sToken (sServerCertificateSubject.getToken(0, ',', nIndex)); 46151ba086bSDamjan Jovanovic if (sToken.compareToAscii("CN=", 3) == 0) 46251ba086bSDamjan Jovanovic { 46351ba086bSDamjan Jovanovic sServerCertificateSubject = sToken.copy(3); 46451ba086bSDamjan Jovanovic break; 46551ba086bSDamjan Jovanovic } 46651ba086bSDamjan Jovanovic else if (sToken.compareToAscii(" CN=", 4) == 0) 46751ba086bSDamjan Jovanovic { 46851ba086bSDamjan Jovanovic sServerCertificateSubject = sToken.copy(4); 46951ba086bSDamjan Jovanovic break; 47051ba086bSDamjan Jovanovic } 47151ba086bSDamjan Jovanovic } 47251ba086bSDamjan Jovanovic 47351ba086bSDamjan Jovanovic // When the certificate container already contains a (trusted) 47451ba086bSDamjan Jovanovic // entry for the server then we do not have to authenticate any 47551ba086bSDamjan Jovanovic // certificate. 47651ba086bSDamjan Jovanovic const security::CertificateContainerStatus eStatus ( 47751ba086bSDamjan Jovanovic xCertificateContainer->hasCertificate( 47851ba086bSDamjan Jovanovic getHostName(), sServerCertificateSubject ) ); 47951ba086bSDamjan Jovanovic if (eStatus != security::CertificateContainerStatus_NOCERT) 48051ba086bSDamjan Jovanovic { 48151ba086bSDamjan Jovanovic m_aLogger.log( LogLevel::FINER, "Cached certificate found with status=$1$", 48251ba086bSDamjan Jovanovic eStatus == security::CertificateContainerStatus_TRUSTED ? "trusted" : "untrusted" ); 48351ba086bSDamjan Jovanovic return eStatus == security::CertificateContainerStatus_TRUSTED 48451ba086bSDamjan Jovanovic ? 1 48551ba086bSDamjan Jovanovic : 0; 48651ba086bSDamjan Jovanovic } 48751ba086bSDamjan Jovanovic 48851ba086bSDamjan Jovanovic // The shortcut failed, so try to verify the whole chain. This is 48951ba086bSDamjan Jovanovic // done outside the isDomainMatch() block because the result is 49051ba086bSDamjan Jovanovic // used by the interaction handler. 49151ba086bSDamjan Jovanovic std::vector< uno::Reference< security::XCertificate > > aChain; 49251ba086bSDamjan Jovanovic for (nIndex=0; nIndex < asn1DerCertificates.size(); ++nIndex) 49351ba086bSDamjan Jovanovic { 49451ba086bSDamjan Jovanovic uno::Reference< security::XCertificate > xCertificate( 49551ba086bSDamjan Jovanovic xSecurityEnv->createCertificateFromRaw( asn1DerCertificates[ nIndex ] ) ); 49651ba086bSDamjan Jovanovic if ( ! xCertificate.is()) 49751ba086bSDamjan Jovanovic { 49851ba086bSDamjan Jovanovic m_aLogger.log( LogLevel::FINE, "Failed to create XCertificate $1$", nIndex ); 49951ba086bSDamjan Jovanovic return 0; 50051ba086bSDamjan Jovanovic } 50151ba086bSDamjan Jovanovic aChain.push_back(xCertificate); 50251ba086bSDamjan Jovanovic } 50351ba086bSDamjan Jovanovic const sal_Int64 nVerificationResult (xSecurityEnv->verifyCertificate( 50451ba086bSDamjan Jovanovic xServerCertificate, 50551ba086bSDamjan Jovanovic ::comphelper::containerToSequence(aChain))); 50651ba086bSDamjan Jovanovic 50751ba086bSDamjan Jovanovic // When the certificate matches the host name then we can use the 50851ba086bSDamjan Jovanovic // result of the verification. 50951ba086bSDamjan Jovanovic bool bHostnameMatchesCertHostnames = false; 51051ba086bSDamjan Jovanovic { 51151ba086bSDamjan Jovanovic uno::Sequence< uno::Reference< security::XCertificateExtension > > extensions = xServerCertificate->getExtensions(); 51251ba086bSDamjan Jovanovic uno::Sequence< security::CertAltNameEntry > altNames; 51351ba086bSDamjan Jovanovic for (sal_Int32 i = 0 ; i < extensions.getLength(); ++i) 51451ba086bSDamjan Jovanovic { 51551ba086bSDamjan Jovanovic uno::Reference< security::XCertificateExtension >element = extensions[i]; 51651ba086bSDamjan Jovanovic 51751ba086bSDamjan Jovanovic const rtl::OString aId ( (const sal_Char *)element->getExtensionId().getArray(), element->getExtensionId().getLength()); 51851ba086bSDamjan Jovanovic if ( aId.equals( OID_SUBJECT_ALTERNATIVE_NAME ) ) 51951ba086bSDamjan Jovanovic { 52051ba086bSDamjan Jovanovic uno::Reference< security::XSanExtension > sanExtension ( element, uno::UNO_QUERY ); 52151ba086bSDamjan Jovanovic altNames = sanExtension->getAlternativeNames(); 52251ba086bSDamjan Jovanovic break; 52351ba086bSDamjan Jovanovic } 52451ba086bSDamjan Jovanovic } 52551ba086bSDamjan Jovanovic 52651ba086bSDamjan Jovanovic uno::Sequence< ::rtl::OUString > certHostNames(altNames.getLength() + 1); 52751ba086bSDamjan Jovanovic certHostNames[0] = sServerCertificateSubject; 52851ba086bSDamjan Jovanovic for( int n = 0; n < altNames.getLength(); ++n ) 52951ba086bSDamjan Jovanovic { 53051ba086bSDamjan Jovanovic if (altNames[n].Type == security::ExtAltNameType_DNS_NAME) 53151ba086bSDamjan Jovanovic { 53251ba086bSDamjan Jovanovic altNames[n].Value >>= certHostNames[n+1]; 53351ba086bSDamjan Jovanovic } 53451ba086bSDamjan Jovanovic } 53551ba086bSDamjan Jovanovic 53651ba086bSDamjan Jovanovic for ( int i = 0; i < certHostNames.getLength() && !bHostnameMatchesCertHostnames; ++i ) 53751ba086bSDamjan Jovanovic { 53851ba086bSDamjan Jovanovic bHostnameMatchesCertHostnames = isDomainMatch( certHostNames[i] ); 53951ba086bSDamjan Jovanovic } 54051ba086bSDamjan Jovanovic 54151ba086bSDamjan Jovanovic } 54251ba086bSDamjan Jovanovic m_aLogger.log( LogLevel::FINE, "URL hostname $1$ certificate hostname", 54351ba086bSDamjan Jovanovic bHostnameMatchesCertHostnames ? "matches" : "DOESN'T MATCH" ); 54451ba086bSDamjan Jovanovic if ( bHostnameMatchesCertHostnames ) 54551ba086bSDamjan Jovanovic { 54651ba086bSDamjan Jovanovic if (nVerificationResult == 0) 54751ba086bSDamjan Jovanovic { 54851ba086bSDamjan Jovanovic m_aLogger.log( LogLevel::FINE, "Certificate (chain) is valid" ); 54951ba086bSDamjan Jovanovic xCertificateContainer->addCertificate(getHostName(), sServerCertificateSubject, sal_True); 55051ba086bSDamjan Jovanovic return 1; 55151ba086bSDamjan Jovanovic } 55251ba086bSDamjan Jovanovic else if ((nVerificationResult & security::CertificateValidity::CHAIN_INCOMPLETE) != 0) 55351ba086bSDamjan Jovanovic { 55451ba086bSDamjan Jovanovic // We do not have enough information for verification, 55551ba086bSDamjan Jovanovic // neither automatically (as we just discovered) nor 55651ba086bSDamjan Jovanovic // manually (so there is no point in showing any dialog.) 55751ba086bSDamjan Jovanovic m_aLogger.log( LogLevel::WARNING, "Certificate (chain) is incomplete" ); 55851ba086bSDamjan Jovanovic return 0; 55951ba086bSDamjan Jovanovic } 56051ba086bSDamjan Jovanovic else if ((nVerificationResult & security::CertificateValidity::REVOKED) != 0) 56151ba086bSDamjan Jovanovic { 56251ba086bSDamjan Jovanovic // Certificate (chain) is invalid. 56351ba086bSDamjan Jovanovic m_aLogger.log( LogLevel::WARNING, "Certificate (chain) is revoked" ); 56451ba086bSDamjan Jovanovic xCertificateContainer->addCertificate(getHostName(), sServerCertificateSubject, sal_False); 56551ba086bSDamjan Jovanovic return 0; 56651ba086bSDamjan Jovanovic } 56751ba086bSDamjan Jovanovic else 56851ba086bSDamjan Jovanovic { 56951ba086bSDamjan Jovanovic // For all other we have to ask the user. 57051ba086bSDamjan Jovanovic m_aLogger.log( LogLevel::FINE, "Promping user to validate the certificate" ); 57151ba086bSDamjan Jovanovic } 57251ba086bSDamjan Jovanovic } 57351ba086bSDamjan Jovanovic 57451ba086bSDamjan Jovanovic // We have not been able to automatically verify (or falsify) the 57551ba086bSDamjan Jovanovic // certificate chain. To resolve this we have to ask the user. 57651ba086bSDamjan Jovanovic const uno::Reference< ucb::XCommandEnvironment > xEnv( getRequestEnvironment().m_xEnv ); 57751ba086bSDamjan Jovanovic if ( xEnv.is() ) 57851ba086bSDamjan Jovanovic { 57951ba086bSDamjan Jovanovic uno::Reference< task::XInteractionHandler > xIH( xEnv->getInteractionHandler() ); 58051ba086bSDamjan Jovanovic if ( xIH.is() ) 58151ba086bSDamjan Jovanovic { 58251ba086bSDamjan Jovanovic rtl::Reference< ucbhelper::SimpleCertificateValidationRequest > 58351ba086bSDamjan Jovanovic xRequest( new ucbhelper::SimpleCertificateValidationRequest( 58451ba086bSDamjan Jovanovic static_cast<sal_Int32>(nVerificationResult), xServerCertificate, getHostName() ) ); 58551ba086bSDamjan Jovanovic xIH->handle( xRequest.get() ); 58651ba086bSDamjan Jovanovic 58751ba086bSDamjan Jovanovic rtl::Reference< ucbhelper::InteractionContinuation > xSelection 58851ba086bSDamjan Jovanovic = xRequest->getSelection(); 58951ba086bSDamjan Jovanovic 59051ba086bSDamjan Jovanovic if ( xSelection.is() ) 59151ba086bSDamjan Jovanovic { 59251ba086bSDamjan Jovanovic uno::Reference< task::XInteractionApprove > xApprove( xSelection.get(), uno::UNO_QUERY ); 59351ba086bSDamjan Jovanovic if ( xApprove.is() ) 59451ba086bSDamjan Jovanovic { 59551ba086bSDamjan Jovanovic m_aLogger.log( LogLevel::FINE, "The user approved the certificate" ); 59651ba086bSDamjan Jovanovic xCertificateContainer->addCertificate( getHostName(), sServerCertificateSubject, sal_True ); 59751ba086bSDamjan Jovanovic return 1; 59851ba086bSDamjan Jovanovic } 59951ba086bSDamjan Jovanovic else 60051ba086bSDamjan Jovanovic { 60151ba086bSDamjan Jovanovic // Don't trust cert 60251ba086bSDamjan Jovanovic m_aLogger.log( LogLevel::FINE, "The user REJECTED the certificate" ); 60351ba086bSDamjan Jovanovic xCertificateContainer->addCertificate( getHostName(), sServerCertificateSubject, sal_False ); 60451ba086bSDamjan Jovanovic return 0; 60551ba086bSDamjan Jovanovic } 60651ba086bSDamjan Jovanovic } 60751ba086bSDamjan Jovanovic } 60851ba086bSDamjan Jovanovic else 60951ba086bSDamjan Jovanovic { 61051ba086bSDamjan Jovanovic // Don't trust cert 61151ba086bSDamjan Jovanovic m_aLogger.log( LogLevel::WARNING, "Couldn't create the interaction handler for user feedback, rejecting the certificate" ); 61251ba086bSDamjan Jovanovic xCertificateContainer->addCertificate( getHostName(), sServerCertificateSubject, sal_False ); 61351ba086bSDamjan Jovanovic return 0; 61451ba086bSDamjan Jovanovic } 61551ba086bSDamjan Jovanovic } 61651ba086bSDamjan Jovanovic m_aLogger.log( LogLevel::WARNING, "No XCommandEnvironment, rejecting the certificate" ); 61751ba086bSDamjan Jovanovic 61851ba086bSDamjan Jovanovic return 0; 61951ba086bSDamjan Jovanovic } 62051ba086bSDamjan Jovanovic 62151ba086bSDamjan Jovanovic bool CurlSession::Curl_ProvideCredentials( long statusCode, void *userdata ) throw (DAVException) 62251ba086bSDamjan Jovanovic { 62351ba086bSDamjan Jovanovic CredentialsData *credentialsData = (CredentialsData*)userdata; 62451ba086bSDamjan Jovanovic return credentialsData->session->provideCredentials( credentialsData->env, credentialsData->request, statusCode ); 62551ba086bSDamjan Jovanovic } 62651ba086bSDamjan Jovanovic 62751ba086bSDamjan Jovanovic bool CurlSession::provideCredentials( const DAVRequestEnvironment &env, CurlRequest &request, long statusCode ) throw (DAVException) 62851ba086bSDamjan Jovanovic { 62951ba086bSDamjan Jovanovic DAVAuthListener * pListener = env.m_xAuthListener.get(); 63051ba086bSDamjan Jovanovic if ( !pListener ) 63151ba086bSDamjan Jovanovic { 63251ba086bSDamjan Jovanovic // abort 63351ba086bSDamjan Jovanovic m_aLogger.log( LogLevel::FINE, "No DAVAuthListener found, failing credentials entry" ); 63451ba086bSDamjan Jovanovic return false; 63551ba086bSDamjan Jovanovic } 63651ba086bSDamjan Jovanovic 63751ba086bSDamjan Jovanovic rtl::OUString theUserName; 63851ba086bSDamjan Jovanovic rtl::OUString thePassWord; 63951ba086bSDamjan Jovanovic try 64051ba086bSDamjan Jovanovic { 64151ba086bSDamjan Jovanovic CurlUri uri( env.m_aRequestURI ); 64251ba086bSDamjan Jovanovic theUserName = uri.GetUserName(); 64351ba086bSDamjan Jovanovic thePassWord = uri.GetPassword(); 64451ba086bSDamjan Jovanovic } 64551ba086bSDamjan Jovanovic catch ( DAVException const &e ) 64651ba086bSDamjan Jovanovic { 64751ba086bSDamjan Jovanovic // abort 64851ba086bSDamjan Jovanovic m_aLogger.log( 64951ba086bSDamjan Jovanovic LogLevel::WARNING, 65051ba086bSDamjan Jovanovic "Error extracing userinfo from URI: exceptionCode=$1$, status=$2$, data=$3$, owner=$4$, extendedError=$5%", 65151ba086bSDamjan Jovanovic (sal_Int32)e.getError(), e.getStatus(), e.getData(), e.getOwner(), e.getExtendedError() 65251ba086bSDamjan Jovanovic ); 65351ba086bSDamjan Jovanovic return false; 65451ba086bSDamjan Jovanovic } 65551ba086bSDamjan Jovanovic 65651ba086bSDamjan Jovanovic bool canUseSystemCreds = false; 65751ba086bSDamjan Jovanovic long authMethods = 0; 65851ba086bSDamjan Jovanovic CURLcode rc = CURLE_OK; 65951ba086bSDamjan Jovanovic if ( statusCode == 401 ) 66051ba086bSDamjan Jovanovic rc = curl_easy_getinfo( m_pCurl, CURLINFO_HTTPAUTH_AVAIL, &authMethods ); 66151ba086bSDamjan Jovanovic else if ( statusCode == 407 ) 66251ba086bSDamjan Jovanovic rc = curl_easy_getinfo( m_pCurl, CURLINFO_PROXYAUTH_AVAIL, &authMethods ); 66351ba086bSDamjan Jovanovic if ( rc == 0 ) 66451ba086bSDamjan Jovanovic canUseSystemCreds = (authMethods & CURLAUTH_NEGOTIATE) || (authMethods & CURLAUTH_NTLM); 66551ba086bSDamjan Jovanovic m_aLogger.log( LogLevel::FINE, "authMethods=$1$, canUseSystemCreds=$2$", 66651ba086bSDamjan Jovanovic (sal_Int64)authMethods, (sal_Int32)canUseSystemCreds ); 66751ba086bSDamjan Jovanovic 66851ba086bSDamjan Jovanovic const CurlRequest::Header *authHeader = NULL; 66951ba086bSDamjan Jovanovic if ( statusCode == 401 ) 67051ba086bSDamjan Jovanovic authHeader = request.findResponseHeader( "WWW-Authenticate" ); 67151ba086bSDamjan Jovanovic else if ( statusCode == 407 ) 67251ba086bSDamjan Jovanovic authHeader = request.findResponseHeader( "Proxy-Authenticate" ); 67351ba086bSDamjan Jovanovic rtl::OUString realm; 67451ba086bSDamjan Jovanovic if ( authHeader != NULL ) 67551ba086bSDamjan Jovanovic { 67651ba086bSDamjan Jovanovic int realmStart = authHeader->value.indexOf( "realm=\"" ); 67751ba086bSDamjan Jovanovic if ( realmStart >= 0 ) 67851ba086bSDamjan Jovanovic { 67951ba086bSDamjan Jovanovic realmStart += 7; 68051ba086bSDamjan Jovanovic int realmEnd = authHeader->value.indexOf( "\"", realmStart ); 68151ba086bSDamjan Jovanovic if ( realmEnd > 0 ) 68251ba086bSDamjan Jovanovic realm = rtl::OStringToOUString( authHeader->value.copy( realmStart, realmEnd - realmStart ), RTL_TEXTENCODING_UTF8 ); 68351ba086bSDamjan Jovanovic } 68451ba086bSDamjan Jovanovic } 68551ba086bSDamjan Jovanovic 68651ba086bSDamjan Jovanovic int theRetVal = pListener->authenticate( realm, 68751ba086bSDamjan Jovanovic getHostName(), 68851ba086bSDamjan Jovanovic theUserName, 68951ba086bSDamjan Jovanovic thePassWord, 69051ba086bSDamjan Jovanovic canUseSystemCreds, 69151ba086bSDamjan Jovanovic // Authenticating with both the proxy 69251ba086bSDamjan Jovanovic // and the destination server requires sal_True here, 69351ba086bSDamjan Jovanovic // and needs filling out 2 x password dialogs. 69451ba086bSDamjan Jovanovic sal_True ); 69551ba086bSDamjan Jovanovic 69651ba086bSDamjan Jovanovic if ( theRetVal == 0 ) 69751ba086bSDamjan Jovanovic { 69851ba086bSDamjan Jovanovic m_aLogger.log( LogLevel::FINEST, "got credentials for user=$1$ on realm=$2$", theUserName, realm ); 69951ba086bSDamjan Jovanovic // "System credentials" means username and password are empty 70051ba086bSDamjan Jovanovic const char *curlUsername = NULL; 70151ba086bSDamjan Jovanovic const char *curlPassword = NULL; 70251ba086bSDamjan Jovanovic if ( !theUserName.isEmpty() ) 70351ba086bSDamjan Jovanovic curlUsername = rtl::OUStringToOString( theUserName, RTL_TEXTENCODING_UTF8 ).getStr(); 70451ba086bSDamjan Jovanovic if ( !thePassWord.isEmpty() ) 70551ba086bSDamjan Jovanovic curlPassword = rtl::OUStringToOString( thePassWord, RTL_TEXTENCODING_UTF8 ).getStr(); 70651ba086bSDamjan Jovanovic if ( statusCode == 401 ) 70751ba086bSDamjan Jovanovic { 70851ba086bSDamjan Jovanovic curl_easy_setopt( m_pCurl, CURLOPT_USERNAME, curlUsername ); 70951ba086bSDamjan Jovanovic curl_easy_setopt( m_pCurl, CURLOPT_PASSWORD, curlPassword ); 71051ba086bSDamjan Jovanovic } 71151ba086bSDamjan Jovanovic else 71251ba086bSDamjan Jovanovic { 71351ba086bSDamjan Jovanovic curl_easy_setopt( m_pCurl, CURLOPT_PROXYUSERNAME, curlUsername ); 71451ba086bSDamjan Jovanovic curl_easy_setopt( m_pCurl, CURLOPT_PROXYPASSWORD, curlPassword ); 71551ba086bSDamjan Jovanovic } 71651ba086bSDamjan Jovanovic return true; 71751ba086bSDamjan Jovanovic } 71851ba086bSDamjan Jovanovic m_aLogger.log( LogLevel::WARNING, "credentials entry cancelled or failed" ); 71951ba086bSDamjan Jovanovic 72051ba086bSDamjan Jovanovic return false; 72151ba086bSDamjan Jovanovic } 72251ba086bSDamjan Jovanovic 72351ba086bSDamjan Jovanovic void CurlSession::addEnvironmentRequestHeaders( CurlRequest &curlRequest, const DAVRequestEnvironment &env ) 72451ba086bSDamjan Jovanovic throw ( DAVException ) 72551ba086bSDamjan Jovanovic { 72651ba086bSDamjan Jovanovic bool bHasUserAgent( false ); 72751ba086bSDamjan Jovanovic DAVRequestHeaders::const_iterator aHeaderIter( env.m_aRequestHeaders.begin() ); 72851ba086bSDamjan Jovanovic const DAVRequestHeaders::const_iterator aEnd( env.m_aRequestHeaders.end() ); 72951ba086bSDamjan Jovanovic 73051ba086bSDamjan Jovanovic while ( aHeaderIter != aEnd ) 73151ba086bSDamjan Jovanovic { 73251ba086bSDamjan Jovanovic const rtl::OString aHeader = rtl::OUStringToOString( aHeaderIter->first, 73351ba086bSDamjan Jovanovic RTL_TEXTENCODING_UTF8 ); 73451ba086bSDamjan Jovanovic const rtl::OString aValue = rtl::OUStringToOString( aHeaderIter->second, 73551ba086bSDamjan Jovanovic RTL_TEXTENCODING_UTF8 ); 73651ba086bSDamjan Jovanovic 73751ba086bSDamjan Jovanovic if ( !bHasUserAgent ) 73851ba086bSDamjan Jovanovic bHasUserAgent = aHeaderIter->first.equalsAsciiL( 73951ba086bSDamjan Jovanovic RTL_CONSTASCII_STRINGPARAM( "User-Agent" ) ); 74051ba086bSDamjan Jovanovic 74151ba086bSDamjan Jovanovic curlRequest.addHeader( aHeader, aValue ); 74251ba086bSDamjan Jovanovic 74351ba086bSDamjan Jovanovic ++aHeaderIter; 74451ba086bSDamjan Jovanovic } 74551ba086bSDamjan Jovanovic 74651ba086bSDamjan Jovanovic if ( !bHasUserAgent ) 74751ba086bSDamjan Jovanovic { 74851ba086bSDamjan Jovanovic const rtl::OUString &rUserAgent = WebDAVUserAgent::get(); 74951ba086bSDamjan Jovanovic curlRequest.addHeader( "User-Agent", rtl::OUStringToOString( rUserAgent, RTL_TEXTENCODING_UTF8 ) ); 75051ba086bSDamjan Jovanovic } 75151ba086bSDamjan Jovanovic } 75251ba086bSDamjan Jovanovic 75351ba086bSDamjan Jovanovic void CurlSession::processResponse( CurlRequest &curlRequest, CURLcode curlCode ) 75451ba086bSDamjan Jovanovic throw( DAVException ) 75551ba086bSDamjan Jovanovic { 75651ba086bSDamjan Jovanovic long statusCode = 0; 75751ba086bSDamjan Jovanovic CURLcode curlRes; 75851ba086bSDamjan Jovanovic curlRes = curl_easy_getinfo( m_pCurl, CURLINFO_RESPONSE_CODE, &statusCode ); 75951ba086bSDamjan Jovanovic if ( curlRes != 0 || statusCode == 0 ) 76051ba086bSDamjan Jovanovic statusCode = curlRequest.getStatusCode(); 76151ba086bSDamjan Jovanovic 76251ba086bSDamjan Jovanovic // check header according: 76351ba086bSDamjan Jovanovic // http://tools.ietf.org/html/rfc7231#section-7.4.2 76451ba086bSDamjan Jovanovic // need to do this so we can adjust the protocol accordingly 76551ba086bSDamjan Jovanovic const CurlRequest::Header *server = curlRequest.findResponseHeader( "server" ); 76651ba086bSDamjan Jovanovic if ( server != NULL ) 76751ba086bSDamjan Jovanovic m_aServerHeaderField = server->value; 76851ba086bSDamjan Jovanovic 76951ba086bSDamjan Jovanovic if ( curlCode != 0 ) 77051ba086bSDamjan Jovanovic { 77151ba086bSDamjan Jovanovic m_aLogger.log( LogLevel::WARNING, "Curl request failed with CURLcode $1$", (sal_Int64)curlCode ); 772b9e06544SArrigo Marchiori DAVException::ExceptionCode exCode = DAVException::DAV_HTTP_ERROR; 773b9e06544SArrigo Marchiori rtl::OUString exData; 774b9e06544SArrigo Marchiori switch (curlCode) { 775b9e06544SArrigo Marchiori case CURLE_COULDNT_RESOLVE_HOST: 776b9e06544SArrigo Marchiori exCode = DAVException::DAV_HTTP_LOOKUP; 777b9e06544SArrigo Marchiori exData = CurlUri::makeConnectionEndPointString( getHostName(), 778b9e06544SArrigo Marchiori getPort() ); 779b9e06544SArrigo Marchiori break; 780b9e06544SArrigo Marchiori case CURLE_COULDNT_CONNECT: 781b9e06544SArrigo Marchiori exCode = DAVException::DAV_HTTP_CONNECT; 782b9e06544SArrigo Marchiori exData = CurlUri::makeConnectionEndPointString( getHostName(), 783b9e06544SArrigo Marchiori getPort() ); 784b9e06544SArrigo Marchiori break; 785b9e06544SArrigo Marchiori case CURLE_OPERATION_TIMEDOUT: 786b9e06544SArrigo Marchiori exCode = DAVException::DAV_HTTP_TIMEOUT; 787b9e06544SArrigo Marchiori exData = CurlUri::makeConnectionEndPointString( getHostName(), 788b9e06544SArrigo Marchiori getPort() ); 789b9e06544SArrigo Marchiori break; 790b9e06544SArrigo Marchiori case CURLE_LOGIN_DENIED: 791b9e06544SArrigo Marchiori case CURLE_AUTH_ERROR: 792b9e06544SArrigo Marchiori exCode = DAVException::DAV_HTTP_AUTH; 793b9e06544SArrigo Marchiori exData = CurlUri::makeConnectionEndPointString( getHostName(), 794b9e06544SArrigo Marchiori getPort() ); 795b9e06544SArrigo Marchiori break; 796b9e06544SArrigo Marchiori default: 797b9e06544SArrigo Marchiori { 798b9e06544SArrigo Marchiori const char *s = curl_easy_strerror(curlCode); 799b9e06544SArrigo Marchiori exCode = DAVException::DAV_HTTP_ERROR; 800b9e06544SArrigo Marchiori exData = ::rtl::OUString(s, strlen(s), 801b9e06544SArrigo Marchiori RTL_TEXTENCODING_UTF8); 802b9e06544SArrigo Marchiori break; 803b9e06544SArrigo Marchiori } 804b9e06544SArrigo Marchiori } 805b9e06544SArrigo Marchiori throw DAVException( exCode, exData ); 80651ba086bSDamjan Jovanovic } 80751ba086bSDamjan Jovanovic 80851ba086bSDamjan Jovanovic rtl::OUString reasonPhrase = rtl::OStringToOUString( curlRequest.getReasonPhrase(), RTL_TEXTENCODING_UTF8 ); 80951ba086bSDamjan Jovanovic if ( statusCode != 0 && statusCode / 100 != 2 ) 81051ba086bSDamjan Jovanovic { 81151ba086bSDamjan Jovanovic switch (statusCode) 81251ba086bSDamjan Jovanovic { 81351ba086bSDamjan Jovanovic case SC_MOVED_PERMANENTLY: // 301 81451ba086bSDamjan Jovanovic case SC_MOVED_TEMPORARILY: // 302 81551ba086bSDamjan Jovanovic case SC_SEE_OTHER: // 303 81651ba086bSDamjan Jovanovic case SC_TEMPORARY_REDIRECT: // 307 81751ba086bSDamjan Jovanovic { 81851ba086bSDamjan Jovanovic // new location for certain redirections 81951ba086bSDamjan Jovanovic 82051ba086bSDamjan Jovanovic const CurlRequest::Header *location = curlRequest.findResponseHeader( "location" ); 82151ba086bSDamjan Jovanovic if ( location != NULL ) 82251ba086bSDamjan Jovanovic { 82351ba086bSDamjan Jovanovic m_aLogger.log( LogLevel::FINE, "HTTP $1$ response with new location = $2$", 82451ba086bSDamjan Jovanovic statusCode, location->value ); 82551ba086bSDamjan Jovanovic throw DAVException( DAVException::DAV_HTTP_REDIRECT, 82651ba086bSDamjan Jovanovic rtl::OStringToOUString( location->value, RTL_TEXTENCODING_UTF8 ) ); 82751ba086bSDamjan Jovanovic } 82851ba086bSDamjan Jovanovic break; 82951ba086bSDamjan Jovanovic } 83051ba086bSDamjan Jovanovic case SC_UNAUTHORIZED: // 401 83151ba086bSDamjan Jovanovic case SC_PROXY_AUTHENTICATION_REQUIRED: // 407 83251ba086bSDamjan Jovanovic { 83351ba086bSDamjan Jovanovic throw DAVException( DAVException::DAV_HTTP_ERROR, 83451ba086bSDamjan Jovanovic reasonPhrase, 83551ba086bSDamjan Jovanovic statusCode ); 83651ba086bSDamjan Jovanovic break; 83751ba086bSDamjan Jovanovic } 83851ba086bSDamjan Jovanovic case SC_REQUEST_ENTITY_TOO_LARGE: // 413 83951ba086bSDamjan Jovanovic { 84051ba086bSDamjan Jovanovic if ( m_bTransferEncodingSwitched ) 84151ba086bSDamjan Jovanovic throw DAVException( DAVException::DAV_HTTP_ERROR, 84251ba086bSDamjan Jovanovic reasonPhrase, 84351ba086bSDamjan Jovanovic statusCode ); 84451ba086bSDamjan Jovanovic m_bTransferEncodingSwitched = true; 84551ba086bSDamjan Jovanovic curlRequest.setChunkedEncoding( !curlRequest.isChunkedEncoding() ); 84651ba086bSDamjan Jovanovic break; 84751ba086bSDamjan Jovanovic } 84851ba086bSDamjan Jovanovic case SC_LOCKED: // 423 84951ba086bSDamjan Jovanovic throw DAVException( DAVException::DAV_LOCKED, 85051ba086bSDamjan Jovanovic reasonPhrase, 85151ba086bSDamjan Jovanovic statusCode ); 85251ba086bSDamjan Jovanovic default: 85351ba086bSDamjan Jovanovic throw DAVException( DAVException::DAV_HTTP_ERROR, 85451ba086bSDamjan Jovanovic reasonPhrase, 85551ba086bSDamjan Jovanovic statusCode ); 85651ba086bSDamjan Jovanovic } 85751ba086bSDamjan Jovanovic } 85851ba086bSDamjan Jovanovic } 85951ba086bSDamjan Jovanovic 86051ba086bSDamjan Jovanovic static void responseHeadersToDAVResource( const std::vector< CurlRequest::Header> &responseHeaders, 86151ba086bSDamjan Jovanovic const std::vector< ::rtl::OUString > &inHeaderNames, 86251ba086bSDamjan Jovanovic DAVResource &ioResource ) 86351ba086bSDamjan Jovanovic { 86451ba086bSDamjan Jovanovic std::vector< CurlRequest::Header >::const_iterator it( responseHeaders.begin() ); 86551ba086bSDamjan Jovanovic const std::vector< CurlRequest::Header >::const_iterator end( responseHeaders.end() ); 86651ba086bSDamjan Jovanovic while ( it != end ) 86751ba086bSDamjan Jovanovic { 86851ba086bSDamjan Jovanovic bool storeHeader = false; 86951ba086bSDamjan Jovanovic if ( inHeaderNames.size() == 0 ) 87051ba086bSDamjan Jovanovic storeHeader = true; 87151ba086bSDamjan Jovanovic else 87251ba086bSDamjan Jovanovic { 87351ba086bSDamjan Jovanovic std::vector< ::rtl::OUString >::const_iterator reqIt( inHeaderNames.begin() ); 87451ba086bSDamjan Jovanovic const std::vector< ::rtl::OUString >::const_iterator reqEnd( inHeaderNames.end() ); 87551ba086bSDamjan Jovanovic while ( reqIt != reqEnd ) 87651ba086bSDamjan Jovanovic { 87751ba086bSDamjan Jovanovic // header names are case insensitive 87851ba086bSDamjan Jovanovic if ( (*reqIt).equalsIgnoreAsciiCase( rtl::OStringToOUString( (*it).name, RTL_TEXTENCODING_UTF8 ) ) ) 87951ba086bSDamjan Jovanovic { 88051ba086bSDamjan Jovanovic storeHeader = true; 88151ba086bSDamjan Jovanovic break; 88251ba086bSDamjan Jovanovic } 88351ba086bSDamjan Jovanovic else 88451ba086bSDamjan Jovanovic { 88551ba086bSDamjan Jovanovic ++reqIt; 88651ba086bSDamjan Jovanovic } 88751ba086bSDamjan Jovanovic } 88851ba086bSDamjan Jovanovic } 88951ba086bSDamjan Jovanovic 89051ba086bSDamjan Jovanovic if ( storeHeader ) 89151ba086bSDamjan Jovanovic { 89251ba086bSDamjan Jovanovic DAVPropertyValue thePropertyValue; 89351ba086bSDamjan Jovanovic thePropertyValue.IsCaseSensitive = false; 89451ba086bSDamjan Jovanovic thePropertyValue.Name = rtl::OStringToOUString( (*it).name, RTL_TEXTENCODING_UTF8 ); 89551ba086bSDamjan Jovanovic thePropertyValue.Value <<= rtl::OStringToOUString( (*it).value, RTL_TEXTENCODING_UTF8 ); 89651ba086bSDamjan Jovanovic ioResource.properties.push_back( thePropertyValue ); 89751ba086bSDamjan Jovanovic } 89851ba086bSDamjan Jovanovic 89951ba086bSDamjan Jovanovic it++; 90051ba086bSDamjan Jovanovic } 90151ba086bSDamjan Jovanovic } 90251ba086bSDamjan Jovanovic 90351ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 90451ba086bSDamjan Jovanovic // PROPFIND - allprop & named 90551ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 90651ba086bSDamjan Jovanovic 90751ba086bSDamjan Jovanovic void CurlSession::propfind( CurlRequest &curlRequest, 90851ba086bSDamjan Jovanovic const rtl::OUString &inPath, 90951ba086bSDamjan Jovanovic const Depth inDepth, 91051ba086bSDamjan Jovanovic const std::vector< ::rtl::OUString > * inPropNames, 91151ba086bSDamjan Jovanovic const bool onlyPropertyNames, 91251ba086bSDamjan Jovanovic const DAVRequestEnvironment & rEnv ) 91351ba086bSDamjan Jovanovic { 91451ba086bSDamjan Jovanovic addEnvironmentRequestHeaders( curlRequest, rEnv ); 91551ba086bSDamjan Jovanovic 91651ba086bSDamjan Jovanovic if ( inDepth == DAVZERO ) 91751ba086bSDamjan Jovanovic curlRequest.addHeader( "Depth", "0" ); 91851ba086bSDamjan Jovanovic else if ( inDepth == DAVONE ) 91951ba086bSDamjan Jovanovic curlRequest.addHeader( "Depth", "1" ); 92051ba086bSDamjan Jovanovic else if ( inDepth == DAVINFINITY ) 92151ba086bSDamjan Jovanovic curlRequest.addHeader( "Depth", "infinity" ); 92251ba086bSDamjan Jovanovic 92351ba086bSDamjan Jovanovic rtl::OString xml = PropfindRequest::generatePROPFINDRequestBody( inPropNames, onlyPropertyNames ); 92451ba086bSDamjan Jovanovic if ( xml.getLength() > 0 ) 92551ba086bSDamjan Jovanovic { 92651ba086bSDamjan Jovanovic curlRequest.addHeader( "Content-Type", "application/xml" ); 92751ba086bSDamjan Jovanovic curlRequest.setRequestBody( xml.getStr(), xml.getLength() ); 92851ba086bSDamjan Jovanovic } 92951ba086bSDamjan Jovanovic 93051ba086bSDamjan Jovanovic CredentialsData credsData( this, curlRequest, rEnv ); 93151ba086bSDamjan Jovanovic curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData ); 93251ba086bSDamjan Jovanovic 93351ba086bSDamjan Jovanovic CURLcode rc = curlRequest.propfind( m_aUri, inPath ); 93451ba086bSDamjan Jovanovic processResponse( curlRequest, rc ); 93551ba086bSDamjan Jovanovic } 93651ba086bSDamjan Jovanovic 93751ba086bSDamjan Jovanovic void CurlSession::PROPFIND( const rtl::OUString & inPath, 93851ba086bSDamjan Jovanovic const Depth inDepth, 93951ba086bSDamjan Jovanovic const std::vector< rtl::OUString > & inPropNames, 94051ba086bSDamjan Jovanovic std::vector< DAVResource > & ioResources, 94151ba086bSDamjan Jovanovic const DAVRequestEnvironment & rEnv ) 94251ba086bSDamjan Jovanovic throw ( DAVException ) 94351ba086bSDamjan Jovanovic { 94451ba086bSDamjan Jovanovic m_aLogger.log( LogLevel::INFO, "PROPFIND line $1$", (sal_Int32)__LINE__ ); 94551ba086bSDamjan Jovanovic 94651ba086bSDamjan Jovanovic osl::Guard< osl::Mutex > theGuard( m_aMutex ); 94751ba086bSDamjan Jovanovic 94851ba086bSDamjan Jovanovic Init( rEnv ); 94951ba086bSDamjan Jovanovic CurlRequest curlRequest( m_pCurl ); 95051ba086bSDamjan Jovanovic 95151ba086bSDamjan Jovanovic propfind( curlRequest, inPath, inDepth, &inPropNames, false, rEnv ); 95251ba086bSDamjan Jovanovic 95351ba086bSDamjan Jovanovic const std::vector< DAVResource > rResources( parseWebDAVPropFindResponse( curlRequest.getResponseBody().get() ) ); 95451ba086bSDamjan Jovanovic std::vector< DAVResource > *pIoResources = &ioResources; 95551ba086bSDamjan Jovanovic *pIoResources = rResources; 95651ba086bSDamjan Jovanovic } 95751ba086bSDamjan Jovanovic 95851ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 95951ba086bSDamjan Jovanovic // PROPFIND - propnames 96051ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 96151ba086bSDamjan Jovanovic void CurlSession::PROPFIND( const rtl::OUString & inPath, 96251ba086bSDamjan Jovanovic const Depth inDepth, 96351ba086bSDamjan Jovanovic std::vector< DAVResourceInfo > & ioResInfo, 96451ba086bSDamjan Jovanovic const DAVRequestEnvironment & rEnv ) 96551ba086bSDamjan Jovanovic throw( DAVException ) 96651ba086bSDamjan Jovanovic { 96751ba086bSDamjan Jovanovic m_aLogger.log( LogLevel::INFO, "PROPFIND line $1$", (sal_Int32)__LINE__ ); 96851ba086bSDamjan Jovanovic 96951ba086bSDamjan Jovanovic osl::Guard< osl::Mutex > theGuard( m_aMutex ); 97051ba086bSDamjan Jovanovic 97151ba086bSDamjan Jovanovic Init( rEnv ); 97251ba086bSDamjan Jovanovic CurlRequest curlRequest( m_pCurl ); 97351ba086bSDamjan Jovanovic 97451ba086bSDamjan Jovanovic propfind( curlRequest, inPath, inDepth, NULL, true, rEnv ); 97551ba086bSDamjan Jovanovic 97651ba086bSDamjan Jovanovic const std::vector< DAVResourceInfo > rResInfo( parseWebDAVPropNameResponse( curlRequest.getResponseBody().get() ) ); 97751ba086bSDamjan Jovanovic std::vector< DAVResourceInfo > *pIoResInfo = &ioResInfo; 97851ba086bSDamjan Jovanovic *pIoResInfo = rResInfo; 97951ba086bSDamjan Jovanovic } 98051ba086bSDamjan Jovanovic 98151ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 98251ba086bSDamjan Jovanovic // PROPPATCH 98351ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 98451ba086bSDamjan Jovanovic void CurlSession::PROPPATCH( const rtl::OUString & inPath, 98551ba086bSDamjan Jovanovic const std::vector< ProppatchValue > & inValues, 98651ba086bSDamjan Jovanovic const DAVRequestEnvironment & rEnv ) 98751ba086bSDamjan Jovanovic throw( DAVException ) 98851ba086bSDamjan Jovanovic { 98951ba086bSDamjan Jovanovic m_aLogger.log( LogLevel::INFO, "PROPPATCH line $1$", (sal_Int32)__LINE__ ); 99051ba086bSDamjan Jovanovic 99151ba086bSDamjan Jovanovic osl::Guard< osl::Mutex > theGuard( m_aMutex ); 99251ba086bSDamjan Jovanovic 99351ba086bSDamjan Jovanovic Init( rEnv ); 99451ba086bSDamjan Jovanovic CurlRequest curlRequest( m_pCurl ); 99551ba086bSDamjan Jovanovic 99651ba086bSDamjan Jovanovic addEnvironmentRequestHeaders( curlRequest, rEnv ); 99751ba086bSDamjan Jovanovic 99851ba086bSDamjan Jovanovic // check whether a lock on this resource is already owned 99951ba086bSDamjan Jovanovic rtl::OUString aUri( composeCurrentUri( inPath ) ); 100051ba086bSDamjan Jovanovic ucb::Lock inLock; 100151ba086bSDamjan Jovanovic CurlLock * pLock = m_aCurlLockStore.findByUri( aUri ); 100251ba086bSDamjan Jovanovic if ( pLock ) 100351ba086bSDamjan Jovanovic { 100451ba086bSDamjan Jovanovic inLock = pLock->getLock(); 100551ba086bSDamjan Jovanovic } 100651ba086bSDamjan Jovanovic if ( inLock.LockTokens.getLength() > 0 ) 100751ba086bSDamjan Jovanovic { 100851ba086bSDamjan Jovanovic curlRequest.addHeader( "If", 100951ba086bSDamjan Jovanovic ( "(<" + rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ) + ">)" ).getStr() ); 101051ba086bSDamjan Jovanovic } 101151ba086bSDamjan Jovanovic 101251ba086bSDamjan Jovanovic rtl::OString xml = ProppatchRequest::generatePROPPATCHRequestBody( inValues ); 101351ba086bSDamjan Jovanovic if ( xml.getLength() > 0 ) 101451ba086bSDamjan Jovanovic { 101551ba086bSDamjan Jovanovic curlRequest.addHeader( "Content-Type", "application/xml" ); 101651ba086bSDamjan Jovanovic curlRequest.setRequestBody( xml.getStr(), xml.getLength() ); 101751ba086bSDamjan Jovanovic } 101851ba086bSDamjan Jovanovic 101951ba086bSDamjan Jovanovic CredentialsData credsData( this, curlRequest, rEnv ); 102051ba086bSDamjan Jovanovic curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData ); 102151ba086bSDamjan Jovanovic 102251ba086bSDamjan Jovanovic CURLcode rc = curlRequest.proppatch( m_aUri, inPath ); 102351ba086bSDamjan Jovanovic processResponse( curlRequest, rc ); 102451ba086bSDamjan Jovanovic } 102551ba086bSDamjan Jovanovic 102651ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 102751ba086bSDamjan Jovanovic // HEAD 102851ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 102951ba086bSDamjan Jovanovic void CurlSession::HEAD( const ::rtl::OUString & inPath, 103051ba086bSDamjan Jovanovic const std::vector< ::rtl::OUString > & inHeaderNames, 103151ba086bSDamjan Jovanovic DAVResource & ioResource, 103251ba086bSDamjan Jovanovic const DAVRequestEnvironment & rEnv ) 103351ba086bSDamjan Jovanovic throw( DAVException ) 103451ba086bSDamjan Jovanovic { 103551ba086bSDamjan Jovanovic m_aLogger.log( LogLevel::INFO, "HEAD line $1$", (sal_Int32)__LINE__ ); 103651ba086bSDamjan Jovanovic 103751ba086bSDamjan Jovanovic osl::Guard< osl::Mutex > theGuard( m_aMutex ); 103851ba086bSDamjan Jovanovic 103951ba086bSDamjan Jovanovic Init(rEnv ); 104051ba086bSDamjan Jovanovic CurlRequest curlRequest( m_pCurl ); 104151ba086bSDamjan Jovanovic 104251ba086bSDamjan Jovanovic addEnvironmentRequestHeaders( curlRequest, rEnv ); 104351ba086bSDamjan Jovanovic 104451ba086bSDamjan Jovanovic ioResource.uri = inPath; 104551ba086bSDamjan Jovanovic ioResource.properties.clear(); 104651ba086bSDamjan Jovanovic 104751ba086bSDamjan Jovanovic CredentialsData credsData( this, curlRequest, rEnv ); 104851ba086bSDamjan Jovanovic curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData ); 104951ba086bSDamjan Jovanovic 105051ba086bSDamjan Jovanovic CURLcode rc = curlRequest.head( m_aUri, inPath ); 105151ba086bSDamjan Jovanovic processResponse( curlRequest, rc ); 105251ba086bSDamjan Jovanovic responseHeadersToDAVResource( curlRequest.getResponseHeaders(), inHeaderNames, ioResource ); 105351ba086bSDamjan Jovanovic } 105451ba086bSDamjan Jovanovic 105551ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 105651ba086bSDamjan Jovanovic // GET 105751ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 105851ba086bSDamjan Jovanovic uno::Reference< io::XInputStream > 105951ba086bSDamjan Jovanovic CurlSession::GET( const rtl::OUString & inPath, 106051ba086bSDamjan Jovanovic const DAVRequestEnvironment & rEnv ) 106151ba086bSDamjan Jovanovic throw ( DAVException ) 106251ba086bSDamjan Jovanovic { 106351ba086bSDamjan Jovanovic m_aLogger.log( LogLevel::INFO, "GET line $1$", (sal_Int32)__LINE__ ); 106451ba086bSDamjan Jovanovic 106551ba086bSDamjan Jovanovic osl::Guard< osl::Mutex > theGuard( m_aMutex ); 106651ba086bSDamjan Jovanovic 106751ba086bSDamjan Jovanovic Init( rEnv ); 106851ba086bSDamjan Jovanovic CurlRequest curlRequest( m_pCurl ); 106951ba086bSDamjan Jovanovic 107051ba086bSDamjan Jovanovic addEnvironmentRequestHeaders( curlRequest, rEnv ); 107151ba086bSDamjan Jovanovic 107251ba086bSDamjan Jovanovic CredentialsData credsData( this, curlRequest, rEnv ); 107351ba086bSDamjan Jovanovic curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData ); 107451ba086bSDamjan Jovanovic 107551ba086bSDamjan Jovanovic CURLcode rc = curlRequest.get( m_aUri, inPath ); 107651ba086bSDamjan Jovanovic processResponse( curlRequest, rc ); 107751ba086bSDamjan Jovanovic 107851ba086bSDamjan Jovanovic return uno::Reference< io::XInputStream >( curlRequest.getResponseBody().get() ); 107951ba086bSDamjan Jovanovic } 108051ba086bSDamjan Jovanovic 108151ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 108251ba086bSDamjan Jovanovic // GET 108351ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 108451ba086bSDamjan Jovanovic void CurlSession::GET( const rtl::OUString & inPath, 108551ba086bSDamjan Jovanovic uno::Reference< io::XOutputStream > & ioOutputStream, 108651ba086bSDamjan Jovanovic const DAVRequestEnvironment & rEnv ) 108751ba086bSDamjan Jovanovic throw ( DAVException ) 108851ba086bSDamjan Jovanovic { 108951ba086bSDamjan Jovanovic m_aLogger.log( LogLevel::INFO, "GET line $1$", (sal_Int32)__LINE__ ); 109051ba086bSDamjan Jovanovic 109151ba086bSDamjan Jovanovic osl::Guard< osl::Mutex > theGuard( m_aMutex ); 109251ba086bSDamjan Jovanovic 109351ba086bSDamjan Jovanovic Init( rEnv ); 109451ba086bSDamjan Jovanovic CurlRequest curlRequest( m_pCurl ); 109551ba086bSDamjan Jovanovic 109651ba086bSDamjan Jovanovic addEnvironmentRequestHeaders( curlRequest, rEnv ); 109751ba086bSDamjan Jovanovic 109851ba086bSDamjan Jovanovic CredentialsData credsData( this, curlRequest, rEnv ); 109951ba086bSDamjan Jovanovic curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData ); 110051ba086bSDamjan Jovanovic 110151ba086bSDamjan Jovanovic curlRequest.saveResponseBodyTo( ioOutputStream ); 110251ba086bSDamjan Jovanovic CURLcode rc = curlRequest.get( m_aUri, inPath ); 110351ba086bSDamjan Jovanovic processResponse( curlRequest, rc ); 110451ba086bSDamjan Jovanovic } 110551ba086bSDamjan Jovanovic 110651ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 110751ba086bSDamjan Jovanovic // GET 110851ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 110951ba086bSDamjan Jovanovic uno::Reference< io::XInputStream > 111051ba086bSDamjan Jovanovic CurlSession::GET( const rtl::OUString & inPath, 111151ba086bSDamjan Jovanovic const std::vector< ::rtl::OUString > & inHeaderNames, 111251ba086bSDamjan Jovanovic DAVResource & ioResource, 111351ba086bSDamjan Jovanovic const DAVRequestEnvironment & rEnv ) 111451ba086bSDamjan Jovanovic throw ( DAVException ) 111551ba086bSDamjan Jovanovic { 111651ba086bSDamjan Jovanovic m_aLogger.log( LogLevel::INFO, "GET line $1$", (sal_Int32)__LINE__ ); 111751ba086bSDamjan Jovanovic 111851ba086bSDamjan Jovanovic osl::Guard< osl::Mutex > theGuard( m_aMutex ); 111951ba086bSDamjan Jovanovic 112051ba086bSDamjan Jovanovic Init( rEnv ); 112151ba086bSDamjan Jovanovic CurlRequest curlRequest( m_pCurl ); 112251ba086bSDamjan Jovanovic 112351ba086bSDamjan Jovanovic addEnvironmentRequestHeaders( curlRequest, rEnv ); 112451ba086bSDamjan Jovanovic 112551ba086bSDamjan Jovanovic CredentialsData credsData( this, curlRequest, rEnv ); 112651ba086bSDamjan Jovanovic curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData ); 112751ba086bSDamjan Jovanovic 112851ba086bSDamjan Jovanovic CURLcode rc = curlRequest.get( m_aUri, inPath ); 112951ba086bSDamjan Jovanovic processResponse( curlRequest, rc ); 113051ba086bSDamjan Jovanovic responseHeadersToDAVResource( curlRequest.getResponseHeaders(), inHeaderNames, ioResource ); 113151ba086bSDamjan Jovanovic 113251ba086bSDamjan Jovanovic return uno::Reference< io::XInputStream >( curlRequest.getResponseBody().get() ); 113351ba086bSDamjan Jovanovic } 113451ba086bSDamjan Jovanovic 113551ba086bSDamjan Jovanovic 113651ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 113751ba086bSDamjan Jovanovic // GET 113851ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 113951ba086bSDamjan Jovanovic void CurlSession::GET( const rtl::OUString & inPath, 114051ba086bSDamjan Jovanovic uno::Reference< io::XOutputStream > & ioOutputStream, 114151ba086bSDamjan Jovanovic const std::vector< ::rtl::OUString > & inHeaderNames, 114251ba086bSDamjan Jovanovic DAVResource & ioResource, 114351ba086bSDamjan Jovanovic const DAVRequestEnvironment & rEnv ) 114451ba086bSDamjan Jovanovic throw ( DAVException ) 114551ba086bSDamjan Jovanovic { 114651ba086bSDamjan Jovanovic m_aLogger.log( LogLevel::INFO, "GET line $1$", (sal_Int32)__LINE__ ); 114751ba086bSDamjan Jovanovic 114851ba086bSDamjan Jovanovic osl::Guard< osl::Mutex > theGuard( m_aMutex ); 114951ba086bSDamjan Jovanovic 115051ba086bSDamjan Jovanovic Init( rEnv ); 115151ba086bSDamjan Jovanovic CurlRequest curlRequest( m_pCurl ); 115251ba086bSDamjan Jovanovic 115351ba086bSDamjan Jovanovic addEnvironmentRequestHeaders( curlRequest, rEnv ); 115451ba086bSDamjan Jovanovic 115551ba086bSDamjan Jovanovic CredentialsData credsData( this, curlRequest, rEnv ); 115651ba086bSDamjan Jovanovic curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData ); 115751ba086bSDamjan Jovanovic 115851ba086bSDamjan Jovanovic curlRequest.saveResponseBodyTo( ioOutputStream ); 115951ba086bSDamjan Jovanovic CURLcode rc = curlRequest.get( m_aUri, inPath ); 116051ba086bSDamjan Jovanovic processResponse( curlRequest, rc ); 116151ba086bSDamjan Jovanovic responseHeadersToDAVResource( curlRequest.getResponseHeaders(), inHeaderNames, ioResource ); 116251ba086bSDamjan Jovanovic } 116351ba086bSDamjan Jovanovic 116451ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 116551ba086bSDamjan Jovanovic // PUT 116651ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 116751ba086bSDamjan Jovanovic void CurlSession::PUT( const rtl::OUString & inPath, 116851ba086bSDamjan Jovanovic const uno::Reference< io::XInputStream > & inInputStream, 116951ba086bSDamjan Jovanovic const DAVRequestEnvironment & rEnv ) 117051ba086bSDamjan Jovanovic throw ( DAVException ) 117151ba086bSDamjan Jovanovic { 117251ba086bSDamjan Jovanovic m_aLogger.log( LogLevel::INFO, "PUT line $1$", (sal_Int32)__LINE__ ); 117351ba086bSDamjan Jovanovic 117451ba086bSDamjan Jovanovic osl::Guard< osl::Mutex > theGuard( m_aMutex ); 117551ba086bSDamjan Jovanovic 117651ba086bSDamjan Jovanovic Init( rEnv ); 117751ba086bSDamjan Jovanovic CurlRequest curlRequest( m_pCurl ); 117851ba086bSDamjan Jovanovic 117951ba086bSDamjan Jovanovic addEnvironmentRequestHeaders( curlRequest, rEnv ); 118051ba086bSDamjan Jovanovic 118151ba086bSDamjan Jovanovic uno::Sequence< sal_Int8 > aDataToSend; 118251ba086bSDamjan Jovanovic if ( !getDataFromInputStream( inInputStream, aDataToSend, false ) ) 118351ba086bSDamjan Jovanovic throw DAVException( DAVException::DAV_INVALID_ARG ); 118451ba086bSDamjan Jovanovic curlRequest.setRequestBody( reinterpret_cast< const char * >( aDataToSend.getConstArray() ), 118551ba086bSDamjan Jovanovic aDataToSend.getLength() ); 118651ba086bSDamjan Jovanovic 118751ba086bSDamjan Jovanovic CredentialsData credsData( this, curlRequest, rEnv ); 118851ba086bSDamjan Jovanovic curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData ); 118951ba086bSDamjan Jovanovic 119051ba086bSDamjan Jovanovic // check whether a lock on this resource is already owned 119151ba086bSDamjan Jovanovic rtl::OUString aUri( composeCurrentUri( inPath ) ); 119251ba086bSDamjan Jovanovic ucb::Lock inLock; 119351ba086bSDamjan Jovanovic CurlLock * pLock = m_aCurlLockStore.findByUri( aUri ); 119451ba086bSDamjan Jovanovic if ( pLock ) 119551ba086bSDamjan Jovanovic { 119651ba086bSDamjan Jovanovic inLock = pLock->getLock(); 119751ba086bSDamjan Jovanovic } 119851ba086bSDamjan Jovanovic if ( inLock.LockTokens.getLength() > 0 ) 119951ba086bSDamjan Jovanovic { 120051ba086bSDamjan Jovanovic curlRequest.addHeader( "If", 120151ba086bSDamjan Jovanovic ( "(<" + rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ) + ">)" ).getStr() ); 120251ba086bSDamjan Jovanovic } 120351ba086bSDamjan Jovanovic 120451ba086bSDamjan Jovanovic CURLcode rc = curlRequest.put( m_aUri, inPath ); 120551ba086bSDamjan Jovanovic processResponse( curlRequest, rc ); 120651ba086bSDamjan Jovanovic } 120751ba086bSDamjan Jovanovic 120851ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 120951ba086bSDamjan Jovanovic // POST 121051ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 121151ba086bSDamjan Jovanovic uno::Reference< io::XInputStream > 121251ba086bSDamjan Jovanovic CurlSession::POST( const rtl::OUString & inPath, 121351ba086bSDamjan Jovanovic const rtl::OUString & rContentType, 121451ba086bSDamjan Jovanovic const rtl::OUString & rReferer, 121551ba086bSDamjan Jovanovic const uno::Reference< io::XInputStream > & inInputStream, 121651ba086bSDamjan Jovanovic const DAVRequestEnvironment & rEnv ) 121751ba086bSDamjan Jovanovic throw ( DAVException ) 121851ba086bSDamjan Jovanovic { 121951ba086bSDamjan Jovanovic m_aLogger.log( LogLevel::INFO, "POST line $1$", (sal_Int32)__LINE__ ); 122051ba086bSDamjan Jovanovic 122151ba086bSDamjan Jovanovic osl::Guard< osl::Mutex > theGuard( m_aMutex ); 122251ba086bSDamjan Jovanovic 122351ba086bSDamjan Jovanovic Init( rEnv ); 122451ba086bSDamjan Jovanovic CurlRequest curlRequest( m_pCurl ); 122551ba086bSDamjan Jovanovic 122651ba086bSDamjan Jovanovic addEnvironmentRequestHeaders( curlRequest, rEnv ); 122751ba086bSDamjan Jovanovic 122851ba086bSDamjan Jovanovic uno::Sequence< sal_Int8 > aDataToSend; 122951ba086bSDamjan Jovanovic if ( !getDataFromInputStream( inInputStream, aDataToSend, false ) ) 123051ba086bSDamjan Jovanovic throw DAVException( DAVException::DAV_INVALID_ARG ); 123151ba086bSDamjan Jovanovic curlRequest.setRequestBody( reinterpret_cast< const char * >( aDataToSend.getConstArray() ), 123251ba086bSDamjan Jovanovic aDataToSend.getLength() ); 123351ba086bSDamjan Jovanovic 123451ba086bSDamjan Jovanovic CredentialsData credsData( this, curlRequest, rEnv ); 123551ba086bSDamjan Jovanovic curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData ); 123651ba086bSDamjan Jovanovic 123751ba086bSDamjan Jovanovic if ( !rContentType.isEmpty() ) 123851ba086bSDamjan Jovanovic curlRequest.addHeader( "Content-Type", rtl::OUStringToOString( rContentType, RTL_TEXTENCODING_UTF8 ).getStr() ); 123951ba086bSDamjan Jovanovic if ( !rReferer.isEmpty() ) 124051ba086bSDamjan Jovanovic curlRequest.addHeader( "Referer", rtl::OUStringToOString( rReferer, RTL_TEXTENCODING_UTF8 ).getStr() ); 124151ba086bSDamjan Jovanovic 124251ba086bSDamjan Jovanovic // check whether a lock on this resource is already owned 124351ba086bSDamjan Jovanovic rtl::OUString aUri( composeCurrentUri( inPath ) ); 124451ba086bSDamjan Jovanovic ucb::Lock inLock; 124551ba086bSDamjan Jovanovic CurlLock * pLock = m_aCurlLockStore.findByUri( aUri ); 124651ba086bSDamjan Jovanovic if ( pLock ) 124751ba086bSDamjan Jovanovic { 124851ba086bSDamjan Jovanovic inLock = pLock->getLock(); 124951ba086bSDamjan Jovanovic } 125051ba086bSDamjan Jovanovic if ( inLock.LockTokens.getLength() > 0 ) 125151ba086bSDamjan Jovanovic { 125251ba086bSDamjan Jovanovic curlRequest.addHeader( "If", 125351ba086bSDamjan Jovanovic ( "(<" + rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ) + ">)" ).getStr() ); 125451ba086bSDamjan Jovanovic } 125551ba086bSDamjan Jovanovic 125651ba086bSDamjan Jovanovic CURLcode rc = curlRequest.post( m_aUri, inPath ); 125751ba086bSDamjan Jovanovic processResponse( curlRequest, rc ); 125851ba086bSDamjan Jovanovic return uno::Reference< io::XInputStream >( curlRequest.getResponseBody().get() ); 125951ba086bSDamjan Jovanovic } 126051ba086bSDamjan Jovanovic 126151ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 126251ba086bSDamjan Jovanovic // POST 126351ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 126451ba086bSDamjan Jovanovic void CurlSession::POST( const rtl::OUString & inPath, 126551ba086bSDamjan Jovanovic const rtl::OUString & rContentType, 126651ba086bSDamjan Jovanovic const rtl::OUString & rReferer, 126751ba086bSDamjan Jovanovic const uno::Reference< io::XInputStream > & inInputStream, 126851ba086bSDamjan Jovanovic uno::Reference< io::XOutputStream > & oOutputStream, 126951ba086bSDamjan Jovanovic const DAVRequestEnvironment & rEnv ) 127051ba086bSDamjan Jovanovic throw ( DAVException ) 127151ba086bSDamjan Jovanovic { 127251ba086bSDamjan Jovanovic m_aLogger.log( LogLevel::INFO, "POST line $1$", (sal_Int32)__LINE__ ); 127351ba086bSDamjan Jovanovic 127451ba086bSDamjan Jovanovic osl::Guard< osl::Mutex > theGuard( m_aMutex ); 127551ba086bSDamjan Jovanovic 127651ba086bSDamjan Jovanovic Init( rEnv ); 127751ba086bSDamjan Jovanovic CurlRequest curlRequest( m_pCurl ); 127851ba086bSDamjan Jovanovic 127951ba086bSDamjan Jovanovic addEnvironmentRequestHeaders( curlRequest, rEnv ); 128051ba086bSDamjan Jovanovic 128151ba086bSDamjan Jovanovic uno::Sequence< sal_Int8 > aDataToSend; 128251ba086bSDamjan Jovanovic if ( !getDataFromInputStream( inInputStream, aDataToSend, false ) ) 128351ba086bSDamjan Jovanovic throw DAVException( DAVException::DAV_INVALID_ARG ); 128451ba086bSDamjan Jovanovic curlRequest.setRequestBody( reinterpret_cast< const char * >( aDataToSend.getConstArray() ), 128551ba086bSDamjan Jovanovic aDataToSend.getLength() ); 128651ba086bSDamjan Jovanovic 128751ba086bSDamjan Jovanovic CredentialsData credsData( this, curlRequest, rEnv ); 128851ba086bSDamjan Jovanovic curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData ); 128951ba086bSDamjan Jovanovic 129051ba086bSDamjan Jovanovic if ( !rContentType.isEmpty() ) 129151ba086bSDamjan Jovanovic curlRequest.addHeader( "Content-Type", rtl::OUStringToOString( rContentType, RTL_TEXTENCODING_UTF8 ).getStr() ); 129251ba086bSDamjan Jovanovic if ( !rReferer.isEmpty() ) 129351ba086bSDamjan Jovanovic curlRequest.addHeader( "Referer", rtl::OUStringToOString( rReferer, RTL_TEXTENCODING_UTF8 ).getStr() ); 129451ba086bSDamjan Jovanovic 129551ba086bSDamjan Jovanovic // check whether a lock on this resource is already owned 129651ba086bSDamjan Jovanovic rtl::OUString aUri( composeCurrentUri( inPath ) ); 129751ba086bSDamjan Jovanovic ucb::Lock inLock; 129851ba086bSDamjan Jovanovic CurlLock * pLock = m_aCurlLockStore.findByUri( aUri ); 129951ba086bSDamjan Jovanovic if ( pLock ) 130051ba086bSDamjan Jovanovic { 130151ba086bSDamjan Jovanovic inLock = pLock->getLock(); 130251ba086bSDamjan Jovanovic } 130351ba086bSDamjan Jovanovic if ( inLock.LockTokens.getLength() > 0 ) 130451ba086bSDamjan Jovanovic { 130551ba086bSDamjan Jovanovic curlRequest.addHeader( "If", 130651ba086bSDamjan Jovanovic ( "(<" + rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ) + ">)" ).getStr() ); 130751ba086bSDamjan Jovanovic } 130851ba086bSDamjan Jovanovic 130951ba086bSDamjan Jovanovic curlRequest.saveResponseBodyTo( oOutputStream ); 131051ba086bSDamjan Jovanovic CURLcode rc = curlRequest.post( m_aUri, inPath ); 131151ba086bSDamjan Jovanovic processResponse( curlRequest, rc ); 131251ba086bSDamjan Jovanovic } 131351ba086bSDamjan Jovanovic 131451ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 131551ba086bSDamjan Jovanovic // MKCOL 131651ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 131751ba086bSDamjan Jovanovic void CurlSession::MKCOL( const rtl::OUString & inPath, 131851ba086bSDamjan Jovanovic const DAVRequestEnvironment & rEnv ) 131951ba086bSDamjan Jovanovic throw ( DAVException ) 132051ba086bSDamjan Jovanovic { 132151ba086bSDamjan Jovanovic m_aLogger.log( LogLevel::INFO, "MKCOL line $1$", (sal_Int32)__LINE__ ); 132251ba086bSDamjan Jovanovic 132351ba086bSDamjan Jovanovic osl::Guard< osl::Mutex > theGuard( m_aMutex ); 132451ba086bSDamjan Jovanovic 132551ba086bSDamjan Jovanovic Init( rEnv ); 132651ba086bSDamjan Jovanovic CurlRequest curlRequest( m_pCurl ); 132751ba086bSDamjan Jovanovic 132851ba086bSDamjan Jovanovic addEnvironmentRequestHeaders( curlRequest, rEnv ); 132951ba086bSDamjan Jovanovic 133051ba086bSDamjan Jovanovic CredentialsData credsData( this, curlRequest, rEnv ); 133151ba086bSDamjan Jovanovic curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData ); 133251ba086bSDamjan Jovanovic 133351ba086bSDamjan Jovanovic // check whether a lock on this resource is already owned 133451ba086bSDamjan Jovanovic rtl::OUString aUri( composeCurrentUri( inPath ) ); 133551ba086bSDamjan Jovanovic ucb::Lock inLock; 133651ba086bSDamjan Jovanovic CurlLock * pLock = m_aCurlLockStore.findByUri( aUri ); 133751ba086bSDamjan Jovanovic if ( pLock ) 133851ba086bSDamjan Jovanovic { 133951ba086bSDamjan Jovanovic inLock = pLock->getLock(); 134051ba086bSDamjan Jovanovic } 134151ba086bSDamjan Jovanovic if ( inLock.LockTokens.getLength() > 0 ) 134251ba086bSDamjan Jovanovic { 134351ba086bSDamjan Jovanovic curlRequest.addHeader( "If", 134451ba086bSDamjan Jovanovic ( "(<" + rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ) + ">)" ).getStr() ); 134551ba086bSDamjan Jovanovic } 134651ba086bSDamjan Jovanovic 134751ba086bSDamjan Jovanovic CURLcode rc = curlRequest.mkcol( m_aUri, inPath ); 134851ba086bSDamjan Jovanovic processResponse( curlRequest, rc ); 134951ba086bSDamjan Jovanovic } 135051ba086bSDamjan Jovanovic 135151ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 135251ba086bSDamjan Jovanovic // COPY 135351ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 135451ba086bSDamjan Jovanovic void CurlSession::COPY( const rtl::OUString & inSourceURL, 135551ba086bSDamjan Jovanovic const rtl::OUString & inDestinationURL, 135651ba086bSDamjan Jovanovic const DAVRequestEnvironment & rEnv, 135751ba086bSDamjan Jovanovic sal_Bool inOverWrite ) 135851ba086bSDamjan Jovanovic throw ( DAVException ) 135951ba086bSDamjan Jovanovic { 136051ba086bSDamjan Jovanovic m_aLogger.log( LogLevel::INFO, "COPY line $1$", (sal_Int32)__LINE__ ); 136151ba086bSDamjan Jovanovic 136251ba086bSDamjan Jovanovic osl::Guard< osl::Mutex > theGuard( m_aMutex ); 136351ba086bSDamjan Jovanovic 136451ba086bSDamjan Jovanovic Init( rEnv ); 136551ba086bSDamjan Jovanovic CurlRequest curlRequest( m_pCurl ); 136651ba086bSDamjan Jovanovic 136751ba086bSDamjan Jovanovic addEnvironmentRequestHeaders( curlRequest, rEnv ); 136851ba086bSDamjan Jovanovic 136951ba086bSDamjan Jovanovic CredentialsData credsData( this, curlRequest, rEnv ); 137051ba086bSDamjan Jovanovic curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData ); 137151ba086bSDamjan Jovanovic 137251ba086bSDamjan Jovanovic curlRequest.addHeader( "Destination", rtl::OUStringToOString( inDestinationURL, RTL_TEXTENCODING_UTF8 ).getStr() ); 137351ba086bSDamjan Jovanovic curlRequest.addHeader( "Overwrite", inOverWrite? "T" : "F" ); 137451ba086bSDamjan Jovanovic 137551ba086bSDamjan Jovanovic // check whether a lock on the destination resource is already owned 137651ba086bSDamjan Jovanovic rtl::OUString aUri( composeCurrentUri( inDestinationURL ) ); 137751ba086bSDamjan Jovanovic ucb::Lock inLock; 137851ba086bSDamjan Jovanovic CurlLock * pLock = m_aCurlLockStore.findByUri( aUri ); 137951ba086bSDamjan Jovanovic if ( pLock ) 138051ba086bSDamjan Jovanovic { 138151ba086bSDamjan Jovanovic inLock = pLock->getLock(); 138251ba086bSDamjan Jovanovic } 138351ba086bSDamjan Jovanovic if ( inLock.LockTokens.getLength() > 0 ) 138451ba086bSDamjan Jovanovic { 138551ba086bSDamjan Jovanovic curlRequest.addHeader( "If", 138651ba086bSDamjan Jovanovic ( "(<" + rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ) + ">)" ).getStr() ); 138751ba086bSDamjan Jovanovic } 138851ba086bSDamjan Jovanovic 138951ba086bSDamjan Jovanovic CURLcode rc = curlRequest.copy( m_aUri, CurlUri( inSourceURL ).GetPath() ); 139051ba086bSDamjan Jovanovic processResponse( curlRequest, rc ); 139151ba086bSDamjan Jovanovic } 139251ba086bSDamjan Jovanovic 139351ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 139451ba086bSDamjan Jovanovic // MOVE 139551ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 139651ba086bSDamjan Jovanovic void CurlSession::MOVE( const rtl::OUString & inSourceURL, 139751ba086bSDamjan Jovanovic const rtl::OUString & inDestinationURL, 139851ba086bSDamjan Jovanovic const DAVRequestEnvironment & rEnv, 139951ba086bSDamjan Jovanovic sal_Bool inOverWrite ) 140051ba086bSDamjan Jovanovic throw ( DAVException ) 140151ba086bSDamjan Jovanovic { 140251ba086bSDamjan Jovanovic m_aLogger.log( LogLevel::INFO, "MOVE line $1$", (sal_Int32)__LINE__ ); 140351ba086bSDamjan Jovanovic 140451ba086bSDamjan Jovanovic osl::Guard< osl::Mutex > theGuard( m_aMutex ); 140551ba086bSDamjan Jovanovic 140651ba086bSDamjan Jovanovic Init( rEnv ); 140751ba086bSDamjan Jovanovic CurlRequest curlRequest( m_pCurl ); 140851ba086bSDamjan Jovanovic 140951ba086bSDamjan Jovanovic addEnvironmentRequestHeaders( curlRequest, rEnv ); 141051ba086bSDamjan Jovanovic 141151ba086bSDamjan Jovanovic CredentialsData credsData( this, curlRequest, rEnv ); 141251ba086bSDamjan Jovanovic curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData ); 141351ba086bSDamjan Jovanovic 141451ba086bSDamjan Jovanovic curlRequest.addHeader( "Destination", rtl::OUStringToOString( inDestinationURL, RTL_TEXTENCODING_UTF8 ).getStr() ); 141551ba086bSDamjan Jovanovic curlRequest.addHeader( "Overwrite", inOverWrite? "T" : "F" ); 141651ba086bSDamjan Jovanovic 141751ba086bSDamjan Jovanovic // check whether a lock on the destination resource is already owned 141851ba086bSDamjan Jovanovic rtl::OUString aUri( composeCurrentUri( inDestinationURL ) ); 141951ba086bSDamjan Jovanovic ucb::Lock inLock; 142051ba086bSDamjan Jovanovic CurlLock * pLock = m_aCurlLockStore.findByUri( aUri ); 142151ba086bSDamjan Jovanovic if ( pLock ) 142251ba086bSDamjan Jovanovic { 142351ba086bSDamjan Jovanovic inLock = pLock->getLock(); 142451ba086bSDamjan Jovanovic } 142551ba086bSDamjan Jovanovic if ( inLock.LockTokens.getLength() > 0 ) 142651ba086bSDamjan Jovanovic { 142751ba086bSDamjan Jovanovic curlRequest.addHeader( "If", 142851ba086bSDamjan Jovanovic ( "(<" + rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ) + ">)" ).getStr() ); 142951ba086bSDamjan Jovanovic } 143051ba086bSDamjan Jovanovic 143151ba086bSDamjan Jovanovic CURLcode rc = curlRequest.copy( m_aUri, CurlUri( inSourceURL ).GetPath() ); 143251ba086bSDamjan Jovanovic processResponse( curlRequest, rc ); 143351ba086bSDamjan Jovanovic } 143451ba086bSDamjan Jovanovic 143551ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 143651ba086bSDamjan Jovanovic // DESTROY 143751ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 143851ba086bSDamjan Jovanovic void CurlSession::DESTROY( const rtl::OUString & inPath, 143951ba086bSDamjan Jovanovic const DAVRequestEnvironment & rEnv ) 144051ba086bSDamjan Jovanovic throw ( DAVException ) 144151ba086bSDamjan Jovanovic { 144251ba086bSDamjan Jovanovic m_aLogger.log( LogLevel::INFO, "DESTROY line $1$", (sal_Int32)__LINE__ ); 144351ba086bSDamjan Jovanovic 144451ba086bSDamjan Jovanovic osl::Guard< osl::Mutex > theGuard( m_aMutex ); 144551ba086bSDamjan Jovanovic 144651ba086bSDamjan Jovanovic Init( rEnv ); 144751ba086bSDamjan Jovanovic CurlRequest curlRequest( m_pCurl ); 144851ba086bSDamjan Jovanovic 144951ba086bSDamjan Jovanovic addEnvironmentRequestHeaders( curlRequest, rEnv ); 145051ba086bSDamjan Jovanovic 145151ba086bSDamjan Jovanovic CredentialsData credsData( this, curlRequest, rEnv ); 145251ba086bSDamjan Jovanovic curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData ); 145351ba086bSDamjan Jovanovic 145451ba086bSDamjan Jovanovic // check whether a lock on this resource is already owned 145551ba086bSDamjan Jovanovic rtl::OUString aUri( composeCurrentUri( inPath ) ); 145651ba086bSDamjan Jovanovic ucb::Lock inLock; 145751ba086bSDamjan Jovanovic CurlLock * pLock = m_aCurlLockStore.findByUri( aUri ); 145851ba086bSDamjan Jovanovic if ( pLock ) 145951ba086bSDamjan Jovanovic { 146051ba086bSDamjan Jovanovic inLock = pLock->getLock(); 146151ba086bSDamjan Jovanovic } 146251ba086bSDamjan Jovanovic if ( inLock.LockTokens.getLength() > 0 ) 146351ba086bSDamjan Jovanovic { 146451ba086bSDamjan Jovanovic curlRequest.addHeader( "If", 146551ba086bSDamjan Jovanovic ( "(<" + rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ) + ">)" ).getStr() ); 146651ba086bSDamjan Jovanovic } 146751ba086bSDamjan Jovanovic 146851ba086bSDamjan Jovanovic CURLcode rc = curlRequest.delete_( m_aUri, inPath ); 146951ba086bSDamjan Jovanovic processResponse( curlRequest, rc ); 147051ba086bSDamjan Jovanovic } 147151ba086bSDamjan Jovanovic 147251ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 147351ba086bSDamjan Jovanovic 147451ba086bSDamjan Jovanovic namespace 147551ba086bSDamjan Jovanovic { 147651ba086bSDamjan Jovanovic sal_Int32 lastChanceToSendRefreshRequest( TimeValue const & rStart, 147751ba086bSDamjan Jovanovic sal_Int32 timeout ) 147851ba086bSDamjan Jovanovic { 147951ba086bSDamjan Jovanovic TimeValue aEnd; 148051ba086bSDamjan Jovanovic osl_getSystemTime( &aEnd ); 148151ba086bSDamjan Jovanovic 148251ba086bSDamjan Jovanovic // Try to estimate a safe absolute time for sending the 148351ba086bSDamjan Jovanovic // lock refresh request. 148451ba086bSDamjan Jovanovic sal_Int32 lastChanceToSendRefreshRequest = DAVINFINITY; 148551ba086bSDamjan Jovanovic if ( timeout != DAVINFINITY ) 148651ba086bSDamjan Jovanovic { 148751ba086bSDamjan Jovanovic sal_Int32 calltime = aEnd.Seconds - rStart.Seconds; 148851ba086bSDamjan Jovanovic if ( calltime <= timeout ) 148951ba086bSDamjan Jovanovic { 149051ba086bSDamjan Jovanovic lastChanceToSendRefreshRequest 149151ba086bSDamjan Jovanovic = aEnd.Seconds + timeout - calltime; 149251ba086bSDamjan Jovanovic } 149351ba086bSDamjan Jovanovic else 149451ba086bSDamjan Jovanovic { 149551ba086bSDamjan Jovanovic OSL_TRACE( "No chance to refresh lock before timeout!" ); 149651ba086bSDamjan Jovanovic } 149751ba086bSDamjan Jovanovic } 149851ba086bSDamjan Jovanovic return lastChanceToSendRefreshRequest; 149951ba086bSDamjan Jovanovic } 150051ba086bSDamjan Jovanovic 150151ba086bSDamjan Jovanovic } // namespace 150251ba086bSDamjan Jovanovic 150351ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 150451ba086bSDamjan Jovanovic // LOCK (set new lock) 150551ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 150651ba086bSDamjan Jovanovic void CurlSession::LOCK( const ::rtl::OUString & inPath, 150751ba086bSDamjan Jovanovic ucb::Lock & inLock, 150851ba086bSDamjan Jovanovic const DAVRequestEnvironment & rEnv ) 150951ba086bSDamjan Jovanovic throw ( DAVException ) 151051ba086bSDamjan Jovanovic { 151151ba086bSDamjan Jovanovic m_aLogger.log( LogLevel::INFO, "LOCK line $1$", (sal_Int32)__LINE__ ); 151251ba086bSDamjan Jovanovic 151351ba086bSDamjan Jovanovic osl::Guard< osl::Mutex > theGuard( m_aMutex ); 151451ba086bSDamjan Jovanovic 151551ba086bSDamjan Jovanovic // before locking, search in the lock store if we already own a lock for this resource 151651ba086bSDamjan Jovanovic // if present, return with exception DAV_LOCKED_SELF 151751ba086bSDamjan Jovanovic rtl::OUString aUri( composeCurrentUri( inPath ) ); 151851ba086bSDamjan Jovanovic CurlLock * pLock = m_aCurlLockStore.findByUri( aUri ); 151951ba086bSDamjan Jovanovic if ( pLock ) 152051ba086bSDamjan Jovanovic { 152151ba086bSDamjan Jovanovic // already present, meaning already locked by the same AOO session and already in the lockstore 152251ba086bSDamjan Jovanovic // just return, nothing to do 152351ba086bSDamjan Jovanovic return; 152451ba086bSDamjan Jovanovic } 152551ba086bSDamjan Jovanovic 152651ba086bSDamjan Jovanovic Init( rEnv ); 152751ba086bSDamjan Jovanovic CurlRequest curlRequest( m_pCurl ); 152851ba086bSDamjan Jovanovic 152951ba086bSDamjan Jovanovic addEnvironmentRequestHeaders( curlRequest, rEnv ); 153051ba086bSDamjan Jovanovic 153151ba086bSDamjan Jovanovic CredentialsData credsData( this, curlRequest, rEnv ); 153251ba086bSDamjan Jovanovic curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData ); 153351ba086bSDamjan Jovanovic 153451ba086bSDamjan Jovanovic if ( inLock.Timeout == -1 ) 153551ba086bSDamjan Jovanovic curlRequest.addHeader( "Timeout", "Infinite" ); 153651ba086bSDamjan Jovanovic else 153751ba086bSDamjan Jovanovic curlRequest.addHeader( "Timeout", "Second-" + rtl::OString::valueOf( inLock.Timeout ) ); 153851ba086bSDamjan Jovanovic 153951ba086bSDamjan Jovanovic switch ( inLock.Depth ) 154051ba086bSDamjan Jovanovic { 154151ba086bSDamjan Jovanovic //i126305 TODO investigate on this case... 154251ba086bSDamjan Jovanovic case ucb::LockDepth_MAKE_FIXED_SIZE: 154351ba086bSDamjan Jovanovic 154451ba086bSDamjan Jovanovic case ucb::LockDepth_ZERO: 154551ba086bSDamjan Jovanovic curlRequest.addHeader( "Depth", "0" ); 154651ba086bSDamjan Jovanovic break; 154751ba086bSDamjan Jovanovic case ucb::LockDepth_ONE: 154851ba086bSDamjan Jovanovic curlRequest.addHeader( "Depth", "1" ); 154951ba086bSDamjan Jovanovic break; 155051ba086bSDamjan Jovanovic case ucb::LockDepth_INFINITY: 155151ba086bSDamjan Jovanovic curlRequest.addHeader( "Depth", "infinity" ); 155251ba086bSDamjan Jovanovic break; 155351ba086bSDamjan Jovanovic } 155451ba086bSDamjan Jovanovic 155551ba086bSDamjan Jovanovic rtl::OString xml = LockRequest::generateRequestBody( inLock ); 155651ba086bSDamjan Jovanovic curlRequest.addHeader( "Content-Type", "application/xml" ); 155751ba086bSDamjan Jovanovic curlRequest.setRequestBody( xml.getStr(), xml.getLength() ); 155851ba086bSDamjan Jovanovic 155951ba086bSDamjan Jovanovic TimeValue startCall; 156051ba086bSDamjan Jovanovic osl_getSystemTime( &startCall ); 156151ba086bSDamjan Jovanovic 156251ba086bSDamjan Jovanovic CURLcode rc = curlRequest.lock( m_aUri, inPath ); 156351ba086bSDamjan Jovanovic processResponse( curlRequest, rc ); 156451ba086bSDamjan Jovanovic 156551ba086bSDamjan Jovanovic // the returned property, a sequence of locks 156651ba086bSDamjan Jovanovic // only the first is used 156751ba086bSDamjan Jovanovic const DAVPropertyValue outLock( parseWebDAVLockResponse( curlRequest.getResponseBody().get() ) ); 156851ba086bSDamjan Jovanovic if(outLock.Name.compareToAscii(RTL_CONSTASCII_STRINGPARAM( "DAV:lockdiscovery" )) == 0 ) 156951ba086bSDamjan Jovanovic { 157051ba086bSDamjan Jovanovic // got a lock, use only the first returned 157151ba086bSDamjan Jovanovic uno::Sequence< ucb::Lock > aLocks; 157251ba086bSDamjan Jovanovic outLock.Value >>= aLocks; 157351ba086bSDamjan Jovanovic ucb::Lock aLock = aLocks[0]; 157451ba086bSDamjan Jovanovic 157551ba086bSDamjan Jovanovic CurlLock* aNewLock = new CurlLock( aLock, aUri, inPath ); 157651ba086bSDamjan Jovanovic // add the store the new lock 157751ba086bSDamjan Jovanovic m_aCurlLockStore.addLock(aNewLock,this, 157851ba086bSDamjan Jovanovic lastChanceToSendRefreshRequest( 157951ba086bSDamjan Jovanovic startCall, static_cast< sal_Int32 >(aLock.Timeout) ) ); 158051ba086bSDamjan Jovanovic } 158151ba086bSDamjan Jovanovic } 158251ba086bSDamjan Jovanovic 158351ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 158451ba086bSDamjan Jovanovic // LOCK (refresh existing lock from DAVResourceAccess) 158551ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 158651ba086bSDamjan Jovanovic sal_Int64 CurlSession::LOCK( const ::rtl::OUString & /*inPath*/, 158751ba086bSDamjan Jovanovic sal_Int64 nTimeout, 158851ba086bSDamjan Jovanovic const DAVRequestEnvironment & /*rEnv*/ ) 158951ba086bSDamjan Jovanovic throw ( DAVException ) 159051ba086bSDamjan Jovanovic { 159151ba086bSDamjan Jovanovic m_aLogger.log( LogLevel::INFO, "LOCK line $1$", (sal_Int32)__LINE__ ); 159251ba086bSDamjan Jovanovic 159351ba086bSDamjan Jovanovic osl::Guard< osl::Mutex > theGuard( m_aMutex ); 159451ba086bSDamjan Jovanovic 159551ba086bSDamjan Jovanovic return nTimeout; 159651ba086bSDamjan Jovanovic /* 159751ba086bSDamjan Jovanovic // Try to get the neon lock from lock store 159851ba086bSDamjan Jovanovic CurlLock * theLock 159951ba086bSDamjan Jovanovic = m_aCurlLockStore.findByUri( makeAbsoluteURL( inPath ) ); 160051ba086bSDamjan Jovanovic if ( !theLock ) 160151ba086bSDamjan Jovanovic throw DAVException( DAVException::DAV_NOT_LOCKED ); 160251ba086bSDamjan Jovanovic 160351ba086bSDamjan Jovanovic Init( rEnv ); 160451ba086bSDamjan Jovanovic 160551ba086bSDamjan Jovanovic // refresh existing lock. 160651ba086bSDamjan Jovanovic theLock->timeout = static_cast< long >( nTimeout ); 160751ba086bSDamjan Jovanovic 160851ba086bSDamjan Jovanovic TimeValue startCall; 160951ba086bSDamjan Jovanovic osl_getSystemTime( &startCall ); 161051ba086bSDamjan Jovanovic 161151ba086bSDamjan Jovanovic int theRetVal = ne_lock_refresh( m_pHttpSession, theLock ); 161251ba086bSDamjan Jovanovic 161351ba086bSDamjan Jovanovic if ( theRetVal == NE_OK ) 161451ba086bSDamjan Jovanovic { 161551ba086bSDamjan Jovanovic m_aCurlLockStore.updateLock( theLock, 161651ba086bSDamjan Jovanovic lastChanceToSendRefreshRequest( 161751ba086bSDamjan Jovanovic startCall, theLock->timeout ) ); 161851ba086bSDamjan Jovanovic } 161951ba086bSDamjan Jovanovic 162051ba086bSDamjan Jovanovic HandleError( theRetVal, inPath, rEnv ); 162151ba086bSDamjan Jovanovic 162251ba086bSDamjan Jovanovic return theLock->timeout; 162351ba086bSDamjan Jovanovic */ 162451ba086bSDamjan Jovanovic } 162551ba086bSDamjan Jovanovic 162651ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 162751ba086bSDamjan Jovanovic // LOCK (refresh existing lock from CurlLockStore) 162851ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 162951ba086bSDamjan Jovanovic bool CurlSession::LOCK( CurlLock * pLock, 163051ba086bSDamjan Jovanovic sal_Int32 & rlastChanceToSendRefreshRequest ) 163151ba086bSDamjan Jovanovic { 163251ba086bSDamjan Jovanovic m_aLogger.log( LogLevel::INFO, "LOCK line $1$", (sal_Int32)__LINE__ ); 163351ba086bSDamjan Jovanovic 163451ba086bSDamjan Jovanovic osl::Guard< osl::Mutex > theGuard( m_aMutex ); 163551ba086bSDamjan Jovanovic 163651ba086bSDamjan Jovanovic Init(); 163751ba086bSDamjan Jovanovic CurlRequest curlRequest( m_pCurl ); 163851ba086bSDamjan Jovanovic 163951ba086bSDamjan Jovanovic const ucb::Lock & inLock = pLock->getLock(); 164051ba086bSDamjan Jovanovic rtl::OUString inPath = pLock->getResourcePath(); 164151ba086bSDamjan Jovanovic 164251ba086bSDamjan Jovanovic if ( inLock.Timeout == -1 ) 164351ba086bSDamjan Jovanovic curlRequest.addHeader( "Timeout", "Infinite" ); 164451ba086bSDamjan Jovanovic else 164551ba086bSDamjan Jovanovic curlRequest.addHeader( "Timeout", "Second-" + rtl::OString::valueOf( inLock.Timeout ) ); 164651ba086bSDamjan Jovanovic 164751ba086bSDamjan Jovanovic switch ( inLock.Depth ) 164851ba086bSDamjan Jovanovic { 164951ba086bSDamjan Jovanovic //i126305 TODO investigate on this case... 165051ba086bSDamjan Jovanovic case ucb::LockDepth_MAKE_FIXED_SIZE: 165151ba086bSDamjan Jovanovic 165251ba086bSDamjan Jovanovic case ucb::LockDepth_ZERO: 165351ba086bSDamjan Jovanovic curlRequest.addHeader( "Depth", "0" ); 165451ba086bSDamjan Jovanovic break; 165551ba086bSDamjan Jovanovic case ucb::LockDepth_ONE: 165651ba086bSDamjan Jovanovic curlRequest.addHeader( "Depth", "1" ); 165751ba086bSDamjan Jovanovic break; 165851ba086bSDamjan Jovanovic case ucb::LockDepth_INFINITY: 165951ba086bSDamjan Jovanovic curlRequest.addHeader( "Depth", "infinity" ); 166051ba086bSDamjan Jovanovic break; 166151ba086bSDamjan Jovanovic } 166251ba086bSDamjan Jovanovic 166351ba086bSDamjan Jovanovic if ( inLock.LockTokens.getLength() > 0 ) 166451ba086bSDamjan Jovanovic { 166551ba086bSDamjan Jovanovic curlRequest.addHeader( "If", 166651ba086bSDamjan Jovanovic ( "(<" + rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ) + ">)" ).getStr() ); 166751ba086bSDamjan Jovanovic } 166851ba086bSDamjan Jovanovic 166951ba086bSDamjan Jovanovic rtl::OString xml = LockRequest::generateRequestBody( inLock ); 167051ba086bSDamjan Jovanovic curlRequest.addHeader( "Content-Type", "application/xml" ); 167151ba086bSDamjan Jovanovic curlRequest.setRequestBody( xml.getStr(), xml.getLength() ); 167251ba086bSDamjan Jovanovic 167351ba086bSDamjan Jovanovic TimeValue startCall; 167451ba086bSDamjan Jovanovic osl_getSystemTime( &startCall ); 167551ba086bSDamjan Jovanovic 167651ba086bSDamjan Jovanovic CURLcode rc = curlRequest.lock( m_aUri, inPath ); 167751ba086bSDamjan Jovanovic processResponse( curlRequest, rc ); 167851ba086bSDamjan Jovanovic 167951ba086bSDamjan Jovanovic // the returned property, a sequence of locks 168051ba086bSDamjan Jovanovic // only the first is used 168151ba086bSDamjan Jovanovic const DAVPropertyValue outLock( parseWebDAVLockResponse( curlRequest.getResponseBody().get() ) ); 168251ba086bSDamjan Jovanovic uno::Sequence< ucb::Lock > aLocks; 168351ba086bSDamjan Jovanovic outLock.Value >>= aLocks; 168451ba086bSDamjan Jovanovic ucb::Lock aLock = aLocks[0]; 168551ba086bSDamjan Jovanovic 168651ba086bSDamjan Jovanovic // if ok, update the lastchance refresh time in lock 168751ba086bSDamjan Jovanovic rlastChanceToSendRefreshRequest 168851ba086bSDamjan Jovanovic = lastChanceToSendRefreshRequest( startCall, static_cast< sal_Int32 >(aLock.Timeout) ); 168951ba086bSDamjan Jovanovic 169051ba086bSDamjan Jovanovic return true; 169151ba086bSDamjan Jovanovic } 169251ba086bSDamjan Jovanovic 169351ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 169451ba086bSDamjan Jovanovic // UNLOCK called from external (DAVResourceAccess) 169551ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 169651ba086bSDamjan Jovanovic void CurlSession::UNLOCK( const ::rtl::OUString & inPath, 169751ba086bSDamjan Jovanovic const DAVRequestEnvironment & rEnv ) 169851ba086bSDamjan Jovanovic throw ( DAVException ) 169951ba086bSDamjan Jovanovic { 170051ba086bSDamjan Jovanovic m_aLogger.log( LogLevel::INFO, "UNLOCK line $1$", (sal_Int32)__LINE__ ); 170151ba086bSDamjan Jovanovic 170251ba086bSDamjan Jovanovic osl::Guard< osl::Mutex > theGuard( m_aMutex ); 170351ba086bSDamjan Jovanovic 170451ba086bSDamjan Jovanovic rtl::OUString aUri( composeCurrentUri( inPath ) ); 170551ba086bSDamjan Jovanovic CurlLock * pLock = m_aCurlLockStore.findByUri( aUri ); 170651ba086bSDamjan Jovanovic if ( !pLock ) 170751ba086bSDamjan Jovanovic { 170851ba086bSDamjan Jovanovic throw DAVException( DAVException::DAV_NOT_LOCKED ); 170951ba086bSDamjan Jovanovic } 171051ba086bSDamjan Jovanovic 171151ba086bSDamjan Jovanovic Init( rEnv ); 171251ba086bSDamjan Jovanovic CurlRequest curlRequest( m_pCurl ); 171351ba086bSDamjan Jovanovic 171451ba086bSDamjan Jovanovic addEnvironmentRequestHeaders( curlRequest, rEnv ); 171551ba086bSDamjan Jovanovic 171651ba086bSDamjan Jovanovic CredentialsData credsData( this, curlRequest, rEnv ); 171751ba086bSDamjan Jovanovic curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData ); 171851ba086bSDamjan Jovanovic 171951ba086bSDamjan Jovanovic ucb::Lock inLock = pLock->getLock(); 172051ba086bSDamjan Jovanovic curlRequest.addHeader( "Lock-Token", 172151ba086bSDamjan Jovanovic ( "<" + rtl::OUStringToOString( inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ) + ">" ).getStr() ); 172251ba086bSDamjan Jovanovic 172351ba086bSDamjan Jovanovic // remove lock from lockstore 172451ba086bSDamjan Jovanovic // so, if something goes wrong, we don't refresh it anymore 172551ba086bSDamjan Jovanovic m_aCurlLockStore.removeLock( pLock ); 172651ba086bSDamjan Jovanovic delete pLock; 172751ba086bSDamjan Jovanovic 172851ba086bSDamjan Jovanovic CURLcode rc = curlRequest.unlock( m_aUri, inPath ); 172951ba086bSDamjan Jovanovic processResponse( curlRequest, rc ); 173051ba086bSDamjan Jovanovic } 173151ba086bSDamjan Jovanovic 173251ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 173351ba086bSDamjan Jovanovic // UNLOCK (called from CurlLockStore) 173451ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 173551ba086bSDamjan Jovanovic bool CurlSession::UNLOCK( CurlLock * pLock ) 173651ba086bSDamjan Jovanovic { 173751ba086bSDamjan Jovanovic m_aLogger.log( LogLevel::INFO, "UNLOCK line $1$", (sal_Int32)__LINE__ ); 173851ba086bSDamjan Jovanovic 173951ba086bSDamjan Jovanovic osl::Guard< osl::Mutex > theGuard( m_aMutex ); 174051ba086bSDamjan Jovanovic 174151ba086bSDamjan Jovanovic Init(); 174251ba086bSDamjan Jovanovic CurlRequest curlRequest( m_pCurl ); 174351ba086bSDamjan Jovanovic 174451ba086bSDamjan Jovanovic rtl::OUString inPath = pLock->getResourcePath(); 174551ba086bSDamjan Jovanovic ucb::Lock inLock = pLock->getLock(); 174651ba086bSDamjan Jovanovic curlRequest.addHeader( "Lock-Token", 174751ba086bSDamjan Jovanovic ( "<" + rtl::OUStringToOString( inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ) + ">" ).getStr() ); 174851ba086bSDamjan Jovanovic 174951ba086bSDamjan Jovanovic CURLcode rc = curlRequest.unlock( m_aUri, inPath ); 175051ba086bSDamjan Jovanovic processResponse( curlRequest, rc ); 175151ba086bSDamjan Jovanovic return true; 175251ba086bSDamjan Jovanovic } 175351ba086bSDamjan Jovanovic 175451ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 175551ba086bSDamjan Jovanovic void CurlSession::abort() 175651ba086bSDamjan Jovanovic throw ( DAVException ) 175751ba086bSDamjan Jovanovic { 175851ba086bSDamjan Jovanovic // 11.11.09 (tkr): The following code lines causing crashes if 175951ba086bSDamjan Jovanovic // closing a ongoing connection. It turned out that this existing 176051ba086bSDamjan Jovanovic // solution doesn't work in multi-threading environments. 176151ba086bSDamjan Jovanovic // So I disabled them in 3.2. . Issue #73893# should fix it in OOo 3.3. 176251ba086bSDamjan Jovanovic //if ( m_pHttpSession ) 176351ba086bSDamjan Jovanovic // ne_close_connection( m_pHttpSession ); 176451ba086bSDamjan Jovanovic } 176551ba086bSDamjan Jovanovic 176651ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 176751ba086bSDamjan Jovanovic const ucbhelper::InternetProxyServer & CurlSession::getProxySettings() const 176851ba086bSDamjan Jovanovic { 176951ba086bSDamjan Jovanovic if ( m_aUri.GetScheme().equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "http" ) ) || 177051ba086bSDamjan Jovanovic m_aUri.GetScheme().equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "https" ) ) ) 177151ba086bSDamjan Jovanovic { 177251ba086bSDamjan Jovanovic return m_rProxyDecider.getProxy( m_aUri.GetScheme(), 177351ba086bSDamjan Jovanovic m_aUri.GetHost(), 177451ba086bSDamjan Jovanovic m_aUri.GetPort() ); 177551ba086bSDamjan Jovanovic } 177651ba086bSDamjan Jovanovic else 177751ba086bSDamjan Jovanovic { 177851ba086bSDamjan Jovanovic // TODO: figure out, if this case can occur 177951ba086bSDamjan Jovanovic return m_rProxyDecider.getProxy( m_aUri.GetScheme(), 178051ba086bSDamjan Jovanovic rtl::OUString() /* not used */, 178151ba086bSDamjan Jovanovic -1 /* not used */ ); 178251ba086bSDamjan Jovanovic } 178351ba086bSDamjan Jovanovic } 178451ba086bSDamjan Jovanovic 178551ba086bSDamjan Jovanovic /* 178651ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 178751ba086bSDamjan Jovanovic namespace { 178851ba086bSDamjan Jovanovic 178951ba086bSDamjan Jovanovic bool containsLocktoken( const uno::Sequence< ucb::Lock > & rLocks, 179051ba086bSDamjan Jovanovic const char * token ) 179151ba086bSDamjan Jovanovic { 179251ba086bSDamjan Jovanovic for ( sal_Int32 n = 0; n < rLocks.getLength(); ++n ) 179351ba086bSDamjan Jovanovic { 179451ba086bSDamjan Jovanovic const uno::Sequence< rtl::OUString > & rTokens 179551ba086bSDamjan Jovanovic = rLocks[ n ].LockTokens; 179651ba086bSDamjan Jovanovic for ( sal_Int32 m = 0; m < rTokens.getLength(); ++m ) 179751ba086bSDamjan Jovanovic { 179851ba086bSDamjan Jovanovic if ( rTokens[ m ].equalsAscii( token ) ) 179951ba086bSDamjan Jovanovic return true; 180051ba086bSDamjan Jovanovic } 180151ba086bSDamjan Jovanovic } 180251ba086bSDamjan Jovanovic return false; 180351ba086bSDamjan Jovanovic } 180451ba086bSDamjan Jovanovic 180551ba086bSDamjan Jovanovic } // namespace 180651ba086bSDamjan Jovanovic */ 180751ba086bSDamjan Jovanovic 180851ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 180951ba086bSDamjan Jovanovic // This method doesn't seem to be used. 181051ba086bSDamjan Jovanovic // In any case the default behavior is to ask a lock with a life of 3 minutes 181151ba086bSDamjan Jovanovic // it will then be refreshed automatically (see CurlLockStore class) 181251ba086bSDamjan Jovanovic // In case of AOO crash the lock will expire by itself 181351ba086bSDamjan Jovanovic bool CurlSession::removeExpiredLocktoken( const rtl::OUString & /*inURL*/, 181451ba086bSDamjan Jovanovic const DAVRequestEnvironment & /*rEnv*/ ) 181551ba086bSDamjan Jovanovic { 181651ba086bSDamjan Jovanovic return true; 181751ba086bSDamjan Jovanovic /* 181851ba086bSDamjan Jovanovic CurlLock * theLock = m_aCurlLockStore.findByUri( inURL ); 181951ba086bSDamjan Jovanovic if ( !theLock ) 182051ba086bSDamjan Jovanovic return false; 182151ba086bSDamjan Jovanovic 182251ba086bSDamjan Jovanovic // do a lockdiscovery to check whether this lock is still valid. 182351ba086bSDamjan Jovanovic try 182451ba086bSDamjan Jovanovic { 182551ba086bSDamjan Jovanovic // @@@ Alternative: use ne_lock_discover() => less overhead 182651ba086bSDamjan Jovanovic 182751ba086bSDamjan Jovanovic std::vector< DAVResource > aResources; 182851ba086bSDamjan Jovanovic std::vector< rtl::OUString > aPropNames; 182951ba086bSDamjan Jovanovic aPropNames.push_back( DAVProperties::LOCKDISCOVERY ); 183051ba086bSDamjan Jovanovic 183151ba086bSDamjan Jovanovic PROPFIND( rEnv.m_aRequestURI, DAVZERO, aPropNames, aResources, rEnv ); 183251ba086bSDamjan Jovanovic 183351ba086bSDamjan Jovanovic if ( aResources.size() == 0 ) 183451ba086bSDamjan Jovanovic return false; 183551ba086bSDamjan Jovanovic 183651ba086bSDamjan Jovanovic std::vector< DAVPropertyValue >::const_iterator it 183751ba086bSDamjan Jovanovic = aResources[ 0 ].properties.begin(); 183851ba086bSDamjan Jovanovic std::vector< DAVPropertyValue >::const_iterator end 183951ba086bSDamjan Jovanovic = aResources[ 0 ].properties.end(); 184051ba086bSDamjan Jovanovic 184151ba086bSDamjan Jovanovic while ( it != end ) 184251ba086bSDamjan Jovanovic { 184351ba086bSDamjan Jovanovic if ( (*it).Name.equals( DAVProperties::LOCKDISCOVERY ) ) 184451ba086bSDamjan Jovanovic { 184551ba086bSDamjan Jovanovic uno::Sequence< ucb::Lock > aLocks; 184651ba086bSDamjan Jovanovic if ( !( (*it).Value >>= aLocks ) ) 184751ba086bSDamjan Jovanovic return false; 184851ba086bSDamjan Jovanovic 184951ba086bSDamjan Jovanovic if ( !containsLocktoken( aLocks, theLock->token ) ) 185051ba086bSDamjan Jovanovic { 185151ba086bSDamjan Jovanovic // expired! 185251ba086bSDamjan Jovanovic break; 185351ba086bSDamjan Jovanovic } 185451ba086bSDamjan Jovanovic 185551ba086bSDamjan Jovanovic // still valid. 185651ba086bSDamjan Jovanovic return false; 185751ba086bSDamjan Jovanovic } 185851ba086bSDamjan Jovanovic ++it; 185951ba086bSDamjan Jovanovic } 186051ba086bSDamjan Jovanovic 186151ba086bSDamjan Jovanovic // No lockdiscovery prop in propfind result / locktoken not found 186251ba086bSDamjan Jovanovic // in propfind result -> not locked 186351ba086bSDamjan Jovanovic OSL_TRACE( "CurlSession::removeExpiredLocktoken: Removing " 186451ba086bSDamjan Jovanovic " expired lock token for %s. token: %s", 186551ba086bSDamjan Jovanovic rtl::OUStringToOString( inURL, 186651ba086bSDamjan Jovanovic RTL_TEXTENCODING_UTF8 ).getStr(), 186751ba086bSDamjan Jovanovic theLock->token ); 186851ba086bSDamjan Jovanovic 186951ba086bSDamjan Jovanovic m_aCurlLockStore.removeLock( theLock ); 187051ba086bSDamjan Jovanovic ne_lock_destroy( theLock ); 187151ba086bSDamjan Jovanovic return true; 187251ba086bSDamjan Jovanovic } 187351ba086bSDamjan Jovanovic catch ( DAVException const & ) 187451ba086bSDamjan Jovanovic { 187551ba086bSDamjan Jovanovic } 187651ba086bSDamjan Jovanovic return false; 187751ba086bSDamjan Jovanovic */ 187851ba086bSDamjan Jovanovic } 187951ba086bSDamjan Jovanovic 188051ba086bSDamjan Jovanovic // ------------------------------------------------------------------- 188151ba086bSDamjan Jovanovic // static 188251ba086bSDamjan Jovanovic bool 188351ba086bSDamjan Jovanovic CurlSession::getDataFromInputStream( 188451ba086bSDamjan Jovanovic const uno::Reference< io::XInputStream > & xStream, 188551ba086bSDamjan Jovanovic uno::Sequence< sal_Int8 > & rData, 188651ba086bSDamjan Jovanovic bool bAppendTrailingZeroByte ) 188751ba086bSDamjan Jovanovic { 188851ba086bSDamjan Jovanovic if ( xStream.is() ) 188951ba086bSDamjan Jovanovic { 189051ba086bSDamjan Jovanovic uno::Reference< io::XSeekable > xSeekable( xStream, uno::UNO_QUERY ); 189151ba086bSDamjan Jovanovic if ( xSeekable.is() ) 189251ba086bSDamjan Jovanovic { 189351ba086bSDamjan Jovanovic try 189451ba086bSDamjan Jovanovic { 189551ba086bSDamjan Jovanovic sal_Int32 nSize 189651ba086bSDamjan Jovanovic = sal::static_int_cast<sal_Int32>(xSeekable->getLength()); 189751ba086bSDamjan Jovanovic sal_Int32 nRead 189851ba086bSDamjan Jovanovic = xStream->readBytes( rData, nSize ); 189951ba086bSDamjan Jovanovic 190051ba086bSDamjan Jovanovic if ( nRead == nSize ) 190151ba086bSDamjan Jovanovic { 190251ba086bSDamjan Jovanovic if ( bAppendTrailingZeroByte ) 190351ba086bSDamjan Jovanovic { 190451ba086bSDamjan Jovanovic rData.realloc( nSize + 1 ); 190551ba086bSDamjan Jovanovic rData[ nSize ] = sal_Int8( 0 ); 190651ba086bSDamjan Jovanovic } 190751ba086bSDamjan Jovanovic return true; 190851ba086bSDamjan Jovanovic } 190951ba086bSDamjan Jovanovic } 191051ba086bSDamjan Jovanovic catch ( io::NotConnectedException const & ) 191151ba086bSDamjan Jovanovic { 191251ba086bSDamjan Jovanovic // readBytes 191351ba086bSDamjan Jovanovic } 191451ba086bSDamjan Jovanovic catch ( io::BufferSizeExceededException const & ) 191551ba086bSDamjan Jovanovic { 191651ba086bSDamjan Jovanovic // readBytes 191751ba086bSDamjan Jovanovic } 191851ba086bSDamjan Jovanovic catch ( io::IOException const & ) 191951ba086bSDamjan Jovanovic { 192051ba086bSDamjan Jovanovic // getLength, readBytes 192151ba086bSDamjan Jovanovic } 192251ba086bSDamjan Jovanovic } 192351ba086bSDamjan Jovanovic else 192451ba086bSDamjan Jovanovic { 192551ba086bSDamjan Jovanovic try 192651ba086bSDamjan Jovanovic { 192751ba086bSDamjan Jovanovic uno::Sequence< sal_Int8 > aBuffer; 192851ba086bSDamjan Jovanovic sal_Int32 nPos = 0; 192951ba086bSDamjan Jovanovic 193051ba086bSDamjan Jovanovic sal_Int32 nRead = xStream->readSomeBytes( aBuffer, 65536 ); 193151ba086bSDamjan Jovanovic while ( nRead > 0 ) 193251ba086bSDamjan Jovanovic { 193351ba086bSDamjan Jovanovic if ( rData.getLength() < ( nPos + nRead ) ) 193451ba086bSDamjan Jovanovic rData.realloc( nPos + nRead ); 193551ba086bSDamjan Jovanovic 193651ba086bSDamjan Jovanovic aBuffer.realloc( nRead ); 193751ba086bSDamjan Jovanovic rtl_copyMemory( (void*)( rData.getArray() + nPos ), 193851ba086bSDamjan Jovanovic (const void*)aBuffer.getConstArray(), 193951ba086bSDamjan Jovanovic nRead ); 194051ba086bSDamjan Jovanovic nPos += nRead; 194151ba086bSDamjan Jovanovic 194251ba086bSDamjan Jovanovic aBuffer.realloc( 0 ); 194351ba086bSDamjan Jovanovic nRead = xStream->readSomeBytes( aBuffer, 65536 ); 194451ba086bSDamjan Jovanovic } 194551ba086bSDamjan Jovanovic 194651ba086bSDamjan Jovanovic if ( bAppendTrailingZeroByte ) 194751ba086bSDamjan Jovanovic { 194851ba086bSDamjan Jovanovic rData.realloc( nPos + 1 ); 194951ba086bSDamjan Jovanovic rData[ nPos ] = sal_Int8( 0 ); 195051ba086bSDamjan Jovanovic } 195151ba086bSDamjan Jovanovic return true; 195251ba086bSDamjan Jovanovic } 195351ba086bSDamjan Jovanovic catch ( io::NotConnectedException const & ) 195451ba086bSDamjan Jovanovic { 195551ba086bSDamjan Jovanovic // readBytes 195651ba086bSDamjan Jovanovic } 195751ba086bSDamjan Jovanovic catch ( io::BufferSizeExceededException const & ) 195851ba086bSDamjan Jovanovic { 195951ba086bSDamjan Jovanovic // readBytes 196051ba086bSDamjan Jovanovic } 196151ba086bSDamjan Jovanovic catch ( io::IOException const & ) 196251ba086bSDamjan Jovanovic { 196351ba086bSDamjan Jovanovic // readBytes 196451ba086bSDamjan Jovanovic } 196551ba086bSDamjan Jovanovic } 196651ba086bSDamjan Jovanovic } 196751ba086bSDamjan Jovanovic return false; 196851ba086bSDamjan Jovanovic } 196951ba086bSDamjan Jovanovic 197051ba086bSDamjan Jovanovic // --------------------------------------------------------------------- 197151ba086bSDamjan Jovanovic sal_Bool 197251ba086bSDamjan Jovanovic CurlSession::isDomainMatch( rtl::OUString certHostName ) 197351ba086bSDamjan Jovanovic { 197451ba086bSDamjan Jovanovic rtl::OUString hostName = getHostName(); 197551ba086bSDamjan Jovanovic 197651ba086bSDamjan Jovanovic if (hostName.equalsIgnoreAsciiCase( certHostName ) ) 197751ba086bSDamjan Jovanovic return sal_True; 197851ba086bSDamjan Jovanovic 197951ba086bSDamjan Jovanovic if ( 0 == certHostName.indexOf( rtl::OUString::createFromAscii( "*" ) ) && 198051ba086bSDamjan Jovanovic hostName.getLength() >= certHostName.getLength() ) 198151ba086bSDamjan Jovanovic { 198251ba086bSDamjan Jovanovic rtl::OUString cmpStr = certHostName.copy( 1 ); 198351ba086bSDamjan Jovanovic 198451ba086bSDamjan Jovanovic if ( hostName.matchIgnoreAsciiCase( 198551ba086bSDamjan Jovanovic cmpStr, hostName.getLength() - cmpStr.getLength() ) ) 198651ba086bSDamjan Jovanovic return sal_True; 198751ba086bSDamjan Jovanovic } 198851ba086bSDamjan Jovanovic return sal_False; 198951ba086bSDamjan Jovanovic } 1990