LCOV - code coverage report
Current view: top level - ucb/source/ucp/webdav - NeonSession.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 3 726 0.4 %
Date: 2012-08-25 Functions: 2 62 3.2 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 2 1144 0.2 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : 
      30                 :            : #include <boost/unordered_map.hpp>
      31                 :            : #include <vector>
      32                 :            : #include <string.h>
      33                 :            : #include "osl/diagnose.h"
      34                 :            : #include "osl/time.h"
      35                 :            : #include <rtl/string.h>
      36                 :            : #include <ne_socket.h>
      37                 :            : #include <ne_auth.h>
      38                 :            : #include <ne_redirect.h>
      39                 :            : #include <ne_ssl.h>
      40                 :            : 
      41                 :            : #if NEON_VERSION < 0x0260
      42                 :            : // old neon versions forgot to set this
      43                 :            : extern "C" {
      44                 :            : #endif
      45                 :            : #include <ne_compress.h>
      46                 :            : #if NEON_VERSION < 0x0260
      47                 :            : }
      48                 :            : #endif
      49                 :            : 
      50                 :            : #include "libxml/parser.h"
      51                 :            : #include "rtl/ustrbuf.hxx"
      52                 :            : #include "comphelper/sequence.hxx"
      53                 :            : #include <comphelper/stl_types.hxx>
      54                 :            : #include "ucbhelper/simplecertificatevalidationrequest.hxx"
      55                 :            : 
      56                 :            : #include "DAVAuthListener.hxx"
      57                 :            : #include "NeonTypes.hxx"
      58                 :            : #include "NeonSession.hxx"
      59                 :            : #include "NeonInputStream.hxx"
      60                 :            : #include "NeonPropFindRequest.hxx"
      61                 :            : #include "NeonHeadRequest.hxx"
      62                 :            : #include "NeonUri.hxx"
      63                 :            : #include "LinkSequence.hxx"
      64                 :            : #include "UCBDeadPropertyValue.hxx"
      65                 :            : 
      66                 :            : #include <com/sun/star/xml/crypto/XSecurityEnvironment.hpp>
      67                 :            : #include <com/sun/star/security/XCertificate.hpp>
      68                 :            : #include <com/sun/star/security/CertificateValidity.hpp>
      69                 :            : #include <com/sun/star/security/CertificateContainerStatus.hpp>
      70                 :            : #include <com/sun/star/security/CertificateContainer.hpp>
      71                 :            : #include <com/sun/star/security/XCertificateContainer.hpp>
      72                 :            : #include <com/sun/star/ucb/Lock.hpp>
      73                 :            : #include <com/sun/star/beans/NamedValue.hpp>
      74                 :            : #include <com/sun/star/xml/crypto/XSEInitializer.hpp>
      75                 :            : 
      76                 :            : #include <boost/bind.hpp>
      77                 :            : 
      78                 :            : using namespace com::sun::star;
      79                 :            : using namespace webdav_ucp;
      80                 :            : 
      81                 :            : #define SEINITIALIZER_COMPONENT "com.sun.star.xml.crypto.SEInitializer"
      82                 :            : 
      83                 :            : #ifndef EOL
      84                 :            : #    define EOL "\r\n"
      85                 :            : #endif
      86                 :            : 
      87                 :            : // -------------------------------------------------------------------
      88                 :            : // RequestData
      89                 :            : // -------------------------------------------------------------------
      90                 :            : 
      91                 :          0 : struct RequestData
      92                 :            : {
      93                 :            :     // POST
      94                 :            :     rtl::OUString aContentType;
      95                 :            :     rtl::OUString aReferer;
      96                 :            : 
      97                 :          0 :     RequestData() {}
      98                 :          0 :     RequestData( const rtl::OUString & rContentType,
      99                 :            :                  const rtl::OUString & rReferer )
     100                 :          0 :     : aContentType( rContentType ), aReferer( rReferer ) {}
     101                 :            : };
     102                 :            : 
     103                 :            : // -------------------------------------------------------------------
     104                 :            : // RequestDataMap
     105                 :            : // -------------------------------------------------------------------
     106                 :            : 
     107                 :            : struct equalPtr
     108                 :            : {
     109                 :          0 :     bool operator()( const ne_request* p1, const ne_request* p2 ) const
     110                 :            :     {
     111                 :          0 :         return p1 == p2;
     112                 :            :     }
     113                 :            : };
     114                 :            : 
     115                 :            : struct hashPtr
     116                 :            : {
     117                 :          0 :     size_t operator()( const ne_request* p ) const
     118                 :            :     {
     119                 :          0 :         return (size_t)p;
     120                 :            :     }
     121                 :            : };
     122                 :            : 
     123                 :            : typedef boost::unordered_map
     124                 :            : <
     125                 :            :     ne_request*,
     126                 :            :     RequestData,
     127                 :            :     hashPtr,
     128                 :            :     equalPtr
     129                 :            : >
     130                 :            : RequestDataMap;
     131                 :            : 
     132                 :            : // -------------------------------------------------------------------
     133                 :            : // Helper fuction
     134                 :            : // -------------------------------------------------------------------
     135                 :          0 : static sal_uInt16 makeStatusCode( const rtl::OUString & rStatusText )
     136                 :            : {
     137                 :            :     // Extract status code from session error string. Unfortunately
     138                 :            :     // neon provides no direct access to the status code...
     139                 :            : 
     140         [ #  # ]:          0 :     if ( rStatusText.getLength() < 3 )
     141                 :            :     {
     142                 :            :         OSL_FAIL(
     143                 :            :             "makeStatusCode - status text string to short!" );
     144                 :          0 :         return 0;
     145                 :            :     }
     146                 :            : 
     147                 :          0 :     sal_Int32 nPos = rStatusText.indexOf( ' ' );
     148         [ #  # ]:          0 :     if ( nPos == -1 )
     149                 :            :     {
     150                 :            :         OSL_FAIL( "makeStatusCode - wrong status text format!" );
     151                 :          0 :         return 0;
     152                 :            :     }
     153                 :            : 
     154                 :          0 :     return sal_uInt16( rStatusText.copy( 0, nPos ).toInt32() );
     155                 :            : }
     156                 :            : 
     157                 :            : // -------------------------------------------------------------------
     158                 :          0 : static bool noKeepAlive( const uno::Sequence< beans::NamedValue >& rFlags )
     159                 :            : {
     160         [ #  # ]:          0 :     if ( !rFlags.hasElements() )
     161                 :          0 :         return false;
     162                 :            : 
     163                 :            :     // find "KeepAlive" property
     164                 :          0 :     const beans::NamedValue* pAry(rFlags.getConstArray());
     165                 :          0 :     const sal_Int32          nLen(rFlags.getLength());
     166                 :            :     const beans::NamedValue* pValue(
     167                 :            :         std::find_if(pAry,pAry+nLen,
     168                 :            :                      boost::bind(comphelper::TNamedValueEqualFunctor(),
     169                 :            :                                  _1,
     170 [ #  # ][ #  # ]:          0 :                                  rtl::OUString("KeepAlive"))));
     171 [ #  # ][ #  # ]:          0 :     if ( pValue != pAry+nLen && !pValue->Value.get<sal_Bool>() )
                 [ #  # ]
     172                 :          0 :         return true;
     173                 :            : 
     174                 :          0 :     return false;
     175                 :            : }
     176                 :            : 
     177                 :            : // -------------------------------------------------------------------
     178                 :          0 : struct NeonRequestContext
     179                 :            : {
     180                 :            :     uno::Reference< io::XOutputStream >    xOutputStream;
     181                 :            :     rtl::Reference< NeonInputStream >      xInputStream;
     182                 :            :     const std::vector< ::rtl::OUString > * pHeaderNames;
     183                 :            :     DAVResource *                          pResource;
     184                 :            : 
     185                 :          0 :     NeonRequestContext( uno::Reference< io::XOutputStream > & xOutStrm )
     186                 :            :     : xOutputStream( xOutStrm ), xInputStream( 0 ),
     187                 :          0 :       pHeaderNames( 0 ), pResource( 0 ) {}
     188                 :            : 
     189                 :          0 :     NeonRequestContext( const rtl::Reference< NeonInputStream > & xInStrm )
     190                 :            :     : xOutputStream( 0 ), xInputStream( xInStrm ),
     191                 :          0 :       pHeaderNames( 0 ), pResource( 0 ) {}
     192                 :            : 
     193                 :          0 :     NeonRequestContext( uno::Reference< io::XOutputStream > & xOutStrm,
     194                 :            :                         const std::vector< ::rtl::OUString > & inHeaderNames,
     195                 :            :                         DAVResource & ioResource )
     196                 :            :     : xOutputStream( xOutStrm ), xInputStream( 0 ),
     197                 :          0 :       pHeaderNames( &inHeaderNames ), pResource( &ioResource ) {}
     198                 :            : 
     199                 :          0 :     NeonRequestContext( const rtl::Reference< NeonInputStream > & xInStrm,
     200                 :            :                         const std::vector< ::rtl::OUString > & inHeaderNames,
     201                 :            :                         DAVResource & ioResource )
     202                 :            :     : xOutputStream( 0 ), xInputStream( xInStrm ),
     203                 :          0 :       pHeaderNames( &inHeaderNames ), pResource( &ioResource ) {}
     204                 :            : };
     205                 :            : 
     206                 :            : //--------------------------------------------------------------------
     207                 :            : //--------------------------------------------------------------------
     208                 :            : //
     209                 :            : // Callback functions
     210                 :            : //
     211                 :            : //--------------------------------------------------------------------
     212                 :            : //--------------------------------------------------------------------
     213                 :            : 
     214                 :            : // -------------------------------------------------------------------
     215                 :            : // ResponseBlockReader
     216                 :            : // A simple Neon response_block_reader for use with an XInputStream
     217                 :            : // -------------------------------------------------------------------
     218                 :            : 
     219                 :          0 : extern "C" int NeonSession_ResponseBlockReader(void * inUserData,
     220                 :            :                                                const char * inBuf,
     221                 :            :                                                size_t inLen )
     222                 :            : {
     223                 :            :     // neon sometimes calls this function with (inLen == 0)...
     224         [ #  # ]:          0 :     if ( inLen > 0 )
     225                 :            :     {
     226                 :            :         NeonRequestContext * pCtx
     227                 :          0 :             = static_cast< NeonRequestContext * >( inUserData );
     228                 :            : 
     229                 :            :         rtl::Reference< NeonInputStream > xInputStream(
     230                 :          0 :             pCtx->xInputStream );
     231                 :            : 
     232         [ #  # ]:          0 :         if ( xInputStream.is() )
     233         [ #  # ]:          0 :             xInputStream->AddToStream( inBuf, inLen );
     234                 :            :     }
     235                 :          0 :     return 0;
     236                 :            : }
     237                 :            : 
     238                 :            : // -------------------------------------------------------------------
     239                 :            : // ResponseBlockWriter
     240                 :            : // A simple Neon response_block_reader for use with an XOutputStream
     241                 :            : // -------------------------------------------------------------------
     242                 :            : 
     243                 :          0 : extern "C" int NeonSession_ResponseBlockWriter( void * inUserData,
     244                 :            :                                                 const char * inBuf,
     245                 :            :                                                 size_t inLen )
     246                 :            : {
     247                 :            :     // neon calls this function with (inLen == 0)...
     248         [ #  # ]:          0 :     if ( inLen > 0 )
     249                 :            :     {
     250                 :            :         NeonRequestContext * pCtx
     251                 :          0 :             = static_cast< NeonRequestContext * >( inUserData );
     252                 :            :         uno::Reference< io::XOutputStream > xOutputStream
     253                 :          0 :             = pCtx->xOutputStream;
     254                 :            : 
     255         [ #  # ]:          0 :         if ( xOutputStream.is() )
     256                 :            :         {
     257         [ #  # ]:          0 :             const uno::Sequence< sal_Int8 > aSeq( (sal_Int8 *)inBuf, inLen );
     258 [ #  # ][ #  # ]:          0 :             xOutputStream->writeBytes( aSeq );
                 [ #  # ]
     259                 :          0 :         }
     260                 :            :     }
     261                 :          0 :     return 0;
     262                 :            : }
     263                 :            : 
     264                 :            : // -------------------------------------------------------------------
     265                 :          0 : extern "C" int NeonSession_NeonAuth( void *       inUserData,
     266                 :            : #ifdef NE_FEATURE_SSPI
     267                 :            :                                      const char * inAuthProtocol,
     268                 :            : #endif
     269                 :            :                                      const char * inRealm,
     270                 :            :                                      int          attempt,
     271                 :            :                                      char *       inoutUserName,
     272                 :            :                                      char *       inoutPassWord )
     273                 :            : {
     274                 :            : /* The callback used to request the username and password in the given
     275                 :            :  * realm. The username and password must be copied into the buffers
     276                 :            :  * which are both of size NE_ABUFSIZ.  The 'attempt' parameter is zero
     277                 :            :  * on the first call to the callback, and increases by one each time
     278                 :            :  * an attempt to authenticate fails.
     279                 :            :  *
     280                 :            :  * The callback must return zero to indicate that authentication
     281                 :            :  * should be attempted with the username/password, or non-zero to
     282                 :            :  * cancel the request. (if non-zero, username and password are
     283                 :            :  * ignored.)  */
     284                 :            : 
     285                 :          0 :     NeonSession * theSession = static_cast< NeonSession * >( inUserData );
     286                 :            :     DAVAuthListener * pListener
     287                 :          0 :         = theSession->getRequestEnvironment().m_xAuthListener.get();
     288         [ #  # ]:          0 :     if ( !pListener )
     289                 :            :     {
     290                 :            :         // abort
     291                 :          0 :         return -1;
     292                 :            :     }
     293                 :          0 :     rtl::OUString theUserName;
     294                 :          0 :     rtl::OUString thePassWord;
     295                 :            : 
     296         [ #  # ]:          0 :     if ( attempt == 0 )
     297                 :            :     {
     298                 :            :         // neon does not handle username supplied with request URI (for
     299                 :            :         // instance when doing FTP over proxy - last checked: 0.23.5 )
     300                 :            : 
     301                 :            :         try
     302                 :            :         {
     303         [ #  # ]:          0 :             NeonUri uri( theSession->getRequestEnvironment().m_aRequestURI );
     304                 :          0 :             rtl::OUString aUserInfo( uri.GetUserInfo() );
     305         [ #  # ]:          0 :             if ( !aUserInfo.isEmpty() )
     306                 :            :             {
     307                 :          0 :                 sal_Int32 nPos = aUserInfo.indexOf( '@' );
     308         [ #  # ]:          0 :                 if ( nPos == -1 )
     309                 :            :                 {
     310                 :          0 :                     theUserName = aUserInfo;
     311                 :            :                 }
     312                 :            :                 else
     313                 :            :                 {
     314                 :          0 :                     theUserName = aUserInfo.copy( 0, nPos );
     315                 :          0 :                     thePassWord = aUserInfo.copy( nPos + 1 );
     316                 :            :                 }
     317         [ #  # ]:          0 :             }
     318                 :            :         }
     319                 :          0 :         catch ( DAVException const & )
     320                 :            :         {
     321                 :            :             // abort
     322                 :          0 :             return -1;
     323                 :            :         }
     324                 :            :     }
     325                 :            :     else
     326                 :            :     {
     327                 :            :         // username buffer is prefilled with user name from last attempt.
     328                 :          0 :         theUserName = rtl::OUString::createFromAscii( inoutUserName );
     329                 :            :         // @@@ Neon does not initialize password buffer (last checked: 0.22.0).
     330                 :            :         //thePassWord = rtl::OUString::createFromAscii( inoutPassWord );
     331                 :            :     }
     332                 :            : 
     333                 :          0 :     bool bCanUseSystemCreds = false;
     334                 :            : 
     335                 :            : #ifdef NE_FEATURE_SSPI
     336                 :            :     bCanUseSystemCreds
     337                 :            :         = (attempt == 0) && // avoid endless loops
     338                 :            :           ne_has_support( NE_FEATURE_SSPI ) && // Windows-only feature.
     339                 :            :           ( ( ne_strcasecmp( inAuthProtocol, "NTLM" ) == 0 ) ||
     340                 :            :             ( ne_strcasecmp( inAuthProtocol, "Negotiate" ) == 0 ) );
     341                 :            : #endif
     342                 :            : 
     343                 :            :     int theRetVal = pListener->authenticate(
     344                 :            :                             rtl::OUString::createFromAscii( inRealm ),
     345                 :          0 :                             theSession->getHostName(),
     346                 :            :                             theUserName,
     347                 :            :                             thePassWord,
     348         [ #  # ]:          0 :                             bCanUseSystemCreds);
     349                 :            : 
     350                 :            :     rtl::OString aUser(
     351         [ #  # ]:          0 :         rtl::OUStringToOString( theUserName, RTL_TEXTENCODING_UTF8 ) );
     352         [ #  # ]:          0 :     if ( aUser.getLength() > ( NE_ABUFSIZ - 1 ) )
     353                 :            :     {
     354                 :            :         OSL_FAIL(
     355                 :            :             "NeonSession_NeonAuth - username to long!" );
     356                 :          0 :         return -1;
     357                 :            :     }
     358                 :            : 
     359                 :            :     rtl::OString aPass(
     360         [ #  # ]:          0 :         rtl::OUStringToOString( thePassWord, RTL_TEXTENCODING_UTF8 ) );
     361         [ #  # ]:          0 :     if ( aPass.getLength() > ( NE_ABUFSIZ - 1 ) )
     362                 :            :     {
     363                 :            :         OSL_FAIL(
     364                 :            :             "NeonSession_NeonAuth - password to long!" );
     365                 :          0 :         return -1;
     366                 :            :     }
     367                 :            : 
     368                 :            :     strcpy( inoutUserName, // #100211# - checked
     369         [ #  # ]:          0 :             rtl::OUStringToOString( theUserName, RTL_TEXTENCODING_UTF8 ).getStr() );
     370                 :            : 
     371                 :            :     strcpy( inoutPassWord, // #100211# - checked
     372         [ #  # ]:          0 :             rtl::OUStringToOString( thePassWord, RTL_TEXTENCODING_UTF8 ).getStr() );
     373                 :            : 
     374         [ #  # ]:          0 :     return theRetVal;
     375                 :            : }
     376                 :            : 
     377                 :            : // -------------------------------------------------------------------
     378                 :            : 
     379                 :            : namespace {
     380                 :            :     // -------------------------------------------------------------------
     381                 :            :     // Helper function
     382                 :          0 :     ::rtl::OUString GetHostnamePart( const ::rtl::OUString& _rRawString )
     383                 :            :     {
     384                 :          0 :         ::rtl::OUString sPart;
     385                 :          0 :         ::rtl::OUString sPartId("CN=");
     386                 :          0 :         sal_Int32 nContStart = _rRawString.indexOf( sPartId );
     387         [ #  # ]:          0 :         if ( nContStart != -1 )
     388                 :            :         {
     389                 :          0 :             nContStart = nContStart + sPartId.getLength();
     390                 :            :             sal_Int32 nContEnd
     391                 :          0 :                 = _rRawString.indexOf( sal_Unicode( ',' ), nContStart );
     392                 :          0 :             sPart = _rRawString.copy( nContStart, nContEnd - nContStart );
     393                 :            :         }
     394                 :          0 :         return sPart;
     395                 :            :     }
     396                 :            : } // namespace
     397                 :            : 
     398                 :            : // -------------------------------------------------------------------
     399                 :          0 : extern "C" int NeonSession_CertificationNotify( void *userdata,
     400                 :            :                                                 int failures,
     401                 :            :                                                 const ne_ssl_certificate *cert )
     402                 :            : {
     403                 :            :     OSL_ASSERT( cert );
     404                 :            : 
     405                 :          0 :     NeonSession * pSession = static_cast< NeonSession * >( userdata );
     406                 :          0 :     uno::Reference< security::XCertificateContainer > xCertificateContainer;
     407                 :            :     try
     408                 :            :     {
     409                 :            :         xCertificateContainer
     410                 :            :             = uno::Reference< security::XCertificateContainer >(
     411   [ #  #  #  # ]:          0 :                 pSession->getMSF()->createInstance(
                 [ #  # ]
     412                 :          0 :                     rtl::OUString( "com.sun.star.security.CertificateContainer" ) ),
     413 [ #  # ][ #  # ]:          0 :                 uno::UNO_QUERY );
                 [ #  # ]
     414                 :            :     }
     415         [ #  # ]:          0 :     catch ( uno::Exception const & )
     416                 :            :     {
     417                 :            :     }
     418                 :            : 
     419         [ #  # ]:          0 :     if ( !xCertificateContainer.is() )
     420                 :          0 :         return 1;
     421                 :            : 
     422                 :          0 :     failures = 0;
     423                 :            : 
     424 [ #  # ][ #  # ]:          0 :     char * dn = ne_ssl_readable_dname( ne_ssl_cert_subject( cert ) );
     425         [ #  # ]:          0 :     rtl::OUString cert_subject( dn, strlen( dn ), RTL_TEXTENCODING_UTF8, 0 );
     426                 :            : 
     427                 :          0 :     ne_free( dn );
     428                 :            : 
     429                 :            :     security::CertificateContainerStatus certificateContainer(
     430         [ #  # ]:          0 :         xCertificateContainer->hasCertificate(
     431         [ #  # ]:          0 :             pSession->getHostName(), cert_subject ) );
     432                 :            : 
     433         [ #  # ]:          0 :     if ( certificateContainer != security::CertificateContainerStatus_NOCERT )
     434                 :            :         return
     435                 :            :             certificateContainer == security::CertificateContainerStatus_TRUSTED
     436                 :            :             ? 0
     437                 :          0 :             : 1;
     438                 :            : 
     439                 :          0 :     uno::Reference< xml::crypto::XSEInitializer > xSEInitializer;
     440                 :            :     try
     441                 :            :     {
     442                 :            :         xSEInitializer = uno::Reference< xml::crypto::XSEInitializer >(
     443   [ #  #  #  # ]:          0 :             pSession->getMSF()->createInstance(
                 [ #  # ]
     444                 :          0 :                 rtl::OUString( SEINITIALIZER_COMPONENT ) ),
     445 [ #  # ][ #  # ]:          0 :             uno::UNO_QUERY );
                 [ #  # ]
     446                 :            :     }
     447         [ #  # ]:          0 :     catch ( uno::Exception const & )
     448                 :            :     {
     449                 :            :     }
     450                 :            : 
     451         [ #  # ]:          0 :     if ( !xSEInitializer.is() )
     452                 :          0 :         return 1;
     453                 :            : 
     454                 :            :     uno::Reference< xml::crypto::XXMLSecurityContext > xSecurityContext(
     455 [ #  # ][ #  # ]:          0 :         xSEInitializer->createSecurityContext( rtl::OUString() ) );
     456                 :            : 
     457                 :            :     uno::Reference< xml::crypto::XSecurityEnvironment > xSecurityEnv(
     458 [ #  # ][ #  # ]:          0 :         xSecurityContext->getSecurityEnvironment() );
     459                 :            : 
     460                 :            :     //The end entity certificate
     461         [ #  # ]:          0 :     char * eeCertB64 = ne_ssl_cert_export( cert );
     462                 :            : 
     463                 :          0 :     rtl::OString sEECertB64( eeCertB64 );
     464                 :            : 
     465                 :            :     uno::Reference< security::XCertificate > xEECert(
     466         [ #  # ]:          0 :         xSecurityEnv->createCertificateFromAscii(
     467 [ #  # ][ #  # ]:          0 :             rtl::OStringToOUString( sEECertB64, RTL_TEXTENCODING_ASCII_US ) ) );
     468                 :            : 
     469                 :          0 :     ne_free( eeCertB64 );
     470                 :          0 :     eeCertB64 = 0;
     471                 :            : 
     472         [ #  # ]:          0 :     std::vector< uno::Reference< security::XCertificate > > vecCerts;
     473                 :          0 :     const ne_ssl_certificate * issuerCert = cert;
     474                 :          0 :     do
     475                 :            :     {
     476                 :            :         //get the intermediate certificate
     477                 :            :         //the returned value is const ! Therfore it does not need to be freed
     478                 :            :         //with ne_ssl_cert_free, which takes a non-const argument
     479         [ #  # ]:          0 :         issuerCert = ne_ssl_cert_signedby( issuerCert );
     480         [ #  # ]:          0 :         if ( NULL == issuerCert )
     481                 :            :             break;
     482                 :            : 
     483         [ #  # ]:          0 :         char * imCertB64 = ne_ssl_cert_export( issuerCert );
     484                 :          0 :         rtl::OString sInterMediateCertB64( imCertB64 );
     485                 :          0 :         ne_free( imCertB64 );
     486                 :            : 
     487                 :            :         uno::Reference< security::XCertificate> xImCert(
     488         [ #  # ]:          0 :             xSecurityEnv->createCertificateFromAscii(
     489 [ #  # ][ #  # ]:          0 :                 rtl::OStringToOUString( sInterMediateCertB64, RTL_TEXTENCODING_ASCII_US ) ) );
     490         [ #  # ]:          0 :         if ( xImCert.is() )
     491         [ #  # ]:          0 :             vecCerts.push_back( xImCert );
     492                 :            :     }
     493                 :            :     while ( 1 );
     494                 :            : 
     495         [ #  # ]:          0 :     sal_Int64 certValidity = xSecurityEnv->verifyCertificate( xEECert,
     496 [ #  # ][ #  # ]:          0 :         ::comphelper::containerToSequence( vecCerts ) );
                 [ #  # ]
     497                 :            : 
     498         [ #  # ]:          0 :     if ( pSession->isDomainMatch(
     499 [ #  # ][ #  # ]:          0 :         GetHostnamePart( xEECert.get()->getSubjectName() ) ) )
                 [ #  # ]
     500                 :            :     {
     501                 :            :         // if host name matched with certificate then look if the
     502                 :            :         // certificate was ok
     503         [ #  # ]:          0 :         if( certValidity == security::CertificateValidity::VALID )
     504                 :          0 :             return 0;
     505                 :            :     }
     506                 :            : 
     507                 :            :     const uno::Reference< ucb::XCommandEnvironment > xEnv(
     508                 :          0 :         pSession->getRequestEnvironment().m_xEnv );
     509         [ #  # ]:          0 :     if ( xEnv.is() )
     510                 :            :     {
     511                 :          0 :         failures = static_cast< int >( certValidity );
     512                 :            : 
     513                 :            :         uno::Reference< task::XInteractionHandler > xIH(
     514 [ #  # ][ #  # ]:          0 :             xEnv->getInteractionHandler() );
     515         [ #  # ]:          0 :         if ( xIH.is() )
     516                 :            :         {
     517                 :            :             rtl::Reference< ucbhelper::SimpleCertificateValidationRequest >
     518                 :            :                 xRequest( new ucbhelper::SimpleCertificateValidationRequest(
     519         [ #  # ]:          0 :                     (sal_Int32)failures, xEECert, pSession->getHostName() ) );
     520 [ #  # ][ #  # ]:          0 :             xIH->handle( xRequest.get() );
         [ #  # ][ #  # ]
     521                 :            : 
     522                 :            :             rtl::Reference< ucbhelper::InteractionContinuation > xSelection
     523         [ #  # ]:          0 :                 = xRequest->getSelection();
     524                 :            : 
     525         [ #  # ]:          0 :             if ( xSelection.is() )
     526                 :            :             {
     527                 :            :                 uno::Reference< task::XInteractionApprove > xApprove(
     528         [ #  # ]:          0 :                     xSelection.get(), uno::UNO_QUERY );
     529         [ #  # ]:          0 :                 if ( xApprove.is() )
     530                 :            :                 {
     531         [ #  # ]:          0 :                     xCertificateContainer->addCertificate(
     532         [ #  # ]:          0 :                         pSession->getHostName(), cert_subject,  sal_True );
     533                 :          0 :                     return 0;
     534                 :            :                 }
     535                 :            :                 else
     536                 :            :                 {
     537                 :            :                     // Don't trust cert
     538         [ #  # ]:          0 :                     xCertificateContainer->addCertificate(
     539         [ #  # ]:          0 :                         pSession->getHostName(), cert_subject, sal_False );
     540                 :          0 :                     return 1;
     541                 :          0 :                 }
     542 [ #  # ][ #  # ]:          0 :             }
     543                 :            :         }
     544                 :            :         else
     545                 :            :         {
     546                 :            :             // Don't trust cert
     547         [ #  # ]:          0 :             xCertificateContainer->addCertificate(
     548         [ #  # ]:          0 :                 pSession->getHostName(), cert_subject, sal_False );
     549                 :          0 :             return 1;
     550         [ #  # ]:          0 :         }
     551                 :            :     }
     552                 :          0 :     return 1;
     553                 :            : }
     554                 :            : 
     555                 :            : // -------------------------------------------------------------------
     556                 :          0 : extern "C" void NeonSession_PreSendRequest( ne_request * req,
     557                 :            :                                             void * userdata,
     558                 :            :                                             ne_buffer * headers )
     559                 :            : {
     560                 :            :     // userdata -> value returned by 'create'
     561                 :            : 
     562                 :          0 :     NeonSession * pSession = static_cast< NeonSession * >( userdata );
     563         [ #  # ]:          0 :     if ( pSession )
     564                 :            :     {
     565                 :            :         // If there is a proxy server in between, it shall never use
     566                 :            :         // cached data. We always want 'up-to-date' data.
     567         [ #  # ]:          0 :         ne_buffer_concat( headers, "Pragma: no-cache", EOL, NULL );
     568                 :            :         // alternative, but understoud by HTTP 1.1 servers only:
     569                 :            :         // ne_buffer_concat( headers, "Cache-Control: max-age=0", EOL, NULL );
     570                 :            : 
     571                 :            :         const RequestDataMap * pRequestData
     572                 :            :             = static_cast< const RequestDataMap* >(
     573                 :          0 :                 pSession->getRequestData() );
     574                 :            : 
     575         [ #  # ]:          0 :         RequestDataMap::const_iterator it = pRequestData->find( req );
     576 [ #  # ][ #  # ]:          0 :         if ( it != pRequestData->end() )
     577                 :            :         {
     578 [ #  # ][ #  # ]:          0 :             if ( !(*it).second.aContentType.isEmpty() )
     579                 :            :             {
     580                 :          0 :                 char * pData = headers->data;
     581         [ #  # ]:          0 :                 if ( strstr( pData, "Content-Type:" ) == NULL )
     582                 :            :                 {
     583                 :            :                     rtl::OString aType
     584         [ #  # ]:          0 :                         = rtl::OUStringToOString( (*it).second.aContentType,
     585         [ #  # ]:          0 :                                                   RTL_TEXTENCODING_UTF8 );
     586                 :            :                     ne_buffer_concat( headers, "Content-Type: ",
     587         [ #  # ]:          0 :                                       aType.getStr(), EOL, NULL );
     588                 :            :                 }
     589                 :            :             }
     590                 :            : 
     591 [ #  # ][ #  # ]:          0 :             if ( !(*it).second.aReferer.isEmpty() )
     592                 :            :             {
     593                 :          0 :                 char * pData = headers->data;
     594         [ #  # ]:          0 :                 if ( strstr( pData, "Referer:" ) == NULL )
     595                 :            :                 {
     596                 :            :                     rtl::OString aReferer
     597         [ #  # ]:          0 :                         = rtl::OUStringToOString( (*it).second.aReferer,
     598         [ #  # ]:          0 :                                                   RTL_TEXTENCODING_UTF8 );
     599                 :            :                     ne_buffer_concat( headers, "Referer: ",
     600         [ #  # ]:          0 :                                       aReferer.getStr(), EOL, NULL );
     601                 :            :                 }
     602                 :            :             }
     603                 :            :         }
     604                 :            : 
     605                 :            :         const DAVRequestHeaders & rHeaders
     606                 :          0 :             = pSession->getRequestEnvironment().m_aRequestHeaders;
     607                 :            : 
     608                 :          0 :         DAVRequestHeaders::const_iterator it1( rHeaders.begin() );
     609                 :          0 :         const DAVRequestHeaders::const_iterator end1( rHeaders.end() );
     610                 :            : 
     611 [ #  # ][ #  # ]:          0 :         while ( it1 != end1 )
     612                 :            :         {
     613                 :            :             rtl::OString aHeader
     614                 :          0 :                 = rtl::OUStringToOString( (*it1).first,
     615         [ #  # ]:          0 :                                           RTL_TEXTENCODING_UTF8 );
     616                 :            :             rtl::OString aValue
     617                 :          0 :                 = rtl::OUStringToOString( (*it1).second,
     618         [ #  # ]:          0 :                                           RTL_TEXTENCODING_UTF8 );
     619                 :            :             ne_buffer_concat( headers, aHeader.getStr(), ": ",
     620         [ #  # ]:          0 :                               aValue.getStr(), EOL, NULL );
     621                 :            : 
     622                 :          0 :             ++it1;
     623                 :          0 :         }
     624                 :            :     }
     625                 :          0 : }
     626                 :            : 
     627                 :            : // -------------------------------------------------------------------
     628                 :            : // static members!
     629                 :            : bool NeonSession::m_bGlobalsInited = false;
     630                 :            : //See https://bugzilla.redhat.com/show_bug.cgi?id=544619#c4
     631                 :            : //neon is threadsafe, but uses gnutls which is only thread-safe
     632                 :            : //if initialized to be thread-safe. cups, unfortunately, generally
     633                 :            : //initializes it first, and as non-thread-safe, leaving the entire
     634                 :            : //stack unsafe
     635                 :          2 : osl::Mutex aGlobalNeonMutex;
     636                 :          2 : NeonLockStore NeonSession::m_aNeonLockStore;
     637                 :            : 
     638                 :            : // -------------------------------------------------------------------
     639                 :            : // Constructor
     640                 :            : // -------------------------------------------------------------------
     641                 :          0 : NeonSession::NeonSession(
     642                 :            :         const rtl::Reference< DAVSessionFactory > & rSessionFactory,
     643                 :            :         const rtl::OUString& inUri,
     644                 :            :         const uno::Sequence< beans::NamedValue >& rFlags,
     645                 :            :         const ucbhelper::InternetProxyDecider & rProxyDecider )
     646                 :            :     throw ( DAVException )
     647                 :            : : DAVSession( rSessionFactory ),
     648                 :            :   m_aFlags( rFlags ),
     649                 :            :   m_pHttpSession( 0 ),
     650         [ #  # ]:          0 :   m_pRequestData( new RequestDataMap ),
     651 [ #  # ][ #  # ]:          0 :   m_rProxyDecider( rProxyDecider )
         [ #  # ][ #  # ]
     652                 :            : {
     653         [ #  # ]:          0 :     NeonUri theUri( inUri );
     654                 :          0 :     m_aScheme    = theUri.GetScheme();
     655                 :          0 :     m_aHostName  = theUri.GetHost();
     656         [ #  # ]:          0 :     m_nPort      = theUri.GetPort();
     657                 :          0 : }
     658                 :            : 
     659                 :            : // -------------------------------------------------------------------
     660                 :            : // Destructor
     661                 :            : // -------------------------------------------------------------------
     662 [ #  # ][ #  # ]:          0 : NeonSession::~NeonSession( )
                 [ #  # ]
     663                 :            : {
     664         [ #  # ]:          0 :     if ( m_pHttpSession )
     665                 :            :     {
     666                 :            :         {
     667         [ #  # ]:          0 :             osl::Guard< osl::Mutex > theGlobalGuard( aGlobalNeonMutex );
     668 [ #  # ][ #  # ]:          0 :             ne_session_destroy( m_pHttpSession );
     669                 :            :         }
     670                 :          0 :         m_pHttpSession = 0;
     671                 :            :     }
     672 [ #  # ][ #  # ]:          0 :     delete static_cast< RequestDataMap * >( m_pRequestData );
     673         [ #  # ]:          0 : }
     674                 :            : 
     675                 :            : // -------------------------------------------------------------------
     676                 :          0 : void NeonSession::Init( const DAVRequestEnvironment & rEnv )
     677                 :            :   throw ( DAVException )
     678                 :            : {
     679         [ #  # ]:          0 :     osl::Guard< osl::Mutex > theGuard( m_aMutex );
     680         [ #  # ]:          0 :     m_aEnv = rEnv;
     681 [ #  # ][ #  # ]:          0 :     Init();
     682                 :          0 : }
     683                 :            : 
     684                 :            : // -------------------------------------------------------------------
     685                 :          0 : void NeonSession::Init()
     686                 :            :     throw ( DAVException )
     687                 :            : {
     688         [ #  # ]:          0 :     osl::Guard< osl::Mutex > theGuard( m_aMutex );
     689                 :            : 
     690                 :          0 :     bool bCreateNewSession = false;
     691                 :            : 
     692         [ #  # ]:          0 :     if ( m_pHttpSession == 0 )
     693                 :            :     {
     694                 :            :         // Ensure that Neon sockets are initialized
     695         [ #  # ]:          0 :         osl::Guard< osl::Mutex > theGlobalGuard( aGlobalNeonMutex );
     696         [ #  # ]:          0 :         if ( !m_bGlobalsInited )
     697                 :            :         {
     698 [ #  # ][ #  # ]:          0 :             if ( ne_sock_init() != 0 )
     699                 :            :                 throw DAVException( DAVException::DAV_SESSION_CREATE,
     700                 :            :                                     NeonUri::makeConnectionEndPointString(
     701         [ #  # ]:          0 :                                                     m_aHostName, m_nPort ) );
     702                 :            : 
     703                 :            :             // #122205# - libxml2 needs to be initialized once if used by
     704                 :            :             // multithreaded programs like OOo.
     705         [ #  # ]:          0 :             xmlInitParser();
     706                 :            : #if 0
     707                 :            :             // for more debug flags see ne_utils.h; NE_DEBUGGING must be defined
     708                 :            :             // while compiling neon in order to actually activate neon debug
     709                 :            :             // output.
     710                 :            :             ne_debug_init( stderr, NE_DBG_FLUSH
     711                 :            :                            | NE_DBG_HTTP
     712                 :            :                            // | NE_DBG_HTTPBODY
     713                 :            :                            // | NE_DBG_HTTPAUTH
     714                 :            :                            // | NE_DBG_XML
     715                 :            :                            // | NE_DBG_XMLPARSE
     716                 :            :                            // | NE_DBG_LOCKS
     717                 :            :                          );
     718                 :            : #endif
     719                 :          0 :             m_bGlobalsInited = true;
     720                 :            :         }
     721                 :            : 
     722         [ #  # ]:          0 :         const ucbhelper::InternetProxyServer & rProxyCfg = getProxySettings();
     723                 :            : 
     724                 :          0 :         m_aProxyName = rProxyCfg.aName;
     725                 :          0 :         m_nProxyPort = rProxyCfg.nPort;
     726                 :            : 
     727                 :            :         // Not yet initialized. Create new session.
     728         [ #  # ]:          0 :         bCreateNewSession = true;
     729                 :            :     }
     730                 :            :     else
     731                 :            :     {
     732                 :            :         // #112271# Check whether proxy settings are still valid (They may
     733                 :            :         // change at any time). If not, create new Neon session.
     734                 :            : 
     735         [ #  # ]:          0 :         const ucbhelper::InternetProxyServer & rProxyCfg = getProxySettings();
     736                 :            : 
     737 [ #  # ][ #  # ]:          0 :         if ( ( rProxyCfg.aName != m_aProxyName )
                 [ #  # ]
     738                 :            :              || ( rProxyCfg.nPort != m_nProxyPort ) )
     739                 :            :         {
     740                 :          0 :             m_aProxyName = rProxyCfg.aName;
     741                 :          0 :             m_nProxyPort = rProxyCfg.nPort;
     742                 :            : 
     743                 :            :             // new session needed, destroy old first
     744                 :            :             {
     745         [ #  # ]:          0 :                 osl::Guard< osl::Mutex > theGlobalGuard( aGlobalNeonMutex );
     746 [ #  # ][ #  # ]:          0 :                 ne_session_destroy( m_pHttpSession );
     747                 :            :             }
     748                 :          0 :             m_pHttpSession = 0;
     749                 :          0 :             bCreateNewSession = true;
     750                 :            :         }
     751                 :            :     }
     752                 :            : 
     753         [ #  # ]:          0 :     if ( bCreateNewSession )
     754                 :            :     {
     755                 :            :         // @@@ For FTP over HTTP proxy inUserInfo is needed to be able to
     756                 :            :         //     build the complete request URI (including user:pass), but
     757                 :            :         //     currently (0.22.0) neon does not allow to pass the user info
     758                 :            :         //     to the session
     759                 :            : 
     760                 :            :         {
     761         [ #  # ]:          0 :             osl::Guard< osl::Mutex > theGlobalGuard( aGlobalNeonMutex );
     762                 :            :             m_pHttpSession = ne_session_create(
     763                 :            :                 rtl::OUStringToOString( m_aScheme, RTL_TEXTENCODING_UTF8 ).getStr(),
     764                 :            :                 /* theUri.GetUserInfo(),
     765                 :            :                    @@@ for FTP via HTTP proxy, but not supported by Neon */
     766                 :            :                 rtl::OUStringToOString( m_aHostName, RTL_TEXTENCODING_UTF8 ).getStr(),
     767 [ #  # ][ #  # ]:          0 :                 m_nPort );
         [ #  # ][ #  # ]
     768                 :            :         }
     769                 :            : 
     770         [ #  # ]:          0 :         if ( m_pHttpSession == 0 )
     771                 :            :             throw DAVException( DAVException::DAV_SESSION_CREATE,
     772                 :            :                                 NeonUri::makeConnectionEndPointString(
     773         [ #  # ]:          0 :                                     m_aHostName, m_nPort ) );
     774                 :            : 
     775                 :            :         // Register the session with the lock store
     776         [ #  # ]:          0 :         m_aNeonLockStore.registerSession( m_pHttpSession );
     777                 :            : 
     778         [ #  # ]:          0 :         if ( m_aScheme.equalsIgnoreAsciiCase(
     779                 :          0 :             rtl::OUString(  "https"  ) ) )
     780                 :            :         {
     781                 :            :             // Set a failure callback for certificate check
     782                 :            :             ne_ssl_set_verify(
     783         [ #  # ]:          0 :                 m_pHttpSession, NeonSession_CertificationNotify, this);
     784                 :            :         }
     785                 :            : 
     786                 :            :         // Add hooks (i.e. for adding additional headers to the request)
     787                 :            : 
     788                 :            : #if 0
     789                 :            :         /* Hook called when a request is created. */
     790                 :            :         //typedef void (*ne_create_request_fn)(ne_request *req, void *userdata,
     791                 :            :         //                 const char *method, const char *path);
     792                 :            : 
     793                 :            :         ne_hook_create_request( m_pHttpSession, create_req_hook_fn, this );
     794                 :            : #endif
     795                 :            : 
     796                 :            :         /* Hook called before the request is sent.  'header' is the raw HTTP
     797                 :            :          * header before the trailing CRLF is added: add in more here. */
     798                 :            :         //typedef void (*ne_pre_send_fn)(ne_request *req, void *userdata,
     799                 :            :         //               ne_buffer *header);
     800                 :            : 
     801         [ #  # ]:          0 :         ne_hook_pre_send( m_pHttpSession, NeonSession_PreSendRequest, this );
     802                 :            : #if 0
     803                 :            :         /* Hook called after the request is sent. May return:
     804                 :            :          *  NE_OK     everything is okay
     805                 :            :          *  NE_RETRY  try sending the request again.
     806                 :            :          * anything else signifies an error, and the request is failed. The
     807                 :            :          * return code is passed back the _dispatch caller, so the session error
     808                 :            :          * must also be set appropriately (ne_set_error).
     809                 :            :          */
     810                 :            :         //typedef int (*ne_post_send_fn)(ne_request *req, void *userdata,
     811                 :            :         //               const ne_status *status);
     812                 :            : 
     813                 :            :         ne_hook_post_send( m_pHttpSession, post_send_req_hook_fn, this );
     814                 :            : 
     815                 :            :         /* Hook called when the request is destroyed. */
     816                 :            :         //typedef void (*ne_destroy_req_fn)(ne_request *req, void *userdata);
     817                 :            : 
     818                 :            :         ne_hook_destroy_request( m_pHttpSession, destroy_req_hook_fn, this );
     819                 :            : 
     820                 :            :         /* Hook called when the session is destroyed. */
     821                 :            :         //typedef void (*ne_destroy_sess_fn)(void *userdata);
     822                 :            : 
     823                 :            :         ne_hook_destroy_session( m_pHttpSession, destroy_sess_hook_fn, this );
     824                 :            : #endif
     825                 :            : 
     826         [ #  # ]:          0 :         if ( !m_aProxyName.isEmpty() )
     827                 :            :         {
     828                 :            :             ne_session_proxy( m_pHttpSession,
     829                 :            :                               rtl::OUStringToOString(
     830                 :            :                                   m_aProxyName,
     831                 :            :                                   RTL_TEXTENCODING_UTF8 ).getStr(),
     832 [ #  # ][ #  # ]:          0 :                               m_nProxyPort );
     833                 :            :         }
     834                 :            : 
     835                 :            :         // avoid KeepAlive?
     836 [ #  # ][ #  # ]:          0 :         if ( noKeepAlive(m_aFlags) )
     837         [ #  # ]:          0 :             ne_set_session_flag( m_pHttpSession, NE_SESSFLAG_PERSIST, 0 );
     838                 :            : 
     839                 :            :         // Register for redirects.
     840         [ #  # ]:          0 :         ne_redirect_register( m_pHttpSession );
     841                 :            : 
     842                 :            :         // authentication callbacks.
     843                 :            : #if NEON_VERSION >= 0x0260
     844         [ #  # ]:          0 :         ne_add_server_auth( m_pHttpSession, NE_AUTH_ALL, NeonSession_NeonAuth, this );
     845         [ #  # ]:          0 :         ne_add_proxy_auth ( m_pHttpSession, NE_AUTH_ALL, NeonSession_NeonAuth, this );
     846                 :            : #else
     847                 :            :         ne_set_server_auth( m_pHttpSession, NeonSession_NeonAuth, this );
     848                 :            :         ne_set_proxy_auth ( m_pHttpSession, NeonSession_NeonAuth, this );
     849                 :            : #endif
     850         [ #  # ]:          0 :     }
     851                 :          0 : }
     852                 :            : 
     853                 :            : // -------------------------------------------------------------------
     854                 :            : // virtual
     855                 :          0 : sal_Bool NeonSession::CanUse( const rtl::OUString & inUri,
     856                 :            :                               const uno::Sequence< beans::NamedValue >& rFlags )
     857                 :            : {
     858                 :            :     try
     859                 :            :     {
     860         [ #  # ]:          0 :         NeonUri theUri( inUri );
     861   [ #  #  #  #  :          0 :         if ( ( theUri.GetPort() == m_nPort ) &&
           #  # ][ #  # ]
                 [ #  # ]
     862                 :          0 :              ( theUri.GetHost() == m_aHostName ) &&
     863                 :          0 :              ( theUri.GetScheme() == m_aScheme ) &&
     864         [ #  # ]:          0 :              ( rFlags == m_aFlags ) )
     865         [ #  # ]:          0 :             return sal_True;
           [ #  #  #  # ]
     866                 :            :     }
     867                 :          0 :     catch ( DAVException const & )
     868                 :            :     {
     869                 :          0 :         return sal_False;
     870                 :            :     }
     871                 :          0 :     return sal_False;
     872                 :            : }
     873                 :            : 
     874                 :            : // -------------------------------------------------------------------
     875                 :            : // virtual
     876                 :          0 : sal_Bool NeonSession::UsesProxy()
     877                 :            : {
     878                 :          0 :     Init();
     879                 :          0 :     return  !m_aProxyName.isEmpty() ;
     880                 :            : }
     881                 :            : 
     882                 :            : // -------------------------------------------------------------------
     883                 :            : // OPTIONS
     884                 :            : // -------------------------------------------------------------------
     885                 :          0 : void NeonSession::OPTIONS( const rtl::OUString & inPath,
     886                 :            :                            DAVCapabilities & outCapabilities,
     887                 :            :                            const DAVRequestEnvironment & rEnv )
     888                 :            :     throw( DAVException )
     889                 :            : {
     890         [ #  # ]:          0 :     osl::Guard< osl::Mutex > theGuard( m_aMutex );
     891                 :            : 
     892         [ #  # ]:          0 :     Init( rEnv );
     893                 :            : 
     894                 :            :     HttpServerCapabilities servercaps;
     895                 :          0 :     memset( &servercaps, 0, sizeof( servercaps ) );
     896                 :            : 
     897                 :            :     int theRetVal = ne_options( m_pHttpSession,
     898                 :            :                                 rtl::OUStringToOString(
     899                 :            :                                     inPath, RTL_TEXTENCODING_UTF8 ).getStr(),
     900 [ #  # ][ #  # ]:          0 :                                 &servercaps );
     901                 :            : 
     902         [ #  # ]:          0 :     HandleError( theRetVal, inPath, rEnv );
     903                 :            : 
     904                 :          0 :     outCapabilities.class1     = !!servercaps.dav_class1;
     905                 :          0 :     outCapabilities.class2     = !!servercaps.dav_class2;
     906         [ #  # ]:          0 :     outCapabilities.executable = !!servercaps.dav_executable;
     907                 :          0 : }
     908                 :            : 
     909                 :            : // -------------------------------------------------------------------
     910                 :            : // PROPFIND - allprop & named
     911                 :            : // -------------------------------------------------------------------
     912                 :          0 : void NeonSession::PROPFIND( const rtl::OUString & inPath,
     913                 :            :                             const Depth inDepth,
     914                 :            :                             const std::vector< rtl::OUString > & inPropNames,
     915                 :            :                             std::vector< DAVResource > & ioResources,
     916                 :            :                             const DAVRequestEnvironment & rEnv )
     917                 :            :     throw ( DAVException )
     918                 :            : {
     919         [ #  # ]:          0 :     osl::Guard< osl::Mutex > theGuard( m_aMutex );
     920                 :            : 
     921         [ #  # ]:          0 :     Init( rEnv );
     922                 :            : 
     923                 :          0 :     int theRetVal = NE_OK;
     924                 :            :     NeonPropFindRequest theRequest( m_pHttpSession,
     925                 :            :                                     rtl::OUStringToOString(
     926                 :            :                                         inPath, RTL_TEXTENCODING_UTF8 ).getStr(),
     927                 :            :                                     inDepth,
     928                 :            :                                     inPropNames,
     929                 :            :                                     ioResources,
     930 [ #  # ][ #  # ]:          0 :                                     theRetVal );
     931                 :            : 
     932 [ #  # ][ #  # ]:          0 :     HandleError( theRetVal, inPath, rEnv );
                 [ #  # ]
     933                 :          0 : }
     934                 :            : 
     935                 :            : // -------------------------------------------------------------------
     936                 :            : // PROPFIND - propnames
     937                 :            : // -------------------------------------------------------------------
     938                 :          0 : void NeonSession::PROPFIND( const rtl::OUString & inPath,
     939                 :            :                             const Depth inDepth,
     940                 :            :                             std::vector< DAVResourceInfo > & ioResInfo,
     941                 :            :                             const DAVRequestEnvironment & rEnv )
     942                 :            :     throw( DAVException )
     943                 :            : {
     944         [ #  # ]:          0 :     osl::Guard< osl::Mutex > theGuard( m_aMutex );
     945                 :            : 
     946         [ #  # ]:          0 :     Init( rEnv );
     947                 :            : 
     948                 :          0 :     int theRetVal = NE_OK;
     949                 :            :     NeonPropFindRequest theRequest( m_pHttpSession,
     950                 :            :                                     rtl::OUStringToOString(
     951                 :            :                                         inPath, RTL_TEXTENCODING_UTF8 ).getStr(),
     952                 :            :                                     inDepth,
     953                 :            :                                     ioResInfo,
     954 [ #  # ][ #  # ]:          0 :                                     theRetVal );
     955                 :            : 
     956 [ #  # ][ #  # ]:          0 :     HandleError( theRetVal, inPath, rEnv );
                 [ #  # ]
     957                 :          0 : }
     958                 :            : 
     959                 :            : // -------------------------------------------------------------------
     960                 :            : // PROPPATCH
     961                 :            : // -------------------------------------------------------------------
     962                 :          0 : void NeonSession::PROPPATCH( const rtl::OUString & inPath,
     963                 :            :                              const std::vector< ProppatchValue > & inValues,
     964                 :            :                              const DAVRequestEnvironment & rEnv )
     965                 :            :     throw( DAVException )
     966                 :            : {
     967                 :            :     /* @@@ Which standard live properties can be set by the client?
     968                 :            :            This is a known WebDAV RFC issue ( verified: 04/10/2001 )
     969                 :            :            --> http://www.ics.uci.edu/pub/ietf/webdav/protocol/issues.html
     970                 :            : 
     971                 :            :         mod_dav implementation:
     972                 :            : 
     973                 :            :         creationdate        r ( File System prop )
     974                 :            :         displayname         w
     975                 :            :         getcontentlanguage  r ( #ifdef DAV_DISABLE_WRITEABLE_PROPS )
     976                 :            :         getcontentlength    r ( File System prop )
     977                 :            :         getcontenttype      r ( #ifdef DAV_DISABLE_WRITEABLE_PROPS )
     978                 :            :         getetag             r ( File System prop )
     979                 :            :         getlastmodified     r ( File System prop )
     980                 :            :         lockdiscovery       r
     981                 :            :         resourcetype        r
     982                 :            :         source              w
     983                 :            :         supportedlock       r
     984                 :            :         executable          w ( #ifndef WIN32 )
     985                 :            : 
     986                 :            :         All dead properties are of course writable.
     987                 :            :     */
     988                 :            : 
     989                 :          0 :     int theRetVal = NE_OK;
     990                 :            : 
     991                 :            :     int n;  // for the "for" loop
     992                 :            : 
     993                 :            :     // Generate the list of properties we want to set.
     994                 :          0 :     int nPropCount = inValues.size();
     995                 :            :     ne_proppatch_operation* pItems
     996                 :          0 :         = new ne_proppatch_operation[ nPropCount + 1 ];
     997         [ #  # ]:          0 :     for ( n = 0; n < nPropCount; ++n )
     998                 :            :     {
     999                 :          0 :         const ProppatchValue & rValue = inValues[ n ];
    1000                 :            : 
    1001                 :            :         // Split fullname into namespace and name!
    1002                 :          0 :         ne_propname * pName = new ne_propname;
    1003                 :          0 :         DAVProperties::createNeonPropName( rValue.name, *pName );
    1004                 :          0 :         pItems[ n ].name = pName;
    1005                 :            : 
    1006         [ #  # ]:          0 :         if ( rValue.operation == PROPSET )
    1007                 :            :         {
    1008                 :          0 :             pItems[ n ].type = ne_propset;
    1009                 :            : 
    1010                 :          0 :             rtl::OUString aStringValue;
    1011 [ #  # ][ #  # ]:          0 :             if ( DAVProperties::isUCBDeadProperty( *pName ) )
    1012                 :            :             {
    1013                 :            :                 // DAV dead property added by WebDAV UCP?
    1014         [ #  # ]:          0 :                 if ( !UCBDeadPropertyValue::toXML( rValue.value,
    1015         [ #  # ]:          0 :                                                    aStringValue ) )
    1016                 :            :                 {
    1017                 :            :                     // Error!
    1018                 :          0 :                     pItems[ n ].value = 0;
    1019                 :          0 :                     theRetVal = NE_ERROR;
    1020                 :          0 :                     nPropCount = n + 1;
    1021                 :            :                     break;
    1022                 :            :                 }
    1023                 :            :             }
    1024         [ #  # ]:          0 :             else if ( !( rValue.value >>= aStringValue ) )
    1025                 :            :             {
    1026                 :            :                 // complex properties...
    1027         [ #  # ]:          0 :                 if ( rValue.name == DAVProperties::SOURCE )
    1028                 :            :                 {
    1029         [ #  # ]:          0 :                     uno::Sequence< ucb::Link > aLinks;
    1030 [ #  # ][ #  # ]:          0 :                     if ( rValue.value >>= aLinks )
    1031                 :            :                     {
    1032         [ #  # ]:          0 :                         LinkSequence::toXML( aLinks, aStringValue );
    1033                 :            :                     }
    1034                 :            :                     else
    1035                 :            :                     {
    1036                 :            :                         // Error!
    1037                 :          0 :                         pItems[ n ].value = 0;
    1038                 :          0 :                         theRetVal = NE_ERROR;
    1039                 :          0 :                         nPropCount = n + 1;
    1040                 :            :                         break;
    1041 [ #  # ][ #  # ]:          0 :                     }
    1042                 :            :                 }
    1043                 :            :                 else
    1044                 :            :                 {
    1045                 :            :                     OSL_FAIL( "NeonSession::PROPPATCH - unsupported type!" );
    1046                 :            :                     // Error!
    1047                 :          0 :                     pItems[ n ].value = 0;
    1048                 :          0 :                     theRetVal = NE_ERROR;
    1049                 :          0 :                     nPropCount = n + 1;
    1050                 :            :                     break;
    1051                 :            :                 }
    1052                 :            :             }
    1053                 :          0 :             pItems[ n ].value
    1054                 :            :                 = strdup( rtl::OUStringToOString( aStringValue,
    1055 [ #  # ][ #  # ]:          0 :                                                   RTL_TEXTENCODING_UTF8 ).getStr() );
    1056                 :            :         }
    1057                 :            :         else
    1058                 :            :         {
    1059                 :          0 :             pItems[ n ].type  = ne_propremove;
    1060                 :          0 :             pItems[ n ].value = 0;
    1061                 :            :         }
    1062                 :            :     }
    1063                 :            : 
    1064         [ #  # ]:          0 :     if ( theRetVal == NE_OK )
    1065                 :            :     {
    1066         [ #  # ]:          0 :         osl::Guard< osl::Mutex > theGuard( m_aMutex );
    1067                 :            : 
    1068         [ #  # ]:          0 :         Init( rEnv );
    1069                 :            : 
    1070                 :          0 :         pItems[ n ].name = 0;
    1071                 :            : 
    1072                 :            :         theRetVal = ne_proppatch( m_pHttpSession,
    1073                 :            :                                   rtl::OUStringToOString(
    1074                 :            :                                       inPath, RTL_TEXTENCODING_UTF8 ).getStr(),
    1075 [ #  # ][ #  # ]:          0 :                                   pItems );
                 [ #  # ]
    1076                 :            :     }
    1077                 :            : 
    1078         [ #  # ]:          0 :     for ( n = 0; n < nPropCount; ++n )
    1079                 :            :     {
    1080                 :          0 :         free( (void *)pItems[ n ].name->name );
    1081                 :          0 :         delete pItems[ n ].name;
    1082                 :          0 :         free( (void *)pItems[ n ].value );
    1083                 :            :     }
    1084                 :            : 
    1085         [ #  # ]:          0 :     delete [] pItems;
    1086                 :            : 
    1087                 :          0 :     HandleError( theRetVal, inPath, rEnv );
    1088                 :          0 : }
    1089                 :            : 
    1090                 :            : // -------------------------------------------------------------------
    1091                 :            : // HEAD
    1092                 :            : // -------------------------------------------------------------------
    1093                 :          0 : void NeonSession::HEAD( const ::rtl::OUString &  inPath,
    1094                 :            :                         const std::vector< ::rtl::OUString > & inHeaderNames,
    1095                 :            :                         DAVResource & ioResource,
    1096                 :            :                         const DAVRequestEnvironment & rEnv )
    1097                 :            :     throw( DAVException )
    1098                 :            : {
    1099         [ #  # ]:          0 :     osl::Guard< osl::Mutex > theGuard( m_aMutex );
    1100                 :            : 
    1101         [ #  # ]:          0 :     Init( rEnv );
    1102                 :            : 
    1103                 :          0 :     int theRetVal = NE_OK;
    1104                 :            :     NeonHeadRequest theRequest( m_pHttpSession,
    1105                 :            :                                 inPath,
    1106                 :            :                                 inHeaderNames,
    1107                 :            :                                 ioResource,
    1108         [ #  # ]:          0 :                                 theRetVal );
    1109                 :            : 
    1110 [ #  # ][ #  # ]:          0 :     HandleError( theRetVal, inPath, rEnv );
                 [ #  # ]
    1111                 :          0 : }
    1112                 :            : 
    1113                 :            : // -------------------------------------------------------------------
    1114                 :            : // GET
    1115                 :            : // -------------------------------------------------------------------
    1116                 :            : uno::Reference< io::XInputStream >
    1117                 :          0 : NeonSession::GET( const rtl::OUString & inPath,
    1118                 :            :                   const DAVRequestEnvironment & rEnv )
    1119                 :            :     throw ( DAVException )
    1120                 :            : {
    1121         [ #  # ]:          0 :     osl::Guard< osl::Mutex > theGuard( m_aMutex );
    1122                 :            : 
    1123         [ #  # ]:          0 :     Init( rEnv );
    1124                 :            : 
    1125         [ #  # ]:          0 :     rtl::Reference< NeonInputStream > xInputStream( new NeonInputStream );
    1126         [ #  # ]:          0 :     NeonRequestContext aCtx( xInputStream );
    1127                 :            :     int theRetVal = GET( m_pHttpSession,
    1128                 :            :                          rtl::OUStringToOString(
    1129                 :            :                              inPath, RTL_TEXTENCODING_UTF8 ).getStr(),
    1130                 :            :                          NeonSession_ResponseBlockReader,
    1131                 :            :                          false,
    1132 [ #  # ][ #  # ]:          0 :                          &aCtx );
    1133                 :            : 
    1134         [ #  # ]:          0 :     HandleError( theRetVal, inPath, rEnv );
    1135                 :            : 
    1136 [ #  # ][ #  # ]:          0 :     return uno::Reference< io::XInputStream >( xInputStream.get() );
                 [ #  # ]
    1137                 :            : }
    1138                 :            : 
    1139                 :            : // -------------------------------------------------------------------
    1140                 :            : // GET
    1141                 :            : // -------------------------------------------------------------------
    1142                 :          0 : void NeonSession::GET( const rtl::OUString & inPath,
    1143                 :            :                        uno::Reference< io::XOutputStream > & ioOutputStream,
    1144                 :            :                        const DAVRequestEnvironment & rEnv )
    1145                 :            :     throw ( DAVException )
    1146                 :            : {
    1147         [ #  # ]:          0 :     osl::Guard< osl::Mutex > theGuard( m_aMutex );
    1148                 :            : 
    1149         [ #  # ]:          0 :     Init( rEnv );
    1150                 :            : 
    1151         [ #  # ]:          0 :     NeonRequestContext aCtx( ioOutputStream );
    1152                 :            :     int theRetVal = GET( m_pHttpSession,
    1153                 :            :                          rtl::OUStringToOString(
    1154                 :            :                              inPath, RTL_TEXTENCODING_UTF8 ).getStr(),
    1155                 :            :                          NeonSession_ResponseBlockWriter,
    1156                 :            :                          false,
    1157 [ #  # ][ #  # ]:          0 :                          &aCtx );
    1158                 :            : 
    1159 [ #  # ][ #  # ]:          0 :     HandleError( theRetVal, inPath, rEnv );
                 [ #  # ]
    1160                 :          0 : }
    1161                 :            : 
    1162                 :            : // -------------------------------------------------------------------
    1163                 :            : // GET
    1164                 :            : // -------------------------------------------------------------------
    1165                 :            : uno::Reference< io::XInputStream >
    1166                 :          0 : NeonSession::GET( const rtl::OUString & inPath,
    1167                 :            :                   const std::vector< ::rtl::OUString > & inHeaderNames,
    1168                 :            :                   DAVResource & ioResource,
    1169                 :            :                   const DAVRequestEnvironment & rEnv )
    1170                 :            :     throw ( DAVException )
    1171                 :            : {
    1172         [ #  # ]:          0 :     osl::Guard< osl::Mutex > theGuard( m_aMutex );
    1173                 :            : 
    1174         [ #  # ]:          0 :     Init( rEnv );
    1175                 :            : 
    1176                 :          0 :     ioResource.uri = inPath;
    1177                 :          0 :     ioResource.properties.clear();
    1178                 :            : 
    1179         [ #  # ]:          0 :     rtl::Reference< NeonInputStream > xInputStream( new NeonInputStream );
    1180         [ #  # ]:          0 :     NeonRequestContext aCtx( xInputStream, inHeaderNames, ioResource );
    1181                 :            :     int theRetVal = GET( m_pHttpSession,
    1182                 :            :                          rtl::OUStringToOString(
    1183                 :            :                              inPath, RTL_TEXTENCODING_UTF8 ).getStr(),
    1184                 :            :                          NeonSession_ResponseBlockReader,
    1185                 :            :                          true,
    1186 [ #  # ][ #  # ]:          0 :                          &aCtx );
    1187                 :            : 
    1188         [ #  # ]:          0 :     HandleError( theRetVal, inPath, rEnv );
    1189                 :            : 
    1190 [ #  # ][ #  # ]:          0 :     return uno::Reference< io::XInputStream >( xInputStream.get() );
                 [ #  # ]
    1191                 :            : }
    1192                 :            : 
    1193                 :            : // -------------------------------------------------------------------
    1194                 :            : // GET
    1195                 :            : // -------------------------------------------------------------------
    1196                 :          0 : void NeonSession::GET( const rtl::OUString & inPath,
    1197                 :            :                        uno::Reference< io::XOutputStream > & ioOutputStream,
    1198                 :            :                        const std::vector< ::rtl::OUString > & inHeaderNames,
    1199                 :            :                        DAVResource & ioResource,
    1200                 :            :                        const DAVRequestEnvironment & rEnv )
    1201                 :            :     throw ( DAVException )
    1202                 :            : {
    1203         [ #  # ]:          0 :     osl::Guard< osl::Mutex > theGuard( m_aMutex );
    1204                 :            : 
    1205         [ #  # ]:          0 :     Init( rEnv );
    1206                 :            : 
    1207                 :          0 :     ioResource.uri = inPath;
    1208                 :          0 :     ioResource.properties.clear();
    1209                 :            : 
    1210         [ #  # ]:          0 :     NeonRequestContext aCtx( ioOutputStream, inHeaderNames, ioResource );
    1211                 :            :     int theRetVal = GET( m_pHttpSession,
    1212                 :            :                          rtl::OUStringToOString(
    1213                 :            :                              inPath, RTL_TEXTENCODING_UTF8 ).getStr(),
    1214                 :            :                          NeonSession_ResponseBlockWriter,
    1215                 :            :                          true,
    1216 [ #  # ][ #  # ]:          0 :                          &aCtx );
    1217                 :            : 
    1218 [ #  # ][ #  # ]:          0 :     HandleError( theRetVal, inPath, rEnv );
                 [ #  # ]
    1219                 :          0 : }
    1220                 :            : 
    1221                 :            : // -------------------------------------------------------------------
    1222                 :            : // PUT
    1223                 :            : // -------------------------------------------------------------------
    1224                 :          0 : void NeonSession::PUT( const rtl::OUString & inPath,
    1225                 :            :                        const uno::Reference< io::XInputStream > & inInputStream,
    1226                 :            :                        const DAVRequestEnvironment & rEnv )
    1227                 :            :     throw ( DAVException )
    1228                 :            : {
    1229         [ #  # ]:          0 :     osl::Guard< osl::Mutex > theGuard( m_aMutex );
    1230                 :            : 
    1231         [ #  # ]:          0 :     uno::Sequence< sal_Int8 > aDataToSend;
    1232 [ #  # ][ #  # ]:          0 :     if ( !getDataFromInputStream( inInputStream, aDataToSend, false ) )
    1233                 :          0 :         throw DAVException( DAVException::DAV_INVALID_ARG );
    1234                 :            : 
    1235         [ #  # ]:          0 :     Init( rEnv );
    1236                 :            : 
    1237                 :            :     int theRetVal = PUT( m_pHttpSession,
    1238                 :            :                          rtl::OUStringToOString(
    1239                 :            :                              inPath, RTL_TEXTENCODING_UTF8 ).getStr(),
    1240                 :            :                          reinterpret_cast< const char * >(
    1241                 :          0 :                             aDataToSend.getConstArray() ),
    1242 [ #  # ][ #  # ]:          0 :                          aDataToSend.getLength() );
    1243                 :            : 
    1244 [ #  # ][ #  # ]:          0 :     HandleError( theRetVal, inPath, rEnv );
                 [ #  # ]
    1245                 :          0 : }
    1246                 :            : 
    1247                 :            : // -------------------------------------------------------------------
    1248                 :            : // POST
    1249                 :            : // -------------------------------------------------------------------
    1250                 :            : uno::Reference< io::XInputStream >
    1251                 :          0 : NeonSession::POST( const rtl::OUString & inPath,
    1252                 :            :                    const rtl::OUString & rContentType,
    1253                 :            :                    const rtl::OUString & rReferer,
    1254                 :            :                    const uno::Reference< io::XInputStream > & inInputStream,
    1255                 :            :                    const DAVRequestEnvironment & rEnv )
    1256                 :            :     throw ( DAVException )
    1257                 :            : {
    1258         [ #  # ]:          0 :     osl::Guard< osl::Mutex > theGuard( m_aMutex );
    1259                 :            : 
    1260         [ #  # ]:          0 :     uno::Sequence< sal_Int8 > aDataToSend;
    1261 [ #  # ][ #  # ]:          0 :     if ( !getDataFromInputStream( inInputStream, aDataToSend, true ) )
    1262                 :          0 :         throw DAVException( DAVException::DAV_INVALID_ARG );
    1263                 :            : 
    1264         [ #  # ]:          0 :     Init( rEnv );
    1265                 :            : 
    1266         [ #  # ]:          0 :     rtl::Reference< NeonInputStream > xInputStream( new NeonInputStream );
    1267         [ #  # ]:          0 :     NeonRequestContext aCtx( xInputStream );
    1268                 :            :     int theRetVal = POST( m_pHttpSession,
    1269                 :            :                           rtl::OUStringToOString(
    1270                 :            :                               inPath, RTL_TEXTENCODING_UTF8 ).getStr(),
    1271                 :            :                           reinterpret_cast< const char * >(
    1272                 :          0 :                               aDataToSend.getConstArray() ),
    1273                 :            :                           NeonSession_ResponseBlockReader,
    1274                 :            :                           &aCtx,
    1275                 :            :                           rContentType,
    1276 [ #  # ][ #  # ]:          0 :                           rReferer );
    1277                 :            : 
    1278         [ #  # ]:          0 :     HandleError( theRetVal, inPath, rEnv );
    1279                 :            : 
    1280 [ #  # ][ #  # ]:          0 :     return uno::Reference< io::XInputStream >( xInputStream.get() );
         [ #  # ][ #  # ]
    1281                 :            : }
    1282                 :            : 
    1283                 :            : // -------------------------------------------------------------------
    1284                 :            : // POST
    1285                 :            : // -------------------------------------------------------------------
    1286                 :          0 : void NeonSession::POST( const rtl::OUString & inPath,
    1287                 :            :                         const rtl::OUString & rContentType,
    1288                 :            :                         const rtl::OUString & rReferer,
    1289                 :            :                         const uno::Reference< io::XInputStream > & inInputStream,
    1290                 :            :                         uno::Reference< io::XOutputStream > & oOutputStream,
    1291                 :            :                         const DAVRequestEnvironment & rEnv )
    1292                 :            :     throw ( DAVException )
    1293                 :            : {
    1294         [ #  # ]:          0 :     osl::Guard< osl::Mutex > theGuard( m_aMutex );
    1295                 :            : 
    1296         [ #  # ]:          0 :     uno::Sequence< sal_Int8 > aDataToSend;
    1297 [ #  # ][ #  # ]:          0 :     if ( !getDataFromInputStream( inInputStream, aDataToSend, true ) )
    1298                 :          0 :         throw DAVException( DAVException::DAV_INVALID_ARG );
    1299                 :            : 
    1300         [ #  # ]:          0 :     Init( rEnv );
    1301                 :            : 
    1302         [ #  # ]:          0 :     NeonRequestContext aCtx( oOutputStream );
    1303                 :            :     int theRetVal = POST( m_pHttpSession,
    1304                 :            :                           rtl::OUStringToOString(
    1305                 :            :                               inPath, RTL_TEXTENCODING_UTF8 ).getStr(),
    1306                 :            :                           reinterpret_cast< const char * >(
    1307                 :          0 :                               aDataToSend.getConstArray() ),
    1308                 :            :                           NeonSession_ResponseBlockWriter,
    1309                 :            :                           &aCtx,
    1310                 :            :                           rContentType,
    1311 [ #  # ][ #  # ]:          0 :                           rReferer );
    1312                 :            : 
    1313 [ #  # ][ #  # ]:          0 :     HandleError( theRetVal, inPath, rEnv );
         [ #  # ][ #  # ]
    1314                 :          0 : }
    1315                 :            : 
    1316                 :            : // -------------------------------------------------------------------
    1317                 :            : // MKCOL
    1318                 :            : // -------------------------------------------------------------------
    1319                 :          0 : void NeonSession::MKCOL( const rtl::OUString & inPath,
    1320                 :            :                          const DAVRequestEnvironment & rEnv )
    1321                 :            :     throw ( DAVException )
    1322                 :            : {
    1323         [ #  # ]:          0 :     osl::Guard< osl::Mutex > theGuard( m_aMutex );
    1324                 :            : 
    1325         [ #  # ]:          0 :     Init( rEnv );
    1326                 :            : 
    1327                 :            :     int theRetVal = ne_mkcol( m_pHttpSession,
    1328                 :            :                               rtl::OUStringToOString(
    1329 [ #  # ][ #  # ]:          0 :                                   inPath, RTL_TEXTENCODING_UTF8 ).getStr() );
    1330                 :            : 
    1331 [ #  # ][ #  # ]:          0 :     HandleError( theRetVal, inPath, rEnv );
    1332                 :          0 : }
    1333                 :            : 
    1334                 :            : // -------------------------------------------------------------------
    1335                 :            : // COPY
    1336                 :            : // -------------------------------------------------------------------
    1337                 :          0 : void NeonSession::COPY( const rtl::OUString & inSourceURL,
    1338                 :            :                         const rtl::OUString & inDestinationURL,
    1339                 :            :                         const DAVRequestEnvironment & rEnv,
    1340                 :            :                         sal_Bool inOverWrite )
    1341                 :            :     throw ( DAVException )
    1342                 :            : {
    1343         [ #  # ]:          0 :     osl::Guard< osl::Mutex > theGuard( m_aMutex );
    1344                 :            : 
    1345         [ #  # ]:          0 :     Init( rEnv );
    1346                 :            : 
    1347         [ #  # ]:          0 :     NeonUri theSourceUri( inSourceURL );
    1348         [ #  # ]:          0 :     NeonUri theDestinationUri( inDestinationURL );
    1349                 :            : 
    1350                 :            :     int theRetVal = ne_copy( m_pHttpSession,
    1351                 :            :                              inOverWrite ? 1 : 0,
    1352                 :            :                              NE_DEPTH_INFINITE,
    1353                 :            :                              rtl::OUStringToOString(
    1354                 :          0 :                                  theSourceUri.GetPath(),
    1355                 :            :                                  RTL_TEXTENCODING_UTF8 ).getStr(),
    1356                 :            :                              rtl::OUStringToOString(
    1357                 :          0 :                                  theDestinationUri.GetPath(),
    1358 [ #  # ][ #  # ]:          0 :                                  RTL_TEXTENCODING_UTF8 ).getStr() );
         [ #  # ][ #  # ]
    1359                 :            : 
    1360 [ #  # ][ #  # ]:          0 :     HandleError( theRetVal, inSourceURL, rEnv );
         [ #  # ][ #  # ]
    1361                 :          0 : }
    1362                 :            : 
    1363                 :            : // -------------------------------------------------------------------
    1364                 :            : // MOVE
    1365                 :            : // -------------------------------------------------------------------
    1366                 :          0 : void NeonSession::MOVE( const rtl::OUString & inSourceURL,
    1367                 :            :                         const rtl::OUString & inDestinationURL,
    1368                 :            :                         const DAVRequestEnvironment & rEnv,
    1369                 :            :                         sal_Bool inOverWrite )
    1370                 :            :     throw ( DAVException )
    1371                 :            : {
    1372         [ #  # ]:          0 :     osl::Guard< osl::Mutex > theGuard( m_aMutex );
    1373                 :            : 
    1374         [ #  # ]:          0 :     Init( rEnv );
    1375                 :            : 
    1376         [ #  # ]:          0 :     NeonUri theSourceUri( inSourceURL );
    1377         [ #  # ]:          0 :     NeonUri theDestinationUri( inDestinationURL );
    1378                 :            :     int theRetVal = ne_move( m_pHttpSession,
    1379                 :            :                              inOverWrite ? 1 : 0,
    1380                 :            :                              rtl::OUStringToOString(
    1381                 :          0 :                                  theSourceUri.GetPath(),
    1382                 :            :                                  RTL_TEXTENCODING_UTF8 ).getStr(),
    1383                 :            :                              rtl::OUStringToOString(
    1384                 :          0 :                                  theDestinationUri.GetPath(),
    1385 [ #  # ][ #  # ]:          0 :                                  RTL_TEXTENCODING_UTF8 ).getStr() );
         [ #  # ][ #  # ]
    1386                 :            : 
    1387 [ #  # ][ #  # ]:          0 :     HandleError( theRetVal, inSourceURL, rEnv );
         [ #  # ][ #  # ]
    1388                 :          0 : }
    1389                 :            : 
    1390                 :            : // -------------------------------------------------------------------
    1391                 :            : // DESTROY
    1392                 :            : // -------------------------------------------------------------------
    1393                 :          0 : void NeonSession::DESTROY( const rtl::OUString & inPath,
    1394                 :            :                            const DAVRequestEnvironment & rEnv )
    1395                 :            :     throw ( DAVException )
    1396                 :            : {
    1397         [ #  # ]:          0 :     osl::Guard< osl::Mutex > theGuard( m_aMutex );
    1398                 :            : 
    1399         [ #  # ]:          0 :     Init( rEnv );
    1400                 :            : 
    1401                 :            :     int theRetVal = ne_delete( m_pHttpSession,
    1402                 :            :                                rtl::OUStringToOString(
    1403 [ #  # ][ #  # ]:          0 :                                    inPath, RTL_TEXTENCODING_UTF8 ).getStr() );
    1404                 :            : 
    1405 [ #  # ][ #  # ]:          0 :     HandleError( theRetVal, inPath, rEnv );
    1406                 :          0 : }
    1407                 :            : 
    1408                 :            : // -------------------------------------------------------------------
    1409                 :            : namespace
    1410                 :            : {
    1411                 :          0 :     sal_Int32 lastChanceToSendRefreshRequest( TimeValue const & rStart,
    1412                 :            :                                               int timeout )
    1413                 :            :     {
    1414                 :            :         TimeValue aEnd;
    1415         [ #  # ]:          0 :         osl_getSystemTime( &aEnd );
    1416                 :            : 
    1417                 :            :         // Try to estimate a safe absolute time for sending the
    1418                 :            :         // lock refresh request.
    1419                 :          0 :         sal_Int32 lastChanceToSendRefreshRequest = -1;
    1420         [ #  # ]:          0 :         if ( timeout != NE_TIMEOUT_INFINITE )
    1421                 :            :         {
    1422                 :          0 :             sal_Int32 calltime = aEnd.Seconds - rStart.Seconds;
    1423         [ #  # ]:          0 :             if ( calltime <= timeout )
    1424                 :            :             {
    1425                 :            :                 lastChanceToSendRefreshRequest
    1426                 :          0 :                     = aEnd.Seconds + timeout - calltime;
    1427                 :            :             }
    1428                 :            :             else
    1429                 :            :             {
    1430                 :            :                 OSL_TRACE( "No chance to refresh lock before timeout!" );
    1431                 :            :             }
    1432                 :            :         }
    1433                 :          0 :         return lastChanceToSendRefreshRequest;
    1434                 :            :     }
    1435                 :            : 
    1436                 :            : } // namespace
    1437                 :            : 
    1438                 :            : // -------------------------------------------------------------------
    1439                 :            : // LOCK (set new lock)
    1440                 :            : // -------------------------------------------------------------------
    1441                 :          0 : void NeonSession::LOCK( const ::rtl::OUString & inPath,
    1442                 :            :                         ucb::Lock & rLock,
    1443                 :            :                         const DAVRequestEnvironment & rEnv )
    1444                 :            :     throw ( DAVException )
    1445                 :            : {
    1446         [ #  # ]:          0 :     osl::Guard< osl::Mutex > theGuard( m_aMutex );
    1447                 :            : 
    1448         [ #  # ]:          0 :     Init( rEnv );
    1449                 :            : 
    1450                 :            :     /* Create a depth zero, exclusive write lock, with default timeout
    1451                 :            :      * (allowing a server to pick a default).  token, owner and uri are
    1452                 :            :      * unset. */
    1453         [ #  # ]:          0 :     NeonLock * theLock = ne_lock_create();
    1454                 :            : 
    1455                 :            :     // Set the lock uri
    1456                 :            :     ne_uri aUri;
    1457                 :            :     ne_uri_parse( rtl::OUStringToOString( makeAbsoluteURL( inPath ),
    1458                 :            :                                           RTL_TEXTENCODING_UTF8 ).getStr(),
    1459 [ #  # ][ #  # ]:          0 :                   &aUri );
                 [ #  # ]
    1460                 :          0 :     theLock->uri = aUri;
    1461                 :            : 
    1462                 :            :     // Set the lock depth
    1463   [ #  #  #  # ]:          0 :     switch( rLock.Depth )
    1464                 :            :     {
    1465                 :            :     case ucb::LockDepth_ZERO:
    1466                 :          0 :         theLock->depth = NE_DEPTH_ZERO;
    1467                 :          0 :         break;
    1468                 :            :     case ucb::LockDepth_ONE:
    1469                 :          0 :         theLock->depth = NE_DEPTH_ONE;
    1470                 :          0 :         break;
    1471                 :            :     case ucb::LockDepth_INFINITY:
    1472                 :          0 :         theLock->depth = NE_DEPTH_INFINITE;
    1473                 :          0 :         break;
    1474                 :            :     default:
    1475                 :          0 :         throw DAVException( DAVException::DAV_INVALID_ARG );
    1476                 :            :     }
    1477                 :            : 
    1478                 :            :     // Set the lock scope
    1479      [ #  #  # ]:          0 :     switch ( rLock.Scope )
    1480                 :            :     {
    1481                 :            :     case ucb::LockScope_EXCLUSIVE:
    1482                 :          0 :         theLock->scope = ne_lockscope_exclusive;
    1483                 :          0 :         break;
    1484                 :            :     case ucb::LockScope_SHARED:
    1485                 :          0 :         theLock->scope = ne_lockscope_shared;
    1486                 :          0 :         break;
    1487                 :            :     default:
    1488                 :          0 :         throw DAVException( DAVException::DAV_INVALID_ARG );
    1489                 :            :     }
    1490                 :            : 
    1491                 :            :     // Set the lock timeout
    1492                 :          0 :     theLock->timeout = (long)rLock.Timeout;
    1493                 :            : 
    1494                 :            :     // Set the lock owner
    1495                 :          0 :     rtl::OUString aValue;
    1496                 :          0 :     rLock.Owner >>= aValue;
    1497                 :            :     theLock->owner =
    1498                 :            :         ne_strdup( rtl::OUStringToOString( aValue,
    1499 [ #  # ][ #  # ]:          0 :                                            RTL_TEXTENCODING_UTF8 ).getStr() );
    1500                 :            :     TimeValue startCall;
    1501         [ #  # ]:          0 :     osl_getSystemTime( &startCall );
    1502                 :            : 
    1503         [ #  # ]:          0 :     int theRetVal = ne_lock( m_pHttpSession, theLock );
    1504                 :            : 
    1505         [ #  # ]:          0 :     if ( theRetVal == NE_OK )
    1506                 :            :     {
    1507                 :            :         m_aNeonLockStore.addLock( theLock,
    1508                 :            :                                   this,
    1509                 :            :                                   lastChanceToSendRefreshRequest(
    1510 [ #  # ][ #  # ]:          0 :                                       startCall, theLock->timeout ) );
         [ #  # ][ #  # ]
    1511                 :            : 
    1512         [ #  # ]:          0 :         uno::Sequence< rtl::OUString > aTokens( 1 );
    1513         [ #  # ]:          0 :         aTokens[ 0 ] = rtl::OUString::createFromAscii( theLock->token );
    1514         [ #  # ]:          0 :         rLock.LockTokens = aTokens;
    1515                 :            : 
    1516                 :            :         OSL_TRACE( "NeonSession::LOCK: created lock for %s. token: %s",
    1517                 :            :                    rtl::OUStringToOString( makeAbsoluteURL( inPath ),
    1518                 :            :                                            RTL_TEXTENCODING_UTF8 ).getStr(),
    1519         [ #  # ]:          0 :                    theLock->token );
    1520                 :            :     }
    1521                 :            :     else
    1522                 :            :     {
    1523         [ #  # ]:          0 :         ne_lock_destroy( theLock );
    1524                 :            : 
    1525                 :            :         OSL_TRACE( "NeonSession::LOCK: obtaining lock for %s failed!",
    1526                 :            :                    rtl::OUStringToOString( makeAbsoluteURL( inPath ),
    1527                 :            :                                            RTL_TEXTENCODING_UTF8 ).getStr() );
    1528                 :            :     }
    1529                 :            : 
    1530 [ #  # ][ #  # ]:          0 :     HandleError( theRetVal, inPath, rEnv );
    1531                 :          0 : }
    1532                 :            : 
    1533                 :            : // -------------------------------------------------------------------
    1534                 :            : // LOCK (refresh existing lock)
    1535                 :            : // -------------------------------------------------------------------
    1536                 :          0 : sal_Int64 NeonSession::LOCK( const ::rtl::OUString & inPath,
    1537                 :            :                              sal_Int64 nTimeout,
    1538                 :            :                              const DAVRequestEnvironment & rEnv )
    1539                 :            :     throw ( DAVException )
    1540                 :            : {
    1541         [ #  # ]:          0 :     osl::Guard< osl::Mutex > theGuard( m_aMutex );
    1542                 :            : 
    1543                 :            :     // Try to get the neon lock from lock store
    1544                 :            :     NeonLock * theLock
    1545 [ #  # ][ #  # ]:          0 :         = m_aNeonLockStore.findByUri( makeAbsoluteURL( inPath ) );
    1546         [ #  # ]:          0 :     if ( !theLock )
    1547                 :          0 :          throw DAVException( DAVException::DAV_NOT_LOCKED );
    1548                 :            : 
    1549         [ #  # ]:          0 :     Init( rEnv );
    1550                 :            : 
    1551                 :            :     // refresh existing lock.
    1552                 :          0 :     theLock->timeout = static_cast< long >( nTimeout );
    1553                 :            : 
    1554                 :            :     TimeValue startCall;
    1555         [ #  # ]:          0 :     osl_getSystemTime( &startCall );
    1556                 :            : 
    1557         [ #  # ]:          0 :     int theRetVal = ne_lock_refresh( m_pHttpSession, theLock );
    1558                 :            : 
    1559         [ #  # ]:          0 :     if ( theRetVal == NE_OK )
    1560                 :            :     {
    1561                 :            :         m_aNeonLockStore.updateLock( theLock,
    1562                 :            :                                      lastChanceToSendRefreshRequest(
    1563 [ #  # ][ #  # ]:          0 :                                          startCall, theLock->timeout ) );
    1564                 :            :     }
    1565                 :            : 
    1566         [ #  # ]:          0 :     HandleError( theRetVal, inPath, rEnv );
    1567                 :            : 
    1568         [ #  # ]:          0 :     return theLock->timeout;
    1569                 :            : }
    1570                 :            : 
    1571                 :            : // -------------------------------------------------------------------
    1572                 :            : // LOCK (refresh existing lock)
    1573                 :            : // -------------------------------------------------------------------
    1574                 :          0 : bool NeonSession::LOCK( NeonLock * pLock,
    1575                 :            :                         sal_Int32 & rlastChanceToSendRefreshRequest )
    1576                 :            : {
    1577         [ #  # ]:          0 :     osl::Guard< osl::Mutex > theGuard( m_aMutex );
    1578                 :            : 
    1579                 :            : #if OSL_DEBUG_LEVEL > 0
    1580                 :            :     char * p = ne_uri_unparse( &(pLock->uri) );
    1581                 :            :     OSL_TRACE( "NeonSession::LOCK: Refreshing lock for %s.", p );
    1582                 :            :     ne_free( p );
    1583                 :            : #endif
    1584                 :            : 
    1585                 :            :     // refresh existing lock.
    1586                 :            : 
    1587                 :            :     TimeValue startCall;
    1588         [ #  # ]:          0 :     osl_getSystemTime( &startCall );
    1589                 :            : 
    1590 [ #  # ][ #  # ]:          0 :     if ( ne_lock_refresh( m_pHttpSession, pLock ) == NE_OK )
    1591                 :            :     {
    1592                 :            :         rlastChanceToSendRefreshRequest
    1593         [ #  # ]:          0 :             = lastChanceToSendRefreshRequest( startCall, pLock->timeout );
    1594                 :            : 
    1595                 :            :         OSL_TRACE( "Lock successfully refreshed." );
    1596                 :          0 :         return true;
    1597                 :            :     }
    1598                 :            :     else
    1599                 :            :     {
    1600                 :            :         OSL_TRACE( "Lock not refreshed!" );
    1601                 :          0 :         return false;
    1602         [ #  # ]:          0 :     }
    1603                 :            : }
    1604                 :            : 
    1605                 :            : // -------------------------------------------------------------------
    1606                 :            : // UNLOCK
    1607                 :            : // -------------------------------------------------------------------
    1608                 :          0 : void NeonSession::UNLOCK( const ::rtl::OUString & inPath,
    1609                 :            :                           const DAVRequestEnvironment & rEnv )
    1610                 :            :     throw ( DAVException )
    1611                 :            : {
    1612         [ #  # ]:          0 :     osl::Guard< osl::Mutex > theGuard( m_aMutex );
    1613                 :            : 
    1614                 :            :     // get the neon lock from lock store
    1615                 :            :     NeonLock * theLock
    1616 [ #  # ][ #  # ]:          0 :         = m_aNeonLockStore.findByUri( makeAbsoluteURL( inPath ) );
    1617         [ #  # ]:          0 :     if ( !theLock )
    1618                 :          0 :         throw DAVException( DAVException::DAV_NOT_LOCKED );
    1619                 :            : 
    1620         [ #  # ]:          0 :     Init( rEnv );
    1621                 :            : 
    1622         [ #  # ]:          0 :     int theRetVal = ne_unlock( m_pHttpSession, theLock );
    1623                 :            : 
    1624         [ #  # ]:          0 :     if ( theRetVal == NE_OK )
    1625                 :            :     {
    1626         [ #  # ]:          0 :         m_aNeonLockStore.removeLock( theLock );
    1627         [ #  # ]:          0 :         ne_lock_destroy( theLock );
    1628                 :            :     }
    1629                 :            :     else
    1630                 :            :     {
    1631                 :            :         OSL_TRACE( "NeonSession::UNLOCK: unlocking of %s failed.",
    1632                 :            :                    rtl::OUStringToOString( makeAbsoluteURL( inPath ),
    1633                 :            :                                            RTL_TEXTENCODING_UTF8 ).getStr() );
    1634                 :            :     }
    1635                 :            : 
    1636 [ #  # ][ #  # ]:          0 :     HandleError( theRetVal, inPath, rEnv );
    1637                 :          0 : }
    1638                 :            : 
    1639                 :            : // -------------------------------------------------------------------
    1640                 :            : // UNLOCK
    1641                 :            : // -------------------------------------------------------------------
    1642                 :          0 : bool NeonSession::UNLOCK( NeonLock * pLock )
    1643                 :            : {
    1644         [ #  # ]:          0 :     osl::Guard< osl::Mutex > theGuard( m_aMutex );
    1645                 :            : 
    1646                 :            : #if OSL_DEBUG_LEVEL > 0
    1647                 :            :     char * p = ne_uri_unparse( &(pLock->uri) );
    1648                 :            :     OSL_TRACE( "NeonSession::UNLOCK: Unlocking %s.", p );
    1649                 :            :     ne_free( p );
    1650                 :            : #endif
    1651                 :            : 
    1652 [ #  # ][ #  # ]:          0 :     if ( ne_unlock( m_pHttpSession, pLock ) == NE_OK )
    1653                 :            :     {
    1654                 :            :         OSL_TRACE( "UNLOCK succeeded." );
    1655                 :          0 :         return true;
    1656                 :            :     }
    1657                 :            :     else
    1658                 :            :     {
    1659                 :            :         OSL_TRACE( "UNLOCK failed!" );
    1660                 :          0 :         return false;
    1661         [ #  # ]:          0 :     }
    1662                 :            : }
    1663                 :            : 
    1664                 :            : // -------------------------------------------------------------------
    1665                 :          0 : void NeonSession::abort()
    1666                 :            :     throw ( DAVException )
    1667                 :            : {
    1668         [ #  # ]:          0 :     if ( m_pHttpSession )
    1669                 :            :     {
    1670         [ #  # ]:          0 :         osl::Guard< osl::Mutex > theGlobalGuard( aGlobalNeonMutex );
    1671 [ #  # ][ #  # ]:          0 :         ne_close_connection( m_pHttpSession );
    1672                 :            :     }
    1673                 :          0 : }
    1674                 :            : 
    1675                 :            : // -------------------------------------------------------------------
    1676                 :          0 : const ucbhelper::InternetProxyServer & NeonSession::getProxySettings() const
    1677                 :            : {
    1678 [ #  # ][ #  # ]:          0 :     if ( m_aScheme == "http" || m_aScheme == "https" )
                 [ #  # ]
    1679                 :            :     {
    1680                 :            :         return m_rProxyDecider.getProxy( m_aScheme,
    1681                 :            :                                          m_aHostName,
    1682                 :          0 :                                          m_nPort );
    1683                 :            :     }
    1684                 :            :     else
    1685                 :            :     {
    1686                 :            :         return m_rProxyDecider.getProxy( m_aScheme,
    1687                 :            :                                          rtl::OUString() /* not used */,
    1688         [ #  # ]:          0 :                                          -1 /* not used */ );
    1689                 :            :     }
    1690                 :            : }
    1691                 :            : 
    1692                 :            : // -------------------------------------------------------------------
    1693                 :            : namespace {
    1694                 :            : 
    1695                 :          0 : bool containsLocktoken( const uno::Sequence< ucb::Lock > & rLocks,
    1696                 :            :                         const char * token )
    1697                 :            : {
    1698         [ #  # ]:          0 :     for ( sal_Int32 n = 0; n < rLocks.getLength(); ++n )
    1699                 :            :     {
    1700                 :            :         const uno::Sequence< rtl::OUString > & rTokens
    1701                 :          0 :             = rLocks[ n ].LockTokens;
    1702         [ #  # ]:          0 :         for ( sal_Int32 m = 0; m < rTokens.getLength(); ++m )
    1703                 :            :         {
    1704         [ #  # ]:          0 :             if ( rTokens[ m ].equalsAscii( token ) )
    1705                 :          0 :                 return true;
    1706                 :            :         }
    1707                 :            :     }
    1708                 :          0 :     return false;
    1709                 :            : }
    1710                 :            : 
    1711                 :            : } // namespace
    1712                 :            : 
    1713                 :            : // -------------------------------------------------------------------
    1714                 :          0 : bool NeonSession::removeExpiredLocktoken( const rtl::OUString & inURL,
    1715                 :            :                                           const DAVRequestEnvironment & rEnv )
    1716                 :            : {
    1717                 :          0 :     NeonLock * theLock = m_aNeonLockStore.findByUri( inURL );
    1718         [ #  # ]:          0 :     if ( !theLock )
    1719                 :          0 :         return false;
    1720                 :            : 
    1721                 :            :     // do a lockdiscovery to check whether this lock is still valid.
    1722                 :            :     try
    1723                 :            :     {
    1724                 :            :         // @@@ Alternative: use ne_lock_discover() => less overhead
    1725                 :            : 
    1726         [ #  # ]:          0 :         std::vector< DAVResource > aResources;
    1727         [ #  # ]:          0 :         std::vector< rtl::OUString > aPropNames;
    1728         [ #  # ]:          0 :         aPropNames.push_back( DAVProperties::LOCKDISCOVERY );
    1729                 :            : 
    1730         [ #  # ]:          0 :         PROPFIND( rEnv.m_aRequestURI, DAVZERO, aPropNames, aResources, rEnv );
    1731                 :            : 
    1732         [ #  # ]:          0 :         if ( aResources.empty() )
    1733                 :          0 :             return false;
    1734                 :            : 
    1735                 :            :         std::vector< DAVPropertyValue >::const_iterator it
    1736         [ #  # ]:          0 :             = aResources[ 0 ].properties.begin();
    1737                 :            :         std::vector< DAVPropertyValue >::const_iterator end
    1738         [ #  # ]:          0 :             = aResources[ 0 ].properties.end();
    1739                 :            : 
    1740 [ #  # ][ #  # ]:          0 :         while ( it != end )
    1741                 :            :         {
    1742         [ #  # ]:          0 :             if ( (*it).Name.equals( DAVProperties::LOCKDISCOVERY ) )
    1743                 :            :             {
    1744         [ #  # ]:          0 :                 uno::Sequence< ucb::Lock > aLocks;
    1745 [ #  # ][ #  # ]:          0 :                 if ( !( (*it).Value >>= aLocks ) )
    1746                 :          0 :                     return false;
    1747                 :            : 
    1748 [ #  # ][ #  # ]:          0 :                 if ( !containsLocktoken( aLocks, theLock->token ) )
    1749                 :            :                 {
    1750                 :            :                     // expired!
    1751                 :            :                     break;
    1752                 :            :                 }
    1753                 :            : 
    1754                 :            :                 // still valid.
    1755 [ #  # ][ #  # ]:          0 :                 return false;
    1756                 :            :             }
    1757                 :          0 :             ++it;
    1758                 :            :         }
    1759                 :            : 
    1760                 :            :         // No lockdiscovery prop in propfind result / locktoken not found
    1761                 :            :         // in propfind result -> not locked
    1762                 :            :         OSL_TRACE( "NeonSession::removeExpiredLocktoken: Removing "
    1763                 :            :                    " expired lock token for %s. token: %s",
    1764                 :            :                    rtl::OUStringToOString( inURL,
    1765                 :            :                                            RTL_TEXTENCODING_UTF8 ).getStr(),
    1766                 :            :                    theLock->token );
    1767                 :            : 
    1768         [ #  # ]:          0 :         m_aNeonLockStore.removeLock( theLock );
    1769         [ #  # ]:          0 :         ne_lock_destroy( theLock );
    1770         [ #  # ]:          0 :         return true;
    1771                 :            :     }
    1772                 :          0 :     catch ( DAVException const & )
    1773                 :            :     {
    1774                 :            :     }
    1775                 :          0 :     return false;
    1776                 :            : }
    1777                 :            : 
    1778                 :            : // -------------------------------------------------------------------
    1779                 :            : // HandleError
    1780                 :            : // Common Error Handler
    1781                 :            : // -------------------------------------------------------------------
    1782                 :          0 : void NeonSession::HandleError( int nError,
    1783                 :            :                                const rtl::OUString & inPath,
    1784                 :            :                                const DAVRequestEnvironment & rEnv )
    1785                 :            :     throw ( DAVException )
    1786                 :            : {
    1787         [ #  # ]:          0 :     m_aEnv = DAVRequestEnvironment();
    1788                 :            : 
    1789                 :            :     // Map error code to DAVException.
    1790   [ #  #  #  #  :          0 :     switch ( nError )
          #  #  #  #  #  
                   #  # ]
    1791                 :            :     {
    1792                 :            :         case NE_OK:
    1793                 :          0 :             return;
    1794                 :            : 
    1795                 :            :         case NE_ERROR:        // Generic error
    1796                 :            :         {
    1797                 :            :             rtl::OUString aText = rtl::OUString::createFromAscii(
    1798         [ #  # ]:          0 :                 ne_get_error( m_pHttpSession ) );
    1799                 :            : 
    1800                 :          0 :             sal_uInt16 code = makeStatusCode( aText );
    1801                 :            : 
    1802         [ #  # ]:          0 :             if ( code == SC_LOCKED )
    1803                 :            :             {
    1804         [ #  # ]:          0 :                 if ( m_aNeonLockStore.findByUri(
    1805 [ #  # ][ #  # ]:          0 :                          makeAbsoluteURL( inPath ) ) == 0 )
    1806                 :            :                 {
    1807                 :            :                     // locked by 3rd party
    1808                 :          0 :                     throw DAVException( DAVException::DAV_LOCKED );
    1809                 :            :                 }
    1810                 :            :                 else
    1811                 :            :                 {
    1812                 :            :                     // locked by ourself
    1813                 :          0 :                     throw DAVException( DAVException::DAV_LOCKED_SELF );
    1814                 :            :                 }
    1815                 :            :             }
    1816                 :            : 
    1817                 :            :             // Special handling for 400 and 412 status codes, which may indicate
    1818                 :            :             // that a lock previously obtained by us has been released meanwhile
    1819                 :            :             // by the server. Unfortunately, RFC is not clear at this point,
    1820                 :            :             // thus server implementations behave different...
    1821 [ #  # ][ #  # ]:          0 :             else if ( code == SC_BAD_REQUEST || code == SC_PRECONDITION_FAILED )
    1822                 :            :             {
    1823 [ #  # ][ #  # ]:          0 :                 if ( removeExpiredLocktoken( makeAbsoluteURL( inPath ), rEnv ) )
                 [ #  # ]
    1824                 :          0 :                     throw DAVException( DAVException::DAV_LOCK_EXPIRED );
    1825                 :            :             }
    1826                 :            : 
    1827                 :          0 :             throw DAVException( DAVException::DAV_HTTP_ERROR, aText, code );
    1828                 :            :         }
    1829                 :            :         case NE_LOOKUP:       // Name lookup failed.
    1830                 :            :             throw DAVException( DAVException::DAV_HTTP_LOOKUP,
    1831                 :            :                                 NeonUri::makeConnectionEndPointString(
    1832         [ #  # ]:          0 :                                     m_aHostName, m_nPort ) );
    1833                 :            : 
    1834                 :            :         case NE_AUTH:         // User authentication failed on server
    1835                 :            :             throw DAVException( DAVException::DAV_HTTP_AUTH,
    1836                 :            :                                 NeonUri::makeConnectionEndPointString(
    1837         [ #  # ]:          0 :                                     m_aHostName, m_nPort ) );
    1838                 :            : 
    1839                 :            :         case NE_PROXYAUTH:    // User authentication failed on proxy
    1840                 :            :             throw DAVException( DAVException::DAV_HTTP_AUTHPROXY,
    1841                 :            :                                 NeonUri::makeConnectionEndPointString(
    1842         [ #  # ]:          0 :                                     m_aProxyName, m_nProxyPort ) );
    1843                 :            : 
    1844                 :            :         case NE_CONNECT:      // Could not connect to server
    1845                 :            :             throw DAVException( DAVException::DAV_HTTP_CONNECT,
    1846                 :            :                                 NeonUri::makeConnectionEndPointString(
    1847         [ #  # ]:          0 :                                     m_aHostName, m_nPort ) );
    1848                 :            : 
    1849                 :            :         case NE_TIMEOUT:      // Connection timed out
    1850                 :            :             throw DAVException( DAVException::DAV_HTTP_TIMEOUT,
    1851                 :            :                                 NeonUri::makeConnectionEndPointString(
    1852         [ #  # ]:          0 :                                     m_aHostName, m_nPort ) );
    1853                 :            : 
    1854                 :            :         case NE_FAILED:       // The precondition failed
    1855                 :            :             throw DAVException( DAVException::DAV_HTTP_FAILED,
    1856                 :            :                                 NeonUri::makeConnectionEndPointString(
    1857         [ #  # ]:          0 :                                     m_aHostName, m_nPort ) );
    1858                 :            : 
    1859                 :            :         case NE_RETRY:        // Retry request (ne_end_request ONLY)
    1860                 :            :             throw DAVException( DAVException::DAV_HTTP_RETRY,
    1861                 :            :                                 NeonUri::makeConnectionEndPointString(
    1862         [ #  # ]:          0 :                                     m_aHostName, m_nPort ) );
    1863                 :            : 
    1864                 :            :         case NE_REDIRECT:
    1865                 :            :         {
    1866 [ #  # ][ #  # ]:          0 :             NeonUri aUri( ne_redirect_location( m_pHttpSession ) );
    1867                 :            :             throw DAVException(
    1868                 :          0 :                 DAVException::DAV_HTTP_REDIRECT, aUri.GetURI() );
    1869                 :            :         }
    1870                 :            :         default:
    1871                 :            :         {
    1872                 :            :             OSL_TRACE( "NeonSession::HandleError : Unknown Neon error code!" );
    1873                 :            :             throw DAVException( DAVException::DAV_HTTP_ERROR,
    1874                 :            :                                 rtl::OUString::createFromAscii(
    1875         [ #  # ]:          0 :                                     ne_get_error( m_pHttpSession ) ) );
    1876                 :            :         }
    1877                 :            :     }
    1878                 :            : }
    1879                 :            : 
    1880                 :            : // -------------------------------------------------------------------
    1881                 :            : namespace {
    1882                 :            : 
    1883                 :          0 : void runResponseHeaderHandler( void * userdata,
    1884                 :            :                                const char * value )
    1885                 :            : {
    1886                 :          0 :     rtl::OUString aHeader( rtl::OUString::createFromAscii( value ) );
    1887                 :          0 :     sal_Int32 nPos = aHeader.indexOf( ':' );
    1888                 :            : 
    1889         [ #  # ]:          0 :     if ( nPos != -1 )
    1890                 :            :     {
    1891                 :          0 :         rtl::OUString aHeaderName( aHeader.copy( 0, nPos ) );
    1892                 :            : 
    1893                 :            :         NeonRequestContext * pCtx
    1894                 :          0 :             = static_cast< NeonRequestContext * >( userdata );
    1895                 :            : 
    1896                 :            :         // Note: Empty vector means that all headers are requested.
    1897                 :          0 :         bool bIncludeIt = ( pCtx->pHeaderNames->empty() );
    1898                 :            : 
    1899         [ #  # ]:          0 :         if ( !bIncludeIt )
    1900                 :            :         {
    1901                 :            :             // Check whether this header was requested.
    1902                 :            :             std::vector< ::rtl::OUString >::const_iterator it(
    1903                 :          0 :                 pCtx->pHeaderNames->begin() );
    1904                 :            :             const std::vector< ::rtl::OUString >::const_iterator end(
    1905                 :          0 :                 pCtx->pHeaderNames->end() );
    1906                 :            : 
    1907 [ #  # ][ #  # ]:          0 :             while ( it != end )
    1908                 :            :             {
    1909                 :            :                 // header names are case insensitive
    1910         [ #  # ]:          0 :                 if ( (*it).equalsIgnoreAsciiCase( aHeaderName ) )
    1911                 :            :                 {
    1912                 :          0 :                     aHeaderName = (*it);
    1913                 :          0 :                     break;
    1914                 :            :                 }
    1915                 :          0 :                 ++it;
    1916                 :            :             }
    1917                 :            : 
    1918 [ #  # ][ #  # ]:          0 :             if ( it != end )
    1919                 :          0 :                 bIncludeIt = true;
    1920                 :            :         }
    1921                 :            : 
    1922         [ #  # ]:          0 :         if ( bIncludeIt )
    1923                 :            :         {
    1924                 :            :             // Create & set the PropertyValue
    1925                 :          0 :             DAVPropertyValue thePropertyValue;
    1926                 :          0 :             thePropertyValue.IsCaseSensitive = false;
    1927                 :          0 :             thePropertyValue.Name = aHeaderName;
    1928                 :            : 
    1929         [ #  # ]:          0 :             if ( nPos < aHeader.getLength() )
    1930         [ #  # ]:          0 :                 thePropertyValue.Value <<= aHeader.copy( nPos + 1 ).trim();
    1931                 :            : 
    1932                 :            :             // Add the newly created PropertyValue
    1933         [ #  # ]:          0 :             pCtx->pResource->properties.push_back( thePropertyValue );
    1934                 :          0 :         }
    1935                 :          0 :     }
    1936                 :          0 : }
    1937                 :            : 
    1938                 :            : } // namespace
    1939                 :            : 
    1940                 :            : // -------------------------------------------------------------------
    1941                 :            : // static
    1942                 :          0 : int NeonSession::GET( ne_session * sess,
    1943                 :            :                       const char * uri,
    1944                 :            :                       ne_block_reader reader,
    1945                 :            :                       bool getheaders,
    1946                 :            :                       void * userdata )
    1947                 :            : {
    1948                 :            :     //struct get_context ctx;
    1949                 :          0 :     ne_request * req = ne_request_create( sess, "GET", uri );
    1950                 :            :     int ret;
    1951                 :            : 
    1952                 :            :     ne_decompress * dc
    1953                 :          0 :         = ne_decompress_reader( req, ne_accept_2xx, reader, userdata );
    1954                 :            : 
    1955                 :            :     {
    1956         [ #  # ]:          0 :         osl::Guard< osl::Mutex > theGlobalGuard( aGlobalNeonMutex );
    1957 [ #  # ][ #  # ]:          0 :         ret = ne_request_dispatch( req );
    1958                 :            :     }
    1959                 :            : 
    1960         [ #  # ]:          0 :     if ( getheaders )
    1961                 :            :     {
    1962                 :          0 :         void *cursor = NULL;
    1963                 :            :         const char *name, *value;
    1964 [ #  # ][ #  # ]:          0 :         while ( ( cursor = ne_response_header_iterate(
    1965                 :            :                                req, cursor, &name, &value ) ) != NULL )
    1966                 :            :         {
    1967                 :            :             char buffer[8192];
    1968                 :            : 
    1969         [ #  # ]:          0 :             ne_snprintf(buffer, sizeof buffer, "%s: %s", name, value);
    1970         [ #  # ]:          0 :             runResponseHeaderHandler(userdata, buffer);
    1971                 :            :         }
    1972                 :            :     }
    1973                 :            : 
    1974 [ #  # ][ #  # ]:          0 :     if ( ret == NE_OK && ne_get_status( req )->klass != 2 )
    1975                 :          0 :         ret = NE_ERROR;
    1976                 :            : 
    1977         [ #  # ]:          0 :     if ( dc != 0 )
    1978                 :          0 :         ne_decompress_destroy(dc);
    1979                 :            : 
    1980                 :          0 :     ne_request_destroy( req );
    1981                 :          0 :     return ret;
    1982                 :            : }
    1983                 :            : 
    1984                 :            : // -------------------------------------------------------------------
    1985                 :            : // static
    1986                 :          0 : int NeonSession::PUT( ne_session * sess,
    1987                 :            :                       const char * uri,
    1988                 :            :                       const char * buffer,
    1989                 :            :                       size_t size)
    1990                 :            : {
    1991                 :          0 :     ne_request * req = ne_request_create( sess, "PUT", uri );
    1992                 :            :     int ret;
    1993                 :            : 
    1994                 :          0 :     ne_lock_using_resource( req, uri, 0 );
    1995                 :          0 :     ne_lock_using_parent( req, uri );
    1996                 :            : 
    1997                 :          0 :     ne_set_request_body_buffer( req, buffer, size );
    1998                 :            : 
    1999                 :            :     {
    2000         [ #  # ]:          0 :         osl::Guard< osl::Mutex > theGlobalGuard( aGlobalNeonMutex );
    2001 [ #  # ][ #  # ]:          0 :         ret = ne_request_dispatch( req );
    2002                 :            :     }
    2003                 :            : 
    2004 [ #  # ][ #  # ]:          0 :     if ( ret == NE_OK && ne_get_status( req )->klass != 2 )
    2005                 :          0 :         ret = NE_ERROR;
    2006                 :            : 
    2007                 :          0 :     ne_request_destroy( req );
    2008                 :          0 :     return ret;
    2009                 :            : }
    2010                 :            : 
    2011                 :            : // -------------------------------------------------------------------
    2012                 :          0 : int NeonSession::POST( ne_session * sess,
    2013                 :            :                        const char * uri,
    2014                 :            :                        const char * buffer,
    2015                 :            :                        ne_block_reader reader,
    2016                 :            :                        void * userdata,
    2017                 :            :                        const rtl::OUString & rContentType,
    2018                 :            :                        const rtl::OUString & rReferer )
    2019                 :            : {
    2020         [ #  # ]:          0 :     ne_request * req = ne_request_create( sess, "POST", uri );
    2021                 :            :     //struct get_context ctx;
    2022                 :            :     int ret;
    2023                 :            : 
    2024                 :          0 :     RequestDataMap * pData = 0;
    2025                 :            : 
    2026 [ #  # ][ #  # ]:          0 :     if ( !rContentType.isEmpty() || !rReferer.isEmpty() )
                 [ #  # ]
    2027                 :            :     {
    2028                 :            :         // Remember contenttype and referer. Data will be added to HTTP request
    2029                 :            :         // header in in 'PreSendRequest' callback.
    2030                 :          0 :         pData = static_cast< RequestDataMap* >( m_pRequestData );
    2031         [ #  # ]:          0 :         (*pData)[ req ] = RequestData( rContentType, rReferer );
    2032                 :            :     }
    2033                 :            : 
    2034                 :            :     //ctx.total = -1;
    2035                 :            :     //ctx.fd = fd;
    2036                 :            :     //ctx.error = 0;
    2037                 :            :     //ctx.session = sess;
    2038                 :            : 
    2039                 :            :     ///* Read the value of the Content-Length header into ctx.total */
    2040                 :            :     //ne_add_response_header_handler( req, "Content-Length",
    2041                 :            :     //                 ne_handle_numeric_header, &ctx.total );
    2042                 :            : 
    2043         [ #  # ]:          0 :     ne_add_response_body_reader( req, ne_accept_2xx, reader, userdata );
    2044                 :            : 
    2045         [ #  # ]:          0 :     ne_set_request_body_buffer( req, buffer, strlen( buffer ) );
    2046                 :            : 
    2047                 :            :     {
    2048         [ #  # ]:          0 :         osl::Guard< osl::Mutex > theGlobalGuard( aGlobalNeonMutex );
    2049 [ #  # ][ #  # ]:          0 :         ret = ne_request_dispatch( req );
    2050                 :            :     }
    2051                 :            : 
    2052                 :            :     //if ( ctx.error )
    2053                 :            :     //    ret = NE_ERROR;
    2054                 :            :     //else
    2055 [ #  # ][ #  # ]:          0 :     if ( ret == NE_OK && ne_get_status( req )->klass != 2 )
                 [ #  # ]
    2056                 :          0 :         ret = NE_ERROR;
    2057                 :            : 
    2058         [ #  # ]:          0 :     ne_request_destroy( req );
    2059                 :            : 
    2060         [ #  # ]:          0 :     if ( pData )
    2061                 :            :     {
    2062                 :            :         // Remove request data from session's list.
    2063         [ #  # ]:          0 :         RequestDataMap::iterator it = pData->find( req );
    2064 [ #  # ][ #  # ]:          0 :         if ( it != pData->end() )
    2065         [ #  # ]:          0 :             pData->erase( it );
    2066                 :            :     }
    2067                 :            : 
    2068                 :          0 :     return ret;
    2069                 :            : }
    2070                 :            : 
    2071                 :            : // -------------------------------------------------------------------
    2072                 :            : // static
    2073                 :            : bool
    2074                 :          0 : NeonSession::getDataFromInputStream(
    2075                 :            :     const uno::Reference< io::XInputStream > & xStream,
    2076                 :            :     uno::Sequence< sal_Int8 > & rData,
    2077                 :            :     bool bAppendTrailingZeroByte )
    2078                 :            : {
    2079         [ #  # ]:          0 :     if ( xStream.is() )
    2080                 :            :     {
    2081         [ #  # ]:          0 :         uno::Reference< io::XSeekable > xSeekable( xStream, uno::UNO_QUERY );
    2082         [ #  # ]:          0 :         if ( xSeekable.is() )
    2083                 :            :         {
    2084                 :            :             try
    2085                 :            :             {
    2086                 :            :                 sal_Int32 nSize
    2087 [ #  # ][ #  # ]:          0 :                     = sal::static_int_cast<sal_Int32>(xSeekable->getLength());
    2088                 :            :                 sal_Int32 nRead
    2089 [ #  # ][ #  # ]:          0 :                     = xStream->readBytes( rData, nSize );
    2090                 :            : 
    2091         [ #  # ]:          0 :                 if ( nRead == nSize )
    2092                 :            :                 {
    2093         [ #  # ]:          0 :                     if ( bAppendTrailingZeroByte )
    2094                 :            :                     {
    2095         [ #  # ]:          0 :                         rData.realloc( nSize + 1 );
    2096         [ #  # ]:          0 :                         rData[ nSize ] = sal_Int8( 0 );
    2097                 :            :                     }
    2098                 :          0 :                     return true;
    2099                 :            :                 }
    2100                 :            :             }
    2101         [ #  # ]:          0 :             catch ( io::NotConnectedException const & )
    2102                 :            :             {
    2103                 :            :                 // readBytes
    2104                 :            :             }
    2105         [ #  # ]:          0 :             catch ( io::BufferSizeExceededException const & )
    2106                 :            :             {
    2107                 :            :                 // readBytes
    2108                 :            :             }
    2109         [ #  # ]:          0 :             catch ( io::IOException const & )
    2110                 :            :             {
    2111                 :            :                 // getLength, readBytes
    2112                 :            :             }
    2113                 :            :         }
    2114                 :            :         else
    2115                 :            :         {
    2116                 :            :             try
    2117                 :            :             {
    2118         [ #  # ]:          0 :                 uno::Sequence< sal_Int8 > aBuffer;
    2119                 :          0 :                 sal_Int32 nPos = 0;
    2120                 :            : 
    2121 [ #  # ][ #  # ]:          0 :                 sal_Int32 nRead = xStream->readSomeBytes( aBuffer, 65536 );
    2122         [ #  # ]:          0 :                 while ( nRead > 0 )
    2123                 :            :                 {
    2124         [ #  # ]:          0 :                     if ( rData.getLength() < ( nPos + nRead ) )
    2125         [ #  # ]:          0 :                         rData.realloc( nPos + nRead );
    2126                 :            : 
    2127         [ #  # ]:          0 :                     aBuffer.realloc( nRead );
    2128         [ #  # ]:          0 :                     rtl_copyMemory( (void*)( rData.getArray() + nPos ),
    2129                 :          0 :                                     (const void*)aBuffer.getConstArray(),
    2130         [ #  # ]:          0 :                                     nRead );
    2131                 :          0 :                     nPos += nRead;
    2132                 :            : 
    2133         [ #  # ]:          0 :                     aBuffer.realloc( 0 );
    2134 [ #  # ][ #  # ]:          0 :                     nRead = xStream->readSomeBytes( aBuffer, 65536 );
    2135                 :            :                 }
    2136                 :            : 
    2137         [ #  # ]:          0 :                 if ( bAppendTrailingZeroByte )
    2138                 :            :                 {
    2139         [ #  # ]:          0 :                     rData.realloc( nPos + 1 );
    2140         [ #  # ]:          0 :                     rData[ nPos ] = sal_Int8( 0 );
    2141                 :            :                 }
    2142         [ #  # ]:          0 :                 return true;
           [ #  #  #  # ]
    2143                 :            :             }
    2144         [ #  # ]:          0 :             catch ( io::NotConnectedException const & )
    2145                 :            :             {
    2146                 :            :                 // readBytes
    2147                 :            :             }
    2148         [ #  # ]:          0 :             catch ( io::BufferSizeExceededException const & )
    2149                 :            :             {
    2150                 :            :                 // readBytes
    2151                 :            :             }
    2152         [ #  # ]:          0 :             catch ( io::IOException const & )
    2153                 :            :             {
    2154                 :            :                 // readBytes
    2155                 :            :             }
    2156         [ #  # ]:          0 :         }
    2157                 :            :     }
    2158   [ #  #  #  # ]:          0 :     return false;
    2159                 :            : }
    2160                 :            : 
    2161                 :            : // ---------------------------------------------------------------------
    2162                 :            : sal_Bool
    2163                 :          0 : NeonSession::isDomainMatch( rtl::OUString certHostName )
    2164                 :            : {
    2165                 :          0 :     rtl::OUString hostName = getHostName();
    2166                 :            : 
    2167         [ #  # ]:          0 :     if (hostName.equalsIgnoreAsciiCase( certHostName ) )
    2168                 :          0 :         return sal_True;
    2169                 :            : 
    2170   [ #  #  #  # ]:          0 :     if ( 0 == certHostName.indexOf( '*' ) &&
                 [ #  # ]
    2171                 :          0 :          hostName.getLength() >= certHostName.getLength()  )
    2172                 :            :     {
    2173                 :          0 :         rtl::OUString cmpStr = certHostName.copy( 1 );
    2174                 :            : 
    2175         [ #  # ]:          0 :         if ( hostName.matchIgnoreAsciiCase(
    2176                 :          0 :                 cmpStr, hostName.getLength() -  cmpStr.getLength() ) )
    2177         [ #  # ]:          0 :             return sal_True;
    2178                 :            :     }
    2179                 :          0 :     return sal_False;
    2180                 :            : }
    2181                 :            : 
    2182                 :            : // ---------------------------------------------------------------------
    2183                 :          0 : rtl::OUString NeonSession::makeAbsoluteURL( rtl::OUString const & rURL ) const
    2184                 :            : {
    2185                 :            :     try
    2186                 :            :     {
    2187                 :            :         // Is URL relative or already absolute?
    2188         [ #  # ]:          0 :         if ( rURL[ 0 ] != sal_Unicode( '/' ) )
    2189                 :            :         {
    2190                 :            :             // absolute.
    2191                 :          0 :             return rtl::OUString( rURL );
    2192                 :            :         }
    2193                 :            :         else
    2194                 :            :         {
    2195                 :            :             ne_uri aUri;
    2196                 :          0 :             memset( &aUri, 0, sizeof( aUri ) );
    2197                 :            : 
    2198         [ #  # ]:          0 :             ne_fill_server_uri( m_pHttpSession, &aUri );
    2199                 :            :             aUri.path
    2200                 :            :                 = ne_strdup( rtl::OUStringToOString(
    2201 [ #  # ][ #  # ]:          0 :                     rURL, RTL_TEXTENCODING_UTF8 ).getStr() );
    2202         [ #  # ]:          0 :             NeonUri aNeonUri( &aUri );
    2203         [ #  # ]:          0 :             ne_uri_free( &aUri );
    2204 [ #  # ][ #  # ]:          0 :             return aNeonUri.GetURI();
    2205                 :            :         }
    2206                 :            :     }
    2207                 :          0 :     catch ( DAVException const & )
    2208                 :            :     {
    2209                 :            :     }
    2210                 :            :     // error.
    2211                 :          0 :     return rtl::OUString();
    2212 [ +  - ][ +  - ]:          6 : }
    2213                 :            : 
    2214                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10