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

Generated by: LCOV version 1.11