OLD | NEW |
1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/http/http_network_transaction.h" | 5 #include "net/http/http_network_transaction.h" |
6 | 6 |
7 #include "base/scoped_ptr.h" | 7 #include "base/scoped_ptr.h" |
8 #include "base/compiler_specific.h" | 8 #include "base/compiler_specific.h" |
9 #include "base/field_trial.h" | 9 #include "base/field_trial.h" |
10 #include "base/histogram.h" | 10 #include "base/histogram.h" |
(...skipping 495 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
506 if (request_->load_flags & LOAD_BYPASS_PROXY) { | 506 if (request_->load_flags & LOAD_BYPASS_PROXY) { |
507 proxy_info_.UseDirect(); | 507 proxy_info_.UseDirect(); |
508 return OK; | 508 return OK; |
509 } | 509 } |
510 | 510 |
511 return session_->proxy_service()->ResolveProxy( | 511 return session_->proxy_service()->ResolveProxy( |
512 request_->url, &proxy_info_, &io_callback_, &pac_request_, load_log_); | 512 request_->url, &proxy_info_, &io_callback_, &pac_request_, load_log_); |
513 } | 513 } |
514 | 514 |
515 int HttpNetworkTransaction::DoResolveProxyComplete(int result) { | 515 int HttpNetworkTransaction::DoResolveProxyComplete(int result) { |
516 next_state_ = STATE_INIT_CONNECTION; | 516 |
| 517 pac_request_ = NULL; |
517 | 518 |
518 // Remove unsupported proxies from the list. | 519 // Remove unsupported proxies from the list. |
519 proxy_info_.RemoveProxiesWithoutScheme( | 520 proxy_info_.RemoveProxiesWithoutScheme( |
520 ProxyServer::SCHEME_DIRECT | ProxyServer::SCHEME_HTTP | | 521 ProxyServer::SCHEME_DIRECT | ProxyServer::SCHEME_HTTP | |
521 ProxyServer::SCHEME_SOCKS4 | ProxyServer::SCHEME_SOCKS5); | 522 ProxyServer::SCHEME_SOCKS4 | ProxyServer::SCHEME_SOCKS5); |
522 | 523 |
523 pac_request_ = NULL; | 524 // There are four possible outcomes of having run the ProxyService: |
| 525 // (1) The ProxyService decided we should connect through a proxy. |
| 526 // (2) The ProxyService decided we should direct-connect. |
| 527 // (3) The ProxyService decided we should give up, as there are no more |
| 528 // proxies to try (this is more likely to happen during |
| 529 // ReconsiderProxyAfterError()). |
| 530 // (4) The ProxyService failed (which can happen if the PAC script |
| 531 // we were configured with threw a runtime exception). |
| 532 // |
| 533 // It is important that we fail the connection in case (3) rather than |
| 534 // falling-back to a direct connection, since sending traffic through |
| 535 // a proxy may be integral to the user's privacy/security model. |
| 536 // |
| 537 // For example if a user had configured traffic to go through the TOR |
| 538 // anonymizing proxy to protect their privacy, it would be bad if we |
| 539 // silently fell-back to direct connect if the proxy server were to |
| 540 // become unreachable. |
| 541 // |
| 542 // In case (4) it is less obvious what the right thing to do is. On the |
| 543 // one hand, for consistency it would be natural to hard-fail as well. |
| 544 // However, both Firefox 3.5 and Internet Explorer 8 will silently fall-back |
| 545 // to DIRECT in this case, so we will do the same for compatibility. |
| 546 // |
| 547 // For more information, see: |
| 548 // http://www.chromium.org/developers/design-documents/proxy-settings-fallback |
| 549 |
| 550 if (proxy_info_.is_empty()) { |
| 551 // No proxies/direct to choose from. This happens when we don't support any |
| 552 // of the proxies in the returned list. |
| 553 return ERR_NO_SUPPORTED_PROXIES; |
| 554 } |
524 | 555 |
525 if (result != OK) { | 556 if (result != OK) { |
526 DLOG(ERROR) << "Failed to resolve proxy: " << result; | 557 DLOG(ERROR) << "Failed to resolve proxy: " << result; |
| 558 // Fall-back to direct when there were runtime errors in the PAC script, |
| 559 // or some other failure with the settings. |
527 proxy_info_.UseDirect(); | 560 proxy_info_.UseDirect(); |
528 } | 561 } |
| 562 |
| 563 next_state_ = STATE_INIT_CONNECTION; |
529 return OK; | 564 return OK; |
530 } | 565 } |
531 | 566 |
532 int HttpNetworkTransaction::DoInitConnection() { | 567 int HttpNetworkTransaction::DoInitConnection() { |
533 DCHECK(!connection_.is_initialized()); | 568 DCHECK(!connection_.is_initialized()); |
| 569 DCHECK(proxy_info_.proxy_server().is_valid()); |
534 | 570 |
535 next_state_ = STATE_INIT_CONNECTION_COMPLETE; | 571 next_state_ = STATE_INIT_CONNECTION_COMPLETE; |
536 | 572 |
537 using_ssl_ = request_->url.SchemeIs("https"); | 573 using_ssl_ = request_->url.SchemeIs("https"); |
538 | 574 |
539 if (proxy_info_.is_direct()) | 575 if (proxy_info_.is_direct()) |
540 proxy_mode_ = kDirectConnection; | 576 proxy_mode_ = kDirectConnection; |
541 else if (proxy_info_.proxy_server().is_socks()) | 577 else if (proxy_info_.proxy_server().is_socks()) |
542 proxy_mode_ = kSOCKSProxy; | 578 proxy_mode_ = kSOCKSProxy; |
543 else if (using_ssl_) | 579 else if (using_ssl_) |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
637 | 673 |
638 next_state_ = STATE_SOCKS_CONNECT_COMPLETE; | 674 next_state_ = STATE_SOCKS_CONNECT_COMPLETE; |
639 | 675 |
640 // Add a SOCKS connection on top of our existing transport socket. | 676 // Add a SOCKS connection on top of our existing transport socket. |
641 ClientSocket* s = connection_.release_socket(); | 677 ClientSocket* s = connection_.release_socket(); |
642 HostResolver::RequestInfo req_info(request_->url.HostNoBrackets(), | 678 HostResolver::RequestInfo req_info(request_->url.HostNoBrackets(), |
643 request_->url.EffectiveIntPort()); | 679 request_->url.EffectiveIntPort()); |
644 req_info.set_referrer(request_->referrer); | 680 req_info.set_referrer(request_->referrer); |
645 | 681 |
646 if (proxy_info_.proxy_server().scheme() == ProxyServer::SCHEME_SOCKS5) | 682 if (proxy_info_.proxy_server().scheme() == ProxyServer::SCHEME_SOCKS5) |
647 s = new SOCKS5ClientSocket(s, req_info, session_->host_resolver()); | 683 s = new SOCKS5ClientSocket(s, req_info); |
648 else | 684 else |
649 s = new SOCKSClientSocket(s, req_info, session_->host_resolver()); | 685 s = new SOCKSClientSocket(s, req_info, session_->host_resolver()); |
650 connection_.set_socket(s); | 686 connection_.set_socket(s); |
651 return connection_.socket()->Connect(&io_callback_, load_log_); | 687 return connection_.socket()->Connect(&io_callback_, load_log_); |
652 } | 688 } |
653 | 689 |
654 int HttpNetworkTransaction::DoSOCKSConnectComplete(int result) { | 690 int HttpNetworkTransaction::DoSOCKSConnectComplete(int result) { |
655 DCHECK_EQ(kSOCKSProxy, proxy_mode_); | 691 DCHECK_EQ(kSOCKSProxy, proxy_mode_); |
656 | 692 |
657 if (result == OK) { | 693 if (result == OK) { |
(...skipping 749 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1407 int rv = session_->proxy_service()->ReconsiderProxyAfterError( | 1443 int rv = session_->proxy_service()->ReconsiderProxyAfterError( |
1408 request_->url, &proxy_info_, &io_callback_, &pac_request_, load_log_); | 1444 request_->url, &proxy_info_, &io_callback_, &pac_request_, load_log_); |
1409 if (rv == OK || rv == ERR_IO_PENDING) { | 1445 if (rv == OK || rv == ERR_IO_PENDING) { |
1410 // If the error was during connection setup, there is no socket to | 1446 // If the error was during connection setup, there is no socket to |
1411 // disconnect. | 1447 // disconnect. |
1412 if (connection_.socket()) | 1448 if (connection_.socket()) |
1413 connection_.socket()->Disconnect(); | 1449 connection_.socket()->Disconnect(); |
1414 connection_.Reset(); | 1450 connection_.Reset(); |
1415 next_state_ = STATE_RESOLVE_PROXY_COMPLETE; | 1451 next_state_ = STATE_RESOLVE_PROXY_COMPLETE; |
1416 } else { | 1452 } else { |
| 1453 // If ReconsiderProxyAfterError() failed synchronously, it means |
| 1454 // there was nothing left to fall-back to, so fail the transaction |
| 1455 // with the last connection error we got. |
| 1456 // TODO(eroman): This is a confusing contract, make it more obvious. |
1417 rv = error; | 1457 rv = error; |
1418 } | 1458 } |
1419 | 1459 |
1420 return rv; | 1460 return rv; |
1421 } | 1461 } |
1422 | 1462 |
1423 bool HttpNetworkTransaction::ShouldApplyProxyAuth() const { | 1463 bool HttpNetworkTransaction::ShouldApplyProxyAuth() const { |
1424 return (proxy_mode_ == kHTTPProxy) || establishing_tunnel_; | 1464 return (proxy_mode_ == kHTTPProxy) || establishing_tunnel_; |
1425 } | 1465 } |
1426 | 1466 |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1684 AuthChallengeInfo* auth_info = new AuthChallengeInfo; | 1724 AuthChallengeInfo* auth_info = new AuthChallengeInfo; |
1685 auth_info->is_proxy = target == HttpAuth::AUTH_PROXY; | 1725 auth_info->is_proxy = target == HttpAuth::AUTH_PROXY; |
1686 auth_info->host_and_port = ASCIIToWide(GetHostAndPort(auth_origin)); | 1726 auth_info->host_and_port = ASCIIToWide(GetHostAndPort(auth_origin)); |
1687 auth_info->scheme = ASCIIToWide(auth_handler_[target]->scheme()); | 1727 auth_info->scheme = ASCIIToWide(auth_handler_[target]->scheme()); |
1688 // TODO(eroman): decode realm according to RFC 2047. | 1728 // TODO(eroman): decode realm according to RFC 2047. |
1689 auth_info->realm = ASCIIToWide(auth_handler_[target]->realm()); | 1729 auth_info->realm = ASCIIToWide(auth_handler_[target]->realm()); |
1690 http_stream_->GetResponseInfo()->auth_challenge = auth_info; | 1730 http_stream_->GetResponseInfo()->auth_challenge = auth_info; |
1691 } | 1731 } |
1692 | 1732 |
1693 } // namespace net | 1733 } // namespace net |
OLD | NEW |