| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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_stream_factory.h" | 5 #include "net/http/http_stream_factory.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/strings/string_number_conversions.h" | 8 #include "base/strings/string_number_conversions.h" |
| 9 #include "base/strings/string_split.h" | 9 #include "base/strings/string_split.h" |
| 10 #include "net/base/host_mapping_rules.h" | 10 #include "net/base/host_mapping_rules.h" |
| 11 #include "net/base/host_port_pair.h" | 11 #include "net/base/host_port_pair.h" |
| 12 #include "net/http/http_network_session.h" |
| 12 #include "url/gurl.h" | 13 #include "url/gurl.h" |
| 13 | 14 |
| 14 namespace net { | 15 namespace net { |
| 15 | 16 |
| 16 // WARNING: If you modify or add any static flags, you must keep them in sync | 17 // WARNING: If you modify or add any static flags, you must keep them in sync |
| 17 // with |ResetStaticSettingsToInit|. This is critical for unit test isolation. | 18 // with |ResetStaticSettingsToInit|. This is critical for unit test isolation. |
| 18 | 19 |
| 19 // static | 20 // static |
| 20 std::vector<std::string>* HttpStreamFactory::next_protos_ = NULL; | |
| 21 // static | |
| 22 bool HttpStreamFactory::enabled_protocols_[NUM_VALID_ALTERNATE_PROTOCOLS]; | |
| 23 // static | |
| 24 bool HttpStreamFactory::spdy_enabled_ = true; | 21 bool HttpStreamFactory::spdy_enabled_ = true; |
| 25 // static | |
| 26 bool HttpStreamFactory::use_alternate_protocols_ = false; | |
| 27 // static | |
| 28 bool HttpStreamFactory::force_spdy_over_ssl_ = true; | |
| 29 // static | |
| 30 bool HttpStreamFactory::force_spdy_always_ = false; | |
| 31 // static | |
| 32 std::list<HostPortPair>* HttpStreamFactory::forced_spdy_exclusions_ = NULL; | |
| 33 | 22 |
| 34 HttpStreamFactory::~HttpStreamFactory() {} | 23 HttpStreamFactory::~HttpStreamFactory() {} |
| 35 | 24 |
| 36 // static | 25 // static |
| 37 bool HttpStreamFactory::IsProtocolEnabled(AlternateProtocol protocol) { | |
| 38 DCHECK(IsAlternateProtocolValid(protocol)); | |
| 39 return enabled_protocols_[ | |
| 40 protocol - ALTERNATE_PROTOCOL_MINIMUM_VALID_VERSION]; | |
| 41 } | |
| 42 | |
| 43 // static | |
| 44 void HttpStreamFactory::SetProtocolEnabled(AlternateProtocol protocol) { | |
| 45 DCHECK(IsAlternateProtocolValid(protocol)); | |
| 46 enabled_protocols_[ | |
| 47 protocol - ALTERNATE_PROTOCOL_MINIMUM_VALID_VERSION] = true; | |
| 48 } | |
| 49 | |
| 50 // static | |
| 51 void HttpStreamFactory::ResetEnabledProtocols() { | |
| 52 for (int i = ALTERNATE_PROTOCOL_MINIMUM_VALID_VERSION; | |
| 53 i <= ALTERNATE_PROTOCOL_MAXIMUM_VALID_VERSION; ++i) { | |
| 54 enabled_protocols_[i - ALTERNATE_PROTOCOL_MINIMUM_VALID_VERSION] = false; | |
| 55 } | |
| 56 } | |
| 57 | |
| 58 // static | |
| 59 void HttpStreamFactory::ResetStaticSettingsToInit() { | 26 void HttpStreamFactory::ResetStaticSettingsToInit() { |
| 60 // WARNING: These must match the initializers above. | |
| 61 delete next_protos_; | |
| 62 delete forced_spdy_exclusions_; | |
| 63 next_protos_ = NULL; | |
| 64 spdy_enabled_ = true; | 27 spdy_enabled_ = true; |
| 65 use_alternate_protocols_ = false; | |
| 66 force_spdy_over_ssl_ = true; | |
| 67 force_spdy_always_ = false; | |
| 68 forced_spdy_exclusions_ = NULL; | |
| 69 ResetEnabledProtocols(); | |
| 70 } | 28 } |
| 71 | 29 |
| 72 void HttpStreamFactory::ProcessAlternateProtocol( | 30 void HttpStreamFactory::ProcessAlternateProtocol( |
| 73 const base::WeakPtr<HttpServerProperties>& http_server_properties, | 31 const base::WeakPtr<HttpServerProperties>& http_server_properties, |
| 74 const std::string& alternate_protocol_str, | 32 const std::string& alternate_protocol_str, |
| 75 const HostPortPair& http_host_port_pair) { | 33 const HostPortPair& http_host_port_pair, |
| 34 const HttpNetworkSession& session) { |
| 76 std::vector<std::string> port_protocol_vector; | 35 std::vector<std::string> port_protocol_vector; |
| 77 base::SplitString(alternate_protocol_str, ':', &port_protocol_vector); | 36 base::SplitString(alternate_protocol_str, ':', &port_protocol_vector); |
| 78 if (port_protocol_vector.size() != 2) { | 37 if (port_protocol_vector.size() != 2) { |
| 79 DVLOG(1) << kAlternateProtocolHeader | 38 DVLOG(1) << kAlternateProtocolHeader |
| 80 << " header has too many tokens: " | 39 << " header has too many tokens: " |
| 81 << alternate_protocol_str; | 40 << alternate_protocol_str; |
| 82 return; | 41 return; |
| 83 } | 42 } |
| 84 | 43 |
| 85 int port; | 44 int port; |
| 86 if (!base::StringToInt(port_protocol_vector[0], &port) || | 45 if (!base::StringToInt(port_protocol_vector[0], &port) || |
| 87 port <= 0 || port >= 1 << 16) { | 46 port <= 0 || port >= 1 << 16) { |
| 88 DVLOG(1) << kAlternateProtocolHeader | 47 DVLOG(1) << kAlternateProtocolHeader |
| 89 << " header has unrecognizable port: " | 48 << " header has unrecognizable port: " |
| 90 << port_protocol_vector[0]; | 49 << port_protocol_vector[0]; |
| 91 return; | 50 return; |
| 92 } | 51 } |
| 93 | 52 |
| 94 AlternateProtocol protocol = | 53 AlternateProtocol protocol = |
| 95 AlternateProtocolFromString(port_protocol_vector[1]); | 54 AlternateProtocolFromString(port_protocol_vector[1]); |
| 96 if (IsAlternateProtocolValid(protocol) && !IsProtocolEnabled(protocol)) { | 55 if (IsAlternateProtocolValid(protocol) && |
| 56 !session.IsProtocolEnabled(protocol)) { |
| 97 protocol = ALTERNATE_PROTOCOL_BROKEN; | 57 protocol = ALTERNATE_PROTOCOL_BROKEN; |
| 98 } | 58 } |
| 99 | 59 |
| 100 if (protocol == ALTERNATE_PROTOCOL_BROKEN) { | 60 if (protocol == ALTERNATE_PROTOCOL_BROKEN) { |
| 101 DVLOG(1) << kAlternateProtocolHeader | 61 DVLOG(1) << kAlternateProtocolHeader |
| 102 << " header has unrecognized protocol: " | 62 << " header has unrecognized protocol: " |
| 103 << port_protocol_vector[1]; | 63 << port_protocol_vector[1]; |
| 104 return; | 64 return; |
| 105 } | 65 } |
| 106 | 66 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 127 url::Replacements<char> replacements; | 87 url::Replacements<char> replacements; |
| 128 const std::string port_str = base::IntToString(endpoint->port()); | 88 const std::string port_str = base::IntToString(endpoint->port()); |
| 129 replacements.SetPort(port_str.c_str(), url::Component(0, port_str.size())); | 89 replacements.SetPort(port_str.c_str(), url::Component(0, port_str.size())); |
| 130 replacements.SetHost(endpoint->host().c_str(), | 90 replacements.SetHost(endpoint->host().c_str(), |
| 131 url::Component(0, endpoint->host().size())); | 91 url::Component(0, endpoint->host().size())); |
| 132 return url.ReplaceComponents(replacements); | 92 return url.ReplaceComponents(replacements); |
| 133 } | 93 } |
| 134 return url; | 94 return url; |
| 135 } | 95 } |
| 136 | 96 |
| 137 // static | |
| 138 void HttpStreamFactory::add_forced_spdy_exclusion(const std::string& value) { | |
| 139 HostPortPair pair = HostPortPair::FromURL(GURL(value)); | |
| 140 if (!forced_spdy_exclusions_) | |
| 141 forced_spdy_exclusions_ = new std::list<HostPortPair>(); | |
| 142 forced_spdy_exclusions_->push_back(pair); | |
| 143 } | |
| 144 | |
| 145 // static | |
| 146 bool HttpStreamFactory::HasSpdyExclusion(const HostPortPair& endpoint) { | |
| 147 std::list<HostPortPair>* exclusions = forced_spdy_exclusions_; | |
| 148 if (!exclusions) | |
| 149 return false; | |
| 150 | |
| 151 std::list<HostPortPair>::const_iterator it; | |
| 152 for (it = exclusions->begin(); it != exclusions->end(); ++it) | |
| 153 if (it->Equals(endpoint)) | |
| 154 return true; | |
| 155 return false; | |
| 156 } | |
| 157 | |
| 158 // static | |
| 159 void HttpStreamFactory::EnableNpnHttpOnly() { | |
| 160 // Avoid alternate protocol in this case. Otherwise, browser will try SSL | |
| 161 // and then fallback to http. This introduces extra load. | |
| 162 set_use_alternate_protocols(false); | |
| 163 std::vector<NextProto> next_protos; | |
| 164 next_protos.push_back(kProtoHTTP11); | |
| 165 SetNextProtos(next_protos); | |
| 166 } | |
| 167 | |
| 168 // static | |
| 169 void HttpStreamFactory::EnableNpnSpdy3() { | |
| 170 set_use_alternate_protocols(true); | |
| 171 std::vector<NextProto> next_protos; | |
| 172 next_protos.push_back(kProtoHTTP11); | |
| 173 next_protos.push_back(kProtoQUIC1SPDY3); | |
| 174 next_protos.push_back(kProtoSPDY3); | |
| 175 SetNextProtos(next_protos); | |
| 176 } | |
| 177 | |
| 178 // static | |
| 179 void HttpStreamFactory::EnableNpnSpdy31() { | |
| 180 set_use_alternate_protocols(true); | |
| 181 std::vector<NextProto> next_protos; | |
| 182 next_protos.push_back(kProtoHTTP11); | |
| 183 next_protos.push_back(kProtoQUIC1SPDY3); | |
| 184 next_protos.push_back(kProtoSPDY3); | |
| 185 next_protos.push_back(kProtoSPDY31); | |
| 186 SetNextProtos(next_protos); | |
| 187 } | |
| 188 | |
| 189 // static | |
| 190 void HttpStreamFactory::EnableNpnSpdy31WithSpdy2() { | |
| 191 set_use_alternate_protocols(true); | |
| 192 std::vector<NextProto> next_protos; | |
| 193 next_protos.push_back(kProtoHTTP11); | |
| 194 next_protos.push_back(kProtoQUIC1SPDY3); | |
| 195 next_protos.push_back(kProtoDeprecatedSPDY2); | |
| 196 next_protos.push_back(kProtoSPDY3); | |
| 197 next_protos.push_back(kProtoSPDY31); | |
| 198 SetNextProtos(next_protos); | |
| 199 } | |
| 200 | |
| 201 // static | |
| 202 void HttpStreamFactory::EnableNpnSpdy4Http2() { | |
| 203 set_use_alternate_protocols(true); | |
| 204 std::vector<NextProto> next_protos; | |
| 205 next_protos.push_back(kProtoHTTP11); | |
| 206 next_protos.push_back(kProtoQUIC1SPDY3); | |
| 207 next_protos.push_back(kProtoSPDY3); | |
| 208 next_protos.push_back(kProtoSPDY31); | |
| 209 next_protos.push_back(kProtoSPDY4); | |
| 210 SetNextProtos(next_protos); | |
| 211 } | |
| 212 | |
| 213 // static | |
| 214 void HttpStreamFactory::SetNextProtos(const std::vector<NextProto>& value) { | |
| 215 if (!next_protos_) | |
| 216 next_protos_ = new std::vector<std::string>; | |
| 217 | |
| 218 next_protos_->clear(); | |
| 219 | |
| 220 ResetEnabledProtocols(); | |
| 221 | |
| 222 // TODO(rtenneti): bug 116575 - consider combining the NextProto and | |
| 223 // AlternateProtocol. | |
| 224 for (uint32 i = 0; i < value.size(); ++i) { | |
| 225 NextProto proto = value[i]; | |
| 226 // Add the protocol to the TLS next protocol list, except for QUIC | |
| 227 // since it uses UDP. | |
| 228 if (proto != kProtoQUIC1SPDY3) { | |
| 229 next_protos_->push_back(SSLClientSocket::NextProtoToString(proto)); | |
| 230 } | |
| 231 | |
| 232 // Enable the corresponding alternate protocol, except for HTTP | |
| 233 // which has not corresponding alternative. | |
| 234 if (proto != kProtoHTTP11) { | |
| 235 AlternateProtocol alternate = AlternateProtocolFromNextProto(proto); | |
| 236 if (!IsAlternateProtocolValid(alternate)) { | |
| 237 NOTREACHED() << "Invalid next proto: " << proto; | |
| 238 continue; | |
| 239 } | |
| 240 SetProtocolEnabled(alternate); | |
| 241 } | |
| 242 } | |
| 243 } | |
| 244 | |
| 245 HttpStreamFactory::HttpStreamFactory() {} | 97 HttpStreamFactory::HttpStreamFactory() {} |
| 246 | 98 |
| 247 } // namespace net | 99 } // namespace net |
| OLD | NEW |