LCOV - code coverage report
Current view: top level - ucbhelper/source/client - proxydecider.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 85 290 29.3 %
Date: 2012-08-25 Functions: 13 23 56.5 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 67 373 18.0 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*
       3                 :            :  * This file is part of the LibreOffice project.
       4                 :            :  *
       5                 :            :  * This Source Code Form is subject to the terms of the Mozilla Public
       6                 :            :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7                 :            :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8                 :            :  *
       9                 :            :  * This file incorporates work covered by the following license notice:
      10                 :            :  *
      11                 :            :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12                 :            :  *   contributor license agreements. See the NOTICE file distributed
      13                 :            :  *   with this work for additional information regarding copyright
      14                 :            :  *   ownership. The ASF licenses this file to you under the Apache
      15                 :            :  *   License, Version 2.0 (the "License"); you may not use this file
      16                 :            :  *   except in compliance with the License. You may obtain a copy of
      17                 :            :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18                 :            :  */
      19                 :            : 
      20                 :            : 
      21                 :            : /**************************************************************************
      22                 :            :                                 TODO
      23                 :            :  **************************************************************************
      24                 :            : 
      25                 :            :  *************************************************************************/
      26                 :            : 
      27                 :            : #include <utility>
      28                 :            : #include <vector>
      29                 :            : #include <list>
      30                 :            : #include <osl/mutex.hxx>
      31                 :            : #include <rtl/ref.hxx>
      32                 :            : #include <osl/socket.hxx>
      33                 :            : #include <rtl/ustrbuf.hxx>
      34                 :            : #include <com/sun/star/container/XNameAccess.hpp>
      35                 :            : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
      36                 :            : #include <com/sun/star/util/XChangesListener.hpp>
      37                 :            : #include <com/sun/star/util/XChangesNotifier.hpp>
      38                 :            : #include <cppuhelper/implbase1.hxx>
      39                 :            : #include "ucbhelper/proxydecider.hxx"
      40                 :            : 
      41                 :            : using namespace com::sun::star;
      42                 :            : using namespace ucbhelper;
      43                 :            : 
      44                 :            : #define CONFIG_ROOT_KEY      "org.openoffice.Inet/Settings"
      45                 :            : #define PROXY_TYPE_KEY       "ooInetProxyType"
      46                 :            : #define NO_PROXY_LIST_KEY    "ooInetNoProxy"
      47                 :            : #define HTTP_PROXY_NAME_KEY  "ooInetHTTPProxyName"
      48                 :            : #define HTTP_PROXY_PORT_KEY  "ooInetHTTPProxyPort"
      49                 :            : #define HTTPS_PROXY_NAME_KEY "ooInetHTTPSProxyName"
      50                 :            : #define HTTPS_PROXY_PORT_KEY "ooInetHTTPSProxyPort"
      51                 :            : #define FTP_PROXY_NAME_KEY   "ooInetFTPProxyName"
      52                 :            : #define FTP_PROXY_PORT_KEY   "ooInetFTPProxyPort"
      53                 :            : 
      54                 :            : //=========================================================================
      55                 :            : namespace ucbhelper
      56                 :            : {
      57                 :            : 
      58                 :            : //=========================================================================
      59                 :            : namespace proxydecider_impl
      60                 :            : {
      61                 :            : 
      62                 :            : // A simple case ignoring wildcard matcher.
      63                 :          0 : class WildCard
      64                 :            : {
      65                 :            : private:
      66                 :            :     rtl::OString m_aWildString;
      67                 :            : 
      68                 :            : public:
      69                 :          0 :     WildCard( const rtl::OUString& rWildCard )
      70                 :            :     : m_aWildString(
      71                 :            :         rtl::OUStringToOString(
      72                 :          0 :             rWildCard, RTL_TEXTENCODING_UTF8 ).toAsciiLowerCase() ) {}
      73                 :            : 
      74                 :            :     bool Matches( const rtl::OUString & rStr ) const;
      75                 :            : };
      76                 :            : 
      77                 :            : //=========================================================================
      78                 :            : typedef std::pair< WildCard, WildCard > NoProxyListEntry;
      79                 :            : 
      80                 :            : //=========================================================================
      81                 :            : 
      82                 :          4 : class HostnameCache
      83                 :            : {
      84                 :            :     typedef std::pair< rtl::OUString, rtl::OUString > HostListEntry;
      85                 :            : 
      86                 :            :     std::list< HostListEntry >     m_aHostList;
      87                 :            :     sal_uInt32                     m_nCapacity;
      88                 :            : 
      89                 :            : public:
      90                 :          4 :     explicit HostnameCache( sal_uInt32 nCapacity )
      91                 :          4 :         : m_nCapacity( nCapacity ) {}
      92                 :            : 
      93                 :          0 :     bool get( const rtl::OUString & rKey, rtl::OUString & rValue ) const
      94                 :            :     {
      95                 :            :         std::list< HostListEntry >::const_iterator it
      96                 :          0 :             = m_aHostList.begin();
      97                 :            :         const std::list< HostListEntry >::const_iterator end
      98                 :          0 :             = m_aHostList.end();
      99                 :            : 
     100         [ #  # ]:          0 :         while ( it != end )
     101                 :            :         {
     102         [ #  # ]:          0 :             if ( (*it).first == rKey )
     103                 :            :             {
     104                 :          0 :                 rValue = (*it).second;
     105                 :          0 :                 return true;
     106                 :            :             }
     107                 :          0 :             ++it;
     108                 :            :         }
     109                 :          0 :         return false;
     110                 :            :     }
     111                 :            : 
     112                 :          0 :     void put( const rtl::OUString & rKey, const rtl::OUString & rValue )
     113                 :            :     {
     114         [ #  # ]:          0 :         if ( m_aHostList.size() == m_nCapacity )
     115                 :          0 :             m_aHostList.resize( m_nCapacity / 2 );
     116                 :            : 
     117         [ #  # ]:          0 :         m_aHostList.push_front( HostListEntry( rKey, rValue ) );
     118                 :          0 :     }
     119                 :            : };
     120                 :            : 
     121                 :            : //=========================================================================
     122                 :            : class InternetProxyDecider_Impl :
     123                 :            :     public cppu::WeakImplHelper1< util::XChangesListener >
     124                 :            : {
     125                 :            :     mutable osl::Mutex                       m_aMutex;
     126                 :            :     InternetProxyServer                      m_aHttpProxy;
     127                 :            :     InternetProxyServer                      m_aHttpsProxy;
     128                 :            :     InternetProxyServer                      m_aFtpProxy;
     129                 :            :     const InternetProxyServer                m_aEmptyProxy;
     130                 :            :     sal_Int32                                m_nProxyType;
     131                 :            :     uno::Reference< util::XChangesNotifier > m_xNotifier;
     132                 :            :     std::vector< NoProxyListEntry >          m_aNoProxyList;
     133                 :            :     mutable HostnameCache                    m_aHostnames;
     134                 :            : 
     135                 :            : private:
     136                 :            :     bool shouldUseProxy( const rtl::OUString & rHost,
     137                 :            :                          sal_Int32 nPort,
     138                 :            :                          bool bUseFullyQualified ) const;
     139                 :            : public:
     140                 :            :     InternetProxyDecider_Impl(
     141                 :            :         const uno::Reference< lang::XMultiServiceFactory >& rxSMgr );
     142                 :            :     virtual ~InternetProxyDecider_Impl();
     143                 :            : 
     144                 :            :     void dispose();
     145                 :            : 
     146                 :            :     const InternetProxyServer & getProxy( const rtl::OUString & rProtocol,
     147                 :            :                                           const rtl::OUString & rHost,
     148                 :            :                                           sal_Int32 nPort ) const;
     149                 :            : 
     150                 :            :     // XChangesListener
     151                 :            :     virtual void SAL_CALL changesOccurred( const util::ChangesEvent& Event )
     152                 :            :         throw( uno::RuntimeException );
     153                 :            : 
     154                 :            :     // XEventListener ( base of XChangesLisetenr )
     155                 :            :     virtual void SAL_CALL disposing( const lang::EventObject& Source )
     156                 :            :         throw( uno::RuntimeException );
     157                 :            : 
     158                 :            : private:
     159                 :            :     void setNoProxyList( const rtl::OUString & rNoProxyList );
     160                 :            : };
     161                 :            : 
     162                 :            : //=========================================================================
     163                 :            : //=========================================================================
     164                 :            : //
     165                 :            : // WildCard Implementation.
     166                 :            : //
     167                 :            : //=========================================================================
     168                 :            : //=========================================================================
     169                 :            : 
     170                 :          0 : bool WildCard::Matches( const rtl::OUString& rString ) const
     171                 :            : {
     172                 :            :     rtl::OString aString
     173                 :            :         = rtl::OUStringToOString(
     174         [ #  # ]:          0 :                     rString, RTL_TEXTENCODING_UTF8 ).toAsciiLowerCase();
     175                 :          0 :     const char * pStr  = aString.getStr();
     176                 :          0 :     const char * pWild = m_aWildString.getStr();
     177                 :            : 
     178                 :          0 :     int pos  = 0;
     179                 :          0 :     int flag = 0;
     180                 :            : 
     181 [ #  # ][ #  # ]:          0 :     while ( *pWild || flag )
                 [ #  # ]
     182                 :            :     {
     183      [ #  #  # ]:          0 :         switch ( *pWild )
     184                 :            :         {
     185                 :            :             case '?':
     186         [ #  # ]:          0 :                 if ( *pStr == '\0' )
     187                 :          0 :                     return 0;
     188                 :          0 :                 break;
     189                 :            : 
     190                 :            :             default:
     191 [ #  # ][ #  # ]:          0 :                 if ( ( *pWild == '\\' ) && ( ( *( pWild + 1 ) == '?' )
                 [ #  # ]
     192                 :          0 :                                              || ( *( pWild + 1 ) == '*') ) )
     193                 :          0 :                     pWild++;
     194         [ #  # ]:          0 :                 if ( *pWild != *pStr )
     195         [ #  # ]:          0 :                     if ( !pos )
     196                 :          0 :                         return 0;
     197                 :            :                     else
     198                 :          0 :                         pWild += pos;
     199                 :            :                 else
     200                 :          0 :                     break;
     201                 :            : 
     202                 :            :                 // Note: fall-thru's are intended!
     203                 :            : 
     204                 :            :             case '*':
     205         [ #  # ]:          0 :                 while ( *pWild == '*' )
     206                 :          0 :                     pWild++;
     207         [ #  # ]:          0 :                 if ( *pWild == '\0' )
     208                 :          0 :                     return 1;
     209                 :          0 :                 flag = 1;
     210                 :          0 :                 pos  = 0;
     211         [ #  # ]:          0 :                 if ( *pStr == '\0' )
     212                 :          0 :                     return ( *pWild == '\0' );
     213 [ #  # ][ #  # ]:          0 :                 while ( *pStr && *pStr != *pWild )
                 [ #  # ]
     214                 :            :                 {
     215         [ #  # ]:          0 :                     if ( *pWild == '?' ) {
     216                 :          0 :                         pWild++;
     217         [ #  # ]:          0 :                         while ( *pWild == '*' )
     218                 :          0 :                             pWild++;
     219                 :            :                     }
     220                 :          0 :                     pStr++;
     221         [ #  # ]:          0 :                     if ( *pStr == '\0' )
     222                 :          0 :                         return ( *pWild == '\0' );
     223                 :            :                 }
     224                 :          0 :                 break;
     225                 :            :         }
     226         [ #  # ]:          0 :         if ( *pWild != '\0' )
     227                 :          0 :             pWild++;
     228         [ #  # ]:          0 :         if ( *pStr != '\0' )
     229                 :          0 :             pStr++;
     230                 :            :         else
     231                 :          0 :             flag = 0;
     232         [ #  # ]:          0 :         if ( flag )
     233                 :          0 :             pos--;
     234                 :            :     }
     235 [ #  # ][ #  # ]:          0 :     return ( *pStr == '\0' ) && ( *pWild == '\0' );
     236                 :            : }
     237                 :            : 
     238                 :            : //=========================================================================
     239                 :         16 : bool getConfigStringValue(
     240                 :            :     const uno::Reference< container::XNameAccess > & xNameAccess,
     241                 :            :     const char * key,
     242                 :            :     rtl::OUString & value )
     243                 :            : {
     244                 :            :     try
     245                 :            :     {
     246   [ +  -  -  + ]:         32 :         if ( !( xNameAccess->getByName( rtl::OUString::createFromAscii( key ) )
     247         [ +  - ]:         16 :                 >>= value ) )
              [ #  #  # ]
     248                 :            :         {
     249                 :            :             OSL_FAIL( "InternetProxyDecider - "
     250                 :            :                         "Error getting config item value!" );
     251                 :          0 :             return false;
     252                 :            :         }
     253                 :            :     }
     254                 :          0 :     catch ( lang::WrappedTargetException const & )
     255                 :            :     {
     256                 :          0 :         return false;
     257                 :            :     }
     258                 :          0 :     catch ( container::NoSuchElementException const & )
     259                 :            :     {
     260                 :          0 :         return false;
     261                 :            :     }
     262                 :         16 :     return true;
     263                 :            : }
     264                 :            : 
     265                 :            : //=========================================================================
     266                 :         16 : bool getConfigInt32Value(
     267                 :            :     const uno::Reference< container::XNameAccess > & xNameAccess,
     268                 :            :     const char * key,
     269                 :            :     sal_Int32 & value )
     270                 :            : {
     271                 :            :     try
     272                 :            :     {
     273         [ +  - ]:         16 :         uno::Any aValue = xNameAccess->getByName(
     274         [ +  - ]:         16 :             rtl::OUString::createFromAscii( key ) );
              [ #  #  # ]
     275 [ -  + ][ -  + ]:         16 :         if ( aValue.hasValue() && !( aValue >>= value ) )
                 [ +  + ]
     276                 :            :         {
     277                 :            :             OSL_FAIL( "InternetProxyDecider - "
     278                 :            :                         "Error getting config item value!" );
     279                 :         16 :             return false;
     280         [ +  - ]:         16 :         }
     281                 :            :     }
     282                 :          0 :     catch ( lang::WrappedTargetException const & )
     283                 :            :     {
     284                 :          0 :         return false;
     285                 :            :     }
     286                 :          0 :     catch ( container::NoSuchElementException const & )
     287                 :            :     {
     288                 :          0 :         return false;
     289                 :            :     }
     290                 :         16 :     return true;
     291                 :            : }
     292                 :            : 
     293                 :            : //=========================================================================
     294                 :            : //=========================================================================
     295                 :            : //
     296                 :            : // InternetProxyDecider_Impl Implementation.
     297                 :            : //
     298                 :            : //=========================================================================
     299                 :            : //=========================================================================
     300                 :            : 
     301                 :          4 : InternetProxyDecider_Impl::InternetProxyDecider_Impl(
     302                 :            :     const uno::Reference< lang::XMultiServiceFactory >& rxSMgr )
     303                 :            :     : m_nProxyType( 0 ),
     304 [ +  - ][ +  - ]:          4 :       m_aHostnames( 256 ) // cache size
                 [ +  - ]
     305                 :            : {
     306                 :            :     try
     307                 :            :     {
     308                 :            :         //////////////////////////////////////////////////////////////
     309                 :            :         // Read proxy configuration from config db.
     310                 :            :         //////////////////////////////////////////////////////////////
     311                 :            : 
     312                 :            :         uno::Reference< lang::XMultiServiceFactory > xConfigProv(
     313         [ +  - ]:          4 :                 rxSMgr->createInstance(
     314                 :            :                     rtl::OUString(
     315                 :          4 :                         "com.sun.star.configuration.ConfigurationProvider" ) ),
     316 [ +  - ][ +  - ]:          4 :                 uno::UNO_QUERY );
     317                 :            : 
     318         [ +  - ]:          4 :         uno::Sequence< uno::Any > aArguments( 1 );
     319 [ +  - ][ +  - ]:          4 :         aArguments[ 0 ] <<= rtl::OUString( CONFIG_ROOT_KEY );
     320                 :            : 
     321                 :            :         uno::Reference< uno::XInterface > xInterface(
     322         [ +  - ]:          4 :                     xConfigProv->createInstanceWithArguments(
     323                 :            :                         rtl::OUString(
     324                 :            :                             "com.sun.star.configuration.ConfigurationAccess" ),
     325         [ +  - ]:          4 :                     aArguments ) );
     326                 :            : 
     327                 :            :         OSL_ENSURE( xInterface.is(),
     328                 :            :                     "InternetProxyDecider - No config access!" );
     329                 :            : 
     330         [ +  - ]:          4 :         if ( xInterface.is() )
     331                 :            :         {
     332                 :            :             uno::Reference< container::XNameAccess > xNameAccess(
     333         [ +  - ]:          4 :                                             xInterface, uno::UNO_QUERY );
     334                 :            :             OSL_ENSURE( xNameAccess.is(),
     335                 :            :                         "InternetProxyDecider - No name access!" );
     336                 :            : 
     337         [ +  - ]:          4 :             if ( xNameAccess.is() )
     338                 :            :             {
     339                 :            :                 // *** Proxy type ***
     340                 :            :                 getConfigInt32Value(
     341         [ +  - ]:          4 :                     xNameAccess, PROXY_TYPE_KEY, m_nProxyType );
     342                 :            : 
     343                 :            :                 // *** No proxy list ***
     344                 :          4 :                 rtl::OUString aNoProxyList;
     345                 :            :                 getConfigStringValue(
     346         [ +  - ]:          4 :                     xNameAccess, NO_PROXY_LIST_KEY, aNoProxyList );
     347         [ +  - ]:          4 :                 setNoProxyList( aNoProxyList );
     348                 :            : 
     349                 :            :                 // *** HTTP ***
     350                 :            :                 getConfigStringValue(
     351         [ +  - ]:          4 :                     xNameAccess, HTTP_PROXY_NAME_KEY, m_aHttpProxy.aName );
     352                 :            : 
     353                 :          4 :                 m_aHttpProxy.nPort = -1;
     354                 :            :                 getConfigInt32Value(
     355         [ +  - ]:          4 :                     xNameAccess, HTTP_PROXY_PORT_KEY, m_aHttpProxy.nPort );
     356         [ +  - ]:          4 :                 if ( m_aHttpProxy.nPort == -1 )
     357                 :          4 :                     m_aHttpProxy.nPort = 80; // standard HTTP port.
     358                 :            : 
     359                 :            :                 // *** HTTPS ***
     360                 :            :                 getConfigStringValue(
     361         [ +  - ]:          4 :                     xNameAccess, HTTPS_PROXY_NAME_KEY, m_aHttpsProxy.aName );
     362                 :            : 
     363                 :          4 :                 m_aHttpsProxy.nPort = -1;
     364                 :            :                 getConfigInt32Value(
     365         [ +  - ]:          4 :                     xNameAccess, HTTPS_PROXY_PORT_KEY, m_aHttpsProxy.nPort );
     366         [ +  - ]:          4 :                 if ( m_aHttpsProxy.nPort == -1 )
     367                 :          4 :                     m_aHttpsProxy.nPort = 443; // standard HTTPS port.
     368                 :            : 
     369                 :            :                 // *** FTP ***
     370                 :            :                 getConfigStringValue(
     371         [ +  - ]:          4 :                     xNameAccess, FTP_PROXY_NAME_KEY, m_aFtpProxy.aName );
     372                 :            : 
     373                 :          4 :                 m_aFtpProxy.nPort = -1;
     374                 :            :                 getConfigInt32Value(
     375         [ +  - ]:          4 :                     xNameAccess, FTP_PROXY_PORT_KEY, m_aFtpProxy.nPort );
     376                 :            :             }
     377                 :            : 
     378                 :            :             // Register as listener for config changes.
     379                 :            : 
     380                 :            :             m_xNotifier = uno::Reference< util::XChangesNotifier >(
     381 [ +  - ][ +  - ]:          4 :                                                 xInterface, uno::UNO_QUERY );
     382                 :            : 
     383                 :            :             OSL_ENSURE( m_xNotifier.is(),
     384                 :            :                         "InternetProxyDecider - No notifier!" );
     385                 :            : 
     386         [ +  - ]:          4 :             if ( m_xNotifier.is() )
     387 [ +  - ][ +  - ]:          4 :                 m_xNotifier->addChangesListener( this );
                 [ +  - ]
     388 [ +  - ][ #  # ]:          4 :         }
     389                 :            :     }
     390         [ #  # ]:          0 :     catch ( uno::Exception const & )
     391                 :            :     {
     392                 :            :         // createInstance, createInstanceWithArguments
     393                 :            :         OSL_FAIL( "InternetProxyDecider - Exception!" );
     394                 :            :     }
     395                 :          4 : }
     396                 :            : 
     397                 :            : //=========================================================================
     398                 :            : // virtual
     399         [ +  - ]:          4 : InternetProxyDecider_Impl::~InternetProxyDecider_Impl()
     400                 :            : {
     401         [ -  + ]:          8 : }
     402                 :            : 
     403                 :            : //=========================================================================
     404                 :          4 : void InternetProxyDecider_Impl::dispose()
     405                 :            : {
     406                 :          4 :     uno::Reference< util::XChangesNotifier > xNotifier;
     407                 :            : 
     408         [ +  - ]:          4 :     if ( m_xNotifier.is() )
     409                 :            :     {
     410         [ +  - ]:          4 :         osl::Guard< osl::Mutex > aGuard( m_aMutex );
     411                 :            : 
     412         [ +  - ]:          4 :         if ( m_xNotifier.is() )
     413                 :            :         {
     414         [ +  - ]:          4 :             xNotifier = m_xNotifier;
     415                 :          4 :             m_xNotifier.clear();
     416         [ +  - ]:          4 :         }
     417                 :            :     }
     418                 :            : 
     419                 :            :     // Do this unguarded!
     420         [ +  - ]:          4 :     if ( xNotifier.is() )
     421 [ +  - ][ +  - ]:          4 :         xNotifier->removeChangesListener( this );
                 [ +  - ]
     422                 :          4 : }
     423                 :            : 
     424                 :            : //=========================================================================
     425                 :          0 : bool InternetProxyDecider_Impl::shouldUseProxy( const rtl::OUString & rHost,
     426                 :            :                                                 sal_Int32 nPort,
     427                 :            :                                                 bool bUseFullyQualified ) const
     428                 :            : {
     429                 :          0 :     rtl::OUStringBuffer aBuffer;
     430                 :            : 
     431         [ #  # ]:          0 :     if ( ( rHost.indexOf( ':' ) != -1 ) &&
           [ #  #  #  # ]
     432                 :          0 :          ( rHost[ 0 ] != sal_Unicode( '[' ) ) )
     433                 :            :     {
     434                 :            :         // host is given as numeric IPv6 address
     435         [ #  # ]:          0 :         aBuffer.appendAscii( "[" );
     436         [ #  # ]:          0 :         aBuffer.append( rHost );
     437         [ #  # ]:          0 :         aBuffer.appendAscii( "]" );
     438                 :            :     }
     439                 :            :     else
     440                 :            :     {
     441                 :            :         // host is given either as numeric IPv4 address or non-numeric hostname
     442         [ #  # ]:          0 :         aBuffer.append( rHost );
     443                 :            :     }
     444                 :            : 
     445         [ #  # ]:          0 :     aBuffer.append( sal_Unicode( ':' ) );
     446         [ #  # ]:          0 :     aBuffer.append( rtl::OUString::valueOf( nPort ) );
     447         [ #  # ]:          0 :     const rtl::OUString aHostAndPort( aBuffer.makeStringAndClear() );
     448                 :            : 
     449                 :            :     std::vector< NoProxyListEntry >::const_iterator it
     450                 :          0 :         = m_aNoProxyList.begin();
     451                 :            :     const std::vector< NoProxyListEntry >::const_iterator end
     452                 :          0 :         = m_aNoProxyList.end();
     453                 :            : 
     454 [ #  # ][ #  # ]:          0 :     while ( it != end )
     455                 :            :     {
     456         [ #  # ]:          0 :         if ( bUseFullyQualified )
     457                 :            :         {
     458 [ #  # ][ #  # ]:          0 :             if ( (*it).second.Matches( aHostAndPort ) )
     459                 :          0 :                 return false;
     460                 :            :         }
     461                 :            :         else
     462                 :            :         {
     463 [ #  # ][ #  # ]:          0 :             if ( (*it).first.Matches( aHostAndPort ) )
     464                 :          0 :                 return false;
     465                 :            :         }
     466                 :          0 :         ++it;
     467                 :            :     }
     468                 :            : 
     469                 :          0 :     return true;
     470                 :            : }
     471                 :            : 
     472                 :            : //=========================================================================
     473                 :          4 : const InternetProxyServer & InternetProxyDecider_Impl::getProxy(
     474                 :            :                                             const rtl::OUString & rProtocol,
     475                 :            :                                             const rtl::OUString & rHost,
     476                 :            :                                             sal_Int32 nPort ) const
     477                 :            : {
     478         [ +  - ]:          4 :     osl::Guard< osl::Mutex > aGuard( m_aMutex );
     479                 :            : 
     480         [ -  + ]:          4 :     if ( m_nProxyType == 0 )
     481                 :            :     {
     482                 :            :         // Never use proxy.
     483                 :          0 :         return m_aEmptyProxy;
     484                 :            :     }
     485                 :            : 
     486 [ +  + ][ -  + ]:          4 :     if ( !rHost.isEmpty() && !m_aNoProxyList.empty() )
                 [ -  + ]
     487                 :            :     {
     488                 :            :         //////////////////////////////////////////////////////////////////
     489                 :            :         // First, try direct hostname match - #110515#
     490                 :            :         //////////////////////////////////////////////////////////////////
     491                 :            : 
     492 [ #  # ][ #  # ]:          0 :         if ( !shouldUseProxy( rHost, nPort, false ) )
     493                 :          0 :             return m_aEmptyProxy;
     494                 :            : 
     495                 :            :         //////////////////////////////////////////////////////////////////
     496                 :            :         // Second, try match against full qualified hostname - #104401#
     497                 :            :         //////////////////////////////////////////////////////////////////
     498                 :            : 
     499                 :          0 :         rtl::OUString aHost;
     500                 :            : 
     501         [ #  # ]:          0 :         if ( ( rHost[ 0 ] == sal_Unicode( '[' ) ) &&
           [ #  #  #  # ]
     502                 :          0 :              ( rHost.getLength() > 1 ) )
     503                 :            :         {
     504                 :            :             // host is given as numeric IPv6 address. name resolution
     505                 :            :             // functions need hostname without square brackets.
     506                 :          0 :             aHost = rHost.copy( 1, rHost.getLength() - 2 );
     507                 :            :         }
     508                 :            :         else
     509                 :            :         {
     510                 :          0 :             aHost = rHost;
     511                 :            :         }
     512                 :            : 
     513                 :          0 :         rtl::OUString aFullyQualifiedHost;
     514 [ #  # ][ #  # ]:          0 :         if ( !m_aHostnames.get( aHost, aFullyQualifiedHost ) )
     515                 :            :         {
     516                 :            :             // This might be quite expensive (DNS lookup).
     517         [ #  # ]:          0 :             const osl::SocketAddr aAddr( aHost, nPort );
     518         [ #  # ]:          0 :             aFullyQualifiedHost = aAddr.getHostname().toAsciiLowerCase();
     519 [ #  # ][ #  # ]:          0 :             m_aHostnames.put( aHost, aFullyQualifiedHost );
     520                 :            :         }
     521                 :            : 
     522                 :            :         // Error resolving name? -> fallback.
     523         [ #  # ]:          0 :         if ( aFullyQualifiedHost.isEmpty() )
     524                 :          0 :             aFullyQualifiedHost = aHost;
     525                 :            : 
     526         [ #  # ]:          0 :         if ( aFullyQualifiedHost != aHost )
     527                 :            :         {
     528 [ #  # ][ #  # ]:          0 :             if ( !shouldUseProxy( aFullyQualifiedHost, nPort, false ) )
     529                 :          0 :                 return m_aEmptyProxy;
     530                 :            :         }
     531                 :            : 
     532                 :            :         //////////////////////////////////////////////////////////////////
     533                 :            :         // Third, try match of fully qualified entries in no-proxy list
     534                 :            :         // against full qualified hostname
     535                 :            :         //
     536                 :            :         // Example:
     537                 :            :         // list: staroffice-doc -> full: xyz.germany.sun.com
     538                 :            :         // in:   staroffice-doc.germany.sun.com -> full: xyz.germany.sun.com
     539                 :            :         //
     540                 :            :         //////////////////////////////////////////////////////////////////
     541                 :            : 
     542 [ #  # ][ #  # ]:          0 :         if ( !shouldUseProxy( aFullyQualifiedHost, nPort, true ) )
     543 [ #  # ][ #  # ]:          0 :             return m_aEmptyProxy;
     544                 :            :     }
     545                 :            : 
     546         [ +  - ]:          4 :     if ( rProtocol.toAsciiLowerCase() == "ftp" )
     547                 :            :     {
     548 [ -  + ][ #  # ]:          4 :         if ( !m_aFtpProxy.aName.isEmpty() && m_aFtpProxy.nPort >= 0 )
                 [ -  + ]
     549                 :          0 :             return m_aFtpProxy;
     550                 :            :     }
     551         [ #  # ]:          0 :     else if ( rProtocol.toAsciiLowerCase() == "https" )
     552                 :            :     {
     553         [ #  # ]:          0 :         if ( !m_aHttpsProxy.aName.isEmpty() )
     554                 :          0 :             return m_aHttpsProxy;
     555                 :            :     }
     556         [ #  # ]:          0 :     else if ( !m_aHttpProxy.aName.isEmpty() )
     557                 :            :     {
     558                 :            :         // All other protocols use the HTTP proxy.
     559                 :          0 :         return m_aHttpProxy;
     560                 :            :     }
     561         [ +  - ]:          4 :     return m_aEmptyProxy;
     562                 :            : }
     563                 :            : 
     564                 :            : //=========================================================================
     565                 :            : // virtual
     566                 :          0 : void SAL_CALL InternetProxyDecider_Impl::changesOccurred(
     567                 :            :                                         const util::ChangesEvent& Event )
     568                 :            :     throw( uno::RuntimeException )
     569                 :            : {
     570         [ #  # ]:          0 :     osl::Guard< osl::Mutex > aGuard( m_aMutex );
     571                 :            : 
     572                 :          0 :     sal_Int32 nCount = Event.Changes.getLength();
     573         [ #  # ]:          0 :     if ( nCount )
     574                 :            :     {
     575                 :            :         const util::ElementChange* pElementChanges
     576                 :          0 :             = Event.Changes.getConstArray();
     577         [ #  # ]:          0 :         for ( sal_Int32 n = 0; n < nCount; ++n )
     578                 :            :         {
     579                 :          0 :             const util::ElementChange& rElem = pElementChanges[ n ];
     580                 :          0 :             rtl::OUString aKey;
     581 [ #  # ][ #  # ]:          0 :             if ( ( rElem.Accessor >>= aKey ) && !aKey.isEmpty() )
                 [ #  # ]
     582                 :            :             {
     583         [ #  # ]:          0 :                 if ( aKey == PROXY_TYPE_KEY )
     584                 :            :                 {
     585                 :          0 :                     if ( !( rElem.Element >>= m_nProxyType ) )
     586                 :            :                     {
     587                 :            :                         OSL_FAIL( "InternetProxyDecider - changesOccurred - "
     588                 :            :                                     "Error getting config item value!" );
     589                 :            :                     }
     590                 :            :                 }
     591         [ #  # ]:          0 :                 else if ( aKey == NO_PROXY_LIST_KEY )
     592                 :            :                 {
     593                 :          0 :                     rtl::OUString aNoProxyList;
     594                 :          0 :                     if ( !( rElem.Element >>= aNoProxyList ) )
     595                 :            :                     {
     596                 :            :                         OSL_FAIL( "InternetProxyDecider - changesOccurred - "
     597                 :            :                                     "Error getting config item value!" );
     598                 :            :                     }
     599                 :            : 
     600         [ #  # ]:          0 :                     setNoProxyList( aNoProxyList );
     601                 :            :                 }
     602         [ #  # ]:          0 :                 else if ( aKey == HTTP_PROXY_NAME_KEY )
     603                 :            :                 {
     604                 :          0 :                     if ( !( rElem.Element >>= m_aHttpProxy.aName ) )
     605                 :            :                     {
     606                 :            :                         OSL_FAIL( "InternetProxyDecider - changesOccurred - "
     607                 :            :                                     "Error getting config item value!" );
     608                 :            :                     }
     609                 :            :                 }
     610         [ #  # ]:          0 :                 else if ( aKey == HTTP_PROXY_PORT_KEY )
     611                 :            :                 {
     612                 :          0 :                     if ( !( rElem.Element >>= m_aHttpProxy.nPort ) )
     613                 :            :                     {
     614                 :            :                         OSL_FAIL( "InternetProxyDecider - changesOccurred - "
     615                 :            :                                     "Error getting config item value!" );
     616                 :            :                     }
     617                 :            : 
     618         [ #  # ]:          0 :                     if ( m_aHttpProxy.nPort == -1 )
     619                 :          0 :                         m_aHttpProxy.nPort = 80; // standard HTTP port.
     620                 :            :                 }
     621         [ #  # ]:          0 :                 else if ( aKey == HTTPS_PROXY_NAME_KEY )
     622                 :            :                 {
     623                 :          0 :                     if ( !( rElem.Element >>= m_aHttpsProxy.aName ) )
     624                 :            :                     {
     625                 :            :                         OSL_FAIL( "InternetProxyDecider - changesOccurred - "
     626                 :            :                                     "Error getting config item value!" );
     627                 :            :                     }
     628                 :            :                 }
     629         [ #  # ]:          0 :                 else if ( aKey == HTTPS_PROXY_PORT_KEY )
     630                 :            :                 {
     631                 :          0 :                     if ( !( rElem.Element >>= m_aHttpsProxy.nPort ) )
     632                 :            :                     {
     633                 :            :                         OSL_FAIL( "InternetProxyDecider - changesOccurred - "
     634                 :            :                                     "Error getting config item value!" );
     635                 :            :                     }
     636                 :            : 
     637         [ #  # ]:          0 :                     if ( m_aHttpsProxy.nPort == -1 )
     638                 :          0 :                         m_aHttpsProxy.nPort = 443; // standard HTTPS port.
     639                 :            :                 }
     640         [ #  # ]:          0 :                 else if ( aKey == FTP_PROXY_NAME_KEY )
     641                 :            :                 {
     642                 :          0 :                     if ( !( rElem.Element >>= m_aFtpProxy.aName ) )
     643                 :            :                     {
     644                 :            :                         OSL_FAIL( "InternetProxyDecider - changesOccurred - "
     645                 :            :                                     "Error getting config item value!" );
     646                 :            :                     }
     647                 :            :                 }
     648         [ #  # ]:          0 :                 else if ( aKey == FTP_PROXY_PORT_KEY )
     649                 :            :                 {
     650                 :          0 :                     if ( !( rElem.Element >>= m_aFtpProxy.nPort ) )
     651                 :            :                     {
     652                 :            :                         OSL_FAIL( "InternetProxyDecider - changesOccurred - "
     653                 :            :                                     "Error getting config item value!" );
     654                 :            :                     }
     655                 :            :                 }
     656                 :            :             }
     657                 :          0 :         }
     658         [ #  # ]:          0 :     }
     659                 :          0 : }
     660                 :            : 
     661                 :            : //=========================================================================
     662                 :            : // virtual
     663                 :          0 : void SAL_CALL InternetProxyDecider_Impl::disposing(const lang::EventObject&)
     664                 :            :     throw( uno::RuntimeException )
     665                 :            : {
     666         [ #  # ]:          0 :     if ( m_xNotifier.is() )
     667                 :            :     {
     668         [ #  # ]:          0 :         osl::Guard< osl::Mutex > aGuard( m_aMutex );
     669                 :            : 
     670         [ #  # ]:          0 :         if ( m_xNotifier.is() )
     671         [ #  # ]:          0 :             m_xNotifier.clear();
     672                 :            :     }
     673                 :          0 : }
     674                 :            : 
     675                 :            : //=========================================================================
     676                 :          4 : void InternetProxyDecider_Impl::setNoProxyList(
     677                 :            :                                         const rtl::OUString & rNoProxyList )
     678                 :            : {
     679         [ +  - ]:          4 :     osl::Guard< osl::Mutex > aGuard( m_aMutex );
     680                 :            : 
     681                 :          4 :     m_aNoProxyList.clear();
     682                 :            : 
     683         [ -  + ]:          4 :     if ( !rNoProxyList.isEmpty() )
     684                 :            :     {
     685                 :            :         // List of connection endpoints hostname[:port],
     686                 :            :         // separated by semicolon. Wilcards allowed.
     687                 :            : 
     688                 :          0 :         sal_Int32 nPos = 0;
     689                 :          0 :         sal_Int32 nEnd = rNoProxyList.indexOf( ';' );
     690                 :          0 :         sal_Int32 nLen = rNoProxyList.getLength();
     691                 :            : 
     692         [ #  # ]:          0 :         do
     693                 :            :         {
     694         [ #  # ]:          0 :             if ( nEnd == -1 )
     695                 :          0 :                 nEnd = nLen;
     696                 :            : 
     697                 :          0 :             rtl::OUString aToken = rNoProxyList.copy( nPos, nEnd - nPos );
     698                 :            : 
     699         [ #  # ]:          0 :             if ( !aToken.isEmpty() )
     700                 :            :             {
     701                 :          0 :                 rtl::OUString aServer;
     702                 :          0 :                 rtl::OUString aPort;
     703                 :            : 
     704                 :            :                 // numerical IPv6 address?
     705                 :          0 :                 bool bIPv6Address = false;
     706                 :          0 :                 sal_Int32 nClosedBracketPos = aToken.indexOf( ']' );
     707         [ #  # ]:          0 :                 if ( nClosedBracketPos == -1 )
     708                 :          0 :                     nClosedBracketPos = 0;
     709                 :            :                 else
     710                 :          0 :                     bIPv6Address = true;
     711                 :            : 
     712                 :          0 :                 sal_Int32 nColonPos = aToken.indexOf( ':', nClosedBracketPos );
     713         [ #  # ]:          0 :                 if ( nColonPos == -1 )
     714                 :            :                 {
     715                 :            :                     // No port given, server pattern equals current token
     716                 :          0 :                     aPort = rtl::OUString("*");
     717         [ #  # ]:          0 :                     if ( aToken.indexOf( '*' ) == -1 )
     718                 :            :                     {
     719                 :            :                         // pattern describes exactly one server
     720                 :          0 :                         aServer = aToken;
     721                 :            :                     }
     722                 :            : 
     723                 :          0 :                     aToken += rtl::OUString(":*");
     724                 :            :                 }
     725                 :            :                 else
     726                 :            :                 {
     727                 :            :                     // Port given, extract server pattern
     728                 :          0 :                     sal_Int32 nAsterixPos = aToken.indexOf( '*' );
     729                 :          0 :                     aPort = aToken.copy( nColonPos + 1 );
     730         [ #  # ]:          0 :                     if ( nAsterixPos < nColonPos )
     731                 :            :                     {
     732                 :            :                         // pattern describes exactly one server
     733                 :          0 :                         aServer = aToken.copy( 0, nColonPos );
     734                 :            :                     }
     735                 :            :                 }
     736                 :            : 
     737                 :          0 :                 rtl::OUStringBuffer aFullyQualifiedHost;
     738         [ #  # ]:          0 :                 if ( !aServer.isEmpty() )
     739                 :            :                 {
     740                 :            :                     // Remember fully qualified server name if current list
     741                 :            :                     // entry specifies exactly one non-fully qualified server
     742                 :            :                     // name.
     743                 :            : 
     744                 :            :                     // remove square brackets from host name in case it's
     745                 :            :                     // a numerical IPv6 address.
     746         [ #  # ]:          0 :                     if ( bIPv6Address )
     747                 :          0 :                         aServer = aServer.copy( 1, aServer.getLength() - 2 );
     748                 :            : 
     749                 :            :                     // This might be quite expensive (DNS lookup).
     750         [ #  # ]:          0 :                     const osl::SocketAddr aAddr( aServer, 0 );
     751         [ #  # ]:          0 :                     rtl::OUString aTmp = aAddr.getHostname().toAsciiLowerCase();
     752         [ #  # ]:          0 :                     if ( aTmp != aServer.toAsciiLowerCase() )
     753                 :            :                     {
     754         [ #  # ]:          0 :                         if ( bIPv6Address )
     755                 :            :                         {
     756         [ #  # ]:          0 :                             aFullyQualifiedHost.appendAscii( "[" );
     757         [ #  # ]:          0 :                             aFullyQualifiedHost.append( aTmp );
     758         [ #  # ]:          0 :                             aFullyQualifiedHost.appendAscii( "]" );
     759                 :            :                         }
     760                 :            :                         else
     761                 :            :                         {
     762         [ #  # ]:          0 :                             aFullyQualifiedHost.append( aTmp );
     763                 :            :                         }
     764         [ #  # ]:          0 :                         aFullyQualifiedHost.appendAscii( ":" );
     765         [ #  # ]:          0 :                         aFullyQualifiedHost.append( aPort );
     766         [ #  # ]:          0 :                     }
     767                 :            :                 }
     768                 :            : 
     769                 :            :                 m_aNoProxyList.push_back(
     770                 :            :                     NoProxyListEntry( WildCard( aToken ),
     771                 :            :                                       WildCard(
     772                 :            :                                         aFullyQualifiedHost
     773 [ #  # ][ #  # ]:          0 :                                             .makeStringAndClear() ) ) );
         [ #  # ][ #  # ]
     774                 :            :             }
     775                 :            : 
     776         [ #  # ]:          0 :             if ( nEnd != nLen )
     777                 :            :             {
     778                 :          0 :                 nPos = nEnd + 1;
     779                 :          0 :                 nEnd = rNoProxyList.indexOf( ';', nPos );
     780                 :          0 :             }
     781                 :            :         }
     782                 :            :         while ( nEnd != nLen );
     783         [ +  - ]:          4 :     }
     784                 :          4 : }
     785                 :            : 
     786                 :            : } // namespace proxydecider_impl
     787                 :            : 
     788                 :            : //=========================================================================
     789                 :            : //=========================================================================
     790                 :            : //
     791                 :            : // InternetProxyDecider Implementation.
     792                 :            : //
     793                 :            : //=========================================================================
     794                 :            : //=========================================================================
     795                 :            : 
     796                 :          4 : InternetProxyDecider::InternetProxyDecider(
     797                 :            :     const uno::Reference< lang::XMultiServiceFactory >& rxSMgr )
     798         [ +  - ]:          4 : : m_pImpl( new proxydecider_impl::InternetProxyDecider_Impl( rxSMgr ) )
     799                 :            : {
     800                 :          4 :     m_pImpl->acquire();
     801                 :          4 : }
     802                 :            : 
     803                 :            : //=========================================================================
     804                 :          4 : InternetProxyDecider::~InternetProxyDecider()
     805                 :            : {
     806                 :            :     // Break circular reference between config listener and notifier.
     807                 :          4 :     m_pImpl->dispose();
     808                 :            : 
     809                 :            :     // Let him go...
     810                 :          4 :     m_pImpl->release();
     811                 :          4 : }
     812                 :            : 
     813                 :            : //=========================================================================
     814                 :          4 : bool InternetProxyDecider::shouldUseProxy( const rtl::OUString & rProtocol,
     815                 :            :                                            const rtl::OUString & rHost,
     816                 :            :                                            sal_Int32 nPort ) const
     817                 :            : {
     818                 :            :     const InternetProxyServer & rData = m_pImpl->getProxy( rProtocol,
     819                 :            :                                                            rHost,
     820                 :          4 :                                                            nPort );
     821                 :          4 :     return !rData.aName.isEmpty();
     822                 :            : }
     823                 :            : 
     824                 :            : //=========================================================================
     825                 :          0 : const InternetProxyServer & InternetProxyDecider::getProxy(
     826                 :            :                                             const rtl::OUString & rProtocol,
     827                 :            :                                             const rtl::OUString & rHost,
     828                 :            :                                             sal_Int32 nPort ) const
     829                 :            : {
     830                 :          0 :     return m_pImpl->getProxy( rProtocol, rHost, nPort );
     831                 :            : }
     832                 :            : 
     833                 :            : } // namespace ucbhelper
     834                 :            : 
     835                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10