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: */
|