| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "net/http/http_server_properties_impl.h" | |
| 6 | |
| 7 #include "base/bind.h" | |
| 8 #include "base/logging.h" | |
| 9 #include "base/memory/scoped_ptr.h" | |
| 10 #include "base/message_loop/message_loop.h" | |
| 11 #include "base/stl_util.h" | |
| 12 #include "base/strings/string_util.h" | |
| 13 #include "base/strings/stringprintf.h" | |
| 14 | |
| 15 namespace net { | |
| 16 | |
| 17 namespace { | |
| 18 | |
| 19 const uint64 kBrokenAlternateProtocolDelaySecs = 300; | |
| 20 | |
| 21 } // namespace | |
| 22 | |
| 23 HttpServerPropertiesImpl::HttpServerPropertiesImpl() | |
| 24 : spdy_servers_map_(SpdyServerHostPortMap::NO_AUTO_EVICT), | |
| 25 alternate_protocol_map_(AlternateProtocolMap::NO_AUTO_EVICT), | |
| 26 spdy_settings_map_(SpdySettingsMap::NO_AUTO_EVICT), | |
| 27 server_network_stats_map_(ServerNetworkStatsMap::NO_AUTO_EVICT), | |
| 28 alternate_protocol_probability_threshold_(1), | |
| 29 weak_ptr_factory_(this) { | |
| 30 canonical_suffixes_.push_back(".c.youtube.com"); | |
| 31 canonical_suffixes_.push_back(".googlevideo.com"); | |
| 32 canonical_suffixes_.push_back(".googleusercontent.com"); | |
| 33 } | |
| 34 | |
| 35 HttpServerPropertiesImpl::~HttpServerPropertiesImpl() { | |
| 36 } | |
| 37 | |
| 38 void HttpServerPropertiesImpl::InitializeSpdyServers( | |
| 39 std::vector<std::string>* spdy_servers, | |
| 40 bool support_spdy) { | |
| 41 DCHECK(CalledOnValidThread()); | |
| 42 if (!spdy_servers) | |
| 43 return; | |
| 44 // Add the entries from persisted data. | |
| 45 for (std::vector<std::string>::reverse_iterator it = spdy_servers->rbegin(); | |
| 46 it != spdy_servers->rend(); ++it) { | |
| 47 spdy_servers_map_.Put(*it, support_spdy); | |
| 48 } | |
| 49 } | |
| 50 | |
| 51 void HttpServerPropertiesImpl::InitializeAlternateProtocolServers( | |
| 52 AlternateProtocolMap* alternate_protocol_map) { | |
| 53 // Keep all the broken ones since those don't get persisted. | |
| 54 for (AlternateProtocolMap::iterator it = alternate_protocol_map_.begin(); | |
| 55 it != alternate_protocol_map_.end();) { | |
| 56 AlternateProtocolMap::iterator old_it = it; | |
| 57 ++it; | |
| 58 if (!old_it->second.is_broken) { | |
| 59 alternate_protocol_map_.Erase(old_it); | |
| 60 } | |
| 61 } | |
| 62 | |
| 63 // Add the entries from persisted data. | |
| 64 for (AlternateProtocolMap::reverse_iterator it = | |
| 65 alternate_protocol_map->rbegin(); | |
| 66 it != alternate_protocol_map->rend(); ++it) { | |
| 67 alternate_protocol_map_.Put(it->first, it->second); | |
| 68 } | |
| 69 | |
| 70 // Attempt to find canonical servers. | |
| 71 uint16 canonical_ports[] = { 80, 443 }; | |
| 72 for (size_t i = 0; i < canonical_suffixes_.size(); ++i) { | |
| 73 std::string canonical_suffix = canonical_suffixes_[i]; | |
| 74 for (size_t j = 0; j < arraysize(canonical_ports); ++j) { | |
| 75 HostPortPair canonical_host(canonical_suffix, canonical_ports[j]); | |
| 76 // If we already have a valid canonical server, we're done. | |
| 77 if (ContainsKey(canonical_host_to_origin_map_, canonical_host) && | |
| 78 (alternate_protocol_map_.Peek(canonical_host_to_origin_map_[ | |
| 79 canonical_host]) != alternate_protocol_map_.end())) { | |
| 80 continue; | |
| 81 } | |
| 82 // Now attempt to find a server which matches this origin and set it as | |
| 83 // canonical . | |
| 84 for (AlternateProtocolMap::const_iterator it = | |
| 85 alternate_protocol_map_.begin(); | |
| 86 it != alternate_protocol_map_.end(); ++it) { | |
| 87 if (EndsWith(it->first.host(), canonical_suffixes_[i], false)) { | |
| 88 canonical_host_to_origin_map_[canonical_host] = it->first; | |
| 89 break; | |
| 90 } | |
| 91 } | |
| 92 } | |
| 93 } | |
| 94 } | |
| 95 | |
| 96 void HttpServerPropertiesImpl::InitializeSpdySettingsServers( | |
| 97 SpdySettingsMap* spdy_settings_map) { | |
| 98 for (SpdySettingsMap::reverse_iterator it = spdy_settings_map->rbegin(); | |
| 99 it != spdy_settings_map->rend(); ++it) { | |
| 100 spdy_settings_map_.Put(it->first, it->second); | |
| 101 } | |
| 102 } | |
| 103 | |
| 104 void HttpServerPropertiesImpl::InitializeSupportsQuic( | |
| 105 IPAddressNumber* last_address) { | |
| 106 if (last_address) | |
| 107 last_quic_address_ = *last_address; | |
| 108 } | |
| 109 | |
| 110 void HttpServerPropertiesImpl::InitializeServerNetworkStats( | |
| 111 ServerNetworkStatsMap* server_network_stats_map) { | |
| 112 for (ServerNetworkStatsMap::reverse_iterator it = | |
| 113 server_network_stats_map->rbegin(); | |
| 114 it != server_network_stats_map->rend(); ++it) { | |
| 115 server_network_stats_map_.Put(it->first, it->second); | |
| 116 } | |
| 117 } | |
| 118 | |
| 119 void HttpServerPropertiesImpl::GetSpdyServerList( | |
| 120 base::ListValue* spdy_server_list, | |
| 121 size_t max_size) const { | |
| 122 DCHECK(CalledOnValidThread()); | |
| 123 DCHECK(spdy_server_list); | |
| 124 spdy_server_list->Clear(); | |
| 125 size_t count = 0; | |
| 126 // Get the list of servers (host/port) that support SPDY. | |
| 127 for (SpdyServerHostPortMap::const_iterator it = spdy_servers_map_.begin(); | |
| 128 it != spdy_servers_map_.end() && count < max_size; ++it) { | |
| 129 const std::string spdy_server_host_port = it->first; | |
| 130 if (it->second) { | |
| 131 spdy_server_list->Append(new base::StringValue(spdy_server_host_port)); | |
| 132 ++count; | |
| 133 } | |
| 134 } | |
| 135 } | |
| 136 | |
| 137 static const AlternateProtocolInfo* g_forced_alternate_protocol = NULL; | |
| 138 | |
| 139 // static | |
| 140 void HttpServerPropertiesImpl::ForceAlternateProtocol( | |
| 141 const AlternateProtocolInfo& info) { | |
| 142 // Note: we're going to leak this. | |
| 143 if (g_forced_alternate_protocol) | |
| 144 delete g_forced_alternate_protocol; | |
| 145 g_forced_alternate_protocol = new AlternateProtocolInfo(info); | |
| 146 } | |
| 147 | |
| 148 // static | |
| 149 void HttpServerPropertiesImpl::DisableForcedAlternateProtocol() { | |
| 150 delete g_forced_alternate_protocol; | |
| 151 g_forced_alternate_protocol = NULL; | |
| 152 } | |
| 153 | |
| 154 base::WeakPtr<HttpServerProperties> HttpServerPropertiesImpl::GetWeakPtr() { | |
| 155 return weak_ptr_factory_.GetWeakPtr(); | |
| 156 } | |
| 157 | |
| 158 void HttpServerPropertiesImpl::Clear() { | |
| 159 DCHECK(CalledOnValidThread()); | |
| 160 spdy_servers_map_.Clear(); | |
| 161 alternate_protocol_map_.Clear(); | |
| 162 canonical_host_to_origin_map_.clear(); | |
| 163 spdy_settings_map_.Clear(); | |
| 164 last_quic_address_.clear(); | |
| 165 server_network_stats_map_.Clear(); | |
| 166 } | |
| 167 | |
| 168 bool HttpServerPropertiesImpl::SupportsRequestPriority( | |
| 169 const HostPortPair& host_port_pair) { | |
| 170 DCHECK(CalledOnValidThread()); | |
| 171 if (host_port_pair.host().empty()) | |
| 172 return false; | |
| 173 | |
| 174 SpdyServerHostPortMap::iterator spdy_host_port = | |
| 175 spdy_servers_map_.Get(host_port_pair.ToString()); | |
| 176 if (spdy_host_port != spdy_servers_map_.end() && spdy_host_port->second) | |
| 177 return true; | |
| 178 | |
| 179 const AlternateProtocolInfo info = GetAlternateProtocol(host_port_pair); | |
| 180 return info.protocol == QUIC; | |
| 181 } | |
| 182 | |
| 183 void HttpServerPropertiesImpl::SetSupportsSpdy( | |
| 184 const HostPortPair& host_port_pair, | |
| 185 bool support_spdy) { | |
| 186 DCHECK(CalledOnValidThread()); | |
| 187 if (host_port_pair.host().empty()) | |
| 188 return; | |
| 189 | |
| 190 SpdyServerHostPortMap::iterator spdy_host_port = | |
| 191 spdy_servers_map_.Get(host_port_pair.ToString()); | |
| 192 if ((spdy_host_port != spdy_servers_map_.end()) && | |
| 193 (spdy_host_port->second == support_spdy)) { | |
| 194 return; | |
| 195 } | |
| 196 // Cache the data. | |
| 197 spdy_servers_map_.Put(host_port_pair.ToString(), support_spdy); | |
| 198 } | |
| 199 | |
| 200 bool HttpServerPropertiesImpl::RequiresHTTP11( | |
| 201 const net::HostPortPair& host_port_pair) { | |
| 202 DCHECK(CalledOnValidThread()); | |
| 203 if (host_port_pair.host().empty()) | |
| 204 return false; | |
| 205 | |
| 206 return (http11_servers_.find(host_port_pair) != http11_servers_.end()); | |
| 207 } | |
| 208 | |
| 209 void HttpServerPropertiesImpl::SetHTTP11Required( | |
| 210 const net::HostPortPair& host_port_pair) { | |
| 211 DCHECK(CalledOnValidThread()); | |
| 212 if (host_port_pair.host().empty()) | |
| 213 return; | |
| 214 | |
| 215 http11_servers_.insert(host_port_pair); | |
| 216 } | |
| 217 | |
| 218 void HttpServerPropertiesImpl::MaybeForceHTTP11(const HostPortPair& server, | |
| 219 SSLConfig* ssl_config) { | |
| 220 if (RequiresHTTP11(server)) { | |
| 221 ForceHTTP11(ssl_config); | |
| 222 } | |
| 223 } | |
| 224 | |
| 225 std::string HttpServerPropertiesImpl::GetCanonicalSuffix( | |
| 226 const std::string& host) { | |
| 227 // If this host ends with a canonical suffix, then return the canonical | |
| 228 // suffix. | |
| 229 for (size_t i = 0; i < canonical_suffixes_.size(); ++i) { | |
| 230 std::string canonical_suffix = canonical_suffixes_[i]; | |
| 231 if (EndsWith(host, canonical_suffixes_[i], false)) { | |
| 232 return canonical_suffix; | |
| 233 } | |
| 234 } | |
| 235 return std::string(); | |
| 236 } | |
| 237 | |
| 238 AlternateProtocolInfo HttpServerPropertiesImpl::GetAlternateProtocol( | |
| 239 const HostPortPair& server) { | |
| 240 AlternateProtocolMap::const_iterator it = | |
| 241 GetAlternateProtocolIterator(server); | |
| 242 if (it != alternate_protocol_map_.end() && | |
| 243 it->second.probability >= alternate_protocol_probability_threshold_) | |
| 244 return it->second; | |
| 245 | |
| 246 if (g_forced_alternate_protocol) | |
| 247 return *g_forced_alternate_protocol; | |
| 248 | |
| 249 AlternateProtocolInfo uninitialized_alternate_protocol; | |
| 250 return uninitialized_alternate_protocol; | |
| 251 } | |
| 252 | |
| 253 void HttpServerPropertiesImpl::SetAlternateProtocol( | |
| 254 const HostPortPair& server, | |
| 255 uint16 alternate_port, | |
| 256 AlternateProtocol alternate_protocol, | |
| 257 double alternate_probability) { | |
| 258 | |
| 259 AlternateProtocolInfo alternate(alternate_port, | |
| 260 alternate_protocol, | |
| 261 alternate_probability); | |
| 262 AlternateProtocolMap::const_iterator it = | |
| 263 GetAlternateProtocolIterator(server); | |
| 264 if (it != alternate_protocol_map_.end()) { | |
| 265 const AlternateProtocolInfo existing_alternate = it->second; | |
| 266 | |
| 267 if (existing_alternate.is_broken) { | |
| 268 DVLOG(1) << "Ignore alternate protocol since it's known to be broken."; | |
| 269 return; | |
| 270 } | |
| 271 | |
| 272 if (!existing_alternate.Equals(alternate)) { | |
| 273 LOG(WARNING) << "Changing the alternate protocol for: " | |
| 274 << server.ToString() | |
| 275 << " from [Port: " << existing_alternate.port | |
| 276 << ", Protocol: " << existing_alternate.protocol | |
| 277 << ", Probability: " << existing_alternate.probability | |
| 278 << "] to [Port: " << alternate_port | |
| 279 << ", Protocol: " << alternate_protocol | |
| 280 << ", Probability: " << alternate_probability | |
| 281 << "]."; | |
| 282 } | |
| 283 } else { | |
| 284 if (alternate_probability >= alternate_protocol_probability_threshold_) { | |
| 285 // TODO(rch): Consider the case where multiple requests are started | |
| 286 // before the first completes. In this case, only one of the jobs | |
| 287 // would reach this code, whereas all of them should should have. | |
| 288 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_MAPPING_MISSING); | |
| 289 } | |
| 290 } | |
| 291 | |
| 292 alternate_protocol_map_.Put(server, alternate); | |
| 293 | |
| 294 // If this host ends with a canonical suffix, then set it as the | |
| 295 // canonical host. | |
| 296 for (size_t i = 0; i < canonical_suffixes_.size(); ++i) { | |
| 297 std::string canonical_suffix = canonical_suffixes_[i]; | |
| 298 if (EndsWith(server.host(), canonical_suffixes_[i], false)) { | |
| 299 HostPortPair canonical_host(canonical_suffix, server.port()); | |
| 300 canonical_host_to_origin_map_[canonical_host] = server; | |
| 301 break; | |
| 302 } | |
| 303 } | |
| 304 } | |
| 305 | |
| 306 void HttpServerPropertiesImpl::SetBrokenAlternateProtocol( | |
| 307 const HostPortPair& server) { | |
| 308 AlternateProtocolMap::iterator it = alternate_protocol_map_.Get(server); | |
| 309 const AlternateProtocolInfo alternate = GetAlternateProtocol(server); | |
| 310 if (it == alternate_protocol_map_.end()) { | |
| 311 if (alternate.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL) { | |
| 312 LOG(DFATAL) << "Trying to mark unknown alternate protocol broken."; | |
| 313 return; | |
| 314 } | |
| 315 // This server's alternate protocol information is coming from a canonical | |
| 316 // server. Add an entry in the map for this server explicitly so that | |
| 317 // it can be marked as broken. | |
| 318 it = alternate_protocol_map_.Put(server, alternate); | |
| 319 } | |
| 320 it->second.is_broken = true; | |
| 321 const BrokenAlternateProtocolEntry entry(server, alternate.port, | |
| 322 alternate.protocol); | |
| 323 int count = ++broken_alternate_protocol_map_[entry]; | |
| 324 base::TimeDelta delay = | |
| 325 base::TimeDelta::FromSeconds(kBrokenAlternateProtocolDelaySecs); | |
| 326 base::TimeTicks when = base::TimeTicks::Now() + delay * (1 << (count - 1)); | |
| 327 broken_alternate_protocol_list_.push_back( | |
| 328 BrokenAlternateProtocolEntryWithTime(entry, when)); | |
| 329 | |
| 330 // Do not leave this host as canonical so that we don't infer the other | |
| 331 // hosts are also broken without testing them first. | |
| 332 RemoveCanonicalHost(server); | |
| 333 | |
| 334 // If this is the only entry in the list, schedule an expiration task. | |
| 335 // Otherwise it will be rescheduled automatically when the pending task runs. | |
| 336 if (broken_alternate_protocol_list_.size() == 1) { | |
| 337 ScheduleBrokenAlternateProtocolMappingsExpiration(); | |
| 338 } | |
| 339 } | |
| 340 | |
| 341 bool HttpServerPropertiesImpl::WasAlternateProtocolRecentlyBroken( | |
| 342 const HostPortPair& server) { | |
| 343 const AlternateProtocolInfo alternate_protocol = GetAlternateProtocol(server); | |
| 344 if (alternate_protocol.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL) | |
| 345 return false; | |
| 346 const BrokenAlternateProtocolEntry entry(server, alternate_protocol.port, | |
| 347 alternate_protocol.protocol); | |
| 348 return ContainsKey(broken_alternate_protocol_map_, entry); | |
| 349 } | |
| 350 | |
| 351 void HttpServerPropertiesImpl::ConfirmAlternateProtocol( | |
| 352 const HostPortPair& server) { | |
| 353 const AlternateProtocolInfo alternate_protocol = GetAlternateProtocol(server); | |
| 354 if (alternate_protocol.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL) | |
| 355 return; | |
| 356 const BrokenAlternateProtocolEntry entry(server, alternate_protocol.port, | |
| 357 alternate_protocol.protocol); | |
| 358 broken_alternate_protocol_map_.erase(entry); | |
| 359 } | |
| 360 | |
| 361 void HttpServerPropertiesImpl::ClearAlternateProtocol( | |
| 362 const HostPortPair& server) { | |
| 363 AlternateProtocolMap::iterator it = alternate_protocol_map_.Peek(server); | |
| 364 if (it != alternate_protocol_map_.end()) | |
| 365 alternate_protocol_map_.Erase(it); | |
| 366 | |
| 367 RemoveCanonicalHost(server); | |
| 368 } | |
| 369 | |
| 370 const AlternateProtocolMap& | |
| 371 HttpServerPropertiesImpl::alternate_protocol_map() const { | |
| 372 return alternate_protocol_map_; | |
| 373 } | |
| 374 | |
| 375 const SettingsMap& HttpServerPropertiesImpl::GetSpdySettings( | |
| 376 const HostPortPair& host_port_pair) { | |
| 377 SpdySettingsMap::iterator it = spdy_settings_map_.Get(host_port_pair); | |
| 378 if (it == spdy_settings_map_.end()) { | |
| 379 CR_DEFINE_STATIC_LOCAL(SettingsMap, kEmptySettingsMap, ()); | |
| 380 return kEmptySettingsMap; | |
| 381 } | |
| 382 return it->second; | |
| 383 } | |
| 384 | |
| 385 bool HttpServerPropertiesImpl::SetSpdySetting( | |
| 386 const HostPortPair& host_port_pair, | |
| 387 SpdySettingsIds id, | |
| 388 SpdySettingsFlags flags, | |
| 389 uint32 value) { | |
| 390 if (!(flags & SETTINGS_FLAG_PLEASE_PERSIST)) | |
| 391 return false; | |
| 392 | |
| 393 SettingsFlagsAndValue flags_and_value(SETTINGS_FLAG_PERSISTED, value); | |
| 394 SpdySettingsMap::iterator it = spdy_settings_map_.Get(host_port_pair); | |
| 395 if (it == spdy_settings_map_.end()) { | |
| 396 SettingsMap settings_map; | |
| 397 settings_map[id] = flags_and_value; | |
| 398 spdy_settings_map_.Put(host_port_pair, settings_map); | |
| 399 } else { | |
| 400 SettingsMap& settings_map = it->second; | |
| 401 settings_map[id] = flags_and_value; | |
| 402 } | |
| 403 return true; | |
| 404 } | |
| 405 | |
| 406 void HttpServerPropertiesImpl::ClearSpdySettings( | |
| 407 const HostPortPair& host_port_pair) { | |
| 408 SpdySettingsMap::iterator it = spdy_settings_map_.Peek(host_port_pair); | |
| 409 if (it != spdy_settings_map_.end()) | |
| 410 spdy_settings_map_.Erase(it); | |
| 411 } | |
| 412 | |
| 413 void HttpServerPropertiesImpl::ClearAllSpdySettings() { | |
| 414 spdy_settings_map_.Clear(); | |
| 415 } | |
| 416 | |
| 417 const SpdySettingsMap& | |
| 418 HttpServerPropertiesImpl::spdy_settings_map() const { | |
| 419 return spdy_settings_map_; | |
| 420 } | |
| 421 | |
| 422 bool HttpServerPropertiesImpl::GetSupportsQuic( | |
| 423 IPAddressNumber* last_address) const { | |
| 424 if (last_quic_address_.empty()) | |
| 425 return false; | |
| 426 | |
| 427 *last_address = last_quic_address_; | |
| 428 return true; | |
| 429 } | |
| 430 | |
| 431 void HttpServerPropertiesImpl::SetSupportsQuic(bool used_quic, | |
| 432 const IPAddressNumber& address) { | |
| 433 if (!used_quic) { | |
| 434 last_quic_address_.clear(); | |
| 435 } else { | |
| 436 last_quic_address_ = address; | |
| 437 } | |
| 438 } | |
| 439 | |
| 440 void HttpServerPropertiesImpl::SetServerNetworkStats( | |
| 441 const HostPortPair& host_port_pair, | |
| 442 ServerNetworkStats stats) { | |
| 443 server_network_stats_map_.Put(host_port_pair, stats); | |
| 444 } | |
| 445 | |
| 446 const ServerNetworkStats* HttpServerPropertiesImpl::GetServerNetworkStats( | |
| 447 const HostPortPair& host_port_pair) { | |
| 448 ServerNetworkStatsMap::iterator it = | |
| 449 server_network_stats_map_.Get(host_port_pair); | |
| 450 if (it == server_network_stats_map_.end()) { | |
| 451 return NULL; | |
| 452 } | |
| 453 return &it->second; | |
| 454 } | |
| 455 | |
| 456 const ServerNetworkStatsMap& | |
| 457 HttpServerPropertiesImpl::server_network_stats_map() const { | |
| 458 return server_network_stats_map_; | |
| 459 } | |
| 460 | |
| 461 void HttpServerPropertiesImpl::SetAlternateProtocolProbabilityThreshold( | |
| 462 double threshold) { | |
| 463 alternate_protocol_probability_threshold_ = threshold; | |
| 464 } | |
| 465 | |
| 466 AlternateProtocolMap::const_iterator | |
| 467 HttpServerPropertiesImpl::GetAlternateProtocolIterator( | |
| 468 const HostPortPair& server) { | |
| 469 AlternateProtocolMap::const_iterator it = alternate_protocol_map_.Get(server); | |
| 470 if (it != alternate_protocol_map_.end()) | |
| 471 return it; | |
| 472 | |
| 473 CanonicalHostMap::const_iterator canonical = GetCanonicalHost(server); | |
| 474 if (canonical != canonical_host_to_origin_map_.end()) | |
| 475 return alternate_protocol_map_.Get(canonical->second); | |
| 476 | |
| 477 return alternate_protocol_map_.end(); | |
| 478 } | |
| 479 | |
| 480 HttpServerPropertiesImpl::CanonicalHostMap::const_iterator | |
| 481 HttpServerPropertiesImpl::GetCanonicalHost(HostPortPair server) const { | |
| 482 for (size_t i = 0; i < canonical_suffixes_.size(); ++i) { | |
| 483 std::string canonical_suffix = canonical_suffixes_[i]; | |
| 484 if (EndsWith(server.host(), canonical_suffixes_[i], false)) { | |
| 485 HostPortPair canonical_host(canonical_suffix, server.port()); | |
| 486 return canonical_host_to_origin_map_.find(canonical_host); | |
| 487 } | |
| 488 } | |
| 489 | |
| 490 return canonical_host_to_origin_map_.end(); | |
| 491 } | |
| 492 | |
| 493 void HttpServerPropertiesImpl::RemoveCanonicalHost( | |
| 494 const HostPortPair& server) { | |
| 495 CanonicalHostMap::const_iterator canonical = GetCanonicalHost(server); | |
| 496 if (canonical == canonical_host_to_origin_map_.end()) | |
| 497 return; | |
| 498 | |
| 499 if (!canonical->second.Equals(server)) | |
| 500 return; | |
| 501 | |
| 502 canonical_host_to_origin_map_.erase(canonical->first); | |
| 503 } | |
| 504 | |
| 505 void HttpServerPropertiesImpl::ExpireBrokenAlternateProtocolMappings() { | |
| 506 base::TimeTicks now = base::TimeTicks::Now(); | |
| 507 while (!broken_alternate_protocol_list_.empty()) { | |
| 508 BrokenAlternateProtocolEntryWithTime entry_with_time = | |
| 509 broken_alternate_protocol_list_.front(); | |
| 510 if (now < entry_with_time.when) { | |
| 511 break; | |
| 512 } | |
| 513 | |
| 514 const BrokenAlternateProtocolEntry& entry = | |
| 515 entry_with_time.broken_alternate_protocol_entry; | |
| 516 ClearAlternateProtocol(entry.server); | |
| 517 broken_alternate_protocol_list_.pop_front(); | |
| 518 } | |
| 519 ScheduleBrokenAlternateProtocolMappingsExpiration(); | |
| 520 } | |
| 521 | |
| 522 void | |
| 523 HttpServerPropertiesImpl::ScheduleBrokenAlternateProtocolMappingsExpiration() { | |
| 524 if (broken_alternate_protocol_list_.empty()) { | |
| 525 return; | |
| 526 } | |
| 527 base::TimeTicks now = base::TimeTicks::Now(); | |
| 528 base::TimeTicks when = broken_alternate_protocol_list_.front().when; | |
| 529 base::TimeDelta delay = when > now ? when - now : base::TimeDelta(); | |
| 530 base::MessageLoop::current()->PostDelayedTask( | |
| 531 FROM_HERE, | |
| 532 base::Bind( | |
| 533 &HttpServerPropertiesImpl::ExpireBrokenAlternateProtocolMappings, | |
| 534 weak_ptr_factory_.GetWeakPtr()), | |
| 535 delay); | |
| 536 } | |
| 537 | |
| 538 } // namespace net | |
| OLD | NEW |