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 |