18590a0fdSAndre Fischer /************************************************************** 28590a0fdSAndre Fischer * 38590a0fdSAndre Fischer * Licensed to the Apache Software Foundation (ASF) under one 48590a0fdSAndre Fischer * or more contributor license agreements. See the NOTICE file 58590a0fdSAndre Fischer * distributed with this work for additional information 68590a0fdSAndre Fischer * regarding copyright ownership. The ASF licenses this file 78590a0fdSAndre Fischer * to you under the Apache License, Version 2.0 (the 88590a0fdSAndre Fischer * "License"); you may not use this file except in compliance 98590a0fdSAndre Fischer * with the License. You may obtain a copy of the License at 108590a0fdSAndre Fischer * 118590a0fdSAndre Fischer * http://www.apache.org/licenses/LICENSE-2.0 128590a0fdSAndre Fischer * 138590a0fdSAndre Fischer * Unless required by applicable law or agreed to in writing, 148590a0fdSAndre Fischer * software distributed under the License is distributed on an 158590a0fdSAndre Fischer * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 168590a0fdSAndre Fischer * KIND, either express or implied. See the License for the 178590a0fdSAndre Fischer * specific language governing permissions and limitations 188590a0fdSAndre Fischer * under the License. 198590a0fdSAndre Fischer * 208590a0fdSAndre Fischer *************************************************************/ 218590a0fdSAndre Fischer 228590a0fdSAndre Fischer // MARKER(update_precomp.py): autogen include statement, do not remove 238590a0fdSAndre Fischer #include "precompiled_ucb.hxx" 248590a0fdSAndre Fischer 258590a0fdSAndre Fischer #include <hash_map> 268590a0fdSAndre Fischer #include <vector> 278590a0fdSAndre Fischer #include <string.h> 288590a0fdSAndre Fischer #include <rtl/string.h> 29*8fd7bf9dSAndrea Pescetti #include <rtl/ustrbuf.hxx> 30*8fd7bf9dSAndrea Pescetti #include <osl/time.h> 318590a0fdSAndre Fischer #include "comphelper/sequence.hxx" 328590a0fdSAndre Fischer #include "ucbhelper/simplecertificatevalidationrequest.hxx" 338590a0fdSAndre Fischer 34c1c10f68SAriel Constenla-Haile #include "AprEnv.hxx" 3508bb353fSPedro Giffuni #include <apr_strings.h> 368590a0fdSAndre Fischer 378590a0fdSAndre Fischer #include "DAVAuthListener.hxx" 38c1c10f68SAriel Constenla-Haile #include "SerfTypes.hxx" 39c1c10f68SAriel Constenla-Haile #include "SerfSession.hxx" 40c1c10f68SAriel Constenla-Haile #include "SerfUri.hxx" 41c1c10f68SAriel Constenla-Haile #include "SerfRequestProcessor.hxx" 42c1c10f68SAriel Constenla-Haile #include "SerfCallbacks.hxx" 43c1c10f68SAriel Constenla-Haile #include "SerfInputStream.hxx" 44c1c10f68SAriel Constenla-Haile #include "UCBDeadPropertyValue.hxx" 458590a0fdSAndre Fischer 468590a0fdSAndre Fischer #include <com/sun/star/xml/crypto/XSecurityEnvironment.hpp> 478590a0fdSAndre Fischer #include <com/sun/star/security/XCertificate.hpp> 488590a0fdSAndre Fischer #include <com/sun/star/security/CertificateValidity.hpp> 498590a0fdSAndre Fischer #include <com/sun/star/security/CertificateContainerStatus.hpp> 508590a0fdSAndre Fischer #include <com/sun/star/security/CertificateContainer.hpp> 518590a0fdSAndre Fischer #include <com/sun/star/security/XCertificateContainer.hpp> 52e54851feSOliver-Rainer Wittmann #include <com/sun/star/security/CertAltNameEntry.hpp> 53e54851feSOliver-Rainer Wittmann #include <com/sun/star/security/XSanExtension.hpp> 54e54851feSOliver-Rainer Wittmann #define OID_SUBJECT_ALTERNATIVE_NAME "2.5.29.17" 55e54851feSOliver-Rainer Wittmann 568590a0fdSAndre Fischer #include <com/sun/star/ucb/Lock.hpp> 578590a0fdSAndre Fischer #include <com/sun/star/xml/crypto/XSEInitializer.hpp> 588590a0fdSAndre Fischer 598590a0fdSAndre Fischer using namespace com::sun::star; 608590a0fdSAndre Fischer using namespace http_dav_ucp; 618590a0fdSAndre Fischer 628590a0fdSAndre Fischer // ------------------------------------------------------------------- 638590a0fdSAndre Fischer // static members! 64*8fd7bf9dSAndrea Pescetti SerfLockStore SerfSession::m_aSerfLockStore; 658590a0fdSAndre Fischer 668590a0fdSAndre Fischer // ------------------------------------------------------------------- 678590a0fdSAndre Fischer // Constructor 688590a0fdSAndre Fischer // ------------------------------------------------------------------- 698590a0fdSAndre Fischer SerfSession::SerfSession( 708590a0fdSAndre Fischer const rtl::Reference< DAVSessionFactory > & rSessionFactory, 718590a0fdSAndre Fischer const rtl::OUString& inUri, 728590a0fdSAndre Fischer const ucbhelper::InternetProxyDecider & rProxyDecider ) 738590a0fdSAndre Fischer throw ( DAVException ) 748590a0fdSAndre Fischer : DAVSession( rSessionFactory ) 758590a0fdSAndre Fischer , m_aMutex() 768590a0fdSAndre Fischer , m_aUri( inUri ) 778590a0fdSAndre Fischer , m_aProxyName() 788590a0fdSAndre Fischer , m_nProxyPort( 0 ) 79*8fd7bf9dSAndrea Pescetti , m_aServerHeaderField() 808590a0fdSAndre Fischer , m_pSerfConnection( 0 ) 818590a0fdSAndre Fischer , m_pSerfContext( 0 ) 828590a0fdSAndre Fischer , m_bIsHeadRequestInProgress( false ) 8349989859SOliver-Rainer Wittmann , m_bUseChunkedEncoding( false ) 8449989859SOliver-Rainer Wittmann , m_bNoOfTransferEncodingSwitches( 0 ) 858590a0fdSAndre Fischer , m_rProxyDecider( rProxyDecider ) 868590a0fdSAndre Fischer , m_aEnv() 878590a0fdSAndre Fischer { 888590a0fdSAndre Fischer m_pSerfContext = serf_context_create( getAprPool() ); 898590a0fdSAndre Fischer 908590a0fdSAndre Fischer m_pSerfBucket_Alloc = serf_bucket_allocator_create( getAprPool(), NULL, NULL ); 918590a0fdSAndre Fischer } 928590a0fdSAndre Fischer 938590a0fdSAndre Fischer // ------------------------------------------------------------------- 948590a0fdSAndre Fischer // Destructor 958590a0fdSAndre Fischer // ------------------------------------------------------------------- 968590a0fdSAndre Fischer SerfSession::~SerfSession( ) 978590a0fdSAndre Fischer { 988590a0fdSAndre Fischer if ( m_pSerfConnection ) 998590a0fdSAndre Fischer { 1008590a0fdSAndre Fischer serf_connection_close( m_pSerfConnection ); 1018590a0fdSAndre Fischer m_pSerfConnection = 0; 102*8fd7bf9dSAndrea Pescetti OSL_TRACE("SerfSession::~SerfSession: closed serf connection"); 1038590a0fdSAndre Fischer } 1048590a0fdSAndre Fischer } 1058590a0fdSAndre Fischer 1068590a0fdSAndre Fischer // ------------------------------------------------------------------- 1078590a0fdSAndre Fischer void SerfSession::Init( const DAVRequestEnvironment & rEnv ) 1088590a0fdSAndre Fischer throw ( DAVException ) 1098590a0fdSAndre Fischer { 1108590a0fdSAndre Fischer osl::Guard< osl::Mutex > theGuard( m_aMutex ); 1118590a0fdSAndre Fischer m_aEnv = rEnv; 1128590a0fdSAndre Fischer Init(); 1138590a0fdSAndre Fischer } 1148590a0fdSAndre Fischer 1158590a0fdSAndre Fischer // ------------------------------------------------------------------- 1168590a0fdSAndre Fischer void SerfSession::Init() 1178590a0fdSAndre Fischer throw ( DAVException ) 1188590a0fdSAndre Fischer { 1198590a0fdSAndre Fischer osl::Guard< osl::Mutex > theGuard( m_aMutex ); 1208590a0fdSAndre Fischer 1218590a0fdSAndre Fischer bool bCreateNewSession = false; 1228590a0fdSAndre Fischer 1238590a0fdSAndre Fischer if ( m_pSerfConnection == 0 ) 1248590a0fdSAndre Fischer { 1258590a0fdSAndre Fischer const ucbhelper::InternetProxyServer & rProxyCfg = getProxySettings(); 1268590a0fdSAndre Fischer 1278590a0fdSAndre Fischer m_aProxyName = rProxyCfg.aName; 1288590a0fdSAndre Fischer m_nProxyPort = rProxyCfg.nPort; 1298590a0fdSAndre Fischer 1308590a0fdSAndre Fischer // Not yet initialized. Create new session. 1318590a0fdSAndre Fischer bCreateNewSession = true; 132*8fd7bf9dSAndrea Pescetti OSL_TRACE("SerfSession::Init: serf connection created"); 1338590a0fdSAndre Fischer } 1348590a0fdSAndre Fischer else 1358590a0fdSAndre Fischer { 1368590a0fdSAndre Fischer const ucbhelper::InternetProxyServer & rProxyCfg = getProxySettings(); 1378590a0fdSAndre Fischer 1388590a0fdSAndre Fischer if ( ( rProxyCfg.aName != m_aProxyName ) 1398590a0fdSAndre Fischer || ( rProxyCfg.nPort != m_nProxyPort ) ) 1408590a0fdSAndre Fischer { 1418590a0fdSAndre Fischer m_aProxyName = rProxyCfg.aName; 1428590a0fdSAndre Fischer m_nProxyPort = rProxyCfg.nPort; 1438590a0fdSAndre Fischer 1448590a0fdSAndre Fischer // new session needed, destroy old first 1458590a0fdSAndre Fischer serf_connection_close( m_pSerfConnection ); 1468590a0fdSAndre Fischer m_pSerfConnection = 0; 1478590a0fdSAndre Fischer bCreateNewSession = true; 1488590a0fdSAndre Fischer } 1498590a0fdSAndre Fischer } 1508590a0fdSAndre Fischer 1518590a0fdSAndre Fischer if ( bCreateNewSession ) 1528590a0fdSAndre Fischer { 1538590a0fdSAndre Fischer // TODO - close_connection callback 1548590a0fdSAndre Fischer apr_status_t status = serf_connection_create2( &m_pSerfConnection, 1558590a0fdSAndre Fischer m_pSerfContext, 1568590a0fdSAndre Fischer *(m_aUri.getAprUri()), 1578590a0fdSAndre Fischer Serf_ConnectSetup, this, 1588590a0fdSAndre Fischer 0 /* close connection callback */, 0 /* close connection baton */, 1598590a0fdSAndre Fischer getAprPool() ); 1608590a0fdSAndre Fischer 1618590a0fdSAndre Fischer if ( m_pSerfConnection == 0 ||status != APR_SUCCESS ) 1628590a0fdSAndre Fischer { 1638590a0fdSAndre Fischer throw DAVException( DAVException::DAV_SESSION_CREATE, 1648590a0fdSAndre Fischer SerfUri::makeConnectionEndPointString( m_aUri.GetHost(), m_aUri.GetPort() ) ); 1658590a0fdSAndre Fischer } 1668590a0fdSAndre Fischer 1678590a0fdSAndre Fischer // Register the session with the lock store 1688590a0fdSAndre Fischer // m_aSerfLockStore.registerSession( m_pSerfConnection ); 1698590a0fdSAndre Fischer 1708590a0fdSAndre Fischer if ( m_aProxyName.getLength() ) 1718590a0fdSAndre Fischer { 1728590a0fdSAndre Fischer apr_sockaddr_t *proxy_address = NULL; 173fdf35928SAndre Fischer status = apr_sockaddr_info_get( &proxy_address, 17424c56ab9SHerbert Dürr rtl::OUStringToOString( m_aProxyName, RTL_TEXTENCODING_UTF8 ).getStr(), 1758590a0fdSAndre Fischer APR_UNSPEC, 1768590a0fdSAndre Fischer static_cast<apr_port_t>(m_nProxyPort), 1778590a0fdSAndre Fischer 0, getAprPool() ); 1788590a0fdSAndre Fischer 1798590a0fdSAndre Fischer if ( status != APR_SUCCESS ) 1808590a0fdSAndre Fischer { 1818590a0fdSAndre Fischer throw DAVException( DAVException::DAV_SESSION_CREATE, 1828590a0fdSAndre Fischer SerfUri::makeConnectionEndPointString( m_aUri.GetHost(), m_aUri.GetPort() ) ); 1838590a0fdSAndre Fischer } 1848590a0fdSAndre Fischer 1858590a0fdSAndre Fischer serf_config_proxy( m_pSerfContext, proxy_address ); 1868590a0fdSAndre Fischer } 1878590a0fdSAndre Fischer 1888590a0fdSAndre Fischer 1898590a0fdSAndre Fischer serf_config_credentials_callback( m_pSerfContext, Serf_Credentials ); 19049989859SOliver-Rainer Wittmann 19149989859SOliver-Rainer Wittmann m_bUseChunkedEncoding = isSSLNeeded(); 1928590a0fdSAndre Fischer } 1938590a0fdSAndre Fischer } 1948590a0fdSAndre Fischer 1958590a0fdSAndre Fischer apr_pool_t* SerfSession::getAprPool() 1968590a0fdSAndre Fischer { 1978590a0fdSAndre Fischer return apr_environment::AprEnv::getAprEnv()->getAprPool(); 1988590a0fdSAndre Fischer } 1998590a0fdSAndre Fischer 2008590a0fdSAndre Fischer serf_bucket_alloc_t* SerfSession::getSerfBktAlloc() 2018590a0fdSAndre Fischer { 2028590a0fdSAndre Fischer return m_pSerfBucket_Alloc; 2038590a0fdSAndre Fischer } 2048590a0fdSAndre Fischer 2058590a0fdSAndre Fischer serf_context_t* SerfSession::getSerfContext() 2068590a0fdSAndre Fischer { 2078590a0fdSAndre Fischer return m_pSerfContext; 2088590a0fdSAndre Fischer } 2098590a0fdSAndre Fischer 2108590a0fdSAndre Fischer SerfConnection* SerfSession::getSerfConnection() 2118590a0fdSAndre Fischer { 2128590a0fdSAndre Fischer return m_pSerfConnection; 2138590a0fdSAndre Fischer } 2148590a0fdSAndre Fischer 2158590a0fdSAndre Fischer bool SerfSession::isHeadRequestInProgress() 2168590a0fdSAndre Fischer { 2178590a0fdSAndre Fischer return m_bIsHeadRequestInProgress; 2188590a0fdSAndre Fischer } 2198590a0fdSAndre Fischer 2208590a0fdSAndre Fischer bool SerfSession::isSSLNeeded() 2218590a0fdSAndre Fischer { 2228590a0fdSAndre Fischer return m_aUri.GetScheme().equalsIgnoreAsciiCase( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "https" ) ) ); 2238590a0fdSAndre Fischer } 2248590a0fdSAndre Fischer 2258590a0fdSAndre Fischer char* SerfSession::getHostinfo() 2268590a0fdSAndre Fischer { 2278590a0fdSAndre Fischer return m_aUri.getAprUri()->hostinfo; 2288590a0fdSAndre Fischer } 2298590a0fdSAndre Fischer 230*8fd7bf9dSAndrea Pescetti // ------------------------------------------------------------------- 231*8fd7bf9dSAndrea Pescetti // helper function 232*8fd7bf9dSAndrea Pescetti // it composes the uri for lockstore registration 233*8fd7bf9dSAndrea Pescetti rtl::OUString SerfSession::composeCurrentUri(const rtl::OUString & inPath) 234*8fd7bf9dSAndrea Pescetti { 235*8fd7bf9dSAndrea Pescetti rtl::OUString aScheme( m_aUri.GetScheme() ); 236*8fd7bf9dSAndrea Pescetti rtl::OUStringBuffer aBuf( aScheme ); 237*8fd7bf9dSAndrea Pescetti aBuf.appendAscii( "://" ); 238*8fd7bf9dSAndrea Pescetti if ( m_aUri.GetUserInfo().getLength() > 0 ) 239*8fd7bf9dSAndrea Pescetti { 240*8fd7bf9dSAndrea Pescetti aBuf.append( m_aUri.GetUserInfo() ); 241*8fd7bf9dSAndrea Pescetti aBuf.appendAscii( "@" ); 242*8fd7bf9dSAndrea Pescetti } 243*8fd7bf9dSAndrea Pescetti // Is host a numeric IPv6 address? 244*8fd7bf9dSAndrea Pescetti if ( ( m_aUri.GetHost().indexOf( ':' ) != -1 ) && 245*8fd7bf9dSAndrea Pescetti ( m_aUri.GetHost()[ 0 ] != sal_Unicode( '[' ) ) ) 246*8fd7bf9dSAndrea Pescetti { 247*8fd7bf9dSAndrea Pescetti aBuf.appendAscii( "[" ); 248*8fd7bf9dSAndrea Pescetti aBuf.append( m_aUri.GetHost() ); 249*8fd7bf9dSAndrea Pescetti aBuf.appendAscii( "]" ); 250*8fd7bf9dSAndrea Pescetti } 251*8fd7bf9dSAndrea Pescetti else 252*8fd7bf9dSAndrea Pescetti { 253*8fd7bf9dSAndrea Pescetti aBuf.append( m_aUri.GetHost() ); 254*8fd7bf9dSAndrea Pescetti } 255*8fd7bf9dSAndrea Pescetti 256*8fd7bf9dSAndrea Pescetti // append port, but only, if not default port. 257*8fd7bf9dSAndrea Pescetti bool bAppendPort = true; 258*8fd7bf9dSAndrea Pescetti sal_Int32 aPort = m_aUri.GetPort(); 259*8fd7bf9dSAndrea Pescetti switch ( aPort ) 260*8fd7bf9dSAndrea Pescetti { 261*8fd7bf9dSAndrea Pescetti case DEFAULT_HTTP_PORT: 262*8fd7bf9dSAndrea Pescetti bAppendPort = aScheme.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "http" ) ); 263*8fd7bf9dSAndrea Pescetti break; 264*8fd7bf9dSAndrea Pescetti 265*8fd7bf9dSAndrea Pescetti case DEFAULT_HTTPS_PORT: 266*8fd7bf9dSAndrea Pescetti bAppendPort = !aScheme.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "https" ) ); 267*8fd7bf9dSAndrea Pescetti break; 268*8fd7bf9dSAndrea Pescetti } 269*8fd7bf9dSAndrea Pescetti if ( bAppendPort ) 270*8fd7bf9dSAndrea Pescetti { 271*8fd7bf9dSAndrea Pescetti aBuf.appendAscii( ":" ); 272*8fd7bf9dSAndrea Pescetti aBuf.append( rtl::OUString::valueOf( aPort ) ); 273*8fd7bf9dSAndrea Pescetti } 274*8fd7bf9dSAndrea Pescetti aBuf.append( inPath ); 275*8fd7bf9dSAndrea Pescetti 276*8fd7bf9dSAndrea Pescetti rtl::OUString aUri(aBuf.makeStringAndClear() ); 277*8fd7bf9dSAndrea Pescetti return aUri; 278*8fd7bf9dSAndrea Pescetti } 2798590a0fdSAndre Fischer 2808590a0fdSAndre Fischer // ------------------------------------------------------------------- 2818590a0fdSAndre Fischer // virtual 2828590a0fdSAndre Fischer sal_Bool SerfSession::CanUse( const rtl::OUString & inUri ) 2838590a0fdSAndre Fischer { 2848590a0fdSAndre Fischer try 2858590a0fdSAndre Fischer { 2868590a0fdSAndre Fischer SerfUri theUri( inUri ); 2878590a0fdSAndre Fischer if ( ( theUri.GetPort() == m_aUri.GetPort() ) && 2888590a0fdSAndre Fischer ( theUri.GetHost() == m_aUri.GetHost() ) && 2898590a0fdSAndre Fischer ( theUri.GetScheme() == m_aUri.GetScheme() ) ) 2908590a0fdSAndre Fischer { 2918590a0fdSAndre Fischer return sal_True; 2928590a0fdSAndre Fischer } 2938590a0fdSAndre Fischer } 2948590a0fdSAndre Fischer catch ( DAVException const & ) 2958590a0fdSAndre Fischer { 2968590a0fdSAndre Fischer return sal_False; 2978590a0fdSAndre Fischer } 2988590a0fdSAndre Fischer return sal_False; 2998590a0fdSAndre Fischer } 3008590a0fdSAndre Fischer 3018590a0fdSAndre Fischer // ------------------------------------------------------------------- 3028590a0fdSAndre Fischer // virtual 3038590a0fdSAndre Fischer sal_Bool SerfSession::UsesProxy() 3048590a0fdSAndre Fischer { 3058590a0fdSAndre Fischer Init(); 3068590a0fdSAndre Fischer return ( m_aProxyName.getLength() > 0 ); 3078590a0fdSAndre Fischer } 3088590a0fdSAndre Fischer 3098590a0fdSAndre Fischer apr_status_t SerfSession::setupSerfConnection( apr_socket_t * inAprSocket, 3108590a0fdSAndre Fischer serf_bucket_t **outSerfInputBucket, 3118590a0fdSAndre Fischer serf_bucket_t **outSerfOutputBucket, 3128590a0fdSAndre Fischer apr_pool_t* /*inAprPool*/ ) 3138590a0fdSAndre Fischer { 3148590a0fdSAndre Fischer serf_bucket_t *tmpInputBkt; 3158590a0fdSAndre Fischer tmpInputBkt = serf_context_bucket_socket_create( getSerfContext(), 3168590a0fdSAndre Fischer inAprSocket, 3178590a0fdSAndre Fischer getSerfBktAlloc() ); 3188590a0fdSAndre Fischer 3198590a0fdSAndre Fischer if ( isSSLNeeded() ) 3208590a0fdSAndre Fischer { 3218590a0fdSAndre Fischer tmpInputBkt = serf_bucket_ssl_decrypt_create( tmpInputBkt, 3228590a0fdSAndre Fischer 0, 3238590a0fdSAndre Fischer getSerfBktAlloc() ); 324c58749d7SAndre Fischer /** Set the callback that is called to authenticate the 325c58749d7SAndre Fischer certifcate (chain). 326c58749d7SAndre Fischer */ 327c58749d7SAndre Fischer serf_ssl_server_cert_chain_callback_set( 328c58749d7SAndre Fischer serf_bucket_ssl_decrypt_context_get(tmpInputBkt), 32910e20387SAndre Fischer NULL, 330c58749d7SAndre Fischer Serf_CertificateChainValidation, 3318590a0fdSAndre Fischer this); 3328590a0fdSAndre Fischer serf_ssl_set_hostname( serf_bucket_ssl_decrypt_context_get( tmpInputBkt ), 3338590a0fdSAndre Fischer getHostinfo() ); 3348590a0fdSAndre Fischer 3358590a0fdSAndre Fischer *outSerfOutputBucket = serf_bucket_ssl_encrypt_create( *outSerfOutputBucket, 3368590a0fdSAndre Fischer serf_bucket_ssl_decrypt_context_get( tmpInputBkt ), 3378590a0fdSAndre Fischer getSerfBktAlloc() ); 3388590a0fdSAndre Fischer } 3398590a0fdSAndre Fischer 3408590a0fdSAndre Fischer *outSerfInputBucket = tmpInputBkt; 3418590a0fdSAndre Fischer 3428590a0fdSAndre Fischer return APR_SUCCESS; 3438590a0fdSAndre Fischer } 3448590a0fdSAndre Fischer 345fb7f54d2SOliver-Rainer Wittmann apr_status_t SerfSession::provideSerfCredentials( bool bGiveProvidedCredentialsASecondTry, 346fb7f54d2SOliver-Rainer Wittmann char ** outUsername, 3478590a0fdSAndre Fischer char ** outPassword, 3488590a0fdSAndre Fischer serf_request_t * /*inRequest*/, 3498590a0fdSAndre Fischer int /*inCode*/, 3508590a0fdSAndre Fischer const char *inAuthProtocol, 3518590a0fdSAndre Fischer const char *inRealm, 3528590a0fdSAndre Fischer apr_pool_t *inAprPool ) 3538590a0fdSAndre Fischer { 3548590a0fdSAndre Fischer DAVAuthListener * pListener = getRequestEnvironment().m_xAuthListener.get(); 3558590a0fdSAndre Fischer if ( !pListener ) 3568590a0fdSAndre Fischer { 3578590a0fdSAndre Fischer // abort 3588590a0fdSAndre Fischer return SERF_ERROR_AUTHN_FAILED; 3598590a0fdSAndre Fischer } 3608590a0fdSAndre Fischer 3618590a0fdSAndre Fischer rtl::OUString theUserName; 3628590a0fdSAndre Fischer rtl::OUString thePassWord; 3638590a0fdSAndre Fischer try 3648590a0fdSAndre Fischer { 3658590a0fdSAndre Fischer SerfUri uri( getRequestEnvironment().m_aRequestURI ); 3668590a0fdSAndre Fischer rtl::OUString aUserInfo( uri.GetUserInfo() ); 3678590a0fdSAndre Fischer if ( aUserInfo.getLength() ) 3688590a0fdSAndre Fischer { 3698590a0fdSAndre Fischer sal_Int32 nPos = aUserInfo.indexOf( '@' ); 3708590a0fdSAndre Fischer if ( nPos == -1 ) 3718590a0fdSAndre Fischer { 3728590a0fdSAndre Fischer theUserName = aUserInfo; 3738590a0fdSAndre Fischer } 3748590a0fdSAndre Fischer else 3758590a0fdSAndre Fischer { 3768590a0fdSAndre Fischer theUserName = aUserInfo.copy( 0, nPos ); 3778590a0fdSAndre Fischer thePassWord = aUserInfo.copy( nPos + 1 ); 3788590a0fdSAndre Fischer } 3798590a0fdSAndre Fischer } 3808590a0fdSAndre Fischer } 3818590a0fdSAndre Fischer catch ( DAVException const & ) 3828590a0fdSAndre Fischer { 3838590a0fdSAndre Fischer // abort 3848590a0fdSAndre Fischer return SERF_ERROR_AUTHN_FAILED; 3858590a0fdSAndre Fischer } 3868590a0fdSAndre Fischer 3878590a0fdSAndre Fischer const bool bCanUseSystemCreds = ( ( strcasecmp( inAuthProtocol, "NTLM" ) == 0 ) || 3888590a0fdSAndre Fischer ( strcasecmp( inAuthProtocol, "Negotiate" ) == 0 ) ); 3898590a0fdSAndre Fischer 3908590a0fdSAndre Fischer int theRetVal = pListener->authenticate( rtl::OUString::createFromAscii( inRealm ), 3918590a0fdSAndre Fischer getHostName(), 3928590a0fdSAndre Fischer theUserName, 3938590a0fdSAndre Fischer thePassWord, 394fb7f54d2SOliver-Rainer Wittmann bCanUseSystemCreds, 395fb7f54d2SOliver-Rainer Wittmann bGiveProvidedCredentialsASecondTry ? sal_False : sal_True ); 3968590a0fdSAndre Fischer 3978590a0fdSAndre Fischer if ( theRetVal == 0 ) 3988590a0fdSAndre Fischer { 39924c56ab9SHerbert Dürr *outUsername = apr_pstrdup( inAprPool, rtl::OUStringToOString( theUserName, RTL_TEXTENCODING_UTF8 ).getStr() ); 40024c56ab9SHerbert Dürr *outPassword = apr_pstrdup( inAprPool, rtl::OUStringToOString( thePassWord, RTL_TEXTENCODING_UTF8 ).getStr() ); 4018590a0fdSAndre Fischer } 4028590a0fdSAndre Fischer 4038590a0fdSAndre Fischer return theRetVal != 0 ? SERF_ERROR_AUTHN_FAILED : APR_SUCCESS; 4048590a0fdSAndre Fischer } 4058590a0fdSAndre Fischer 4068590a0fdSAndre Fischer namespace { 4078590a0fdSAndre Fischer // ------------------------------------------------------------------- 4088590a0fdSAndre Fischer // Helper function 4098590a0fdSAndre Fischer ::rtl::OUString GetHostnamePart( const ::rtl::OUString& _rRawString ) 4108590a0fdSAndre Fischer { 4118590a0fdSAndre Fischer ::rtl::OUString sPart; 4128590a0fdSAndre Fischer ::rtl::OUString sPartId = ::rtl::OUString::createFromAscii( "CN=" ); 4138590a0fdSAndre Fischer sal_Int32 nContStart = _rRawString.indexOf( sPartId ); 4148590a0fdSAndre Fischer if ( nContStart != -1 ) 4158590a0fdSAndre Fischer { 4168590a0fdSAndre Fischer nContStart = nContStart + sPartId.getLength(); 4178590a0fdSAndre Fischer sal_Int32 nContEnd 4188590a0fdSAndre Fischer = _rRawString.indexOf( sal_Unicode( ',' ), nContStart ); 4198590a0fdSAndre Fischer sPart = _rRawString.copy( nContStart, nContEnd - nContStart ); 4208590a0fdSAndre Fischer } 4218590a0fdSAndre Fischer return sPart; 4228590a0fdSAndre Fischer } 4238590a0fdSAndre Fischer } // namespace 4248590a0fdSAndre Fischer 4258590a0fdSAndre Fischer 426c58749d7SAndre Fischer apr_status_t SerfSession::verifySerfCertificateChain ( 427c58749d7SAndre Fischer int, 42810e20387SAndre Fischer const serf_ssl_certificate_t * const * pCertificateChainBase64Encoded, 429de38cc67SOliver-Rainer Wittmann int nCertificateChainLength) 430c58749d7SAndre Fischer { 431c58749d7SAndre Fischer // Check arguments. 432c58749d7SAndre Fischer if (pCertificateChainBase64Encoded == NULL || nCertificateChainLength<=0) 433c58749d7SAndre Fischer { 434c58749d7SAndre Fischer OSL_ASSERT(pCertificateChainBase64Encoded != NULL); 435c58749d7SAndre Fischer OSL_ASSERT(nCertificateChainLength>0); 436c58749d7SAndre Fischer return SERF_SSL_CERT_UNKNOWN_FAILURE; 437c58749d7SAndre Fischer } 438c58749d7SAndre Fischer 439c58749d7SAndre Fischer // Create some crypto objects to decode and handle the base64 440c58749d7SAndre Fischer // encoded certificate chain. 441c58749d7SAndre Fischer uno::Reference< xml::crypto::XSEInitializer > xSEInitializer; 4428590a0fdSAndre Fischer uno::Reference< security::XCertificateContainer > xCertificateContainer; 443c58749d7SAndre Fischer uno::Reference< xml::crypto::XXMLSecurityContext > xSecurityContext; 444c58749d7SAndre Fischer uno::Reference< xml::crypto::XSecurityEnvironment > xSecurityEnv; 4458590a0fdSAndre Fischer try 4468590a0fdSAndre Fischer { 447c58749d7SAndre Fischer // Create a certificate container. 448c58749d7SAndre Fischer xCertificateContainer = uno::Reference< security::XCertificateContainer >( 4498590a0fdSAndre Fischer getMSF()->createInstance( 4508590a0fdSAndre Fischer rtl::OUString::createFromAscii( 4518590a0fdSAndre Fischer "com.sun.star.security.CertificateContainer" ) ), 452c58749d7SAndre Fischer uno::UNO_QUERY_THROW); 453c58749d7SAndre Fischer 454c58749d7SAndre Fischer xSEInitializer = uno::Reference< xml::crypto::XSEInitializer >( 455c58749d7SAndre Fischer getMSF()->createInstance( 456c58749d7SAndre Fischer rtl::OUString::createFromAscii( "com.sun.star.xml.crypto.SEInitializer" ) ), 457c58749d7SAndre Fischer uno::UNO_QUERY_THROW); 458c58749d7SAndre Fischer 459c58749d7SAndre Fischer xSecurityContext = xSEInitializer->createSecurityContext( rtl::OUString() ); 460c58749d7SAndre Fischer if (xSecurityContext.is()) 461c58749d7SAndre Fischer xSecurityEnv = xSecurityContext->getSecurityEnvironment(); 462c58749d7SAndre Fischer 463c58749d7SAndre Fischer if ( ! xSecurityContext.is() || ! xSecurityEnv.is()) 464c58749d7SAndre Fischer { 465c58749d7SAndre Fischer // Do we have to dispose xSEInitializer or xCertificateContainer? 466c58749d7SAndre Fischer return SERF_SSL_CERT_UNKNOWN_FAILURE; 467c58749d7SAndre Fischer } 4688590a0fdSAndre Fischer } 4698590a0fdSAndre Fischer catch ( uno::Exception const &) 4708590a0fdSAndre Fischer { 471c58749d7SAndre Fischer return SERF_SSL_CERT_UNKNOWN_FAILURE; 4728590a0fdSAndre Fischer } 4738590a0fdSAndre Fischer 474c58749d7SAndre Fischer // Decode the server certificate. 47510e20387SAndre Fischer const char* sBase64EncodedServerCertificate ( 47610e20387SAndre Fischer serf_ssl_cert_export( 47710e20387SAndre Fischer pCertificateChainBase64Encoded[0], 47810e20387SAndre Fischer getAprPool())); 479c58749d7SAndre Fischer uno::Reference< security::XCertificate > xServerCertificate( 480c58749d7SAndre Fischer xSecurityEnv->createCertificateFromAscii( 48110e20387SAndre Fischer rtl::OUString::createFromAscii(sBase64EncodedServerCertificate))); 482c58749d7SAndre Fischer if ( ! xServerCertificate.is()) 4838590a0fdSAndre Fischer return SERF_SSL_CERT_UNKNOWN_FAILURE; 4848590a0fdSAndre Fischer 485c58749d7SAndre Fischer // Get the subject from the server certificate. 486c58749d7SAndre Fischer ::rtl::OUString sServerCertificateSubject (xServerCertificate->getSubjectName()); 487c58749d7SAndre Fischer sal_Int32 nIndex = 0; 488c58749d7SAndre Fischer while (nIndex >= 0) 4898590a0fdSAndre Fischer { 490c58749d7SAndre Fischer const ::rtl::OUString sToken (sServerCertificateSubject.getToken(0, ',', nIndex)); 491c58749d7SAndre Fischer if (sToken.compareToAscii("CN=", 3) == 0) 492c58749d7SAndre Fischer { 493c58749d7SAndre Fischer sServerCertificateSubject = sToken.copy(3); 494c58749d7SAndre Fischer break; 4958590a0fdSAndre Fischer } 496c58749d7SAndre Fischer else if (sToken.compareToAscii(" CN=", 4) == 0) 4978590a0fdSAndre Fischer { 498c58749d7SAndre Fischer sServerCertificateSubject = sToken.copy(4); 499c58749d7SAndre Fischer break; 5008590a0fdSAndre Fischer } 5018590a0fdSAndre Fischer } 5028590a0fdSAndre Fischer 503c58749d7SAndre Fischer // When the certificate container already contains a (trusted) 504c58749d7SAndre Fischer // entry for the server then we do not have to authenticate any 505c58749d7SAndre Fischer // certificate. 506c58749d7SAndre Fischer const security::CertificateContainerStatus eStatus ( 5078590a0fdSAndre Fischer xCertificateContainer->hasCertificate( 508c58749d7SAndre Fischer getHostName(), sServerCertificateSubject ) ); 509c58749d7SAndre Fischer if (eStatus != security::CertificateContainerStatus_NOCERT) 5108590a0fdSAndre Fischer { 511c58749d7SAndre Fischer return eStatus == security::CertificateContainerStatus_TRUSTED 5128590a0fdSAndre Fischer ? APR_SUCCESS 5138590a0fdSAndre Fischer : SERF_SSL_CERT_UNKNOWN_FAILURE; 5148590a0fdSAndre Fischer } 5158590a0fdSAndre Fischer 516c58749d7SAndre Fischer // The shortcut failed, so try to verify the whole chain. This is 517c58749d7SAndre Fischer // done outside the isDomainMatch() block because the result is 518c58749d7SAndre Fischer // used by the interaction handler. 519c58749d7SAndre Fischer std::vector< uno::Reference< security::XCertificate > > aChain; 520fdf35928SAndre Fischer for (nIndex=1; nIndex<nCertificateChainLength; ++nIndex) 5218590a0fdSAndre Fischer { 52210e20387SAndre Fischer const char* sBase64EncodedCertificate ( 52310e20387SAndre Fischer serf_ssl_cert_export( 52410e20387SAndre Fischer pCertificateChainBase64Encoded[nIndex], 52510e20387SAndre Fischer getAprPool())); 526c58749d7SAndre Fischer uno::Reference< security::XCertificate > xCertificate( 527c58749d7SAndre Fischer xSecurityEnv->createCertificateFromAscii( 52810e20387SAndre Fischer rtl::OUString::createFromAscii(sBase64EncodedCertificate))); 529c58749d7SAndre Fischer if ( ! xCertificate.is()) 5308590a0fdSAndre Fischer return SERF_SSL_CERT_UNKNOWN_FAILURE; 531c58749d7SAndre Fischer aChain.push_back(xCertificate); 5328590a0fdSAndre Fischer } 533c58749d7SAndre Fischer const sal_Int64 nVerificationResult (xSecurityEnv->verifyCertificate( 534c58749d7SAndre Fischer xServerCertificate, 535c58749d7SAndre Fischer ::comphelper::containerToSequence(aChain))); 5368590a0fdSAndre Fischer 537c58749d7SAndre Fischer // When the certificate matches the host name then we can use the 538c58749d7SAndre Fischer // result of the verification. 539e54851feSOliver-Rainer Wittmann bool bHostnameMatchesCertHostnames = false; 540e54851feSOliver-Rainer Wittmann { 541e54851feSOliver-Rainer Wittmann uno::Sequence< uno::Reference< security::XCertificateExtension > > extensions = xServerCertificate->getExtensions(); 542e54851feSOliver-Rainer Wittmann uno::Sequence< security::CertAltNameEntry > altNames; 543e54851feSOliver-Rainer Wittmann for (sal_Int32 i = 0 ; i < extensions.getLength(); ++i) 544e54851feSOliver-Rainer Wittmann { 545e54851feSOliver-Rainer Wittmann uno::Reference< security::XCertificateExtension >element = extensions[i]; 546e54851feSOliver-Rainer Wittmann 547e54851feSOliver-Rainer Wittmann const rtl::OString aId ( (const sal_Char *)element->getExtensionId().getArray(), element->getExtensionId().getLength()); 548e54851feSOliver-Rainer Wittmann if ( aId.equals( OID_SUBJECT_ALTERNATIVE_NAME ) ) 549e54851feSOliver-Rainer Wittmann { 550e54851feSOliver-Rainer Wittmann uno::Reference< security::XSanExtension > sanExtension ( element, uno::UNO_QUERY ); 551e54851feSOliver-Rainer Wittmann altNames = sanExtension->getAlternativeNames(); 552e54851feSOliver-Rainer Wittmann break; 553e54851feSOliver-Rainer Wittmann } 554e54851feSOliver-Rainer Wittmann } 555e54851feSOliver-Rainer Wittmann 556e54851feSOliver-Rainer Wittmann uno::Sequence< ::rtl::OUString > certHostNames(altNames.getLength() + 1); 557e54851feSOliver-Rainer Wittmann certHostNames[0] = sServerCertificateSubject; 558e54851feSOliver-Rainer Wittmann for( int n = 0; n < altNames.getLength(); ++n ) 559e54851feSOliver-Rainer Wittmann { 560e54851feSOliver-Rainer Wittmann if (altNames[n].Type == security::ExtAltNameType_DNS_NAME) 561e54851feSOliver-Rainer Wittmann { 562e54851feSOliver-Rainer Wittmann altNames[n].Value >>= certHostNames[n+1]; 563e54851feSOliver-Rainer Wittmann } 564e54851feSOliver-Rainer Wittmann } 565e54851feSOliver-Rainer Wittmann 566e54851feSOliver-Rainer Wittmann for ( int i = 0; i < certHostNames.getLength() && !bHostnameMatchesCertHostnames; ++i ) 567e54851feSOliver-Rainer Wittmann { 568e54851feSOliver-Rainer Wittmann bHostnameMatchesCertHostnames = isDomainMatch( certHostNames[i] ); 569e54851feSOliver-Rainer Wittmann } 570e54851feSOliver-Rainer Wittmann 571e54851feSOliver-Rainer Wittmann } 572e54851feSOliver-Rainer Wittmann if ( bHostnameMatchesCertHostnames ) 5738590a0fdSAndre Fischer { 574c58749d7SAndre Fischer 575c58749d7SAndre Fischer if (nVerificationResult == 0) 576c58749d7SAndre Fischer { 577c58749d7SAndre Fischer // Certificate (chain) is valid. 578c58749d7SAndre Fischer xCertificateContainer->addCertificate(getHostName(), sServerCertificateSubject, sal_True); 5798590a0fdSAndre Fischer return APR_SUCCESS; 5808590a0fdSAndre Fischer } 581c58749d7SAndre Fischer else if ((nVerificationResult & security::CertificateValidity::CHAIN_INCOMPLETE) != 0) 582c58749d7SAndre Fischer { 583c58749d7SAndre Fischer // We do not have enough information for verification, 584c58749d7SAndre Fischer // neither automatically (as we just discovered) nor 585c58749d7SAndre Fischer // manually (so there is no point in showing any dialog.) 586c58749d7SAndre Fischer return SERF_SSL_CERT_UNKNOWN_FAILURE; 587c58749d7SAndre Fischer } 588c58749d7SAndre Fischer else if ((nVerificationResult & 589c58749d7SAndre Fischer (security::CertificateValidity::INVALID | security::CertificateValidity::REVOKED)) != 0) 590c58749d7SAndre Fischer { 591c58749d7SAndre Fischer // Certificate (chain) is invalid. 592c58749d7SAndre Fischer xCertificateContainer->addCertificate(getHostName(), sServerCertificateSubject, sal_False); 593c58749d7SAndre Fischer return SERF_SSL_CERT_UNKNOWN_FAILURE; 594c58749d7SAndre Fischer } 595c58749d7SAndre Fischer else 596c58749d7SAndre Fischer { 597c58749d7SAndre Fischer // For all other we have to ask the user. 598c58749d7SAndre Fischer } 599c58749d7SAndre Fischer } 6008590a0fdSAndre Fischer 601c58749d7SAndre Fischer // We have not been able to automatically verify (or falsify) the 602c58749d7SAndre Fischer // certificate chain. To resolve this we have to ask the user. 6038590a0fdSAndre Fischer const uno::Reference< ucb::XCommandEnvironment > xEnv( getRequestEnvironment().m_xEnv ); 6048590a0fdSAndre Fischer if ( xEnv.is() ) 6058590a0fdSAndre Fischer { 6068590a0fdSAndre Fischer uno::Reference< task::XInteractionHandler > xIH( xEnv->getInteractionHandler() ); 6078590a0fdSAndre Fischer if ( xIH.is() ) 6088590a0fdSAndre Fischer { 6098590a0fdSAndre Fischer rtl::Reference< ucbhelper::SimpleCertificateValidationRequest > 6108590a0fdSAndre Fischer xRequest( new ucbhelper::SimpleCertificateValidationRequest( 611c58749d7SAndre Fischer static_cast<sal_Int32>(nVerificationResult), xServerCertificate, getHostName() ) ); 6128590a0fdSAndre Fischer xIH->handle( xRequest.get() ); 6138590a0fdSAndre Fischer 6148590a0fdSAndre Fischer rtl::Reference< ucbhelper::InteractionContinuation > xSelection 6158590a0fdSAndre Fischer = xRequest->getSelection(); 6168590a0fdSAndre Fischer 6178590a0fdSAndre Fischer if ( xSelection.is() ) 6188590a0fdSAndre Fischer { 619e54851feSOliver-Rainer Wittmann uno::Reference< task::XInteractionApprove > xApprove( xSelection.get(), uno::UNO_QUERY ); 6208590a0fdSAndre Fischer if ( xApprove.is() ) 6218590a0fdSAndre Fischer { 622c58749d7SAndre Fischer xCertificateContainer->addCertificate( getHostName(), sServerCertificateSubject, sal_True ); 6238590a0fdSAndre Fischer return APR_SUCCESS; 6248590a0fdSAndre Fischer } 6258590a0fdSAndre Fischer else 6268590a0fdSAndre Fischer { 6278590a0fdSAndre Fischer // Don't trust cert 628c58749d7SAndre Fischer xCertificateContainer->addCertificate( getHostName(), sServerCertificateSubject, sal_False ); 6298590a0fdSAndre Fischer return SERF_SSL_CERT_UNKNOWN_FAILURE; 6308590a0fdSAndre Fischer } 6318590a0fdSAndre Fischer } 6328590a0fdSAndre Fischer } 6338590a0fdSAndre Fischer else 6348590a0fdSAndre Fischer { 6358590a0fdSAndre Fischer // Don't trust cert 636c58749d7SAndre Fischer xCertificateContainer->addCertificate( getHostName(), sServerCertificateSubject, sal_False ); 6378590a0fdSAndre Fischer return SERF_SSL_CERT_UNKNOWN_FAILURE; 6388590a0fdSAndre Fischer } 6398590a0fdSAndre Fischer } 640c58749d7SAndre Fischer 6418590a0fdSAndre Fischer return SERF_SSL_CERT_UNKNOWN_FAILURE; 6428590a0fdSAndre Fischer } 6438590a0fdSAndre Fischer 6448590a0fdSAndre Fischer serf_bucket_t* SerfSession::acceptSerfResponse( serf_request_t * inSerfRequest, 6458590a0fdSAndre Fischer serf_bucket_t * inSerfStreamBucket, 6468590a0fdSAndre Fischer apr_pool_t* /*inAprPool*/ ) 6478590a0fdSAndre Fischer { 6488590a0fdSAndre Fischer // get the per-request bucket allocator 6498590a0fdSAndre Fischer serf_bucket_alloc_t* SerfBktAlloc = serf_request_get_alloc( inSerfRequest ); 6508590a0fdSAndre Fischer 6518590a0fdSAndre Fischer // create a barrier bucket so the response doesn't eat us! 6528590a0fdSAndre Fischer serf_bucket_t *responseBkt = serf_bucket_barrier_create( inSerfStreamBucket, 6538590a0fdSAndre Fischer SerfBktAlloc ); 6548590a0fdSAndre Fischer 6558590a0fdSAndre Fischer // create response bucket 6568590a0fdSAndre Fischer responseBkt = serf_bucket_response_create( responseBkt, 6578590a0fdSAndre Fischer SerfBktAlloc ); 6588590a0fdSAndre Fischer 6598590a0fdSAndre Fischer if ( isHeadRequestInProgress() ) 6608590a0fdSAndre Fischer { 6618590a0fdSAndre Fischer // advise the response bucket that this was from a HEAD request and that it should not expect to see a response body. 6628590a0fdSAndre Fischer serf_bucket_response_set_head( responseBkt ); 6638590a0fdSAndre Fischer } 6648590a0fdSAndre Fischer 6658590a0fdSAndre Fischer return responseBkt; 6668590a0fdSAndre Fischer } 6678590a0fdSAndre Fischer 66849989859SOliver-Rainer Wittmann SerfRequestProcessor* SerfSession::createReqProc( const rtl::OUString & inPath ) 66949989859SOliver-Rainer Wittmann { 67049989859SOliver-Rainer Wittmann return new SerfRequestProcessor( *this, 67149989859SOliver-Rainer Wittmann inPath, 67249989859SOliver-Rainer Wittmann m_bUseChunkedEncoding ); 67349989859SOliver-Rainer Wittmann } 67449989859SOliver-Rainer Wittmann 6758590a0fdSAndre Fischer // ------------------------------------------------------------------- 6768590a0fdSAndre Fischer // PROPFIND - allprop & named 6778590a0fdSAndre Fischer // ------------------------------------------------------------------- 6788590a0fdSAndre Fischer void SerfSession::PROPFIND( const rtl::OUString & inPath, 6798590a0fdSAndre Fischer const Depth inDepth, 6808590a0fdSAndre Fischer const std::vector< rtl::OUString > & inPropNames, 6818590a0fdSAndre Fischer std::vector< DAVResource > & ioResources, 6828590a0fdSAndre Fischer const DAVRequestEnvironment & rEnv ) 6838590a0fdSAndre Fischer throw ( DAVException ) 6848590a0fdSAndre Fischer { 6858590a0fdSAndre Fischer osl::Guard< osl::Mutex > theGuard( m_aMutex ); 6868590a0fdSAndre Fischer 6878590a0fdSAndre Fischer Init( rEnv ); 6888590a0fdSAndre Fischer 6898590a0fdSAndre Fischer apr_status_t status = APR_SUCCESS; 69049989859SOliver-Rainer Wittmann boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); 69149989859SOliver-Rainer Wittmann aReqProc->processPropFind( inDepth, 6928590a0fdSAndre Fischer inPropNames, 6938590a0fdSAndre Fischer ioResources, 6948590a0fdSAndre Fischer status ); 6958590a0fdSAndre Fischer 6968590a0fdSAndre Fischer if ( status == APR_SUCCESS && 69749989859SOliver-Rainer Wittmann aReqProc->mpDAVException == 0 && 6988590a0fdSAndre Fischer ioResources.empty() ) 6998590a0fdSAndre Fischer { 7008590a0fdSAndre Fischer m_aEnv = DAVRequestEnvironment(); 7018590a0fdSAndre Fischer throw DAVException( DAVException::DAV_HTTP_ERROR, inPath, (sal_uInt16)APR_EGENERAL ); 7028590a0fdSAndre Fischer } 70349989859SOliver-Rainer Wittmann HandleError( aReqProc ); 7048590a0fdSAndre Fischer } 7058590a0fdSAndre Fischer 7068590a0fdSAndre Fischer // ------------------------------------------------------------------- 7078590a0fdSAndre Fischer // PROPFIND - propnames 7088590a0fdSAndre Fischer // ------------------------------------------------------------------- 7098590a0fdSAndre Fischer void SerfSession::PROPFIND( const rtl::OUString & inPath, 7108590a0fdSAndre Fischer const Depth inDepth, 7118590a0fdSAndre Fischer std::vector< DAVResourceInfo > & ioResInfo, 7128590a0fdSAndre Fischer const DAVRequestEnvironment & rEnv ) 7138590a0fdSAndre Fischer throw( DAVException ) 7148590a0fdSAndre Fischer { 7158590a0fdSAndre Fischer osl::Guard< osl::Mutex > theGuard( m_aMutex ); 7168590a0fdSAndre Fischer 7178590a0fdSAndre Fischer Init( rEnv ); 7188590a0fdSAndre Fischer 7198590a0fdSAndre Fischer apr_status_t status = APR_SUCCESS; 72049989859SOliver-Rainer Wittmann boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); 72149989859SOliver-Rainer Wittmann aReqProc->processPropFind( inDepth, 7228590a0fdSAndre Fischer ioResInfo, 7238590a0fdSAndre Fischer status ); 7248590a0fdSAndre Fischer 7258590a0fdSAndre Fischer if ( status == APR_SUCCESS && 72649989859SOliver-Rainer Wittmann aReqProc->mpDAVException == 0 && 7278590a0fdSAndre Fischer ioResInfo.empty() ) 7288590a0fdSAndre Fischer { 7298590a0fdSAndre Fischer m_aEnv = DAVRequestEnvironment(); 7308590a0fdSAndre Fischer throw DAVException( DAVException::DAV_HTTP_ERROR, inPath, (sal_uInt16)APR_EGENERAL ); 7318590a0fdSAndre Fischer } 73249989859SOliver-Rainer Wittmann HandleError( aReqProc ); 7338590a0fdSAndre Fischer } 7348590a0fdSAndre Fischer 7358590a0fdSAndre Fischer // ------------------------------------------------------------------- 7368590a0fdSAndre Fischer // PROPPATCH 7378590a0fdSAndre Fischer // ------------------------------------------------------------------- 7388590a0fdSAndre Fischer void SerfSession::PROPPATCH( const rtl::OUString & inPath, 7398590a0fdSAndre Fischer const std::vector< ProppatchValue > & inValues, 7408590a0fdSAndre Fischer const DAVRequestEnvironment & rEnv ) 7418590a0fdSAndre Fischer throw( DAVException ) 7428590a0fdSAndre Fischer { 7438590a0fdSAndre Fischer osl::Guard< osl::Mutex > theGuard( m_aMutex ); 7448590a0fdSAndre Fischer 7458590a0fdSAndre Fischer Init( rEnv ); 7468590a0fdSAndre Fischer 7478590a0fdSAndre Fischer apr_status_t status = APR_SUCCESS; 74849989859SOliver-Rainer Wittmann boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); 749*8fd7bf9dSAndrea Pescetti //check whether a lock on this resource is already owned 750*8fd7bf9dSAndrea Pescetti rtl::OUString aUri( composeCurrentUri( inPath ) ); 751*8fd7bf9dSAndrea Pescetti ucb::Lock inLock; 752*8fd7bf9dSAndrea Pescetti SerfLock * pLock = m_aSerfLockStore.findByUri( aUri ); 753*8fd7bf9dSAndrea Pescetti if ( pLock ) 754*8fd7bf9dSAndrea Pescetti { 755*8fd7bf9dSAndrea Pescetti inLock = pLock->getLock(); 756*8fd7bf9dSAndrea Pescetti } 75749989859SOliver-Rainer Wittmann aReqProc->processPropPatch( inValues, 758*8fd7bf9dSAndrea Pescetti inLock, 7598590a0fdSAndre Fischer status ); 7608590a0fdSAndre Fischer 76149989859SOliver-Rainer Wittmann HandleError( aReqProc ); 7628590a0fdSAndre Fischer } 7638590a0fdSAndre Fischer 7648590a0fdSAndre Fischer // ------------------------------------------------------------------- 7658590a0fdSAndre Fischer // HEAD 7668590a0fdSAndre Fischer // ------------------------------------------------------------------- 7678590a0fdSAndre Fischer void SerfSession::HEAD( const ::rtl::OUString & inPath, 7688590a0fdSAndre Fischer const std::vector< ::rtl::OUString > & inHeaderNames, 7698590a0fdSAndre Fischer DAVResource & ioResource, 7708590a0fdSAndre Fischer const DAVRequestEnvironment & rEnv ) 7718590a0fdSAndre Fischer throw( DAVException ) 7728590a0fdSAndre Fischer { 7738590a0fdSAndre Fischer osl::Guard< osl::Mutex > theGuard( m_aMutex ); 7748590a0fdSAndre Fischer 7758590a0fdSAndre Fischer Init( rEnv ); 7768590a0fdSAndre Fischer 7778590a0fdSAndre Fischer m_bIsHeadRequestInProgress = true; 7788590a0fdSAndre Fischer 77949989859SOliver-Rainer Wittmann boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); 7808590a0fdSAndre Fischer ioResource.uri = inPath; 7818590a0fdSAndre Fischer ioResource.properties.clear(); 7828590a0fdSAndre Fischer apr_status_t status = APR_SUCCESS; 78349989859SOliver-Rainer Wittmann aReqProc->processHead( inHeaderNames, 7848590a0fdSAndre Fischer ioResource, 7858590a0fdSAndre Fischer status ); 7868590a0fdSAndre Fischer 7878590a0fdSAndre Fischer m_bIsHeadRequestInProgress = false; 78849989859SOliver-Rainer Wittmann 78949989859SOliver-Rainer Wittmann HandleError( aReqProc ); 7908590a0fdSAndre Fischer } 7918590a0fdSAndre Fischer 7928590a0fdSAndre Fischer // ------------------------------------------------------------------- 7938590a0fdSAndre Fischer // GET 7948590a0fdSAndre Fischer // ------------------------------------------------------------------- 7958590a0fdSAndre Fischer uno::Reference< io::XInputStream > 7968590a0fdSAndre Fischer SerfSession::GET( const rtl::OUString & inPath, 7978590a0fdSAndre Fischer const DAVRequestEnvironment & rEnv ) 7988590a0fdSAndre Fischer throw ( DAVException ) 7998590a0fdSAndre Fischer { 8008590a0fdSAndre Fischer osl::Guard< osl::Mutex > theGuard( m_aMutex ); 8018590a0fdSAndre Fischer 8028590a0fdSAndre Fischer Init( rEnv ); 8038590a0fdSAndre Fischer 8048590a0fdSAndre Fischer uno::Reference< SerfInputStream > xInputStream( new SerfInputStream ); 8058590a0fdSAndre Fischer apr_status_t status = APR_SUCCESS; 80649989859SOliver-Rainer Wittmann boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); 80749989859SOliver-Rainer Wittmann aReqProc->processGet( xInputStream, 8088590a0fdSAndre Fischer status ); 8098590a0fdSAndre Fischer 81049989859SOliver-Rainer Wittmann HandleError( aReqProc ); 8118590a0fdSAndre Fischer 8128590a0fdSAndre Fischer return uno::Reference< io::XInputStream >( xInputStream.get() ); 8138590a0fdSAndre Fischer } 8148590a0fdSAndre Fischer 8158590a0fdSAndre Fischer // ------------------------------------------------------------------- 8168590a0fdSAndre Fischer // GET 8178590a0fdSAndre Fischer // ------------------------------------------------------------------- 8188590a0fdSAndre Fischer void SerfSession::GET( const rtl::OUString & inPath, 8198590a0fdSAndre Fischer uno::Reference< io::XOutputStream > & ioOutputStream, 8208590a0fdSAndre Fischer const DAVRequestEnvironment & rEnv ) 8218590a0fdSAndre Fischer throw ( DAVException ) 8228590a0fdSAndre Fischer { 8238590a0fdSAndre Fischer osl::Guard< osl::Mutex > theGuard( m_aMutex ); 8248590a0fdSAndre Fischer 8258590a0fdSAndre Fischer Init( rEnv ); 8268590a0fdSAndre Fischer 8278590a0fdSAndre Fischer apr_status_t status = APR_SUCCESS; 82849989859SOliver-Rainer Wittmann boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); 82949989859SOliver-Rainer Wittmann aReqProc->processGet( ioOutputStream, 8308590a0fdSAndre Fischer status ); 8318590a0fdSAndre Fischer 83249989859SOliver-Rainer Wittmann HandleError( aReqProc ); 8338590a0fdSAndre Fischer } 8348590a0fdSAndre Fischer 8358590a0fdSAndre Fischer // ------------------------------------------------------------------- 8368590a0fdSAndre Fischer // GET 8378590a0fdSAndre Fischer // ------------------------------------------------------------------- 8388590a0fdSAndre Fischer uno::Reference< io::XInputStream > 8398590a0fdSAndre Fischer SerfSession::GET( const rtl::OUString & inPath, 8408590a0fdSAndre Fischer const std::vector< ::rtl::OUString > & inHeaderNames, 8418590a0fdSAndre Fischer DAVResource & ioResource, 8428590a0fdSAndre Fischer const DAVRequestEnvironment & rEnv ) 8438590a0fdSAndre Fischer throw ( DAVException ) 8448590a0fdSAndre Fischer { 8458590a0fdSAndre Fischer osl::Guard< osl::Mutex > theGuard( m_aMutex ); 8468590a0fdSAndre Fischer 8478590a0fdSAndre Fischer Init( rEnv ); 8488590a0fdSAndre Fischer 84949989859SOliver-Rainer Wittmann boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); 8508590a0fdSAndre Fischer uno::Reference< SerfInputStream > xInputStream( new SerfInputStream ); 8518590a0fdSAndre Fischer ioResource.uri = inPath; 8528590a0fdSAndre Fischer ioResource.properties.clear(); 8538590a0fdSAndre Fischer apr_status_t status = APR_SUCCESS; 85449989859SOliver-Rainer Wittmann aReqProc->processGet( xInputStream, 8558590a0fdSAndre Fischer inHeaderNames, 8568590a0fdSAndre Fischer ioResource, 8578590a0fdSAndre Fischer status ); 8588590a0fdSAndre Fischer 85949989859SOliver-Rainer Wittmann HandleError( aReqProc ); 8608590a0fdSAndre Fischer 8618590a0fdSAndre Fischer return uno::Reference< io::XInputStream >( xInputStream.get() ); 8628590a0fdSAndre Fischer } 8638590a0fdSAndre Fischer 8648590a0fdSAndre Fischer 8658590a0fdSAndre Fischer // ------------------------------------------------------------------- 8668590a0fdSAndre Fischer // GET 8678590a0fdSAndre Fischer // ------------------------------------------------------------------- 8688590a0fdSAndre Fischer void SerfSession::GET( const rtl::OUString & inPath, 8698590a0fdSAndre Fischer uno::Reference< io::XOutputStream > & ioOutputStream, 8708590a0fdSAndre Fischer const std::vector< ::rtl::OUString > & inHeaderNames, 8718590a0fdSAndre Fischer DAVResource & ioResource, 8728590a0fdSAndre Fischer const DAVRequestEnvironment & rEnv ) 8738590a0fdSAndre Fischer throw ( DAVException ) 8748590a0fdSAndre Fischer { 8758590a0fdSAndre Fischer osl::Guard< osl::Mutex > theGuard( m_aMutex ); 8768590a0fdSAndre Fischer 8778590a0fdSAndre Fischer Init( rEnv ); 8788590a0fdSAndre Fischer 87949989859SOliver-Rainer Wittmann boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); 8808590a0fdSAndre Fischer ioResource.uri = inPath; 8818590a0fdSAndre Fischer ioResource.properties.clear(); 8828590a0fdSAndre Fischer apr_status_t status = APR_SUCCESS; 88349989859SOliver-Rainer Wittmann aReqProc->processGet( ioOutputStream, 8848590a0fdSAndre Fischer inHeaderNames, 8858590a0fdSAndre Fischer ioResource, 8868590a0fdSAndre Fischer status ); 8878590a0fdSAndre Fischer 88849989859SOliver-Rainer Wittmann HandleError( aReqProc ); 8898590a0fdSAndre Fischer } 8908590a0fdSAndre Fischer 8918590a0fdSAndre Fischer // ------------------------------------------------------------------- 8928590a0fdSAndre Fischer // PUT 8938590a0fdSAndre Fischer // ------------------------------------------------------------------- 8948590a0fdSAndre Fischer void SerfSession::PUT( const rtl::OUString & inPath, 8958590a0fdSAndre Fischer const uno::Reference< io::XInputStream > & inInputStream, 8968590a0fdSAndre Fischer const DAVRequestEnvironment & rEnv ) 8978590a0fdSAndre Fischer throw ( DAVException ) 8988590a0fdSAndre Fischer { 8998590a0fdSAndre Fischer osl::Guard< osl::Mutex > theGuard( m_aMutex ); 9008590a0fdSAndre Fischer 9018590a0fdSAndre Fischer Init( rEnv ); 9028590a0fdSAndre Fischer 90349989859SOliver-Rainer Wittmann boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); 9048590a0fdSAndre Fischer uno::Sequence< sal_Int8 > aDataToSend; 9058590a0fdSAndre Fischer if ( !getDataFromInputStream( inInputStream, aDataToSend, false ) ) 9068590a0fdSAndre Fischer throw DAVException( DAVException::DAV_INVALID_ARG ); 9078590a0fdSAndre Fischer apr_status_t status = APR_SUCCESS; 908*8fd7bf9dSAndrea Pescetti 909*8fd7bf9dSAndrea Pescetti //check whether a lock on this resource is already owned 910*8fd7bf9dSAndrea Pescetti rtl::OUString aUri( composeCurrentUri( inPath ) ); 911*8fd7bf9dSAndrea Pescetti ucb::Lock inLock; 912*8fd7bf9dSAndrea Pescetti SerfLock * pLock = m_aSerfLockStore.findByUri( aUri ); 913*8fd7bf9dSAndrea Pescetti if ( pLock ) 914*8fd7bf9dSAndrea Pescetti { 915*8fd7bf9dSAndrea Pescetti inLock = pLock->getLock(); 916*8fd7bf9dSAndrea Pescetti } 91749989859SOliver-Rainer Wittmann aReqProc->processPut( reinterpret_cast< const char * >( aDataToSend.getConstArray() ), 9188590a0fdSAndre Fischer aDataToSend.getLength(), 919*8fd7bf9dSAndrea Pescetti inLock, 9208590a0fdSAndre Fischer status ); 9218590a0fdSAndre Fischer 92249989859SOliver-Rainer Wittmann HandleError( aReqProc ); 9238590a0fdSAndre Fischer } 9248590a0fdSAndre Fischer 9258590a0fdSAndre Fischer // ------------------------------------------------------------------- 9268590a0fdSAndre Fischer // POST 9278590a0fdSAndre Fischer // ------------------------------------------------------------------- 9288590a0fdSAndre Fischer uno::Reference< io::XInputStream > 9298590a0fdSAndre Fischer SerfSession::POST( const rtl::OUString & inPath, 9308590a0fdSAndre Fischer const rtl::OUString & rContentType, 9318590a0fdSAndre Fischer const rtl::OUString & rReferer, 9328590a0fdSAndre Fischer const uno::Reference< io::XInputStream > & inInputStream, 9338590a0fdSAndre Fischer const DAVRequestEnvironment & rEnv ) 9348590a0fdSAndre Fischer throw ( DAVException ) 9358590a0fdSAndre Fischer { 9368590a0fdSAndre Fischer osl::Guard< osl::Mutex > theGuard( m_aMutex ); 9378590a0fdSAndre Fischer 9388590a0fdSAndre Fischer uno::Sequence< sal_Int8 > aDataToSend; 9398590a0fdSAndre Fischer if ( !getDataFromInputStream( inInputStream, aDataToSend, true ) ) 9408590a0fdSAndre Fischer { 9418590a0fdSAndre Fischer throw DAVException( DAVException::DAV_INVALID_ARG ); 9428590a0fdSAndre Fischer } 9438590a0fdSAndre Fischer 9448590a0fdSAndre Fischer Init( rEnv ); 9458590a0fdSAndre Fischer 94649989859SOliver-Rainer Wittmann boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); 9478590a0fdSAndre Fischer uno::Reference< SerfInputStream > xInputStream( new SerfInputStream ); 9488590a0fdSAndre Fischer apr_status_t status = APR_SUCCESS; 949*8fd7bf9dSAndrea Pescetti //check whether a lock on this resource is already owned 950*8fd7bf9dSAndrea Pescetti rtl::OUString aUri( composeCurrentUri( inPath ) ); 951*8fd7bf9dSAndrea Pescetti ucb::Lock inLock; 952*8fd7bf9dSAndrea Pescetti SerfLock * pLock = m_aSerfLockStore.findByUri( aUri ); 953*8fd7bf9dSAndrea Pescetti if ( pLock ) 954*8fd7bf9dSAndrea Pescetti { 955*8fd7bf9dSAndrea Pescetti inLock = pLock->getLock(); 956*8fd7bf9dSAndrea Pescetti } 95749989859SOliver-Rainer Wittmann aReqProc->processPost( reinterpret_cast< const char * >( aDataToSend.getConstArray() ), 9588590a0fdSAndre Fischer aDataToSend.getLength(), 9598590a0fdSAndre Fischer rContentType, 9608590a0fdSAndre Fischer rReferer, 961*8fd7bf9dSAndrea Pescetti inLock, 9628590a0fdSAndre Fischer xInputStream, 9638590a0fdSAndre Fischer status ); 9648590a0fdSAndre Fischer 96549989859SOliver-Rainer Wittmann HandleError( aReqProc ); 9668590a0fdSAndre Fischer return uno::Reference< io::XInputStream >( xInputStream.get() ); 9678590a0fdSAndre Fischer } 9688590a0fdSAndre Fischer 9698590a0fdSAndre Fischer // ------------------------------------------------------------------- 9708590a0fdSAndre Fischer // POST 9718590a0fdSAndre Fischer // ------------------------------------------------------------------- 9728590a0fdSAndre Fischer void SerfSession::POST( const rtl::OUString & inPath, 9738590a0fdSAndre Fischer const rtl::OUString & rContentType, 9748590a0fdSAndre Fischer const rtl::OUString & rReferer, 9758590a0fdSAndre Fischer const uno::Reference< io::XInputStream > & inInputStream, 9768590a0fdSAndre Fischer uno::Reference< io::XOutputStream > & oOutputStream, 9778590a0fdSAndre Fischer const DAVRequestEnvironment & rEnv ) 9788590a0fdSAndre Fischer throw ( DAVException ) 9798590a0fdSAndre Fischer { 9808590a0fdSAndre Fischer osl::Guard< osl::Mutex > theGuard( m_aMutex ); 9818590a0fdSAndre Fischer 9828590a0fdSAndre Fischer uno::Sequence< sal_Int8 > aDataToSend; 9838590a0fdSAndre Fischer if ( !getDataFromInputStream( inInputStream, aDataToSend, true ) ) 9848590a0fdSAndre Fischer { 9858590a0fdSAndre Fischer throw DAVException( DAVException::DAV_INVALID_ARG ); 9868590a0fdSAndre Fischer } 9878590a0fdSAndre Fischer 9888590a0fdSAndre Fischer Init( rEnv ); 9898590a0fdSAndre Fischer 99049989859SOliver-Rainer Wittmann boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); 9918590a0fdSAndre Fischer apr_status_t status = APR_SUCCESS; 992*8fd7bf9dSAndrea Pescetti //check whether a lock on this resource is already owned 993*8fd7bf9dSAndrea Pescetti rtl::OUString aUri( composeCurrentUri( inPath ) ); 994*8fd7bf9dSAndrea Pescetti ucb::Lock inLock; 995*8fd7bf9dSAndrea Pescetti SerfLock * pLock = m_aSerfLockStore.findByUri( aUri ); 996*8fd7bf9dSAndrea Pescetti if ( pLock ) 997*8fd7bf9dSAndrea Pescetti { 998*8fd7bf9dSAndrea Pescetti inLock = pLock->getLock(); 999*8fd7bf9dSAndrea Pescetti } 100049989859SOliver-Rainer Wittmann aReqProc->processPost( reinterpret_cast< const char * >( aDataToSend.getConstArray() ), 10018590a0fdSAndre Fischer aDataToSend.getLength(), 10028590a0fdSAndre Fischer rContentType, 10038590a0fdSAndre Fischer rReferer, 1004*8fd7bf9dSAndrea Pescetti inLock, 10058590a0fdSAndre Fischer oOutputStream, 10068590a0fdSAndre Fischer status ); 10078590a0fdSAndre Fischer 100849989859SOliver-Rainer Wittmann HandleError( aReqProc ); 10098590a0fdSAndre Fischer } 10108590a0fdSAndre Fischer 10118590a0fdSAndre Fischer // ------------------------------------------------------------------- 10128590a0fdSAndre Fischer // MKCOL 10138590a0fdSAndre Fischer // ------------------------------------------------------------------- 10148590a0fdSAndre Fischer void SerfSession::MKCOL( const rtl::OUString & inPath, 10158590a0fdSAndre Fischer const DAVRequestEnvironment & rEnv ) 10168590a0fdSAndre Fischer throw ( DAVException ) 10178590a0fdSAndre Fischer { 10188590a0fdSAndre Fischer osl::Guard< osl::Mutex > theGuard( m_aMutex ); 10198590a0fdSAndre Fischer 10208590a0fdSAndre Fischer Init( rEnv ); 10218590a0fdSAndre Fischer 102249989859SOliver-Rainer Wittmann boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); 10238590a0fdSAndre Fischer apr_status_t status = APR_SUCCESS; 1024*8fd7bf9dSAndrea Pescetti //check whether a lock on the destination resource is already owned 1025*8fd7bf9dSAndrea Pescetti rtl::OUString aUri( composeCurrentUri( inPath ) ); 1026*8fd7bf9dSAndrea Pescetti ucb::Lock inLock; 1027*8fd7bf9dSAndrea Pescetti SerfLock * pLock = m_aSerfLockStore.findByUri( aUri ); 1028*8fd7bf9dSAndrea Pescetti if ( pLock ) 1029*8fd7bf9dSAndrea Pescetti { 1030*8fd7bf9dSAndrea Pescetti inLock = pLock->getLock(); 1031*8fd7bf9dSAndrea Pescetti } 1032*8fd7bf9dSAndrea Pescetti aReqProc->processMkCol( inLock, status ); 10338590a0fdSAndre Fischer 103449989859SOliver-Rainer Wittmann HandleError( aReqProc ); 10358590a0fdSAndre Fischer } 10368590a0fdSAndre Fischer 10378590a0fdSAndre Fischer // ------------------------------------------------------------------- 10388590a0fdSAndre Fischer // COPY 10398590a0fdSAndre Fischer // ------------------------------------------------------------------- 10408590a0fdSAndre Fischer void SerfSession::COPY( const rtl::OUString & inSourceURL, 10418590a0fdSAndre Fischer const rtl::OUString & inDestinationURL, 10428590a0fdSAndre Fischer const DAVRequestEnvironment & rEnv, 10438590a0fdSAndre Fischer sal_Bool inOverWrite ) 10448590a0fdSAndre Fischer throw ( DAVException ) 10458590a0fdSAndre Fischer { 10468590a0fdSAndre Fischer osl::Guard< osl::Mutex > theGuard( m_aMutex ); 10478590a0fdSAndre Fischer 10488590a0fdSAndre Fischer Init( rEnv ); 10498590a0fdSAndre Fischer 10508590a0fdSAndre Fischer SerfUri theSourceUri( inSourceURL ); 105149989859SOliver-Rainer Wittmann boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( theSourceUri.GetPath() ) ); 10528590a0fdSAndre Fischer apr_status_t status = APR_SUCCESS; 1053*8fd7bf9dSAndrea Pescetti //check whether a lock on the destination resource is already owned 1054*8fd7bf9dSAndrea Pescetti rtl::OUString aUri( composeCurrentUri( inDestinationURL ) ); 1055*8fd7bf9dSAndrea Pescetti ucb::Lock inLock; 1056*8fd7bf9dSAndrea Pescetti SerfLock * pLock = m_aSerfLockStore.findByUri( aUri ); 1057*8fd7bf9dSAndrea Pescetti if ( pLock ) 1058*8fd7bf9dSAndrea Pescetti { 1059*8fd7bf9dSAndrea Pescetti inLock = pLock->getLock(); 1060*8fd7bf9dSAndrea Pescetti } 106149989859SOliver-Rainer Wittmann aReqProc->processCopy( inDestinationURL, 10628590a0fdSAndre Fischer (inOverWrite ? true : false), 1063*8fd7bf9dSAndrea Pescetti inLock, 10648590a0fdSAndre Fischer status ); 10658590a0fdSAndre Fischer 106649989859SOliver-Rainer Wittmann HandleError( aReqProc ); 10678590a0fdSAndre Fischer } 10688590a0fdSAndre Fischer 10698590a0fdSAndre Fischer // ------------------------------------------------------------------- 10708590a0fdSAndre Fischer // MOVE 10718590a0fdSAndre Fischer // ------------------------------------------------------------------- 10728590a0fdSAndre Fischer void SerfSession::MOVE( const rtl::OUString & inSourceURL, 10738590a0fdSAndre Fischer const rtl::OUString & inDestinationURL, 10748590a0fdSAndre Fischer const DAVRequestEnvironment & rEnv, 10758590a0fdSAndre Fischer sal_Bool inOverWrite ) 10768590a0fdSAndre Fischer throw ( DAVException ) 10778590a0fdSAndre Fischer { 10788590a0fdSAndre Fischer osl::Guard< osl::Mutex > theGuard( m_aMutex ); 10798590a0fdSAndre Fischer 10808590a0fdSAndre Fischer Init( rEnv ); 10818590a0fdSAndre Fischer 10828590a0fdSAndre Fischer SerfUri theSourceUri( inSourceURL ); 108349989859SOliver-Rainer Wittmann boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( theSourceUri.GetPath() ) ); 10848590a0fdSAndre Fischer apr_status_t status = APR_SUCCESS; 1085*8fd7bf9dSAndrea Pescetti //check whether a lock on the destination resource is already owned 1086*8fd7bf9dSAndrea Pescetti rtl::OUString aUri( composeCurrentUri( inDestinationURL ) ); 1087*8fd7bf9dSAndrea Pescetti ucb::Lock inLock; 1088*8fd7bf9dSAndrea Pescetti SerfLock * pLock = m_aSerfLockStore.findByUri( aUri ); 1089*8fd7bf9dSAndrea Pescetti if ( pLock ) 1090*8fd7bf9dSAndrea Pescetti { 1091*8fd7bf9dSAndrea Pescetti inLock = pLock->getLock(); 1092*8fd7bf9dSAndrea Pescetti } 109349989859SOliver-Rainer Wittmann aReqProc->processMove( inDestinationURL, 10948590a0fdSAndre Fischer (inOverWrite ? true : false), 1095*8fd7bf9dSAndrea Pescetti inLock, 10968590a0fdSAndre Fischer status ); 10978590a0fdSAndre Fischer 109849989859SOliver-Rainer Wittmann HandleError( aReqProc ); 10998590a0fdSAndre Fischer } 11008590a0fdSAndre Fischer 11018590a0fdSAndre Fischer // ------------------------------------------------------------------- 11028590a0fdSAndre Fischer // DESTROY 11038590a0fdSAndre Fischer // ------------------------------------------------------------------- 11048590a0fdSAndre Fischer void SerfSession::DESTROY( const rtl::OUString & inPath, 11058590a0fdSAndre Fischer const DAVRequestEnvironment & rEnv ) 11068590a0fdSAndre Fischer throw ( DAVException ) 11078590a0fdSAndre Fischer { 11088590a0fdSAndre Fischer osl::Guard< osl::Mutex > theGuard( m_aMutex ); 11098590a0fdSAndre Fischer 11108590a0fdSAndre Fischer Init( rEnv ); 11118590a0fdSAndre Fischer 111249989859SOliver-Rainer Wittmann boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); 11138590a0fdSAndre Fischer apr_status_t status = APR_SUCCESS; 1114*8fd7bf9dSAndrea Pescetti //check whether a lock on this resource is already owned 1115*8fd7bf9dSAndrea Pescetti rtl::OUString aUri( composeCurrentUri( inPath ) ); 1116*8fd7bf9dSAndrea Pescetti ucb::Lock inLock; 1117*8fd7bf9dSAndrea Pescetti SerfLock * pLock = m_aSerfLockStore.findByUri( aUri ); 1118*8fd7bf9dSAndrea Pescetti if ( pLock ) 1119*8fd7bf9dSAndrea Pescetti { 1120*8fd7bf9dSAndrea Pescetti inLock = pLock->getLock(); 1121*8fd7bf9dSAndrea Pescetti } 1122*8fd7bf9dSAndrea Pescetti aReqProc->processDelete( inLock, status ); 11238590a0fdSAndre Fischer 112449989859SOliver-Rainer Wittmann HandleError( aReqProc ); 11258590a0fdSAndre Fischer } 11268590a0fdSAndre Fischer 11278590a0fdSAndre Fischer // ------------------------------------------------------------------- 1128*8fd7bf9dSAndrea Pescetti 11298590a0fdSAndre Fischer namespace 11308590a0fdSAndre Fischer { 11318590a0fdSAndre Fischer sal_Int32 lastChanceToSendRefreshRequest( TimeValue const & rStart, 1132*8fd7bf9dSAndrea Pescetti sal_Int32 timeout ) 11338590a0fdSAndre Fischer { 11348590a0fdSAndre Fischer TimeValue aEnd; 11358590a0fdSAndre Fischer osl_getSystemTime( &aEnd ); 11368590a0fdSAndre Fischer 11378590a0fdSAndre Fischer // Try to estimate a safe absolute time for sending the 11388590a0fdSAndre Fischer // lock refresh request. 1139*8fd7bf9dSAndrea Pescetti sal_Int32 lastChanceToSendRefreshRequest = DAVINFINITY; 1140*8fd7bf9dSAndrea Pescetti if ( timeout != DAVINFINITY ) 11418590a0fdSAndre Fischer { 11428590a0fdSAndre Fischer sal_Int32 calltime = aEnd.Seconds - rStart.Seconds; 11438590a0fdSAndre Fischer if ( calltime <= timeout ) 11448590a0fdSAndre Fischer { 11458590a0fdSAndre Fischer lastChanceToSendRefreshRequest 11468590a0fdSAndre Fischer = aEnd.Seconds + timeout - calltime; 11478590a0fdSAndre Fischer } 11488590a0fdSAndre Fischer else 11498590a0fdSAndre Fischer { 11508590a0fdSAndre Fischer OSL_TRACE( "No chance to refresh lock before timeout!" ); 11518590a0fdSAndre Fischer } 11528590a0fdSAndre Fischer } 11538590a0fdSAndre Fischer return lastChanceToSendRefreshRequest; 11548590a0fdSAndre Fischer } 11558590a0fdSAndre Fischer 11568590a0fdSAndre Fischer } // namespace 1157*8fd7bf9dSAndrea Pescetti 11588590a0fdSAndre Fischer // ------------------------------------------------------------------- 11598590a0fdSAndre Fischer // LOCK (set new lock) 11608590a0fdSAndre Fischer // ------------------------------------------------------------------- 11618590a0fdSAndre Fischer void SerfSession::LOCK( const ::rtl::OUString & inPath, 1162*8fd7bf9dSAndrea Pescetti ucb::Lock & rLock, 11638590a0fdSAndre Fischer const DAVRequestEnvironment & rEnv ) 11648590a0fdSAndre Fischer throw ( DAVException ) 11658590a0fdSAndre Fischer { 11668590a0fdSAndre Fischer osl::Guard< osl::Mutex > theGuard( m_aMutex ); 11678590a0fdSAndre Fischer 1168*8fd7bf9dSAndrea Pescetti //before locking, search in the lock store if we already own a lock for this resource 1169*8fd7bf9dSAndrea Pescetti //if present, return with exception DAV_LOCKED_SELF 1170*8fd7bf9dSAndrea Pescetti rtl::OUString aUri( composeCurrentUri( inPath ) ); 1171*8fd7bf9dSAndrea Pescetti SerfLock * pLock = m_aSerfLockStore.findByUri( aUri ); 1172*8fd7bf9dSAndrea Pescetti if ( pLock ) 1173*8fd7bf9dSAndrea Pescetti { 1174*8fd7bf9dSAndrea Pescetti //already present, meaning already locked by the same AOO session and already in the lockstore 1175*8fd7bf9dSAndrea Pescetti //just return, nothing to do 1176*8fd7bf9dSAndrea Pescetti return; 1177*8fd7bf9dSAndrea Pescetti } 1178*8fd7bf9dSAndrea Pescetti 11798590a0fdSAndre Fischer Init( rEnv ); 11808590a0fdSAndre Fischer 118149989859SOliver-Rainer Wittmann boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); 1182*8fd7bf9dSAndrea Pescetti apr_status_t status = APR_SUCCESS; 11838590a0fdSAndre Fischer 1184*8fd7bf9dSAndrea Pescetti //the returned property, a sequence of locks 1185*8fd7bf9dSAndrea Pescetti //only the first is used 1186*8fd7bf9dSAndrea Pescetti DAVPropertyValue outLock; 11878590a0fdSAndre Fischer 11888590a0fdSAndre Fischer TimeValue startCall; 11898590a0fdSAndre Fischer osl_getSystemTime( &startCall ); 1190*8fd7bf9dSAndrea Pescetti aReqProc->processLock(inPath, rLock, outLock, status); 11918590a0fdSAndre Fischer 1192*8fd7bf9dSAndrea Pescetti //HandleError will handle the error and throw an exception, if needed 1193*8fd7bf9dSAndrea Pescetti HandleError( aReqProc ); 11948590a0fdSAndre Fischer 1195*8fd7bf9dSAndrea Pescetti if(outLock.Name.compareToAscii(RTL_CONSTASCII_STRINGPARAM( "DAV:lockdiscovery" )) == 0 ) 11968590a0fdSAndre Fischer { 1197*8fd7bf9dSAndrea Pescetti //got a lock, use only the first returned 1198*8fd7bf9dSAndrea Pescetti uno::Sequence< ucb::Lock > aLocks; 1199*8fd7bf9dSAndrea Pescetti outLock.Value >>= aLocks; 1200*8fd7bf9dSAndrea Pescetti ucb::Lock aLock = aLocks[0]; 1201*8fd7bf9dSAndrea Pescetti 1202*8fd7bf9dSAndrea Pescetti SerfLock* aNewLock = new SerfLock( aLock, aUri, inPath ); 1203*8fd7bf9dSAndrea Pescetti // add the store the new lock 1204*8fd7bf9dSAndrea Pescetti m_aSerfLockStore.addLock(aNewLock,this, 12058590a0fdSAndre Fischer lastChanceToSendRefreshRequest( 1206*8fd7bf9dSAndrea Pescetti startCall, static_cast< sal_Int32 >(aLock.Timeout) ) ); 12078590a0fdSAndre Fischer } 12088590a0fdSAndre Fischer 12098590a0fdSAndre Fischer } 12108590a0fdSAndre Fischer 12118590a0fdSAndre Fischer // ------------------------------------------------------------------- 1212*8fd7bf9dSAndrea Pescetti // LOCK (refresh existing lock from DAVResourceAccess) 12138590a0fdSAndre Fischer // ------------------------------------------------------------------- 12148590a0fdSAndre Fischer sal_Int64 SerfSession::LOCK( const ::rtl::OUString & /*inPath*/, 12158590a0fdSAndre Fischer sal_Int64 nTimeout, 12168590a0fdSAndre Fischer const DAVRequestEnvironment & /*rEnv*/ ) 12178590a0fdSAndre Fischer throw ( DAVException ) 12188590a0fdSAndre Fischer { 12198590a0fdSAndre Fischer osl::Guard< osl::Mutex > theGuard( m_aMutex ); 12208590a0fdSAndre Fischer 12218590a0fdSAndre Fischer return nTimeout; 12228590a0fdSAndre Fischer /* 12238590a0fdSAndre Fischer // Try to get the neon lock from lock store 12248590a0fdSAndre Fischer SerfLock * theLock 12258590a0fdSAndre Fischer = m_aSerfLockStore.findByUri( makeAbsoluteURL( inPath ) ); 12268590a0fdSAndre Fischer if ( !theLock ) 12278590a0fdSAndre Fischer throw DAVException( DAVException::DAV_NOT_LOCKED ); 12288590a0fdSAndre Fischer 12298590a0fdSAndre Fischer Init( rEnv ); 12308590a0fdSAndre Fischer 12318590a0fdSAndre Fischer // refresh existing lock. 12328590a0fdSAndre Fischer theLock->timeout = static_cast< long >( nTimeout ); 12338590a0fdSAndre Fischer 12348590a0fdSAndre Fischer TimeValue startCall; 12358590a0fdSAndre Fischer osl_getSystemTime( &startCall ); 12368590a0fdSAndre Fischer 12378590a0fdSAndre Fischer int theRetVal = ne_lock_refresh( m_pHttpSession, theLock ); 12388590a0fdSAndre Fischer 12398590a0fdSAndre Fischer if ( theRetVal == NE_OK ) 12408590a0fdSAndre Fischer { 12418590a0fdSAndre Fischer m_aSerfLockStore.updateLock( theLock, 12428590a0fdSAndre Fischer lastChanceToSendRefreshRequest( 12438590a0fdSAndre Fischer startCall, theLock->timeout ) ); 12448590a0fdSAndre Fischer } 12458590a0fdSAndre Fischer 12468590a0fdSAndre Fischer HandleError( theRetVal, inPath, rEnv ); 12478590a0fdSAndre Fischer 12488590a0fdSAndre Fischer return theLock->timeout; 12498590a0fdSAndre Fischer */ 12508590a0fdSAndre Fischer } 12518590a0fdSAndre Fischer 12528590a0fdSAndre Fischer // ------------------------------------------------------------------- 1253*8fd7bf9dSAndrea Pescetti // LOCK (refresh existing lock from SerfLockStore) 12548590a0fdSAndre Fischer // ------------------------------------------------------------------- 1255*8fd7bf9dSAndrea Pescetti bool SerfSession::LOCK( SerfLock * pLock, 1256*8fd7bf9dSAndrea Pescetti sal_Int32 & rlastChanceToSendRefreshRequest ) 12578590a0fdSAndre Fischer { 12588590a0fdSAndre Fischer osl::Guard< osl::Mutex > theGuard( m_aMutex ); 1259*8fd7bf9dSAndrea Pescetti rtl::OUString inPath = pLock->getResourcePath(); 12608590a0fdSAndre Fischer 1261*8fd7bf9dSAndrea Pescetti boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); 1262*8fd7bf9dSAndrea Pescetti apr_status_t status = APR_SUCCESS; 1263*8fd7bf9dSAndrea Pescetti 1264*8fd7bf9dSAndrea Pescetti //the returned property, a sequence of locks 1265*8fd7bf9dSAndrea Pescetti //only the first is used 1266*8fd7bf9dSAndrea Pescetti DAVPropertyValue outLock; 12678590a0fdSAndre Fischer 12688590a0fdSAndre Fischer TimeValue startCall; 12698590a0fdSAndre Fischer osl_getSystemTime( &startCall ); 12708590a0fdSAndre Fischer 1271*8fd7bf9dSAndrea Pescetti // refresh existing lock. 1272*8fd7bf9dSAndrea Pescetti aReqProc->processLockRefresh( inPath, pLock->getLock(), outLock, status); 12738590a0fdSAndre Fischer 1274*8fd7bf9dSAndrea Pescetti // TODO: possible enhancement as the following: 1275*8fd7bf9dSAndrea Pescetti // - use an interaction handler to alert the user if the lock was not refreshed, 1276*8fd7bf9dSAndrea Pescetti // offering to try again with a new session, asking the user for credential, if necessary. 1277*8fd7bf9dSAndrea Pescetti // This may happen if the WebDAV server goes off-line for whatever reason, or the connection is dropped for time-out 1278*8fd7bf9dSAndrea Pescetti // To implement this behavior, some redesigning of the current session implementation may be needed. 1279*8fd7bf9dSAndrea Pescetti // 1280*8fd7bf9dSAndrea Pescetti 1281*8fd7bf9dSAndrea Pescetti //HandleError will handle the error and throw an exception, if needed 1282*8fd7bf9dSAndrea Pescetti HandleError( aReqProc ); 1283*8fd7bf9dSAndrea Pescetti 1284*8fd7bf9dSAndrea Pescetti uno::Sequence< ucb::Lock > aLocks; 1285*8fd7bf9dSAndrea Pescetti outLock.Value >>= aLocks; 1286*8fd7bf9dSAndrea Pescetti ucb::Lock aLock = aLocks[0]; 1287*8fd7bf9dSAndrea Pescetti 1288*8fd7bf9dSAndrea Pescetti //if ok, udate the lastchance refresh time in lock 1289*8fd7bf9dSAndrea Pescetti rlastChanceToSendRefreshRequest 1290*8fd7bf9dSAndrea Pescetti = lastChanceToSendRefreshRequest( startCall, static_cast< sal_Int32 >(aLock.Timeout) ); 1291*8fd7bf9dSAndrea Pescetti 12928590a0fdSAndre Fischer return true; 12938590a0fdSAndre Fischer } 12948590a0fdSAndre Fischer 12958590a0fdSAndre Fischer // ------------------------------------------------------------------- 1296*8fd7bf9dSAndrea Pescetti // UNLOCK called from external (DAVResourceAccess) 12978590a0fdSAndre Fischer // ------------------------------------------------------------------- 1298*8fd7bf9dSAndrea Pescetti void SerfSession::UNLOCK( const ::rtl::OUString & inPath, 1299*8fd7bf9dSAndrea Pescetti const DAVRequestEnvironment & rEnv ) 13008590a0fdSAndre Fischer throw ( DAVException ) 13018590a0fdSAndre Fischer { 13028590a0fdSAndre Fischer osl::Guard< osl::Mutex > theGuard( m_aMutex ); 13038590a0fdSAndre Fischer 1304*8fd7bf9dSAndrea Pescetti rtl::OUString aUri( composeCurrentUri( inPath ) ); 1305*8fd7bf9dSAndrea Pescetti SerfLock * pLock = m_aSerfLockStore.findByUri( aUri ); 1306*8fd7bf9dSAndrea Pescetti if ( !pLock ) 1307*8fd7bf9dSAndrea Pescetti { 13088590a0fdSAndre Fischer throw DAVException( DAVException::DAV_NOT_LOCKED ); 1309*8fd7bf9dSAndrea Pescetti } 13108590a0fdSAndre Fischer 13118590a0fdSAndre Fischer Init( rEnv ); 13128590a0fdSAndre Fischer 1313*8fd7bf9dSAndrea Pescetti boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); 1314*8fd7bf9dSAndrea Pescetti apr_status_t status = APR_SUCCESS; 13158590a0fdSAndre Fischer 1316*8fd7bf9dSAndrea Pescetti ucb::Lock inLock = pLock->getLock(); 1317*8fd7bf9dSAndrea Pescetti //remove lock from lockstore 1318*8fd7bf9dSAndrea Pescetti // so, if something goes wrong, we don't refresh it anymore 1319*8fd7bf9dSAndrea Pescetti m_aSerfLockStore.removeLock(pLock); 1320*8fd7bf9dSAndrea Pescetti delete pLock; 13218590a0fdSAndre Fischer 1322*8fd7bf9dSAndrea Pescetti // remove existing lock 1323*8fd7bf9dSAndrea Pescetti aReqProc->processUnlock( inPath, inLock, status); 1324*8fd7bf9dSAndrea Pescetti 1325*8fd7bf9dSAndrea Pescetti //HandleError will handle the error and throw an exception, if needed 1326*8fd7bf9dSAndrea Pescetti HandleError( aReqProc ); 13278590a0fdSAndre Fischer } 13288590a0fdSAndre Fischer 13298590a0fdSAndre Fischer // ------------------------------------------------------------------- 1330*8fd7bf9dSAndrea Pescetti // UNLOCK (called from SerfLockStore) 13318590a0fdSAndre Fischer // ------------------------------------------------------------------- 1332*8fd7bf9dSAndrea Pescetti bool SerfSession::UNLOCK( SerfLock * pLock ) 13338590a0fdSAndre Fischer { 13348590a0fdSAndre Fischer osl::Guard< osl::Mutex > theGuard( m_aMutex ); 1335*8fd7bf9dSAndrea Pescetti rtl::OUString inPath = pLock->getResourcePath(); 1336*8fd7bf9dSAndrea Pescetti 1337*8fd7bf9dSAndrea Pescetti boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); 1338*8fd7bf9dSAndrea Pescetti apr_status_t status = APR_SUCCESS; 1339*8fd7bf9dSAndrea Pescetti 1340*8fd7bf9dSAndrea Pescetti rtl::OUString aToken; 1341*8fd7bf9dSAndrea Pescetti aToken = pLock->getLock().LockTokens[0]; 1342*8fd7bf9dSAndrea Pescetti 1343*8fd7bf9dSAndrea Pescetti aReqProc->processUnlock( inPath, pLock->getLock(), status); 1344*8fd7bf9dSAndrea Pescetti 1345*8fd7bf9dSAndrea Pescetti //HandleError will handle the error and throw an exception, if needed 1346*8fd7bf9dSAndrea Pescetti HandleError( aReqProc ); 13478590a0fdSAndre Fischer 13488590a0fdSAndre Fischer return true; 13498590a0fdSAndre Fischer } 13508590a0fdSAndre Fischer 13518590a0fdSAndre Fischer // ------------------------------------------------------------------- 13528590a0fdSAndre Fischer void SerfSession::abort() 13538590a0fdSAndre Fischer throw ( DAVException ) 13548590a0fdSAndre Fischer { 13558590a0fdSAndre Fischer // 11.11.09 (tkr): The following code lines causing crashes if 13568590a0fdSAndre Fischer // closing a ongoing connection. It turned out that this existing 13578590a0fdSAndre Fischer // solution doesn't work in multi-threading environments. 13588590a0fdSAndre Fischer // So I disabled them in 3.2. . Issue #73893# should fix it in OOo 3.3. 13598590a0fdSAndre Fischer //if ( m_pHttpSession ) 13608590a0fdSAndre Fischer // ne_close_connection( m_pHttpSession ); 13618590a0fdSAndre Fischer } 13628590a0fdSAndre Fischer 13638590a0fdSAndre Fischer // ------------------------------------------------------------------- 13648590a0fdSAndre Fischer const ucbhelper::InternetProxyServer & SerfSession::getProxySettings() const 13658590a0fdSAndre Fischer { 13668590a0fdSAndre Fischer if ( m_aUri.GetScheme().equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "http" ) ) || 13678590a0fdSAndre Fischer m_aUri.GetScheme().equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "https" ) ) ) 13688590a0fdSAndre Fischer { 13698590a0fdSAndre Fischer return m_rProxyDecider.getProxy( m_aUri.GetScheme(), 13708590a0fdSAndre Fischer m_aUri.GetHost(), 13718590a0fdSAndre Fischer m_aUri.GetPort() ); 13728590a0fdSAndre Fischer } 13738590a0fdSAndre Fischer else 13748590a0fdSAndre Fischer { 13758590a0fdSAndre Fischer // TODO: figure out, if this case can occur 13768590a0fdSAndre Fischer return m_rProxyDecider.getProxy( m_aUri.GetScheme(), 13778590a0fdSAndre Fischer rtl::OUString() /* not used */, 13788590a0fdSAndre Fischer -1 /* not used */ ); 13798590a0fdSAndre Fischer } 13808590a0fdSAndre Fischer } 13818590a0fdSAndre Fischer 13828590a0fdSAndre Fischer /* 13838590a0fdSAndre Fischer // ------------------------------------------------------------------- 13848590a0fdSAndre Fischer namespace { 13858590a0fdSAndre Fischer 13868590a0fdSAndre Fischer bool containsLocktoken( const uno::Sequence< ucb::Lock > & rLocks, 13878590a0fdSAndre Fischer const char * token ) 13888590a0fdSAndre Fischer { 13898590a0fdSAndre Fischer for ( sal_Int32 n = 0; n < rLocks.getLength(); ++n ) 13908590a0fdSAndre Fischer { 13918590a0fdSAndre Fischer const uno::Sequence< rtl::OUString > & rTokens 13928590a0fdSAndre Fischer = rLocks[ n ].LockTokens; 13938590a0fdSAndre Fischer for ( sal_Int32 m = 0; m < rTokens.getLength(); ++m ) 13948590a0fdSAndre Fischer { 13958590a0fdSAndre Fischer if ( rTokens[ m ].equalsAscii( token ) ) 13968590a0fdSAndre Fischer return true; 13978590a0fdSAndre Fischer } 13988590a0fdSAndre Fischer } 13998590a0fdSAndre Fischer return false; 14008590a0fdSAndre Fischer } 14018590a0fdSAndre Fischer 14028590a0fdSAndre Fischer } // namespace 14038590a0fdSAndre Fischer */ 14048590a0fdSAndre Fischer 14058590a0fdSAndre Fischer // ------------------------------------------------------------------- 1406*8fd7bf9dSAndrea Pescetti // This method doesn't seem to be used. 1407*8fd7bf9dSAndrea Pescetti // In any case the default behavior is to ask a lock whith a life of 3 minutes 1408*8fd7bf9dSAndrea Pescetti // it will then be refreshed automatically (see SerfLockStore class) 1409*8fd7bf9dSAndrea Pescetti // In case of AOO crash the lock will expire by itself 14108590a0fdSAndre Fischer bool SerfSession::removeExpiredLocktoken( const rtl::OUString & /*inURL*/, 14118590a0fdSAndre Fischer const DAVRequestEnvironment & /*rEnv*/ ) 14128590a0fdSAndre Fischer { 14138590a0fdSAndre Fischer return true; 14148590a0fdSAndre Fischer /* 14158590a0fdSAndre Fischer SerfLock * theLock = m_aSerfLockStore.findByUri( inURL ); 14168590a0fdSAndre Fischer if ( !theLock ) 14178590a0fdSAndre Fischer return false; 14188590a0fdSAndre Fischer 14198590a0fdSAndre Fischer // do a lockdiscovery to check whether this lock is still valid. 14208590a0fdSAndre Fischer try 14218590a0fdSAndre Fischer { 14228590a0fdSAndre Fischer // @@@ Alternative: use ne_lock_discover() => less overhead 14238590a0fdSAndre Fischer 14248590a0fdSAndre Fischer std::vector< DAVResource > aResources; 14258590a0fdSAndre Fischer std::vector< rtl::OUString > aPropNames; 14268590a0fdSAndre Fischer aPropNames.push_back( DAVProperties::LOCKDISCOVERY ); 14278590a0fdSAndre Fischer 14288590a0fdSAndre Fischer PROPFIND( rEnv.m_aRequestURI, DAVZERO, aPropNames, aResources, rEnv ); 14298590a0fdSAndre Fischer 14308590a0fdSAndre Fischer if ( aResources.size() == 0 ) 14318590a0fdSAndre Fischer return false; 14328590a0fdSAndre Fischer 14338590a0fdSAndre Fischer std::vector< DAVPropertyValue >::const_iterator it 14348590a0fdSAndre Fischer = aResources[ 0 ].properties.begin(); 14358590a0fdSAndre Fischer std::vector< DAVPropertyValue >::const_iterator end 14368590a0fdSAndre Fischer = aResources[ 0 ].properties.end(); 14378590a0fdSAndre Fischer 14388590a0fdSAndre Fischer while ( it != end ) 14398590a0fdSAndre Fischer { 14408590a0fdSAndre Fischer if ( (*it).Name.equals( DAVProperties::LOCKDISCOVERY ) ) 14418590a0fdSAndre Fischer { 14428590a0fdSAndre Fischer uno::Sequence< ucb::Lock > aLocks; 14438590a0fdSAndre Fischer if ( !( (*it).Value >>= aLocks ) ) 14448590a0fdSAndre Fischer return false; 14458590a0fdSAndre Fischer 14468590a0fdSAndre Fischer if ( !containsLocktoken( aLocks, theLock->token ) ) 14478590a0fdSAndre Fischer { 14488590a0fdSAndre Fischer // expired! 14498590a0fdSAndre Fischer break; 14508590a0fdSAndre Fischer } 14518590a0fdSAndre Fischer 14528590a0fdSAndre Fischer // still valid. 14538590a0fdSAndre Fischer return false; 14548590a0fdSAndre Fischer } 14558590a0fdSAndre Fischer ++it; 14568590a0fdSAndre Fischer } 14578590a0fdSAndre Fischer 14588590a0fdSAndre Fischer // No lockdiscovery prop in propfind result / locktoken not found 14598590a0fdSAndre Fischer // in propfind result -> not locked 14608590a0fdSAndre Fischer OSL_TRACE( "SerfSession::removeExpiredLocktoken: Removing " 14618590a0fdSAndre Fischer " expired lock token for %s. token: %s", 14628590a0fdSAndre Fischer rtl::OUStringToOString( inURL, 14638590a0fdSAndre Fischer RTL_TEXTENCODING_UTF8 ).getStr(), 14648590a0fdSAndre Fischer theLock->token ); 14658590a0fdSAndre Fischer 14668590a0fdSAndre Fischer m_aSerfLockStore.removeLock( theLock ); 14678590a0fdSAndre Fischer ne_lock_destroy( theLock ); 14688590a0fdSAndre Fischer return true; 14698590a0fdSAndre Fischer } 14708590a0fdSAndre Fischer catch ( DAVException const & ) 14718590a0fdSAndre Fischer { 14728590a0fdSAndre Fischer } 14738590a0fdSAndre Fischer return false; 14748590a0fdSAndre Fischer */ 14758590a0fdSAndre Fischer } 14768590a0fdSAndre Fischer 14778590a0fdSAndre Fischer // ------------------------------------------------------------------- 14788590a0fdSAndre Fischer // HandleError 14798590a0fdSAndre Fischer // Common Error Handler 14808590a0fdSAndre Fischer // ------------------------------------------------------------------- 148149989859SOliver-Rainer Wittmann void SerfSession::HandleError( boost::shared_ptr<SerfRequestProcessor> rReqProc ) 14828590a0fdSAndre Fischer throw ( DAVException ) 14838590a0fdSAndre Fischer { 14848590a0fdSAndre Fischer m_aEnv = DAVRequestEnvironment(); 14858590a0fdSAndre Fischer 148649989859SOliver-Rainer Wittmann if ( rReqProc->mpDAVException ) 14878590a0fdSAndre Fischer { 148849989859SOliver-Rainer Wittmann DAVException* mpDAVExp( rReqProc->mpDAVException ); 14898590a0fdSAndre Fischer 14908590a0fdSAndre Fischer serf_connection_reset( getSerfConnection() ); 14918590a0fdSAndre Fischer 149249989859SOliver-Rainer Wittmann if ( mpDAVExp->getStatus() == 413 && 149349989859SOliver-Rainer Wittmann m_bNoOfTransferEncodingSwitches < 2 ) 149449989859SOliver-Rainer Wittmann { 149549989859SOliver-Rainer Wittmann m_bUseChunkedEncoding = !m_bUseChunkedEncoding; 149649989859SOliver-Rainer Wittmann ++m_bNoOfTransferEncodingSwitches; 149749989859SOliver-Rainer Wittmann } 149849989859SOliver-Rainer Wittmann 14998590a0fdSAndre Fischer throw DAVException( mpDAVExp->getError(), 15008590a0fdSAndre Fischer mpDAVExp->getData(), 15018590a0fdSAndre Fischer mpDAVExp->getStatus() ); 15028590a0fdSAndre Fischer } 15038590a0fdSAndre Fischer 15048590a0fdSAndre Fischer /* 15058590a0fdSAndre Fischer // Map error code to DAVException. 15068590a0fdSAndre Fischer switch ( nError ) 15078590a0fdSAndre Fischer { 15088590a0fdSAndre Fischer case NE_OK: 15098590a0fdSAndre Fischer return; 15108590a0fdSAndre Fischer 15118590a0fdSAndre Fischer case NE_ERROR: // Generic error 15128590a0fdSAndre Fischer { 15138590a0fdSAndre Fischer rtl::OUString aText = rtl::OUString::createFromAscii( 15148590a0fdSAndre Fischer ne_get_error( m_pHttpSession ) ); 15158590a0fdSAndre Fischer 15168590a0fdSAndre Fischer sal_uInt16 code = makeStatusCode( aText ); 15178590a0fdSAndre Fischer 15188590a0fdSAndre Fischer if ( code == SC_LOCKED ) 15198590a0fdSAndre Fischer { 15208590a0fdSAndre Fischer if ( m_aSerfLockStore.findByUri( 15218590a0fdSAndre Fischer makeAbsoluteURL( inPath ) ) == 0 ) 15228590a0fdSAndre Fischer { 15238590a0fdSAndre Fischer // locked by 3rd party 15248590a0fdSAndre Fischer throw DAVException( DAVException::DAV_LOCKED ); 15258590a0fdSAndre Fischer } 15268590a0fdSAndre Fischer else 15278590a0fdSAndre Fischer { 15288590a0fdSAndre Fischer // locked by ourself 15298590a0fdSAndre Fischer throw DAVException( DAVException::DAV_LOCKED_SELF ); 15308590a0fdSAndre Fischer } 15318590a0fdSAndre Fischer } 15328590a0fdSAndre Fischer 15338590a0fdSAndre Fischer // Special handling for 400 and 412 status codes, which may indicate 15348590a0fdSAndre Fischer // that a lock previously obtained by us has been released meanwhile 15358590a0fdSAndre Fischer // by the server. Unfortunately, RFC is not clear at this point, 15368590a0fdSAndre Fischer // thus server implementations behave different... 15378590a0fdSAndre Fischer else if ( code == SC_BAD_REQUEST || code == SC_PRECONDITION_FAILED ) 15388590a0fdSAndre Fischer { 15398590a0fdSAndre Fischer if ( removeExpiredLocktoken( makeAbsoluteURL( inPath ), rEnv ) ) 15408590a0fdSAndre Fischer throw DAVException( DAVException::DAV_LOCK_EXPIRED ); 15418590a0fdSAndre Fischer } 15428590a0fdSAndre Fischer 15438590a0fdSAndre Fischer throw DAVException( DAVException::DAV_HTTP_ERROR, aText, code ); 15448590a0fdSAndre Fischer } 15458590a0fdSAndre Fischer case NE_LOOKUP: // Name lookup failed. 15468590a0fdSAndre Fischer throw DAVException( DAVException::DAV_HTTP_LOOKUP, 15478590a0fdSAndre Fischer SerfUri::makeConnectionEndPointString( 15488590a0fdSAndre Fischer m_aHostName, m_nPort ) ); 15498590a0fdSAndre Fischer 15508590a0fdSAndre Fischer case NE_AUTH: // User authentication failed on server 15518590a0fdSAndre Fischer throw DAVException( DAVException::DAV_HTTP_AUTH, 15528590a0fdSAndre Fischer SerfUri::makeConnectionEndPointString( 15538590a0fdSAndre Fischer m_aHostName, m_nPort ) ); 15548590a0fdSAndre Fischer 15558590a0fdSAndre Fischer case NE_PROXYAUTH: // User authentication failed on proxy 15568590a0fdSAndre Fischer throw DAVException( DAVException::DAV_HTTP_AUTHPROXY, 15578590a0fdSAndre Fischer SerfUri::makeConnectionEndPointString( 15588590a0fdSAndre Fischer m_aProxyName, m_nProxyPort ) ); 15598590a0fdSAndre Fischer 15608590a0fdSAndre Fischer case NE_CONNECT: // Could not connect to server 15618590a0fdSAndre Fischer throw DAVException( DAVException::DAV_HTTP_CONNECT, 15628590a0fdSAndre Fischer SerfUri::makeConnectionEndPointString( 15638590a0fdSAndre Fischer m_aHostName, m_nPort ) ); 15648590a0fdSAndre Fischer 15658590a0fdSAndre Fischer case NE_TIMEOUT: // Connection timed out 15668590a0fdSAndre Fischer throw DAVException( DAVException::DAV_HTTP_TIMEOUT, 15678590a0fdSAndre Fischer SerfUri::makeConnectionEndPointString( 15688590a0fdSAndre Fischer m_aHostName, m_nPort ) ); 15698590a0fdSAndre Fischer 15708590a0fdSAndre Fischer case NE_FAILED: // The precondition failed 15718590a0fdSAndre Fischer throw DAVException( DAVException::DAV_HTTP_FAILED, 15728590a0fdSAndre Fischer SerfUri::makeConnectionEndPointString( 15738590a0fdSAndre Fischer m_aHostName, m_nPort ) ); 15748590a0fdSAndre Fischer 15758590a0fdSAndre Fischer case NE_RETRY: // Retry request (ne_end_request ONLY) 15768590a0fdSAndre Fischer throw DAVException( DAVException::DAV_HTTP_RETRY, 15778590a0fdSAndre Fischer SerfUri::makeConnectionEndPointString( 15788590a0fdSAndre Fischer m_aHostName, m_nPort ) ); 15798590a0fdSAndre Fischer 15808590a0fdSAndre Fischer case NE_REDIRECT: 15818590a0fdSAndre Fischer { 15828590a0fdSAndre Fischer SerfUri aUri( ne_redirect_location( m_pHttpSession ) ); 15838590a0fdSAndre Fischer throw DAVException( 15848590a0fdSAndre Fischer DAVException::DAV_HTTP_REDIRECT, aUri.GetURI() ); 15858590a0fdSAndre Fischer } 15868590a0fdSAndre Fischer default: 15878590a0fdSAndre Fischer { 15888590a0fdSAndre Fischer OSL_TRACE( "SerfSession::HandleError : Unknown Serf error code!" ); 15898590a0fdSAndre Fischer throw DAVException( DAVException::DAV_HTTP_ERROR, 15908590a0fdSAndre Fischer rtl::OUString::createFromAscii( 15918590a0fdSAndre Fischer ne_get_error( m_pHttpSession ) ) ); 15928590a0fdSAndre Fischer } 15938590a0fdSAndre Fischer } 15948590a0fdSAndre Fischer */ 15958590a0fdSAndre Fischer } 15968590a0fdSAndre Fischer 15978590a0fdSAndre Fischer // ------------------------------------------------------------------- 15988590a0fdSAndre Fischer // static 15998590a0fdSAndre Fischer bool 16008590a0fdSAndre Fischer SerfSession::getDataFromInputStream( 16018590a0fdSAndre Fischer const uno::Reference< io::XInputStream > & xStream, 16028590a0fdSAndre Fischer uno::Sequence< sal_Int8 > & rData, 16038590a0fdSAndre Fischer bool bAppendTrailingZeroByte ) 16048590a0fdSAndre Fischer { 16058590a0fdSAndre Fischer if ( xStream.is() ) 16068590a0fdSAndre Fischer { 16078590a0fdSAndre Fischer uno::Reference< io::XSeekable > xSeekable( xStream, uno::UNO_QUERY ); 16088590a0fdSAndre Fischer if ( xSeekable.is() ) 16098590a0fdSAndre Fischer { 16108590a0fdSAndre Fischer try 16118590a0fdSAndre Fischer { 16128590a0fdSAndre Fischer sal_Int32 nSize 16138590a0fdSAndre Fischer = sal::static_int_cast<sal_Int32>(xSeekable->getLength()); 16148590a0fdSAndre Fischer sal_Int32 nRead 16158590a0fdSAndre Fischer = xStream->readBytes( rData, nSize ); 16168590a0fdSAndre Fischer 16178590a0fdSAndre Fischer if ( nRead == nSize ) 16188590a0fdSAndre Fischer { 16198590a0fdSAndre Fischer if ( bAppendTrailingZeroByte ) 16208590a0fdSAndre Fischer { 16218590a0fdSAndre Fischer rData.realloc( nSize + 1 ); 16228590a0fdSAndre Fischer rData[ nSize ] = sal_Int8( 0 ); 16238590a0fdSAndre Fischer } 16248590a0fdSAndre Fischer return true; 16258590a0fdSAndre Fischer } 16268590a0fdSAndre Fischer } 16278590a0fdSAndre Fischer catch ( io::NotConnectedException const & ) 16288590a0fdSAndre Fischer { 16298590a0fdSAndre Fischer // readBytes 16308590a0fdSAndre Fischer } 16318590a0fdSAndre Fischer catch ( io::BufferSizeExceededException const & ) 16328590a0fdSAndre Fischer { 16338590a0fdSAndre Fischer // readBytes 16348590a0fdSAndre Fischer } 16358590a0fdSAndre Fischer catch ( io::IOException const & ) 16368590a0fdSAndre Fischer { 16378590a0fdSAndre Fischer // getLength, readBytes 16388590a0fdSAndre Fischer } 16398590a0fdSAndre Fischer } 16408590a0fdSAndre Fischer else 16418590a0fdSAndre Fischer { 16428590a0fdSAndre Fischer try 16438590a0fdSAndre Fischer { 16448590a0fdSAndre Fischer uno::Sequence< sal_Int8 > aBuffer; 16458590a0fdSAndre Fischer sal_Int32 nPos = 0; 16468590a0fdSAndre Fischer 16478590a0fdSAndre Fischer sal_Int32 nRead = xStream->readSomeBytes( aBuffer, 65536 ); 16488590a0fdSAndre Fischer while ( nRead > 0 ) 16498590a0fdSAndre Fischer { 16508590a0fdSAndre Fischer if ( rData.getLength() < ( nPos + nRead ) ) 16518590a0fdSAndre Fischer rData.realloc( nPos + nRead ); 16528590a0fdSAndre Fischer 16538590a0fdSAndre Fischer aBuffer.realloc( nRead ); 16548590a0fdSAndre Fischer rtl_copyMemory( (void*)( rData.getArray() + nPos ), 16558590a0fdSAndre Fischer (const void*)aBuffer.getConstArray(), 16568590a0fdSAndre Fischer nRead ); 16578590a0fdSAndre Fischer nPos += nRead; 16588590a0fdSAndre Fischer 16598590a0fdSAndre Fischer aBuffer.realloc( 0 ); 16608590a0fdSAndre Fischer nRead = xStream->readSomeBytes( aBuffer, 65536 ); 16618590a0fdSAndre Fischer } 16628590a0fdSAndre Fischer 16638590a0fdSAndre Fischer if ( bAppendTrailingZeroByte ) 16648590a0fdSAndre Fischer { 16658590a0fdSAndre Fischer rData.realloc( nPos + 1 ); 16668590a0fdSAndre Fischer rData[ nPos ] = sal_Int8( 0 ); 16678590a0fdSAndre Fischer } 16688590a0fdSAndre Fischer return true; 16698590a0fdSAndre Fischer } 16708590a0fdSAndre Fischer catch ( io::NotConnectedException const & ) 16718590a0fdSAndre Fischer { 16728590a0fdSAndre Fischer // readBytes 16738590a0fdSAndre Fischer } 16748590a0fdSAndre Fischer catch ( io::BufferSizeExceededException const & ) 16758590a0fdSAndre Fischer { 16768590a0fdSAndre Fischer // readBytes 16778590a0fdSAndre Fischer } 16788590a0fdSAndre Fischer catch ( io::IOException const & ) 16798590a0fdSAndre Fischer { 16808590a0fdSAndre Fischer // readBytes 16818590a0fdSAndre Fischer } 16828590a0fdSAndre Fischer } 16838590a0fdSAndre Fischer } 16848590a0fdSAndre Fischer return false; 16858590a0fdSAndre Fischer } 16868590a0fdSAndre Fischer 16878590a0fdSAndre Fischer // --------------------------------------------------------------------- 16888590a0fdSAndre Fischer sal_Bool 16898590a0fdSAndre Fischer SerfSession::isDomainMatch( rtl::OUString certHostName ) 16908590a0fdSAndre Fischer { 16918590a0fdSAndre Fischer rtl::OUString hostName = getHostName(); 16928590a0fdSAndre Fischer 16938590a0fdSAndre Fischer if (hostName.equalsIgnoreAsciiCase( certHostName ) ) 16948590a0fdSAndre Fischer return sal_True; 16958590a0fdSAndre Fischer 16968590a0fdSAndre Fischer if ( 0 == certHostName.indexOf( rtl::OUString::createFromAscii( "*" ) ) && 16978590a0fdSAndre Fischer hostName.getLength() >= certHostName.getLength() ) 16988590a0fdSAndre Fischer { 16998590a0fdSAndre Fischer rtl::OUString cmpStr = certHostName.copy( 1 ); 17008590a0fdSAndre Fischer 17018590a0fdSAndre Fischer if ( hostName.matchIgnoreAsciiCase( 17028590a0fdSAndre Fischer cmpStr, hostName.getLength() - cmpStr.getLength() ) ) 17038590a0fdSAndre Fischer return sal_True; 17048590a0fdSAndre Fischer } 17058590a0fdSAndre Fischer return sal_False; 17068590a0fdSAndre Fischer } 1707