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