Fix Alternate-Protocol to work for PAC proxies.
* Includes some IPv6 fixups for Alternate-Protocol.
* Refactors some Alternate-Protocol code, moves the check from DoInitConnection() to DoResolveProxy() so we can send the updated endpoint to the ProxyResolver.
BUG=42666
Review URL: http://codereview.chromium.org/1750020
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@46088 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc
index 1514dc3..5242db87 100644
--- a/net/http/http_network_transaction.cc
+++ b/net/http/http_network_transaction.cc
@@ -14,6 +14,7 @@
#include "base/string_util.h"
#include "base/trace_event.h"
#include "build/build_config.h"
+#include "googleurl/src/gurl.h"
#include "net/base/connection_type_histograms.h"
#include "net/base/io_buffer.h"
#include "net/base/load_flags.h"
@@ -659,13 +660,44 @@
next_state_ = STATE_RESOLVE_PROXY_COMPLETE;
+ // |endpoint_| indicates the final destination endpoint.
+ endpoint_ = HostPortPair(request_->url.HostNoBrackets(),
+ request_->url.EffectiveIntPort());
+
+ GURL alternate_endpoint;
+
+ if (alternate_protocol_mode_ == kUnspecified) {
+ const HttpAlternateProtocols& alternate_protocols =
+ session_->alternate_protocols();
+ if (alternate_protocols.HasAlternateProtocolFor(endpoint_)) {
+ HttpAlternateProtocols::PortProtocolPair alternate =
+ alternate_protocols.GetAlternateProtocolFor(endpoint_);
+ if (alternate.protocol != HttpAlternateProtocols::BROKEN) {
+ DCHECK_EQ(HttpAlternateProtocols::NPN_SPDY_1, alternate.protocol);
+ endpoint_.port = alternate.port;
+ alternate_protocol_ = HttpAlternateProtocols::NPN_SPDY_1;
+ alternate_protocol_mode_ = kUsingAlternateProtocol;
+
+ url_canon::Replacements<char> replacements;
+ replacements.SetScheme("https",
+ url_parse::Component(0, strlen("https")));
+ const std::string port_str = IntToString(endpoint_.port);
+ replacements.SetPort(port_str.c_str(),
+ url_parse::Component(0, port_str.size()));
+ alternate_endpoint = request_->url.ReplaceComponents(replacements);
+ }
+ }
+ }
+
if (request_->load_flags & LOAD_BYPASS_PROXY) {
proxy_info_.UseDirect();
return OK;
}
return session_->proxy_service()->ResolveProxy(
- request_->url, &proxy_info_, &io_callback_, &pac_request_, net_log_);
+ alternate_protocol_mode_ == kUsingAlternateProtocol ?
+ alternate_endpoint : request_->url,
+ &proxy_info_, &io_callback_, &pac_request_, net_log_);
}
int HttpNetworkTransaction::DoResolveProxyComplete(int result) {
@@ -695,33 +727,16 @@
next_state_ = STATE_INIT_CONNECTION_COMPLETE;
- using_ssl_ = request_->url.SchemeIs("https");
+ using_ssl_ = request_->url.SchemeIs("https") ||
+ (alternate_protocol_mode_ == kUsingAlternateProtocol &&
+ alternate_protocol_ == HttpAlternateProtocols::NPN_SPDY_1);
+
using_spdy_ = false;
// Build the string used to uniquely identify connections of this type.
// Determine the host and port to connect to.
std::string connection_group;
- // |endpoint_| indicates the final destination endpoint.
- endpoint_ = HostPortPair(request_->url.HostNoBrackets(),
- request_->url.EffectiveIntPort());
-
- if (alternate_protocol_mode_ == kUnspecified) {
- const HttpAlternateProtocols& alternate_protocols =
- session_->alternate_protocols();
- if (alternate_protocols.HasAlternateProtocolFor(endpoint_)) {
- HttpAlternateProtocols::PortProtocolPair alternate =
- alternate_protocols.GetAlternateProtocolFor(endpoint_);
- if (alternate.protocol != HttpAlternateProtocols::BROKEN) {
- DCHECK_EQ(HttpAlternateProtocols::NPN_SPDY_1, alternate.protocol);
- endpoint_.port = alternate.port;
- using_ssl_ = true;
- alternate_protocol_ = HttpAlternateProtocols::NPN_SPDY_1;
- alternate_protocol_mode_ = kUsingAlternateProtocol;
- }
- }
- }
-
// Use the fixed testing ports if they've been provided.
if (using_ssl_) {
if (session_->fixed_https_port() != 0)
@@ -1129,7 +1144,7 @@
}
HostPortPair http_host_port_pair;
- http_host_port_pair.host = request_->url.host();
+ http_host_port_pair.host = request_->url.HostNoBrackets();
http_host_port_pair.port = request_->url.EffectiveIntPort();
ProcessAlternateProtocol(*response_.headers,
@@ -1978,12 +1993,18 @@
}
void HttpNetworkTransaction::MarkBrokenAlternateProtocolAndFallback() {
- HostPortPair http_host_port_pair;
- http_host_port_pair.host = request_->url.host();
- http_host_port_pair.port = request_->url.EffectiveIntPort();
+ // We have to:
+ // * Reset the endpoint to be the unmodified URL specified destination.
+ // * Mark the endpoint as broken so we don't try again.
+ // * Set the alternate protocol mode to kDoNotUseAlternateProtocol so we
+ // ignore future Alternate-Protocol headers from the HostPortPair.
+ // * Reset the connection and go back to STATE_INIT_CONNECTION.
+
+ endpoint_ = HostPortPair(request_->url.HostNoBrackets(),
+ request_->url.EffectiveIntPort());
session_->mutable_alternate_protocols()->MarkBrokenAlternateProtocolFor(
- http_host_port_pair);
+ endpoint_);
alternate_protocol_mode_ = kDoNotUseAlternateProtocol;
if (connection_->socket())