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