1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski  *
3*b1cdbd2cSJim Jagielski  * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski  * or more contributor license agreements.  See the NOTICE file
5*b1cdbd2cSJim Jagielski  * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski  * regarding copyright ownership.  The ASF licenses this file
7*b1cdbd2cSJim Jagielski  * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski  * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski  * with the License.  You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski  *
11*b1cdbd2cSJim Jagielski  *   http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski  *
13*b1cdbd2cSJim Jagielski  * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski  * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski  * KIND, either express or implied.  See the License for the
17*b1cdbd2cSJim Jagielski  * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski  * under the License.
19*b1cdbd2cSJim Jagielski  *
20*b1cdbd2cSJim Jagielski  *************************************************************/
21*b1cdbd2cSJim Jagielski 
22*b1cdbd2cSJim Jagielski // MARKER(update_precomp.py): autogen include statement, do not remove
23*b1cdbd2cSJim Jagielski #include "precompiled_ucb.hxx"
24*b1cdbd2cSJim Jagielski 
25*b1cdbd2cSJim Jagielski #include <hash_map>
26*b1cdbd2cSJim Jagielski #include <vector>
27*b1cdbd2cSJim Jagielski #include <string.h>
28*b1cdbd2cSJim Jagielski #include <rtl/string.h>
29*b1cdbd2cSJim Jagielski #include <rtl/ustrbuf.hxx>
30*b1cdbd2cSJim Jagielski #include <osl/time.h>
31*b1cdbd2cSJim Jagielski #include "comphelper/sequence.hxx"
32*b1cdbd2cSJim Jagielski #include "ucbhelper/simplecertificatevalidationrequest.hxx"
33*b1cdbd2cSJim Jagielski 
34*b1cdbd2cSJim Jagielski #include "AprEnv.hxx"
35*b1cdbd2cSJim Jagielski #include <apr_strings.h>
36*b1cdbd2cSJim Jagielski 
37*b1cdbd2cSJim Jagielski #include "DAVAuthListener.hxx"
38*b1cdbd2cSJim Jagielski #include "SerfTypes.hxx"
39*b1cdbd2cSJim Jagielski #include "SerfSession.hxx"
40*b1cdbd2cSJim Jagielski #include "SerfUri.hxx"
41*b1cdbd2cSJim Jagielski #include "SerfRequestProcessor.hxx"
42*b1cdbd2cSJim Jagielski #include "SerfCallbacks.hxx"
43*b1cdbd2cSJim Jagielski #include "SerfInputStream.hxx"
44*b1cdbd2cSJim Jagielski #include "UCBDeadPropertyValue.hxx"
45*b1cdbd2cSJim Jagielski 
46*b1cdbd2cSJim Jagielski #include <com/sun/star/xml/crypto/XSecurityEnvironment.hpp>
47*b1cdbd2cSJim Jagielski #include <com/sun/star/security/XCertificate.hpp>
48*b1cdbd2cSJim Jagielski #include <com/sun/star/security/CertificateValidity.hpp>
49*b1cdbd2cSJim Jagielski #include <com/sun/star/security/CertificateContainerStatus.hpp>
50*b1cdbd2cSJim Jagielski #include <com/sun/star/security/CertificateContainer.hpp>
51*b1cdbd2cSJim Jagielski #include <com/sun/star/security/XCertificateContainer.hpp>
52*b1cdbd2cSJim Jagielski #include <com/sun/star/security/CertAltNameEntry.hpp>
53*b1cdbd2cSJim Jagielski #include <com/sun/star/security/XSanExtension.hpp>
54*b1cdbd2cSJim Jagielski #define OID_SUBJECT_ALTERNATIVE_NAME "2.5.29.17"
55*b1cdbd2cSJim Jagielski 
56*b1cdbd2cSJim Jagielski #include <com/sun/star/ucb/Lock.hpp>
57*b1cdbd2cSJim Jagielski #include <com/sun/star/xml/crypto/XSEInitializer.hpp>
58*b1cdbd2cSJim Jagielski 
59*b1cdbd2cSJim Jagielski using namespace com::sun::star;
60*b1cdbd2cSJim Jagielski using namespace http_dav_ucp;
61*b1cdbd2cSJim Jagielski 
62*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
63*b1cdbd2cSJim Jagielski // static members!
64*b1cdbd2cSJim Jagielski SerfLockStore SerfSession::m_aSerfLockStore;
65*b1cdbd2cSJim Jagielski 
66*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
67*b1cdbd2cSJim Jagielski // Constructor
68*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
SerfSession(const rtl::Reference<DAVSessionFactory> & rSessionFactory,const rtl::OUString & inUri,const ucbhelper::InternetProxyDecider & rProxyDecider)69*b1cdbd2cSJim Jagielski SerfSession::SerfSession(
70*b1cdbd2cSJim Jagielski         const rtl::Reference< DAVSessionFactory > & rSessionFactory,
71*b1cdbd2cSJim Jagielski         const rtl::OUString& inUri,
72*b1cdbd2cSJim Jagielski         const ucbhelper::InternetProxyDecider & rProxyDecider )
73*b1cdbd2cSJim Jagielski     throw ( DAVException )
74*b1cdbd2cSJim Jagielski     : DAVSession( rSessionFactory )
75*b1cdbd2cSJim Jagielski     , m_aMutex()
76*b1cdbd2cSJim Jagielski     , m_aUri( inUri )
77*b1cdbd2cSJim Jagielski     , m_aProxyName()
78*b1cdbd2cSJim Jagielski     , m_nProxyPort( 0 )
79*b1cdbd2cSJim Jagielski     , m_aServerHeaderField()
80*b1cdbd2cSJim Jagielski     , m_pSerfConnection( 0 )
81*b1cdbd2cSJim Jagielski     , m_pSerfContext( 0 )
82*b1cdbd2cSJim Jagielski     , m_bIsHeadRequestInProgress( false )
83*b1cdbd2cSJim Jagielski     , m_bUseChunkedEncoding( false )
84*b1cdbd2cSJim Jagielski     , m_bNoOfTransferEncodingSwitches( 0 )
85*b1cdbd2cSJim Jagielski     , m_rProxyDecider( rProxyDecider )
86*b1cdbd2cSJim Jagielski     , m_aEnv()
87*b1cdbd2cSJim Jagielski {
88*b1cdbd2cSJim Jagielski     m_pSerfContext = serf_context_create( getAprPool() );
89*b1cdbd2cSJim Jagielski 
90*b1cdbd2cSJim Jagielski     m_pSerfBucket_Alloc = serf_bucket_allocator_create( getAprPool(), NULL, NULL );
91*b1cdbd2cSJim Jagielski }
92*b1cdbd2cSJim Jagielski 
93*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
94*b1cdbd2cSJim Jagielski // Destructor
95*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
~SerfSession()96*b1cdbd2cSJim Jagielski SerfSession::~SerfSession( )
97*b1cdbd2cSJim Jagielski {
98*b1cdbd2cSJim Jagielski     if ( m_pSerfConnection )
99*b1cdbd2cSJim Jagielski     {
100*b1cdbd2cSJim Jagielski         serf_connection_close( m_pSerfConnection );
101*b1cdbd2cSJim Jagielski         m_pSerfConnection = 0;
102*b1cdbd2cSJim Jagielski         OSL_TRACE("SerfSession::~SerfSession: closed serf connection");
103*b1cdbd2cSJim Jagielski     }
104*b1cdbd2cSJim Jagielski }
105*b1cdbd2cSJim Jagielski 
106*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
Init(const DAVRequestEnvironment & rEnv)107*b1cdbd2cSJim Jagielski void SerfSession::Init( const DAVRequestEnvironment & rEnv )
108*b1cdbd2cSJim Jagielski   throw ( DAVException )
109*b1cdbd2cSJim Jagielski {
110*b1cdbd2cSJim Jagielski     osl::Guard< osl::Mutex > theGuard( m_aMutex );
111*b1cdbd2cSJim Jagielski     m_aEnv = rEnv;
112*b1cdbd2cSJim Jagielski     Init();
113*b1cdbd2cSJim Jagielski }
114*b1cdbd2cSJim Jagielski 
115*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
Init()116*b1cdbd2cSJim Jagielski void SerfSession::Init()
117*b1cdbd2cSJim Jagielski     throw ( DAVException )
118*b1cdbd2cSJim Jagielski {
119*b1cdbd2cSJim Jagielski     osl::Guard< osl::Mutex > theGuard( m_aMutex );
120*b1cdbd2cSJim Jagielski 
121*b1cdbd2cSJim Jagielski     bool bCreateNewSession = false;
122*b1cdbd2cSJim Jagielski 
123*b1cdbd2cSJim Jagielski     if ( m_pSerfConnection == 0 )
124*b1cdbd2cSJim Jagielski     {
125*b1cdbd2cSJim Jagielski         const ucbhelper::InternetProxyServer & rProxyCfg = getProxySettings();
126*b1cdbd2cSJim Jagielski 
127*b1cdbd2cSJim Jagielski         m_aProxyName = rProxyCfg.aName;
128*b1cdbd2cSJim Jagielski         m_nProxyPort = rProxyCfg.nPort;
129*b1cdbd2cSJim Jagielski 
130*b1cdbd2cSJim Jagielski         // Not yet initialized. Create new session.
131*b1cdbd2cSJim Jagielski         bCreateNewSession = true;
132*b1cdbd2cSJim Jagielski         OSL_TRACE("SerfSession::Init: serf connection created");
133*b1cdbd2cSJim Jagielski     }
134*b1cdbd2cSJim Jagielski     else
135*b1cdbd2cSJim Jagielski     {
136*b1cdbd2cSJim Jagielski         const ucbhelper::InternetProxyServer & rProxyCfg = getProxySettings();
137*b1cdbd2cSJim Jagielski 
138*b1cdbd2cSJim Jagielski         if ( ( rProxyCfg.aName != m_aProxyName )
139*b1cdbd2cSJim Jagielski              || ( rProxyCfg.nPort != m_nProxyPort ) )
140*b1cdbd2cSJim Jagielski         {
141*b1cdbd2cSJim Jagielski             m_aProxyName = rProxyCfg.aName;
142*b1cdbd2cSJim Jagielski             m_nProxyPort = rProxyCfg.nPort;
143*b1cdbd2cSJim Jagielski 
144*b1cdbd2cSJim Jagielski             // new session needed, destroy old first
145*b1cdbd2cSJim Jagielski             serf_connection_close( m_pSerfConnection );
146*b1cdbd2cSJim Jagielski             m_pSerfConnection = 0;
147*b1cdbd2cSJim Jagielski             bCreateNewSession = true;
148*b1cdbd2cSJim Jagielski         }
149*b1cdbd2cSJim Jagielski     }
150*b1cdbd2cSJim Jagielski 
151*b1cdbd2cSJim Jagielski     if ( bCreateNewSession )
152*b1cdbd2cSJim Jagielski     {
153*b1cdbd2cSJim Jagielski         // TODO - close_connection callback
154*b1cdbd2cSJim Jagielski         apr_status_t status = serf_connection_create2( &m_pSerfConnection,
155*b1cdbd2cSJim Jagielski                                                        m_pSerfContext,
156*b1cdbd2cSJim Jagielski                                                        *(m_aUri.getAprUri()),
157*b1cdbd2cSJim Jagielski                                                        Serf_ConnectSetup, this,
158*b1cdbd2cSJim Jagielski                                                        0 /* close connection callback */, 0 /* close connection baton */,
159*b1cdbd2cSJim Jagielski                                                        getAprPool() );
160*b1cdbd2cSJim Jagielski 
161*b1cdbd2cSJim Jagielski         if ( m_pSerfConnection == 0 ||status != APR_SUCCESS )
162*b1cdbd2cSJim Jagielski         {
163*b1cdbd2cSJim Jagielski             throw DAVException( DAVException::DAV_SESSION_CREATE,
164*b1cdbd2cSJim Jagielski                                 SerfUri::makeConnectionEndPointString( m_aUri.GetHost(), m_aUri.GetPort() ) );
165*b1cdbd2cSJim Jagielski         }
166*b1cdbd2cSJim Jagielski 
167*b1cdbd2cSJim Jagielski         // Register the session with the lock store
168*b1cdbd2cSJim Jagielski //        m_aSerfLockStore.registerSession( m_pSerfConnection );
169*b1cdbd2cSJim Jagielski 
170*b1cdbd2cSJim Jagielski         if ( m_aProxyName.getLength() )
171*b1cdbd2cSJim Jagielski         {
172*b1cdbd2cSJim Jagielski             apr_sockaddr_t *proxy_address = NULL;
173*b1cdbd2cSJim Jagielski             status = apr_sockaddr_info_get( &proxy_address,
174*b1cdbd2cSJim Jagielski                                                                rtl::OUStringToOString( m_aProxyName, RTL_TEXTENCODING_UTF8 ).getStr(),
175*b1cdbd2cSJim Jagielski                                                                APR_UNSPEC,
176*b1cdbd2cSJim Jagielski                                                                static_cast<apr_port_t>(m_nProxyPort),
177*b1cdbd2cSJim Jagielski                                                                0, getAprPool() );
178*b1cdbd2cSJim Jagielski 
179*b1cdbd2cSJim Jagielski             if ( status != APR_SUCCESS )
180*b1cdbd2cSJim Jagielski             {
181*b1cdbd2cSJim Jagielski                 throw DAVException( DAVException::DAV_SESSION_CREATE,
182*b1cdbd2cSJim Jagielski                                     SerfUri::makeConnectionEndPointString( m_aUri.GetHost(), m_aUri.GetPort() ) );
183*b1cdbd2cSJim Jagielski             }
184*b1cdbd2cSJim Jagielski 
185*b1cdbd2cSJim Jagielski             serf_config_proxy( m_pSerfContext, proxy_address );
186*b1cdbd2cSJim Jagielski         }
187*b1cdbd2cSJim Jagielski 
188*b1cdbd2cSJim Jagielski 
189*b1cdbd2cSJim Jagielski         serf_config_credentials_callback( m_pSerfContext, Serf_Credentials );
190*b1cdbd2cSJim Jagielski 
191*b1cdbd2cSJim Jagielski         m_bUseChunkedEncoding = isSSLNeeded();
192*b1cdbd2cSJim Jagielski     }
193*b1cdbd2cSJim Jagielski }
194*b1cdbd2cSJim Jagielski 
getAprPool()195*b1cdbd2cSJim Jagielski apr_pool_t* SerfSession::getAprPool()
196*b1cdbd2cSJim Jagielski {
197*b1cdbd2cSJim Jagielski     return apr_environment::AprEnv::getAprEnv()->getAprPool();
198*b1cdbd2cSJim Jagielski }
199*b1cdbd2cSJim Jagielski 
getSerfBktAlloc()200*b1cdbd2cSJim Jagielski serf_bucket_alloc_t* SerfSession::getSerfBktAlloc()
201*b1cdbd2cSJim Jagielski {
202*b1cdbd2cSJim Jagielski     return m_pSerfBucket_Alloc;
203*b1cdbd2cSJim Jagielski }
204*b1cdbd2cSJim Jagielski 
getSerfContext()205*b1cdbd2cSJim Jagielski serf_context_t* SerfSession::getSerfContext()
206*b1cdbd2cSJim Jagielski {
207*b1cdbd2cSJim Jagielski     return m_pSerfContext;
208*b1cdbd2cSJim Jagielski }
209*b1cdbd2cSJim Jagielski 
getSerfConnection()210*b1cdbd2cSJim Jagielski SerfConnection* SerfSession::getSerfConnection()
211*b1cdbd2cSJim Jagielski {
212*b1cdbd2cSJim Jagielski     return m_pSerfConnection;
213*b1cdbd2cSJim Jagielski }
214*b1cdbd2cSJim Jagielski 
isHeadRequestInProgress()215*b1cdbd2cSJim Jagielski bool SerfSession::isHeadRequestInProgress()
216*b1cdbd2cSJim Jagielski {
217*b1cdbd2cSJim Jagielski     return m_bIsHeadRequestInProgress;
218*b1cdbd2cSJim Jagielski }
219*b1cdbd2cSJim Jagielski 
isSSLNeeded()220*b1cdbd2cSJim Jagielski bool SerfSession::isSSLNeeded()
221*b1cdbd2cSJim Jagielski {
222*b1cdbd2cSJim Jagielski     return m_aUri.GetScheme().equalsIgnoreAsciiCase( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "https" ) ) );
223*b1cdbd2cSJim Jagielski }
224*b1cdbd2cSJim Jagielski 
getHostinfo()225*b1cdbd2cSJim Jagielski char* SerfSession::getHostinfo()
226*b1cdbd2cSJim Jagielski {
227*b1cdbd2cSJim Jagielski     return m_aUri.getAprUri()->hostinfo;
228*b1cdbd2cSJim Jagielski }
229*b1cdbd2cSJim Jagielski 
230*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
231*b1cdbd2cSJim Jagielski // helper function
232*b1cdbd2cSJim Jagielski // it composes the uri for lockstore registration
composeCurrentUri(const rtl::OUString & inPath)233*b1cdbd2cSJim Jagielski rtl::OUString SerfSession::composeCurrentUri(const rtl::OUString & inPath)
234*b1cdbd2cSJim Jagielski {
235*b1cdbd2cSJim Jagielski     rtl::OUString aScheme( m_aUri.GetScheme() );
236*b1cdbd2cSJim Jagielski     rtl::OUStringBuffer aBuf( aScheme );
237*b1cdbd2cSJim Jagielski     aBuf.appendAscii( "://" );
238*b1cdbd2cSJim Jagielski     if ( m_aUri.GetUserInfo().getLength() > 0 )
239*b1cdbd2cSJim Jagielski     {
240*b1cdbd2cSJim Jagielski         aBuf.append( m_aUri.GetUserInfo() );
241*b1cdbd2cSJim Jagielski         aBuf.appendAscii( "@" );
242*b1cdbd2cSJim Jagielski     }
243*b1cdbd2cSJim Jagielski     // Is host a numeric IPv6 address?
244*b1cdbd2cSJim Jagielski     if ( ( m_aUri.GetHost().indexOf( ':' ) != -1 ) &&
245*b1cdbd2cSJim Jagielski          ( m_aUri.GetHost()[ 0 ] != sal_Unicode( '[' ) ) )
246*b1cdbd2cSJim Jagielski     {
247*b1cdbd2cSJim Jagielski         aBuf.appendAscii( "[" );
248*b1cdbd2cSJim Jagielski         aBuf.append( m_aUri.GetHost() );
249*b1cdbd2cSJim Jagielski         aBuf.appendAscii( "]" );
250*b1cdbd2cSJim Jagielski     }
251*b1cdbd2cSJim Jagielski     else
252*b1cdbd2cSJim Jagielski     {
253*b1cdbd2cSJim Jagielski         aBuf.append( m_aUri.GetHost() );
254*b1cdbd2cSJim Jagielski     }
255*b1cdbd2cSJim Jagielski 
256*b1cdbd2cSJim Jagielski     // append port, but only, if not default port.
257*b1cdbd2cSJim Jagielski     bool bAppendPort = true;
258*b1cdbd2cSJim Jagielski     sal_Int32 aPort = m_aUri.GetPort();
259*b1cdbd2cSJim Jagielski     switch ( aPort )
260*b1cdbd2cSJim Jagielski     {
261*b1cdbd2cSJim Jagielski     case DEFAULT_HTTP_PORT:
262*b1cdbd2cSJim Jagielski         bAppendPort = aScheme.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "http" ) );
263*b1cdbd2cSJim Jagielski         break;
264*b1cdbd2cSJim Jagielski 
265*b1cdbd2cSJim Jagielski     case DEFAULT_HTTPS_PORT:
266*b1cdbd2cSJim Jagielski         bAppendPort = !aScheme.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "https" ) );
267*b1cdbd2cSJim Jagielski         break;
268*b1cdbd2cSJim Jagielski     }
269*b1cdbd2cSJim Jagielski     if ( bAppendPort )
270*b1cdbd2cSJim Jagielski     {
271*b1cdbd2cSJim Jagielski         aBuf.appendAscii( ":" );
272*b1cdbd2cSJim Jagielski         aBuf.append( rtl::OUString::valueOf( aPort ) );
273*b1cdbd2cSJim Jagielski     }
274*b1cdbd2cSJim Jagielski     aBuf.append( inPath );
275*b1cdbd2cSJim Jagielski 
276*b1cdbd2cSJim Jagielski     rtl::OUString   aUri(aBuf.makeStringAndClear() );
277*b1cdbd2cSJim Jagielski     return aUri;
278*b1cdbd2cSJim Jagielski }
279*b1cdbd2cSJim Jagielski 
280*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
281*b1cdbd2cSJim Jagielski // virtual
CanUse(const rtl::OUString & inUri)282*b1cdbd2cSJim Jagielski sal_Bool SerfSession::CanUse( const rtl::OUString & inUri )
283*b1cdbd2cSJim Jagielski {
284*b1cdbd2cSJim Jagielski     try
285*b1cdbd2cSJim Jagielski     {
286*b1cdbd2cSJim Jagielski         SerfUri theUri( inUri );
287*b1cdbd2cSJim Jagielski         if ( ( theUri.GetPort() == m_aUri.GetPort() ) &&
288*b1cdbd2cSJim Jagielski              ( theUri.GetHost() == m_aUri.GetHost() ) &&
289*b1cdbd2cSJim Jagielski              ( theUri.GetScheme() == m_aUri.GetScheme() ) )
290*b1cdbd2cSJim Jagielski         {
291*b1cdbd2cSJim Jagielski             return sal_True;
292*b1cdbd2cSJim Jagielski         }
293*b1cdbd2cSJim Jagielski     }
294*b1cdbd2cSJim Jagielski     catch ( DAVException const & )
295*b1cdbd2cSJim Jagielski     {
296*b1cdbd2cSJim Jagielski         return sal_False;
297*b1cdbd2cSJim Jagielski     }
298*b1cdbd2cSJim Jagielski     return sal_False;
299*b1cdbd2cSJim Jagielski }
300*b1cdbd2cSJim Jagielski 
301*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
302*b1cdbd2cSJim Jagielski // virtual
UsesProxy()303*b1cdbd2cSJim Jagielski sal_Bool SerfSession::UsesProxy()
304*b1cdbd2cSJim Jagielski {
305*b1cdbd2cSJim Jagielski     Init();
306*b1cdbd2cSJim Jagielski     return ( m_aProxyName.getLength() > 0 );
307*b1cdbd2cSJim Jagielski }
308*b1cdbd2cSJim Jagielski 
setupSerfConnection(apr_socket_t * inAprSocket,serf_bucket_t ** outSerfInputBucket,serf_bucket_t ** outSerfOutputBucket,apr_pool_t *)309*b1cdbd2cSJim Jagielski apr_status_t SerfSession::setupSerfConnection( apr_socket_t * inAprSocket,
310*b1cdbd2cSJim Jagielski                                                serf_bucket_t **outSerfInputBucket,
311*b1cdbd2cSJim Jagielski                                                serf_bucket_t **outSerfOutputBucket,
312*b1cdbd2cSJim Jagielski                                                apr_pool_t* /*inAprPool*/ )
313*b1cdbd2cSJim Jagielski {
314*b1cdbd2cSJim Jagielski     serf_bucket_t *tmpInputBkt;
315*b1cdbd2cSJim Jagielski     tmpInputBkt = serf_context_bucket_socket_create( getSerfContext(),
316*b1cdbd2cSJim Jagielski                                                      inAprSocket,
317*b1cdbd2cSJim Jagielski                                                      getSerfBktAlloc() );
318*b1cdbd2cSJim Jagielski 
319*b1cdbd2cSJim Jagielski     if ( isSSLNeeded() )
320*b1cdbd2cSJim Jagielski     {
321*b1cdbd2cSJim Jagielski         tmpInputBkt = serf_bucket_ssl_decrypt_create( tmpInputBkt,
322*b1cdbd2cSJim Jagielski                                                       0,
323*b1cdbd2cSJim Jagielski                                                       getSerfBktAlloc() );
324*b1cdbd2cSJim Jagielski         /** Set the callback that is called to authenticate the
325*b1cdbd2cSJim Jagielski             certifcate (chain).
326*b1cdbd2cSJim Jagielski         */
327*b1cdbd2cSJim Jagielski         serf_ssl_server_cert_chain_callback_set(
328*b1cdbd2cSJim Jagielski             serf_bucket_ssl_decrypt_context_get(tmpInputBkt),
329*b1cdbd2cSJim Jagielski             NULL,
330*b1cdbd2cSJim Jagielski             Serf_CertificateChainValidation,
331*b1cdbd2cSJim Jagielski             this);
332*b1cdbd2cSJim Jagielski         serf_ssl_set_hostname( serf_bucket_ssl_decrypt_context_get( tmpInputBkt ),
333*b1cdbd2cSJim Jagielski                                getHostinfo() );
334*b1cdbd2cSJim Jagielski 
335*b1cdbd2cSJim Jagielski         *outSerfOutputBucket = serf_bucket_ssl_encrypt_create( *outSerfOutputBucket,
336*b1cdbd2cSJim Jagielski                                                                serf_bucket_ssl_decrypt_context_get( tmpInputBkt ),
337*b1cdbd2cSJim Jagielski                                                                getSerfBktAlloc() );
338*b1cdbd2cSJim Jagielski     }
339*b1cdbd2cSJim Jagielski 
340*b1cdbd2cSJim Jagielski     *outSerfInputBucket = tmpInputBkt;
341*b1cdbd2cSJim Jagielski 
342*b1cdbd2cSJim Jagielski     return APR_SUCCESS;
343*b1cdbd2cSJim Jagielski }
344*b1cdbd2cSJim Jagielski 
provideSerfCredentials(bool bGiveProvidedCredentialsASecondTry,char ** outUsername,char ** outPassword,serf_request_t *,int,const char * inAuthProtocol,const char * inRealm,apr_pool_t * inAprPool)345*b1cdbd2cSJim Jagielski apr_status_t SerfSession::provideSerfCredentials( bool bGiveProvidedCredentialsASecondTry,
346*b1cdbd2cSJim Jagielski                                                   char ** outUsername,
347*b1cdbd2cSJim Jagielski                                                   char ** outPassword,
348*b1cdbd2cSJim Jagielski                                                   serf_request_t * /*inRequest*/,
349*b1cdbd2cSJim Jagielski                                                   int /*inCode*/,
350*b1cdbd2cSJim Jagielski                                                   const char *inAuthProtocol,
351*b1cdbd2cSJim Jagielski                                                   const char *inRealm,
352*b1cdbd2cSJim Jagielski                                                   apr_pool_t *inAprPool )
353*b1cdbd2cSJim Jagielski {
354*b1cdbd2cSJim Jagielski     DAVAuthListener * pListener = getRequestEnvironment().m_xAuthListener.get();
355*b1cdbd2cSJim Jagielski     if ( !pListener )
356*b1cdbd2cSJim Jagielski     {
357*b1cdbd2cSJim Jagielski         // abort
358*b1cdbd2cSJim Jagielski         return SERF_ERROR_AUTHN_FAILED;
359*b1cdbd2cSJim Jagielski     }
360*b1cdbd2cSJim Jagielski 
361*b1cdbd2cSJim Jagielski     rtl::OUString theUserName;
362*b1cdbd2cSJim Jagielski     rtl::OUString thePassWord;
363*b1cdbd2cSJim Jagielski     try
364*b1cdbd2cSJim Jagielski     {
365*b1cdbd2cSJim Jagielski         SerfUri uri( getRequestEnvironment().m_aRequestURI );
366*b1cdbd2cSJim Jagielski         rtl::OUString aUserInfo( uri.GetUserInfo() );
367*b1cdbd2cSJim Jagielski         if ( aUserInfo.getLength() )
368*b1cdbd2cSJim Jagielski         {
369*b1cdbd2cSJim Jagielski             sal_Int32 nPos = aUserInfo.indexOf( '@' );
370*b1cdbd2cSJim Jagielski             if ( nPos == -1 )
371*b1cdbd2cSJim Jagielski             {
372*b1cdbd2cSJim Jagielski                 theUserName = aUserInfo;
373*b1cdbd2cSJim Jagielski             }
374*b1cdbd2cSJim Jagielski             else
375*b1cdbd2cSJim Jagielski             {
376*b1cdbd2cSJim Jagielski                 theUserName = aUserInfo.copy( 0, nPos );
377*b1cdbd2cSJim Jagielski                 thePassWord = aUserInfo.copy( nPos + 1 );
378*b1cdbd2cSJim Jagielski             }
379*b1cdbd2cSJim Jagielski         }
380*b1cdbd2cSJim Jagielski     }
381*b1cdbd2cSJim Jagielski     catch ( DAVException const & )
382*b1cdbd2cSJim Jagielski     {
383*b1cdbd2cSJim Jagielski         // abort
384*b1cdbd2cSJim Jagielski         return SERF_ERROR_AUTHN_FAILED;
385*b1cdbd2cSJim Jagielski     }
386*b1cdbd2cSJim Jagielski 
387*b1cdbd2cSJim Jagielski     const bool bCanUseSystemCreds = ( ( strcasecmp( inAuthProtocol, "NTLM" ) == 0 ) ||
388*b1cdbd2cSJim Jagielski                                       ( strcasecmp( inAuthProtocol, "Negotiate" ) == 0 ) );
389*b1cdbd2cSJim Jagielski 
390*b1cdbd2cSJim Jagielski     int theRetVal = pListener->authenticate( rtl::OUString::createFromAscii( inRealm ),
391*b1cdbd2cSJim Jagielski                                              getHostName(),
392*b1cdbd2cSJim Jagielski                                              theUserName,
393*b1cdbd2cSJim Jagielski                                              thePassWord,
394*b1cdbd2cSJim Jagielski                                              bCanUseSystemCreds,
395*b1cdbd2cSJim Jagielski                                              bGiveProvidedCredentialsASecondTry ? sal_False : sal_True );
396*b1cdbd2cSJim Jagielski 
397*b1cdbd2cSJim Jagielski     if ( theRetVal == 0 )
398*b1cdbd2cSJim Jagielski     {
399*b1cdbd2cSJim Jagielski         *outUsername = apr_pstrdup( inAprPool, rtl::OUStringToOString( theUserName, RTL_TEXTENCODING_UTF8 ).getStr() );
400*b1cdbd2cSJim Jagielski         *outPassword = apr_pstrdup( inAprPool, rtl::OUStringToOString( thePassWord, RTL_TEXTENCODING_UTF8 ).getStr() );
401*b1cdbd2cSJim Jagielski     }
402*b1cdbd2cSJim Jagielski 
403*b1cdbd2cSJim Jagielski     return theRetVal != 0 ? SERF_ERROR_AUTHN_FAILED : APR_SUCCESS;
404*b1cdbd2cSJim Jagielski }
405*b1cdbd2cSJim Jagielski 
406*b1cdbd2cSJim Jagielski namespace {
407*b1cdbd2cSJim Jagielski     // -------------------------------------------------------------------
408*b1cdbd2cSJim Jagielski     // Helper function
GetHostnamePart(const::rtl::OUString & _rRawString)409*b1cdbd2cSJim Jagielski     ::rtl::OUString GetHostnamePart( const ::rtl::OUString& _rRawString )
410*b1cdbd2cSJim Jagielski     {
411*b1cdbd2cSJim Jagielski         ::rtl::OUString sPart;
412*b1cdbd2cSJim Jagielski         ::rtl::OUString sPartId = ::rtl::OUString::createFromAscii( "CN=" );
413*b1cdbd2cSJim Jagielski         sal_Int32 nContStart = _rRawString.indexOf( sPartId );
414*b1cdbd2cSJim Jagielski         if ( nContStart != -1 )
415*b1cdbd2cSJim Jagielski         {
416*b1cdbd2cSJim Jagielski             nContStart = nContStart + sPartId.getLength();
417*b1cdbd2cSJim Jagielski             sal_Int32 nContEnd
418*b1cdbd2cSJim Jagielski                 = _rRawString.indexOf( sal_Unicode( ',' ), nContStart );
419*b1cdbd2cSJim Jagielski             sPart = _rRawString.copy( nContStart, nContEnd - nContStart );
420*b1cdbd2cSJim Jagielski         }
421*b1cdbd2cSJim Jagielski         return sPart;
422*b1cdbd2cSJim Jagielski     }
423*b1cdbd2cSJim Jagielski } // namespace
424*b1cdbd2cSJim Jagielski 
425*b1cdbd2cSJim Jagielski 
verifySerfCertificateChain(int,const serf_ssl_certificate_t * const * pCertificateChainBase64Encoded,int nCertificateChainLength)426*b1cdbd2cSJim Jagielski apr_status_t SerfSession::verifySerfCertificateChain (
427*b1cdbd2cSJim Jagielski     int,
428*b1cdbd2cSJim Jagielski     const serf_ssl_certificate_t * const * pCertificateChainBase64Encoded,
429*b1cdbd2cSJim Jagielski     int nCertificateChainLength)
430*b1cdbd2cSJim Jagielski {
431*b1cdbd2cSJim Jagielski     // Check arguments.
432*b1cdbd2cSJim Jagielski     if (pCertificateChainBase64Encoded == NULL || nCertificateChainLength<=0)
433*b1cdbd2cSJim Jagielski     {
434*b1cdbd2cSJim Jagielski         OSL_ASSERT(pCertificateChainBase64Encoded != NULL);
435*b1cdbd2cSJim Jagielski         OSL_ASSERT(nCertificateChainLength>0);
436*b1cdbd2cSJim Jagielski         return SERF_SSL_CERT_UNKNOWN_FAILURE;
437*b1cdbd2cSJim Jagielski     }
438*b1cdbd2cSJim Jagielski 
439*b1cdbd2cSJim Jagielski     // Create some crypto objects to decode and handle the base64
440*b1cdbd2cSJim Jagielski     // encoded certificate chain.
441*b1cdbd2cSJim Jagielski     uno::Reference< xml::crypto::XSEInitializer > xSEInitializer;
442*b1cdbd2cSJim Jagielski     uno::Reference< security::XCertificateContainer > xCertificateContainer;
443*b1cdbd2cSJim Jagielski     uno::Reference< xml::crypto::XXMLSecurityContext > xSecurityContext;
444*b1cdbd2cSJim Jagielski     uno::Reference< xml::crypto::XSecurityEnvironment > xSecurityEnv;
445*b1cdbd2cSJim Jagielski     try
446*b1cdbd2cSJim Jagielski     {
447*b1cdbd2cSJim Jagielski         // Create a certificate container.
448*b1cdbd2cSJim Jagielski         xCertificateContainer = uno::Reference< security::XCertificateContainer >(
449*b1cdbd2cSJim Jagielski             getMSF()->createInstance(
450*b1cdbd2cSJim Jagielski                 rtl::OUString::createFromAscii(
451*b1cdbd2cSJim Jagielski                     "com.sun.star.security.CertificateContainer" ) ),
452*b1cdbd2cSJim Jagielski             uno::UNO_QUERY_THROW);
453*b1cdbd2cSJim Jagielski 
454*b1cdbd2cSJim Jagielski         xSEInitializer = uno::Reference< xml::crypto::XSEInitializer >(
455*b1cdbd2cSJim Jagielski             getMSF()->createInstance(
456*b1cdbd2cSJim Jagielski                 rtl::OUString::createFromAscii( "com.sun.star.xml.crypto.SEInitializer" ) ),
457*b1cdbd2cSJim Jagielski             uno::UNO_QUERY_THROW);
458*b1cdbd2cSJim Jagielski 
459*b1cdbd2cSJim Jagielski         xSecurityContext = xSEInitializer->createSecurityContext( rtl::OUString() );
460*b1cdbd2cSJim Jagielski         if (xSecurityContext.is())
461*b1cdbd2cSJim Jagielski             xSecurityEnv = xSecurityContext->getSecurityEnvironment();
462*b1cdbd2cSJim Jagielski 
463*b1cdbd2cSJim Jagielski         if ( ! xSecurityContext.is() || ! xSecurityEnv.is())
464*b1cdbd2cSJim Jagielski         {
465*b1cdbd2cSJim Jagielski             // Do we have to dispose xSEInitializer or xCertificateContainer?
466*b1cdbd2cSJim Jagielski             return SERF_SSL_CERT_UNKNOWN_FAILURE;
467*b1cdbd2cSJim Jagielski         }
468*b1cdbd2cSJim Jagielski     }
469*b1cdbd2cSJim Jagielski     catch ( uno::Exception const &)
470*b1cdbd2cSJim Jagielski     {
471*b1cdbd2cSJim Jagielski         return SERF_SSL_CERT_UNKNOWN_FAILURE;
472*b1cdbd2cSJim Jagielski     }
473*b1cdbd2cSJim Jagielski 
474*b1cdbd2cSJim Jagielski     // Decode the server certificate.
475*b1cdbd2cSJim Jagielski     const char* sBase64EncodedServerCertificate (
476*b1cdbd2cSJim Jagielski         serf_ssl_cert_export(
477*b1cdbd2cSJim Jagielski             pCertificateChainBase64Encoded[0],
478*b1cdbd2cSJim Jagielski             getAprPool()));
479*b1cdbd2cSJim Jagielski     uno::Reference< security::XCertificate > xServerCertificate(
480*b1cdbd2cSJim Jagielski         xSecurityEnv->createCertificateFromAscii(
481*b1cdbd2cSJim Jagielski             rtl::OUString::createFromAscii(sBase64EncodedServerCertificate)));
482*b1cdbd2cSJim Jagielski     if ( ! xServerCertificate.is())
483*b1cdbd2cSJim Jagielski         return SERF_SSL_CERT_UNKNOWN_FAILURE;
484*b1cdbd2cSJim Jagielski 
485*b1cdbd2cSJim Jagielski     // Get the subject from the server certificate.
486*b1cdbd2cSJim Jagielski     ::rtl::OUString sServerCertificateSubject (xServerCertificate->getSubjectName());
487*b1cdbd2cSJim Jagielski     sal_Int32 nIndex = 0;
488*b1cdbd2cSJim Jagielski     while (nIndex >= 0)
489*b1cdbd2cSJim Jagielski     {
490*b1cdbd2cSJim Jagielski         const ::rtl::OUString sToken (sServerCertificateSubject.getToken(0, ',', nIndex));
491*b1cdbd2cSJim Jagielski         if (sToken.compareToAscii("CN=", 3) == 0)
492*b1cdbd2cSJim Jagielski         {
493*b1cdbd2cSJim Jagielski             sServerCertificateSubject = sToken.copy(3);
494*b1cdbd2cSJim Jagielski             break;
495*b1cdbd2cSJim Jagielski         }
496*b1cdbd2cSJim Jagielski         else if (sToken.compareToAscii(" CN=", 4) == 0)
497*b1cdbd2cSJim Jagielski         {
498*b1cdbd2cSJim Jagielski             sServerCertificateSubject = sToken.copy(4);
499*b1cdbd2cSJim Jagielski             break;
500*b1cdbd2cSJim Jagielski         }
501*b1cdbd2cSJim Jagielski     }
502*b1cdbd2cSJim Jagielski 
503*b1cdbd2cSJim Jagielski     // When the certificate container already contains a (trusted)
504*b1cdbd2cSJim Jagielski     // entry for the server then we do not have to authenticate any
505*b1cdbd2cSJim Jagielski     // certificate.
506*b1cdbd2cSJim Jagielski     const security::CertificateContainerStatus eStatus (
507*b1cdbd2cSJim Jagielski         xCertificateContainer->hasCertificate(
508*b1cdbd2cSJim Jagielski             getHostName(), sServerCertificateSubject ) );
509*b1cdbd2cSJim Jagielski     if (eStatus != security::CertificateContainerStatus_NOCERT)
510*b1cdbd2cSJim Jagielski     {
511*b1cdbd2cSJim Jagielski         return eStatus == security::CertificateContainerStatus_TRUSTED
512*b1cdbd2cSJim Jagielski                ? APR_SUCCESS
513*b1cdbd2cSJim Jagielski                : SERF_SSL_CERT_UNKNOWN_FAILURE;
514*b1cdbd2cSJim Jagielski     }
515*b1cdbd2cSJim Jagielski 
516*b1cdbd2cSJim Jagielski     // The shortcut failed, so try to verify the whole chain.  This is
517*b1cdbd2cSJim Jagielski     // done outside the isDomainMatch() block because the result is
518*b1cdbd2cSJim Jagielski     // used by the interaction handler.
519*b1cdbd2cSJim Jagielski     std::vector< uno::Reference< security::XCertificate > > aChain;
520*b1cdbd2cSJim Jagielski     for (nIndex=1; nIndex<nCertificateChainLength; ++nIndex)
521*b1cdbd2cSJim Jagielski     {
522*b1cdbd2cSJim Jagielski         const char* sBase64EncodedCertificate (
523*b1cdbd2cSJim Jagielski             serf_ssl_cert_export(
524*b1cdbd2cSJim Jagielski                 pCertificateChainBase64Encoded[nIndex],
525*b1cdbd2cSJim Jagielski                 getAprPool()));
526*b1cdbd2cSJim Jagielski         uno::Reference< security::XCertificate > xCertificate(
527*b1cdbd2cSJim Jagielski             xSecurityEnv->createCertificateFromAscii(
528*b1cdbd2cSJim Jagielski                 rtl::OUString::createFromAscii(sBase64EncodedCertificate)));
529*b1cdbd2cSJim Jagielski         if ( ! xCertificate.is())
530*b1cdbd2cSJim Jagielski             return SERF_SSL_CERT_UNKNOWN_FAILURE;
531*b1cdbd2cSJim Jagielski         aChain.push_back(xCertificate);
532*b1cdbd2cSJim Jagielski     }
533*b1cdbd2cSJim Jagielski     const sal_Int64 nVerificationResult (xSecurityEnv->verifyCertificate(
534*b1cdbd2cSJim Jagielski             xServerCertificate,
535*b1cdbd2cSJim Jagielski             ::comphelper::containerToSequence(aChain)));
536*b1cdbd2cSJim Jagielski 
537*b1cdbd2cSJim Jagielski     // When the certificate matches the host name then we can use the
538*b1cdbd2cSJim Jagielski     // result of the verification.
539*b1cdbd2cSJim Jagielski     bool bHostnameMatchesCertHostnames = false;
540*b1cdbd2cSJim Jagielski     {
541*b1cdbd2cSJim Jagielski         uno::Sequence< uno::Reference< security::XCertificateExtension > > extensions = xServerCertificate->getExtensions();
542*b1cdbd2cSJim Jagielski         uno::Sequence< security::CertAltNameEntry > altNames;
543*b1cdbd2cSJim Jagielski         for (sal_Int32 i = 0 ; i < extensions.getLength(); ++i)
544*b1cdbd2cSJim Jagielski         {
545*b1cdbd2cSJim Jagielski             uno::Reference< security::XCertificateExtension >element = extensions[i];
546*b1cdbd2cSJim Jagielski 
547*b1cdbd2cSJim Jagielski             const rtl::OString aId ( (const sal_Char *)element->getExtensionId().getArray(), element->getExtensionId().getLength());
548*b1cdbd2cSJim Jagielski             if ( aId.equals( OID_SUBJECT_ALTERNATIVE_NAME ) )
549*b1cdbd2cSJim Jagielski             {
550*b1cdbd2cSJim Jagielski                 uno::Reference< security::XSanExtension > sanExtension ( element, uno::UNO_QUERY );
551*b1cdbd2cSJim Jagielski                 altNames =  sanExtension->getAlternativeNames();
552*b1cdbd2cSJim Jagielski                 break;
553*b1cdbd2cSJim Jagielski             }
554*b1cdbd2cSJim Jagielski         }
555*b1cdbd2cSJim Jagielski 
556*b1cdbd2cSJim Jagielski         uno::Sequence< ::rtl::OUString > certHostNames(altNames.getLength() + 1);
557*b1cdbd2cSJim Jagielski         certHostNames[0] = sServerCertificateSubject;
558*b1cdbd2cSJim Jagielski         for( int n = 0; n < altNames.getLength(); ++n )
559*b1cdbd2cSJim Jagielski         {
560*b1cdbd2cSJim Jagielski             if (altNames[n].Type ==  security::ExtAltNameType_DNS_NAME)
561*b1cdbd2cSJim Jagielski             {
562*b1cdbd2cSJim Jagielski                 altNames[n].Value >>= certHostNames[n+1];
563*b1cdbd2cSJim Jagielski             }
564*b1cdbd2cSJim Jagielski         }
565*b1cdbd2cSJim Jagielski 
566*b1cdbd2cSJim Jagielski         for ( int i = 0; i < certHostNames.getLength() && !bHostnameMatchesCertHostnames; ++i )
567*b1cdbd2cSJim Jagielski         {
568*b1cdbd2cSJim Jagielski             bHostnameMatchesCertHostnames = isDomainMatch( certHostNames[i] );
569*b1cdbd2cSJim Jagielski         }
570*b1cdbd2cSJim Jagielski 
571*b1cdbd2cSJim Jagielski     }
572*b1cdbd2cSJim Jagielski     if ( bHostnameMatchesCertHostnames )
573*b1cdbd2cSJim Jagielski     {
574*b1cdbd2cSJim Jagielski 
575*b1cdbd2cSJim Jagielski         if (nVerificationResult == 0)
576*b1cdbd2cSJim Jagielski         {
577*b1cdbd2cSJim Jagielski             // Certificate (chain) is valid.
578*b1cdbd2cSJim Jagielski             xCertificateContainer->addCertificate(getHostName(), sServerCertificateSubject,  sal_True);
579*b1cdbd2cSJim Jagielski             return APR_SUCCESS;
580*b1cdbd2cSJim Jagielski         }
581*b1cdbd2cSJim Jagielski         else if ((nVerificationResult & security::CertificateValidity::CHAIN_INCOMPLETE) != 0)
582*b1cdbd2cSJim Jagielski         {
583*b1cdbd2cSJim Jagielski             // We do not have enough information for verification,
584*b1cdbd2cSJim Jagielski             // neither automatically (as we just discovered) nor
585*b1cdbd2cSJim Jagielski             // manually (so there is no point in showing any dialog.)
586*b1cdbd2cSJim Jagielski             return SERF_SSL_CERT_UNKNOWN_FAILURE;
587*b1cdbd2cSJim Jagielski         }
588*b1cdbd2cSJim Jagielski         else if ((nVerificationResult &
589*b1cdbd2cSJim Jagielski                 (security::CertificateValidity::INVALID | security::CertificateValidity::REVOKED)) != 0)
590*b1cdbd2cSJim Jagielski         {
591*b1cdbd2cSJim Jagielski             // Certificate (chain) is invalid.
592*b1cdbd2cSJim Jagielski             xCertificateContainer->addCertificate(getHostName(), sServerCertificateSubject,  sal_False);
593*b1cdbd2cSJim Jagielski             return SERF_SSL_CERT_UNKNOWN_FAILURE;
594*b1cdbd2cSJim Jagielski         }
595*b1cdbd2cSJim Jagielski         else
596*b1cdbd2cSJim Jagielski         {
597*b1cdbd2cSJim Jagielski             // For all other we have to ask the user.
598*b1cdbd2cSJim Jagielski         }
599*b1cdbd2cSJim Jagielski     }
600*b1cdbd2cSJim Jagielski 
601*b1cdbd2cSJim Jagielski     // We have not been able to automatically verify (or falsify) the
602*b1cdbd2cSJim Jagielski     // certificate chain.  To resolve this we have to ask the user.
603*b1cdbd2cSJim Jagielski     const uno::Reference< ucb::XCommandEnvironment > xEnv( getRequestEnvironment().m_xEnv );
604*b1cdbd2cSJim Jagielski     if ( xEnv.is() )
605*b1cdbd2cSJim Jagielski     {
606*b1cdbd2cSJim Jagielski         uno::Reference< task::XInteractionHandler > xIH( xEnv->getInteractionHandler() );
607*b1cdbd2cSJim Jagielski         if ( xIH.is() )
608*b1cdbd2cSJim Jagielski         {
609*b1cdbd2cSJim Jagielski             rtl::Reference< ucbhelper::SimpleCertificateValidationRequest >
610*b1cdbd2cSJim Jagielski                 xRequest( new ucbhelper::SimpleCertificateValidationRequest(
611*b1cdbd2cSJim Jagielski                         static_cast<sal_Int32>(nVerificationResult), xServerCertificate, getHostName() ) );
612*b1cdbd2cSJim Jagielski             xIH->handle( xRequest.get() );
613*b1cdbd2cSJim Jagielski 
614*b1cdbd2cSJim Jagielski             rtl::Reference< ucbhelper::InteractionContinuation > xSelection
615*b1cdbd2cSJim Jagielski                 = xRequest->getSelection();
616*b1cdbd2cSJim Jagielski 
617*b1cdbd2cSJim Jagielski             if ( xSelection.is() )
618*b1cdbd2cSJim Jagielski             {
619*b1cdbd2cSJim Jagielski                 uno::Reference< task::XInteractionApprove > xApprove( xSelection.get(), uno::UNO_QUERY );
620*b1cdbd2cSJim Jagielski                 if ( xApprove.is() )
621*b1cdbd2cSJim Jagielski                 {
622*b1cdbd2cSJim Jagielski                     xCertificateContainer->addCertificate( getHostName(), sServerCertificateSubject,  sal_True );
623*b1cdbd2cSJim Jagielski                     return APR_SUCCESS;
624*b1cdbd2cSJim Jagielski                 }
625*b1cdbd2cSJim Jagielski                 else
626*b1cdbd2cSJim Jagielski                 {
627*b1cdbd2cSJim Jagielski                     // Don't trust cert
628*b1cdbd2cSJim Jagielski                     xCertificateContainer->addCertificate( getHostName(), sServerCertificateSubject, sal_False );
629*b1cdbd2cSJim Jagielski                     return SERF_SSL_CERT_UNKNOWN_FAILURE;
630*b1cdbd2cSJim Jagielski                 }
631*b1cdbd2cSJim Jagielski             }
632*b1cdbd2cSJim Jagielski         }
633*b1cdbd2cSJim Jagielski         else
634*b1cdbd2cSJim Jagielski         {
635*b1cdbd2cSJim Jagielski             // Don't trust cert
636*b1cdbd2cSJim Jagielski             xCertificateContainer->addCertificate( getHostName(), sServerCertificateSubject, sal_False );
637*b1cdbd2cSJim Jagielski             return SERF_SSL_CERT_UNKNOWN_FAILURE;
638*b1cdbd2cSJim Jagielski         }
639*b1cdbd2cSJim Jagielski     }
640*b1cdbd2cSJim Jagielski 
641*b1cdbd2cSJim Jagielski     return SERF_SSL_CERT_UNKNOWN_FAILURE;
642*b1cdbd2cSJim Jagielski }
643*b1cdbd2cSJim Jagielski 
acceptSerfResponse(serf_request_t * inSerfRequest,serf_bucket_t * inSerfStreamBucket,apr_pool_t *)644*b1cdbd2cSJim Jagielski serf_bucket_t* SerfSession::acceptSerfResponse( serf_request_t * inSerfRequest,
645*b1cdbd2cSJim Jagielski                                                 serf_bucket_t * inSerfStreamBucket,
646*b1cdbd2cSJim Jagielski                                                 apr_pool_t* /*inAprPool*/ )
647*b1cdbd2cSJim Jagielski {
648*b1cdbd2cSJim Jagielski     // get the per-request bucket allocator
649*b1cdbd2cSJim Jagielski     serf_bucket_alloc_t* SerfBktAlloc = serf_request_get_alloc( inSerfRequest );
650*b1cdbd2cSJim Jagielski 
651*b1cdbd2cSJim Jagielski     // create a barrier bucket so the response doesn't eat us!
652*b1cdbd2cSJim Jagielski     serf_bucket_t *responseBkt = serf_bucket_barrier_create( inSerfStreamBucket,
653*b1cdbd2cSJim Jagielski                                                              SerfBktAlloc );
654*b1cdbd2cSJim Jagielski 
655*b1cdbd2cSJim Jagielski     // create response bucket
656*b1cdbd2cSJim Jagielski     responseBkt = serf_bucket_response_create( responseBkt,
657*b1cdbd2cSJim Jagielski                                                SerfBktAlloc );
658*b1cdbd2cSJim Jagielski 
659*b1cdbd2cSJim Jagielski     if ( isHeadRequestInProgress() )
660*b1cdbd2cSJim Jagielski     {
661*b1cdbd2cSJim Jagielski         // advise the response bucket that this was from a HEAD request and that it should not expect to see a response body.
662*b1cdbd2cSJim Jagielski         serf_bucket_response_set_head( responseBkt );
663*b1cdbd2cSJim Jagielski     }
664*b1cdbd2cSJim Jagielski 
665*b1cdbd2cSJim Jagielski     return responseBkt;
666*b1cdbd2cSJim Jagielski }
667*b1cdbd2cSJim Jagielski 
createReqProc(const rtl::OUString & inPath)668*b1cdbd2cSJim Jagielski SerfRequestProcessor* SerfSession::createReqProc( const rtl::OUString & inPath )
669*b1cdbd2cSJim Jagielski {
670*b1cdbd2cSJim Jagielski     return new SerfRequestProcessor( *this,
671*b1cdbd2cSJim Jagielski                                      inPath,
672*b1cdbd2cSJim Jagielski                                      m_bUseChunkedEncoding );
673*b1cdbd2cSJim Jagielski }
674*b1cdbd2cSJim Jagielski 
675*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
676*b1cdbd2cSJim Jagielski // PROPFIND - allprop & named
677*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
PROPFIND(const rtl::OUString & inPath,const Depth inDepth,const std::vector<rtl::OUString> & inPropNames,std::vector<DAVResource> & ioResources,const DAVRequestEnvironment & rEnv)678*b1cdbd2cSJim Jagielski void SerfSession::PROPFIND( const rtl::OUString & inPath,
679*b1cdbd2cSJim Jagielski                             const Depth inDepth,
680*b1cdbd2cSJim Jagielski                             const std::vector< rtl::OUString > & inPropNames,
681*b1cdbd2cSJim Jagielski                             std::vector< DAVResource > & ioResources,
682*b1cdbd2cSJim Jagielski                             const DAVRequestEnvironment & rEnv )
683*b1cdbd2cSJim Jagielski     throw ( DAVException )
684*b1cdbd2cSJim Jagielski {
685*b1cdbd2cSJim Jagielski     osl::Guard< osl::Mutex > theGuard( m_aMutex );
686*b1cdbd2cSJim Jagielski 
687*b1cdbd2cSJim Jagielski     Init( rEnv );
688*b1cdbd2cSJim Jagielski 
689*b1cdbd2cSJim Jagielski     apr_status_t status = APR_SUCCESS;
690*b1cdbd2cSJim Jagielski     boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) );
691*b1cdbd2cSJim Jagielski     aReqProc->processPropFind( inDepth,
692*b1cdbd2cSJim Jagielski                                inPropNames,
693*b1cdbd2cSJim Jagielski                                ioResources,
694*b1cdbd2cSJim Jagielski                                status );
695*b1cdbd2cSJim Jagielski 
696*b1cdbd2cSJim Jagielski     if ( status == APR_SUCCESS &&
697*b1cdbd2cSJim Jagielski          aReqProc->mpDAVException == 0 &&
698*b1cdbd2cSJim Jagielski          ioResources.empty() )
699*b1cdbd2cSJim Jagielski     {
700*b1cdbd2cSJim Jagielski         m_aEnv = DAVRequestEnvironment();
701*b1cdbd2cSJim Jagielski         throw DAVException( DAVException::DAV_HTTP_ERROR, inPath, (sal_uInt16)APR_EGENERAL );
702*b1cdbd2cSJim Jagielski     }
703*b1cdbd2cSJim Jagielski     HandleError( aReqProc );
704*b1cdbd2cSJim Jagielski }
705*b1cdbd2cSJim Jagielski 
706*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
707*b1cdbd2cSJim Jagielski // PROPFIND - propnames
708*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
PROPFIND(const rtl::OUString & inPath,const Depth inDepth,std::vector<DAVResourceInfo> & ioResInfo,const DAVRequestEnvironment & rEnv)709*b1cdbd2cSJim Jagielski void SerfSession::PROPFIND( const rtl::OUString & inPath,
710*b1cdbd2cSJim Jagielski                             const Depth inDepth,
711*b1cdbd2cSJim Jagielski                             std::vector< DAVResourceInfo > & ioResInfo,
712*b1cdbd2cSJim Jagielski                             const DAVRequestEnvironment & rEnv )
713*b1cdbd2cSJim Jagielski     throw( DAVException )
714*b1cdbd2cSJim Jagielski {
715*b1cdbd2cSJim Jagielski     osl::Guard< osl::Mutex > theGuard( m_aMutex );
716*b1cdbd2cSJim Jagielski 
717*b1cdbd2cSJim Jagielski     Init( rEnv );
718*b1cdbd2cSJim Jagielski 
719*b1cdbd2cSJim Jagielski     apr_status_t status = APR_SUCCESS;
720*b1cdbd2cSJim Jagielski     boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) );
721*b1cdbd2cSJim Jagielski     aReqProc->processPropFind( inDepth,
722*b1cdbd2cSJim Jagielski                                ioResInfo,
723*b1cdbd2cSJim Jagielski                                status );
724*b1cdbd2cSJim Jagielski 
725*b1cdbd2cSJim Jagielski     if ( status == APR_SUCCESS &&
726*b1cdbd2cSJim Jagielski          aReqProc->mpDAVException == 0 &&
727*b1cdbd2cSJim Jagielski          ioResInfo.empty() )
728*b1cdbd2cSJim Jagielski     {
729*b1cdbd2cSJim Jagielski         m_aEnv = DAVRequestEnvironment();
730*b1cdbd2cSJim Jagielski         throw DAVException( DAVException::DAV_HTTP_ERROR, inPath, (sal_uInt16)APR_EGENERAL );
731*b1cdbd2cSJim Jagielski     }
732*b1cdbd2cSJim Jagielski     HandleError( aReqProc );
733*b1cdbd2cSJim Jagielski }
734*b1cdbd2cSJim Jagielski 
735*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
736*b1cdbd2cSJim Jagielski // PROPPATCH
737*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
PROPPATCH(const rtl::OUString & inPath,const std::vector<ProppatchValue> & inValues,const DAVRequestEnvironment & rEnv)738*b1cdbd2cSJim Jagielski void SerfSession::PROPPATCH( const rtl::OUString & inPath,
739*b1cdbd2cSJim Jagielski                              const std::vector< ProppatchValue > & inValues,
740*b1cdbd2cSJim Jagielski                              const DAVRequestEnvironment & rEnv )
741*b1cdbd2cSJim Jagielski     throw( DAVException )
742*b1cdbd2cSJim Jagielski {
743*b1cdbd2cSJim Jagielski     osl::Guard< osl::Mutex > theGuard( m_aMutex );
744*b1cdbd2cSJim Jagielski 
745*b1cdbd2cSJim Jagielski     Init( rEnv );
746*b1cdbd2cSJim Jagielski 
747*b1cdbd2cSJim Jagielski     apr_status_t status = APR_SUCCESS;
748*b1cdbd2cSJim Jagielski     boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) );
749*b1cdbd2cSJim Jagielski     //check whether a lock on this resource is already owned
750*b1cdbd2cSJim Jagielski     rtl::OUString aUri( composeCurrentUri( inPath ) );
751*b1cdbd2cSJim Jagielski     ucb::Lock inLock;
752*b1cdbd2cSJim Jagielski     SerfLock * pLock = m_aSerfLockStore.findByUri( aUri );
753*b1cdbd2cSJim Jagielski     if ( pLock )
754*b1cdbd2cSJim Jagielski     {
755*b1cdbd2cSJim Jagielski         inLock = pLock->getLock();
756*b1cdbd2cSJim Jagielski     }
757*b1cdbd2cSJim Jagielski     aReqProc->processPropPatch( inValues,
758*b1cdbd2cSJim Jagielski                                 inLock,
759*b1cdbd2cSJim Jagielski                                 status );
760*b1cdbd2cSJim Jagielski 
761*b1cdbd2cSJim Jagielski     HandleError( aReqProc );
762*b1cdbd2cSJim Jagielski }
763*b1cdbd2cSJim Jagielski 
764*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
765*b1cdbd2cSJim Jagielski // HEAD
766*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
HEAD(const::rtl::OUString & inPath,const std::vector<::rtl::OUString> & inHeaderNames,DAVResource & ioResource,const DAVRequestEnvironment & rEnv)767*b1cdbd2cSJim Jagielski void SerfSession::HEAD( const ::rtl::OUString & inPath,
768*b1cdbd2cSJim Jagielski                         const std::vector< ::rtl::OUString > & inHeaderNames,
769*b1cdbd2cSJim Jagielski                         DAVResource & ioResource,
770*b1cdbd2cSJim Jagielski                         const DAVRequestEnvironment & rEnv )
771*b1cdbd2cSJim Jagielski     throw( DAVException )
772*b1cdbd2cSJim Jagielski {
773*b1cdbd2cSJim Jagielski     osl::Guard< osl::Mutex > theGuard( m_aMutex );
774*b1cdbd2cSJim Jagielski 
775*b1cdbd2cSJim Jagielski     Init( rEnv );
776*b1cdbd2cSJim Jagielski 
777*b1cdbd2cSJim Jagielski     m_bIsHeadRequestInProgress = true;
778*b1cdbd2cSJim Jagielski 
779*b1cdbd2cSJim Jagielski     boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) );
780*b1cdbd2cSJim Jagielski     ioResource.uri = inPath;
781*b1cdbd2cSJim Jagielski     ioResource.properties.clear();
782*b1cdbd2cSJim Jagielski     apr_status_t status = APR_SUCCESS;
783*b1cdbd2cSJim Jagielski     aReqProc->processHead( inHeaderNames,
784*b1cdbd2cSJim Jagielski                            ioResource,
785*b1cdbd2cSJim Jagielski                            status );
786*b1cdbd2cSJim Jagielski 
787*b1cdbd2cSJim Jagielski     m_bIsHeadRequestInProgress = false;
788*b1cdbd2cSJim Jagielski 
789*b1cdbd2cSJim Jagielski     HandleError( aReqProc );
790*b1cdbd2cSJim Jagielski }
791*b1cdbd2cSJim Jagielski 
792*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
793*b1cdbd2cSJim Jagielski // GET
794*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
795*b1cdbd2cSJim Jagielski uno::Reference< io::XInputStream >
GET(const rtl::OUString & inPath,const DAVRequestEnvironment & rEnv)796*b1cdbd2cSJim Jagielski SerfSession::GET( const rtl::OUString & inPath,
797*b1cdbd2cSJim Jagielski                   const DAVRequestEnvironment & rEnv )
798*b1cdbd2cSJim Jagielski     throw ( DAVException )
799*b1cdbd2cSJim Jagielski {
800*b1cdbd2cSJim Jagielski     osl::Guard< osl::Mutex > theGuard( m_aMutex );
801*b1cdbd2cSJim Jagielski 
802*b1cdbd2cSJim Jagielski     Init( rEnv );
803*b1cdbd2cSJim Jagielski 
804*b1cdbd2cSJim Jagielski     uno::Reference< SerfInputStream > xInputStream( new SerfInputStream );
805*b1cdbd2cSJim Jagielski     apr_status_t status = APR_SUCCESS;
806*b1cdbd2cSJim Jagielski     boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) );
807*b1cdbd2cSJim Jagielski     aReqProc->processGet( xInputStream,
808*b1cdbd2cSJim Jagielski                           status );
809*b1cdbd2cSJim Jagielski 
810*b1cdbd2cSJim Jagielski     HandleError( aReqProc );
811*b1cdbd2cSJim Jagielski 
812*b1cdbd2cSJim Jagielski     return uno::Reference< io::XInputStream >( xInputStream.get() );
813*b1cdbd2cSJim Jagielski }
814*b1cdbd2cSJim Jagielski 
815*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
816*b1cdbd2cSJim Jagielski // GET
817*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
GET(const rtl::OUString & inPath,uno::Reference<io::XOutputStream> & ioOutputStream,const DAVRequestEnvironment & rEnv)818*b1cdbd2cSJim Jagielski void SerfSession::GET( const rtl::OUString & inPath,
819*b1cdbd2cSJim Jagielski                        uno::Reference< io::XOutputStream > & ioOutputStream,
820*b1cdbd2cSJim Jagielski                        const DAVRequestEnvironment & rEnv )
821*b1cdbd2cSJim Jagielski     throw ( DAVException )
822*b1cdbd2cSJim Jagielski {
823*b1cdbd2cSJim Jagielski     osl::Guard< osl::Mutex > theGuard( m_aMutex );
824*b1cdbd2cSJim Jagielski 
825*b1cdbd2cSJim Jagielski     Init( rEnv );
826*b1cdbd2cSJim Jagielski 
827*b1cdbd2cSJim Jagielski     apr_status_t status = APR_SUCCESS;
828*b1cdbd2cSJim Jagielski     boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) );
829*b1cdbd2cSJim Jagielski     aReqProc->processGet( ioOutputStream,
830*b1cdbd2cSJim Jagielski                           status );
831*b1cdbd2cSJim Jagielski 
832*b1cdbd2cSJim Jagielski     HandleError( aReqProc );
833*b1cdbd2cSJim Jagielski }
834*b1cdbd2cSJim Jagielski 
835*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
836*b1cdbd2cSJim Jagielski // GET
837*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
838*b1cdbd2cSJim Jagielski uno::Reference< io::XInputStream >
GET(const rtl::OUString & inPath,const std::vector<::rtl::OUString> & inHeaderNames,DAVResource & ioResource,const DAVRequestEnvironment & rEnv)839*b1cdbd2cSJim Jagielski SerfSession::GET( const rtl::OUString & inPath,
840*b1cdbd2cSJim Jagielski                   const std::vector< ::rtl::OUString > & inHeaderNames,
841*b1cdbd2cSJim Jagielski                   DAVResource & ioResource,
842*b1cdbd2cSJim Jagielski                   const DAVRequestEnvironment & rEnv )
843*b1cdbd2cSJim Jagielski     throw ( DAVException )
844*b1cdbd2cSJim Jagielski {
845*b1cdbd2cSJim Jagielski     osl::Guard< osl::Mutex > theGuard( m_aMutex );
846*b1cdbd2cSJim Jagielski 
847*b1cdbd2cSJim Jagielski     Init( rEnv );
848*b1cdbd2cSJim Jagielski 
849*b1cdbd2cSJim Jagielski     boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) );
850*b1cdbd2cSJim Jagielski     uno::Reference< SerfInputStream > xInputStream( new SerfInputStream );
851*b1cdbd2cSJim Jagielski     ioResource.uri = inPath;
852*b1cdbd2cSJim Jagielski     ioResource.properties.clear();
853*b1cdbd2cSJim Jagielski     apr_status_t status = APR_SUCCESS;
854*b1cdbd2cSJim Jagielski     aReqProc->processGet( xInputStream,
855*b1cdbd2cSJim Jagielski                           inHeaderNames,
856*b1cdbd2cSJim Jagielski                           ioResource,
857*b1cdbd2cSJim Jagielski                           status );
858*b1cdbd2cSJim Jagielski 
859*b1cdbd2cSJim Jagielski     HandleError( aReqProc );
860*b1cdbd2cSJim Jagielski 
861*b1cdbd2cSJim Jagielski     return uno::Reference< io::XInputStream >( xInputStream.get() );
862*b1cdbd2cSJim Jagielski }
863*b1cdbd2cSJim Jagielski 
864*b1cdbd2cSJim Jagielski 
865*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
866*b1cdbd2cSJim Jagielski // GET
867*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
GET(const rtl::OUString & inPath,uno::Reference<io::XOutputStream> & ioOutputStream,const std::vector<::rtl::OUString> & inHeaderNames,DAVResource & ioResource,const DAVRequestEnvironment & rEnv)868*b1cdbd2cSJim Jagielski void SerfSession::GET( const rtl::OUString & inPath,
869*b1cdbd2cSJim Jagielski                        uno::Reference< io::XOutputStream > & ioOutputStream,
870*b1cdbd2cSJim Jagielski                        const std::vector< ::rtl::OUString > & inHeaderNames,
871*b1cdbd2cSJim Jagielski                        DAVResource & ioResource,
872*b1cdbd2cSJim Jagielski                        const DAVRequestEnvironment & rEnv )
873*b1cdbd2cSJim Jagielski     throw ( DAVException )
874*b1cdbd2cSJim Jagielski {
875*b1cdbd2cSJim Jagielski     osl::Guard< osl::Mutex > theGuard( m_aMutex );
876*b1cdbd2cSJim Jagielski 
877*b1cdbd2cSJim Jagielski     Init( rEnv );
878*b1cdbd2cSJim Jagielski 
879*b1cdbd2cSJim Jagielski     boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) );
880*b1cdbd2cSJim Jagielski     ioResource.uri = inPath;
881*b1cdbd2cSJim Jagielski     ioResource.properties.clear();
882*b1cdbd2cSJim Jagielski     apr_status_t status = APR_SUCCESS;
883*b1cdbd2cSJim Jagielski     aReqProc->processGet( ioOutputStream,
884*b1cdbd2cSJim Jagielski                           inHeaderNames,
885*b1cdbd2cSJim Jagielski                           ioResource,
886*b1cdbd2cSJim Jagielski                           status );
887*b1cdbd2cSJim Jagielski 
888*b1cdbd2cSJim Jagielski     HandleError( aReqProc );
889*b1cdbd2cSJim Jagielski }
890*b1cdbd2cSJim Jagielski 
891*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
892*b1cdbd2cSJim Jagielski // PUT
893*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
PUT(const rtl::OUString & inPath,const uno::Reference<io::XInputStream> & inInputStream,const DAVRequestEnvironment & rEnv)894*b1cdbd2cSJim Jagielski void SerfSession::PUT( const rtl::OUString & inPath,
895*b1cdbd2cSJim Jagielski                        const uno::Reference< io::XInputStream > & inInputStream,
896*b1cdbd2cSJim Jagielski                        const DAVRequestEnvironment & rEnv )
897*b1cdbd2cSJim Jagielski     throw ( DAVException )
898*b1cdbd2cSJim Jagielski {
899*b1cdbd2cSJim Jagielski     osl::Guard< osl::Mutex > theGuard( m_aMutex );
900*b1cdbd2cSJim Jagielski 
901*b1cdbd2cSJim Jagielski     Init( rEnv );
902*b1cdbd2cSJim Jagielski 
903*b1cdbd2cSJim Jagielski     boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) );
904*b1cdbd2cSJim Jagielski     uno::Sequence< sal_Int8 > aDataToSend;
905*b1cdbd2cSJim Jagielski     if ( !getDataFromInputStream( inInputStream, aDataToSend, false ) )
906*b1cdbd2cSJim Jagielski         throw DAVException( DAVException::DAV_INVALID_ARG );
907*b1cdbd2cSJim Jagielski     apr_status_t status = APR_SUCCESS;
908*b1cdbd2cSJim Jagielski 
909*b1cdbd2cSJim Jagielski     //check whether a lock on this resource is already owned
910*b1cdbd2cSJim Jagielski     rtl::OUString aUri( composeCurrentUri( inPath ) );
911*b1cdbd2cSJim Jagielski     ucb::Lock inLock;
912*b1cdbd2cSJim Jagielski     SerfLock * pLock = m_aSerfLockStore.findByUri( aUri );
913*b1cdbd2cSJim Jagielski     if ( pLock )
914*b1cdbd2cSJim Jagielski     {
915*b1cdbd2cSJim Jagielski         inLock = pLock->getLock();
916*b1cdbd2cSJim Jagielski     }
917*b1cdbd2cSJim Jagielski     aReqProc->processPut( reinterpret_cast< const char * >( aDataToSend.getConstArray() ),
918*b1cdbd2cSJim Jagielski                           aDataToSend.getLength(),
919*b1cdbd2cSJim Jagielski                           inLock,
920*b1cdbd2cSJim Jagielski                           status );
921*b1cdbd2cSJim Jagielski 
922*b1cdbd2cSJim Jagielski     HandleError( aReqProc );
923*b1cdbd2cSJim Jagielski }
924*b1cdbd2cSJim Jagielski 
925*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
926*b1cdbd2cSJim Jagielski // POST
927*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
928*b1cdbd2cSJim Jagielski 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)929*b1cdbd2cSJim Jagielski SerfSession::POST( const rtl::OUString & inPath,
930*b1cdbd2cSJim Jagielski                    const rtl::OUString & rContentType,
931*b1cdbd2cSJim Jagielski                    const rtl::OUString & rReferer,
932*b1cdbd2cSJim Jagielski                    const uno::Reference< io::XInputStream > & inInputStream,
933*b1cdbd2cSJim Jagielski                    const DAVRequestEnvironment & rEnv )
934*b1cdbd2cSJim Jagielski     throw ( DAVException )
935*b1cdbd2cSJim Jagielski {
936*b1cdbd2cSJim Jagielski     osl::Guard< osl::Mutex > theGuard( m_aMutex );
937*b1cdbd2cSJim Jagielski 
938*b1cdbd2cSJim Jagielski     uno::Sequence< sal_Int8 > aDataToSend;
939*b1cdbd2cSJim Jagielski     if ( !getDataFromInputStream( inInputStream, aDataToSend, true ) )
940*b1cdbd2cSJim Jagielski     {
941*b1cdbd2cSJim Jagielski         throw DAVException( DAVException::DAV_INVALID_ARG );
942*b1cdbd2cSJim Jagielski     }
943*b1cdbd2cSJim Jagielski 
944*b1cdbd2cSJim Jagielski     Init( rEnv );
945*b1cdbd2cSJim Jagielski 
946*b1cdbd2cSJim Jagielski     boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) );
947*b1cdbd2cSJim Jagielski     uno::Reference< SerfInputStream > xInputStream( new SerfInputStream );
948*b1cdbd2cSJim Jagielski     apr_status_t status = APR_SUCCESS;
949*b1cdbd2cSJim Jagielski     //check whether a lock on this resource is already owned
950*b1cdbd2cSJim Jagielski     rtl::OUString aUri( composeCurrentUri( inPath ) );
951*b1cdbd2cSJim Jagielski     ucb::Lock inLock;
952*b1cdbd2cSJim Jagielski     SerfLock * pLock = m_aSerfLockStore.findByUri( aUri );
953*b1cdbd2cSJim Jagielski     if ( pLock )
954*b1cdbd2cSJim Jagielski     {
955*b1cdbd2cSJim Jagielski         inLock = pLock->getLock();
956*b1cdbd2cSJim Jagielski     }
957*b1cdbd2cSJim Jagielski     aReqProc->processPost( reinterpret_cast< const char * >( aDataToSend.getConstArray() ),
958*b1cdbd2cSJim Jagielski                            aDataToSend.getLength(),
959*b1cdbd2cSJim Jagielski                            rContentType,
960*b1cdbd2cSJim Jagielski                            rReferer,
961*b1cdbd2cSJim Jagielski                            inLock,
962*b1cdbd2cSJim Jagielski                            xInputStream,
963*b1cdbd2cSJim Jagielski                            status );
964*b1cdbd2cSJim Jagielski 
965*b1cdbd2cSJim Jagielski     HandleError( aReqProc );
966*b1cdbd2cSJim Jagielski     return uno::Reference< io::XInputStream >( xInputStream.get() );
967*b1cdbd2cSJim Jagielski }
968*b1cdbd2cSJim Jagielski 
969*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
970*b1cdbd2cSJim Jagielski // POST
971*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
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)972*b1cdbd2cSJim Jagielski void SerfSession::POST( const rtl::OUString & inPath,
973*b1cdbd2cSJim Jagielski                         const rtl::OUString & rContentType,
974*b1cdbd2cSJim Jagielski                         const rtl::OUString & rReferer,
975*b1cdbd2cSJim Jagielski                         const uno::Reference< io::XInputStream > & inInputStream,
976*b1cdbd2cSJim Jagielski                         uno::Reference< io::XOutputStream > & oOutputStream,
977*b1cdbd2cSJim Jagielski                         const DAVRequestEnvironment & rEnv )
978*b1cdbd2cSJim Jagielski     throw ( DAVException )
979*b1cdbd2cSJim Jagielski {
980*b1cdbd2cSJim Jagielski     osl::Guard< osl::Mutex > theGuard( m_aMutex );
981*b1cdbd2cSJim Jagielski 
982*b1cdbd2cSJim Jagielski     uno::Sequence< sal_Int8 > aDataToSend;
983*b1cdbd2cSJim Jagielski     if ( !getDataFromInputStream( inInputStream, aDataToSend, true ) )
984*b1cdbd2cSJim Jagielski     {
985*b1cdbd2cSJim Jagielski         throw DAVException( DAVException::DAV_INVALID_ARG );
986*b1cdbd2cSJim Jagielski     }
987*b1cdbd2cSJim Jagielski 
988*b1cdbd2cSJim Jagielski     Init( rEnv );
989*b1cdbd2cSJim Jagielski 
990*b1cdbd2cSJim Jagielski     boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) );
991*b1cdbd2cSJim Jagielski     apr_status_t status = APR_SUCCESS;
992*b1cdbd2cSJim Jagielski     //check whether a lock on this resource is already owned
993*b1cdbd2cSJim Jagielski     rtl::OUString aUri( composeCurrentUri( inPath ) );
994*b1cdbd2cSJim Jagielski     ucb::Lock inLock;
995*b1cdbd2cSJim Jagielski     SerfLock * pLock = m_aSerfLockStore.findByUri( aUri );
996*b1cdbd2cSJim Jagielski     if ( pLock )
997*b1cdbd2cSJim Jagielski     {
998*b1cdbd2cSJim Jagielski         inLock = pLock->getLock();
999*b1cdbd2cSJim Jagielski     }
1000*b1cdbd2cSJim Jagielski     aReqProc->processPost( reinterpret_cast< const char * >( aDataToSend.getConstArray() ),
1001*b1cdbd2cSJim Jagielski                            aDataToSend.getLength(),
1002*b1cdbd2cSJim Jagielski                            rContentType,
1003*b1cdbd2cSJim Jagielski                            rReferer,
1004*b1cdbd2cSJim Jagielski                            inLock,
1005*b1cdbd2cSJim Jagielski                            oOutputStream,
1006*b1cdbd2cSJim Jagielski                            status );
1007*b1cdbd2cSJim Jagielski 
1008*b1cdbd2cSJim Jagielski     HandleError( aReqProc );
1009*b1cdbd2cSJim Jagielski }
1010*b1cdbd2cSJim Jagielski 
1011*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
1012*b1cdbd2cSJim Jagielski // MKCOL
1013*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
MKCOL(const rtl::OUString & inPath,const DAVRequestEnvironment & rEnv)1014*b1cdbd2cSJim Jagielski void SerfSession::MKCOL( const rtl::OUString & inPath,
1015*b1cdbd2cSJim Jagielski                          const DAVRequestEnvironment & rEnv )
1016*b1cdbd2cSJim Jagielski     throw ( DAVException )
1017*b1cdbd2cSJim Jagielski {
1018*b1cdbd2cSJim Jagielski     osl::Guard< osl::Mutex > theGuard( m_aMutex );
1019*b1cdbd2cSJim Jagielski 
1020*b1cdbd2cSJim Jagielski     Init( rEnv );
1021*b1cdbd2cSJim Jagielski 
1022*b1cdbd2cSJim Jagielski     boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) );
1023*b1cdbd2cSJim Jagielski     apr_status_t status = APR_SUCCESS;
1024*b1cdbd2cSJim Jagielski     //check whether a lock on the destination resource is already owned
1025*b1cdbd2cSJim Jagielski     rtl::OUString aUri( composeCurrentUri( inPath ) );
1026*b1cdbd2cSJim Jagielski     ucb::Lock inLock;
1027*b1cdbd2cSJim Jagielski     SerfLock * pLock = m_aSerfLockStore.findByUri( aUri );
1028*b1cdbd2cSJim Jagielski     if ( pLock )
1029*b1cdbd2cSJim Jagielski     {
1030*b1cdbd2cSJim Jagielski         inLock = pLock->getLock();
1031*b1cdbd2cSJim Jagielski     }
1032*b1cdbd2cSJim Jagielski     aReqProc->processMkCol( inLock, status );
1033*b1cdbd2cSJim Jagielski 
1034*b1cdbd2cSJim Jagielski     HandleError( aReqProc );
1035*b1cdbd2cSJim Jagielski }
1036*b1cdbd2cSJim Jagielski 
1037*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
1038*b1cdbd2cSJim Jagielski // COPY
1039*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
COPY(const rtl::OUString & inSourceURL,const rtl::OUString & inDestinationURL,const DAVRequestEnvironment & rEnv,sal_Bool inOverWrite)1040*b1cdbd2cSJim Jagielski void SerfSession::COPY( const rtl::OUString & inSourceURL,
1041*b1cdbd2cSJim Jagielski                         const rtl::OUString & inDestinationURL,
1042*b1cdbd2cSJim Jagielski                         const DAVRequestEnvironment & rEnv,
1043*b1cdbd2cSJim Jagielski                         sal_Bool inOverWrite )
1044*b1cdbd2cSJim Jagielski     throw ( DAVException )
1045*b1cdbd2cSJim Jagielski {
1046*b1cdbd2cSJim Jagielski     osl::Guard< osl::Mutex > theGuard( m_aMutex );
1047*b1cdbd2cSJim Jagielski 
1048*b1cdbd2cSJim Jagielski     Init( rEnv );
1049*b1cdbd2cSJim Jagielski 
1050*b1cdbd2cSJim Jagielski     SerfUri theSourceUri( inSourceURL );
1051*b1cdbd2cSJim Jagielski     boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( theSourceUri.GetPath() ) );
1052*b1cdbd2cSJim Jagielski     apr_status_t status = APR_SUCCESS;
1053*b1cdbd2cSJim Jagielski     //check whether a lock on the destination resource is already owned
1054*b1cdbd2cSJim Jagielski     rtl::OUString aUri( composeCurrentUri( inDestinationURL ) );
1055*b1cdbd2cSJim Jagielski     ucb::Lock inLock;
1056*b1cdbd2cSJim Jagielski     SerfLock * pLock = m_aSerfLockStore.findByUri( aUri );
1057*b1cdbd2cSJim Jagielski     if ( pLock )
1058*b1cdbd2cSJim Jagielski     {
1059*b1cdbd2cSJim Jagielski         inLock = pLock->getLock();
1060*b1cdbd2cSJim Jagielski     }
1061*b1cdbd2cSJim Jagielski     aReqProc->processCopy( inDestinationURL,
1062*b1cdbd2cSJim Jagielski                            (inOverWrite ? true : false),
1063*b1cdbd2cSJim Jagielski                            inLock,
1064*b1cdbd2cSJim Jagielski                            status );
1065*b1cdbd2cSJim Jagielski 
1066*b1cdbd2cSJim Jagielski     HandleError( aReqProc );
1067*b1cdbd2cSJim Jagielski }
1068*b1cdbd2cSJim Jagielski 
1069*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
1070*b1cdbd2cSJim Jagielski // MOVE
1071*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
MOVE(const rtl::OUString & inSourceURL,const rtl::OUString & inDestinationURL,const DAVRequestEnvironment & rEnv,sal_Bool inOverWrite)1072*b1cdbd2cSJim Jagielski void SerfSession::MOVE( const rtl::OUString & inSourceURL,
1073*b1cdbd2cSJim Jagielski                         const rtl::OUString & inDestinationURL,
1074*b1cdbd2cSJim Jagielski                         const DAVRequestEnvironment & rEnv,
1075*b1cdbd2cSJim Jagielski                         sal_Bool inOverWrite )
1076*b1cdbd2cSJim Jagielski     throw ( DAVException )
1077*b1cdbd2cSJim Jagielski {
1078*b1cdbd2cSJim Jagielski     osl::Guard< osl::Mutex > theGuard( m_aMutex );
1079*b1cdbd2cSJim Jagielski 
1080*b1cdbd2cSJim Jagielski     Init( rEnv );
1081*b1cdbd2cSJim Jagielski 
1082*b1cdbd2cSJim Jagielski     SerfUri theSourceUri( inSourceURL );
1083*b1cdbd2cSJim Jagielski     boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( theSourceUri.GetPath() ) );
1084*b1cdbd2cSJim Jagielski     apr_status_t status = APR_SUCCESS;
1085*b1cdbd2cSJim Jagielski     //check whether a lock on the destination resource is already owned
1086*b1cdbd2cSJim Jagielski     rtl::OUString aUri( composeCurrentUri( inDestinationURL ) );
1087*b1cdbd2cSJim Jagielski     ucb::Lock inLock;
1088*b1cdbd2cSJim Jagielski     SerfLock * pLock = m_aSerfLockStore.findByUri( aUri );
1089*b1cdbd2cSJim Jagielski     if ( pLock )
1090*b1cdbd2cSJim Jagielski     {
1091*b1cdbd2cSJim Jagielski         inLock = pLock->getLock();
1092*b1cdbd2cSJim Jagielski     }
1093*b1cdbd2cSJim Jagielski     aReqProc->processMove( inDestinationURL,
1094*b1cdbd2cSJim Jagielski                            (inOverWrite ? true : false),
1095*b1cdbd2cSJim Jagielski                            inLock,
1096*b1cdbd2cSJim Jagielski                            status );
1097*b1cdbd2cSJim Jagielski 
1098*b1cdbd2cSJim Jagielski     HandleError( aReqProc );
1099*b1cdbd2cSJim Jagielski }
1100*b1cdbd2cSJim Jagielski 
1101*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
1102*b1cdbd2cSJim Jagielski // DESTROY
1103*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
DESTROY(const rtl::OUString & inPath,const DAVRequestEnvironment & rEnv)1104*b1cdbd2cSJim Jagielski void SerfSession::DESTROY( const rtl::OUString & inPath,
1105*b1cdbd2cSJim Jagielski                            const DAVRequestEnvironment & rEnv )
1106*b1cdbd2cSJim Jagielski     throw ( DAVException )
1107*b1cdbd2cSJim Jagielski {
1108*b1cdbd2cSJim Jagielski     osl::Guard< osl::Mutex > theGuard( m_aMutex );
1109*b1cdbd2cSJim Jagielski 
1110*b1cdbd2cSJim Jagielski     Init( rEnv );
1111*b1cdbd2cSJim Jagielski 
1112*b1cdbd2cSJim Jagielski     boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) );
1113*b1cdbd2cSJim Jagielski     apr_status_t status = APR_SUCCESS;
1114*b1cdbd2cSJim Jagielski     //check whether a lock on this resource is already owned
1115*b1cdbd2cSJim Jagielski     rtl::OUString aUri( composeCurrentUri( inPath ) );
1116*b1cdbd2cSJim Jagielski     ucb::Lock inLock;
1117*b1cdbd2cSJim Jagielski     SerfLock * pLock = m_aSerfLockStore.findByUri( aUri );
1118*b1cdbd2cSJim Jagielski     if ( pLock )
1119*b1cdbd2cSJim Jagielski     {
1120*b1cdbd2cSJim Jagielski         inLock = pLock->getLock();
1121*b1cdbd2cSJim Jagielski     }
1122*b1cdbd2cSJim Jagielski     aReqProc->processDelete( inLock, status );
1123*b1cdbd2cSJim Jagielski 
1124*b1cdbd2cSJim Jagielski     HandleError( aReqProc );
1125*b1cdbd2cSJim Jagielski }
1126*b1cdbd2cSJim Jagielski 
1127*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
1128*b1cdbd2cSJim Jagielski 
1129*b1cdbd2cSJim Jagielski namespace
1130*b1cdbd2cSJim Jagielski {
lastChanceToSendRefreshRequest(TimeValue const & rStart,sal_Int32 timeout)1131*b1cdbd2cSJim Jagielski     sal_Int32 lastChanceToSendRefreshRequest( TimeValue const & rStart,
1132*b1cdbd2cSJim Jagielski                                               sal_Int32 timeout )
1133*b1cdbd2cSJim Jagielski     {
1134*b1cdbd2cSJim Jagielski         TimeValue aEnd;
1135*b1cdbd2cSJim Jagielski         osl_getSystemTime( &aEnd );
1136*b1cdbd2cSJim Jagielski 
1137*b1cdbd2cSJim Jagielski         // Try to estimate a safe absolute time for sending the
1138*b1cdbd2cSJim Jagielski         // lock refresh request.
1139*b1cdbd2cSJim Jagielski         sal_Int32 lastChanceToSendRefreshRequest = DAVINFINITY;
1140*b1cdbd2cSJim Jagielski         if ( timeout != DAVINFINITY )
1141*b1cdbd2cSJim Jagielski         {
1142*b1cdbd2cSJim Jagielski             sal_Int32 calltime = aEnd.Seconds - rStart.Seconds;
1143*b1cdbd2cSJim Jagielski             if ( calltime <= timeout )
1144*b1cdbd2cSJim Jagielski             {
1145*b1cdbd2cSJim Jagielski                 lastChanceToSendRefreshRequest
1146*b1cdbd2cSJim Jagielski                     = aEnd.Seconds + timeout - calltime;
1147*b1cdbd2cSJim Jagielski             }
1148*b1cdbd2cSJim Jagielski             else
1149*b1cdbd2cSJim Jagielski             {
1150*b1cdbd2cSJim Jagielski                 OSL_TRACE( "No chance to refresh lock before timeout!" );
1151*b1cdbd2cSJim Jagielski             }
1152*b1cdbd2cSJim Jagielski         }
1153*b1cdbd2cSJim Jagielski         return lastChanceToSendRefreshRequest;
1154*b1cdbd2cSJim Jagielski     }
1155*b1cdbd2cSJim Jagielski 
1156*b1cdbd2cSJim Jagielski } // namespace
1157*b1cdbd2cSJim Jagielski 
1158*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
1159*b1cdbd2cSJim Jagielski // LOCK (set new lock)
1160*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
LOCK(const::rtl::OUString & inPath,ucb::Lock & rLock,const DAVRequestEnvironment & rEnv)1161*b1cdbd2cSJim Jagielski void SerfSession::LOCK( const ::rtl::OUString & inPath,
1162*b1cdbd2cSJim Jagielski                         ucb::Lock & rLock,
1163*b1cdbd2cSJim Jagielski                         const DAVRequestEnvironment & rEnv )
1164*b1cdbd2cSJim Jagielski     throw ( DAVException )
1165*b1cdbd2cSJim Jagielski {
1166*b1cdbd2cSJim Jagielski     osl::Guard< osl::Mutex > theGuard( m_aMutex );
1167*b1cdbd2cSJim Jagielski 
1168*b1cdbd2cSJim Jagielski     //before locking, search in the lock store if we already own a lock for this resource
1169*b1cdbd2cSJim Jagielski     //if present, return with exception DAV_LOCKED_SELF
1170*b1cdbd2cSJim Jagielski     rtl::OUString   aUri( composeCurrentUri( inPath ) );
1171*b1cdbd2cSJim Jagielski     SerfLock * pLock = m_aSerfLockStore.findByUri( aUri );
1172*b1cdbd2cSJim Jagielski     if ( pLock )
1173*b1cdbd2cSJim Jagielski     {
1174*b1cdbd2cSJim Jagielski //already present, meaning already locked by the same AOO session and already in the lockstore
1175*b1cdbd2cSJim Jagielski //just return, nothing to do
1176*b1cdbd2cSJim Jagielski         return;
1177*b1cdbd2cSJim Jagielski     }
1178*b1cdbd2cSJim Jagielski 
1179*b1cdbd2cSJim Jagielski     Init( rEnv );
1180*b1cdbd2cSJim Jagielski 
1181*b1cdbd2cSJim Jagielski     boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) );
1182*b1cdbd2cSJim Jagielski     apr_status_t status = APR_SUCCESS;
1183*b1cdbd2cSJim Jagielski 
1184*b1cdbd2cSJim Jagielski     //the returned property, a sequence of locks
1185*b1cdbd2cSJim Jagielski     //only the first is used
1186*b1cdbd2cSJim Jagielski     DAVPropertyValue outLock;
1187*b1cdbd2cSJim Jagielski 
1188*b1cdbd2cSJim Jagielski     TimeValue startCall;
1189*b1cdbd2cSJim Jagielski     osl_getSystemTime( &startCall );
1190*b1cdbd2cSJim Jagielski     aReqProc->processLock(inPath, rLock, outLock, status);
1191*b1cdbd2cSJim Jagielski 
1192*b1cdbd2cSJim Jagielski     //HandleError will handle the error and throw an exception, if needed
1193*b1cdbd2cSJim Jagielski     HandleError( aReqProc );
1194*b1cdbd2cSJim Jagielski 
1195*b1cdbd2cSJim Jagielski     if(outLock.Name.compareToAscii(RTL_CONSTASCII_STRINGPARAM( "DAV:lockdiscovery" )) == 0 )
1196*b1cdbd2cSJim Jagielski     {
1197*b1cdbd2cSJim Jagielski         //got a lock, use only the first returned
1198*b1cdbd2cSJim Jagielski         uno::Sequence< ucb::Lock >      aLocks;
1199*b1cdbd2cSJim Jagielski         outLock.Value >>= aLocks;
1200*b1cdbd2cSJim Jagielski         ucb::Lock aLock = aLocks[0];
1201*b1cdbd2cSJim Jagielski 
1202*b1cdbd2cSJim Jagielski         SerfLock* aNewLock = new SerfLock( aLock, aUri, inPath );
1203*b1cdbd2cSJim Jagielski         // add the store the new lock
1204*b1cdbd2cSJim Jagielski         m_aSerfLockStore.addLock(aNewLock,this,
1205*b1cdbd2cSJim Jagielski                                  lastChanceToSendRefreshRequest(
1206*b1cdbd2cSJim Jagielski                                      startCall, static_cast< sal_Int32 >(aLock.Timeout) ) );
1207*b1cdbd2cSJim Jagielski     }
1208*b1cdbd2cSJim Jagielski 
1209*b1cdbd2cSJim Jagielski }
1210*b1cdbd2cSJim Jagielski 
1211*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
1212*b1cdbd2cSJim Jagielski // LOCK (refresh existing lock from DAVResourceAccess)
1213*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
LOCK(const::rtl::OUString &,sal_Int64 nTimeout,const DAVRequestEnvironment &)1214*b1cdbd2cSJim Jagielski sal_Int64 SerfSession::LOCK( const ::rtl::OUString & /*inPath*/,
1215*b1cdbd2cSJim Jagielski                              sal_Int64 nTimeout,
1216*b1cdbd2cSJim Jagielski                              const DAVRequestEnvironment & /*rEnv*/ )
1217*b1cdbd2cSJim Jagielski     throw ( DAVException )
1218*b1cdbd2cSJim Jagielski {
1219*b1cdbd2cSJim Jagielski     osl::Guard< osl::Mutex > theGuard( m_aMutex );
1220*b1cdbd2cSJim Jagielski 
1221*b1cdbd2cSJim Jagielski     return nTimeout;
1222*b1cdbd2cSJim Jagielski     /*
1223*b1cdbd2cSJim Jagielski     // Try to get the neon lock from lock store
1224*b1cdbd2cSJim Jagielski     SerfLock * theLock
1225*b1cdbd2cSJim Jagielski         = m_aSerfLockStore.findByUri( makeAbsoluteURL( inPath ) );
1226*b1cdbd2cSJim Jagielski     if ( !theLock )
1227*b1cdbd2cSJim Jagielski          throw DAVException( DAVException::DAV_NOT_LOCKED );
1228*b1cdbd2cSJim Jagielski 
1229*b1cdbd2cSJim Jagielski     Init( rEnv );
1230*b1cdbd2cSJim Jagielski 
1231*b1cdbd2cSJim Jagielski     // refresh existing lock.
1232*b1cdbd2cSJim Jagielski     theLock->timeout = static_cast< long >( nTimeout );
1233*b1cdbd2cSJim Jagielski 
1234*b1cdbd2cSJim Jagielski     TimeValue startCall;
1235*b1cdbd2cSJim Jagielski     osl_getSystemTime( &startCall );
1236*b1cdbd2cSJim Jagielski 
1237*b1cdbd2cSJim Jagielski     int theRetVal = ne_lock_refresh( m_pHttpSession, theLock );
1238*b1cdbd2cSJim Jagielski 
1239*b1cdbd2cSJim Jagielski     if ( theRetVal == NE_OK )
1240*b1cdbd2cSJim Jagielski     {
1241*b1cdbd2cSJim Jagielski         m_aSerfLockStore.updateLock( theLock,
1242*b1cdbd2cSJim Jagielski                                      lastChanceToSendRefreshRequest(
1243*b1cdbd2cSJim Jagielski                                          startCall, theLock->timeout ) );
1244*b1cdbd2cSJim Jagielski     }
1245*b1cdbd2cSJim Jagielski 
1246*b1cdbd2cSJim Jagielski     HandleError( theRetVal, inPath, rEnv );
1247*b1cdbd2cSJim Jagielski 
1248*b1cdbd2cSJim Jagielski     return theLock->timeout;
1249*b1cdbd2cSJim Jagielski     */
1250*b1cdbd2cSJim Jagielski }
1251*b1cdbd2cSJim Jagielski 
1252*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
1253*b1cdbd2cSJim Jagielski // LOCK (refresh existing lock from SerfLockStore)
1254*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
LOCK(SerfLock * pLock,sal_Int32 & rlastChanceToSendRefreshRequest)1255*b1cdbd2cSJim Jagielski bool SerfSession::LOCK( SerfLock * pLock,
1256*b1cdbd2cSJim Jagielski                         sal_Int32 & rlastChanceToSendRefreshRequest )
1257*b1cdbd2cSJim Jagielski {
1258*b1cdbd2cSJim Jagielski     osl::Guard< osl::Mutex > theGuard( m_aMutex );
1259*b1cdbd2cSJim Jagielski     rtl::OUString inPath = pLock->getResourcePath();
1260*b1cdbd2cSJim Jagielski 
1261*b1cdbd2cSJim Jagielski     boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) );
1262*b1cdbd2cSJim Jagielski     apr_status_t status = APR_SUCCESS;
1263*b1cdbd2cSJim Jagielski 
1264*b1cdbd2cSJim Jagielski     //the returned property, a sequence of locks
1265*b1cdbd2cSJim Jagielski     //only the first is used
1266*b1cdbd2cSJim Jagielski     DAVPropertyValue outLock;
1267*b1cdbd2cSJim Jagielski 
1268*b1cdbd2cSJim Jagielski     TimeValue startCall;
1269*b1cdbd2cSJim Jagielski     osl_getSystemTime( &startCall );
1270*b1cdbd2cSJim Jagielski 
1271*b1cdbd2cSJim Jagielski     // refresh existing lock.
1272*b1cdbd2cSJim Jagielski     aReqProc->processLockRefresh( inPath, pLock->getLock(), outLock, status);
1273*b1cdbd2cSJim Jagielski 
1274*b1cdbd2cSJim Jagielski     // TODO: possible enhancement as the following:
1275*b1cdbd2cSJim Jagielski     // - use an interaction handler to alert the user if the lock was not refreshed,
1276*b1cdbd2cSJim Jagielski     //   offering to try again with a new session, asking the user for credential, if necessary.
1277*b1cdbd2cSJim Jagielski     //   This may happen if the WebDAV server goes off-line for whatever reason, or the connection is dropped for time-out
1278*b1cdbd2cSJim Jagielski     //   To implement this behavior, some redesigning of the current session implementation may be needed.
1279*b1cdbd2cSJim Jagielski     //
1280*b1cdbd2cSJim Jagielski 
1281*b1cdbd2cSJim Jagielski     //HandleError will handle the error and throw an exception, if needed
1282*b1cdbd2cSJim Jagielski     HandleError( aReqProc );
1283*b1cdbd2cSJim Jagielski 
1284*b1cdbd2cSJim Jagielski     uno::Sequence< ucb::Lock >      aLocks;
1285*b1cdbd2cSJim Jagielski     outLock.Value >>= aLocks;
1286*b1cdbd2cSJim Jagielski     ucb::Lock aLock = aLocks[0];
1287*b1cdbd2cSJim Jagielski 
1288*b1cdbd2cSJim Jagielski     //if ok, udate the lastchance refresh time in lock
1289*b1cdbd2cSJim Jagielski     rlastChanceToSendRefreshRequest
1290*b1cdbd2cSJim Jagielski         = lastChanceToSendRefreshRequest( startCall, static_cast< sal_Int32 >(aLock.Timeout) );
1291*b1cdbd2cSJim Jagielski 
1292*b1cdbd2cSJim Jagielski     return true;
1293*b1cdbd2cSJim Jagielski }
1294*b1cdbd2cSJim Jagielski 
1295*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
1296*b1cdbd2cSJim Jagielski // UNLOCK called from external (DAVResourceAccess)
1297*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
UNLOCK(const::rtl::OUString & inPath,const DAVRequestEnvironment & rEnv)1298*b1cdbd2cSJim Jagielski void SerfSession::UNLOCK( const ::rtl::OUString & inPath,
1299*b1cdbd2cSJim Jagielski                           const DAVRequestEnvironment & rEnv )
1300*b1cdbd2cSJim Jagielski     throw ( DAVException )
1301*b1cdbd2cSJim Jagielski {
1302*b1cdbd2cSJim Jagielski     osl::Guard< osl::Mutex > theGuard( m_aMutex );
1303*b1cdbd2cSJim Jagielski 
1304*b1cdbd2cSJim Jagielski     rtl::OUString aUri( composeCurrentUri( inPath ) );
1305*b1cdbd2cSJim Jagielski     SerfLock * pLock = m_aSerfLockStore.findByUri( aUri );
1306*b1cdbd2cSJim Jagielski     if ( !pLock )
1307*b1cdbd2cSJim Jagielski     {
1308*b1cdbd2cSJim Jagielski         throw DAVException( DAVException::DAV_NOT_LOCKED );
1309*b1cdbd2cSJim Jagielski     }
1310*b1cdbd2cSJim Jagielski 
1311*b1cdbd2cSJim Jagielski     Init( rEnv );
1312*b1cdbd2cSJim Jagielski 
1313*b1cdbd2cSJim Jagielski     boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) );
1314*b1cdbd2cSJim Jagielski     apr_status_t status = APR_SUCCESS;
1315*b1cdbd2cSJim Jagielski 
1316*b1cdbd2cSJim Jagielski     ucb::Lock inLock = pLock->getLock();
1317*b1cdbd2cSJim Jagielski     //remove lock from lockstore
1318*b1cdbd2cSJim Jagielski     // so, if something goes wrong, we don't refresh it anymore
1319*b1cdbd2cSJim Jagielski     m_aSerfLockStore.removeLock(pLock);
1320*b1cdbd2cSJim Jagielski     delete pLock;
1321*b1cdbd2cSJim Jagielski 
1322*b1cdbd2cSJim Jagielski     // remove existing lock
1323*b1cdbd2cSJim Jagielski     aReqProc->processUnlock( inPath, inLock, status);
1324*b1cdbd2cSJim Jagielski 
1325*b1cdbd2cSJim Jagielski     //HandleError will handle the error and throw an exception, if needed
1326*b1cdbd2cSJim Jagielski     HandleError( aReqProc );
1327*b1cdbd2cSJim Jagielski }
1328*b1cdbd2cSJim Jagielski 
1329*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
1330*b1cdbd2cSJim Jagielski // UNLOCK (called from SerfLockStore)
1331*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
UNLOCK(SerfLock * pLock)1332*b1cdbd2cSJim Jagielski bool SerfSession::UNLOCK( SerfLock * pLock )
1333*b1cdbd2cSJim Jagielski {
1334*b1cdbd2cSJim Jagielski     osl::Guard< osl::Mutex > theGuard( m_aMutex );
1335*b1cdbd2cSJim Jagielski     rtl::OUString inPath = pLock->getResourcePath();
1336*b1cdbd2cSJim Jagielski 
1337*b1cdbd2cSJim Jagielski     boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) );
1338*b1cdbd2cSJim Jagielski     apr_status_t status = APR_SUCCESS;
1339*b1cdbd2cSJim Jagielski 
1340*b1cdbd2cSJim Jagielski     rtl::OUString   aToken;
1341*b1cdbd2cSJim Jagielski     aToken = pLock->getLock().LockTokens[0];
1342*b1cdbd2cSJim Jagielski 
1343*b1cdbd2cSJim Jagielski     aReqProc->processUnlock( inPath, pLock->getLock(), status);
1344*b1cdbd2cSJim Jagielski 
1345*b1cdbd2cSJim Jagielski     //HandleError will handle the error and throw an exception, if needed
1346*b1cdbd2cSJim Jagielski     HandleError( aReqProc );
1347*b1cdbd2cSJim Jagielski 
1348*b1cdbd2cSJim Jagielski     return true;
1349*b1cdbd2cSJim Jagielski }
1350*b1cdbd2cSJim Jagielski 
1351*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
abort()1352*b1cdbd2cSJim Jagielski void SerfSession::abort()
1353*b1cdbd2cSJim Jagielski     throw ( DAVException )
1354*b1cdbd2cSJim Jagielski {
1355*b1cdbd2cSJim Jagielski     // 11.11.09 (tkr): The following code lines causing crashes if
1356*b1cdbd2cSJim Jagielski     // closing a ongoing connection. It turned out that this existing
1357*b1cdbd2cSJim Jagielski     // solution doesn't work in multi-threading environments.
1358*b1cdbd2cSJim Jagielski     // So I disabled them in 3.2. . Issue #73893# should fix it in OOo 3.3.
1359*b1cdbd2cSJim Jagielski     //if ( m_pHttpSession )
1360*b1cdbd2cSJim Jagielski     //    ne_close_connection( m_pHttpSession );
1361*b1cdbd2cSJim Jagielski }
1362*b1cdbd2cSJim Jagielski 
1363*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
getProxySettings() const1364*b1cdbd2cSJim Jagielski const ucbhelper::InternetProxyServer & SerfSession::getProxySettings() const
1365*b1cdbd2cSJim Jagielski {
1366*b1cdbd2cSJim Jagielski     if ( m_aUri.GetScheme().equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "http" ) ) ||
1367*b1cdbd2cSJim Jagielski          m_aUri.GetScheme().equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "https" ) ) )
1368*b1cdbd2cSJim Jagielski     {
1369*b1cdbd2cSJim Jagielski         return m_rProxyDecider.getProxy( m_aUri.GetScheme(),
1370*b1cdbd2cSJim Jagielski                                          m_aUri.GetHost(),
1371*b1cdbd2cSJim Jagielski                                          m_aUri.GetPort() );
1372*b1cdbd2cSJim Jagielski     }
1373*b1cdbd2cSJim Jagielski     else
1374*b1cdbd2cSJim Jagielski     {
1375*b1cdbd2cSJim Jagielski         // TODO: figure out, if this case can occur
1376*b1cdbd2cSJim Jagielski         return m_rProxyDecider.getProxy( m_aUri.GetScheme(),
1377*b1cdbd2cSJim Jagielski                                          rtl::OUString() /* not used */,
1378*b1cdbd2cSJim Jagielski                                          -1 /* not used */ );
1379*b1cdbd2cSJim Jagielski     }
1380*b1cdbd2cSJim Jagielski }
1381*b1cdbd2cSJim Jagielski 
1382*b1cdbd2cSJim Jagielski /*
1383*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
1384*b1cdbd2cSJim Jagielski namespace {
1385*b1cdbd2cSJim Jagielski 
1386*b1cdbd2cSJim Jagielski bool containsLocktoken( const uno::Sequence< ucb::Lock > & rLocks,
1387*b1cdbd2cSJim Jagielski                         const char * token )
1388*b1cdbd2cSJim Jagielski {
1389*b1cdbd2cSJim Jagielski     for ( sal_Int32 n = 0; n < rLocks.getLength(); ++n )
1390*b1cdbd2cSJim Jagielski     {
1391*b1cdbd2cSJim Jagielski         const uno::Sequence< rtl::OUString > & rTokens
1392*b1cdbd2cSJim Jagielski             = rLocks[ n ].LockTokens;
1393*b1cdbd2cSJim Jagielski         for ( sal_Int32 m = 0; m < rTokens.getLength(); ++m )
1394*b1cdbd2cSJim Jagielski         {
1395*b1cdbd2cSJim Jagielski             if ( rTokens[ m ].equalsAscii( token ) )
1396*b1cdbd2cSJim Jagielski                 return true;
1397*b1cdbd2cSJim Jagielski         }
1398*b1cdbd2cSJim Jagielski     }
1399*b1cdbd2cSJim Jagielski     return false;
1400*b1cdbd2cSJim Jagielski }
1401*b1cdbd2cSJim Jagielski 
1402*b1cdbd2cSJim Jagielski } // namespace
1403*b1cdbd2cSJim Jagielski */
1404*b1cdbd2cSJim Jagielski 
1405*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
1406*b1cdbd2cSJim Jagielski // This method doesn't seem to be used.
1407*b1cdbd2cSJim Jagielski // In any case the default behavior is to ask a lock whith a life of 3 minutes
1408*b1cdbd2cSJim Jagielski // it will then be refreshed automatically (see SerfLockStore class)
1409*b1cdbd2cSJim Jagielski // In case of AOO crash the lock will expire by itself
removeExpiredLocktoken(const rtl::OUString &,const DAVRequestEnvironment &)1410*b1cdbd2cSJim Jagielski bool SerfSession::removeExpiredLocktoken( const rtl::OUString & /*inURL*/,
1411*b1cdbd2cSJim Jagielski                                           const DAVRequestEnvironment & /*rEnv*/ )
1412*b1cdbd2cSJim Jagielski {
1413*b1cdbd2cSJim Jagielski     return true;
1414*b1cdbd2cSJim Jagielski     /*
1415*b1cdbd2cSJim Jagielski     SerfLock * theLock = m_aSerfLockStore.findByUri( inURL );
1416*b1cdbd2cSJim Jagielski     if ( !theLock )
1417*b1cdbd2cSJim Jagielski         return false;
1418*b1cdbd2cSJim Jagielski 
1419*b1cdbd2cSJim Jagielski     // do a lockdiscovery to check whether this lock is still valid.
1420*b1cdbd2cSJim Jagielski     try
1421*b1cdbd2cSJim Jagielski     {
1422*b1cdbd2cSJim Jagielski         // @@@ Alternative: use ne_lock_discover() => less overhead
1423*b1cdbd2cSJim Jagielski 
1424*b1cdbd2cSJim Jagielski         std::vector< DAVResource > aResources;
1425*b1cdbd2cSJim Jagielski         std::vector< rtl::OUString > aPropNames;
1426*b1cdbd2cSJim Jagielski         aPropNames.push_back( DAVProperties::LOCKDISCOVERY );
1427*b1cdbd2cSJim Jagielski 
1428*b1cdbd2cSJim Jagielski         PROPFIND( rEnv.m_aRequestURI, DAVZERO, aPropNames, aResources, rEnv );
1429*b1cdbd2cSJim Jagielski 
1430*b1cdbd2cSJim Jagielski         if ( aResources.size() == 0 )
1431*b1cdbd2cSJim Jagielski             return false;
1432*b1cdbd2cSJim Jagielski 
1433*b1cdbd2cSJim Jagielski         std::vector< DAVPropertyValue >::const_iterator it
1434*b1cdbd2cSJim Jagielski             = aResources[ 0 ].properties.begin();
1435*b1cdbd2cSJim Jagielski         std::vector< DAVPropertyValue >::const_iterator end
1436*b1cdbd2cSJim Jagielski             = aResources[ 0 ].properties.end();
1437*b1cdbd2cSJim Jagielski 
1438*b1cdbd2cSJim Jagielski         while ( it != end )
1439*b1cdbd2cSJim Jagielski         {
1440*b1cdbd2cSJim Jagielski             if ( (*it).Name.equals( DAVProperties::LOCKDISCOVERY ) )
1441*b1cdbd2cSJim Jagielski             {
1442*b1cdbd2cSJim Jagielski                 uno::Sequence< ucb::Lock > aLocks;
1443*b1cdbd2cSJim Jagielski                 if ( !( (*it).Value >>= aLocks ) )
1444*b1cdbd2cSJim Jagielski                     return false;
1445*b1cdbd2cSJim Jagielski 
1446*b1cdbd2cSJim Jagielski                 if ( !containsLocktoken( aLocks, theLock->token ) )
1447*b1cdbd2cSJim Jagielski                 {
1448*b1cdbd2cSJim Jagielski                     // expired!
1449*b1cdbd2cSJim Jagielski                     break;
1450*b1cdbd2cSJim Jagielski                 }
1451*b1cdbd2cSJim Jagielski 
1452*b1cdbd2cSJim Jagielski                 // still valid.
1453*b1cdbd2cSJim Jagielski                 return false;
1454*b1cdbd2cSJim Jagielski             }
1455*b1cdbd2cSJim Jagielski             ++it;
1456*b1cdbd2cSJim Jagielski         }
1457*b1cdbd2cSJim Jagielski 
1458*b1cdbd2cSJim Jagielski         // No lockdiscovery prop in propfind result / locktoken not found
1459*b1cdbd2cSJim Jagielski         // in propfind result -> not locked
1460*b1cdbd2cSJim Jagielski         OSL_TRACE( "SerfSession::removeExpiredLocktoken: Removing "
1461*b1cdbd2cSJim Jagielski                    " expired lock token for %s. token: %s",
1462*b1cdbd2cSJim Jagielski                    rtl::OUStringToOString( inURL,
1463*b1cdbd2cSJim Jagielski                                            RTL_TEXTENCODING_UTF8 ).getStr(),
1464*b1cdbd2cSJim Jagielski                    theLock->token );
1465*b1cdbd2cSJim Jagielski 
1466*b1cdbd2cSJim Jagielski         m_aSerfLockStore.removeLock( theLock );
1467*b1cdbd2cSJim Jagielski         ne_lock_destroy( theLock );
1468*b1cdbd2cSJim Jagielski         return true;
1469*b1cdbd2cSJim Jagielski     }
1470*b1cdbd2cSJim Jagielski     catch ( DAVException const & )
1471*b1cdbd2cSJim Jagielski     {
1472*b1cdbd2cSJim Jagielski     }
1473*b1cdbd2cSJim Jagielski     return false;
1474*b1cdbd2cSJim Jagielski     */
1475*b1cdbd2cSJim Jagielski }
1476*b1cdbd2cSJim Jagielski 
1477*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
1478*b1cdbd2cSJim Jagielski // HandleError
1479*b1cdbd2cSJim Jagielski // Common Error Handler
1480*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
HandleError(boost::shared_ptr<SerfRequestProcessor> rReqProc)1481*b1cdbd2cSJim Jagielski void SerfSession::HandleError( boost::shared_ptr<SerfRequestProcessor> rReqProc )
1482*b1cdbd2cSJim Jagielski     throw ( DAVException )
1483*b1cdbd2cSJim Jagielski {
1484*b1cdbd2cSJim Jagielski     m_aEnv = DAVRequestEnvironment();
1485*b1cdbd2cSJim Jagielski 
1486*b1cdbd2cSJim Jagielski     if ( rReqProc->mpDAVException )
1487*b1cdbd2cSJim Jagielski     {
1488*b1cdbd2cSJim Jagielski         DAVException* mpDAVExp( rReqProc->mpDAVException );
1489*b1cdbd2cSJim Jagielski 
1490*b1cdbd2cSJim Jagielski         serf_connection_reset( getSerfConnection() );
1491*b1cdbd2cSJim Jagielski 
1492*b1cdbd2cSJim Jagielski         if ( mpDAVExp->getStatus() == 413 &&
1493*b1cdbd2cSJim Jagielski              m_bNoOfTransferEncodingSwitches < 2 )
1494*b1cdbd2cSJim Jagielski         {
1495*b1cdbd2cSJim Jagielski             m_bUseChunkedEncoding = !m_bUseChunkedEncoding;
1496*b1cdbd2cSJim Jagielski             ++m_bNoOfTransferEncodingSwitches;
1497*b1cdbd2cSJim Jagielski         }
1498*b1cdbd2cSJim Jagielski 
1499*b1cdbd2cSJim Jagielski         throw DAVException( mpDAVExp->getError(),
1500*b1cdbd2cSJim Jagielski                             mpDAVExp->getData(),
1501*b1cdbd2cSJim Jagielski                             mpDAVExp->getStatus() );
1502*b1cdbd2cSJim Jagielski     }
1503*b1cdbd2cSJim Jagielski 
1504*b1cdbd2cSJim Jagielski     /*
1505*b1cdbd2cSJim Jagielski     // Map error code to DAVException.
1506*b1cdbd2cSJim Jagielski     switch ( nError )
1507*b1cdbd2cSJim Jagielski     {
1508*b1cdbd2cSJim Jagielski         case NE_OK:
1509*b1cdbd2cSJim Jagielski             return;
1510*b1cdbd2cSJim Jagielski 
1511*b1cdbd2cSJim Jagielski         case NE_ERROR:        // Generic error
1512*b1cdbd2cSJim Jagielski         {
1513*b1cdbd2cSJim Jagielski             rtl::OUString aText = rtl::OUString::createFromAscii(
1514*b1cdbd2cSJim Jagielski                 ne_get_error( m_pHttpSession ) );
1515*b1cdbd2cSJim Jagielski 
1516*b1cdbd2cSJim Jagielski             sal_uInt16 code = makeStatusCode( aText );
1517*b1cdbd2cSJim Jagielski 
1518*b1cdbd2cSJim Jagielski             if ( code == SC_LOCKED )
1519*b1cdbd2cSJim Jagielski             {
1520*b1cdbd2cSJim Jagielski                 if ( m_aSerfLockStore.findByUri(
1521*b1cdbd2cSJim Jagielski                          makeAbsoluteURL( inPath ) ) == 0 )
1522*b1cdbd2cSJim Jagielski                 {
1523*b1cdbd2cSJim Jagielski                     // locked by 3rd party
1524*b1cdbd2cSJim Jagielski                     throw DAVException( DAVException::DAV_LOCKED );
1525*b1cdbd2cSJim Jagielski                 }
1526*b1cdbd2cSJim Jagielski                 else
1527*b1cdbd2cSJim Jagielski                 {
1528*b1cdbd2cSJim Jagielski                     // locked by ourself
1529*b1cdbd2cSJim Jagielski                     throw DAVException( DAVException::DAV_LOCKED_SELF );
1530*b1cdbd2cSJim Jagielski                 }
1531*b1cdbd2cSJim Jagielski             }
1532*b1cdbd2cSJim Jagielski 
1533*b1cdbd2cSJim Jagielski             // Special handling for 400 and 412 status codes, which may indicate
1534*b1cdbd2cSJim Jagielski             // that a lock previously obtained by us has been released meanwhile
1535*b1cdbd2cSJim Jagielski             // by the server. Unfortunately, RFC is not clear at this point,
1536*b1cdbd2cSJim Jagielski             // thus server implementations behave different...
1537*b1cdbd2cSJim Jagielski             else if ( code == SC_BAD_REQUEST || code == SC_PRECONDITION_FAILED )
1538*b1cdbd2cSJim Jagielski             {
1539*b1cdbd2cSJim Jagielski                 if ( removeExpiredLocktoken( makeAbsoluteURL( inPath ), rEnv ) )
1540*b1cdbd2cSJim Jagielski                     throw DAVException( DAVException::DAV_LOCK_EXPIRED );
1541*b1cdbd2cSJim Jagielski             }
1542*b1cdbd2cSJim Jagielski 
1543*b1cdbd2cSJim Jagielski             throw DAVException( DAVException::DAV_HTTP_ERROR, aText, code );
1544*b1cdbd2cSJim Jagielski         }
1545*b1cdbd2cSJim Jagielski         case NE_LOOKUP:       // Name lookup failed.
1546*b1cdbd2cSJim Jagielski             throw DAVException( DAVException::DAV_HTTP_LOOKUP,
1547*b1cdbd2cSJim Jagielski                                 SerfUri::makeConnectionEndPointString(
1548*b1cdbd2cSJim Jagielski                                     m_aHostName, m_nPort ) );
1549*b1cdbd2cSJim Jagielski 
1550*b1cdbd2cSJim Jagielski         case NE_AUTH:         // User authentication failed on server
1551*b1cdbd2cSJim Jagielski             throw DAVException( DAVException::DAV_HTTP_AUTH,
1552*b1cdbd2cSJim Jagielski                                 SerfUri::makeConnectionEndPointString(
1553*b1cdbd2cSJim Jagielski                                     m_aHostName, m_nPort ) );
1554*b1cdbd2cSJim Jagielski 
1555*b1cdbd2cSJim Jagielski         case NE_PROXYAUTH:    // User authentication failed on proxy
1556*b1cdbd2cSJim Jagielski             throw DAVException( DAVException::DAV_HTTP_AUTHPROXY,
1557*b1cdbd2cSJim Jagielski                                 SerfUri::makeConnectionEndPointString(
1558*b1cdbd2cSJim Jagielski                                     m_aProxyName, m_nProxyPort ) );
1559*b1cdbd2cSJim Jagielski 
1560*b1cdbd2cSJim Jagielski         case NE_CONNECT:      // Could not connect to server
1561*b1cdbd2cSJim Jagielski             throw DAVException( DAVException::DAV_HTTP_CONNECT,
1562*b1cdbd2cSJim Jagielski                                 SerfUri::makeConnectionEndPointString(
1563*b1cdbd2cSJim Jagielski                                     m_aHostName, m_nPort ) );
1564*b1cdbd2cSJim Jagielski 
1565*b1cdbd2cSJim Jagielski         case NE_TIMEOUT:      // Connection timed out
1566*b1cdbd2cSJim Jagielski             throw DAVException( DAVException::DAV_HTTP_TIMEOUT,
1567*b1cdbd2cSJim Jagielski                                 SerfUri::makeConnectionEndPointString(
1568*b1cdbd2cSJim Jagielski                                     m_aHostName, m_nPort ) );
1569*b1cdbd2cSJim Jagielski 
1570*b1cdbd2cSJim Jagielski         case NE_FAILED:       // The precondition failed
1571*b1cdbd2cSJim Jagielski             throw DAVException( DAVException::DAV_HTTP_FAILED,
1572*b1cdbd2cSJim Jagielski                                 SerfUri::makeConnectionEndPointString(
1573*b1cdbd2cSJim Jagielski                                     m_aHostName, m_nPort ) );
1574*b1cdbd2cSJim Jagielski 
1575*b1cdbd2cSJim Jagielski         case NE_RETRY:        // Retry request (ne_end_request ONLY)
1576*b1cdbd2cSJim Jagielski             throw DAVException( DAVException::DAV_HTTP_RETRY,
1577*b1cdbd2cSJim Jagielski                                 SerfUri::makeConnectionEndPointString(
1578*b1cdbd2cSJim Jagielski                                     m_aHostName, m_nPort ) );
1579*b1cdbd2cSJim Jagielski 
1580*b1cdbd2cSJim Jagielski         case NE_REDIRECT:
1581*b1cdbd2cSJim Jagielski         {
1582*b1cdbd2cSJim Jagielski             SerfUri aUri( ne_redirect_location( m_pHttpSession ) );
1583*b1cdbd2cSJim Jagielski             throw DAVException(
1584*b1cdbd2cSJim Jagielski                 DAVException::DAV_HTTP_REDIRECT, aUri.GetURI() );
1585*b1cdbd2cSJim Jagielski         }
1586*b1cdbd2cSJim Jagielski         default:
1587*b1cdbd2cSJim Jagielski         {
1588*b1cdbd2cSJim Jagielski             OSL_TRACE( "SerfSession::HandleError : Unknown Serf error code!" );
1589*b1cdbd2cSJim Jagielski             throw DAVException( DAVException::DAV_HTTP_ERROR,
1590*b1cdbd2cSJim Jagielski                                 rtl::OUString::createFromAscii(
1591*b1cdbd2cSJim Jagielski                                     ne_get_error( m_pHttpSession ) ) );
1592*b1cdbd2cSJim Jagielski         }
1593*b1cdbd2cSJim Jagielski     }
1594*b1cdbd2cSJim Jagielski     */
1595*b1cdbd2cSJim Jagielski }
1596*b1cdbd2cSJim Jagielski 
1597*b1cdbd2cSJim Jagielski // -------------------------------------------------------------------
1598*b1cdbd2cSJim Jagielski // static
1599*b1cdbd2cSJim Jagielski bool
getDataFromInputStream(const uno::Reference<io::XInputStream> & xStream,uno::Sequence<sal_Int8> & rData,bool bAppendTrailingZeroByte)1600*b1cdbd2cSJim Jagielski SerfSession::getDataFromInputStream(
1601*b1cdbd2cSJim Jagielski     const uno::Reference< io::XInputStream > & xStream,
1602*b1cdbd2cSJim Jagielski     uno::Sequence< sal_Int8 > & rData,
1603*b1cdbd2cSJim Jagielski     bool bAppendTrailingZeroByte )
1604*b1cdbd2cSJim Jagielski {
1605*b1cdbd2cSJim Jagielski     if ( xStream.is() )
1606*b1cdbd2cSJim Jagielski     {
1607*b1cdbd2cSJim Jagielski         uno::Reference< io::XSeekable > xSeekable( xStream, uno::UNO_QUERY );
1608*b1cdbd2cSJim Jagielski         if ( xSeekable.is() )
1609*b1cdbd2cSJim Jagielski         {
1610*b1cdbd2cSJim Jagielski             try
1611*b1cdbd2cSJim Jagielski             {
1612*b1cdbd2cSJim Jagielski                 sal_Int32 nSize
1613*b1cdbd2cSJim Jagielski                     = sal::static_int_cast<sal_Int32>(xSeekable->getLength());
1614*b1cdbd2cSJim Jagielski                 sal_Int32 nRead
1615*b1cdbd2cSJim Jagielski                     = xStream->readBytes( rData, nSize );
1616*b1cdbd2cSJim Jagielski 
1617*b1cdbd2cSJim Jagielski                 if ( nRead == nSize )
1618*b1cdbd2cSJim Jagielski                 {
1619*b1cdbd2cSJim Jagielski                     if ( bAppendTrailingZeroByte )
1620*b1cdbd2cSJim Jagielski                     {
1621*b1cdbd2cSJim Jagielski                         rData.realloc( nSize + 1 );
1622*b1cdbd2cSJim Jagielski                         rData[ nSize ] = sal_Int8( 0 );
1623*b1cdbd2cSJim Jagielski                     }
1624*b1cdbd2cSJim Jagielski                     return true;
1625*b1cdbd2cSJim Jagielski                 }
1626*b1cdbd2cSJim Jagielski             }
1627*b1cdbd2cSJim Jagielski             catch ( io::NotConnectedException const & )
1628*b1cdbd2cSJim Jagielski             {
1629*b1cdbd2cSJim Jagielski                 // readBytes
1630*b1cdbd2cSJim Jagielski             }
1631*b1cdbd2cSJim Jagielski             catch ( io::BufferSizeExceededException const & )
1632*b1cdbd2cSJim Jagielski             {
1633*b1cdbd2cSJim Jagielski                 // readBytes
1634*b1cdbd2cSJim Jagielski             }
1635*b1cdbd2cSJim Jagielski             catch ( io::IOException const & )
1636*b1cdbd2cSJim Jagielski             {
1637*b1cdbd2cSJim Jagielski                 // getLength, readBytes
1638*b1cdbd2cSJim Jagielski             }
1639*b1cdbd2cSJim Jagielski         }
1640*b1cdbd2cSJim Jagielski         else
1641*b1cdbd2cSJim Jagielski         {
1642*b1cdbd2cSJim Jagielski             try
1643*b1cdbd2cSJim Jagielski             {
1644*b1cdbd2cSJim Jagielski                 uno::Sequence< sal_Int8 > aBuffer;
1645*b1cdbd2cSJim Jagielski                 sal_Int32 nPos = 0;
1646*b1cdbd2cSJim Jagielski 
1647*b1cdbd2cSJim Jagielski                 sal_Int32 nRead = xStream->readSomeBytes( aBuffer, 65536 );
1648*b1cdbd2cSJim Jagielski                 while ( nRead > 0 )
1649*b1cdbd2cSJim Jagielski                 {
1650*b1cdbd2cSJim Jagielski                     if ( rData.getLength() < ( nPos + nRead ) )
1651*b1cdbd2cSJim Jagielski                         rData.realloc( nPos + nRead );
1652*b1cdbd2cSJim Jagielski 
1653*b1cdbd2cSJim Jagielski                     aBuffer.realloc( nRead );
1654*b1cdbd2cSJim Jagielski                     rtl_copyMemory( (void*)( rData.getArray() + nPos ),
1655*b1cdbd2cSJim Jagielski                                     (const void*)aBuffer.getConstArray(),
1656*b1cdbd2cSJim Jagielski                                     nRead );
1657*b1cdbd2cSJim Jagielski                     nPos += nRead;
1658*b1cdbd2cSJim Jagielski 
1659*b1cdbd2cSJim Jagielski                     aBuffer.realloc( 0 );
1660*b1cdbd2cSJim Jagielski                     nRead = xStream->readSomeBytes( aBuffer, 65536 );
1661*b1cdbd2cSJim Jagielski                 }
1662*b1cdbd2cSJim Jagielski 
1663*b1cdbd2cSJim Jagielski                 if ( bAppendTrailingZeroByte )
1664*b1cdbd2cSJim Jagielski                 {
1665*b1cdbd2cSJim Jagielski                     rData.realloc( nPos + 1 );
1666*b1cdbd2cSJim Jagielski                     rData[ nPos ] = sal_Int8( 0 );
1667*b1cdbd2cSJim Jagielski                 }
1668*b1cdbd2cSJim Jagielski                 return true;
1669*b1cdbd2cSJim Jagielski             }
1670*b1cdbd2cSJim Jagielski             catch ( io::NotConnectedException const & )
1671*b1cdbd2cSJim Jagielski             {
1672*b1cdbd2cSJim Jagielski                 // readBytes
1673*b1cdbd2cSJim Jagielski             }
1674*b1cdbd2cSJim Jagielski             catch ( io::BufferSizeExceededException const & )
1675*b1cdbd2cSJim Jagielski             {
1676*b1cdbd2cSJim Jagielski                 // readBytes
1677*b1cdbd2cSJim Jagielski             }
1678*b1cdbd2cSJim Jagielski             catch ( io::IOException const & )
1679*b1cdbd2cSJim Jagielski             {
1680*b1cdbd2cSJim Jagielski                 // readBytes
1681*b1cdbd2cSJim Jagielski             }
1682*b1cdbd2cSJim Jagielski         }
1683*b1cdbd2cSJim Jagielski     }
1684*b1cdbd2cSJim Jagielski     return false;
1685*b1cdbd2cSJim Jagielski }
1686*b1cdbd2cSJim Jagielski 
1687*b1cdbd2cSJim Jagielski // ---------------------------------------------------------------------
1688*b1cdbd2cSJim Jagielski sal_Bool
isDomainMatch(rtl::OUString certHostName)1689*b1cdbd2cSJim Jagielski SerfSession::isDomainMatch( rtl::OUString certHostName )
1690*b1cdbd2cSJim Jagielski {
1691*b1cdbd2cSJim Jagielski     rtl::OUString hostName = getHostName();
1692*b1cdbd2cSJim Jagielski 
1693*b1cdbd2cSJim Jagielski     if (hostName.equalsIgnoreAsciiCase( certHostName ) )
1694*b1cdbd2cSJim Jagielski         return sal_True;
1695*b1cdbd2cSJim Jagielski 
1696*b1cdbd2cSJim Jagielski     if ( 0 == certHostName.indexOf( rtl::OUString::createFromAscii( "*" ) ) &&
1697*b1cdbd2cSJim Jagielski          hostName.getLength() >= certHostName.getLength()  )
1698*b1cdbd2cSJim Jagielski     {
1699*b1cdbd2cSJim Jagielski         rtl::OUString cmpStr = certHostName.copy( 1 );
1700*b1cdbd2cSJim Jagielski 
1701*b1cdbd2cSJim Jagielski         if ( hostName.matchIgnoreAsciiCase(
1702*b1cdbd2cSJim Jagielski                 cmpStr, hostName.getLength() -  cmpStr.getLength() ) )
1703*b1cdbd2cSJim Jagielski             return sal_True;
1704*b1cdbd2cSJim Jagielski     }
1705*b1cdbd2cSJim Jagielski     return sal_False;
1706*b1cdbd2cSJim Jagielski }
1707