| 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_server_properties_impl.h" | 5 #include "net/http/http_server_properties_impl.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
| 10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
| 11 #include "base/stl_util.h" | 11 #include "base/stl_util.h" |
| 12 #include "base/strings/string_util.h" | 12 #include "base/strings/string_util.h" |
| 13 #include "base/strings/stringprintf.h" | 13 #include "base/strings/stringprintf.h" |
| 14 | 14 |
| 15 namespace net { | 15 namespace net { |
| 16 | 16 |
| 17 namespace { | 17 namespace { |
| 18 | 18 |
| 19 const uint64 kBrokenAlternateProtocolDelaySecs = 300; | 19 const uint64 kBrokenAlternateProtocolDelaySecs = 300; |
| 20 | 20 |
| 21 } // namespace | 21 } // namespace |
| 22 | 22 |
| 23 HttpServerPropertiesImpl::HttpServerPropertiesImpl() | 23 HttpServerPropertiesImpl::HttpServerPropertiesImpl() |
| 24 : spdy_servers_map_(SpdyServerHostPortMap::NO_AUTO_EVICT), | 24 : spdy_servers_map_(SpdyServerHostPortMap::NO_AUTO_EVICT), |
| 25 alternate_protocol_map_(AlternateProtocolMap::NO_AUTO_EVICT), | 25 alternate_protocol_map_(AlternateProtocolMap::NO_AUTO_EVICT), |
| 26 alternate_protocol_experiment_( | 26 alternate_protocol_experiment_( |
| 27 ALTERNATE_PROTOCOL_NOT_PART_OF_EXPERIMENT), | 27 ALTERNATE_PROTOCOL_NOT_PART_OF_EXPERIMENT), |
| 28 spdy_settings_map_(SpdySettingsMap::NO_AUTO_EVICT), | 28 spdy_settings_map_(SpdySettingsMap::NO_AUTO_EVICT), |
| 29 alternate_protocol_probability_threshold_(0), |
| 29 weak_ptr_factory_(this) { | 30 weak_ptr_factory_(this) { |
| 30 canoncial_suffixes_.push_back(".c.youtube.com"); | 31 canoncial_suffixes_.push_back(".c.youtube.com"); |
| 31 canoncial_suffixes_.push_back(".googlevideo.com"); | 32 canoncial_suffixes_.push_back(".googlevideo.com"); |
| 32 canoncial_suffixes_.push_back(".googleusercontent.com"); | 33 canoncial_suffixes_.push_back(".googleusercontent.com"); |
| 33 } | 34 } |
| 34 | 35 |
| 35 HttpServerPropertiesImpl::~HttpServerPropertiesImpl() { | 36 HttpServerPropertiesImpl::~HttpServerPropertiesImpl() { |
| 36 } | 37 } |
| 37 | 38 |
| 38 void HttpServerPropertiesImpl::InitializeSpdyServers( | 39 void HttpServerPropertiesImpl::InitializeSpdyServers( |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 123 // static | 124 // static |
| 124 std::string HttpServerPropertiesImpl::GetFlattenedSpdyServer( | 125 std::string HttpServerPropertiesImpl::GetFlattenedSpdyServer( |
| 125 const net::HostPortPair& host_port_pair) { | 126 const net::HostPortPair& host_port_pair) { |
| 126 std::string spdy_server; | 127 std::string spdy_server; |
| 127 spdy_server.append(host_port_pair.host()); | 128 spdy_server.append(host_port_pair.host()); |
| 128 spdy_server.append(":"); | 129 spdy_server.append(":"); |
| 129 base::StringAppendF(&spdy_server, "%d", host_port_pair.port()); | 130 base::StringAppendF(&spdy_server, "%d", host_port_pair.port()); |
| 130 return spdy_server; | 131 return spdy_server; |
| 131 } | 132 } |
| 132 | 133 |
| 133 static const PortAlternateProtocolPair* g_forced_alternate_protocol = NULL; | 134 static const AlternateProtocolInfo* g_forced_alternate_protocol = NULL; |
| 134 | 135 |
| 135 // static | 136 // static |
| 136 void HttpServerPropertiesImpl::ForceAlternateProtocol( | 137 void HttpServerPropertiesImpl::ForceAlternateProtocol( |
| 137 const PortAlternateProtocolPair& pair) { | 138 const AlternateProtocolInfo& info) { |
| 138 // Note: we're going to leak this. | 139 // Note: we're going to leak this. |
| 139 if (g_forced_alternate_protocol) | 140 if (g_forced_alternate_protocol) |
| 140 delete g_forced_alternate_protocol; | 141 delete g_forced_alternate_protocol; |
| 141 g_forced_alternate_protocol = new PortAlternateProtocolPair(pair); | 142 g_forced_alternate_protocol = new AlternateProtocolInfo(info); |
| 142 } | 143 } |
| 143 | 144 |
| 144 // static | 145 // static |
| 145 void HttpServerPropertiesImpl::DisableForcedAlternateProtocol() { | 146 void HttpServerPropertiesImpl::DisableForcedAlternateProtocol() { |
| 146 delete g_forced_alternate_protocol; | 147 delete g_forced_alternate_protocol; |
| 147 g_forced_alternate_protocol = NULL; | 148 g_forced_alternate_protocol = NULL; |
| 148 } | 149 } |
| 149 | 150 |
| 150 base::WeakPtr<HttpServerProperties> HttpServerPropertiesImpl::GetWeakPtr() { | 151 base::WeakPtr<HttpServerProperties> HttpServerPropertiesImpl::GetWeakPtr() { |
| 151 return weak_ptr_factory_.GetWeakPtr(); | 152 return weak_ptr_factory_.GetWeakPtr(); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 186 if ((spdy_host_port != spdy_servers_map_.end()) && | 187 if ((spdy_host_port != spdy_servers_map_.end()) && |
| 187 (spdy_host_port->second == support_spdy)) { | 188 (spdy_host_port->second == support_spdy)) { |
| 188 return; | 189 return; |
| 189 } | 190 } |
| 190 // Cache the data. | 191 // Cache the data. |
| 191 spdy_servers_map_.Put(spdy_server, support_spdy); | 192 spdy_servers_map_.Put(spdy_server, support_spdy); |
| 192 } | 193 } |
| 193 | 194 |
| 194 bool HttpServerPropertiesImpl::HasAlternateProtocol( | 195 bool HttpServerPropertiesImpl::HasAlternateProtocol( |
| 195 const HostPortPair& server) { | 196 const HostPortPair& server) { |
| 196 if (alternate_protocol_map_.Get(server) != alternate_protocol_map_.end() || | 197 if (g_forced_alternate_protocol) |
| 197 g_forced_alternate_protocol) | |
| 198 return true; | 198 return true; |
| 199 AlternateProtocolMap::const_iterator it = alternate_protocol_map_.Get(server); |
| 200 if (it != alternate_protocol_map_.end() && |
| 201 it->second.probability > alternate_protocol_probability_threshold_) { |
| 202 return true; |
| 203 } |
| 199 | 204 |
| 200 return GetCanonicalHost(server) != canonical_host_to_origin_map_.end(); | 205 return GetCanonicalHost(server) != canonical_host_to_origin_map_.end(); |
| 201 } | 206 } |
| 202 | 207 |
| 203 std::string HttpServerPropertiesImpl::GetCanonicalSuffix( | 208 std::string HttpServerPropertiesImpl::GetCanonicalSuffix( |
| 204 const HostPortPair& server) { | 209 const HostPortPair& server) { |
| 205 // If this host ends with a canonical suffix, then return the canonical | 210 // If this host ends with a canonical suffix, then return the canonical |
| 206 // suffix. | 211 // suffix. |
| 207 for (size_t i = 0; i < canoncial_suffixes_.size(); ++i) { | 212 for (size_t i = 0; i < canoncial_suffixes_.size(); ++i) { |
| 208 std::string canonical_suffix = canoncial_suffixes_[i]; | 213 std::string canonical_suffix = canoncial_suffixes_[i]; |
| 209 if (EndsWith(server.host(), canoncial_suffixes_[i], false)) { | 214 if (EndsWith(server.host(), canoncial_suffixes_[i], false)) { |
| 210 return canonical_suffix; | 215 return canonical_suffix; |
| 211 } | 216 } |
| 212 } | 217 } |
| 213 return std::string(); | 218 return std::string(); |
| 214 } | 219 } |
| 215 | 220 |
| 216 PortAlternateProtocolPair | 221 AlternateProtocolInfo |
| 217 HttpServerPropertiesImpl::GetAlternateProtocol( | 222 HttpServerPropertiesImpl::GetAlternateProtocol( |
| 218 const HostPortPair& server) { | 223 const HostPortPair& server) { |
| 219 DCHECK(HasAlternateProtocol(server)); | 224 DCHECK(HasAlternateProtocol(server)); |
| 220 | 225 |
| 221 // First check the map. | 226 // First check the map. |
| 222 AlternateProtocolMap::iterator it = alternate_protocol_map_.Get(server); | 227 AlternateProtocolMap::iterator it = alternate_protocol_map_.Get(server); |
| 223 if (it != alternate_protocol_map_.end()) | 228 if (it != alternate_protocol_map_.end()) |
| 224 return it->second; | 229 return it->second; |
| 225 | 230 |
| 226 // Next check the canonical host. | 231 // Next check the canonical host. |
| 227 CanonicalHostMap::const_iterator canonical_host = GetCanonicalHost(server); | 232 CanonicalHostMap::const_iterator canonical_host = GetCanonicalHost(server); |
| 228 if (canonical_host != canonical_host_to_origin_map_.end()) | 233 if (canonical_host != canonical_host_to_origin_map_.end()) |
| 229 return alternate_protocol_map_.Get(canonical_host->second)->second; | 234 return alternate_protocol_map_.Get(canonical_host->second)->second; |
| 230 | 235 |
| 231 // We must be forcing an alternate. | 236 // We must be forcing an alternate. |
| 232 DCHECK(g_forced_alternate_protocol); | 237 DCHECK(g_forced_alternate_protocol); |
| 233 return *g_forced_alternate_protocol; | 238 return *g_forced_alternate_protocol; |
| 234 } | 239 } |
| 235 | 240 |
| 236 void HttpServerPropertiesImpl::SetAlternateProtocol( | 241 void HttpServerPropertiesImpl::SetAlternateProtocol( |
| 237 const HostPortPair& server, | 242 const HostPortPair& server, |
| 238 uint16 alternate_port, | 243 uint16 alternate_port, |
| 239 AlternateProtocol alternate_protocol) { | 244 AlternateProtocol alternate_protocol, |
| 245 double alternate_probability) { |
| 240 if (alternate_protocol == ALTERNATE_PROTOCOL_BROKEN) { | 246 if (alternate_protocol == ALTERNATE_PROTOCOL_BROKEN) { |
| 241 LOG(DFATAL) << "Call SetBrokenAlternateProtocol() instead."; | 247 LOG(DFATAL) << "Call SetBrokenAlternateProtocol() instead."; |
| 242 return; | 248 return; |
| 243 } | 249 } |
| 244 | 250 |
| 245 PortAlternateProtocolPair alternate; | 251 AlternateProtocolInfo alternate(alternate_port, |
| 246 alternate.port = alternate_port; | 252 alternate_protocol, |
| 247 alternate.protocol = alternate_protocol; | 253 alternate_probability); |
| 248 if (HasAlternateProtocol(server)) { | 254 if (HasAlternateProtocol(server)) { |
| 249 const PortAlternateProtocolPair existing_alternate = | 255 const AlternateProtocolInfo existing_alternate = |
| 250 GetAlternateProtocol(server); | 256 GetAlternateProtocol(server); |
| 251 | 257 |
| 252 if (existing_alternate.protocol == ALTERNATE_PROTOCOL_BROKEN) { | 258 if (existing_alternate.protocol == ALTERNATE_PROTOCOL_BROKEN) { |
| 253 DVLOG(1) << "Ignore alternate protocol since it's known to be broken."; | 259 DVLOG(1) << "Ignore alternate protocol since it's known to be broken."; |
| 254 return; | 260 return; |
| 255 } | 261 } |
| 256 | 262 |
| 257 if (alternate_protocol != ALTERNATE_PROTOCOL_BROKEN && | 263 if (alternate_protocol != ALTERNATE_PROTOCOL_BROKEN && |
| 258 !existing_alternate.Equals(alternate)) { | 264 !existing_alternate.Equals(alternate)) { |
| 259 LOG(WARNING) << "Changing the alternate protocol for: " | 265 LOG(WARNING) << "Changing the alternate protocol for: " |
| 260 << server.ToString() | 266 << server.ToString() |
| 261 << " from [Port: " << existing_alternate.port | 267 << " from [Port: " << existing_alternate.port |
| 262 << ", Protocol: " << existing_alternate.protocol | 268 << ", Protocol: " << existing_alternate.protocol |
| 269 << ", Probability: " << existing_alternate.probability |
| 263 << "] to [Port: " << alternate_port | 270 << "] to [Port: " << alternate_port |
| 264 << ", Protocol: " << alternate_protocol | 271 << ", Protocol: " << alternate_protocol |
| 272 << ", Probability: " << alternate_probability |
| 265 << "]."; | 273 << "]."; |
| 266 } | 274 } |
| 267 } else { | 275 } else { |
| 268 // TODO(rch): Consider the case where multiple requests are started | 276 // TODO(rch): Consider the case where multiple requests are started |
| 269 // before the first completes. In this case, only one of the jobs | 277 // before the first completes. In this case, only one of the jobs |
| 270 // would reach this code, whereas all of them should should have. | 278 // would reach this code, whereas all of them should should have. |
| 271 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_MAPPING_MISSING, | 279 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_MAPPING_MISSING, |
| 272 alternate_protocol_experiment_); | 280 alternate_protocol_experiment_); |
| 273 } | 281 } |
| 274 | 282 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 285 } | 293 } |
| 286 } | 294 } |
| 287 } | 295 } |
| 288 | 296 |
| 289 void HttpServerPropertiesImpl::SetBrokenAlternateProtocol( | 297 void HttpServerPropertiesImpl::SetBrokenAlternateProtocol( |
| 290 const HostPortPair& server) { | 298 const HostPortPair& server) { |
| 291 AlternateProtocolMap::iterator it = alternate_protocol_map_.Get(server); | 299 AlternateProtocolMap::iterator it = alternate_protocol_map_.Get(server); |
| 292 if (it != alternate_protocol_map_.end()) { | 300 if (it != alternate_protocol_map_.end()) { |
| 293 it->second.protocol = ALTERNATE_PROTOCOL_BROKEN; | 301 it->second.protocol = ALTERNATE_PROTOCOL_BROKEN; |
| 294 } else { | 302 } else { |
| 295 PortAlternateProtocolPair alternate; | 303 AlternateProtocolInfo alternate(server.port(), |
| 296 alternate.protocol = ALTERNATE_PROTOCOL_BROKEN; | 304 ALTERNATE_PROTOCOL_BROKEN, |
| 305 1); |
| 297 alternate_protocol_map_.Put(server, alternate); | 306 alternate_protocol_map_.Put(server, alternate); |
| 298 } | 307 } |
| 299 int count = ++broken_alternate_protocol_map_[server]; | 308 int count = ++broken_alternate_protocol_map_[server]; |
| 300 base::TimeDelta delay = | 309 base::TimeDelta delay = |
| 301 base::TimeDelta::FromSeconds(kBrokenAlternateProtocolDelaySecs); | 310 base::TimeDelta::FromSeconds(kBrokenAlternateProtocolDelaySecs); |
| 302 BrokenAlternateProtocolEntry entry; | 311 BrokenAlternateProtocolEntry entry; |
| 303 entry.server = server; | 312 entry.server = server; |
| 304 entry.when = base::TimeTicks::Now() + delay * (1 << (count - 1)); | 313 entry.when = base::TimeTicks::Now() + delay * (1 << (count - 1)); |
| 305 broken_alternate_protocol_list_.push_back(entry); | 314 broken_alternate_protocol_list_.push_back(entry); |
| 306 | 315 |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 407 HttpServerPropertiesImpl::GetServerNetworkStats( | 416 HttpServerPropertiesImpl::GetServerNetworkStats( |
| 408 const HostPortPair& host_port_pair) const { | 417 const HostPortPair& host_port_pair) const { |
| 409 ServerNetworkStatsMap::const_iterator it = | 418 ServerNetworkStatsMap::const_iterator it = |
| 410 server_network_stats_map_.find(host_port_pair); | 419 server_network_stats_map_.find(host_port_pair); |
| 411 if (it == server_network_stats_map_.end()) { | 420 if (it == server_network_stats_map_.end()) { |
| 412 return NULL; | 421 return NULL; |
| 413 } | 422 } |
| 414 return &it->second; | 423 return &it->second; |
| 415 } | 424 } |
| 416 | 425 |
| 426 void HttpServerPropertiesImpl::SetAlternateProtocolProbabilityThreshold( |
| 427 double threshold) { |
| 428 alternate_protocol_probability_threshold_ = threshold; |
| 429 } |
| 430 |
| 417 HttpServerPropertiesImpl::CanonicalHostMap::const_iterator | 431 HttpServerPropertiesImpl::CanonicalHostMap::const_iterator |
| 418 HttpServerPropertiesImpl::GetCanonicalHost(HostPortPair server) const { | 432 HttpServerPropertiesImpl::GetCanonicalHost(HostPortPair server) const { |
| 419 for (size_t i = 0; i < canoncial_suffixes_.size(); ++i) { | 433 for (size_t i = 0; i < canoncial_suffixes_.size(); ++i) { |
| 420 std::string canonical_suffix = canoncial_suffixes_[i]; | 434 std::string canonical_suffix = canoncial_suffixes_[i]; |
| 421 if (EndsWith(server.host(), canoncial_suffixes_[i], false)) { | 435 if (EndsWith(server.host(), canoncial_suffixes_[i], false)) { |
| 422 HostPortPair canonical_host(canonical_suffix, server.port()); | 436 HostPortPair canonical_host(canonical_suffix, server.port()); |
| 423 return canonical_host_to_origin_map_.find(canonical_host); | 437 return canonical_host_to_origin_map_.find(canonical_host); |
| 424 } | 438 } |
| 425 } | 439 } |
| 426 | 440 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 464 base::TimeDelta delay = when > now ? when - now : base::TimeDelta(); | 478 base::TimeDelta delay = when > now ? when - now : base::TimeDelta(); |
| 465 base::MessageLoop::current()->PostDelayedTask( | 479 base::MessageLoop::current()->PostDelayedTask( |
| 466 FROM_HERE, | 480 FROM_HERE, |
| 467 base::Bind( | 481 base::Bind( |
| 468 &HttpServerPropertiesImpl::ExpireBrokenAlternateProtocolMappings, | 482 &HttpServerPropertiesImpl::ExpireBrokenAlternateProtocolMappings, |
| 469 weak_ptr_factory_.GetWeakPtr()), | 483 weak_ptr_factory_.GetWeakPtr()), |
| 470 delay); | 484 delay); |
| 471 } | 485 } |
| 472 | 486 |
| 473 } // namespace net | 487 } // namespace net |
| OLD | NEW |