Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(45)

Side by Side Diff: net/http/http_server_properties_impl.cc

Issue 665083009: ABANDONED Handle multiple AlternateProtocols for each HostPortPair. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Custom entries for broken_alternate_protocol_list_ and map_. Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 return; 43 return;
44 // Add the entries from persisted data. 44 // Add the entries from persisted data.
45 for (std::vector<std::string>::reverse_iterator it = spdy_servers->rbegin(); 45 for (std::vector<std::string>::reverse_iterator it = spdy_servers->rbegin();
46 it != spdy_servers->rend(); ++it) { 46 it != spdy_servers->rend(); ++it) {
47 spdy_servers_map_.Put(*it, support_spdy); 47 spdy_servers_map_.Put(*it, support_spdy);
48 } 48 }
49 } 49 }
50 50
51 void HttpServerPropertiesImpl::InitializeAlternateProtocolServers( 51 void HttpServerPropertiesImpl::InitializeAlternateProtocolServers(
52 AlternateProtocolMap* alternate_protocol_map) { 52 AlternateProtocolMap* alternate_protocol_map) {
53 // Keep all the broken ones since those don't get persisted. 53 for (AlternateProtocolMap::iterator alternate_protocols =
54 for (AlternateProtocolMap::iterator it = alternate_protocol_map_.begin(); 54 alternate_protocol_map_.begin();
55 it != alternate_protocol_map_.end();) { 55 alternate_protocols != alternate_protocol_map_.end();) {
56 AlternateProtocolMap::iterator old_it = it; 56 // TODO(bnc): Factor out code shared with ClearNonBrokenAlternateProtocols
57 ++it; 57 // into separate method.
58 if (!old_it->second.is_broken) { 58 // Keep all the broken ones since those don't get persisted.
59 alternate_protocol_map_.Erase(old_it); 59 for (AlternateProtocols::iterator it = alternate_protocols->second.begin();
60 it != alternate_protocols->second.end();) {
61 if (!it->is_broken) {
62 it = alternate_protocols->second.erase(it);
63 } else {
64 ++it;
65 }
66 }
67 if (alternate_protocols->second.size() == 0) {
68 RemoveCanonicalHost(alternate_protocols->first);
69 alternate_protocols = alternate_protocol_map_.Erase(alternate_protocols);
70 } else {
71 ++alternate_protocols;
60 } 72 }
61 } 73 }
62 74
63 // Add the entries from persisted data. 75 // Add the entries from persisted data.
64 for (AlternateProtocolMap::reverse_iterator it = 76 for (AlternateProtocolMap::reverse_iterator it =
65 alternate_protocol_map->rbegin(); 77 alternate_protocol_map->rbegin();
66 it != alternate_protocol_map->rend(); ++it) { 78 it != alternate_protocol_map->rend(); ++it) {
67 alternate_protocol_map_.Put(it->first, it->second); 79 alternate_protocol_map_.Put(it->first, it->second);
68 } 80 }
69 81
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 230
219 void HttpServerPropertiesImpl::MaybeForceHTTP11(const HostPortPair& server, 231 void HttpServerPropertiesImpl::MaybeForceHTTP11(const HostPortPair& server,
220 SSLConfig* ssl_config) { 232 SSLConfig* ssl_config) {
221 if (RequiresHTTP11(server)) { 233 if (RequiresHTTP11(server)) {
222 ForceHTTP11(ssl_config); 234 ForceHTTP11(ssl_config);
223 } 235 }
224 } 236 }
225 237
226 bool HttpServerPropertiesImpl::HasAlternateProtocol( 238 bool HttpServerPropertiesImpl::HasAlternateProtocol(
227 const HostPortPair& server) { 239 const HostPortPair& server) {
228 if (g_forced_alternate_protocol) 240 return GetAlternateProtocol(server).protocol !=
229 return true; 241 UNINITIALIZED_ALTERNATE_PROTOCOL;
230 AlternateProtocolMap::const_iterator it =
231 GetAlternateProtocolIterator(server);
232 return it != alternate_protocol_map_.end() &&
233 it->second.probability >= alternate_protocol_probability_threshold_;
234 } 242 }
235 243
236 std::string HttpServerPropertiesImpl::GetCanonicalSuffix( 244 std::string HttpServerPropertiesImpl::GetCanonicalSuffix(
237 const HostPortPair& server) { 245 const HostPortPair& server) {
238 // If this host ends with a canonical suffix, then return the canonical 246 // If this host ends with a canonical suffix, then return the canonical
239 // suffix. 247 // suffix.
240 for (size_t i = 0; i < canonical_suffixes_.size(); ++i) { 248 for (size_t i = 0; i < canonical_suffixes_.size(); ++i) {
241 std::string canonical_suffix = canonical_suffixes_[i]; 249 std::string canonical_suffix = canonical_suffixes_[i];
242 if (EndsWith(server.host(), canonical_suffixes_[i], false)) { 250 if (EndsWith(server.host(), canonical_suffixes_[i], false)) {
243 return canonical_suffix; 251 return canonical_suffix;
244 } 252 }
245 } 253 }
246 return std::string(); 254 return std::string();
247 } 255 }
248 256
249 AlternateProtocolInfo 257 AlternateProtocolInfo HttpServerPropertiesImpl::GetAlternateProtocol(
250 HttpServerPropertiesImpl::GetAlternateProtocol(
251 const HostPortPair& server) { 258 const HostPortPair& server) {
252 DCHECK(HasAlternateProtocol(server)); 259 AlternateProtocolMap::const_iterator alternate_protocols =
260 GetAlternateProtocolIterator(server);
261 if (alternate_protocols != alternate_protocol_map_.end()) {
262 for (const AlternateProtocolInfo& alternate_protocol :
263 alternate_protocols->second) {
264 if (!alternate_protocol.is_broken &&
265 alternate_protocol.probability >=
266 alternate_protocol_probability_threshold_) {
267 return alternate_protocol;
268 }
269 }
270 }
253 271
254 AlternateProtocolMap::const_iterator it = 272 if (g_forced_alternate_protocol)
255 GetAlternateProtocolIterator(server); 273 return *g_forced_alternate_protocol;
256 if (it != alternate_protocol_map_.end())
257 return it->second;
258 274
259 // We must be forcing an alternate. 275 AlternateProtocolInfo uninitialized_alternate_protocol;
260 DCHECK(g_forced_alternate_protocol); 276 return uninitialized_alternate_protocol;
261 return *g_forced_alternate_protocol;
262 } 277 }
263 278
264 void HttpServerPropertiesImpl::SetAlternateProtocol( 279 void HttpServerPropertiesImpl::AddAlternateProtocol(
265 const HostPortPair& server, 280 const HostPortPair& server,
266 uint16 alternate_port, 281 uint16 alternate_port,
267 AlternateProtocol alternate_protocol, 282 AlternateProtocol alternate_protocol,
268 double alternate_probability) { 283 double alternate_probability) {
269 284 if (!IsAlternateProtocolValid(alternate_protocol))
285 return;
270 AlternateProtocolInfo alternate(alternate_port, 286 AlternateProtocolInfo alternate(alternate_port,
271 alternate_protocol, 287 alternate_protocol,
272 alternate_probability); 288 alternate_probability);
273 AlternateProtocolMap::const_iterator it = 289 AlternateProtocolMap::const_iterator map_it =
274 GetAlternateProtocolIterator(server); 290 alternate_protocol_map_.Get(server);
275 if (it != alternate_protocol_map_.end()) { 291 if (map_it != alternate_protocol_map_.end()) {
276 const AlternateProtocolInfo existing_alternate = it->second; 292 AlternateProtocols existing_alternates = map_it->second;
277 293 AlternateProtocols::iterator it;
278 if (existing_alternate.is_broken) { 294 for (it = existing_alternates.begin(); it != existing_alternates.end();
279 DVLOG(1) << "Ignore alternate protocol since it's known to be broken."; 295 ++it) {
280 return; 296 if (it->EqualsModuloProbability(alternate)) {
297 break;
298 }
281 } 299 }
282 300
283 if (!existing_alternate.Equals(alternate)) { 301 if (it != existing_alternates.end()) {
284 LOG(WARNING) << "Changing the alternate protocol for: " 302 if (it->is_broken) {
285 << server.ToString() 303 DVLOG(1) << "Ignore alternate protocol since it's known to be broken.";
286 << " from [Port: " << existing_alternate.port 304 return;
287 << ", Protocol: " << existing_alternate.protocol 305 }
288 << ", Probability: " << existing_alternate.probability 306 if (it->probability != alternate_probability) {
289 << "] to [Port: " << alternate_port 307 LOG(WARNING) << "Changing the probability of alternate protocol for: "
290 << ", Protocol: " << alternate_protocol 308 << server.ToString() << " Port: " << it->port
291 << ", Probability: " << alternate_probability 309 << ", Protocol: " << it->protocol
292 << "]."; 310 << ", Probability from: " << it->probability
311 << " to: " << alternate_probability << ".";
312 it->probability = alternate_probability;
313 }
314 } else {
315 existing_alternates.push_back(alternate);
293 } 316 }
317
318 alternate_protocol_map_.Put(server, existing_alternates);
294 } else { 319 } else {
295 if (alternate_probability >= alternate_protocol_probability_threshold_) { 320 if (alternate_probability >= alternate_protocol_probability_threshold_) {
296 // TODO(rch): Consider the case where multiple requests are started 321 // TODO(rch): Consider the case where multiple requests are started
297 // before the first completes. In this case, only one of the jobs 322 // before the first completes. In this case, only one of the jobs
298 // would reach this code, whereas all of them should should have. 323 // would reach this code, whereas all of them should should have.
299 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_MAPPING_MISSING); 324 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_MAPPING_MISSING);
300 } 325 }
326 alternate_protocol_map_.Put(server,
327 AlternateProtocols(/*size=*/1, alternate));
301 } 328 }
302 329
303 alternate_protocol_map_.Put(server, alternate);
304
305 // If this host ends with a canonical suffix, then set it as the 330 // If this host ends with a canonical suffix, then set it as the
306 // canonical host. 331 // canonical host.
307 for (size_t i = 0; i < canonical_suffixes_.size(); ++i) { 332 for (size_t i = 0; i < canonical_suffixes_.size(); ++i) {
308 std::string canonical_suffix = canonical_suffixes_[i]; 333 std::string canonical_suffix = canonical_suffixes_[i];
309 if (EndsWith(server.host(), canonical_suffixes_[i], false)) { 334 if (EndsWith(server.host(), canonical_suffixes_[i], false)) {
310 HostPortPair canonical_host(canonical_suffix, server.port()); 335 HostPortPair canonical_host(canonical_suffix, server.port());
311 canonical_host_to_origin_map_[canonical_host] = server; 336 canonical_host_to_origin_map_[canonical_host] = server;
312 break; 337 break;
313 } 338 }
314 } 339 }
315 } 340 }
316 341
317 void HttpServerPropertiesImpl::SetBrokenAlternateProtocol( 342 void HttpServerPropertiesImpl::SetBrokenAlternateProtocol(
318 const HostPortPair& server) { 343 const HostPortPair& server,
319 AlternateProtocolMap::iterator it = alternate_protocol_map_.Get(server); 344 const AlternateProtocolInfo& broken_alternate_protocol) {
320 if (it == alternate_protocol_map_.end()) { 345 if (!IsAlternateProtocolValid(broken_alternate_protocol.protocol))
321 if (!HasAlternateProtocol(server)) { 346 return;
322 LOG(DFATAL) << "Trying to mark unknown alternate protocol broken."; 347 AddAlternateProtocol(server, broken_alternate_protocol.port,
323 return; 348 broken_alternate_protocol.protocol,
349 broken_alternate_protocol.probability);
350 AlternateProtocolMap::iterator alternate_protocols =
351 alternate_protocol_map_.Get(server);
352 DCHECK(alternate_protocols != alternate_protocol_map_.end());
353 AlternateProtocols::iterator it;
354 for (it = alternate_protocols->second.begin();
355 it != alternate_protocols->second.end(); ++it) {
356 if (it->Equals(broken_alternate_protocol)) {
357 it->is_broken = true;
358 break;
324 } 359 }
325 // This server's alternate protocol information is coming from a canonical
326 // server. Add an entry in the map for this server explicitly so that
327 // it can be marked as broken.
328 it = alternate_protocol_map_.Put(server, GetAlternateProtocol(server));
329 } 360 }
330 it->second.is_broken = true; 361 DCHECK(it != alternate_protocols->second.end());
331 int count = ++broken_alternate_protocol_map_[server]; 362
363 const BrokenAlternateProtocolEntry entry(server,
364 broken_alternate_protocol.port,
365 broken_alternate_protocol.protocol);
366 int count = ++broken_alternate_protocol_map_[entry];
332 base::TimeDelta delay = 367 base::TimeDelta delay =
333 base::TimeDelta::FromSeconds(kBrokenAlternateProtocolDelaySecs); 368 base::TimeDelta::FromSeconds(kBrokenAlternateProtocolDelaySecs);
334 BrokenAlternateProtocolEntry entry; 369 base::TimeTicks when = base::TimeTicks::Now() + delay * (1 << (count - 1));
335 entry.server = server; 370 broken_alternate_protocol_list_.push_back(
336 entry.when = base::TimeTicks::Now() + delay * (1 << (count - 1)); 371 BrokenAlternateProtocolEntryWithTime(entry, when));
337 broken_alternate_protocol_list_.push_back(entry);
338 372
339 // Do not leave this host as canonical so that we don't infer the other 373 // Do not leave this host as canonical so that we don't infer the other
340 // hosts are also broken without testing them first. 374 // hosts are also broken without testing them first.
341 RemoveCanonicalHost(server); 375 RemoveCanonicalHost(server);
342 376
343 // If this is the only entry in the list, schedule an expiration task. 377 // If this is the only entry in the list, schedule an expiration task.
344 // Otherwse it will be rescheduled automatically when the pending 378 // Otherwise it will be rescheduled automatically when the pending task runs.
345 // task runs.
346 if (broken_alternate_protocol_list_.size() == 1) { 379 if (broken_alternate_protocol_list_.size() == 1) {
347 ScheduleBrokenAlternateProtocolMappingsExpiration(); 380 ScheduleBrokenAlternateProtocolMappingsExpiration();
348 } 381 }
349 } 382 }
350 383
351 bool HttpServerPropertiesImpl::WasAlternateProtocolRecentlyBroken( 384 bool HttpServerPropertiesImpl::WasAlternateProtocolRecentlyBroken(
352 const HostPortPair& server) { 385 const HostPortPair& server,
353 return ContainsKey(broken_alternate_protocol_map_, server); 386 const AlternateProtocolInfo& alternate_protocol) {
387 const BrokenAlternateProtocolEntry entry(server, alternate_protocol.port,
388 alternate_protocol.protocol);
389 return ContainsKey(broken_alternate_protocol_map_, entry);
354 } 390 }
355 391
356 void HttpServerPropertiesImpl::ConfirmAlternateProtocol( 392 void HttpServerPropertiesImpl::ConfirmAlternateProtocol(
357 const HostPortPair& server) { 393 const HostPortPair& server,
358 broken_alternate_protocol_map_.erase(server); 394 const AlternateProtocolInfo& alternate_protocol) {
395 const BrokenAlternateProtocolEntry entry(server, alternate_protocol.port,
396 alternate_protocol.protocol);
397 broken_alternate_protocol_map_.erase(entry);
359 } 398 }
360 399
361 void HttpServerPropertiesImpl::ClearAlternateProtocol( 400 void HttpServerPropertiesImpl::ClearAlternateProtocol(
362 const HostPortPair& server) { 401 const HostPortPair& server) {
363 AlternateProtocolMap::iterator it = alternate_protocol_map_.Peek(server); 402 AlternateProtocolMap::iterator it = alternate_protocol_map_.Peek(server);
364 if (it != alternate_protocol_map_.end()) 403 if (it != alternate_protocol_map_.end())
365 alternate_protocol_map_.Erase(it); 404 alternate_protocol_map_.Erase(it);
366 405
367 RemoveCanonicalHost(server); 406 RemoveCanonicalHost(server);
368 } 407 }
369 408
409 void HttpServerPropertiesImpl::ClearNonBrokenAlternateProtocols(
410 const HostPortPair& server) {
411 AlternateProtocolMap::iterator alternate_protocols =
412 alternate_protocol_map_.Peek(server);
413 if (alternate_protocols == alternate_protocol_map_.end()) {
414 return;
415 }
416 for (AlternateProtocols::iterator it = alternate_protocols->second.begin();
417 it != alternate_protocols->second.end();) {
418 if (!it->is_broken) {
419 it = alternate_protocols->second.erase(it);
420 } else {
421 ++it;
422 }
423 }
424 if (alternate_protocols->second.size() == 0) {
425 alternate_protocol_map_.Erase(alternate_protocols);
426 RemoveCanonicalHost(server);
427 }
428 }
429
430 void HttpServerPropertiesImpl::RemoveAlternateProtocol(
431 const HostPortPair& server,
432 const AlternateProtocolInfo& alternate_protocol) {
433 AlternateProtocolMap::iterator alternate_protocols =
434 alternate_protocol_map_.Peek(server);
435 if (alternate_protocols == alternate_protocol_map_.end()) {
436 return;
437 }
438 for (AlternateProtocols::iterator it = alternate_protocols->second.begin();
439 it != alternate_protocols->second.end(); ++it) {
440 if (it->EqualsModuloProbability(alternate_protocol)) {
441 alternate_protocols->second.erase(it);
442 break;
443 }
444 }
445 if (alternate_protocols->second.size() == 0) {
446 alternate_protocol_map_.Erase(alternate_protocols);
447 RemoveCanonicalHost(server);
448 }
449 }
450
370 const AlternateProtocolMap& 451 const AlternateProtocolMap&
371 HttpServerPropertiesImpl::alternate_protocol_map() const { 452 HttpServerPropertiesImpl::alternate_protocol_map() const {
372 return alternate_protocol_map_; 453 return alternate_protocol_map_;
373 } 454 }
374 455
375 const SettingsMap& HttpServerPropertiesImpl::GetSpdySettings( 456 const SettingsMap& HttpServerPropertiesImpl::GetSpdySettings(
376 const HostPortPair& host_port_pair) { 457 const HostPortPair& host_port_pair) {
377 SpdySettingsMap::iterator it = spdy_settings_map_.Get(host_port_pair); 458 SpdySettingsMap::iterator it = spdy_settings_map_.Get(host_port_pair);
378 if (it == spdy_settings_map_.end()) { 459 if (it == spdy_settings_map_.end()) {
379 CR_DEFINE_STATIC_LOCAL(SettingsMap, kEmptySettingsMap, ()); 460 CR_DEFINE_STATIC_LOCAL(SettingsMap, kEmptySettingsMap, ());
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
502 583
503 if (!canonical->second.Equals(server)) 584 if (!canonical->second.Equals(server))
504 return; 585 return;
505 586
506 canonical_host_to_origin_map_.erase(canonical->first); 587 canonical_host_to_origin_map_.erase(canonical->first);
507 } 588 }
508 589
509 void HttpServerPropertiesImpl::ExpireBrokenAlternateProtocolMappings() { 590 void HttpServerPropertiesImpl::ExpireBrokenAlternateProtocolMappings() {
510 base::TimeTicks now = base::TimeTicks::Now(); 591 base::TimeTicks now = base::TimeTicks::Now();
511 while (!broken_alternate_protocol_list_.empty()) { 592 while (!broken_alternate_protocol_list_.empty()) {
512 BrokenAlternateProtocolEntry entry = 593 BrokenAlternateProtocolEntryWithTime entry_with_time =
513 broken_alternate_protocol_list_.front(); 594 broken_alternate_protocol_list_.front();
514 if (now < entry.when) { 595 if (now < entry_with_time.when) {
515 break; 596 break;
516 } 597 }
517 598
518 ClearAlternateProtocol(entry.server); 599 const BrokenAlternateProtocolEntry& entry =
600 entry_with_time.broken_alternate_protocol_entry;
601 const AlternateProtocolInfo alternate_protocol(entry.port, entry.protocol,
602 1.0);
603 RemoveAlternateProtocol(entry.server, alternate_protocol);
519 broken_alternate_protocol_list_.pop_front(); 604 broken_alternate_protocol_list_.pop_front();
520 } 605 }
521 ScheduleBrokenAlternateProtocolMappingsExpiration(); 606 ScheduleBrokenAlternateProtocolMappingsExpiration();
522 } 607 }
523 608
524 void 609 void
525 HttpServerPropertiesImpl::ScheduleBrokenAlternateProtocolMappingsExpiration() { 610 HttpServerPropertiesImpl::ScheduleBrokenAlternateProtocolMappingsExpiration() {
526 if (broken_alternate_protocol_list_.empty()) { 611 if (broken_alternate_protocol_list_.empty()) {
527 return; 612 return;
528 } 613 }
529 base::TimeTicks now = base::TimeTicks::Now(); 614 base::TimeTicks now = base::TimeTicks::Now();
530 base::TimeTicks when = broken_alternate_protocol_list_.front().when; 615 base::TimeTicks when = broken_alternate_protocol_list_.front().when;
531 base::TimeDelta delay = when > now ? when - now : base::TimeDelta(); 616 base::TimeDelta delay = when > now ? when - now : base::TimeDelta();
532 base::MessageLoop::current()->PostDelayedTask( 617 base::MessageLoop::current()->PostDelayedTask(
533 FROM_HERE, 618 FROM_HERE,
534 base::Bind( 619 base::Bind(
535 &HttpServerPropertiesImpl::ExpireBrokenAlternateProtocolMappings, 620 &HttpServerPropertiesImpl::ExpireBrokenAlternateProtocolMappings,
536 weak_ptr_factory_.GetWeakPtr()), 621 weak_ptr_factory_.GetWeakPtr()),
537 delay); 622 delay);
538 } 623 }
539 624
540 } // namespace net 625 } // namespace net
OLDNEW
« no previous file with comments | « net/http/http_server_properties_impl.h ('k') | net/http/http_server_properties_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698