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