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