diff options
author | Kai Sommerfeld <kso@openoffice.org> | 2002-10-28 15:05:22 +0000 |
---|---|---|
committer | Kai Sommerfeld <kso@openoffice.org> | 2002-10-28 15:05:22 +0000 |
commit | dfff706198e151ac84dbe5f9ecc96e0709d2f3ff (patch) | |
tree | c95269e69765d2137de7b5c35ab9fb502781429c /ucbhelper | |
parent | 4ab9e299b94ef01dadcd3dfda986b9623969e42d (diff) |
#104432# - Introduced class ucbhelper::ProxyDecider
Diffstat (limited to 'ucbhelper')
-rw-r--r-- | ucbhelper/inc/ucbhelper/proxydecider.hxx | 180 | ||||
-rw-r--r-- | ucbhelper/prj/d.lst | 1 | ||||
-rw-r--r-- | ucbhelper/source/client/makefile.mk | 9 | ||||
-rw-r--r-- | ucbhelper/source/client/proxydecider.cxx | 717 |
4 files changed, 903 insertions, 4 deletions
diff --git a/ucbhelper/inc/ucbhelper/proxydecider.hxx b/ucbhelper/inc/ucbhelper/proxydecider.hxx new file mode 100644 index 000000000000..cff4f99d3aa8 --- /dev/null +++ b/ucbhelper/inc/ucbhelper/proxydecider.hxx @@ -0,0 +1,180 @@ +/************************************************************************* + * + * $RCSfile: proxydecider.hxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: kso $ $Date: 2002-10-28 16:05:17 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Kai Sommerfeld ( kso@sun.com ) + * + * + ************************************************************************/ + +#ifndef _UCBHELPER_PROXYDECIDER_HXX +#define _UCBHELPER_PROXYDECIDER_HXX + +#ifndef _RTL_USTRING_HXX_ +#include <rtl/ustring.hxx> +#endif +#ifndef _COM_SUN_STAR_UNO_REFERENCE_HXX_ +#include <com/sun/star/uno/Reference.hXX> +#endif + +namespace com { namespace sun { namespace star { namespace lang { + class XMultiServiceFactory; +} } } } + +namespace ucbhelper +{ + +/** + * This struct describes a proxy server. + */ +struct InternetProxyServer +{ + /** + * The name of the proxy server. + */ + ::rtl::OUString aName; + + /** + * The port of the proxy server. + */ + sal_Int32 nPort; + + /** + * Constructor. + */ + InternetProxyServer() : nPort( -1 ) {} +}; + +namespace proxydecider_impl { class InternetProxyDecider_Impl; } + +/** + * This class is able to decide whether and which internet proxy server is to + * be used to access a given URI. + * + * The implementation reads the internet proxy settings from Office + * configuration. It listens for configuration changes and adapts itself + * accordingly. Because configuration data can change during runtime clients + * should not cache results obtained from InternetProxyDecider instances. One + * instance should be kept to be queried multiple times instead. + */ +class InternetProxyDecider +{ +public: + /** + * Constructor. + * + * Note: Every instance should be held alive as long as possible because + * because construction is quite expensive. + * + * @param rxSMgr is a Service Manager. + */ + InternetProxyDecider( const ::com::sun::star::uno::Reference< + ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr ); + + /** + * Destructor. + */ + ~InternetProxyDecider(); + + /** + * Informs whether a proxy server should be used. + * + * @param rProtocol contains the internet protocol to be used to + * access the server (i.e. "ftp", "http"). The protocol string + * is handled case-insensitive and must not be empty. + * @param rHost contains the name of the server that should be accessed. + * This parameter might be left empty. In this case the + * implementation will return whether a proxy is configured + * for the given protocol. + * @param nPort contains the port of the server that should be accessed. + * If host is not empty this parameter must always contain a valid + * port number, for instance the default port for the requested + * protocol(i.e. 80 or http). + * @return true if a proxy server should be used, false otherwise. + */ + bool + shouldUseProxy( const rtl::OUString & rProtocol, + const rtl::OUString & rHost, + sal_Int32 nPort ) const; + + /** + * Returns the proxy server to be used. + * + * @param rProtocol contains the internet protocol to be used to + * access the server (i.e. "ftp", "http"). The protocol string + * is handled case-insensitive and must not be empty. + * @param rHost contains the name of the server that should be accessed. + * This parameter might be left empty. In this case the + * implementation will return the proxy that is configured + * for the given protocol. + * @param nPort contains the port of the server that should be accessed. + * If host is not empty this parameter must always contain a valid + * port number, for instance the default port for the requested + * protocol(i.e. 80 or http). + * @return a InternetProxyServer reference. If member aName of the + * InternetProxyServer is empty no proxy server is to be used. + */ + const InternetProxyServer & + getProxy( const rtl::OUString & rProtocol, + const rtl::OUString & rHost, + sal_Int32 nPort ) const; + +private: + proxydecider_impl::InternetProxyDecider_Impl * m_pImpl; +}; + +} // namespace ucbhelper + +#endif /* !_UCBHELPER_PROXYDECIDER_HXX */ diff --git a/ucbhelper/prj/d.lst b/ucbhelper/prj/d.lst index 9948732999eb..39bac37b6ca5 100644 --- a/ucbhelper/prj/d.lst +++ b/ucbhelper/prj/d.lst @@ -34,6 +34,7 @@ mkdir: %_DEST%\inc%_EXT%\ucbhelper ..\inc\ucbhelper\simpleioerrorrequest.hxx %_DEST%\inc%_EXT%\ucbhelper\simpleioerrorrequest.hxx ..\inc\ucbhelper\cancelcommandexecution.hxx %_DEST%\inc%_EXT%\ucbhelper\cancelcommandexecution.hxx ..\inc\ucbhelper\handleinteractionrequest.hxx %_DEST%\inc%_EXT%\ucbhelper\handleinteractionrequest.hxx +..\inc\ucbhelper\proxydecider.hxx %_DEST%\inc%_EXT%\ucbhelper\proxydecider.hxx ..\version.mk %_DEST%\inc%_EXT%\ucbhelper\version.mk ..\%__SRC%\lib\lib*static*.dylib %_DEST%\lib%_EXT%\lib*static*.dylib diff --git a/ucbhelper/source/client/makefile.mk b/ucbhelper/source/client/makefile.mk index c273b0cf49ed..16f1ea21df91 100644 --- a/ucbhelper/source/client/makefile.mk +++ b/ucbhelper/source/client/makefile.mk @@ -2,9 +2,9 @@ # # $RCSfile: makefile.mk,v $ # -# $Revision: 1.8 $ +# $Revision: 1.9 $ # -# last change: $Author: vg $ $Date: 2002-04-05 09:57:24 $ +# last change: $Author: kso $ $Date: 2002-10-28 16:05:21 $ # # The Contents of this file are made available subject to the terms of # either of the following licenses @@ -82,8 +82,9 @@ SLOFILES=\ $(SLO)$/content.obj \ $(SLO)$/contentbroker.obj \ $(SLO)$/commandenvironment.obj \ - $(SLO)$/fileidentifierconverter.obj \ - $(SLO)$/activedatasink.obj + $(SLO)$/fileidentifierconverter.obj \ + $(SLO)$/activedatasink.obj \ + $(SLO)$/proxydecider.obj .ENDIF diff --git a/ucbhelper/source/client/proxydecider.cxx b/ucbhelper/source/client/proxydecider.cxx new file mode 100644 index 000000000000..5a704ea586b2 --- /dev/null +++ b/ucbhelper/source/client/proxydecider.cxx @@ -0,0 +1,717 @@ +/************************************************************************* + * + * $RCSfile: proxydecider.cxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: kso $ $Date: 2002-10-28 16:05:22 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +/************************************************************************** + TODO + ************************************************************************** + + *************************************************************************/ + +#include <vector> + +#ifndef _OSL_MUTEX_HXX_ +#include <osl/mutex.hxx> +#endif +#ifndef _RTL_REF_HXX_ +#include <rtl/ref.hxx> +#ifndef _OSL_SOCKET_HXX_ +#include <osl/socket.hxx> +#endif +#endif +#ifndef _RTL_USTRBUF_HXX_ +#include <rtl/ustrbuf.hxx> +#endif +#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_ +#include <com/sun/star/container/XNameAccess.hpp> +#endif +#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_ +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#endif +#ifndef _COM_SUN_STAR_UTIL_XCHANGESLISTENER_HPP_ +#include <com/sun/star/util/XChangesListener.hpp> +#endif +#ifndef _COM_SUN_STAR_UTIL_XCHANGESNOTIFIER_HPP_ +#include <com/sun/star/util/XChangesNotifier.hpp> +#endif +#ifndef _CPPUHELPER_IMPLBASE1_HXX_ +#include <cppuhelper/implbase1.hxx> +#endif +#ifndef _UCBHELPER_PROXYDECIDER_HXX +#include "ucbhelper/proxydecider.hxx" +#endif + +using namespace com::sun::star; +using namespace ucbhelper; + +#define CONFIG_ROOT_KEY "org.openoffice.Inet/Settings" +#define PROXY_TYPE_KEY "ooInetProxyType" +#define NO_PROXY_LIST_KEY "ooInetNoProxy" +#define HTTP_PROXY_NAME_KEY "ooInetHTTPProxyName" +#define HTTP_PROXY_PORT_KEY "ooInetHTTPProxyPort" +#define FTP_PROXY_NAME_KEY "ooInetFTPProxyName" +#define FTP_PROXY_PORT_KEY "ooInetFTPProxyPort" + +//========================================================================= +namespace ucbhelper +{ + +//========================================================================= +namespace proxydecider_impl +{ + +// A simple case ignoring wildcard matcher. +class WildCard +{ +private: + rtl::OString m_aWildString; + +public: + WildCard( const rtl::OUString& rWildCard ) + : m_aWildString( + rtl::OUStringToOString( + rWildCard, RTL_TEXTENCODING_UTF8 ).toAsciiLowerCase() ) {} + + bool Matches( const rtl::OUString & rStr ) const; +}; + +//========================================================================= +class InternetProxyDecider_Impl : + public cppu::WeakImplHelper1< util::XChangesListener > +{ + mutable osl::Mutex m_aMutex; + InternetProxyServer m_aHttpProxy; + InternetProxyServer m_aFtpProxy; + const InternetProxyServer m_aEmptyProxy; + sal_Int32 m_nProxyType; + uno::Reference< util::XChangesNotifier > m_xNotifier; + std::vector< WildCard > m_aNoProxyList; + +public: + InternetProxyDecider_Impl( + const uno::Reference< lang::XMultiServiceFactory >& rxSMgr ); + virtual ~InternetProxyDecider_Impl(); + + static rtl::Reference< InternetProxyDecider_Impl > createInstance( + const uno::Reference< lang::XMultiServiceFactory >& rxSMgr ); + + void dispose(); + + const InternetProxyServer & getProxy( const rtl::OUString & rProtocol, + const rtl::OUString & rHost, + sal_Int32 nPort ) const; + + // XChangesListener + virtual void SAL_CALL changesOccurred( const util::ChangesEvent& Event ) + throw( uno::RuntimeException ); + + // XEventListener ( base of XChangesLisetenr ) + virtual void SAL_CALL disposing( const lang::EventObject& Source ) + throw( uno::RuntimeException ); + +private: + void setNoProxyList( const rtl::OUString & rNoProxyList ); +}; + +//========================================================================= +//========================================================================= +// +// WildCard Implementation. +// +//========================================================================= +//========================================================================= + +bool WildCard::Matches( const rtl::OUString& rString ) const +{ + rtl::OString aString + = rtl::OUStringToOString( + rString, RTL_TEXTENCODING_UTF8 ).toAsciiLowerCase(); + const char * pStr = aString.getStr(); + const char * pWild = m_aWildString.getStr(); + + int pos = 0; + int flag = 0; + + while ( *pWild || flag ) + { + switch ( *pWild ) + { + case '?': + if ( *pStr == '\0' ) + return 0; + break; + + default: + if ( ( *pWild == '\\' ) && ( ( *( pWild + 1 ) == '?' ) + || ( *( pWild + 1 ) == '*') ) ) + pWild++; + if ( *pWild != *pStr ) + if ( !pos ) + return 0; + else + pWild += pos; + else + break; + + // Note: fall-thru's are intended! + + case '*': + while ( *pWild == '*' ) + pWild++; + if ( *pWild == '\0' ) + return 1; + flag = 1; + pos = 0; + if ( *pStr == '\0' ) + return ( *pWild == '\0' ); + while ( *pStr && *pStr != *pWild ) + { + if ( *pWild == '?' ) { + pWild++; + while ( *pWild == '*' ) + pWild++; + } + pStr++; + if ( *pStr == '\0' ) + return ( *pWild == '\0' ); + } + break; + } + if ( *pWild != '\0' ) + pWild++; + if ( *pStr != '\0' ) + pStr++; + else + flag = 0; + if ( flag ) + pos--; + } + return ( *pStr == '\0' ) && ( *pWild == '\0' ); +} + +//========================================================================= +//========================================================================= +// +// InternetProxyDecider_Impl Implementation. +// +//========================================================================= +//========================================================================= + +InternetProxyDecider_Impl::InternetProxyDecider_Impl( + const uno::Reference< lang::XMultiServiceFactory >& rxSMgr ) +: m_nProxyType( 0 ) +{ + try + { + ////////////////////////////////////////////////////////////// + // Read proxy configuration from config db. + ////////////////////////////////////////////////////////////// + + uno::Reference< lang::XMultiServiceFactory > xConfigProv( + rxSMgr->createInstance( + rtl::OUString::createFromAscii( + "com.sun.star.configuration.ConfigurationProvider" ) ), + uno::UNO_QUERY ); + + uno::Sequence< uno::Any > aArguments( 1 ); + aArguments[ 0 ] <<= rtl::OUString::createFromAscii( CONFIG_ROOT_KEY ); + + uno::Reference< uno::XInterface > xInterface( + xConfigProv->createInstanceWithArguments( + rtl::OUString::createFromAscii( + "com.sun.star.configuration.ConfigurationAccess" ), + aArguments ) ); + + OSL_ENSURE( xInterface.is(), + "InternetProxyDecider - No config access!" ); + + if ( xInterface.is() ) + { + uno::Reference< container::XNameAccess > xNameAccess( + xInterface, uno::UNO_QUERY ); + OSL_ENSURE( xNameAccess.is(), + "InternetProxyDecider - No name access!" ); + + if ( xNameAccess.is() ) + { + try + { + if ( !( xNameAccess->getByName( + rtl::OUString::createFromAscii( + PROXY_TYPE_KEY ) ) >>= m_nProxyType ) ) + { + OSL_ENSURE( sal_False, + "InternetProxyDecider - " + "Error getting config item value!" ); + } + } + catch ( lang::WrappedTargetException const & ) + { + } + catch ( container::NoSuchElementException const & ) + { + } + + rtl::OUString aNoProxyList; + try + { + if ( !( xNameAccess->getByName( + rtl::OUString::createFromAscii( + NO_PROXY_LIST_KEY ) ) >>= aNoProxyList ) ) + { + OSL_ENSURE( sal_False, + "InternetProxyDecider - " + "Error getting config item value!" ); + } + } + catch ( lang::WrappedTargetException const & ) + { + } + catch ( container::NoSuchElementException const & ) + { + } + + setNoProxyList( aNoProxyList ); + + try + { + if ( !( xNameAccess->getByName( + rtl::OUString::createFromAscii( + HTTP_PROXY_NAME_KEY ) ) + >>= m_aHttpProxy.aName ) ) + { + OSL_ENSURE( sal_False, + "InternetProxyDecider - " + "Error getting config item value!" ); + } + } + catch ( lang::WrappedTargetException const & ) + { + } + catch ( container::NoSuchElementException const & ) + { + } + + m_aHttpProxy.nPort = -1; + try + { + uno::Any aValue = xNameAccess->getByName( + rtl::OUString::createFromAscii( + HTTP_PROXY_PORT_KEY ) ); + if ( aValue.hasValue() && + !( aValue >>= m_aHttpProxy.nPort ) ) + { + OSL_ENSURE( sal_False, + "InternetProxyDecider - " + "Error getting config item value!" ); + } + } + catch ( lang::WrappedTargetException const & ) + { + } + catch ( container::NoSuchElementException const & ) + { + } + + if ( m_aHttpProxy.nPort == -1 ) + m_aHttpProxy.nPort = 80; // standard HTTP port. + + try + { + if ( !( xNameAccess->getByName( + rtl::OUString::createFromAscii( + FTP_PROXY_NAME_KEY ) ) + >>= m_aFtpProxy.aName ) ) + { + OSL_ENSURE( sal_False, + "InternetProxyDecider - " + "Error getting config item value!" ); + } + } + catch ( lang::WrappedTargetException const & ) + { + } + catch ( container::NoSuchElementException const & ) + { + } + + m_aFtpProxy.nPort = -1; + try + { + uno::Any aValue = xNameAccess->getByName( + rtl::OUString::createFromAscii( + FTP_PROXY_PORT_KEY ) ); + if ( aValue.hasValue() && + !( aValue >>= m_aFtpProxy.nPort ) ) + { + OSL_ENSURE( sal_False, + "InternetProxyDecider - " + "Error getting config item value!" ); + } + } + catch ( lang::WrappedTargetException const & ) + { + } + catch ( container::NoSuchElementException const & ) + { + } + } + + // Register as listener for config changes. + + m_xNotifier = uno::Reference< util::XChangesNotifier >( + xInterface, uno::UNO_QUERY ); + + OSL_ENSURE( m_xNotifier.is(), + "InternetProxyDecider - No notifier!" ); + + if ( m_xNotifier.is() ) + m_xNotifier->addChangesListener( this ); + } + } + catch ( uno::Exception const & ) + { + // createInstance, createInstanceWithArguments + OSL_ENSURE( sal_False, "InternetProxyDecider - Exception!" ); + } +} + +//========================================================================= +// virtual +InternetProxyDecider_Impl::~InternetProxyDecider_Impl() +{ +} + +//========================================================================= +void InternetProxyDecider_Impl::dispose() +{ + uno::Reference< util::XChangesNotifier > xNotifier; + + if ( m_xNotifier.is() ) + { + osl::Guard< osl::Mutex > aGuard( m_aMutex ); + + if ( m_xNotifier.is() ) + { + xNotifier = m_xNotifier; + m_xNotifier.clear(); + } + } + + // Do this unguarded! + if ( xNotifier.is() ) + xNotifier->removeChangesListener( this ); +} + +//========================================================================= +const InternetProxyServer & InternetProxyDecider_Impl::getProxy( + const rtl::OUString & rProtocol, + const rtl::OUString & rHost, + sal_Int32 nPort ) const +{ + osl::Guard< osl::Mutex > aGuard( m_aMutex ); + + if ( m_nProxyType == 0 ) + { + // Never use proxy. + return m_aEmptyProxy; + } + + if ( rHost.getLength() && m_aNoProxyList.size() ) + { + // #104401# + // Obtain fully qualified hostname. This might be quite expensive + // (DNS lookup). + const osl::SocketAddr aAddr( rHost, nPort ); + rtl::OUString aHost( aAddr.getHostname().toAsciiLowerCase() ); + // #104401# + + // Error resolving name? -> fallback. + if ( !aHost.getLength() ) + aHost = rHost; + + rtl::OUStringBuffer aBuffer( aHost ); + aBuffer.append( sal_Unicode( ':' ) ); + aBuffer.append( rtl::OUString::valueOf( nPort ) ); + const rtl::OUString aHostAndPort( aBuffer ); + + std::vector< WildCard >::const_iterator it + = m_aNoProxyList.begin(); + const std::vector< WildCard >::const_iterator end + = m_aNoProxyList.end(); + + while ( it != end ) + { + if ( (*it).Matches( aHostAndPort ) ) + return m_aEmptyProxy; + + it++; + } + } + + if ( rProtocol.toAsciiLowerCase() + .equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ftp" ) ) ) + { + if ( m_aFtpProxy.aName.getLength() > 0 && m_aFtpProxy.nPort >= 0 ) + return m_aFtpProxy; + } + else if ( m_aHttpProxy.aName.getLength() ) + { + // All other protocols use the HTTP proxy. + return m_aHttpProxy; + } + return m_aEmptyProxy; +} + +//========================================================================= +// virtual +void SAL_CALL InternetProxyDecider_Impl::changesOccurred( + const util::ChangesEvent& Event ) + throw( uno::RuntimeException ) +{ + osl::Guard< osl::Mutex > aGuard( m_aMutex ); + + sal_Int32 nCount = Event.Changes.getLength(); + if ( nCount ) + { + const util::ElementChange* pElementChanges + = Event.Changes.getConstArray(); + for ( sal_Int32 n = 0; n < nCount; ++n ) + { + const util::ElementChange& rElem = pElementChanges[ n ]; + rtl::OUString aKey; + if ( ( rElem.Accessor >>= aKey ) && aKey.getLength() ) + { + if ( aKey.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( + PROXY_TYPE_KEY ) ) ) + { + if ( !( rElem.Element >>= m_nProxyType ) ) + { + OSL_ENSURE( sal_False, + "InternetProxyDecider - changesOccurred - " + "Error getting config item value!" ); + } + } + else if ( aKey.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( + NO_PROXY_LIST_KEY ) ) ) + { + rtl::OUString aNoProxyList; + if ( !( rElem.Element >>= aNoProxyList ) ) + { + OSL_ENSURE( sal_False, + "InternetProxyDecider - changesOccurred - " + "Error getting config item value!" ); + } + + setNoProxyList( aNoProxyList ); + } + else if ( aKey.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( + HTTP_PROXY_NAME_KEY ) ) ) + { + if ( !( rElem.Element >>= m_aHttpProxy.aName ) ) + { + OSL_ENSURE( sal_False, + "InternetProxyDecider - changesOccurred - " + "Error getting config item value!" ); + } + } + else if ( aKey.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( + HTTP_PROXY_PORT_KEY ) ) ) + { + if ( !( rElem.Element >>= m_aHttpProxy.nPort ) ) + { + OSL_ENSURE( sal_False, + "InternetProxyDecider - changesOccurred - " + "Error getting config item value!" ); + } + + if ( m_aHttpProxy.nPort == -1 ) + m_aHttpProxy.nPort = 80; // standard HTTP port. + } + else if ( aKey.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( + FTP_PROXY_NAME_KEY ) ) ) + { + if ( !( rElem.Element >>= m_aFtpProxy.aName ) ) + { + OSL_ENSURE( sal_False, + "InternetProxyDecider - changesOccurred - " + "Error getting config item value!" ); + } + } + else if ( aKey.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( + FTP_PROXY_PORT_KEY ) ) ) + { + if ( !( rElem.Element >>= m_aFtpProxy.nPort ) ) + { + OSL_ENSURE( sal_False, + "InternetProxyDecider - changesOccurred - " + "Error getting config item value!" ); + } + } + } + } + } +} + +//========================================================================= +// virtual +void SAL_CALL InternetProxyDecider_Impl::disposing( + const lang::EventObject& Source ) + throw( uno::RuntimeException ) +{ + if ( m_xNotifier.is() ) + { + osl::Guard< osl::Mutex > aGuard( m_aMutex ); + + if ( m_xNotifier.is() ) + m_xNotifier.clear(); + } +} + +//========================================================================= +void InternetProxyDecider_Impl::setNoProxyList( + const rtl::OUString & rNoProxyList ) +{ + osl::Guard< osl::Mutex > aGuard( m_aMutex ); + + m_aNoProxyList.clear(); + + if ( rNoProxyList.getLength() ) + { + // List of connection endpoints hostname[:port], + // separated by semicolon. Wilcards allowed. + + sal_Int32 nPos = 0; + sal_Int32 nEnd = rNoProxyList.indexOf( ';' ); + sal_Int32 nLen = rNoProxyList.getLength(); + + do + { + if ( nEnd == -1 ) + nEnd = nLen; + + rtl::OUString aToken = rNoProxyList.copy( nPos, nEnd - nPos ); + + if ( aToken.getLength() ) + { + if ( aToken.indexOf( ':' ) == -1 ) + aToken += rtl::OUString::createFromAscii( ":*" ); + + m_aNoProxyList.push_back( WildCard( aToken ) ); + } + + if ( nEnd != nLen ) + { + nPos = nEnd + 1; + nEnd = rNoProxyList.indexOf( ';', nPos ); + } + } + while ( nEnd != nLen ); + } +} + +} // namespace proxydecider_impl + +//========================================================================= +//========================================================================= +// +// InternetProxyDecider Implementation. +// +//========================================================================= +//========================================================================= + +InternetProxyDecider::InternetProxyDecider( + const uno::Reference< lang::XMultiServiceFactory >& rxSMgr ) +: m_pImpl( new proxydecider_impl::InternetProxyDecider_Impl( rxSMgr ) ) +{ + m_pImpl->acquire(); +} + +//========================================================================= +InternetProxyDecider::~InternetProxyDecider() +{ + // Break circular reference between config listener and notifier. + m_pImpl->dispose(); + + // Let him go... + m_pImpl->release(); +} + +//========================================================================= +bool InternetProxyDecider::shouldUseProxy( const rtl::OUString & rProtocol, + const rtl::OUString & rHost, + sal_Int32 nPort ) const +{ + const InternetProxyServer & rData = m_pImpl->getProxy( rProtocol, + rHost, + nPort ); + return ( rData.aName.getLength() > 0 ); +} + +//========================================================================= +const InternetProxyServer & InternetProxyDecider::getProxy( + const rtl::OUString & rProtocol, + const rtl::OUString & rHost, + sal_Int32 nPort ) const +{ + return m_pImpl->getProxy( rProtocol, rHost, nPort ); +} + +} // namespace ucbhelper |