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