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