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