fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / ucb / source / ucp / webdav / SerfSession.cxx
blob33c54281fb1085500c81b40d95e6252b07bf90b1
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <hash_map>
21 #include <vector>
22 #include <string.h>
23 #include <rtl/string.h>
24 #include "comphelper/processfactory.hxx"
25 #include "comphelper/sequence.hxx"
26 #include "ucbhelper/simplecertificatevalidationrequest.hxx"
28 #include <AprEnv.hxx>
29 #include <apr_strings.h>
31 #include "DAVAuthListener.hxx"
32 #include <SerfTypes.hxx>
33 #include <SerfSession.hxx>
34 #include <SerfUri.hxx>
35 #include <SerfRequestProcessor.hxx>
36 #include <SerfCallbacks.hxx>
37 #include <SerfInputStream.hxx>
38 #include <UCBDeadPropertyValue.hxx>
40 #include <com/sun/star/xml/crypto/XSecurityEnvironment.hpp>
41 #include <com/sun/star/security/XCertificate.hpp>
42 #include <com/sun/star/security/CertificateValidity.hpp>
43 #include <com/sun/star/security/CertificateContainerStatus.hpp>
44 #include <com/sun/star/security/CertificateContainer.hpp>
45 #include <com/sun/star/security/XCertificateContainer.hpp>
46 #include <com/sun/star/ucb/Lock.hpp>
47 #include <com/sun/star/xml/crypto/XSEInitializer.hpp>
49 using namespace com::sun::star;
50 using namespace http_dav_ucp;
53 // -------------------------------------------------------------------
54 // static members!
55 //SerfLockStore SerfSession::m_aSerfLockStore;
57 // -------------------------------------------------------------------
58 // Constructor
59 // -------------------------------------------------------------------
60 SerfSession::SerfSession(
61 const rtl::Reference< DAVSessionFactory > & rSessionFactory,
62 const OUString& inUri,
63 const ucbhelper::InternetProxyDecider & rProxyDecider )
64 throw ( DAVException )
65 : DAVSession( rSessionFactory )
66 , m_aMutex()
67 , m_aUri( inUri )
68 , m_aProxyName()
69 , m_nProxyPort( 0 )
70 , m_pSerfConnection( 0 )
71 , m_pSerfContext( 0 )
72 , m_bIsHeadRequestInProgress( false )
73 , m_bUseChunkedEncoding( false )
74 , m_bNoOfTransferEncodingSwitches( 0 )
75 , m_rProxyDecider( rProxyDecider )
76 , m_aEnv()
78 m_pSerfContext = serf_context_create( getAprPool() );
80 m_pSerfBucket_Alloc = serf_bucket_allocator_create( getAprPool(), NULL, NULL );
83 // -------------------------------------------------------------------
84 // Destructor
85 // -------------------------------------------------------------------
86 SerfSession::~SerfSession( )
88 if ( m_pSerfConnection )
90 serf_connection_close( m_pSerfConnection );
91 m_pSerfConnection = 0;
95 // -------------------------------------------------------------------
96 void SerfSession::Init( const DAVRequestEnvironment & rEnv )
97 throw ( DAVException )
99 osl::Guard< osl::Mutex > theGuard( m_aMutex );
100 m_aEnv = rEnv;
101 Init();
104 // -------------------------------------------------------------------
105 void SerfSession::Init()
106 throw ( DAVException )
108 osl::Guard< osl::Mutex > theGuard( m_aMutex );
110 bool bCreateNewSession = false;
112 if ( m_pSerfConnection == 0 )
114 const ucbhelper::InternetProxyServer & rProxyCfg = getProxySettings();
116 m_aProxyName = rProxyCfg.aName;
117 m_nProxyPort = rProxyCfg.nPort;
119 // Not yet initialized. Create new session.
120 bCreateNewSession = true;
122 else
124 const ucbhelper::InternetProxyServer & rProxyCfg = getProxySettings();
126 if ( ( rProxyCfg.aName != m_aProxyName )
127 || ( rProxyCfg.nPort != m_nProxyPort ) )
129 m_aProxyName = rProxyCfg.aName;
130 m_nProxyPort = rProxyCfg.nPort;
132 // new session needed, destroy old first
133 serf_connection_close( m_pSerfConnection );
134 m_pSerfConnection = 0;
135 bCreateNewSession = true;
139 if ( bCreateNewSession )
141 // TODO - close_connection callback
142 apr_status_t status = serf_connection_create2( &m_pSerfConnection,
143 m_pSerfContext,
144 *(m_aUri.getAprUri()),
145 Serf_ConnectSetup, this,
146 0 /* close connection callback */, 0 /* close connection baton */,
147 getAprPool() );
149 if ( m_pSerfConnection == 0 ||status != APR_SUCCESS )
151 throw DAVException( DAVException::DAV_SESSION_CREATE,
152 SerfUri::makeConnectionEndPointString( m_aUri.GetHost(), m_aUri.GetPort() ) );
155 // Register the session with the lock store
156 // m_aSerfLockStore.registerSession( m_pSerfConnection );
158 if ( m_aProxyName.getLength() )
160 apr_sockaddr_t *proxy_address = NULL;
161 const apr_status_t status = apr_sockaddr_info_get( &proxy_address,
162 OUStringToOString( m_aProxyName, RTL_TEXTENCODING_UTF8 ),
163 APR_UNSPEC,
164 static_cast<apr_port_t>(m_nProxyPort),
165 0, getAprPool() );
167 if ( status != APR_SUCCESS )
169 throw DAVException( DAVException::DAV_SESSION_CREATE,
170 SerfUri::makeConnectionEndPointString( m_aUri.GetHost(), m_aUri.GetPort() ) );
173 serf_config_proxy( m_pSerfContext, proxy_address );
177 serf_config_credentials_callback( m_pSerfContext, Serf_Credentials );
179 m_bUseChunkedEncoding = isSSLNeeded();
183 apr_pool_t* SerfSession::getAprPool()
185 return apr_environment::AprEnv::getAprEnv()->getAprPool();
188 serf_bucket_alloc_t* SerfSession::getSerfBktAlloc()
190 return m_pSerfBucket_Alloc;
193 serf_context_t* SerfSession::getSerfContext()
195 return m_pSerfContext;
198 SerfConnection* SerfSession::getSerfConnection()
200 return m_pSerfConnection;
203 bool SerfSession::isHeadRequestInProgress()
205 return m_bIsHeadRequestInProgress;
208 bool SerfSession::isSSLNeeded()
210 return m_aUri.GetScheme().equalsIgnoreAsciiCase( OUString( "https" ) );
213 char* SerfSession::getHostinfo()
215 return m_aUri.getAprUri()->hostinfo;
219 // -------------------------------------------------------------------
220 // virtual
221 sal_Bool SerfSession::CanUse( const OUString & inUri )
225 SerfUri theUri( inUri );
226 if ( ( theUri.GetPort() == m_aUri.GetPort() ) &&
227 ( theUri.GetHost() == m_aUri.GetHost() ) &&
228 ( theUri.GetScheme() == m_aUri.GetScheme() ) )
230 return sal_True;
233 catch ( DAVException const & )
235 return sal_False;
237 return sal_False;
240 // -------------------------------------------------------------------
241 // virtual
242 sal_Bool SerfSession::UsesProxy()
244 Init();
245 return ( m_aProxyName.getLength() > 0 );
248 apr_status_t SerfSession::setupSerfConnection( apr_socket_t * inAprSocket,
249 serf_bucket_t **outSerfInputBucket,
250 serf_bucket_t **outSerfOutputBucket,
251 apr_pool_t* /*inAprPool*/ )
253 serf_bucket_t *tmpInputBkt;
254 tmpInputBkt = serf_context_bucket_socket_create( getSerfContext(),
255 inAprSocket,
256 getSerfBktAlloc() );
258 if ( isSSLNeeded() )
260 tmpInputBkt = serf_bucket_ssl_decrypt_create( tmpInputBkt,
262 getSerfBktAlloc() );
263 /** Set the callback that is called to authenticate the
264 certifcate (chain).
266 serf_ssl_server_cert_chain_callback_set(
267 serf_bucket_ssl_decrypt_context_get(tmpInputBkt),
268 Serf_CertificateChainValidation,
269 this);
270 serf_ssl_set_hostname( serf_bucket_ssl_decrypt_context_get( tmpInputBkt ),
271 getHostinfo() );
273 *outSerfOutputBucket = serf_bucket_ssl_encrypt_create( *outSerfOutputBucket,
274 serf_bucket_ssl_decrypt_context_get( tmpInputBkt ),
275 getSerfBktAlloc() );
278 *outSerfInputBucket = tmpInputBkt;
280 return APR_SUCCESS;
283 apr_status_t SerfSession::provideSerfCredentials( bool bGiveProvidedCredentialsASecondTry,
284 char ** outUsername,
285 char ** outPassword,
286 serf_request_t * /*inRequest*/,
287 int /*inCode*/,
288 const char *inAuthProtocol,
289 const char *inRealm,
290 apr_pool_t *inAprPool )
292 DAVAuthListener * pListener = getRequestEnvironment().m_xAuthListener.get();
293 if ( !pListener )
295 // abort
296 return SERF_ERROR_AUTHN_FAILED;
299 OUString theUserName;
300 OUString thePassWord;
303 SerfUri uri( getRequestEnvironment().m_aRequestURI );
304 OUString aUserInfo( uri.GetUserInfo() );
305 if ( aUserInfo.getLength() )
307 sal_Int32 nPos = aUserInfo.indexOf( '@' );
308 if ( nPos == -1 )
310 theUserName = aUserInfo;
312 else
314 theUserName = aUserInfo.copy( 0, nPos );
315 thePassWord = aUserInfo.copy( nPos + 1 );
319 catch ( DAVException const & )
321 // abort
322 return SERF_ERROR_AUTHN_FAILED;
325 const bool bCanUseSystemCreds = ( ( strcasecmp( inAuthProtocol, "NTLM" ) == 0 ) ||
326 ( strcasecmp( inAuthProtocol, "Negotiate" ) == 0 ) );
328 int theRetVal = pListener->authenticate( OUString::createFromAscii( inRealm ),
329 getHostName(),
330 theUserName,
331 thePassWord,
332 bCanUseSystemCreds,
333 bGiveProvidedCredentialsASecondTry ? sal_False : sal_True );
335 if ( theRetVal == 0 )
337 *outUsername = apr_pstrdup( inAprPool, OUStringToOString( theUserName, RTL_TEXTENCODING_UTF8 ) );
338 *outPassword = apr_pstrdup( inAprPool, OUStringToOString( thePassWord, RTL_TEXTENCODING_UTF8 ) );
341 return theRetVal != 0 ? SERF_ERROR_AUTHN_FAILED : APR_SUCCESS;
344 namespace {
345 // -------------------------------------------------------------------
346 // Helper function
347 OUString GetHostnamePart( const OUString& _rRawString )
349 OUString sPart;
350 OUString sPartId = OUString::createFromAscii( "CN=" );
351 sal_Int32 nContStart = _rRawString.indexOf( sPartId );
352 if ( nContStart != -1 )
354 nContStart = nContStart + sPartId.getLength();
355 sal_Int32 nContEnd
356 = _rRawString.indexOf( sal_Unicode( ',' ), nContStart );
357 sPart = _rRawString.copy( nContStart, nContEnd - nContStart );
359 return sPart;
361 } // namespace
364 apr_status_t SerfSession::verifySerfCertificateChain (
365 int,
366 const char** pCertificateChainBase64Encoded,
367 int nCertificateChainLength)
369 // Check arguments.
370 if (pCertificateChainBase64Encoded == NULL || nCertificateChainLength<=0)
372 OSL_ASSERT(pCertificateChainBase64Encoded != NULL);
373 OSL_ASSERT(nCertificateChainLength>0);
374 return SERF_SSL_CERT_UNKNOWN_FAILURE;
377 // Create some crypto objects to decode and handle the base64
378 // encoded certificate chain.
379 uno::Reference< xml::crypto::XSEInitializer > xSEInitializer;
380 uno::Reference< security::XCertificateContainer > xCertificateContainer;
381 uno::Reference< xml::crypto::XXMLSecurityContext > xSecurityContext;
382 uno::Reference< xml::crypto::XSecurityEnvironment > xSecurityEnv;
385 // Create a certificate container.
386 xCertificateContainer = security::CertificateContainer::create( comphelper::getComponentContext(getMSF()) );
388 xSEInitializer = uno::Reference< xml::crypto::XSEInitializer >(
389 getMSF()->createInstance(
390 OUString::createFromAscii( "com.sun.star.xml.crypto.SEInitializer" ) ),
391 uno::UNO_QUERY_THROW);
393 xSecurityContext = xSEInitializer->createSecurityContext( OUString() );
394 if (xSecurityContext.is())
395 xSecurityEnv = xSecurityContext->getSecurityEnvironment();
397 if ( ! xSecurityContext.is() || ! xSecurityEnv.is())
399 // Do we have to dispose xSEInitializer or xCertificateContainer?
400 return SERF_SSL_CERT_UNKNOWN_FAILURE;
403 catch ( uno::Exception const &)
405 return SERF_SSL_CERT_UNKNOWN_FAILURE;
408 // Decode the server certificate.
409 uno::Reference< security::XCertificate > xServerCertificate(
410 xSecurityEnv->createCertificateFromAscii(
411 OUString::createFromAscii(pCertificateChainBase64Encoded[0])));
412 if ( ! xServerCertificate.is())
413 return SERF_SSL_CERT_UNKNOWN_FAILURE;
415 // Get the subject from the server certificate.
416 OUString sServerCertificateSubject (xServerCertificate->getSubjectName());
417 sal_Int32 nIndex = 0;
418 while (nIndex >= 0)
420 const OUString sToken (sServerCertificateSubject.getToken(0, ',', nIndex));
421 if (sToken.startsWith("CN="))
423 sServerCertificateSubject = sToken.copy(3);
424 break;
426 else if (sToken.startsWith(" CN="))
428 sServerCertificateSubject = sToken.copy(4);
429 break;
433 // When the certificate container already contains a (trusted)
434 // entry for the server then we do not have to authenticate any
435 // certificate.
436 const security::CertificateContainerStatus eStatus (
437 xCertificateContainer->hasCertificate(
438 getHostName(), sServerCertificateSubject ) );
439 if (eStatus != security::CertificateContainerStatus_NOCERT)
441 return eStatus == security::CertificateContainerStatus_TRUSTED
442 ? APR_SUCCESS
443 : SERF_SSL_CERT_UNKNOWN_FAILURE;
446 // The shortcut failed, so try to verify the whole chain. This is
447 // done outside the isDomainMatch() block because the result is
448 // used by the interaction handler.
449 std::vector< uno::Reference< security::XCertificate > > aChain;
450 for (int nIndex=1; nIndex<nCertificateChainLength; ++nIndex)
452 uno::Reference< security::XCertificate > xCertificate(
453 xSecurityEnv->createCertificateFromAscii(
454 OUString::createFromAscii(pCertificateChainBase64Encoded[nIndex])));
455 if ( ! xCertificate.is())
456 return SERF_SSL_CERT_UNKNOWN_FAILURE;
457 aChain.push_back(xCertificate);
459 const sal_Int64 nVerificationResult (xSecurityEnv->verifyCertificate(
460 xServerCertificate,
461 ::comphelper::containerToSequence(aChain)));
463 // When the certificate matches the host name then we can use the
464 // result of the verification.
465 if (isDomainMatch(sServerCertificateSubject))
468 if (nVerificationResult == 0)
470 // Certificate (chain) is valid.
471 xCertificateContainer->addCertificate(getHostName(), sServerCertificateSubject, sal_True);
472 return APR_SUCCESS;
474 else if ((nVerificationResult & security::CertificateValidity::CHAIN_INCOMPLETE) != 0)
476 // We do not have enough information for verification,
477 // neither automatically (as we just discovered) nor
478 // manually (so there is no point in showing any dialog.)
479 return SERF_SSL_CERT_UNKNOWN_FAILURE;
481 else if ((nVerificationResult &
482 (security::CertificateValidity::INVALID | security::CertificateValidity::REVOKED)) != 0)
484 // Certificate (chain) is invalid.
485 xCertificateContainer->addCertificate(getHostName(), sServerCertificateSubject, sal_False);
486 return SERF_SSL_CERT_UNKNOWN_FAILURE;
488 else
490 // For all other we have to ask the user.
494 // We have not been able to automatically verify (or falsify) the
495 // certificate chain. To resolve this we have to ask the user.
496 const uno::Reference< ucb::XCommandEnvironment > xEnv( getRequestEnvironment().m_xEnv );
497 if ( xEnv.is() )
499 uno::Reference< task::XInteractionHandler > xIH( xEnv->getInteractionHandler() );
500 if ( xIH.is() )
502 rtl::Reference< ucbhelper::SimpleCertificateValidationRequest >
503 xRequest( new ucbhelper::SimpleCertificateValidationRequest(
504 static_cast<sal_Int32>(nVerificationResult), xServerCertificate, getHostName() ) );
505 xIH->handle( xRequest.get() );
507 rtl::Reference< ucbhelper::InteractionContinuation > xSelection
508 = xRequest->getSelection();
510 if ( xSelection.is() )
512 uno::Reference< task::XInteractionApprove > xApprove(
513 xSelection.get(), uno::UNO_QUERY );
514 if ( xApprove.is() )
516 xCertificateContainer->addCertificate( getHostName(), sServerCertificateSubject, sal_True );
517 return APR_SUCCESS;
519 else
521 // Don't trust cert
522 xCertificateContainer->addCertificate( getHostName(), sServerCertificateSubject, sal_False );
523 return SERF_SSL_CERT_UNKNOWN_FAILURE;
527 else
529 // Don't trust cert
530 xCertificateContainer->addCertificate( getHostName(), sServerCertificateSubject, sal_False );
531 return SERF_SSL_CERT_UNKNOWN_FAILURE;
535 return SERF_SSL_CERT_UNKNOWN_FAILURE;
538 serf_bucket_t* SerfSession::acceptSerfResponse( serf_request_t * inSerfRequest,
539 serf_bucket_t * inSerfStreamBucket,
540 apr_pool_t* /*inAprPool*/ )
542 // get the per-request bucket allocator
543 serf_bucket_alloc_t* SerfBktAlloc = serf_request_get_alloc( inSerfRequest );
545 // create a barrier bucket so the response doesn't eat us!
546 serf_bucket_t *responseBkt = serf_bucket_barrier_create( inSerfStreamBucket,
547 SerfBktAlloc );
549 // create response bucket
550 responseBkt = serf_bucket_response_create( responseBkt,
551 SerfBktAlloc );
553 if ( isHeadRequestInProgress() )
555 // advise the response bucket that this was from a HEAD request and that it should not expect to see a response body.
556 serf_bucket_response_set_head( responseBkt );
559 return responseBkt;
562 SerfRequestProcessor* SerfSession::createReqProc( const OUString & inPath )
564 return new SerfRequestProcessor( *this,
565 inPath,
566 m_bUseChunkedEncoding );
569 // -------------------------------------------------------------------
570 // PROPFIND - allprop & named
571 // -------------------------------------------------------------------
572 void SerfSession::PROPFIND( const OUString & inPath,
573 const Depth inDepth,
574 const std::vector< OUString > & inPropNames,
575 std::vector< DAVResource > & ioResources,
576 const DAVRequestEnvironment & rEnv )
577 throw ( DAVException )
579 osl::Guard< osl::Mutex > theGuard( m_aMutex );
581 Init( rEnv );
583 apr_status_t status = APR_SUCCESS;
584 boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) );
585 aReqProc->processPropFind( inDepth,
586 inPropNames,
587 ioResources,
588 status );
590 if ( status == APR_SUCCESS &&
591 aReqProc->mpDAVException == 0 &&
592 ioResources.empty() )
594 m_aEnv = DAVRequestEnvironment();
595 throw DAVException( DAVException::DAV_HTTP_ERROR, inPath, (sal_uInt16)APR_EGENERAL );
597 HandleError( aReqProc );
600 // -------------------------------------------------------------------
601 // PROPFIND - propnames
602 // -------------------------------------------------------------------
603 void SerfSession::PROPFIND( const OUString & inPath,
604 const Depth inDepth,
605 std::vector< DAVResourceInfo > & ioResInfo,
606 const DAVRequestEnvironment & rEnv )
607 throw( DAVException )
609 osl::Guard< osl::Mutex > theGuard( m_aMutex );
611 Init( rEnv );
613 apr_status_t status = APR_SUCCESS;
614 boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) );
615 aReqProc->processPropFind( inDepth,
616 ioResInfo,
617 status );
619 if ( status == APR_SUCCESS &&
620 aReqProc->mpDAVException == 0 &&
621 ioResInfo.empty() )
623 m_aEnv = DAVRequestEnvironment();
624 throw DAVException( DAVException::DAV_HTTP_ERROR, inPath, (sal_uInt16)APR_EGENERAL );
626 HandleError( aReqProc );
629 // -------------------------------------------------------------------
630 // PROPPATCH
631 // -------------------------------------------------------------------
632 void SerfSession::PROPPATCH( const OUString & inPath,
633 const std::vector< ProppatchValue > & inValues,
634 const DAVRequestEnvironment & rEnv )
635 throw( DAVException )
637 osl::Guard< osl::Mutex > theGuard( m_aMutex );
639 Init( rEnv );
641 apr_status_t status = APR_SUCCESS;
642 boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) );
643 aReqProc->processPropPatch( inValues,
644 status );
646 HandleError( aReqProc );
649 // -------------------------------------------------------------------
650 // HEAD
651 // -------------------------------------------------------------------
652 void SerfSession::HEAD( const OUString & inPath,
653 const std::vector< OUString > & inHeaderNames,
654 DAVResource & ioResource,
655 const DAVRequestEnvironment & rEnv )
656 throw( DAVException )
658 osl::Guard< osl::Mutex > theGuard( m_aMutex );
660 Init( rEnv );
662 m_bIsHeadRequestInProgress = true;
664 boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) );
665 ioResource.uri = inPath;
666 ioResource.properties.clear();
667 apr_status_t status = APR_SUCCESS;
668 aReqProc->processHead( inHeaderNames,
669 ioResource,
670 status );
672 m_bIsHeadRequestInProgress = false;
674 HandleError( aReqProc );
677 // -------------------------------------------------------------------
678 // GET
679 // -------------------------------------------------------------------
680 uno::Reference< io::XInputStream >
681 SerfSession::GET( const OUString & inPath,
682 const DAVRequestEnvironment & rEnv )
683 throw ( DAVException )
685 osl::Guard< osl::Mutex > theGuard( m_aMutex );
687 Init( rEnv );
689 uno::Reference< SerfInputStream > xInputStream( new SerfInputStream );
690 apr_status_t status = APR_SUCCESS;
691 boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) );
692 aReqProc->processGet( xInputStream,
693 status );
695 HandleError( aReqProc );
697 return uno::Reference< io::XInputStream >( xInputStream.get() );
700 // -------------------------------------------------------------------
701 // GET
702 // -------------------------------------------------------------------
703 void SerfSession::GET( const OUString & inPath,
704 uno::Reference< io::XOutputStream > & ioOutputStream,
705 const DAVRequestEnvironment & rEnv )
706 throw ( DAVException )
708 osl::Guard< osl::Mutex > theGuard( m_aMutex );
710 Init( rEnv );
712 apr_status_t status = APR_SUCCESS;
713 boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) );
714 aReqProc->processGet( ioOutputStream,
715 status );
717 HandleError( aReqProc );
720 // -------------------------------------------------------------------
721 // GET
722 // -------------------------------------------------------------------
723 uno::Reference< io::XInputStream >
724 SerfSession::GET( const OUString & inPath,
725 const std::vector< OUString > & inHeaderNames,
726 DAVResource & ioResource,
727 const DAVRequestEnvironment & rEnv )
728 throw ( DAVException )
730 osl::Guard< osl::Mutex > theGuard( m_aMutex );
732 Init( rEnv );
734 boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) );
735 uno::Reference< SerfInputStream > xInputStream( new SerfInputStream );
736 ioResource.uri = inPath;
737 ioResource.properties.clear();
738 apr_status_t status = APR_SUCCESS;
739 aReqProc->processGet( xInputStream,
740 inHeaderNames,
741 ioResource,
742 status );
744 HandleError( aReqProc );
746 return uno::Reference< io::XInputStream >( xInputStream.get() );
750 // -------------------------------------------------------------------
751 // GET
752 // -------------------------------------------------------------------
753 void SerfSession::GET( const OUString & inPath,
754 uno::Reference< io::XOutputStream > & ioOutputStream,
755 const std::vector< OUString > & inHeaderNames,
756 DAVResource & ioResource,
757 const DAVRequestEnvironment & rEnv )
758 throw ( DAVException )
760 osl::Guard< osl::Mutex > theGuard( m_aMutex );
762 Init( rEnv );
764 boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) );
765 ioResource.uri = inPath;
766 ioResource.properties.clear();
767 apr_status_t status = APR_SUCCESS;
768 aReqProc->processGet( ioOutputStream,
769 inHeaderNames,
770 ioResource,
771 status );
773 HandleError( aReqProc );
776 // -------------------------------------------------------------------
777 // PUT
778 // -------------------------------------------------------------------
779 void SerfSession::PUT( const OUString & inPath,
780 const uno::Reference< io::XInputStream > & inInputStream,
781 const DAVRequestEnvironment & rEnv )
782 throw ( DAVException )
784 osl::Guard< osl::Mutex > theGuard( m_aMutex );
786 Init( rEnv );
788 boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) );
789 uno::Sequence< sal_Int8 > aDataToSend;
790 if ( !getDataFromInputStream( inInputStream, aDataToSend, false ) )
791 throw DAVException( DAVException::DAV_INVALID_ARG );
792 apr_status_t status = APR_SUCCESS;
793 aReqProc->processPut( reinterpret_cast< const char * >( aDataToSend.getConstArray() ),
794 aDataToSend.getLength(),
795 status );
797 HandleError( aReqProc );
800 // -------------------------------------------------------------------
801 // POST
802 // -------------------------------------------------------------------
803 uno::Reference< io::XInputStream >
804 SerfSession::POST( const OUString & inPath,
805 const OUString & rContentType,
806 const OUString & rReferer,
807 const uno::Reference< io::XInputStream > & inInputStream,
808 const DAVRequestEnvironment & rEnv )
809 throw ( DAVException )
811 osl::Guard< osl::Mutex > theGuard( m_aMutex );
813 uno::Sequence< sal_Int8 > aDataToSend;
814 if ( !getDataFromInputStream( inInputStream, aDataToSend, true ) )
816 throw DAVException( DAVException::DAV_INVALID_ARG );
819 Init( rEnv );
821 boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) );
822 uno::Reference< SerfInputStream > xInputStream( new SerfInputStream );
823 apr_status_t status = APR_SUCCESS;
824 aReqProc->processPost( reinterpret_cast< const char * >( aDataToSend.getConstArray() ),
825 aDataToSend.getLength(),
826 rContentType,
827 rReferer,
828 xInputStream,
829 status );
831 HandleError( aReqProc );
832 return uno::Reference< io::XInputStream >( xInputStream.get() );
835 // -------------------------------------------------------------------
836 // POST
837 // -------------------------------------------------------------------
838 void SerfSession::POST( const OUString & inPath,
839 const OUString & rContentType,
840 const OUString & rReferer,
841 const uno::Reference< io::XInputStream > & inInputStream,
842 uno::Reference< io::XOutputStream > & oOutputStream,
843 const DAVRequestEnvironment & rEnv )
844 throw ( DAVException )
846 osl::Guard< osl::Mutex > theGuard( m_aMutex );
848 uno::Sequence< sal_Int8 > aDataToSend;
849 if ( !getDataFromInputStream( inInputStream, aDataToSend, true ) )
851 throw DAVException( DAVException::DAV_INVALID_ARG );
854 Init( rEnv );
856 boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) );
857 apr_status_t status = APR_SUCCESS;
858 aReqProc->processPost( reinterpret_cast< const char * >( aDataToSend.getConstArray() ),
859 aDataToSend.getLength(),
860 rContentType,
861 rReferer,
862 oOutputStream,
863 status );
865 HandleError( aReqProc );
868 // -------------------------------------------------------------------
869 // MKCOL
870 // -------------------------------------------------------------------
871 void SerfSession::MKCOL( const OUString & inPath,
872 const DAVRequestEnvironment & rEnv )
873 throw ( DAVException )
875 osl::Guard< osl::Mutex > theGuard( m_aMutex );
877 Init( rEnv );
879 boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) );
880 apr_status_t status = APR_SUCCESS;
881 aReqProc->processMkCol( status );
883 HandleError( aReqProc );
886 // -------------------------------------------------------------------
887 // COPY
888 // -------------------------------------------------------------------
889 void SerfSession::COPY( const OUString & inSourceURL,
890 const OUString & inDestinationURL,
891 const DAVRequestEnvironment & rEnv,
892 sal_Bool inOverWrite )
893 throw ( DAVException )
895 osl::Guard< osl::Mutex > theGuard( m_aMutex );
897 Init( rEnv );
899 SerfUri theSourceUri( inSourceURL );
900 boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( theSourceUri.GetPath() ) );
901 apr_status_t status = APR_SUCCESS;
902 aReqProc->processCopy( inDestinationURL,
903 (inOverWrite ? true : false),
904 status );
906 HandleError( aReqProc );
909 // -------------------------------------------------------------------
910 // MOVE
911 // -------------------------------------------------------------------
912 void SerfSession::MOVE( const OUString & inSourceURL,
913 const OUString & inDestinationURL,
914 const DAVRequestEnvironment & rEnv,
915 sal_Bool inOverWrite )
916 throw ( DAVException )
918 osl::Guard< osl::Mutex > theGuard( m_aMutex );
920 Init( rEnv );
922 SerfUri theSourceUri( inSourceURL );
923 boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( theSourceUri.GetPath() ) );
924 apr_status_t status = APR_SUCCESS;
925 aReqProc->processMove( inDestinationURL,
926 (inOverWrite ? true : false),
927 status );
929 HandleError( aReqProc );
932 // -------------------------------------------------------------------
933 // DESTROY
934 // -------------------------------------------------------------------
935 void SerfSession::DESTROY( const OUString & inPath,
936 const DAVRequestEnvironment & rEnv )
937 throw ( DAVException )
939 osl::Guard< osl::Mutex > theGuard( m_aMutex );
941 Init( rEnv );
943 boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) );
944 apr_status_t status = APR_SUCCESS;
945 aReqProc->processDelete( status );
947 HandleError( aReqProc );
950 // -------------------------------------------------------------------
952 namespace
954 sal_Int32 lastChanceToSendRefreshRequest( TimeValue const & rStart,
955 int timeout )
957 TimeValue aEnd;
958 osl_getSystemTime( &aEnd );
960 // Try to estimate a safe absolute time for sending the
961 // lock refresh request.
962 sal_Int32 lastChanceToSendRefreshRequest = -1;
963 if ( timeout != NE_TIMEOUT_INFINITE )
965 sal_Int32 calltime = aEnd.Seconds - rStart.Seconds;
966 if ( calltime <= timeout )
968 lastChanceToSendRefreshRequest
969 = aEnd.Seconds + timeout - calltime;
971 else
973 OSL_TRACE( "No chance to refresh lock before timeout!" );
976 return lastChanceToSendRefreshRequest;
979 } // namespace
981 // -------------------------------------------------------------------
982 // LOCK (set new lock)
983 // -------------------------------------------------------------------
984 void SerfSession::LOCK( const OUString & inPath,
985 ucb::Lock & /*rLock*/,
986 const DAVRequestEnvironment & rEnv )
987 throw ( DAVException )
989 osl::Guard< osl::Mutex > theGuard( m_aMutex );
991 Init( rEnv );
993 boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) );
994 HandleError( aReqProc );
995 /* Create a depth zero, exclusive write lock, with default timeout
996 * (allowing a server to pick a default). token, owner and uri are
997 * unset. */
999 SerfLock * theLock = ne_lock_create();
1001 // Set the lock uri
1002 ne_uri aUri;
1003 ne_uri_parse( OUStringToOString( makeAbsoluteURL( inPath ),
1004 RTL_TEXTENCODING_UTF8 ).getStr(),
1005 &aUri );
1006 theLock->uri = aUri;
1008 // Set the lock depth
1009 switch( rLock.Depth )
1011 case ucb::LockDepth_ZERO:
1012 theLock->depth = NE_DEPTH_ZERO;
1013 break;
1014 case ucb::LockDepth_ONE:
1015 theLock->depth = NE_DEPTH_ONE;
1016 break;
1017 case ucb::LockDepth_INFINITY:
1018 theLock->depth = NE_DEPTH_INFINITE;
1019 break;
1020 default:
1021 throw DAVException( DAVException::DAV_INVALID_ARG );
1024 // Set the lock scope
1025 switch ( rLock.Scope )
1027 case ucb::LockScope_EXCLUSIVE:
1028 theLock->scope = ne_lockscope_exclusive;
1029 break;
1030 case ucb::LockScope_SHARED:
1031 theLock->scope = ne_lockscope_shared;
1032 break;
1033 default:
1034 throw DAVException( DAVException::DAV_INVALID_ARG );
1037 // Set the lock timeout
1038 theLock->timeout = (long)rLock.Timeout;
1040 // Set the lock owner
1041 OUString aValue;
1042 rLock.Owner >>= aValue;
1043 theLock->owner =
1044 ne_strdup( OUStringToOString( aValue,
1045 RTL_TEXTENCODING_UTF8 ).getStr() );
1046 TimeValue startCall;
1047 osl_getSystemTime( &startCall );
1049 int theRetVal = ne_lock( m_pHttpSession, theLock );
1051 if ( theRetVal == NE_OK )
1053 m_aSerfLockStore.addLock( theLock,
1054 this,
1055 lastChanceToSendRefreshRequest(
1056 startCall, theLock->timeout ) );
1058 uno::Sequence< OUString > aTokens( 1 );
1059 aTokens[ 0 ] = OUString::createFromAscii( theLock->token );
1060 rLock.LockTokens = aTokens;
1062 OSL_TRACE( "SerfSession::LOCK: created lock for %s. token: %s",
1063 OUStringToOString( makeAbsoluteURL( inPath ),
1064 RTL_TEXTENCODING_UTF8 ).getStr(),
1065 theLock->token );
1067 else
1069 ne_lock_destroy( theLock );
1071 OSL_TRACE( "SerfSession::LOCK: obtaining lock for %s failed!",
1072 OUStringToOString( makeAbsoluteURL( inPath ),
1073 RTL_TEXTENCODING_UTF8 ).getStr() );
1076 HandleError( theRetVal, inPath, rEnv );
1080 // -------------------------------------------------------------------
1081 // LOCK (refresh existing lock)
1082 // -------------------------------------------------------------------
1083 sal_Int64 SerfSession::LOCK( const OUString & /*inPath*/,
1084 sal_Int64 nTimeout,
1085 const DAVRequestEnvironment & /*rEnv*/ )
1086 throw ( DAVException )
1088 osl::Guard< osl::Mutex > theGuard( m_aMutex );
1090 return nTimeout;
1092 // Try to get the neon lock from lock store
1093 SerfLock * theLock
1094 = m_aSerfLockStore.findByUri( makeAbsoluteURL( inPath ) );
1095 if ( !theLock )
1096 throw DAVException( DAVException::DAV_NOT_LOCKED );
1098 Init( rEnv );
1100 // refresh existing lock.
1101 theLock->timeout = static_cast< long >( nTimeout );
1103 TimeValue startCall;
1104 osl_getSystemTime( &startCall );
1106 int theRetVal = ne_lock_refresh( m_pHttpSession, theLock );
1108 if ( theRetVal == NE_OK )
1110 m_aSerfLockStore.updateLock( theLock,
1111 lastChanceToSendRefreshRequest(
1112 startCall, theLock->timeout ) );
1115 HandleError( theRetVal, inPath, rEnv );
1117 return theLock->timeout;
1121 // -------------------------------------------------------------------
1122 // LOCK (refresh existing lock)
1123 // -------------------------------------------------------------------
1124 bool SerfSession::LOCK( SerfLock * /*pLock*/,
1125 sal_Int32 & /*rlastChanceToSendRefreshRequest*/ )
1127 osl::Guard< osl::Mutex > theGuard( m_aMutex );
1129 return true;
1131 // refresh existing lock.
1133 TimeValue startCall;
1134 osl_getSystemTime( &startCall );
1136 if ( ne_lock_refresh( m_pHttpSession, pLock ) == NE_OK )
1138 rlastChanceToSendRefreshRequest
1139 = lastChanceToSendRefreshRequest( startCall, pLock->timeout );
1141 OSL_TRACE( "Lock successfully refreshed." );
1142 return true;
1144 else
1146 OSL_TRACE( "Lock not refreshed!" );
1147 return false;
1152 // -------------------------------------------------------------------
1153 // UNLOCK
1154 // -------------------------------------------------------------------
1155 void SerfSession::UNLOCK( const OUString & /*inPath*/,
1156 const DAVRequestEnvironment & /*rEnv*/ )
1157 throw ( DAVException )
1159 osl::Guard< osl::Mutex > theGuard( m_aMutex );
1162 // get the neon lock from lock store
1163 SerfLock * theLock
1164 = m_aSerfLockStore.findByUri( makeAbsoluteURL( inPath ) );
1165 if ( !theLock )
1166 throw DAVException( DAVException::DAV_NOT_LOCKED );
1168 Init( rEnv );
1170 int theRetVal = ne_unlock( m_pHttpSession, theLock );
1172 if ( theRetVal == NE_OK )
1174 m_aSerfLockStore.removeLock( theLock );
1175 ne_lock_destroy( theLock );
1177 else
1179 OSL_TRACE( "SerfSession::UNLOCK: unlocking of %s failed.",
1180 OUStringToOString( makeAbsoluteURL( inPath ),
1181 RTL_TEXTENCODING_UTF8 ).getStr() );
1184 HandleError( theRetVal, inPath, rEnv );
1188 // -------------------------------------------------------------------
1189 // UNLOCK
1190 // -------------------------------------------------------------------
1191 bool SerfSession::UNLOCK( SerfLock * /*pLock*/ )
1193 osl::Guard< osl::Mutex > theGuard( m_aMutex );
1195 return true;
1197 if ( ne_unlock( m_pHttpSession, pLock ) == NE_OK )
1199 OSL_TRACE( "UNLOCK succeeded." );
1200 return true;
1202 else
1204 OSL_TRACE( "UNLOCK failed!" );
1205 return false;
1210 // -------------------------------------------------------------------
1211 void SerfSession::abort()
1212 throw ( DAVException )
1214 // 11.11.09 (tkr): The following code lines causing crashes if
1215 // closing a ongoing connection. It turned out that this existing
1216 // solution doesn't work in multi-threading environments.
1217 // So I disabled them in 3.2. . Issue #73893# should fix it in OOo 3.3.
1218 //if ( m_pHttpSession )
1219 // ne_close_connection( m_pHttpSession );
1222 // -------------------------------------------------------------------
1223 const ucbhelper::InternetProxyServer & SerfSession::getProxySettings() const
1225 if ( m_aUri.GetScheme() == "http" || m_aUri.GetScheme() == "https" )
1227 return m_rProxyDecider.getProxy( m_aUri.GetScheme(),
1228 m_aUri.GetHost(),
1229 m_aUri.GetPort() );
1231 else
1233 // TODO: figure out, if this case can occur
1234 return m_rProxyDecider.getProxy( m_aUri.GetScheme(),
1235 OUString() /* not used */,
1236 -1 /* not used */ );
1241 // -------------------------------------------------------------------
1242 namespace {
1244 bool containsLocktoken( const uno::Sequence< ucb::Lock > & rLocks,
1245 const char * token )
1247 for ( sal_Int32 n = 0; n < rLocks.getLength(); ++n )
1249 const uno::Sequence< OUString > & rTokens
1250 = rLocks[ n ].LockTokens;
1251 for ( sal_Int32 m = 0; m < rTokens.getLength(); ++m )
1253 if ( rTokens[ m ].equalsAscii( token ) )
1254 return true;
1257 return false;
1260 } // namespace
1263 // -------------------------------------------------------------------
1264 bool SerfSession::removeExpiredLocktoken( const OUString & /*inURL*/,
1265 const DAVRequestEnvironment & /*rEnv*/ )
1267 return true;
1269 SerfLock * theLock = m_aSerfLockStore.findByUri( inURL );
1270 if ( !theLock )
1271 return false;
1273 // do a lockdiscovery to check whether this lock is still valid.
1276 // @@@ Alternative: use ne_lock_discover() => less overhead
1278 std::vector< DAVResource > aResources;
1279 std::vector< OUString > aPropNames;
1280 aPropNames.push_back( DAVProperties::LOCKDISCOVERY );
1282 PROPFIND( rEnv.m_aRequestURI, DAVZERO, aPropNames, aResources, rEnv );
1284 if ( aResources.size() == 0 )
1285 return false;
1287 std::vector< DAVPropertyValue >::const_iterator it
1288 = aResources[ 0 ].properties.begin();
1289 std::vector< DAVPropertyValue >::const_iterator end
1290 = aResources[ 0 ].properties.end();
1292 while ( it != end )
1294 if ( (*it).Name.equals( DAVProperties::LOCKDISCOVERY ) )
1296 uno::Sequence< ucb::Lock > aLocks;
1297 if ( !( (*it).Value >>= aLocks ) )
1298 return false;
1300 if ( !containsLocktoken( aLocks, theLock->token ) )
1302 // expired!
1303 break;
1306 // still valid.
1307 return false;
1309 ++it;
1312 // No lockdiscovery prop in propfind result / locktoken not found
1313 // in propfind result -> not locked
1314 OSL_TRACE( "SerfSession::removeExpiredLocktoken: Removing "
1315 " expired lock token for %s. token: %s",
1316 OUStringToOString( inURL,
1317 RTL_TEXTENCODING_UTF8 ).getStr(),
1318 theLock->token );
1320 m_aSerfLockStore.removeLock( theLock );
1321 ne_lock_destroy( theLock );
1322 return true;
1324 catch ( DAVException const & )
1327 return false;
1331 // -------------------------------------------------------------------
1332 // HandleError
1333 // Common Error Handler
1334 // -------------------------------------------------------------------
1335 void SerfSession::HandleError( boost::shared_ptr<SerfRequestProcessor> rReqProc )
1336 throw ( DAVException )
1338 m_aEnv = DAVRequestEnvironment();
1340 if ( rReqProc->mpDAVException )
1342 DAVException* mpDAVExp( rReqProc->mpDAVException );
1344 serf_connection_reset( getSerfConnection() );
1346 if ( mpDAVExp->getStatus() == 413 &&
1347 m_bNoOfTransferEncodingSwitches < 2 )
1349 m_bUseChunkedEncoding = !m_bUseChunkedEncoding;
1350 ++m_bNoOfTransferEncodingSwitches;
1353 throw DAVException( mpDAVExp->getError(),
1354 mpDAVExp->getData(),
1355 mpDAVExp->getStatus() );
1359 // Map error code to DAVException.
1360 switch ( nError )
1362 case NE_OK:
1363 return;
1365 case NE_ERROR: // Generic error
1367 OUString aText = OUString::createFromAscii(
1368 ne_get_error( m_pHttpSession ) );
1370 sal_uInt16 code = makeStatusCode( aText );
1372 if ( code == SC_LOCKED )
1374 if ( m_aSerfLockStore.findByUri(
1375 makeAbsoluteURL( inPath ) ) == 0 )
1377 // locked by 3rd party
1378 throw DAVException( DAVException::DAV_LOCKED );
1380 else
1382 // locked by ourself
1383 throw DAVException( DAVException::DAV_LOCKED_SELF );
1387 // Special handling for 400 and 412 status codes, which may indicate
1388 // that a lock previously obtained by us has been released meanwhile
1389 // by the server. Unfortunately, RFC is not clear at this point,
1390 // thus server implementations behave different...
1391 else if ( code == SC_BAD_REQUEST || code == SC_PRECONDITION_FAILED )
1393 if ( removeExpiredLocktoken( makeAbsoluteURL( inPath ), rEnv ) )
1394 throw DAVException( DAVException::DAV_LOCK_EXPIRED );
1397 throw DAVException( DAVException::DAV_HTTP_ERROR, aText, code );
1399 case NE_LOOKUP: // Name lookup failed.
1400 throw DAVException( DAVException::DAV_HTTP_LOOKUP,
1401 SerfUri::makeConnectionEndPointString(
1402 m_aHostName, m_nPort ) );
1404 case NE_AUTH: // User authentication failed on server
1405 throw DAVException( DAVException::DAV_HTTP_AUTH,
1406 SerfUri::makeConnectionEndPointString(
1407 m_aHostName, m_nPort ) );
1409 case NE_PROXYAUTH: // User authentication failed on proxy
1410 throw DAVException( DAVException::DAV_HTTP_AUTHPROXY,
1411 SerfUri::makeConnectionEndPointString(
1412 m_aProxyName, m_nProxyPort ) );
1414 case NE_CONNECT: // Could not connect to server
1415 throw DAVException( DAVException::DAV_HTTP_CONNECT,
1416 SerfUri::makeConnectionEndPointString(
1417 m_aHostName, m_nPort ) );
1419 case NE_TIMEOUT: // Connection timed out
1420 throw DAVException( DAVException::DAV_HTTP_TIMEOUT,
1421 SerfUri::makeConnectionEndPointString(
1422 m_aHostName, m_nPort ) );
1424 case NE_FAILED: // The precondition failed
1425 throw DAVException( DAVException::DAV_HTTP_FAILED,
1426 SerfUri::makeConnectionEndPointString(
1427 m_aHostName, m_nPort ) );
1429 case NE_RETRY: // Retry request (ne_end_request ONLY)
1430 throw DAVException( DAVException::DAV_HTTP_RETRY,
1431 SerfUri::makeConnectionEndPointString(
1432 m_aHostName, m_nPort ) );
1434 case NE_REDIRECT:
1436 SerfUri aUri( ne_redirect_location( m_pHttpSession ) );
1437 throw DAVException(
1438 DAVException::DAV_HTTP_REDIRECT, aUri.GetURI() );
1440 default:
1442 OSL_TRACE( "SerfSession::HandleError : Unknown Serf error code!" );
1443 throw DAVException( DAVException::DAV_HTTP_ERROR,
1444 OUString::createFromAscii(
1445 ne_get_error( m_pHttpSession ) ) );
1451 // -------------------------------------------------------------------
1452 // static
1453 bool
1454 SerfSession::getDataFromInputStream(
1455 const uno::Reference< io::XInputStream > & xStream,
1456 uno::Sequence< sal_Int8 > & rData,
1457 bool bAppendTrailingZeroByte )
1459 if ( xStream.is() )
1461 uno::Reference< io::XSeekable > xSeekable( xStream, uno::UNO_QUERY );
1462 if ( xSeekable.is() )
1466 sal_Int32 nSize
1467 = sal::static_int_cast<sal_Int32>(xSeekable->getLength());
1468 sal_Int32 nRead
1469 = xStream->readBytes( rData, nSize );
1471 if ( nRead == nSize )
1473 if ( bAppendTrailingZeroByte )
1475 rData.realloc( nSize + 1 );
1476 rData[ nSize ] = sal_Int8( 0 );
1478 return true;
1481 catch ( io::NotConnectedException const & )
1483 // readBytes
1485 catch ( io::BufferSizeExceededException const & )
1487 // readBytes
1489 catch ( io::IOException const & )
1491 // getLength, readBytes
1494 else
1498 uno::Sequence< sal_Int8 > aBuffer;
1499 sal_Int32 nPos = 0;
1501 sal_Int32 nRead = xStream->readSomeBytes( aBuffer, 65536 );
1502 while ( nRead > 0 )
1504 if ( rData.getLength() < ( nPos + nRead ) )
1505 rData.realloc( nPos + nRead );
1507 aBuffer.realloc( nRead );
1508 memcpy( (void*)( rData.getArray() + nPos ),
1509 (const void*)aBuffer.getConstArray(),
1510 nRead );
1511 nPos += nRead;
1513 aBuffer.realloc( 0 );
1514 nRead = xStream->readSomeBytes( aBuffer, 65536 );
1517 if ( bAppendTrailingZeroByte )
1519 rData.realloc( nPos + 1 );
1520 rData[ nPos ] = sal_Int8( 0 );
1522 return true;
1524 catch ( io::NotConnectedException const & )
1526 // readBytes
1528 catch ( io::BufferSizeExceededException const & )
1530 // readBytes
1532 catch ( io::IOException const & )
1534 // readBytes
1538 return false;
1541 // ---------------------------------------------------------------------
1542 sal_Bool
1543 SerfSession::isDomainMatch( OUString certHostName )
1545 OUString hostName = getHostName();
1547 if (hostName.equalsIgnoreAsciiCase( certHostName ) )
1548 return sal_True;
1550 if ( 0 == certHostName.indexOf( OUString::createFromAscii( "*" ) ) &&
1551 hostName.getLength() >= certHostName.getLength() )
1553 OUString cmpStr = certHostName.copy( 1 );
1555 if ( hostName.matchIgnoreAsciiCase(
1556 cmpStr, hostName.getLength() - cmpStr.getLength() ) )
1557 return sal_True;
1559 return sal_False;
1563 // ---------------------------------------------------------------------
1564 OUString SerfSession::makeAbsoluteURL( OUString const & rURL ) const
1568 // Is URL relative or already absolute?
1569 if ( rURL[ 0 ] != sal_Unicode( '/' ) )
1571 // absolute.
1572 return OUString( rURL );
1574 else
1576 ne_uri aUri;
1577 memset( &aUri, 0, sizeof( aUri ) );
1579 ne_fill_server_uri( m_pHttpSession, &aUri );
1580 aUri.path
1581 = ne_strdup( OUStringToOString(
1582 rURL, RTL_TEXTENCODING_UTF8 ).getStr() );
1583 SerfUri aSerfUri( &aUri );
1584 ne_uri_free( &aUri );
1585 return aSerfUri.GetURI();
1588 catch ( DAVException const & )
1591 // error.
1592 return OUString();
1596 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */