Chromium Code Reviews| 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" |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 248 it->second.port); | 248 it->second.port); |
| 249 | 249 |
| 250 if (g_forced_alternate_protocol) | 250 if (g_forced_alternate_protocol) |
| 251 return AlternativeService(g_forced_alternate_protocol->protocol, | 251 return AlternativeService(g_forced_alternate_protocol->protocol, |
| 252 origin.host(), g_forced_alternate_protocol->port); | 252 origin.host(), g_forced_alternate_protocol->port); |
| 253 | 253 |
| 254 AlternativeService uninitialize_alternative_service; | 254 AlternativeService uninitialize_alternative_service; |
| 255 return uninitialize_alternative_service; | 255 return uninitialize_alternative_service; |
| 256 } | 256 } |
| 257 | 257 |
| 258 void HttpServerPropertiesImpl::SetAlternateProtocol( | 258 void HttpServerPropertiesImpl::SetAlternativeService( |
| 259 const HostPortPair& origin, | 259 const HostPortPair& origin, |
| 260 uint16 alternate_port, | 260 const AlternativeService& alternative_service, |
| 261 AlternateProtocol alternate_protocol, | 261 double alternative_probability) { |
| 262 double alternate_probability) { | |
| 263 const AlternativeService alternative_service(alternate_protocol, | |
| 264 origin.host(), alternate_port); | |
| 265 if (IsAlternativeServiceBroken(alternative_service)) { | 262 if (IsAlternativeServiceBroken(alternative_service)) { |
| 266 DVLOG(1) << "Ignore alternative service since it is known to be broken."; | 263 DVLOG(1) << "Ignore alternative service since it is known to be broken."; |
| 267 return; | 264 return; |
| 268 } | 265 } |
| 269 | 266 |
| 270 const AlternateProtocolInfo alternate(alternate_port, alternate_protocol, | 267 const AlternateProtocolInfo alternate(alternative_service.port, |
| 271 alternate_probability); | 268 alternative_service.protocol, |
| 269 alternative_probability); | |
| 272 AlternateProtocolMap::const_iterator it = | 270 AlternateProtocolMap::const_iterator it = |
| 273 GetAlternateProtocolIterator(origin); | 271 GetAlternateProtocolIterator(origin); |
| 274 if (it != alternate_protocol_map_.end()) { | 272 if (it != alternate_protocol_map_.end()) { |
| 275 const AlternateProtocolInfo existing_alternate = it->second; | 273 const AlternateProtocolInfo existing_alternate = it->second; |
| 276 | 274 |
| 277 if (!existing_alternate.Equals(alternate)) { | 275 if (!existing_alternate.Equals(alternate)) { |
| 278 LOG(WARNING) << "Changing the alternate protocol for: " | 276 LOG(WARNING) << "Changing the alternate protocol for: " |
| 279 << origin.ToString() | 277 << origin.ToString() |
| 280 << " from [Port: " << existing_alternate.port | 278 << " from [Port: " << existing_alternate.port |
| 281 << ", Protocol: " << existing_alternate.protocol | 279 << ", Protocol: " << existing_alternate.protocol |
| 282 << ", Probability: " << existing_alternate.probability | 280 << ", Probability: " << existing_alternate.probability |
| 283 << "] to [Port: " << alternate_port | 281 << "] to [Port: " << alternative_service.port |
| 284 << ", Protocol: " << alternate_protocol | 282 << ", Protocol: " << alternative_service.protocol |
| 285 << ", Probability: " << alternate_probability << "]."; | 283 << ", Probability: " << alternative_probability << "]."; |
| 286 } | 284 } |
| 287 } else { | 285 } else { |
| 288 if (alternate_probability >= alternate_protocol_probability_threshold_) { | 286 if (alternative_probability >= alternate_protocol_probability_threshold_) { |
| 289 // TODO(rch): Consider the case where multiple requests are started | 287 // TODO(rch): Consider the case where multiple requests are started |
| 290 // before the first completes. In this case, only one of the jobs | 288 // before the first completes. In this case, only one of the jobs |
| 291 // would reach this code, whereas all of them should should have. | 289 // would reach this code, whereas all of them should should have. |
| 292 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_MAPPING_MISSING); | 290 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_MAPPING_MISSING); |
| 293 } | 291 } |
| 294 } | 292 } |
| 295 | 293 |
| 296 alternate_protocol_map_.Put(origin, alternate); | 294 alternate_protocol_map_.Put(origin, alternate); |
| 297 | 295 |
| 298 // If this host ends with a canonical suffix, then set it as the | 296 // If this host ends with a canonical suffix, then set it as the |
| 299 // canonical host. | 297 // canonical host. |
| 300 for (size_t i = 0; i < canonical_suffixes_.size(); ++i) { | 298 for (size_t i = 0; i < canonical_suffixes_.size(); ++i) { |
| 301 std::string canonical_suffix = canonical_suffixes_[i]; | 299 std::string canonical_suffix = canonical_suffixes_[i]; |
| 302 if (EndsWith(origin.host(), canonical_suffixes_[i], false)) { | 300 if (EndsWith(origin.host(), canonical_suffixes_[i], false)) { |
| 303 HostPortPair canonical_host(canonical_suffix, origin.port()); | 301 HostPortPair canonical_host(canonical_suffix, origin.port()); |
| 304 canonical_host_to_origin_map_[canonical_host] = origin; | 302 canonical_host_to_origin_map_[canonical_host] = origin; |
| 305 break; | 303 break; |
| 306 } | 304 } |
| 307 } | 305 } |
| 308 } | 306 } |
| 309 | 307 |
| 310 void HttpServerPropertiesImpl::SetBrokenAlternateProtocol( | 308 void HttpServerPropertiesImpl::MarkAlternativeServiceBroken( |
| 311 const HostPortPair& origin) { | 309 const AlternativeService& alternative_service) { |
| 312 const AlternativeService alternative_service = GetAlternativeService(origin); | |
| 313 if (alternative_service.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL) { | 310 if (alternative_service.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL) { |
| 314 LOG(DFATAL) << "Trying to mark unknown alternate protocol broken."; | 311 LOG(DFATAL) << "Trying to mark unknown alternate protocol broken."; |
| 315 return; | 312 return; |
| 316 } | 313 } |
| 317 int count = ++recently_broken_alternative_services_[alternative_service]; | 314 int count = ++recently_broken_alternative_services_[alternative_service]; |
| 318 base::TimeDelta delay = | 315 base::TimeDelta delay = |
| 319 base::TimeDelta::FromSeconds(kBrokenAlternateProtocolDelaySecs); | 316 base::TimeDelta::FromSeconds(kBrokenAlternateProtocolDelaySecs); |
| 320 base::TimeTicks when = base::TimeTicks::Now() + delay * (1 << (count - 1)); | 317 base::TimeTicks when = base::TimeTicks::Now() + delay * (1 << (count - 1)); |
| 321 auto result = broken_alternative_services_.insert( | 318 auto result = broken_alternative_services_.insert( |
| 322 std::make_pair(alternative_service, when)); | 319 std::make_pair(alternative_service, when)); |
| 323 // Return if alternative service is already in expiration queue. | 320 // Return if alternative service is already in expiration queue. |
| 324 if (!result.second) { | 321 if (!result.second) { |
| 325 return; | 322 return; |
| 326 } | 323 } |
| 327 | 324 |
| 328 // Do not leave this host as canonical so that we don't infer the other | |
| 329 // hosts are also broken without testing them first. | |
| 330 RemoveCanonicalHost(origin); | |
|
Ryan Hamilton
2015/03/18 22:55:42
Because of your "Lazy delete" CL you don't need th
Bence
2015/03/19 12:45:39
Correct. This part of the diff will disappear onc
| |
| 331 | |
| 332 // If this is the only entry in the list, schedule an expiration task. | 325 // If this is the only entry in the list, schedule an expiration task. |
| 333 // Otherwise it will be rescheduled automatically when the pending task runs. | 326 // Otherwise it will be rescheduled automatically when the pending task runs. |
| 334 if (broken_alternative_services_.size() == 1) { | 327 if (broken_alternative_services_.size() == 1) { |
| 335 ScheduleBrokenAlternateProtocolMappingsExpiration(); | 328 ScheduleBrokenAlternateProtocolMappingsExpiration(); |
| 336 } | 329 } |
| 337 } | 330 } |
| 338 | 331 |
| 339 void HttpServerPropertiesImpl::MarkAlternativeServiceRecentlyBroken( | 332 void HttpServerPropertiesImpl::MarkAlternativeServiceRecentlyBroken( |
| 340 const AlternativeService& alternative_service) { | 333 const AlternativeService& alternative_service) { |
| 341 if (!ContainsKey(recently_broken_alternative_services_, alternative_service)) | 334 if (!ContainsKey(recently_broken_alternative_services_, alternative_service)) |
| 342 recently_broken_alternative_services_[alternative_service] = 1; | 335 recently_broken_alternative_services_[alternative_service] = 1; |
| 343 } | 336 } |
| 344 | 337 |
| 345 bool HttpServerPropertiesImpl::IsAlternativeServiceBroken( | 338 bool HttpServerPropertiesImpl::IsAlternativeServiceBroken( |
| 346 const AlternativeService& alternative_service) { | 339 const AlternativeService& alternative_service) { |
| 347 return ContainsKey(broken_alternative_services_, alternative_service); | 340 return ContainsKey(broken_alternative_services_, alternative_service); |
| 348 } | 341 } |
| 349 | 342 |
| 350 bool HttpServerPropertiesImpl::WasAlternateProtocolRecentlyBroken( | 343 bool HttpServerPropertiesImpl::WasAlternativeServiceRecentlyBroken( |
| 351 const HostPortPair& origin) { | 344 const AlternativeService& alternative_service) { |
| 352 const AlternativeService alternative_service = GetAlternativeService(origin); | |
| 353 if (alternative_service.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL) | 345 if (alternative_service.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL) |
| 354 return false; | 346 return false; |
| 355 return ContainsKey(recently_broken_alternative_services_, | 347 return ContainsKey(recently_broken_alternative_services_, |
| 356 alternative_service); | 348 alternative_service); |
| 357 } | 349 } |
| 358 | 350 |
| 359 void HttpServerPropertiesImpl::ConfirmAlternateProtocol( | 351 void HttpServerPropertiesImpl::ConfirmAlternativeService( |
| 360 const HostPortPair& origin) { | 352 const AlternativeService& alternative_service) { |
| 361 const AlternativeService alternative_service = GetAlternativeService(origin); | |
| 362 if (alternative_service.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL) | 353 if (alternative_service.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL) |
| 363 return; | 354 return; |
| 364 broken_alternative_services_.erase(alternative_service); | 355 broken_alternative_services_.erase(alternative_service); |
| 365 recently_broken_alternative_services_.erase(alternative_service); | 356 recently_broken_alternative_services_.erase(alternative_service); |
| 366 } | 357 } |
| 367 | 358 |
| 368 void HttpServerPropertiesImpl::ClearAlternateProtocol( | 359 void HttpServerPropertiesImpl::ClearAlternativeService( |
| 369 const HostPortPair& origin) { | 360 const HostPortPair& origin) { |
| 370 RemoveCanonicalHost(origin); | 361 RemoveCanonicalHost(origin); |
| 371 | 362 |
| 372 AlternateProtocolMap::iterator it = alternate_protocol_map_.Peek(origin); | 363 AlternateProtocolMap::iterator it = alternate_protocol_map_.Peek(origin); |
| 373 if (it == alternate_protocol_map_.end()) { | 364 if (it == alternate_protocol_map_.end()) { |
| 374 return; | 365 return; |
| 375 } | 366 } |
| 376 const AlternativeService alternative_service( | 367 const AlternativeService alternative_service( |
| 377 it->second.protocol, it->first.host(), it->second.port); | 368 it->second.protocol, it->first.host(), it->second.port); |
| 378 alternate_protocol_map_.Erase(it); | 369 alternate_protocol_map_.Erase(it); |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 486 } | 477 } |
| 487 | 478 |
| 488 AlternateProtocolMap::const_iterator | 479 AlternateProtocolMap::const_iterator |
| 489 HttpServerPropertiesImpl::GetAlternateProtocolIterator( | 480 HttpServerPropertiesImpl::GetAlternateProtocolIterator( |
| 490 const HostPortPair& server) { | 481 const HostPortPair& server) { |
| 491 AlternateProtocolMap::const_iterator it = alternate_protocol_map_.Get(server); | 482 AlternateProtocolMap::const_iterator it = alternate_protocol_map_.Get(server); |
| 492 if (it != alternate_protocol_map_.end()) | 483 if (it != alternate_protocol_map_.end()) |
| 493 return it; | 484 return it; |
| 494 | 485 |
| 495 CanonicalHostMap::const_iterator canonical = GetCanonicalHost(server); | 486 CanonicalHostMap::const_iterator canonical = GetCanonicalHost(server); |
| 496 if (canonical != canonical_host_to_origin_map_.end()) | 487 if (canonical == canonical_host_to_origin_map_.end()) { |
| 497 return alternate_protocol_map_.Get(canonical->second); | 488 return alternate_protocol_map_.end(); |
| 489 } | |
| 498 | 490 |
| 491 const HostPortPair canonical_host_port = canonical->second; | |
| 492 it = alternate_protocol_map_.Get(canonical_host_port); | |
| 493 if (it == alternate_protocol_map_.end()) { | |
| 494 return alternate_protocol_map_.end(); | |
| 495 } | |
| 496 | |
| 497 const AlternativeService alternative_service( | |
| 498 it->second.protocol, canonical_host_port.host(), it->second.port); | |
| 499 if (!IsAlternativeServiceBroken(alternative_service)) { | |
| 500 return it; | |
| 501 } | |
| 502 | |
| 503 RemoveCanonicalHost(canonical_host_port); | |
|
Ryan Hamilton
2015/03/18 22:55:42
Is in your other CL?
Bence
2015/03/19 12:45:39
Correct. This part of the diff will disappear onc
| |
| 499 return alternate_protocol_map_.end(); | 504 return alternate_protocol_map_.end(); |
| 500 } | 505 } |
| 501 | 506 |
| 502 HttpServerPropertiesImpl::CanonicalHostMap::const_iterator | 507 HttpServerPropertiesImpl::CanonicalHostMap::const_iterator |
| 503 HttpServerPropertiesImpl::GetCanonicalHost(HostPortPair server) const { | 508 HttpServerPropertiesImpl::GetCanonicalHost(HostPortPair server) const { |
| 504 for (size_t i = 0; i < canonical_suffixes_.size(); ++i) { | 509 for (size_t i = 0; i < canonical_suffixes_.size(); ++i) { |
| 505 std::string canonical_suffix = canonical_suffixes_[i]; | 510 std::string canonical_suffix = canonical_suffixes_[i]; |
| 506 if (EndsWith(server.host(), canonical_suffixes_[i], false)) { | 511 if (EndsWith(server.host(), canonical_suffixes_[i], false)) { |
| 507 HostPortPair canonical_host(canonical_suffix, server.port()); | 512 HostPortPair canonical_host(canonical_suffix, server.port()); |
| 508 return canonical_host_to_origin_map_.find(canonical_host); | 513 return canonical_host_to_origin_map_.find(canonical_host); |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 528 base::TimeTicks now = base::TimeTicks::Now(); | 533 base::TimeTicks now = base::TimeTicks::Now(); |
| 529 while (!broken_alternative_services_.empty()) { | 534 while (!broken_alternative_services_.empty()) { |
| 530 BrokenAlternativeServices::iterator it = | 535 BrokenAlternativeServices::iterator it = |
| 531 broken_alternative_services_.begin(); | 536 broken_alternative_services_.begin(); |
| 532 if (now < it->second) { | 537 if (now < it->second) { |
| 533 break; | 538 break; |
| 534 } | 539 } |
| 535 | 540 |
| 536 const AlternativeService alternative_service = it->first; | 541 const AlternativeService alternative_service = it->first; |
| 537 broken_alternative_services_.erase(it); | 542 broken_alternative_services_.erase(it); |
| 538 ClearAlternateProtocol( | 543 ClearAlternativeService( |
| 539 HostPortPair(alternative_service.host, alternative_service.port)); | 544 HostPortPair(alternative_service.host, alternative_service.port)); |
| 540 } | 545 } |
| 541 ScheduleBrokenAlternateProtocolMappingsExpiration(); | 546 ScheduleBrokenAlternateProtocolMappingsExpiration(); |
| 542 } | 547 } |
| 543 | 548 |
| 544 void | 549 void |
| 545 HttpServerPropertiesImpl::ScheduleBrokenAlternateProtocolMappingsExpiration() { | 550 HttpServerPropertiesImpl::ScheduleBrokenAlternateProtocolMappingsExpiration() { |
| 546 if (broken_alternative_services_.empty()) { | 551 if (broken_alternative_services_.empty()) { |
| 547 return; | 552 return; |
| 548 } | 553 } |
| 549 base::TimeTicks now = base::TimeTicks::Now(); | 554 base::TimeTicks now = base::TimeTicks::Now(); |
| 550 base::TimeTicks when = broken_alternative_services_.front().second; | 555 base::TimeTicks when = broken_alternative_services_.front().second; |
| 551 base::TimeDelta delay = when > now ? when - now : base::TimeDelta(); | 556 base::TimeDelta delay = when > now ? when - now : base::TimeDelta(); |
| 552 base::MessageLoop::current()->PostDelayedTask( | 557 base::MessageLoop::current()->PostDelayedTask( |
| 553 FROM_HERE, | 558 FROM_HERE, |
| 554 base::Bind( | 559 base::Bind( |
| 555 &HttpServerPropertiesImpl::ExpireBrokenAlternateProtocolMappings, | 560 &HttpServerPropertiesImpl::ExpireBrokenAlternateProtocolMappings, |
| 556 weak_ptr_factory_.GetWeakPtr()), | 561 weak_ptr_factory_.GetWeakPtr()), |
| 557 delay); | 562 delay); |
| 558 } | 563 } |
| 559 | 564 |
| 560 } // namespace net | 565 } // namespace net |
| OLD | NEW |