Chromium Code Reviews| 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/format_macros.h" | 7 #include "base/format_macros.h" |
| 8 #include "base/scoped_ptr.h" | 8 #include "base/scoped_ptr.h" |
| 9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
| 10 #include "base/field_trial.h" | 10 #include "base/field_trial.h" |
| (...skipping 558 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 569 if (request_->load_flags & LOAD_BYPASS_PROXY) { | 569 if (request_->load_flags & LOAD_BYPASS_PROXY) { |
| 570 proxy_info_.UseDirect(); | 570 proxy_info_.UseDirect(); |
| 571 return OK; | 571 return OK; |
| 572 } | 572 } |
| 573 | 573 |
| 574 return session_->proxy_service()->ResolveProxy( | 574 return session_->proxy_service()->ResolveProxy( |
| 575 request_->url, &proxy_info_, &io_callback_, &pac_request_, load_log_); | 575 request_->url, &proxy_info_, &io_callback_, &pac_request_, load_log_); |
| 576 } | 576 } |
| 577 | 577 |
| 578 int HttpNetworkTransaction::DoResolveProxyComplete(int result) { | 578 int HttpNetworkTransaction::DoResolveProxyComplete(int result) { |
| 579 next_state_ = STATE_INIT_CONNECTION; | 579 |
|
wtc
2010/01/07 20:12:27
Nit: remove this blank line.
| |
| 580 pac_request_ = NULL; | |
| 580 | 581 |
| 581 // Remove unsupported proxies from the list. | 582 // Remove unsupported proxies from the list. |
| 582 proxy_info_.RemoveProxiesWithoutScheme( | 583 proxy_info_.RemoveProxiesWithoutScheme( |
| 583 ProxyServer::SCHEME_DIRECT | ProxyServer::SCHEME_HTTP | | 584 ProxyServer::SCHEME_DIRECT | ProxyServer::SCHEME_HTTP | |
| 584 ProxyServer::SCHEME_SOCKS4 | ProxyServer::SCHEME_SOCKS5); | 585 ProxyServer::SCHEME_SOCKS4 | ProxyServer::SCHEME_SOCKS5); |
| 585 | 586 |
| 586 pac_request_ = NULL; | 587 // There are four possible outcomes of having run the ProxyService: |
| 588 // (1) The ProxyService decided we should connect through a proxy. | |
| 589 // (2) The ProxyService decided we should direct-connect. | |
| 590 // (3) The ProxyService decided we should give up, as there are no more | |
| 591 // proxies to try (this is more likely to happen during | |
| 592 // ReconsiderProxyAfterError()). | |
| 593 // (4) The ProxyService failed (which can happen if the PAC script | |
| 594 // we were configured with threw a runtime exception). | |
| 595 // | |
| 596 // It is important that we fail the connection in case (3) rather than | |
| 597 // falling-back to a direct connection, since sending traffic through | |
| 598 // a proxy may be integral to the user's privacy/security model. | |
| 599 // | |
| 600 // For example if a user had configured traffic to go through the TOR | |
| 601 // anonymizing proxy to protect their privacy, it would be bad if we | |
| 602 // silently fell-back to direct connect if the proxy server were to | |
| 603 // become unreachable. | |
| 604 // | |
| 605 // In case (4) it is less obvious what the right thing to do is. On the | |
| 606 // one hand, for consistency it would be natural to hard-fail as well. | |
| 607 // However, both Firefox 3.5 and Internet Explorer 8 will silently fall-back | |
| 608 // to DIRECT in this case, so we will do the same for compatibility. | |
| 609 // | |
| 610 // For more information, see: | |
| 611 // http://www.chromium.org/developers/design-documents/proxy-settings-fallback | |
| 612 | |
| 613 if (proxy_info_.is_empty()) { | |
| 614 // No proxies/direct to choose from. This can happen when: | |
| 615 // a. We don't support any of the proxies in the returned list. | |
| 616 // b. The proxy service returned us an empty list. | |
| 617 // 1. this can happen if all the proxies were marked as bad already. | |
| 618 // | |
| 619 // TODO(eroman): in case (b.1) it would be better to just try the bad | |
| 620 // proxies again rather than failing without having tried anything! | |
| 621 return ERR_EMPTY_PROXY_LIST; | |
| 622 } | |
| 587 | 623 |
| 588 if (result != OK) { | 624 if (result != OK) { |
| 589 DLOG(ERROR) << "Failed to resolve proxy: " << result; | 625 DLOG(ERROR) << "Failed to resolve proxy: " << result; |
| 626 // Fall-back to direct when there were runtime errors in the PAC script, | |
| 627 // or some other failure with the settings. | |
| 590 proxy_info_.UseDirect(); | 628 proxy_info_.UseDirect(); |
| 591 } | 629 } |
| 630 | |
| 631 next_state_ = STATE_INIT_CONNECTION; | |
| 592 return OK; | 632 return OK; |
| 593 } | 633 } |
| 594 | 634 |
| 595 int HttpNetworkTransaction::DoInitConnection() { | 635 int HttpNetworkTransaction::DoInitConnection() { |
| 596 DCHECK(!connection_->is_initialized()); | 636 DCHECK(!connection_->is_initialized()); |
| 637 DCHECK(proxy_info_.proxy_server().is_valid()); | |
| 597 | 638 |
| 598 next_state_ = STATE_INIT_CONNECTION_COMPLETE; | 639 next_state_ = STATE_INIT_CONNECTION_COMPLETE; |
| 599 | 640 |
| 600 using_ssl_ = request_->url.SchemeIs("https"); | 641 using_ssl_ = request_->url.SchemeIs("https"); |
| 601 | 642 |
| 602 if (proxy_info_.is_direct()) | 643 if (proxy_info_.is_direct()) |
| 603 proxy_mode_ = kDirectConnection; | 644 proxy_mode_ = kDirectConnection; |
| 604 else if (proxy_info_.proxy_server().is_socks()) | 645 else if (proxy_info_.proxy_server().is_socks()) |
| 605 proxy_mode_ = kSOCKSProxy; | 646 proxy_mode_ = kSOCKSProxy; |
| 606 else if (using_ssl_) | 647 else if (using_ssl_) |
| (...skipping 936 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1543 int rv = session_->proxy_service()->ReconsiderProxyAfterError( | 1584 int rv = session_->proxy_service()->ReconsiderProxyAfterError( |
| 1544 request_->url, &proxy_info_, &io_callback_, &pac_request_, load_log_); | 1585 request_->url, &proxy_info_, &io_callback_, &pac_request_, load_log_); |
| 1545 if (rv == OK || rv == ERR_IO_PENDING) { | 1586 if (rv == OK || rv == ERR_IO_PENDING) { |
| 1546 // If the error was during connection setup, there is no socket to | 1587 // If the error was during connection setup, there is no socket to |
| 1547 // disconnect. | 1588 // disconnect. |
| 1548 if (connection_->socket()) | 1589 if (connection_->socket()) |
| 1549 connection_->socket()->Disconnect(); | 1590 connection_->socket()->Disconnect(); |
| 1550 connection_->Reset(); | 1591 connection_->Reset(); |
| 1551 next_state_ = STATE_RESOLVE_PROXY_COMPLETE; | 1592 next_state_ = STATE_RESOLVE_PROXY_COMPLETE; |
| 1552 } else { | 1593 } else { |
| 1594 // If ReconsiderProxyAfterError() failed synchronously, it means | |
|
wtc
2010/01/07 20:25:38
Nit: ReconsiderProxyAfterError() =>
session_->prox
| |
| 1595 // there was nothing left to fall-back to, so fail the transaction | |
| 1596 // with the last connection error we got. | |
|
wtc
2010/01/07 20:25:38
Nit: "last" => "original".
There is another reaso
| |
| 1597 // TODO(eroman): This is a confusing contract, make it more obvious. | |
| 1553 rv = error; | 1598 rv = error; |
| 1554 } | 1599 } |
| 1555 | 1600 |
| 1556 return rv; | 1601 return rv; |
| 1557 } | 1602 } |
| 1558 | 1603 |
| 1559 bool HttpNetworkTransaction::ShouldApplyProxyAuth() const { | 1604 bool HttpNetworkTransaction::ShouldApplyProxyAuth() const { |
| 1560 return (proxy_mode_ == kHTTPProxy) || establishing_tunnel_; | 1605 return (proxy_mode_ == kHTTPProxy) || establishing_tunnel_; |
| 1561 } | 1606 } |
| 1562 | 1607 |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1820 AuthChallengeInfo* auth_info = new AuthChallengeInfo; | 1865 AuthChallengeInfo* auth_info = new AuthChallengeInfo; |
| 1821 auth_info->is_proxy = target == HttpAuth::AUTH_PROXY; | 1866 auth_info->is_proxy = target == HttpAuth::AUTH_PROXY; |
| 1822 auth_info->host_and_port = ASCIIToWide(GetHostAndPort(auth_origin)); | 1867 auth_info->host_and_port = ASCIIToWide(GetHostAndPort(auth_origin)); |
| 1823 auth_info->scheme = ASCIIToWide(auth_handler_[target]->scheme()); | 1868 auth_info->scheme = ASCIIToWide(auth_handler_[target]->scheme()); |
| 1824 // TODO(eroman): decode realm according to RFC 2047. | 1869 // TODO(eroman): decode realm according to RFC 2047. |
| 1825 auth_info->realm = ASCIIToWide(auth_handler_[target]->realm()); | 1870 auth_info->realm = ASCIIToWide(auth_handler_[target]->realm()); |
| 1826 response_.auth_challenge = auth_info; | 1871 response_.auth_challenge = auth_info; |
| 1827 } | 1872 } |
| 1828 | 1873 |
| 1829 } // namespace net | 1874 } // namespace net |
| OLD | NEW |