LCOV - code coverage report
Current view: top level - ucbhelper/source/client - proxydecider.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 83 289 28.7 %
Date: 2014-11-03 Functions: 13 24 54.2 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10