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