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> 298590a0fdSAndre Fischer #include "comphelper/sequence.hxx" 308590a0fdSAndre Fischer #include "ucbhelper/simplecertificatevalidationrequest.hxx" 318590a0fdSAndre Fischer 32c1c10f68SAriel Constenla-Haile #include "AprEnv.hxx" 3308bb353fSPedro Giffuni #include <apr_strings.h> 348590a0fdSAndre Fischer 358590a0fdSAndre Fischer #include "DAVAuthListener.hxx" 36c1c10f68SAriel Constenla-Haile #include "SerfTypes.hxx" 37c1c10f68SAriel Constenla-Haile #include "SerfSession.hxx" 38c1c10f68SAriel Constenla-Haile #include "SerfUri.hxx" 39c1c10f68SAriel Constenla-Haile #include "SerfRequestProcessor.hxx" 40c1c10f68SAriel Constenla-Haile #include "SerfCallbacks.hxx" 41c1c10f68SAriel Constenla-Haile #include "SerfInputStream.hxx" 42c1c10f68SAriel Constenla-Haile #include "UCBDeadPropertyValue.hxx" 438590a0fdSAndre Fischer 448590a0fdSAndre Fischer #include <com/sun/star/xml/crypto/XSecurityEnvironment.hpp> 458590a0fdSAndre Fischer #include <com/sun/star/security/XCertificate.hpp> 468590a0fdSAndre Fischer #include <com/sun/star/security/CertificateValidity.hpp> 478590a0fdSAndre Fischer #include <com/sun/star/security/CertificateContainerStatus.hpp> 488590a0fdSAndre Fischer #include <com/sun/star/security/CertificateContainer.hpp> 498590a0fdSAndre Fischer #include <com/sun/star/security/XCertificateContainer.hpp> 50e54851feSOliver-Rainer Wittmann #include <com/sun/star/security/CertAltNameEntry.hpp> 51e54851feSOliver-Rainer Wittmann #include <com/sun/star/security/XSanExtension.hpp> 52e54851feSOliver-Rainer Wittmann #define OID_SUBJECT_ALTERNATIVE_NAME "2.5.29.17" 53e54851feSOliver-Rainer Wittmann 548590a0fdSAndre Fischer #include <com/sun/star/ucb/Lock.hpp> 558590a0fdSAndre Fischer #include <com/sun/star/xml/crypto/XSEInitializer.hpp> 568590a0fdSAndre Fischer 578590a0fdSAndre Fischer using namespace com::sun::star; 588590a0fdSAndre Fischer using namespace http_dav_ucp; 598590a0fdSAndre Fischer 60*5f30f85eSAndrea Pescetti 618590a0fdSAndre Fischer // ------------------------------------------------------------------- 628590a0fdSAndre Fischer // static members! 63*5f30f85eSAndrea Pescetti //SerfLockStore SerfSession::m_aSerfLockStore; 648590a0fdSAndre Fischer 658590a0fdSAndre Fischer // ------------------------------------------------------------------- 668590a0fdSAndre Fischer // Constructor 678590a0fdSAndre Fischer // ------------------------------------------------------------------- 688590a0fdSAndre Fischer SerfSession::SerfSession( 698590a0fdSAndre Fischer const rtl::Reference< DAVSessionFactory > & rSessionFactory, 708590a0fdSAndre Fischer const rtl::OUString& inUri, 718590a0fdSAndre Fischer const ucbhelper::InternetProxyDecider & rProxyDecider ) 728590a0fdSAndre Fischer throw ( DAVException ) 738590a0fdSAndre Fischer : DAVSession( rSessionFactory ) 748590a0fdSAndre Fischer , m_aMutex() 758590a0fdSAndre Fischer , m_aUri( inUri ) 768590a0fdSAndre Fischer , m_aProxyName() 778590a0fdSAndre Fischer , m_nProxyPort( 0 ) 788590a0fdSAndre Fischer , m_pSerfConnection( 0 ) 798590a0fdSAndre Fischer , m_pSerfContext( 0 ) 808590a0fdSAndre Fischer , m_bIsHeadRequestInProgress( false ) 8149989859SOliver-Rainer Wittmann , m_bUseChunkedEncoding( false ) 8249989859SOliver-Rainer Wittmann , m_bNoOfTransferEncodingSwitches( 0 ) 838590a0fdSAndre Fischer , m_rProxyDecider( rProxyDecider ) 848590a0fdSAndre Fischer , m_aEnv() 858590a0fdSAndre Fischer { 868590a0fdSAndre Fischer m_pSerfContext = serf_context_create( getAprPool() ); 878590a0fdSAndre Fischer 888590a0fdSAndre Fischer m_pSerfBucket_Alloc = serf_bucket_allocator_create( getAprPool(), NULL, NULL ); 898590a0fdSAndre Fischer } 908590a0fdSAndre Fischer 918590a0fdSAndre Fischer // ------------------------------------------------------------------- 928590a0fdSAndre Fischer // Destructor 938590a0fdSAndre Fischer // ------------------------------------------------------------------- 948590a0fdSAndre Fischer SerfSession::~SerfSession( ) 958590a0fdSAndre Fischer { 968590a0fdSAndre Fischer if ( m_pSerfConnection ) 978590a0fdSAndre Fischer { 988590a0fdSAndre Fischer serf_connection_close( m_pSerfConnection ); 998590a0fdSAndre Fischer m_pSerfConnection = 0; 1008590a0fdSAndre Fischer } 1018590a0fdSAndre Fischer } 1028590a0fdSAndre Fischer 1038590a0fdSAndre Fischer // ------------------------------------------------------------------- 1048590a0fdSAndre Fischer void SerfSession::Init( const DAVRequestEnvironment & rEnv ) 1058590a0fdSAndre Fischer throw ( DAVException ) 1068590a0fdSAndre Fischer { 1078590a0fdSAndre Fischer osl::Guard< osl::Mutex > theGuard( m_aMutex ); 1088590a0fdSAndre Fischer m_aEnv = rEnv; 1098590a0fdSAndre Fischer Init(); 1108590a0fdSAndre Fischer } 1118590a0fdSAndre Fischer 1128590a0fdSAndre Fischer // ------------------------------------------------------------------- 1138590a0fdSAndre Fischer void SerfSession::Init() 1148590a0fdSAndre Fischer throw ( DAVException ) 1158590a0fdSAndre Fischer { 1168590a0fdSAndre Fischer osl::Guard< osl::Mutex > theGuard( m_aMutex ); 1178590a0fdSAndre Fischer 1188590a0fdSAndre Fischer bool bCreateNewSession = false; 1198590a0fdSAndre Fischer 1208590a0fdSAndre Fischer if ( m_pSerfConnection == 0 ) 1218590a0fdSAndre Fischer { 1228590a0fdSAndre Fischer const ucbhelper::InternetProxyServer & rProxyCfg = getProxySettings(); 1238590a0fdSAndre Fischer 1248590a0fdSAndre Fischer m_aProxyName = rProxyCfg.aName; 1258590a0fdSAndre Fischer m_nProxyPort = rProxyCfg.nPort; 1268590a0fdSAndre Fischer 1278590a0fdSAndre Fischer // Not yet initialized. Create new session. 1288590a0fdSAndre Fischer bCreateNewSession = true; 1298590a0fdSAndre Fischer } 1308590a0fdSAndre Fischer else 1318590a0fdSAndre Fischer { 1328590a0fdSAndre Fischer const ucbhelper::InternetProxyServer & rProxyCfg = getProxySettings(); 1338590a0fdSAndre Fischer 1348590a0fdSAndre Fischer if ( ( rProxyCfg.aName != m_aProxyName ) 1358590a0fdSAndre Fischer || ( rProxyCfg.nPort != m_nProxyPort ) ) 1368590a0fdSAndre Fischer { 1378590a0fdSAndre Fischer m_aProxyName = rProxyCfg.aName; 1388590a0fdSAndre Fischer m_nProxyPort = rProxyCfg.nPort; 1398590a0fdSAndre Fischer 1408590a0fdSAndre Fischer // new session needed, destroy old first 1418590a0fdSAndre Fischer serf_connection_close( m_pSerfConnection ); 1428590a0fdSAndre Fischer m_pSerfConnection = 0; 1438590a0fdSAndre Fischer bCreateNewSession = true; 1448590a0fdSAndre Fischer } 1458590a0fdSAndre Fischer } 1468590a0fdSAndre Fischer 1478590a0fdSAndre Fischer if ( bCreateNewSession ) 1488590a0fdSAndre Fischer { 1498590a0fdSAndre Fischer // TODO - close_connection callback 1508590a0fdSAndre Fischer apr_status_t status = serf_connection_create2( &m_pSerfConnection, 1518590a0fdSAndre Fischer m_pSerfContext, 1528590a0fdSAndre Fischer *(m_aUri.getAprUri()), 1538590a0fdSAndre Fischer Serf_ConnectSetup, this, 1548590a0fdSAndre Fischer 0 /* close connection callback */, 0 /* close connection baton */, 1558590a0fdSAndre Fischer getAprPool() ); 1568590a0fdSAndre Fischer 1578590a0fdSAndre Fischer if ( m_pSerfConnection == 0 ||status != APR_SUCCESS ) 1588590a0fdSAndre Fischer { 1598590a0fdSAndre Fischer throw DAVException( DAVException::DAV_SESSION_CREATE, 1608590a0fdSAndre Fischer SerfUri::makeConnectionEndPointString( m_aUri.GetHost(), m_aUri.GetPort() ) ); 1618590a0fdSAndre Fischer } 1628590a0fdSAndre Fischer 1638590a0fdSAndre Fischer // Register the session with the lock store 1648590a0fdSAndre Fischer // m_aSerfLockStore.registerSession( m_pSerfConnection ); 1658590a0fdSAndre Fischer 1668590a0fdSAndre Fischer if ( m_aProxyName.getLength() ) 1678590a0fdSAndre Fischer { 1688590a0fdSAndre Fischer apr_sockaddr_t *proxy_address = NULL; 169*5f30f85eSAndrea Pescetti status = apr_sockaddr_info_get( &proxy_address, 17024c56ab9SHerbert Dürr rtl::OUStringToOString( m_aProxyName, RTL_TEXTENCODING_UTF8 ).getStr(), 1718590a0fdSAndre Fischer APR_UNSPEC, 1728590a0fdSAndre Fischer static_cast<apr_port_t>(m_nProxyPort), 1738590a0fdSAndre Fischer 0, getAprPool() ); 1748590a0fdSAndre Fischer 1758590a0fdSAndre Fischer if ( status != APR_SUCCESS ) 1768590a0fdSAndre Fischer { 1778590a0fdSAndre Fischer throw DAVException( DAVException::DAV_SESSION_CREATE, 1788590a0fdSAndre Fischer SerfUri::makeConnectionEndPointString( m_aUri.GetHost(), m_aUri.GetPort() ) ); 1798590a0fdSAndre Fischer } 1808590a0fdSAndre Fischer 1818590a0fdSAndre Fischer serf_config_proxy( m_pSerfContext, proxy_address ); 1828590a0fdSAndre Fischer } 1838590a0fdSAndre Fischer 1848590a0fdSAndre Fischer 185307c6619SOliver-Rainer Wittmann serf_config_credentials_callback( m_pSerfContext, Serf_Credentials ); 18649989859SOliver-Rainer Wittmann 18749989859SOliver-Rainer Wittmann m_bUseChunkedEncoding = isSSLNeeded(); 1888590a0fdSAndre Fischer } 1898590a0fdSAndre Fischer } 1908590a0fdSAndre Fischer 1918590a0fdSAndre Fischer apr_pool_t* SerfSession::getAprPool() 1928590a0fdSAndre Fischer { 1938590a0fdSAndre Fischer return apr_environment::AprEnv::getAprEnv()->getAprPool(); 1948590a0fdSAndre Fischer } 1958590a0fdSAndre Fischer 1968590a0fdSAndre Fischer serf_bucket_alloc_t* SerfSession::getSerfBktAlloc() 1978590a0fdSAndre Fischer { 1988590a0fdSAndre Fischer return m_pSerfBucket_Alloc; 1998590a0fdSAndre Fischer } 2008590a0fdSAndre Fischer 2018590a0fdSAndre Fischer serf_context_t* SerfSession::getSerfContext() 2028590a0fdSAndre Fischer { 2038590a0fdSAndre Fischer return m_pSerfContext; 2048590a0fdSAndre Fischer } 2058590a0fdSAndre Fischer 2068590a0fdSAndre Fischer SerfConnection* SerfSession::getSerfConnection() 2078590a0fdSAndre Fischer { 2088590a0fdSAndre Fischer return m_pSerfConnection; 2098590a0fdSAndre Fischer } 2108590a0fdSAndre Fischer 2118590a0fdSAndre Fischer bool SerfSession::isHeadRequestInProgress() 2128590a0fdSAndre Fischer { 2138590a0fdSAndre Fischer return m_bIsHeadRequestInProgress; 2148590a0fdSAndre Fischer } 2158590a0fdSAndre Fischer 2168590a0fdSAndre Fischer bool SerfSession::isSSLNeeded() 2178590a0fdSAndre Fischer { 2188590a0fdSAndre Fischer return m_aUri.GetScheme().equalsIgnoreAsciiCase( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "https" ) ) ); 2198590a0fdSAndre Fischer } 2208590a0fdSAndre Fischer 2218590a0fdSAndre Fischer char* SerfSession::getHostinfo() 2228590a0fdSAndre Fischer { 2238590a0fdSAndre Fischer return m_aUri.getAprUri()->hostinfo; 2248590a0fdSAndre Fischer } 2258590a0fdSAndre Fischer 2268590a0fdSAndre Fischer 2278590a0fdSAndre Fischer // ------------------------------------------------------------------- 2288590a0fdSAndre Fischer // virtual 2298590a0fdSAndre Fischer sal_Bool SerfSession::CanUse( const rtl::OUString & inUri ) 2308590a0fdSAndre Fischer { 2318590a0fdSAndre Fischer try 2328590a0fdSAndre Fischer { 2338590a0fdSAndre Fischer SerfUri theUri( inUri ); 2348590a0fdSAndre Fischer if ( ( theUri.GetPort() == m_aUri.GetPort() ) && 2358590a0fdSAndre Fischer ( theUri.GetHost() == m_aUri.GetHost() ) && 2368590a0fdSAndre Fischer ( theUri.GetScheme() == m_aUri.GetScheme() ) ) 2378590a0fdSAndre Fischer { 2388590a0fdSAndre Fischer return sal_True; 2398590a0fdSAndre Fischer } 2408590a0fdSAndre Fischer } 2418590a0fdSAndre Fischer catch ( DAVException const & ) 2428590a0fdSAndre Fischer { 2438590a0fdSAndre Fischer return sal_False; 2448590a0fdSAndre Fischer } 2458590a0fdSAndre Fischer return sal_False; 2468590a0fdSAndre Fischer } 2478590a0fdSAndre Fischer 2488590a0fdSAndre Fischer // ------------------------------------------------------------------- 2498590a0fdSAndre Fischer // virtual 2508590a0fdSAndre Fischer sal_Bool SerfSession::UsesProxy() 2518590a0fdSAndre Fischer { 2528590a0fdSAndre Fischer Init(); 2538590a0fdSAndre Fischer return ( m_aProxyName.getLength() > 0 ); 2548590a0fdSAndre Fischer } 2558590a0fdSAndre Fischer 2568590a0fdSAndre Fischer apr_status_t SerfSession::setupSerfConnection( apr_socket_t * inAprSocket, 2578590a0fdSAndre Fischer serf_bucket_t **outSerfInputBucket, 2588590a0fdSAndre Fischer serf_bucket_t **outSerfOutputBucket, 2598590a0fdSAndre Fischer apr_pool_t* /*inAprPool*/ ) 2608590a0fdSAndre Fischer { 2618590a0fdSAndre Fischer serf_bucket_t *tmpInputBkt; 262*5f30f85eSAndrea Pescetti tmpInputBkt = serf_context_bucket_socket_create( getSerfContext(), 263*5f30f85eSAndrea Pescetti inAprSocket, 2648590a0fdSAndre Fischer getSerfBktAlloc() ); 265*5f30f85eSAndrea Pescetti 266*5f30f85eSAndrea Pescetti if ( isSSLNeeded() ) 2678590a0fdSAndre Fischer { 2688590a0fdSAndre Fischer tmpInputBkt = serf_bucket_ssl_decrypt_create( tmpInputBkt, 2698590a0fdSAndre Fischer 0, 2708590a0fdSAndre Fischer getSerfBktAlloc() ); 271c58749d7SAndre Fischer /** Set the callback that is called to authenticate the 272c58749d7SAndre Fischer certifcate (chain). 273c58749d7SAndre Fischer */ 274c58749d7SAndre Fischer serf_ssl_server_cert_chain_callback_set( 275c58749d7SAndre Fischer serf_bucket_ssl_decrypt_context_get(tmpInputBkt), 27610e20387SAndre Fischer NULL, 277c58749d7SAndre Fischer Serf_CertificateChainValidation, 278c58749d7SAndre Fischer this); 279*5f30f85eSAndrea Pescetti serf_ssl_set_hostname( serf_bucket_ssl_decrypt_context_get( tmpInputBkt ), 2808590a0fdSAndre Fischer getHostinfo() ); 2818590a0fdSAndre Fischer 2828590a0fdSAndre Fischer *outSerfOutputBucket = serf_bucket_ssl_encrypt_create( *outSerfOutputBucket, 2838590a0fdSAndre Fischer serf_bucket_ssl_decrypt_context_get( tmpInputBkt ), 2848590a0fdSAndre Fischer getSerfBktAlloc() ); 2858590a0fdSAndre Fischer } 2868590a0fdSAndre Fischer 2878590a0fdSAndre Fischer *outSerfInputBucket = tmpInputBkt; 2888590a0fdSAndre Fischer 2898590a0fdSAndre Fischer return APR_SUCCESS; 2908590a0fdSAndre Fischer } 2918590a0fdSAndre Fischer 292fb7f54d2SOliver-Rainer Wittmann apr_status_t SerfSession::provideSerfCredentials( bool bGiveProvidedCredentialsASecondTry, 293*5f30f85eSAndrea Pescetti char ** outUsername, 294307c6619SOliver-Rainer Wittmann char ** outPassword, 295*5f30f85eSAndrea Pescetti serf_request_t * /*inRequest*/, 296*5f30f85eSAndrea Pescetti int /*inCode*/, 297307c6619SOliver-Rainer Wittmann const char *inAuthProtocol, 298307c6619SOliver-Rainer Wittmann const char *inRealm, 2998590a0fdSAndre Fischer apr_pool_t *inAprPool ) 3008590a0fdSAndre Fischer { 3018590a0fdSAndre Fischer DAVAuthListener * pListener = getRequestEnvironment().m_xAuthListener.get(); 3028590a0fdSAndre Fischer if ( !pListener ) 3038590a0fdSAndre Fischer { 3048590a0fdSAndre Fischer // abort 3058590a0fdSAndre Fischer return SERF_ERROR_AUTHN_FAILED; 3068590a0fdSAndre Fischer } 3078590a0fdSAndre Fischer 3088590a0fdSAndre Fischer rtl::OUString theUserName; 3098590a0fdSAndre Fischer rtl::OUString thePassWord; 3108590a0fdSAndre Fischer try 3118590a0fdSAndre Fischer { 3128590a0fdSAndre Fischer SerfUri uri( getRequestEnvironment().m_aRequestURI ); 3138590a0fdSAndre Fischer rtl::OUString aUserInfo( uri.GetUserInfo() ); 3148590a0fdSAndre Fischer if ( aUserInfo.getLength() ) 3158590a0fdSAndre Fischer { 3168590a0fdSAndre Fischer sal_Int32 nPos = aUserInfo.indexOf( '@' ); 3178590a0fdSAndre Fischer if ( nPos == -1 ) 3188590a0fdSAndre Fischer { 3198590a0fdSAndre Fischer theUserName = aUserInfo; 3208590a0fdSAndre Fischer } 3218590a0fdSAndre Fischer else 3228590a0fdSAndre Fischer { 3238590a0fdSAndre Fischer theUserName = aUserInfo.copy( 0, nPos ); 3248590a0fdSAndre Fischer thePassWord = aUserInfo.copy( nPos + 1 ); 3258590a0fdSAndre Fischer } 3268590a0fdSAndre Fischer } 3278590a0fdSAndre Fischer } 3288590a0fdSAndre Fischer catch ( DAVException const & ) 3298590a0fdSAndre Fischer { 3308590a0fdSAndre Fischer // abort 3318590a0fdSAndre Fischer return SERF_ERROR_AUTHN_FAILED; 3328590a0fdSAndre Fischer } 3338590a0fdSAndre Fischer 3348590a0fdSAndre Fischer const bool bCanUseSystemCreds = ( ( strcasecmp( inAuthProtocol, "NTLM" ) == 0 ) || 3358590a0fdSAndre Fischer ( strcasecmp( inAuthProtocol, "Negotiate" ) == 0 ) ); 3368590a0fdSAndre Fischer 3378590a0fdSAndre Fischer int theRetVal = pListener->authenticate( rtl::OUString::createFromAscii( inRealm ), 3388590a0fdSAndre Fischer getHostName(), 3398590a0fdSAndre Fischer theUserName, 3408590a0fdSAndre Fischer thePassWord, 341fb7f54d2SOliver-Rainer Wittmann bCanUseSystemCreds, 342fb7f54d2SOliver-Rainer Wittmann bGiveProvidedCredentialsASecondTry ? sal_False : sal_True ); 3438590a0fdSAndre Fischer 3448590a0fdSAndre Fischer if ( theRetVal == 0 ) 3458590a0fdSAndre Fischer { 34624c56ab9SHerbert Dürr *outUsername = apr_pstrdup( inAprPool, rtl::OUStringToOString( theUserName, RTL_TEXTENCODING_UTF8 ).getStr() ); 34724c56ab9SHerbert Dürr *outPassword = apr_pstrdup( inAprPool, rtl::OUStringToOString( thePassWord, RTL_TEXTENCODING_UTF8 ).getStr() ); 3488590a0fdSAndre Fischer } 3498590a0fdSAndre Fischer 3508590a0fdSAndre Fischer return theRetVal != 0 ? SERF_ERROR_AUTHN_FAILED : APR_SUCCESS; 3518590a0fdSAndre Fischer } 3528590a0fdSAndre Fischer 3538590a0fdSAndre Fischer namespace { 3548590a0fdSAndre Fischer // ------------------------------------------------------------------- 3558590a0fdSAndre Fischer // Helper function 3568590a0fdSAndre Fischer ::rtl::OUString GetHostnamePart( const ::rtl::OUString& _rRawString ) 3578590a0fdSAndre Fischer { 3588590a0fdSAndre Fischer ::rtl::OUString sPart; 3598590a0fdSAndre Fischer ::rtl::OUString sPartId = ::rtl::OUString::createFromAscii( "CN=" ); 3608590a0fdSAndre Fischer sal_Int32 nContStart = _rRawString.indexOf( sPartId ); 3618590a0fdSAndre Fischer if ( nContStart != -1 ) 3628590a0fdSAndre Fischer { 3638590a0fdSAndre Fischer nContStart = nContStart + sPartId.getLength(); 3648590a0fdSAndre Fischer sal_Int32 nContEnd 3658590a0fdSAndre Fischer = _rRawString.indexOf( sal_Unicode( ',' ), nContStart ); 3668590a0fdSAndre Fischer sPart = _rRawString.copy( nContStart, nContEnd - nContStart ); 3678590a0fdSAndre Fischer } 3688590a0fdSAndre Fischer return sPart; 3698590a0fdSAndre Fischer } 3708590a0fdSAndre Fischer } // namespace 3718590a0fdSAndre Fischer 3728590a0fdSAndre Fischer 373c58749d7SAndre Fischer apr_status_t SerfSession::verifySerfCertificateChain ( 374c58749d7SAndre Fischer int, 37510e20387SAndre Fischer const serf_ssl_certificate_t * const * pCertificateChainBase64Encoded, 376de38cc67SOliver-Rainer Wittmann int nCertificateChainLength) 377c58749d7SAndre Fischer { 378c58749d7SAndre Fischer // Check arguments. 379c58749d7SAndre Fischer if (pCertificateChainBase64Encoded == NULL || nCertificateChainLength<=0) 3808590a0fdSAndre Fischer { 381c58749d7SAndre Fischer OSL_ASSERT(pCertificateChainBase64Encoded != NULL); 382c58749d7SAndre Fischer OSL_ASSERT(nCertificateChainLength>0); 3838590a0fdSAndre Fischer return SERF_SSL_CERT_UNKNOWN_FAILURE; 3848590a0fdSAndre Fischer } 3858590a0fdSAndre Fischer 386c58749d7SAndre Fischer // Create some crypto objects to decode and handle the base64 387c58749d7SAndre Fischer // encoded certificate chain. 3888590a0fdSAndre Fischer uno::Reference< xml::crypto::XSEInitializer > xSEInitializer; 389c58749d7SAndre Fischer uno::Reference< security::XCertificateContainer > xCertificateContainer; 390c58749d7SAndre Fischer uno::Reference< xml::crypto::XXMLSecurityContext > xSecurityContext; 391c58749d7SAndre Fischer uno::Reference< xml::crypto::XSecurityEnvironment > xSecurityEnv; 3928590a0fdSAndre Fischer try 3938590a0fdSAndre Fischer { 394c58749d7SAndre Fischer // Create a certificate container. 395c58749d7SAndre Fischer xCertificateContainer = uno::Reference< security::XCertificateContainer >( 396c58749d7SAndre Fischer getMSF()->createInstance( 397c58749d7SAndre Fischer rtl::OUString::createFromAscii( 398c58749d7SAndre Fischer "com.sun.star.security.CertificateContainer" ) ), 399c58749d7SAndre Fischer uno::UNO_QUERY_THROW); 400c58749d7SAndre Fischer 4018590a0fdSAndre Fischer xSEInitializer = uno::Reference< xml::crypto::XSEInitializer >( 4028590a0fdSAndre Fischer getMSF()->createInstance( 4038590a0fdSAndre Fischer rtl::OUString::createFromAscii( "com.sun.star.xml.crypto.SEInitializer" ) ), 404c58749d7SAndre Fischer uno::UNO_QUERY_THROW); 405c58749d7SAndre Fischer 406c58749d7SAndre Fischer xSecurityContext = xSEInitializer->createSecurityContext( rtl::OUString() ); 407c58749d7SAndre Fischer if (xSecurityContext.is()) 408c58749d7SAndre Fischer xSecurityEnv = xSecurityContext->getSecurityEnvironment(); 409c58749d7SAndre Fischer 410c58749d7SAndre Fischer if ( ! xSecurityContext.is() || ! xSecurityEnv.is()) 411c58749d7SAndre Fischer { 412c58749d7SAndre Fischer // Do we have to dispose xSEInitializer or xCertificateContainer? 413c58749d7SAndre Fischer return SERF_SSL_CERT_UNKNOWN_FAILURE; 414c58749d7SAndre Fischer } 4158590a0fdSAndre Fischer } 416c58749d7SAndre Fischer catch ( uno::Exception const &) 4178590a0fdSAndre Fischer { 4188590a0fdSAndre Fischer return SERF_SSL_CERT_UNKNOWN_FAILURE; 419c58749d7SAndre Fischer } 4208590a0fdSAndre Fischer 421c58749d7SAndre Fischer // Decode the server certificate. 42210e20387SAndre Fischer const char* sBase64EncodedServerCertificate ( 42310e20387SAndre Fischer serf_ssl_cert_export( 42410e20387SAndre Fischer pCertificateChainBase64Encoded[0], 42510e20387SAndre Fischer getAprPool())); 426c58749d7SAndre Fischer uno::Reference< security::XCertificate > xServerCertificate( 4278590a0fdSAndre Fischer xSecurityEnv->createCertificateFromAscii( 42810e20387SAndre Fischer rtl::OUString::createFromAscii(sBase64EncodedServerCertificate))); 429c58749d7SAndre Fischer if ( ! xServerCertificate.is()) 430c58749d7SAndre Fischer return SERF_SSL_CERT_UNKNOWN_FAILURE; 4318590a0fdSAndre Fischer 432c58749d7SAndre Fischer // Get the subject from the server certificate. 433c58749d7SAndre Fischer ::rtl::OUString sServerCertificateSubject (xServerCertificate->getSubjectName()); 434c58749d7SAndre Fischer sal_Int32 nIndex = 0; 435c58749d7SAndre Fischer while (nIndex >= 0) 4368590a0fdSAndre Fischer { 437c58749d7SAndre Fischer const ::rtl::OUString sToken (sServerCertificateSubject.getToken(0, ',', nIndex)); 438c58749d7SAndre Fischer if (sToken.compareToAscii("CN=", 3) == 0) 439c58749d7SAndre Fischer { 440c58749d7SAndre Fischer sServerCertificateSubject = sToken.copy(3); 4418590a0fdSAndre Fischer break; 442c58749d7SAndre Fischer } 443c58749d7SAndre Fischer else if (sToken.compareToAscii(" CN=", 4) == 0) 444c58749d7SAndre Fischer { 445c58749d7SAndre Fischer sServerCertificateSubject = sToken.copy(4); 446c58749d7SAndre Fischer break; 447c58749d7SAndre Fischer } 448c58749d7SAndre Fischer } 4498590a0fdSAndre Fischer 450c58749d7SAndre Fischer // When the certificate container already contains a (trusted) 451c58749d7SAndre Fischer // entry for the server then we do not have to authenticate any 452c58749d7SAndre Fischer // certificate. 453c58749d7SAndre Fischer const security::CertificateContainerStatus eStatus ( 454c58749d7SAndre Fischer xCertificateContainer->hasCertificate( 455c58749d7SAndre Fischer getHostName(), sServerCertificateSubject ) ); 456c58749d7SAndre Fischer if (eStatus != security::CertificateContainerStatus_NOCERT) 457c58749d7SAndre Fischer { 458c58749d7SAndre Fischer return eStatus == security::CertificateContainerStatus_TRUSTED 459c58749d7SAndre Fischer ? APR_SUCCESS 460c58749d7SAndre Fischer : SERF_SSL_CERT_UNKNOWN_FAILURE; 461c58749d7SAndre Fischer } 4628590a0fdSAndre Fischer 463c58749d7SAndre Fischer // The shortcut failed, so try to verify the whole chain. This is 464c58749d7SAndre Fischer // done outside the isDomainMatch() block because the result is 465c58749d7SAndre Fischer // used by the interaction handler. 466c58749d7SAndre Fischer std::vector< uno::Reference< security::XCertificate > > aChain; 467fdf35928SAndre Fischer for (nIndex=1; nIndex<nCertificateChainLength; ++nIndex) 468c58749d7SAndre Fischer { 46910e20387SAndre Fischer const char* sBase64EncodedCertificate ( 47010e20387SAndre Fischer serf_ssl_cert_export( 47110e20387SAndre Fischer pCertificateChainBase64Encoded[nIndex], 47210e20387SAndre Fischer getAprPool())); 473c58749d7SAndre Fischer uno::Reference< security::XCertificate > xCertificate( 4748590a0fdSAndre Fischer xSecurityEnv->createCertificateFromAscii( 47510e20387SAndre Fischer rtl::OUString::createFromAscii(sBase64EncodedCertificate))); 476c58749d7SAndre Fischer if ( ! xCertificate.is()) 477c58749d7SAndre Fischer return SERF_SSL_CERT_UNKNOWN_FAILURE; 478c58749d7SAndre Fischer aChain.push_back(xCertificate); 4798590a0fdSAndre Fischer } 480c58749d7SAndre Fischer const sal_Int64 nVerificationResult (xSecurityEnv->verifyCertificate( 481c58749d7SAndre Fischer xServerCertificate, 482c58749d7SAndre Fischer ::comphelper::containerToSequence(aChain))); 4838590a0fdSAndre Fischer 484c58749d7SAndre Fischer // When the certificate matches the host name then we can use the 485c58749d7SAndre Fischer // result of the verification. 486e54851feSOliver-Rainer Wittmann bool bHostnameMatchesCertHostnames = false; 487e54851feSOliver-Rainer Wittmann { 488e54851feSOliver-Rainer Wittmann uno::Sequence< uno::Reference< security::XCertificateExtension > > extensions = xServerCertificate->getExtensions(); 489e54851feSOliver-Rainer Wittmann uno::Sequence< security::CertAltNameEntry > altNames; 490e54851feSOliver-Rainer Wittmann for (sal_Int32 i = 0 ; i < extensions.getLength(); ++i) 491e54851feSOliver-Rainer Wittmann { 492e54851feSOliver-Rainer Wittmann uno::Reference< security::XCertificateExtension >element = extensions[i]; 493e54851feSOliver-Rainer Wittmann 494e54851feSOliver-Rainer Wittmann const rtl::OString aId ( (const sal_Char *)element->getExtensionId().getArray(), element->getExtensionId().getLength()); 495e54851feSOliver-Rainer Wittmann if ( aId.equals( OID_SUBJECT_ALTERNATIVE_NAME ) ) 496e54851feSOliver-Rainer Wittmann { 497e54851feSOliver-Rainer Wittmann uno::Reference< security::XSanExtension > sanExtension ( element, uno::UNO_QUERY ); 498e54851feSOliver-Rainer Wittmann altNames = sanExtension->getAlternativeNames(); 499e54851feSOliver-Rainer Wittmann break; 500e54851feSOliver-Rainer Wittmann } 501e54851feSOliver-Rainer Wittmann } 502e54851feSOliver-Rainer Wittmann 503e54851feSOliver-Rainer Wittmann uno::Sequence< ::rtl::OUString > certHostNames(altNames.getLength() + 1); 504e54851feSOliver-Rainer Wittmann certHostNames[0] = sServerCertificateSubject; 505e54851feSOliver-Rainer Wittmann for( int n = 0; n < altNames.getLength(); ++n ) 506e54851feSOliver-Rainer Wittmann { 507e54851feSOliver-Rainer Wittmann if (altNames[n].Type == security::ExtAltNameType_DNS_NAME) 508e54851feSOliver-Rainer Wittmann { 509e54851feSOliver-Rainer Wittmann altNames[n].Value >>= certHostNames[n+1]; 510e54851feSOliver-Rainer Wittmann } 511e54851feSOliver-Rainer Wittmann } 512e54851feSOliver-Rainer Wittmann 513e54851feSOliver-Rainer Wittmann for ( int i = 0; i < certHostNames.getLength() && !bHostnameMatchesCertHostnames; ++i ) 514e54851feSOliver-Rainer Wittmann { 515e54851feSOliver-Rainer Wittmann bHostnameMatchesCertHostnames = isDomainMatch( certHostNames[i] ); 516e54851feSOliver-Rainer Wittmann } 517e54851feSOliver-Rainer Wittmann 518e54851feSOliver-Rainer Wittmann } 519e54851feSOliver-Rainer Wittmann if ( bHostnameMatchesCertHostnames ) 5208590a0fdSAndre Fischer { 521c58749d7SAndre Fischer 522c58749d7SAndre Fischer if (nVerificationResult == 0) 523c58749d7SAndre Fischer { 524c58749d7SAndre Fischer // Certificate (chain) is valid. 525c58749d7SAndre Fischer xCertificateContainer->addCertificate(getHostName(), sServerCertificateSubject, sal_True); 5268590a0fdSAndre Fischer return APR_SUCCESS; 527c58749d7SAndre Fischer } 528c58749d7SAndre Fischer else if ((nVerificationResult & security::CertificateValidity::CHAIN_INCOMPLETE) != 0) 529c58749d7SAndre Fischer { 530c58749d7SAndre Fischer // We do not have enough information for verification, 531c58749d7SAndre Fischer // neither automatically (as we just discovered) nor 532c58749d7SAndre Fischer // manually (so there is no point in showing any dialog.) 533c58749d7SAndre Fischer return SERF_SSL_CERT_UNKNOWN_FAILURE; 534c58749d7SAndre Fischer } 535c58749d7SAndre Fischer else if ((nVerificationResult & 536c58749d7SAndre Fischer (security::CertificateValidity::INVALID | security::CertificateValidity::REVOKED)) != 0) 537c58749d7SAndre Fischer { 538c58749d7SAndre Fischer // Certificate (chain) is invalid. 539c58749d7SAndre Fischer xCertificateContainer->addCertificate(getHostName(), sServerCertificateSubject, sal_False); 540c58749d7SAndre Fischer return SERF_SSL_CERT_UNKNOWN_FAILURE; 541c58749d7SAndre Fischer } 542c58749d7SAndre Fischer else 543c58749d7SAndre Fischer { 544c58749d7SAndre Fischer // For all other we have to ask the user. 545c58749d7SAndre Fischer } 5468590a0fdSAndre Fischer } 5478590a0fdSAndre Fischer 548c58749d7SAndre Fischer // We have not been able to automatically verify (or falsify) the 549c58749d7SAndre Fischer // certificate chain. To resolve this we have to ask the user. 5508590a0fdSAndre Fischer const uno::Reference< ucb::XCommandEnvironment > xEnv( getRequestEnvironment().m_xEnv ); 5518590a0fdSAndre Fischer if ( xEnv.is() ) 5528590a0fdSAndre Fischer { 5538590a0fdSAndre Fischer uno::Reference< task::XInteractionHandler > xIH( xEnv->getInteractionHandler() ); 5548590a0fdSAndre Fischer if ( xIH.is() ) 5558590a0fdSAndre Fischer { 5568590a0fdSAndre Fischer rtl::Reference< ucbhelper::SimpleCertificateValidationRequest > 5578590a0fdSAndre Fischer xRequest( new ucbhelper::SimpleCertificateValidationRequest( 558c58749d7SAndre Fischer static_cast<sal_Int32>(nVerificationResult), xServerCertificate, getHostName() ) ); 5598590a0fdSAndre Fischer xIH->handle( xRequest.get() ); 5608590a0fdSAndre Fischer 5618590a0fdSAndre Fischer rtl::Reference< ucbhelper::InteractionContinuation > xSelection 5628590a0fdSAndre Fischer = xRequest->getSelection(); 5638590a0fdSAndre Fischer 5648590a0fdSAndre Fischer if ( xSelection.is() ) 5658590a0fdSAndre Fischer { 566e54851feSOliver-Rainer Wittmann uno::Reference< task::XInteractionApprove > xApprove( xSelection.get(), uno::UNO_QUERY ); 5678590a0fdSAndre Fischer if ( xApprove.is() ) 5688590a0fdSAndre Fischer { 569c58749d7SAndre Fischer xCertificateContainer->addCertificate( getHostName(), sServerCertificateSubject, sal_True ); 5708590a0fdSAndre Fischer return APR_SUCCESS; 5718590a0fdSAndre Fischer } 5728590a0fdSAndre Fischer else 5738590a0fdSAndre Fischer { 5748590a0fdSAndre Fischer // Don't trust cert 575c58749d7SAndre Fischer xCertificateContainer->addCertificate( getHostName(), sServerCertificateSubject, sal_False ); 5768590a0fdSAndre Fischer return SERF_SSL_CERT_UNKNOWN_FAILURE; 5778590a0fdSAndre Fischer } 5788590a0fdSAndre Fischer } 5798590a0fdSAndre Fischer } 5808590a0fdSAndre Fischer else 5818590a0fdSAndre Fischer { 5828590a0fdSAndre Fischer // Don't trust cert 583c58749d7SAndre Fischer xCertificateContainer->addCertificate( getHostName(), sServerCertificateSubject, sal_False ); 5848590a0fdSAndre Fischer return SERF_SSL_CERT_UNKNOWN_FAILURE; 5858590a0fdSAndre Fischer } 5868590a0fdSAndre Fischer } 587c58749d7SAndre Fischer 5888590a0fdSAndre Fischer return SERF_SSL_CERT_UNKNOWN_FAILURE; 5898590a0fdSAndre Fischer } 5908590a0fdSAndre Fischer 5918590a0fdSAndre Fischer serf_bucket_t* SerfSession::acceptSerfResponse( serf_request_t * inSerfRequest, 5928590a0fdSAndre Fischer serf_bucket_t * inSerfStreamBucket, 5938590a0fdSAndre Fischer apr_pool_t* /*inAprPool*/ ) 5948590a0fdSAndre Fischer { 5958590a0fdSAndre Fischer // get the per-request bucket allocator 5968590a0fdSAndre Fischer serf_bucket_alloc_t* SerfBktAlloc = serf_request_get_alloc( inSerfRequest ); 5978590a0fdSAndre Fischer 5988590a0fdSAndre Fischer // create a barrier bucket so the response doesn't eat us! 5998590a0fdSAndre Fischer serf_bucket_t *responseBkt = serf_bucket_barrier_create( inSerfStreamBucket, 6008590a0fdSAndre Fischer SerfBktAlloc ); 6018590a0fdSAndre Fischer 6028590a0fdSAndre Fischer // create response bucket 603*5f30f85eSAndrea Pescetti responseBkt = serf_bucket_response_create( responseBkt, 6048590a0fdSAndre Fischer SerfBktAlloc ); 6058590a0fdSAndre Fischer 6068590a0fdSAndre Fischer if ( isHeadRequestInProgress() ) 6078590a0fdSAndre Fischer { 6088590a0fdSAndre Fischer // advise the response bucket that this was from a HEAD request and that it should not expect to see a response body. 6098590a0fdSAndre Fischer serf_bucket_response_set_head( responseBkt ); 6108590a0fdSAndre Fischer } 6118590a0fdSAndre Fischer 6128590a0fdSAndre Fischer return responseBkt; 6138590a0fdSAndre Fischer } 6148590a0fdSAndre Fischer 61549989859SOliver-Rainer Wittmann SerfRequestProcessor* SerfSession::createReqProc( const rtl::OUString & inPath ) 61649989859SOliver-Rainer Wittmann { 61749989859SOliver-Rainer Wittmann return new SerfRequestProcessor( *this, 61849989859SOliver-Rainer Wittmann inPath, 61949989859SOliver-Rainer Wittmann m_bUseChunkedEncoding ); 62049989859SOliver-Rainer Wittmann } 62149989859SOliver-Rainer Wittmann 6228590a0fdSAndre Fischer // ------------------------------------------------------------------- 6238590a0fdSAndre Fischer // PROPFIND - allprop & named 6248590a0fdSAndre Fischer // ------------------------------------------------------------------- 6258590a0fdSAndre Fischer void SerfSession::PROPFIND( const rtl::OUString & inPath, 6268590a0fdSAndre Fischer const Depth inDepth, 6278590a0fdSAndre Fischer const std::vector< rtl::OUString > & inPropNames, 6288590a0fdSAndre Fischer std::vector< DAVResource > & ioResources, 6298590a0fdSAndre Fischer const DAVRequestEnvironment & rEnv ) 6308590a0fdSAndre Fischer throw ( DAVException ) 6318590a0fdSAndre Fischer { 6328590a0fdSAndre Fischer osl::Guard< osl::Mutex > theGuard( m_aMutex ); 6338590a0fdSAndre Fischer 6348590a0fdSAndre Fischer Init( rEnv ); 6358590a0fdSAndre Fischer 6368590a0fdSAndre Fischer apr_status_t status = APR_SUCCESS; 63749989859SOliver-Rainer Wittmann boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); 63849989859SOliver-Rainer Wittmann aReqProc->processPropFind( inDepth, 63949989859SOliver-Rainer Wittmann inPropNames, 64049989859SOliver-Rainer Wittmann ioResources, 64149989859SOliver-Rainer Wittmann status ); 6428590a0fdSAndre Fischer 6438590a0fdSAndre Fischer if ( status == APR_SUCCESS && 64449989859SOliver-Rainer Wittmann aReqProc->mpDAVException == 0 && 6458590a0fdSAndre Fischer ioResources.empty() ) 6468590a0fdSAndre Fischer { 6478590a0fdSAndre Fischer m_aEnv = DAVRequestEnvironment(); 6488590a0fdSAndre Fischer throw DAVException( DAVException::DAV_HTTP_ERROR, inPath, (sal_uInt16)APR_EGENERAL ); 6498590a0fdSAndre Fischer } 65049989859SOliver-Rainer Wittmann HandleError( aReqProc ); 6518590a0fdSAndre Fischer } 6528590a0fdSAndre Fischer 6538590a0fdSAndre Fischer // ------------------------------------------------------------------- 6548590a0fdSAndre Fischer // PROPFIND - propnames 6558590a0fdSAndre Fischer // ------------------------------------------------------------------- 6568590a0fdSAndre Fischer void SerfSession::PROPFIND( const rtl::OUString & inPath, 6578590a0fdSAndre Fischer const Depth inDepth, 6588590a0fdSAndre Fischer std::vector< DAVResourceInfo > & ioResInfo, 6598590a0fdSAndre Fischer const DAVRequestEnvironment & rEnv ) 6608590a0fdSAndre Fischer throw( DAVException ) 6618590a0fdSAndre Fischer { 6628590a0fdSAndre Fischer osl::Guard< osl::Mutex > theGuard( m_aMutex ); 6638590a0fdSAndre Fischer 6648590a0fdSAndre Fischer Init( rEnv ); 6658590a0fdSAndre Fischer 6668590a0fdSAndre Fischer apr_status_t status = APR_SUCCESS; 66749989859SOliver-Rainer Wittmann boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); 66849989859SOliver-Rainer Wittmann aReqProc->processPropFind( inDepth, 66949989859SOliver-Rainer Wittmann ioResInfo, 67049989859SOliver-Rainer Wittmann status ); 6718590a0fdSAndre Fischer 6728590a0fdSAndre Fischer if ( status == APR_SUCCESS && 67349989859SOliver-Rainer Wittmann aReqProc->mpDAVException == 0 && 6748590a0fdSAndre Fischer ioResInfo.empty() ) 6758590a0fdSAndre Fischer { 6768590a0fdSAndre Fischer m_aEnv = DAVRequestEnvironment(); 6778590a0fdSAndre Fischer throw DAVException( DAVException::DAV_HTTP_ERROR, inPath, (sal_uInt16)APR_EGENERAL ); 6788590a0fdSAndre Fischer } 67949989859SOliver-Rainer Wittmann HandleError( aReqProc ); 6808590a0fdSAndre Fischer } 6818590a0fdSAndre Fischer 6828590a0fdSAndre Fischer // ------------------------------------------------------------------- 6838590a0fdSAndre Fischer // PROPPATCH 6848590a0fdSAndre Fischer // ------------------------------------------------------------------- 6858590a0fdSAndre Fischer void SerfSession::PROPPATCH( const rtl::OUString & inPath, 6868590a0fdSAndre Fischer const std::vector< ProppatchValue > & inValues, 6878590a0fdSAndre Fischer const DAVRequestEnvironment & rEnv ) 6888590a0fdSAndre Fischer throw( DAVException ) 6898590a0fdSAndre Fischer { 6908590a0fdSAndre Fischer osl::Guard< osl::Mutex > theGuard( m_aMutex ); 6918590a0fdSAndre Fischer 6928590a0fdSAndre Fischer Init( rEnv ); 6938590a0fdSAndre Fischer 6948590a0fdSAndre Fischer apr_status_t status = APR_SUCCESS; 69549989859SOliver-Rainer Wittmann boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); 69649989859SOliver-Rainer Wittmann aReqProc->processPropPatch( inValues, 69749989859SOliver-Rainer Wittmann status ); 6988590a0fdSAndre Fischer 69949989859SOliver-Rainer Wittmann HandleError( aReqProc ); 7008590a0fdSAndre Fischer } 7018590a0fdSAndre Fischer 7028590a0fdSAndre Fischer // ------------------------------------------------------------------- 7038590a0fdSAndre Fischer // HEAD 7048590a0fdSAndre Fischer // ------------------------------------------------------------------- 7058590a0fdSAndre Fischer void SerfSession::HEAD( const ::rtl::OUString & inPath, 7068590a0fdSAndre Fischer const std::vector< ::rtl::OUString > & inHeaderNames, 7078590a0fdSAndre Fischer DAVResource & ioResource, 7088590a0fdSAndre Fischer const DAVRequestEnvironment & rEnv ) 7098590a0fdSAndre Fischer throw( DAVException ) 7108590a0fdSAndre Fischer { 7118590a0fdSAndre Fischer osl::Guard< osl::Mutex > theGuard( m_aMutex ); 7128590a0fdSAndre Fischer 7138590a0fdSAndre Fischer Init( rEnv ); 7148590a0fdSAndre Fischer 7158590a0fdSAndre Fischer m_bIsHeadRequestInProgress = true; 7168590a0fdSAndre Fischer 71749989859SOliver-Rainer Wittmann boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); 7188590a0fdSAndre Fischer ioResource.uri = inPath; 7198590a0fdSAndre Fischer ioResource.properties.clear(); 7208590a0fdSAndre Fischer apr_status_t status = APR_SUCCESS; 72149989859SOliver-Rainer Wittmann aReqProc->processHead( inHeaderNames, 72249989859SOliver-Rainer Wittmann ioResource, 72349989859SOliver-Rainer Wittmann status ); 7248590a0fdSAndre Fischer 7258590a0fdSAndre Fischer m_bIsHeadRequestInProgress = false; 72649989859SOliver-Rainer Wittmann 72749989859SOliver-Rainer Wittmann HandleError( aReqProc ); 7288590a0fdSAndre Fischer } 7298590a0fdSAndre Fischer 7308590a0fdSAndre Fischer // ------------------------------------------------------------------- 7318590a0fdSAndre Fischer // GET 7328590a0fdSAndre Fischer // ------------------------------------------------------------------- 7338590a0fdSAndre Fischer uno::Reference< io::XInputStream > 7348590a0fdSAndre Fischer SerfSession::GET( const rtl::OUString & inPath, 7358590a0fdSAndre Fischer const DAVRequestEnvironment & rEnv ) 7368590a0fdSAndre Fischer throw ( DAVException ) 7378590a0fdSAndre Fischer { 7388590a0fdSAndre Fischer osl::Guard< osl::Mutex > theGuard( m_aMutex ); 7398590a0fdSAndre Fischer 7408590a0fdSAndre Fischer Init( rEnv ); 7418590a0fdSAndre Fischer 7428590a0fdSAndre Fischer uno::Reference< SerfInputStream > xInputStream( new SerfInputStream ); 7438590a0fdSAndre Fischer apr_status_t status = APR_SUCCESS; 74449989859SOliver-Rainer Wittmann boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); 74549989859SOliver-Rainer Wittmann aReqProc->processGet( xInputStream, 74649989859SOliver-Rainer Wittmann status ); 7478590a0fdSAndre Fischer 74849989859SOliver-Rainer Wittmann HandleError( aReqProc ); 7498590a0fdSAndre Fischer 7508590a0fdSAndre Fischer return uno::Reference< io::XInputStream >( xInputStream.get() ); 7518590a0fdSAndre Fischer } 7528590a0fdSAndre Fischer 7538590a0fdSAndre Fischer // ------------------------------------------------------------------- 7548590a0fdSAndre Fischer // GET 7558590a0fdSAndre Fischer // ------------------------------------------------------------------- 7568590a0fdSAndre Fischer void SerfSession::GET( const rtl::OUString & inPath, 7578590a0fdSAndre Fischer uno::Reference< io::XOutputStream > & ioOutputStream, 7588590a0fdSAndre Fischer const DAVRequestEnvironment & rEnv ) 7598590a0fdSAndre Fischer throw ( DAVException ) 7608590a0fdSAndre Fischer { 7618590a0fdSAndre Fischer osl::Guard< osl::Mutex > theGuard( m_aMutex ); 7628590a0fdSAndre Fischer 7638590a0fdSAndre Fischer Init( rEnv ); 7648590a0fdSAndre Fischer 7658590a0fdSAndre Fischer apr_status_t status = APR_SUCCESS; 76649989859SOliver-Rainer Wittmann boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); 76749989859SOliver-Rainer Wittmann aReqProc->processGet( ioOutputStream, 76849989859SOliver-Rainer Wittmann status ); 7698590a0fdSAndre Fischer 77049989859SOliver-Rainer Wittmann HandleError( aReqProc ); 7718590a0fdSAndre Fischer } 7728590a0fdSAndre Fischer 7738590a0fdSAndre Fischer // ------------------------------------------------------------------- 7748590a0fdSAndre Fischer // GET 7758590a0fdSAndre Fischer // ------------------------------------------------------------------- 7768590a0fdSAndre Fischer uno::Reference< io::XInputStream > 7778590a0fdSAndre Fischer SerfSession::GET( const rtl::OUString & inPath, 7788590a0fdSAndre Fischer const std::vector< ::rtl::OUString > & inHeaderNames, 7798590a0fdSAndre Fischer DAVResource & ioResource, 7808590a0fdSAndre Fischer const DAVRequestEnvironment & rEnv ) 7818590a0fdSAndre Fischer throw ( DAVException ) 7828590a0fdSAndre Fischer { 7838590a0fdSAndre Fischer osl::Guard< osl::Mutex > theGuard( m_aMutex ); 7848590a0fdSAndre Fischer 7858590a0fdSAndre Fischer Init( rEnv ); 7868590a0fdSAndre Fischer 78749989859SOliver-Rainer Wittmann boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); 7888590a0fdSAndre Fischer uno::Reference< SerfInputStream > xInputStream( new SerfInputStream ); 7898590a0fdSAndre Fischer ioResource.uri = inPath; 7908590a0fdSAndre Fischer ioResource.properties.clear(); 7918590a0fdSAndre Fischer apr_status_t status = APR_SUCCESS; 79249989859SOliver-Rainer Wittmann aReqProc->processGet( xInputStream, 79349989859SOliver-Rainer Wittmann inHeaderNames, 79449989859SOliver-Rainer Wittmann ioResource, 79549989859SOliver-Rainer Wittmann status ); 7968590a0fdSAndre Fischer 79749989859SOliver-Rainer Wittmann HandleError( aReqProc ); 7988590a0fdSAndre Fischer 7998590a0fdSAndre Fischer return uno::Reference< io::XInputStream >( xInputStream.get() ); 8008590a0fdSAndre Fischer } 8018590a0fdSAndre Fischer 8028590a0fdSAndre Fischer 8038590a0fdSAndre Fischer // ------------------------------------------------------------------- 8048590a0fdSAndre Fischer // GET 8058590a0fdSAndre Fischer // ------------------------------------------------------------------- 8068590a0fdSAndre Fischer void SerfSession::GET( const rtl::OUString & inPath, 8078590a0fdSAndre Fischer uno::Reference< io::XOutputStream > & ioOutputStream, 8088590a0fdSAndre Fischer const std::vector< ::rtl::OUString > & inHeaderNames, 8098590a0fdSAndre Fischer DAVResource & ioResource, 8108590a0fdSAndre Fischer const DAVRequestEnvironment & rEnv ) 8118590a0fdSAndre Fischer throw ( DAVException ) 8128590a0fdSAndre Fischer { 8138590a0fdSAndre Fischer osl::Guard< osl::Mutex > theGuard( m_aMutex ); 8148590a0fdSAndre Fischer 8158590a0fdSAndre Fischer Init( rEnv ); 8168590a0fdSAndre Fischer 81749989859SOliver-Rainer Wittmann boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); 8188590a0fdSAndre Fischer ioResource.uri = inPath; 8198590a0fdSAndre Fischer ioResource.properties.clear(); 8208590a0fdSAndre Fischer apr_status_t status = APR_SUCCESS; 82149989859SOliver-Rainer Wittmann aReqProc->processGet( ioOutputStream, 82249989859SOliver-Rainer Wittmann inHeaderNames, 82349989859SOliver-Rainer Wittmann ioResource, 82449989859SOliver-Rainer Wittmann status ); 8258590a0fdSAndre Fischer 82649989859SOliver-Rainer Wittmann HandleError( aReqProc ); 8278590a0fdSAndre Fischer } 8288590a0fdSAndre Fischer 8298590a0fdSAndre Fischer // ------------------------------------------------------------------- 8308590a0fdSAndre Fischer // PUT 8318590a0fdSAndre Fischer // ------------------------------------------------------------------- 8328590a0fdSAndre Fischer void SerfSession::PUT( const rtl::OUString & inPath, 8338590a0fdSAndre Fischer const uno::Reference< io::XInputStream > & inInputStream, 8348590a0fdSAndre Fischer const DAVRequestEnvironment & rEnv ) 8358590a0fdSAndre Fischer throw ( DAVException ) 8368590a0fdSAndre Fischer { 8378590a0fdSAndre Fischer osl::Guard< osl::Mutex > theGuard( m_aMutex ); 8388590a0fdSAndre Fischer 8398590a0fdSAndre Fischer Init( rEnv ); 8408590a0fdSAndre Fischer 84149989859SOliver-Rainer Wittmann boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); 8428590a0fdSAndre Fischer uno::Sequence< sal_Int8 > aDataToSend; 8438590a0fdSAndre Fischer if ( !getDataFromInputStream( inInputStream, aDataToSend, false ) ) 8448590a0fdSAndre Fischer throw DAVException( DAVException::DAV_INVALID_ARG ); 8458590a0fdSAndre Fischer apr_status_t status = APR_SUCCESS; 84649989859SOliver-Rainer Wittmann aReqProc->processPut( reinterpret_cast< const char * >( aDataToSend.getConstArray() ), 84749989859SOliver-Rainer Wittmann aDataToSend.getLength(), 84849989859SOliver-Rainer Wittmann status ); 8498590a0fdSAndre Fischer 85049989859SOliver-Rainer Wittmann HandleError( aReqProc ); 8518590a0fdSAndre Fischer } 8528590a0fdSAndre Fischer 8538590a0fdSAndre Fischer // ------------------------------------------------------------------- 8548590a0fdSAndre Fischer // POST 8558590a0fdSAndre Fischer // ------------------------------------------------------------------- 8568590a0fdSAndre Fischer uno::Reference< io::XInputStream > 8578590a0fdSAndre Fischer SerfSession::POST( const rtl::OUString & inPath, 8588590a0fdSAndre Fischer const rtl::OUString & rContentType, 8598590a0fdSAndre Fischer const rtl::OUString & rReferer, 8608590a0fdSAndre Fischer const uno::Reference< io::XInputStream > & inInputStream, 8618590a0fdSAndre Fischer const DAVRequestEnvironment & rEnv ) 8628590a0fdSAndre Fischer throw ( DAVException ) 8638590a0fdSAndre Fischer { 8648590a0fdSAndre Fischer osl::Guard< osl::Mutex > theGuard( m_aMutex ); 8658590a0fdSAndre Fischer 8668590a0fdSAndre Fischer uno::Sequence< sal_Int8 > aDataToSend; 8678590a0fdSAndre Fischer if ( !getDataFromInputStream( inInputStream, aDataToSend, true ) ) 8688590a0fdSAndre Fischer { 8698590a0fdSAndre Fischer throw DAVException( DAVException::DAV_INVALID_ARG ); 8708590a0fdSAndre Fischer } 8718590a0fdSAndre Fischer 8728590a0fdSAndre Fischer Init( rEnv ); 8738590a0fdSAndre Fischer 87449989859SOliver-Rainer Wittmann boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); 8758590a0fdSAndre Fischer uno::Reference< SerfInputStream > xInputStream( new SerfInputStream ); 8768590a0fdSAndre Fischer apr_status_t status = APR_SUCCESS; 87749989859SOliver-Rainer Wittmann aReqProc->processPost( reinterpret_cast< const char * >( aDataToSend.getConstArray() ), 87849989859SOliver-Rainer Wittmann aDataToSend.getLength(), 87949989859SOliver-Rainer Wittmann rContentType, 88049989859SOliver-Rainer Wittmann rReferer, 88149989859SOliver-Rainer Wittmann xInputStream, 88249989859SOliver-Rainer Wittmann status ); 88349989859SOliver-Rainer Wittmann 88449989859SOliver-Rainer Wittmann HandleError( aReqProc ); 8858590a0fdSAndre Fischer return uno::Reference< io::XInputStream >( xInputStream.get() ); 8868590a0fdSAndre Fischer } 8878590a0fdSAndre Fischer 8888590a0fdSAndre Fischer // ------------------------------------------------------------------- 8898590a0fdSAndre Fischer // POST 8908590a0fdSAndre Fischer // ------------------------------------------------------------------- 8918590a0fdSAndre Fischer void SerfSession::POST( const rtl::OUString & inPath, 8928590a0fdSAndre Fischer const rtl::OUString & rContentType, 8938590a0fdSAndre Fischer const rtl::OUString & rReferer, 8948590a0fdSAndre Fischer const uno::Reference< io::XInputStream > & inInputStream, 8958590a0fdSAndre Fischer uno::Reference< io::XOutputStream > & oOutputStream, 8968590a0fdSAndre Fischer const DAVRequestEnvironment & rEnv ) 8978590a0fdSAndre Fischer throw ( DAVException ) 8988590a0fdSAndre Fischer { 8998590a0fdSAndre Fischer osl::Guard< osl::Mutex > theGuard( m_aMutex ); 9008590a0fdSAndre Fischer 9018590a0fdSAndre Fischer uno::Sequence< sal_Int8 > aDataToSend; 9028590a0fdSAndre Fischer if ( !getDataFromInputStream( inInputStream, aDataToSend, true ) ) 9038590a0fdSAndre Fischer { 9048590a0fdSAndre Fischer throw DAVException( DAVException::DAV_INVALID_ARG ); 9058590a0fdSAndre Fischer } 9068590a0fdSAndre Fischer 9078590a0fdSAndre Fischer Init( rEnv ); 9088590a0fdSAndre Fischer 90949989859SOliver-Rainer Wittmann boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); 9108590a0fdSAndre Fischer apr_status_t status = APR_SUCCESS; 91149989859SOliver-Rainer Wittmann aReqProc->processPost( reinterpret_cast< const char * >( aDataToSend.getConstArray() ), 91249989859SOliver-Rainer Wittmann aDataToSend.getLength(), 91349989859SOliver-Rainer Wittmann rContentType, 91449989859SOliver-Rainer Wittmann rReferer, 91549989859SOliver-Rainer Wittmann oOutputStream, 91649989859SOliver-Rainer Wittmann status ); 91749989859SOliver-Rainer Wittmann 91849989859SOliver-Rainer Wittmann HandleError( aReqProc ); 9198590a0fdSAndre Fischer } 9208590a0fdSAndre Fischer 9218590a0fdSAndre Fischer // ------------------------------------------------------------------- 9228590a0fdSAndre Fischer // MKCOL 9238590a0fdSAndre Fischer // ------------------------------------------------------------------- 9248590a0fdSAndre Fischer void SerfSession::MKCOL( const rtl::OUString & inPath, 9258590a0fdSAndre Fischer const DAVRequestEnvironment & rEnv ) 9268590a0fdSAndre Fischer throw ( DAVException ) 9278590a0fdSAndre Fischer { 9288590a0fdSAndre Fischer osl::Guard< osl::Mutex > theGuard( m_aMutex ); 9298590a0fdSAndre Fischer 9308590a0fdSAndre Fischer Init( rEnv ); 9318590a0fdSAndre Fischer 93249989859SOliver-Rainer Wittmann boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); 9338590a0fdSAndre Fischer apr_status_t status = APR_SUCCESS; 934*5f30f85eSAndrea Pescetti aReqProc->processMkCol( status ); 9358590a0fdSAndre Fischer 93649989859SOliver-Rainer Wittmann HandleError( aReqProc ); 9378590a0fdSAndre Fischer } 9388590a0fdSAndre Fischer 9398590a0fdSAndre Fischer // ------------------------------------------------------------------- 9408590a0fdSAndre Fischer // COPY 9418590a0fdSAndre Fischer // ------------------------------------------------------------------- 9428590a0fdSAndre Fischer void SerfSession::COPY( const rtl::OUString & inSourceURL, 9438590a0fdSAndre Fischer const rtl::OUString & inDestinationURL, 9448590a0fdSAndre Fischer const DAVRequestEnvironment & rEnv, 9458590a0fdSAndre Fischer sal_Bool inOverWrite ) 9468590a0fdSAndre Fischer throw ( DAVException ) 9478590a0fdSAndre Fischer { 9488590a0fdSAndre Fischer osl::Guard< osl::Mutex > theGuard( m_aMutex ); 9498590a0fdSAndre Fischer 9508590a0fdSAndre Fischer Init( rEnv ); 9518590a0fdSAndre Fischer 9528590a0fdSAndre Fischer SerfUri theSourceUri( inSourceURL ); 95349989859SOliver-Rainer Wittmann boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( theSourceUri.GetPath() ) ); 9548590a0fdSAndre Fischer apr_status_t status = APR_SUCCESS; 95549989859SOliver-Rainer Wittmann aReqProc->processCopy( inDestinationURL, 95649989859SOliver-Rainer Wittmann (inOverWrite ? true : false), 95749989859SOliver-Rainer Wittmann status ); 9588590a0fdSAndre Fischer 95949989859SOliver-Rainer Wittmann HandleError( aReqProc ); 9608590a0fdSAndre Fischer } 9618590a0fdSAndre Fischer 9628590a0fdSAndre Fischer // ------------------------------------------------------------------- 9638590a0fdSAndre Fischer // MOVE 9648590a0fdSAndre Fischer // ------------------------------------------------------------------- 9658590a0fdSAndre Fischer void SerfSession::MOVE( const rtl::OUString & inSourceURL, 9668590a0fdSAndre Fischer const rtl::OUString & inDestinationURL, 9678590a0fdSAndre Fischer const DAVRequestEnvironment & rEnv, 9688590a0fdSAndre Fischer sal_Bool inOverWrite ) 9698590a0fdSAndre Fischer throw ( DAVException ) 9708590a0fdSAndre Fischer { 9718590a0fdSAndre Fischer osl::Guard< osl::Mutex > theGuard( m_aMutex ); 9728590a0fdSAndre Fischer 9738590a0fdSAndre Fischer Init( rEnv ); 9748590a0fdSAndre Fischer 9758590a0fdSAndre Fischer SerfUri theSourceUri( inSourceURL ); 97649989859SOliver-Rainer Wittmann boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( theSourceUri.GetPath() ) ); 9778590a0fdSAndre Fischer apr_status_t status = APR_SUCCESS; 97849989859SOliver-Rainer Wittmann aReqProc->processMove( inDestinationURL, 97949989859SOliver-Rainer Wittmann (inOverWrite ? true : false), 98049989859SOliver-Rainer Wittmann status ); 9818590a0fdSAndre Fischer 98249989859SOliver-Rainer Wittmann HandleError( aReqProc ); 9838590a0fdSAndre Fischer } 9848590a0fdSAndre Fischer 9858590a0fdSAndre Fischer // ------------------------------------------------------------------- 9868590a0fdSAndre Fischer // DESTROY 9878590a0fdSAndre Fischer // ------------------------------------------------------------------- 9888590a0fdSAndre Fischer void SerfSession::DESTROY( const rtl::OUString & inPath, 9898590a0fdSAndre Fischer const DAVRequestEnvironment & rEnv ) 9908590a0fdSAndre Fischer throw ( DAVException ) 9918590a0fdSAndre Fischer { 9928590a0fdSAndre Fischer osl::Guard< osl::Mutex > theGuard( m_aMutex ); 9938590a0fdSAndre Fischer 9948590a0fdSAndre Fischer Init( rEnv ); 9958590a0fdSAndre Fischer 99649989859SOliver-Rainer Wittmann boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); 9978590a0fdSAndre Fischer apr_status_t status = APR_SUCCESS; 998*5f30f85eSAndrea Pescetti aReqProc->processDelete( status ); 9998590a0fdSAndre Fischer 100049989859SOliver-Rainer Wittmann HandleError( aReqProc ); 10018590a0fdSAndre Fischer } 10028590a0fdSAndre Fischer 10038590a0fdSAndre Fischer // ------------------------------------------------------------------- 1004*5f30f85eSAndrea Pescetti /* 10058590a0fdSAndre Fischer namespace 10068590a0fdSAndre Fischer { 10078590a0fdSAndre Fischer sal_Int32 lastChanceToSendRefreshRequest( TimeValue const & rStart, 1008*5f30f85eSAndrea Pescetti int timeout ) 10098590a0fdSAndre Fischer { 10108590a0fdSAndre Fischer TimeValue aEnd; 10118590a0fdSAndre Fischer osl_getSystemTime( &aEnd ); 10128590a0fdSAndre Fischer 10138590a0fdSAndre Fischer // Try to estimate a safe absolute time for sending the 10148590a0fdSAndre Fischer // lock refresh request. 1015*5f30f85eSAndrea Pescetti sal_Int32 lastChanceToSendRefreshRequest = -1; 1016*5f30f85eSAndrea Pescetti if ( timeout != NE_TIMEOUT_INFINITE ) 10178590a0fdSAndre Fischer { 10188590a0fdSAndre Fischer sal_Int32 calltime = aEnd.Seconds - rStart.Seconds; 10198590a0fdSAndre Fischer if ( calltime <= timeout ) 10208590a0fdSAndre Fischer { 10218590a0fdSAndre Fischer lastChanceToSendRefreshRequest 10228590a0fdSAndre Fischer = aEnd.Seconds + timeout - calltime; 10238590a0fdSAndre Fischer } 10248590a0fdSAndre Fischer else 10258590a0fdSAndre Fischer { 10268590a0fdSAndre Fischer OSL_TRACE( "No chance to refresh lock before timeout!" ); 10278590a0fdSAndre Fischer } 10288590a0fdSAndre Fischer } 10298590a0fdSAndre Fischer return lastChanceToSendRefreshRequest; 10308590a0fdSAndre Fischer } 10318590a0fdSAndre Fischer 10328590a0fdSAndre Fischer } // namespace 1033*5f30f85eSAndrea Pescetti */ 10348590a0fdSAndre Fischer // ------------------------------------------------------------------- 10358590a0fdSAndre Fischer // LOCK (set new lock) 10368590a0fdSAndre Fischer // ------------------------------------------------------------------- 10378590a0fdSAndre Fischer void SerfSession::LOCK( const ::rtl::OUString & inPath, 1038*5f30f85eSAndrea Pescetti ucb::Lock & /*rLock*/, 10398590a0fdSAndre Fischer const DAVRequestEnvironment & rEnv ) 10408590a0fdSAndre Fischer throw ( DAVException ) 10418590a0fdSAndre Fischer { 10428590a0fdSAndre Fischer osl::Guard< osl::Mutex > theGuard( m_aMutex ); 10438590a0fdSAndre Fischer 10448fd7bf9dSAndrea Pescetti Init( rEnv ); 10458fd7bf9dSAndrea Pescetti 10468fd7bf9dSAndrea Pescetti boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); 1047*5f30f85eSAndrea Pescetti HandleError( aReqProc ); 1048*5f30f85eSAndrea Pescetti /* Create a depth zero, exclusive write lock, with default timeout 1049*5f30f85eSAndrea Pescetti * (allowing a server to pick a default). token, owner and uri are 1050*5f30f85eSAndrea Pescetti * unset. */ 1051*5f30f85eSAndrea Pescetti /* 1052*5f30f85eSAndrea Pescetti SerfLock * theLock = ne_lock_create(); 10538590a0fdSAndre Fischer 1054*5f30f85eSAndrea Pescetti // Set the lock uri 1055*5f30f85eSAndrea Pescetti ne_uri aUri; 1056*5f30f85eSAndrea Pescetti ne_uri_parse( rtl::OUStringToOString( makeAbsoluteURL( inPath ), 1057*5f30f85eSAndrea Pescetti RTL_TEXTENCODING_UTF8 ).getStr(), 1058*5f30f85eSAndrea Pescetti &aUri ); 1059*5f30f85eSAndrea Pescetti theLock->uri = aUri; 10608590a0fdSAndre Fischer 1061*5f30f85eSAndrea Pescetti // Set the lock depth 1062*5f30f85eSAndrea Pescetti switch( rLock.Depth ) 1063*5f30f85eSAndrea Pescetti { 1064*5f30f85eSAndrea Pescetti case ucb::LockDepth_ZERO: 1065*5f30f85eSAndrea Pescetti theLock->depth = NE_DEPTH_ZERO; 1066*5f30f85eSAndrea Pescetti break; 1067*5f30f85eSAndrea Pescetti case ucb::LockDepth_ONE: 1068*5f30f85eSAndrea Pescetti theLock->depth = NE_DEPTH_ONE; 1069*5f30f85eSAndrea Pescetti break; 1070*5f30f85eSAndrea Pescetti case ucb::LockDepth_INFINITY: 1071*5f30f85eSAndrea Pescetti theLock->depth = NE_DEPTH_INFINITE; 1072*5f30f85eSAndrea Pescetti break; 1073*5f30f85eSAndrea Pescetti default: 1074*5f30f85eSAndrea Pescetti throw DAVException( DAVException::DAV_INVALID_ARG ); 1075*5f30f85eSAndrea Pescetti } 1076*5f30f85eSAndrea Pescetti 1077*5f30f85eSAndrea Pescetti // Set the lock scope 1078*5f30f85eSAndrea Pescetti switch ( rLock.Scope ) 1079*5f30f85eSAndrea Pescetti { 1080*5f30f85eSAndrea Pescetti case ucb::LockScope_EXCLUSIVE: 1081*5f30f85eSAndrea Pescetti theLock->scope = ne_lockscope_exclusive; 1082*5f30f85eSAndrea Pescetti break; 1083*5f30f85eSAndrea Pescetti case ucb::LockScope_SHARED: 1084*5f30f85eSAndrea Pescetti theLock->scope = ne_lockscope_shared; 1085*5f30f85eSAndrea Pescetti break; 1086*5f30f85eSAndrea Pescetti default: 1087*5f30f85eSAndrea Pescetti throw DAVException( DAVException::DAV_INVALID_ARG ); 1088*5f30f85eSAndrea Pescetti } 1089*5f30f85eSAndrea Pescetti 1090*5f30f85eSAndrea Pescetti // Set the lock timeout 1091*5f30f85eSAndrea Pescetti theLock->timeout = (long)rLock.Timeout; 1092*5f30f85eSAndrea Pescetti 1093*5f30f85eSAndrea Pescetti // Set the lock owner 1094*5f30f85eSAndrea Pescetti rtl::OUString aValue; 1095*5f30f85eSAndrea Pescetti rLock.Owner >>= aValue; 1096*5f30f85eSAndrea Pescetti theLock->owner = 1097*5f30f85eSAndrea Pescetti ne_strdup( rtl::OUStringToOString( aValue, 1098*5f30f85eSAndrea Pescetti RTL_TEXTENCODING_UTF8 ).getStr() ); 10998590a0fdSAndre Fischer TimeValue startCall; 11008590a0fdSAndre Fischer osl_getSystemTime( &startCall ); 11018590a0fdSAndre Fischer 1102*5f30f85eSAndrea Pescetti int theRetVal = ne_lock( m_pHttpSession, theLock ); 1103*5f30f85eSAndrea Pescetti 1104*5f30f85eSAndrea Pescetti if ( theRetVal == NE_OK ) 1105*5f30f85eSAndrea Pescetti { 1106*5f30f85eSAndrea Pescetti m_aSerfLockStore.addLock( theLock, 1107*5f30f85eSAndrea Pescetti this, 1108*5f30f85eSAndrea Pescetti lastChanceToSendRefreshRequest( 1109*5f30f85eSAndrea Pescetti startCall, theLock->timeout ) ); 11108590a0fdSAndre Fischer 1111*5f30f85eSAndrea Pescetti uno::Sequence< rtl::OUString > aTokens( 1 ); 1112*5f30f85eSAndrea Pescetti aTokens[ 0 ] = rtl::OUString::createFromAscii( theLock->token ); 1113*5f30f85eSAndrea Pescetti rLock.LockTokens = aTokens; 1114*5f30f85eSAndrea Pescetti 1115*5f30f85eSAndrea Pescetti OSL_TRACE( "SerfSession::LOCK: created lock for %s. token: %s", 1116*5f30f85eSAndrea Pescetti rtl::OUStringToOString( makeAbsoluteURL( inPath ), 1117*5f30f85eSAndrea Pescetti RTL_TEXTENCODING_UTF8 ).getStr(), 1118*5f30f85eSAndrea Pescetti theLock->token ); 1119*5f30f85eSAndrea Pescetti } 1120*5f30f85eSAndrea Pescetti else 11218590a0fdSAndre Fischer { 1122*5f30f85eSAndrea Pescetti ne_lock_destroy( theLock ); 1123*5f30f85eSAndrea Pescetti 1124*5f30f85eSAndrea Pescetti OSL_TRACE( "SerfSession::LOCK: obtaining lock for %s failed!", 1125*5f30f85eSAndrea Pescetti rtl::OUStringToOString( makeAbsoluteURL( inPath ), 1126*5f30f85eSAndrea Pescetti RTL_TEXTENCODING_UTF8 ).getStr() ); 11278590a0fdSAndre Fischer } 11288590a0fdSAndre Fischer 1129*5f30f85eSAndrea Pescetti HandleError( theRetVal, inPath, rEnv ); 1130*5f30f85eSAndrea Pescetti */ 11318590a0fdSAndre Fischer } 11328590a0fdSAndre Fischer 11338590a0fdSAndre Fischer // ------------------------------------------------------------------- 1134*5f30f85eSAndrea Pescetti // LOCK (refresh existing lock) 11358590a0fdSAndre Fischer // ------------------------------------------------------------------- 11368590a0fdSAndre Fischer sal_Int64 SerfSession::LOCK( const ::rtl::OUString & /*inPath*/, 11378590a0fdSAndre Fischer sal_Int64 nTimeout, 11388590a0fdSAndre Fischer const DAVRequestEnvironment & /*rEnv*/ ) 11398590a0fdSAndre Fischer throw ( DAVException ) 11408590a0fdSAndre Fischer { 11418590a0fdSAndre Fischer osl::Guard< osl::Mutex > theGuard( m_aMutex ); 11428590a0fdSAndre Fischer 11438590a0fdSAndre Fischer return nTimeout; 11448590a0fdSAndre Fischer /* 11458590a0fdSAndre Fischer // Try to get the neon lock from lock store 11468590a0fdSAndre Fischer SerfLock * theLock 11478590a0fdSAndre Fischer = m_aSerfLockStore.findByUri( makeAbsoluteURL( inPath ) ); 11488590a0fdSAndre Fischer if ( !theLock ) 11498590a0fdSAndre Fischer throw DAVException( DAVException::DAV_NOT_LOCKED ); 11508590a0fdSAndre Fischer 11518590a0fdSAndre Fischer Init( rEnv ); 11528590a0fdSAndre Fischer 11538590a0fdSAndre Fischer // refresh existing lock. 11548590a0fdSAndre Fischer theLock->timeout = static_cast< long >( nTimeout ); 11558590a0fdSAndre Fischer 11568590a0fdSAndre Fischer TimeValue startCall; 11578590a0fdSAndre Fischer osl_getSystemTime( &startCall ); 11588590a0fdSAndre Fischer 11598590a0fdSAndre Fischer int theRetVal = ne_lock_refresh( m_pHttpSession, theLock ); 11608590a0fdSAndre Fischer 11618590a0fdSAndre Fischer if ( theRetVal == NE_OK ) 11628590a0fdSAndre Fischer { 11638590a0fdSAndre Fischer m_aSerfLockStore.updateLock( theLock, 11648590a0fdSAndre Fischer lastChanceToSendRefreshRequest( 11658590a0fdSAndre Fischer startCall, theLock->timeout ) ); 11668590a0fdSAndre Fischer } 11678590a0fdSAndre Fischer 11688590a0fdSAndre Fischer HandleError( theRetVal, inPath, rEnv ); 11698590a0fdSAndre Fischer 11708590a0fdSAndre Fischer return theLock->timeout; 11718590a0fdSAndre Fischer */ 11728590a0fdSAndre Fischer } 11738590a0fdSAndre Fischer 11748590a0fdSAndre Fischer // ------------------------------------------------------------------- 1175*5f30f85eSAndrea Pescetti // LOCK (refresh existing lock) 11768590a0fdSAndre Fischer // ------------------------------------------------------------------- 1177*5f30f85eSAndrea Pescetti bool SerfSession::LOCK( SerfLock * /*pLock*/, 1178*5f30f85eSAndrea Pescetti sal_Int32 & /*rlastChanceToSendRefreshRequest*/ ) 11798590a0fdSAndre Fischer { 11808590a0fdSAndre Fischer osl::Guard< osl::Mutex > theGuard( m_aMutex ); 11818590a0fdSAndre Fischer 1182*5f30f85eSAndrea Pescetti return true; 1183*5f30f85eSAndrea Pescetti /* 1184*5f30f85eSAndrea Pescetti // refresh existing lock. 11858590a0fdSAndre Fischer 11868590a0fdSAndre Fischer TimeValue startCall; 11878590a0fdSAndre Fischer osl_getSystemTime( &startCall ); 11888590a0fdSAndre Fischer 1189*5f30f85eSAndrea Pescetti if ( ne_lock_refresh( m_pHttpSession, pLock ) == NE_OK ) 1190*5f30f85eSAndrea Pescetti { 1191*5f30f85eSAndrea Pescetti rlastChanceToSendRefreshRequest 1192*5f30f85eSAndrea Pescetti = lastChanceToSendRefreshRequest( startCall, pLock->timeout ); 11938fd7bf9dSAndrea Pescetti 1194*5f30f85eSAndrea Pescetti OSL_TRACE( "Lock successfully refreshed." ); 1195*5f30f85eSAndrea Pescetti return true; 1196*5f30f85eSAndrea Pescetti } 1197*5f30f85eSAndrea Pescetti else 1198*5f30f85eSAndrea Pescetti { 1199*5f30f85eSAndrea Pescetti OSL_TRACE( "Lock not refreshed!" ); 1200*5f30f85eSAndrea Pescetti return false; 1201*5f30f85eSAndrea Pescetti } 1202*5f30f85eSAndrea Pescetti */ 12038590a0fdSAndre Fischer } 12048590a0fdSAndre Fischer 12058590a0fdSAndre Fischer // ------------------------------------------------------------------- 1206*5f30f85eSAndrea Pescetti // UNLOCK 12078590a0fdSAndre Fischer // ------------------------------------------------------------------- 1208*5f30f85eSAndrea Pescetti void SerfSession::UNLOCK( const ::rtl::OUString & /*inPath*/, 1209*5f30f85eSAndrea Pescetti const DAVRequestEnvironment & /*rEnv*/ ) 12108590a0fdSAndre Fischer throw ( DAVException ) 12118590a0fdSAndre Fischer { 12128590a0fdSAndre Fischer osl::Guard< osl::Mutex > theGuard( m_aMutex ); 12138590a0fdSAndre Fischer 1214*5f30f85eSAndrea Pescetti /* 1215*5f30f85eSAndrea Pescetti // get the neon lock from lock store 1216*5f30f85eSAndrea Pescetti SerfLock * theLock 1217*5f30f85eSAndrea Pescetti = m_aSerfLockStore.findByUri( makeAbsoluteURL( inPath ) ); 1218*5f30f85eSAndrea Pescetti if ( !theLock ) 12198590a0fdSAndre Fischer throw DAVException( DAVException::DAV_NOT_LOCKED ); 12208590a0fdSAndre Fischer 12218590a0fdSAndre Fischer Init( rEnv ); 12228590a0fdSAndre Fischer 1223*5f30f85eSAndrea Pescetti int theRetVal = ne_unlock( m_pHttpSession, theLock ); 12248590a0fdSAndre Fischer 1225*5f30f85eSAndrea Pescetti if ( theRetVal == NE_OK ) 1226*5f30f85eSAndrea Pescetti { 1227*5f30f85eSAndrea Pescetti m_aSerfLockStore.removeLock( theLock ); 1228*5f30f85eSAndrea Pescetti ne_lock_destroy( theLock ); 1229*5f30f85eSAndrea Pescetti } 1230*5f30f85eSAndrea Pescetti else 1231*5f30f85eSAndrea Pescetti { 1232*5f30f85eSAndrea Pescetti OSL_TRACE( "SerfSession::UNLOCK: unlocking of %s failed.", 1233*5f30f85eSAndrea Pescetti rtl::OUStringToOString( makeAbsoluteURL( inPath ), 1234*5f30f85eSAndrea Pescetti RTL_TEXTENCODING_UTF8 ).getStr() ); 1235*5f30f85eSAndrea Pescetti } 12368fd7bf9dSAndrea Pescetti 1237*5f30f85eSAndrea Pescetti HandleError( theRetVal, inPath, rEnv ); 1238*5f30f85eSAndrea Pescetti */ 12398590a0fdSAndre Fischer } 12408590a0fdSAndre Fischer 12418590a0fdSAndre Fischer // ------------------------------------------------------------------- 1242*5f30f85eSAndrea Pescetti // UNLOCK 12438590a0fdSAndre Fischer // ------------------------------------------------------------------- 1244*5f30f85eSAndrea Pescetti bool SerfSession::UNLOCK( SerfLock * /*pLock*/ ) 12458590a0fdSAndre Fischer { 12468590a0fdSAndre Fischer osl::Guard< osl::Mutex > theGuard( m_aMutex ); 12478590a0fdSAndre Fischer 12488590a0fdSAndre Fischer return true; 1249*5f30f85eSAndrea Pescetti /* 1250*5f30f85eSAndrea Pescetti if ( ne_unlock( m_pHttpSession, pLock ) == NE_OK ) 1251*5f30f85eSAndrea Pescetti { 1252*5f30f85eSAndrea Pescetti OSL_TRACE( "UNLOCK succeeded." ); 1253*5f30f85eSAndrea Pescetti return true; 1254*5f30f85eSAndrea Pescetti } 1255*5f30f85eSAndrea Pescetti else 1256*5f30f85eSAndrea Pescetti { 1257*5f30f85eSAndrea Pescetti OSL_TRACE( "UNLOCK failed!" ); 1258*5f30f85eSAndrea Pescetti return false; 1259*5f30f85eSAndrea Pescetti } 1260*5f30f85eSAndrea Pescetti */ 12618590a0fdSAndre Fischer } 12628590a0fdSAndre Fischer 12638590a0fdSAndre Fischer // ------------------------------------------------------------------- 12648590a0fdSAndre Fischer void SerfSession::abort() 12658590a0fdSAndre Fischer throw ( DAVException ) 12668590a0fdSAndre Fischer { 12678590a0fdSAndre Fischer // 11.11.09 (tkr): The following code lines causing crashes if 12688590a0fdSAndre Fischer // closing a ongoing connection. It turned out that this existing 12698590a0fdSAndre Fischer // solution doesn't work in multi-threading environments. 12708590a0fdSAndre Fischer // So I disabled them in 3.2. . Issue #73893# should fix it in OOo 3.3. 12718590a0fdSAndre Fischer //if ( m_pHttpSession ) 12728590a0fdSAndre Fischer // ne_close_connection( m_pHttpSession ); 12738590a0fdSAndre Fischer } 12748590a0fdSAndre Fischer 12758590a0fdSAndre Fischer // ------------------------------------------------------------------- 12768590a0fdSAndre Fischer const ucbhelper::InternetProxyServer & SerfSession::getProxySettings() const 12778590a0fdSAndre Fischer { 12788590a0fdSAndre Fischer if ( m_aUri.GetScheme().equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "http" ) ) || 12798590a0fdSAndre Fischer m_aUri.GetScheme().equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "https" ) ) ) 12808590a0fdSAndre Fischer { 12818590a0fdSAndre Fischer return m_rProxyDecider.getProxy( m_aUri.GetScheme(), 12828590a0fdSAndre Fischer m_aUri.GetHost(), 12838590a0fdSAndre Fischer m_aUri.GetPort() ); 12848590a0fdSAndre Fischer } 12858590a0fdSAndre Fischer else 12868590a0fdSAndre Fischer { 12878590a0fdSAndre Fischer // TODO: figure out, if this case can occur 12888590a0fdSAndre Fischer return m_rProxyDecider.getProxy( m_aUri.GetScheme(), 12898590a0fdSAndre Fischer rtl::OUString() /* not used */, 12908590a0fdSAndre Fischer -1 /* not used */ ); 12918590a0fdSAndre Fischer } 12928590a0fdSAndre Fischer } 12938590a0fdSAndre Fischer 12948590a0fdSAndre Fischer /* 12958590a0fdSAndre Fischer // ------------------------------------------------------------------- 12968590a0fdSAndre Fischer namespace { 12978590a0fdSAndre Fischer 12988590a0fdSAndre Fischer bool containsLocktoken( const uno::Sequence< ucb::Lock > & rLocks, 12998590a0fdSAndre Fischer const char * token ) 13008590a0fdSAndre Fischer { 13018590a0fdSAndre Fischer for ( sal_Int32 n = 0; n < rLocks.getLength(); ++n ) 13028590a0fdSAndre Fischer { 13038590a0fdSAndre Fischer const uno::Sequence< rtl::OUString > & rTokens 13048590a0fdSAndre Fischer = rLocks[ n ].LockTokens; 13058590a0fdSAndre Fischer for ( sal_Int32 m = 0; m < rTokens.getLength(); ++m ) 13068590a0fdSAndre Fischer { 13078590a0fdSAndre Fischer if ( rTokens[ m ].equalsAscii( token ) ) 13088590a0fdSAndre Fischer return true; 13098590a0fdSAndre Fischer } 13108590a0fdSAndre Fischer } 13118590a0fdSAndre Fischer return false; 13128590a0fdSAndre Fischer } 13138590a0fdSAndre Fischer 13148590a0fdSAndre Fischer } // namespace 13158590a0fdSAndre Fischer */ 13168590a0fdSAndre Fischer 13178590a0fdSAndre Fischer // ------------------------------------------------------------------- 13188590a0fdSAndre Fischer bool SerfSession::removeExpiredLocktoken( const rtl::OUString & /*inURL*/, 13198590a0fdSAndre Fischer const DAVRequestEnvironment & /*rEnv*/ ) 13208590a0fdSAndre Fischer { 13218590a0fdSAndre Fischer return true; 13228590a0fdSAndre Fischer /* 13238590a0fdSAndre Fischer SerfLock * theLock = m_aSerfLockStore.findByUri( inURL ); 13248590a0fdSAndre Fischer if ( !theLock ) 13258590a0fdSAndre Fischer return false; 13268590a0fdSAndre Fischer 13278590a0fdSAndre Fischer // do a lockdiscovery to check whether this lock is still valid. 13288590a0fdSAndre Fischer try 13298590a0fdSAndre Fischer { 13308590a0fdSAndre Fischer // @@@ Alternative: use ne_lock_discover() => less overhead 13318590a0fdSAndre Fischer 13328590a0fdSAndre Fischer std::vector< DAVResource > aResources; 13338590a0fdSAndre Fischer std::vector< rtl::OUString > aPropNames; 13348590a0fdSAndre Fischer aPropNames.push_back( DAVProperties::LOCKDISCOVERY ); 13358590a0fdSAndre Fischer 13368590a0fdSAndre Fischer PROPFIND( rEnv.m_aRequestURI, DAVZERO, aPropNames, aResources, rEnv ); 13378590a0fdSAndre Fischer 13388590a0fdSAndre Fischer if ( aResources.size() == 0 ) 13398590a0fdSAndre Fischer return false; 13408590a0fdSAndre Fischer 13418590a0fdSAndre Fischer std::vector< DAVPropertyValue >::const_iterator it 13428590a0fdSAndre Fischer = aResources[ 0 ].properties.begin(); 13438590a0fdSAndre Fischer std::vector< DAVPropertyValue >::const_iterator end 13448590a0fdSAndre Fischer = aResources[ 0 ].properties.end(); 13458590a0fdSAndre Fischer 13468590a0fdSAndre Fischer while ( it != end ) 13478590a0fdSAndre Fischer { 13488590a0fdSAndre Fischer if ( (*it).Name.equals( DAVProperties::LOCKDISCOVERY ) ) 13498590a0fdSAndre Fischer { 13508590a0fdSAndre Fischer uno::Sequence< ucb::Lock > aLocks; 13518590a0fdSAndre Fischer if ( !( (*it).Value >>= aLocks ) ) 13528590a0fdSAndre Fischer return false; 13538590a0fdSAndre Fischer 13548590a0fdSAndre Fischer if ( !containsLocktoken( aLocks, theLock->token ) ) 13558590a0fdSAndre Fischer { 13568590a0fdSAndre Fischer // expired! 13578590a0fdSAndre Fischer break; 13588590a0fdSAndre Fischer } 13598590a0fdSAndre Fischer 13608590a0fdSAndre Fischer // still valid. 13618590a0fdSAndre Fischer return false; 13628590a0fdSAndre Fischer } 13638590a0fdSAndre Fischer ++it; 13648590a0fdSAndre Fischer } 13658590a0fdSAndre Fischer 13668590a0fdSAndre Fischer // No lockdiscovery prop in propfind result / locktoken not found 13678590a0fdSAndre Fischer // in propfind result -> not locked 13688590a0fdSAndre Fischer OSL_TRACE( "SerfSession::removeExpiredLocktoken: Removing " 13698590a0fdSAndre Fischer " expired lock token for %s. token: %s", 13708590a0fdSAndre Fischer rtl::OUStringToOString( inURL, 13718590a0fdSAndre Fischer RTL_TEXTENCODING_UTF8 ).getStr(), 13728590a0fdSAndre Fischer theLock->token ); 13738590a0fdSAndre Fischer 13748590a0fdSAndre Fischer m_aSerfLockStore.removeLock( theLock ); 13758590a0fdSAndre Fischer ne_lock_destroy( theLock ); 13768590a0fdSAndre Fischer return true; 13778590a0fdSAndre Fischer } 13788590a0fdSAndre Fischer catch ( DAVException const & ) 13798590a0fdSAndre Fischer { 13808590a0fdSAndre Fischer } 13818590a0fdSAndre Fischer return false; 13828590a0fdSAndre Fischer */ 13838590a0fdSAndre Fischer } 13848590a0fdSAndre Fischer 13858590a0fdSAndre Fischer // ------------------------------------------------------------------- 13868590a0fdSAndre Fischer // HandleError 13878590a0fdSAndre Fischer // Common Error Handler 13888590a0fdSAndre Fischer // ------------------------------------------------------------------- 138949989859SOliver-Rainer Wittmann void SerfSession::HandleError( boost::shared_ptr<SerfRequestProcessor> rReqProc ) 13908590a0fdSAndre Fischer throw ( DAVException ) 13918590a0fdSAndre Fischer { 13928590a0fdSAndre Fischer m_aEnv = DAVRequestEnvironment(); 13938590a0fdSAndre Fischer 139449989859SOliver-Rainer Wittmann if ( rReqProc->mpDAVException ) 13958590a0fdSAndre Fischer { 139649989859SOliver-Rainer Wittmann DAVException* mpDAVExp( rReqProc->mpDAVException ); 13978590a0fdSAndre Fischer 13988590a0fdSAndre Fischer serf_connection_reset( getSerfConnection() ); 13998590a0fdSAndre Fischer 140049989859SOliver-Rainer Wittmann if ( mpDAVExp->getStatus() == 413 && 140149989859SOliver-Rainer Wittmann m_bNoOfTransferEncodingSwitches < 2 ) 140249989859SOliver-Rainer Wittmann { 140349989859SOliver-Rainer Wittmann m_bUseChunkedEncoding = !m_bUseChunkedEncoding; 140449989859SOliver-Rainer Wittmann ++m_bNoOfTransferEncodingSwitches; 140549989859SOliver-Rainer Wittmann } 140649989859SOliver-Rainer Wittmann 14078590a0fdSAndre Fischer throw DAVException( mpDAVExp->getError(), 14088590a0fdSAndre Fischer mpDAVExp->getData(), 14098590a0fdSAndre Fischer mpDAVExp->getStatus() ); 14108590a0fdSAndre Fischer } 14118590a0fdSAndre Fischer 14128590a0fdSAndre Fischer /* 14138590a0fdSAndre Fischer // Map error code to DAVException. 14148590a0fdSAndre Fischer switch ( nError ) 14158590a0fdSAndre Fischer { 14168590a0fdSAndre Fischer case NE_OK: 14178590a0fdSAndre Fischer return; 14188590a0fdSAndre Fischer 14198590a0fdSAndre Fischer case NE_ERROR: // Generic error 14208590a0fdSAndre Fischer { 14218590a0fdSAndre Fischer rtl::OUString aText = rtl::OUString::createFromAscii( 14228590a0fdSAndre Fischer ne_get_error( m_pHttpSession ) ); 14238590a0fdSAndre Fischer 14248590a0fdSAndre Fischer sal_uInt16 code = makeStatusCode( aText ); 14258590a0fdSAndre Fischer 14268590a0fdSAndre Fischer if ( code == SC_LOCKED ) 14278590a0fdSAndre Fischer { 14288590a0fdSAndre Fischer if ( m_aSerfLockStore.findByUri( 14298590a0fdSAndre Fischer makeAbsoluteURL( inPath ) ) == 0 ) 14308590a0fdSAndre Fischer { 14318590a0fdSAndre Fischer // locked by 3rd party 14328590a0fdSAndre Fischer throw DAVException( DAVException::DAV_LOCKED ); 14338590a0fdSAndre Fischer } 14348590a0fdSAndre Fischer else 14358590a0fdSAndre Fischer { 14368590a0fdSAndre Fischer // locked by ourself 14378590a0fdSAndre Fischer throw DAVException( DAVException::DAV_LOCKED_SELF ); 14388590a0fdSAndre Fischer } 14398590a0fdSAndre Fischer } 14408590a0fdSAndre Fischer 14418590a0fdSAndre Fischer // Special handling for 400 and 412 status codes, which may indicate 14428590a0fdSAndre Fischer // that a lock previously obtained by us has been released meanwhile 14438590a0fdSAndre Fischer // by the server. Unfortunately, RFC is not clear at this point, 14448590a0fdSAndre Fischer // thus server implementations behave different... 14458590a0fdSAndre Fischer else if ( code == SC_BAD_REQUEST || code == SC_PRECONDITION_FAILED ) 14468590a0fdSAndre Fischer { 14478590a0fdSAndre Fischer if ( removeExpiredLocktoken( makeAbsoluteURL( inPath ), rEnv ) ) 14488590a0fdSAndre Fischer throw DAVException( DAVException::DAV_LOCK_EXPIRED ); 14498590a0fdSAndre Fischer } 14508590a0fdSAndre Fischer 14518590a0fdSAndre Fischer throw DAVException( DAVException::DAV_HTTP_ERROR, aText, code ); 14528590a0fdSAndre Fischer } 14538590a0fdSAndre Fischer case NE_LOOKUP: // Name lookup failed. 14548590a0fdSAndre Fischer throw DAVException( DAVException::DAV_HTTP_LOOKUP, 14558590a0fdSAndre Fischer SerfUri::makeConnectionEndPointString( 14568590a0fdSAndre Fischer m_aHostName, m_nPort ) ); 14578590a0fdSAndre Fischer 14588590a0fdSAndre Fischer case NE_AUTH: // User authentication failed on server 14598590a0fdSAndre Fischer throw DAVException( DAVException::DAV_HTTP_AUTH, 14608590a0fdSAndre Fischer SerfUri::makeConnectionEndPointString( 14618590a0fdSAndre Fischer m_aHostName, m_nPort ) ); 14628590a0fdSAndre Fischer 14638590a0fdSAndre Fischer case NE_PROXYAUTH: // User authentication failed on proxy 14648590a0fdSAndre Fischer throw DAVException( DAVException::DAV_HTTP_AUTHPROXY, 14658590a0fdSAndre Fischer SerfUri::makeConnectionEndPointString( 14668590a0fdSAndre Fischer m_aProxyName, m_nProxyPort ) ); 14678590a0fdSAndre Fischer 14688590a0fdSAndre Fischer case NE_CONNECT: // Could not connect to server 14698590a0fdSAndre Fischer throw DAVException( DAVException::DAV_HTTP_CONNECT, 14708590a0fdSAndre Fischer SerfUri::makeConnectionEndPointString( 14718590a0fdSAndre Fischer m_aHostName, m_nPort ) ); 14728590a0fdSAndre Fischer 14738590a0fdSAndre Fischer case NE_TIMEOUT: // Connection timed out 14748590a0fdSAndre Fischer throw DAVException( DAVException::DAV_HTTP_TIMEOUT, 14758590a0fdSAndre Fischer SerfUri::makeConnectionEndPointString( 14768590a0fdSAndre Fischer m_aHostName, m_nPort ) ); 14778590a0fdSAndre Fischer 14788590a0fdSAndre Fischer case NE_FAILED: // The precondition failed 14798590a0fdSAndre Fischer throw DAVException( DAVException::DAV_HTTP_FAILED, 14808590a0fdSAndre Fischer SerfUri::makeConnectionEndPointString( 14818590a0fdSAndre Fischer m_aHostName, m_nPort ) ); 14828590a0fdSAndre Fischer 14838590a0fdSAndre Fischer case NE_RETRY: // Retry request (ne_end_request ONLY) 14848590a0fdSAndre Fischer throw DAVException( DAVException::DAV_HTTP_RETRY, 14858590a0fdSAndre Fischer SerfUri::makeConnectionEndPointString( 14868590a0fdSAndre Fischer m_aHostName, m_nPort ) ); 14878590a0fdSAndre Fischer 14888590a0fdSAndre Fischer case NE_REDIRECT: 14898590a0fdSAndre Fischer { 14908590a0fdSAndre Fischer SerfUri aUri( ne_redirect_location( m_pHttpSession ) ); 14918590a0fdSAndre Fischer throw DAVException( 14928590a0fdSAndre Fischer DAVException::DAV_HTTP_REDIRECT, aUri.GetURI() ); 14938590a0fdSAndre Fischer } 14948590a0fdSAndre Fischer default: 14958590a0fdSAndre Fischer { 14968590a0fdSAndre Fischer OSL_TRACE( "SerfSession::HandleError : Unknown Serf error code!" ); 14978590a0fdSAndre Fischer throw DAVException( DAVException::DAV_HTTP_ERROR, 14988590a0fdSAndre Fischer rtl::OUString::createFromAscii( 14998590a0fdSAndre Fischer ne_get_error( m_pHttpSession ) ) ); 15008590a0fdSAndre Fischer } 15018590a0fdSAndre Fischer } 15028590a0fdSAndre Fischer */ 15038590a0fdSAndre Fischer } 15048590a0fdSAndre Fischer 15058590a0fdSAndre Fischer // ------------------------------------------------------------------- 15068590a0fdSAndre Fischer // static 15078590a0fdSAndre Fischer bool 15088590a0fdSAndre Fischer SerfSession::getDataFromInputStream( 15098590a0fdSAndre Fischer const uno::Reference< io::XInputStream > & xStream, 15108590a0fdSAndre Fischer uno::Sequence< sal_Int8 > & rData, 15118590a0fdSAndre Fischer bool bAppendTrailingZeroByte ) 15128590a0fdSAndre Fischer { 15138590a0fdSAndre Fischer if ( xStream.is() ) 15148590a0fdSAndre Fischer { 15158590a0fdSAndre Fischer uno::Reference< io::XSeekable > xSeekable( xStream, uno::UNO_QUERY ); 15168590a0fdSAndre Fischer if ( xSeekable.is() ) 15178590a0fdSAndre Fischer { 15188590a0fdSAndre Fischer try 15198590a0fdSAndre Fischer { 15208590a0fdSAndre Fischer sal_Int32 nSize 15218590a0fdSAndre Fischer = sal::static_int_cast<sal_Int32>(xSeekable->getLength()); 15228590a0fdSAndre Fischer sal_Int32 nRead 15238590a0fdSAndre Fischer = xStream->readBytes( rData, nSize ); 15248590a0fdSAndre Fischer 15258590a0fdSAndre Fischer if ( nRead == nSize ) 15268590a0fdSAndre Fischer { 15278590a0fdSAndre Fischer if ( bAppendTrailingZeroByte ) 15288590a0fdSAndre Fischer { 15298590a0fdSAndre Fischer rData.realloc( nSize + 1 ); 15308590a0fdSAndre Fischer rData[ nSize ] = sal_Int8( 0 ); 15318590a0fdSAndre Fischer } 15328590a0fdSAndre Fischer return true; 15338590a0fdSAndre Fischer } 15348590a0fdSAndre Fischer } 15358590a0fdSAndre Fischer catch ( io::NotConnectedException const & ) 15368590a0fdSAndre Fischer { 15378590a0fdSAndre Fischer // readBytes 15388590a0fdSAndre Fischer } 15398590a0fdSAndre Fischer catch ( io::BufferSizeExceededException const & ) 15408590a0fdSAndre Fischer { 15418590a0fdSAndre Fischer // readBytes 15428590a0fdSAndre Fischer } 15438590a0fdSAndre Fischer catch ( io::IOException const & ) 15448590a0fdSAndre Fischer { 15458590a0fdSAndre Fischer // getLength, readBytes 15468590a0fdSAndre Fischer } 15478590a0fdSAndre Fischer } 15488590a0fdSAndre Fischer else 15498590a0fdSAndre Fischer { 15508590a0fdSAndre Fischer try 15518590a0fdSAndre Fischer { 15528590a0fdSAndre Fischer uno::Sequence< sal_Int8 > aBuffer; 15538590a0fdSAndre Fischer sal_Int32 nPos = 0; 15548590a0fdSAndre Fischer 15558590a0fdSAndre Fischer sal_Int32 nRead = xStream->readSomeBytes( aBuffer, 65536 ); 15568590a0fdSAndre Fischer while ( nRead > 0 ) 15578590a0fdSAndre Fischer { 15588590a0fdSAndre Fischer if ( rData.getLength() < ( nPos + nRead ) ) 15598590a0fdSAndre Fischer rData.realloc( nPos + nRead ); 15608590a0fdSAndre Fischer 15618590a0fdSAndre Fischer aBuffer.realloc( nRead ); 15628590a0fdSAndre Fischer rtl_copyMemory( (void*)( rData.getArray() + nPos ), 15638590a0fdSAndre Fischer (const void*)aBuffer.getConstArray(), 15648590a0fdSAndre Fischer nRead ); 15658590a0fdSAndre Fischer nPos += nRead; 15668590a0fdSAndre Fischer 15678590a0fdSAndre Fischer aBuffer.realloc( 0 ); 15688590a0fdSAndre Fischer nRead = xStream->readSomeBytes( aBuffer, 65536 ); 15698590a0fdSAndre Fischer } 15708590a0fdSAndre Fischer 15718590a0fdSAndre Fischer if ( bAppendTrailingZeroByte ) 15728590a0fdSAndre Fischer { 15738590a0fdSAndre Fischer rData.realloc( nPos + 1 ); 15748590a0fdSAndre Fischer rData[ nPos ] = sal_Int8( 0 ); 15758590a0fdSAndre Fischer } 15768590a0fdSAndre Fischer return true; 15778590a0fdSAndre Fischer } 15788590a0fdSAndre Fischer catch ( io::NotConnectedException const & ) 15798590a0fdSAndre Fischer { 15808590a0fdSAndre Fischer // readBytes 15818590a0fdSAndre Fischer } 15828590a0fdSAndre Fischer catch ( io::BufferSizeExceededException const & ) 15838590a0fdSAndre Fischer { 15848590a0fdSAndre Fischer // readBytes 15858590a0fdSAndre Fischer } 15868590a0fdSAndre Fischer catch ( io::IOException const & ) 15878590a0fdSAndre Fischer { 15888590a0fdSAndre Fischer // readBytes 15898590a0fdSAndre Fischer } 15908590a0fdSAndre Fischer } 15918590a0fdSAndre Fischer } 15928590a0fdSAndre Fischer return false; 15938590a0fdSAndre Fischer } 15948590a0fdSAndre Fischer 15958590a0fdSAndre Fischer // --------------------------------------------------------------------- 15968590a0fdSAndre Fischer sal_Bool 15978590a0fdSAndre Fischer SerfSession::isDomainMatch( rtl::OUString certHostName ) 15988590a0fdSAndre Fischer { 15998590a0fdSAndre Fischer rtl::OUString hostName = getHostName(); 16008590a0fdSAndre Fischer 16018590a0fdSAndre Fischer if (hostName.equalsIgnoreAsciiCase( certHostName ) ) 16028590a0fdSAndre Fischer return sal_True; 16038590a0fdSAndre Fischer 16048590a0fdSAndre Fischer if ( 0 == certHostName.indexOf( rtl::OUString::createFromAscii( "*" ) ) && 16058590a0fdSAndre Fischer hostName.getLength() >= certHostName.getLength() ) 16068590a0fdSAndre Fischer { 16078590a0fdSAndre Fischer rtl::OUString cmpStr = certHostName.copy( 1 ); 16088590a0fdSAndre Fischer 16098590a0fdSAndre Fischer if ( hostName.matchIgnoreAsciiCase( 16108590a0fdSAndre Fischer cmpStr, hostName.getLength() - cmpStr.getLength() ) ) 16118590a0fdSAndre Fischer return sal_True; 16128590a0fdSAndre Fischer } 16138590a0fdSAndre Fischer return sal_False; 16148590a0fdSAndre Fischer } 1615*5f30f85eSAndrea Pescetti 1616*5f30f85eSAndrea Pescetti /* 1617*5f30f85eSAndrea Pescetti // --------------------------------------------------------------------- 1618*5f30f85eSAndrea Pescetti rtl::OUString SerfSession::makeAbsoluteURL( rtl::OUString const & rURL ) const 1619*5f30f85eSAndrea Pescetti { 1620*5f30f85eSAndrea Pescetti try 1621*5f30f85eSAndrea Pescetti { 1622*5f30f85eSAndrea Pescetti // Is URL relative or already absolute? 1623*5f30f85eSAndrea Pescetti if ( rURL[ 0 ] != sal_Unicode( '/' ) ) 1624*5f30f85eSAndrea Pescetti { 1625*5f30f85eSAndrea Pescetti // absolute. 1626*5f30f85eSAndrea Pescetti return rtl::OUString( rURL ); 1627*5f30f85eSAndrea Pescetti } 1628*5f30f85eSAndrea Pescetti else 1629*5f30f85eSAndrea Pescetti { 1630*5f30f85eSAndrea Pescetti ne_uri aUri; 1631*5f30f85eSAndrea Pescetti memset( &aUri, 0, sizeof( aUri ) ); 1632*5f30f85eSAndrea Pescetti 1633*5f30f85eSAndrea Pescetti ne_fill_server_uri( m_pHttpSession, &aUri ); 1634*5f30f85eSAndrea Pescetti aUri.path 1635*5f30f85eSAndrea Pescetti = ne_strdup( rtl::OUStringToOString( 1636*5f30f85eSAndrea Pescetti rURL, RTL_TEXTENCODING_UTF8 ).getStr() ); 1637*5f30f85eSAndrea Pescetti SerfUri aSerfUri( &aUri ); 1638*5f30f85eSAndrea Pescetti ne_uri_free( &aUri ); 1639*5f30f85eSAndrea Pescetti return aSerfUri.GetURI(); 1640*5f30f85eSAndrea Pescetti } 1641*5f30f85eSAndrea Pescetti } 1642*5f30f85eSAndrea Pescetti catch ( DAVException const & ) 1643*5f30f85eSAndrea Pescetti { 1644*5f30f85eSAndrea Pescetti } 1645*5f30f85eSAndrea Pescetti // error. 1646*5f30f85eSAndrea Pescetti return rtl::OUString(); 1647*5f30f85eSAndrea Pescetti } 1648*5f30f85eSAndrea Pescetti */ 1649