| 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 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 251 UMA_HISTOGRAM_BOOLEAN("Net.ForceAlternativeService", | 251 UMA_HISTOGRAM_BOOLEAN("Net.ForceAlternativeService", |
| 252 g_forced_alternate_protocol != nullptr); | 252 g_forced_alternate_protocol != nullptr); |
| 253 if (g_forced_alternate_protocol) | 253 if (g_forced_alternate_protocol) |
| 254 return AlternativeService(g_forced_alternate_protocol->protocol, | 254 return AlternativeService(g_forced_alternate_protocol->protocol, |
| 255 origin.host(), g_forced_alternate_protocol->port); | 255 origin.host(), g_forced_alternate_protocol->port); |
| 256 | 256 |
| 257 AlternativeService uninitialize_alternative_service; | 257 AlternativeService uninitialize_alternative_service; |
| 258 return uninitialize_alternative_service; | 258 return uninitialize_alternative_service; |
| 259 } | 259 } |
| 260 | 260 |
| 261 void HttpServerPropertiesImpl::SetAlternateProtocol( | 261 void HttpServerPropertiesImpl::SetAlternativeService( |
| 262 const HostPortPair& origin, | 262 const HostPortPair& origin, |
| 263 uint16 alternate_port, | 263 const AlternativeService& alternative_service, |
| 264 AlternateProtocol alternate_protocol, | 264 double alternative_probability) { |
| 265 double alternate_probability) { | |
| 266 const AlternativeService alternative_service(alternate_protocol, | |
| 267 origin.host(), alternate_port); | |
| 268 if (IsAlternativeServiceBroken(alternative_service)) { | 265 if (IsAlternativeServiceBroken(alternative_service)) { |
| 269 DVLOG(1) << "Ignore alternative service since it is known to be broken."; | 266 DVLOG(1) << "Ignore alternative service since it is known to be broken."; |
| 270 return; | 267 return; |
| 271 } | 268 } |
| 272 | 269 |
| 273 const AlternateProtocolInfo alternate(alternate_port, alternate_protocol, | 270 const AlternateProtocolInfo alternate(alternative_service.port, |
| 274 alternate_probability); | 271 alternative_service.protocol, |
| 272 alternative_probability); |
| 275 AlternateProtocolMap::const_iterator it = | 273 AlternateProtocolMap::const_iterator it = |
| 276 GetAlternateProtocolIterator(origin); | 274 GetAlternateProtocolIterator(origin); |
| 277 if (it != alternate_protocol_map_.end()) { | 275 if (it != alternate_protocol_map_.end()) { |
| 278 const AlternateProtocolInfo existing_alternate = it->second; | 276 const AlternateProtocolInfo existing_alternate = it->second; |
| 279 | 277 |
| 280 if (!existing_alternate.Equals(alternate)) { | 278 if (!existing_alternate.Equals(alternate)) { |
| 281 LOG(WARNING) << "Changing the alternate protocol for: " | 279 LOG(WARNING) << "Changing the alternate protocol for: " |
| 282 << origin.ToString() | 280 << origin.ToString() |
| 283 << " from [Port: " << existing_alternate.port | 281 << " from [Port: " << existing_alternate.port |
| 284 << ", Protocol: " << existing_alternate.protocol | 282 << ", Protocol: " << existing_alternate.protocol |
| 285 << ", Probability: " << existing_alternate.probability | 283 << ", Probability: " << existing_alternate.probability |
| 286 << "] to [Port: " << alternate_port | 284 << "] to [Port: " << alternative_service.port |
| 287 << ", Protocol: " << alternate_protocol | 285 << ", Protocol: " << alternative_service.protocol |
| 288 << ", Probability: " << alternate_probability << "]."; | 286 << ", Probability: " << alternative_probability << "]."; |
| 289 } | 287 } |
| 290 } else { | 288 } else { |
| 291 if (alternate_probability >= alternate_protocol_probability_threshold_) { | 289 if (alternative_probability >= alternate_protocol_probability_threshold_) { |
| 292 // TODO(rch): Consider the case where multiple requests are started | 290 // TODO(rch): Consider the case where multiple requests are started |
| 293 // before the first completes. In this case, only one of the jobs | 291 // before the first completes. In this case, only one of the jobs |
| 294 // would reach this code, whereas all of them should should have. | 292 // would reach this code, whereas all of them should should have. |
| 295 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_MAPPING_MISSING); | 293 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_MAPPING_MISSING); |
| 296 } | 294 } |
| 297 } | 295 } |
| 298 | 296 |
| 299 alternate_protocol_map_.Put(origin, alternate); | 297 alternate_protocol_map_.Put(origin, alternate); |
| 300 | 298 |
| 301 // If this host ends with a canonical suffix, then set it as the | 299 // If this host ends with a canonical suffix, then set it as the |
| 302 // canonical host. | 300 // canonical host. |
| 303 for (size_t i = 0; i < canonical_suffixes_.size(); ++i) { | 301 for (size_t i = 0; i < canonical_suffixes_.size(); ++i) { |
| 304 std::string canonical_suffix = canonical_suffixes_[i]; | 302 std::string canonical_suffix = canonical_suffixes_[i]; |
| 305 if (EndsWith(origin.host(), canonical_suffixes_[i], false)) { | 303 if (EndsWith(origin.host(), canonical_suffixes_[i], false)) { |
| 306 HostPortPair canonical_host(canonical_suffix, origin.port()); | 304 HostPortPair canonical_host(canonical_suffix, origin.port()); |
| 307 canonical_host_to_origin_map_[canonical_host] = origin; | 305 canonical_host_to_origin_map_[canonical_host] = origin; |
| 308 break; | 306 break; |
| 309 } | 307 } |
| 310 } | 308 } |
| 311 } | 309 } |
| 312 | 310 |
| 313 void HttpServerPropertiesImpl::SetBrokenAlternateProtocol( | 311 void HttpServerPropertiesImpl::MarkAlternativeServiceBroken( |
| 314 const HostPortPair& origin) { | 312 const AlternativeService& alternative_service) { |
| 315 const AlternativeService alternative_service = GetAlternativeService(origin); | |
| 316 if (alternative_service.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL) { | 313 if (alternative_service.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL) { |
| 317 LOG(DFATAL) << "Trying to mark unknown alternate protocol broken."; | 314 LOG(DFATAL) << "Trying to mark unknown alternate protocol broken."; |
| 318 return; | 315 return; |
| 319 } | 316 } |
| 320 int count = ++recently_broken_alternative_services_[alternative_service]; | 317 int count = ++recently_broken_alternative_services_[alternative_service]; |
| 321 base::TimeDelta delay = | 318 base::TimeDelta delay = |
| 322 base::TimeDelta::FromSeconds(kBrokenAlternateProtocolDelaySecs); | 319 base::TimeDelta::FromSeconds(kBrokenAlternateProtocolDelaySecs); |
| 323 base::TimeTicks when = base::TimeTicks::Now() + delay * (1 << (count - 1)); | 320 base::TimeTicks when = base::TimeTicks::Now() + delay * (1 << (count - 1)); |
| 324 auto result = broken_alternative_services_.insert( | 321 auto result = broken_alternative_services_.insert( |
| 325 std::make_pair(alternative_service, when)); | 322 std::make_pair(alternative_service, when)); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 339 const AlternativeService& alternative_service) { | 336 const AlternativeService& alternative_service) { |
| 340 if (!ContainsKey(recently_broken_alternative_services_, alternative_service)) | 337 if (!ContainsKey(recently_broken_alternative_services_, alternative_service)) |
| 341 recently_broken_alternative_services_[alternative_service] = 1; | 338 recently_broken_alternative_services_[alternative_service] = 1; |
| 342 } | 339 } |
| 343 | 340 |
| 344 bool HttpServerPropertiesImpl::IsAlternativeServiceBroken( | 341 bool HttpServerPropertiesImpl::IsAlternativeServiceBroken( |
| 345 const AlternativeService& alternative_service) { | 342 const AlternativeService& alternative_service) { |
| 346 return ContainsKey(broken_alternative_services_, alternative_service); | 343 return ContainsKey(broken_alternative_services_, alternative_service); |
| 347 } | 344 } |
| 348 | 345 |
| 349 bool HttpServerPropertiesImpl::WasAlternateProtocolRecentlyBroken( | 346 bool HttpServerPropertiesImpl::WasAlternativeServiceRecentlyBroken( |
| 350 const HostPortPair& origin) { | 347 const AlternativeService& alternative_service) { |
| 351 const AlternativeService alternative_service = GetAlternativeService(origin); | |
| 352 if (alternative_service.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL) | 348 if (alternative_service.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL) |
| 353 return false; | 349 return false; |
| 354 return ContainsKey(recently_broken_alternative_services_, | 350 return ContainsKey(recently_broken_alternative_services_, |
| 355 alternative_service); | 351 alternative_service); |
| 356 } | 352 } |
| 357 | 353 |
| 358 void HttpServerPropertiesImpl::ConfirmAlternateProtocol( | 354 void HttpServerPropertiesImpl::ConfirmAlternativeService( |
| 359 const HostPortPair& origin) { | 355 const AlternativeService& alternative_service) { |
| 360 const AlternativeService alternative_service = GetAlternativeService(origin); | |
| 361 if (alternative_service.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL) | 356 if (alternative_service.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL) |
| 362 return; | 357 return; |
| 363 broken_alternative_services_.erase(alternative_service); | 358 broken_alternative_services_.erase(alternative_service); |
| 364 recently_broken_alternative_services_.erase(alternative_service); | 359 recently_broken_alternative_services_.erase(alternative_service); |
| 365 } | 360 } |
| 366 | 361 |
| 367 void HttpServerPropertiesImpl::ClearAlternateProtocol( | 362 void HttpServerPropertiesImpl::ClearAlternativeService( |
| 368 const HostPortPair& origin) { | 363 const HostPortPair& origin) { |
| 369 RemoveCanonicalHost(origin); | 364 RemoveCanonicalHost(origin); |
| 370 | 365 |
| 371 AlternateProtocolMap::iterator it = alternate_protocol_map_.Peek(origin); | 366 AlternateProtocolMap::iterator it = alternate_protocol_map_.Peek(origin); |
| 372 if (it == alternate_protocol_map_.end()) { | 367 if (it == alternate_protocol_map_.end()) { |
| 373 return; | 368 return; |
| 374 } | 369 } |
| 375 const AlternativeService alternative_service( | 370 const AlternativeService alternative_service( |
| 376 it->second.protocol, it->first.host(), it->second.port); | 371 it->second.protocol, it->first.host(), it->second.port); |
| 377 alternate_protocol_map_.Erase(it); | 372 alternate_protocol_map_.Erase(it); |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 541 base::TimeTicks now = base::TimeTicks::Now(); | 536 base::TimeTicks now = base::TimeTicks::Now(); |
| 542 while (!broken_alternative_services_.empty()) { | 537 while (!broken_alternative_services_.empty()) { |
| 543 BrokenAlternativeServices::iterator it = | 538 BrokenAlternativeServices::iterator it = |
| 544 broken_alternative_services_.begin(); | 539 broken_alternative_services_.begin(); |
| 545 if (now < it->second) { | 540 if (now < it->second) { |
| 546 break; | 541 break; |
| 547 } | 542 } |
| 548 | 543 |
| 549 const AlternativeService alternative_service = it->first; | 544 const AlternativeService alternative_service = it->first; |
| 550 broken_alternative_services_.erase(it); | 545 broken_alternative_services_.erase(it); |
| 551 ClearAlternateProtocol( | 546 ClearAlternativeService( |
| 552 HostPortPair(alternative_service.host, alternative_service.port)); | 547 HostPortPair(alternative_service.host, alternative_service.port)); |
| 553 } | 548 } |
| 554 ScheduleBrokenAlternateProtocolMappingsExpiration(); | 549 ScheduleBrokenAlternateProtocolMappingsExpiration(); |
| 555 } | 550 } |
| 556 | 551 |
| 557 void | 552 void |
| 558 HttpServerPropertiesImpl::ScheduleBrokenAlternateProtocolMappingsExpiration() { | 553 HttpServerPropertiesImpl::ScheduleBrokenAlternateProtocolMappingsExpiration() { |
| 559 if (broken_alternative_services_.empty()) { | 554 if (broken_alternative_services_.empty()) { |
| 560 return; | 555 return; |
| 561 } | 556 } |
| 562 base::TimeTicks now = base::TimeTicks::Now(); | 557 base::TimeTicks now = base::TimeTicks::Now(); |
| 563 base::TimeTicks when = broken_alternative_services_.front().second; | 558 base::TimeTicks when = broken_alternative_services_.front().second; |
| 564 base::TimeDelta delay = when > now ? when - now : base::TimeDelta(); | 559 base::TimeDelta delay = when > now ? when - now : base::TimeDelta(); |
| 565 base::MessageLoop::current()->PostDelayedTask( | 560 base::MessageLoop::current()->PostDelayedTask( |
| 566 FROM_HERE, | 561 FROM_HERE, |
| 567 base::Bind( | 562 base::Bind( |
| 568 &HttpServerPropertiesImpl::ExpireBrokenAlternateProtocolMappings, | 563 &HttpServerPropertiesImpl::ExpireBrokenAlternateProtocolMappings, |
| 569 weak_ptr_factory_.GetWeakPtr()), | 564 weak_ptr_factory_.GetWeakPtr()), |
| 570 delay); | 565 delay); |
| 571 } | 566 } |
| 572 | 567 |
| 573 } // namespace net | 568 } // namespace net |
| OLD | NEW |