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