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