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