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 "chrome/browser/net/http_server_properties_manager.h" | 5 #include "chrome/browser/net/http_server_properties_manager.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/metrics/histogram.h" | 8 #include "base/metrics/histogram.h" |
9 #include "base/prefs/pref_service.h" | 9 #include "base/prefs/pref_service.h" |
| 10 #include "base/rand_util.h" |
10 #include "base/stl_util.h" | 11 #include "base/stl_util.h" |
11 #include "base/strings/string_number_conversions.h" | 12 #include "base/strings/string_number_conversions.h" |
12 #include "base/strings/stringprintf.h" | 13 #include "base/strings/stringprintf.h" |
13 #include "base/values.h" | 14 #include "base/values.h" |
14 #include "chrome/browser/chrome_notification_types.h" | 15 #include "chrome/browser/chrome_notification_types.h" |
15 #include "chrome/common/pref_names.h" | 16 #include "chrome/common/pref_names.h" |
16 #include "components/pref_registry/pref_registry_syncable.h" | 17 #include "components/pref_registry/pref_registry_syncable.h" |
17 #include "content/public/browser/browser_thread.h" | 18 #include "content/public/browser/browser_thread.h" |
18 #include "content/public/browser/notification_details.h" | 19 #include "content/public/browser/notification_details.h" |
19 #include "content/public/browser/notification_source.h" | 20 #include "content/public/browser/notification_source.h" |
(...skipping 12 matching lines...) Expand all Loading... |
32 // Time to wait before starting an update the preferences from the | 33 // Time to wait before starting an update the preferences from the |
33 // http_server_properties_impl_ cache. Scheduling another update during this | 34 // http_server_properties_impl_ cache. Scheduling another update during this |
34 // period will reset the timer. | 35 // period will reset the timer. |
35 const int64 kUpdatePrefsDelayMs = 5000; | 36 const int64 kUpdatePrefsDelayMs = 5000; |
36 | 37 |
37 // "version" 0 indicates, http_server_properties doesn't have "version" | 38 // "version" 0 indicates, http_server_properties doesn't have "version" |
38 // property. | 39 // property. |
39 const int kMissingVersion = 0; | 40 const int kMissingVersion = 0; |
40 | 41 |
41 // The version number of persisted http_server_properties. | 42 // The version number of persisted http_server_properties. |
42 const int kVersionNumber = 2; | 43 const int kVersionNumber = 3; |
43 | 44 |
44 typedef std::vector<std::string> StringVector; | 45 typedef std::vector<std::string> StringVector; |
45 | 46 |
46 // Persist 200 MRU AlternateProtocolHostPortPairs. | 47 // Load either 200 or 1000 servers based on a coin flip. |
47 const int kMaxAlternateProtocolHostsToPersist = 200; | 48 const int k200AlternateProtocolHostsToLoad = 200; |
| 49 const int k1000AlternateProtocolHostsToLoad = 1000; |
| 50 // Persist 1000 MRU AlternateProtocolHostPortPairs. |
| 51 const int kMaxAlternateProtocolHostsToPersist = 1000; |
48 | 52 |
49 // Persist 200 MRU SpdySettingsHostPortPairs. | 53 // Persist 200 MRU SpdySettingsHostPortPairs. |
50 const int kMaxSpdySettingsHostsToPersist = 200; | 54 const int kMaxSpdySettingsHostsToPersist = 200; |
51 | 55 |
52 // Persist 300 MRU SupportsSpdyServerHostPortPairs. | 56 // Persist 300 MRU SupportsSpdyServerHostPortPairs. |
53 const int kMaxSupportsSpdyServerHostsToPersist = 300; | 57 const int kMaxSupportsSpdyServerHostsToPersist = 300; |
54 | 58 |
55 } // namespace | 59 } // namespace |
56 | 60 |
57 //////////////////////////////////////////////////////////////////////////////// | 61 //////////////////////////////////////////////////////////////////////////////// |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
206 http_server_properties_impl_->ClearAlternateProtocol(server); | 210 http_server_properties_impl_->ClearAlternateProtocol(server); |
207 ScheduleUpdatePrefsOnIO(); | 211 ScheduleUpdatePrefsOnIO(); |
208 } | 212 } |
209 | 213 |
210 const net::AlternateProtocolMap& | 214 const net::AlternateProtocolMap& |
211 HttpServerPropertiesManager::alternate_protocol_map() const { | 215 HttpServerPropertiesManager::alternate_protocol_map() const { |
212 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 216 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
213 return http_server_properties_impl_->alternate_protocol_map(); | 217 return http_server_properties_impl_->alternate_protocol_map(); |
214 } | 218 } |
215 | 219 |
| 220 void HttpServerPropertiesManager::SetAlternateProtocolExperiment( |
| 221 net::AlternateProtocolExperiment experiment) { |
| 222 http_server_properties_impl_->SetAlternateProtocolExperiment(experiment); |
| 223 } |
| 224 |
| 225 net::AlternateProtocolExperiment |
| 226 HttpServerPropertiesManager::GetAlternateProtocolExperiment() const { |
| 227 return http_server_properties_impl_->GetAlternateProtocolExperiment(); |
| 228 } |
| 229 |
216 const net::SettingsMap& | 230 const net::SettingsMap& |
217 HttpServerPropertiesManager::GetSpdySettings( | 231 HttpServerPropertiesManager::GetSpdySettings( |
218 const net::HostPortPair& host_port_pair) { | 232 const net::HostPortPair& host_port_pair) { |
219 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 233 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
220 return http_server_properties_impl_->GetSpdySettings(host_port_pair); | 234 return http_server_properties_impl_->GetSpdySettings(host_port_pair); |
221 } | 235 } |
222 | 236 |
223 bool HttpServerPropertiesManager::SetSpdySetting( | 237 bool HttpServerPropertiesManager::SetSpdySetting( |
224 const net::HostPortPair& host_port_pair, | 238 const net::HostPortPair& host_port_pair, |
225 net::SpdySettingsIds id, | 239 net::SpdySettingsIds id, |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
338 } | 352 } |
339 | 353 |
340 // String is host/port pair of spdy server. | 354 // String is host/port pair of spdy server. |
341 scoped_ptr<StringVector> spdy_servers(new StringVector); | 355 scoped_ptr<StringVector> spdy_servers(new StringVector); |
342 scoped_ptr<net::SpdySettingsMap> spdy_settings_map( | 356 scoped_ptr<net::SpdySettingsMap> spdy_settings_map( |
343 new net::SpdySettingsMap(kMaxSpdySettingsHostsToPersist)); | 357 new net::SpdySettingsMap(kMaxSpdySettingsHostsToPersist)); |
344 scoped_ptr<net::PipelineCapabilityMap> pipeline_capability_map( | 358 scoped_ptr<net::PipelineCapabilityMap> pipeline_capability_map( |
345 new net::PipelineCapabilityMap); | 359 new net::PipelineCapabilityMap); |
346 scoped_ptr<net::AlternateProtocolMap> alternate_protocol_map( | 360 scoped_ptr<net::AlternateProtocolMap> alternate_protocol_map( |
347 new net::AlternateProtocolMap(kMaxAlternateProtocolHostsToPersist)); | 361 new net::AlternateProtocolMap(kMaxAlternateProtocolHostsToPersist)); |
| 362 // TODO(rtenneti): Delete the following code after the experiment. |
| 363 int alternate_protocols_to_load = k200AlternateProtocolHostsToLoad; |
| 364 net::AlternateProtocolExperiment alternate_protocol_experiment = |
| 365 net::ALTERNATE_PROTOCOL_NOT_PART_OF_EXPERIMENT; |
| 366 if (version == kVersionNumber) { |
| 367 if (base::RandInt(0, 99) == 0) { |
| 368 alternate_protocol_experiment = |
| 369 net::ALTERNATE_PROTOCOL_TRUNCATED_200_SERVERS; |
| 370 } else { |
| 371 alternate_protocols_to_load = k1000AlternateProtocolHostsToLoad; |
| 372 alternate_protocol_experiment = |
| 373 net::ALTERNATE_PROTOCOL_TRUNCATED_1000_SERVERS; |
| 374 } |
| 375 DVLOG(1) << "# of servers that support alternate_protocol: " |
| 376 << alternate_protocols_to_load; |
| 377 } |
348 | 378 |
| 379 int count = 0; |
349 for (base::DictionaryValue::Iterator it(*servers_dict); !it.IsAtEnd(); | 380 for (base::DictionaryValue::Iterator it(*servers_dict); !it.IsAtEnd(); |
350 it.Advance()) { | 381 it.Advance()) { |
351 // Get server's host/pair. | 382 // Get server's host/pair. |
352 const std::string& server_str = it.key(); | 383 const std::string& server_str = it.key(); |
353 net::HostPortPair server = net::HostPortPair::FromString(server_str); | 384 net::HostPortPair server = net::HostPortPair::FromString(server_str); |
354 if (server.host().empty()) { | 385 if (server.host().empty()) { |
355 DVLOG(1) << "Malformed http_server_properties for server: " << server_str; | 386 DVLOG(1) << "Malformed http_server_properties for server: " << server_str; |
356 detected_corrupted_prefs = true; | 387 detected_corrupted_prefs = true; |
357 continue; | 388 continue; |
358 } | 389 } |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
411 | 442 |
412 // Get alternate_protocol server. | 443 // Get alternate_protocol server. |
413 DCHECK(alternate_protocol_map->Peek(server) == | 444 DCHECK(alternate_protocol_map->Peek(server) == |
414 alternate_protocol_map->end()); | 445 alternate_protocol_map->end()); |
415 const base::DictionaryValue* port_alternate_protocol_dict = NULL; | 446 const base::DictionaryValue* port_alternate_protocol_dict = NULL; |
416 if (!server_pref_dict->GetDictionaryWithoutPathExpansion( | 447 if (!server_pref_dict->GetDictionaryWithoutPathExpansion( |
417 "alternate_protocol", &port_alternate_protocol_dict)) { | 448 "alternate_protocol", &port_alternate_protocol_dict)) { |
418 continue; | 449 continue; |
419 } | 450 } |
420 | 451 |
| 452 if (count >= alternate_protocols_to_load) |
| 453 continue; |
421 do { | 454 do { |
422 int port = 0; | 455 int port = 0; |
423 if (!port_alternate_protocol_dict->GetIntegerWithoutPathExpansion( | 456 if (!port_alternate_protocol_dict->GetIntegerWithoutPathExpansion( |
424 "port", &port) || (port > (1 << 16))) { | 457 "port", &port) || (port > (1 << 16))) { |
425 DVLOG(1) << "Malformed Alternate-Protocol server: " << server_str; | 458 DVLOG(1) << "Malformed Alternate-Protocol server: " << server_str; |
426 detected_corrupted_prefs = true; | 459 detected_corrupted_prefs = true; |
427 continue; | 460 continue; |
428 } | 461 } |
429 std::string protocol_str; | 462 std::string protocol_str; |
430 if (!port_alternate_protocol_dict->GetStringWithoutPathExpansion( | 463 if (!port_alternate_protocol_dict->GetStringWithoutPathExpansion( |
431 "protocol_str", &protocol_str)) { | 464 "protocol_str", &protocol_str)) { |
432 DVLOG(1) << "Malformed Alternate-Protocol server: " << server_str; | 465 DVLOG(1) << "Malformed Alternate-Protocol server: " << server_str; |
433 detected_corrupted_prefs = true; | 466 detected_corrupted_prefs = true; |
434 continue; | 467 continue; |
435 } | 468 } |
436 net::AlternateProtocol protocol = | 469 net::AlternateProtocol protocol = |
437 net::AlternateProtocolFromString(protocol_str); | 470 net::AlternateProtocolFromString(protocol_str); |
438 if (!net::IsAlternateProtocolValid(protocol)) { | 471 if (!net::IsAlternateProtocolValid(protocol)) { |
439 DVLOG(1) << "Malformed Alternate-Protocol server: " << server_str; | 472 DVLOG(1) << "Malformed Alternate-Protocol server: " << server_str; |
440 detected_corrupted_prefs = true; | 473 detected_corrupted_prefs = true; |
441 continue; | 474 continue; |
442 } | 475 } |
443 | 476 |
444 net::PortAlternateProtocolPair port_alternate_protocol; | 477 net::PortAlternateProtocolPair port_alternate_protocol; |
445 port_alternate_protocol.port = port; | 478 port_alternate_protocol.port = port; |
446 port_alternate_protocol.protocol = protocol; | 479 port_alternate_protocol.protocol = protocol; |
447 | 480 |
448 alternate_protocol_map->Put(server, port_alternate_protocol); | 481 alternate_protocol_map->Put(server, port_alternate_protocol); |
| 482 ++count; |
449 } while (false); | 483 } while (false); |
450 } | 484 } |
451 | 485 |
452 BrowserThread::PostTask( | 486 BrowserThread::PostTask( |
453 BrowserThread::IO, | 487 BrowserThread::IO, |
454 FROM_HERE, | 488 FROM_HERE, |
455 base::Bind(&HttpServerPropertiesManager:: | 489 base::Bind(&HttpServerPropertiesManager:: |
456 UpdateCacheFromPrefsOnIO, | 490 UpdateCacheFromPrefsOnIO, |
457 base::Unretained(this), | 491 base::Unretained(this), |
458 base::Owned(spdy_servers.release()), | 492 base::Owned(spdy_servers.release()), |
459 base::Owned(spdy_settings_map.release()), | 493 base::Owned(spdy_settings_map.release()), |
460 base::Owned(alternate_protocol_map.release()), | 494 base::Owned(alternate_protocol_map.release()), |
461 base::Owned(pipeline_capability_map.release()), | 495 base::Owned(pipeline_capability_map.release()), |
| 496 alternate_protocol_experiment, |
462 detected_corrupted_prefs)); | 497 detected_corrupted_prefs)); |
463 } | 498 } |
464 | 499 |
465 void HttpServerPropertiesManager::UpdateCacheFromPrefsOnIO( | 500 void HttpServerPropertiesManager::UpdateCacheFromPrefsOnIO( |
466 StringVector* spdy_servers, | 501 StringVector* spdy_servers, |
467 net::SpdySettingsMap* spdy_settings_map, | 502 net::SpdySettingsMap* spdy_settings_map, |
468 net::AlternateProtocolMap* alternate_protocol_map, | 503 net::AlternateProtocolMap* alternate_protocol_map, |
469 net::PipelineCapabilityMap* pipeline_capability_map, | 504 net::PipelineCapabilityMap* pipeline_capability_map, |
| 505 net::AlternateProtocolExperiment alternate_protocol_experiment, |
470 bool detected_corrupted_prefs) { | 506 bool detected_corrupted_prefs) { |
471 // Preferences have the master data because admins might have pushed new | 507 // Preferences have the master data because admins might have pushed new |
472 // preferences. Update the cached data with new data from preferences. | 508 // preferences. Update the cached data with new data from preferences. |
473 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 509 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
474 | 510 |
475 UMA_HISTOGRAM_COUNTS("Net.CountOfSpdyServers", spdy_servers->size()); | 511 UMA_HISTOGRAM_COUNTS("Net.CountOfSpdyServers", spdy_servers->size()); |
476 http_server_properties_impl_->InitializeSpdyServers(spdy_servers, true); | 512 http_server_properties_impl_->InitializeSpdyServers(spdy_servers, true); |
477 | 513 |
478 // Clear the cached data and use the new spdy_settings from preferences. | 514 // Update the cached data and use the new spdy_settings from preferences. |
479 UMA_HISTOGRAM_COUNTS("Net.CountOfSpdySettings", spdy_settings_map->size()); | 515 UMA_HISTOGRAM_COUNTS("Net.CountOfSpdySettings", spdy_settings_map->size()); |
480 http_server_properties_impl_->InitializeSpdySettingsServers( | 516 http_server_properties_impl_->InitializeSpdySettingsServers( |
481 spdy_settings_map); | 517 spdy_settings_map); |
482 | 518 |
483 // Clear the cached data and use the new Alternate-Protocol server list from | 519 // Update the cached data and use the new Alternate-Protocol server list from |
484 // preferences. | 520 // preferences. |
485 UMA_HISTOGRAM_COUNTS("Net.CountOfAlternateProtocolServers", | 521 UMA_HISTOGRAM_COUNTS("Net.CountOfAlternateProtocolServers", |
486 alternate_protocol_map->size()); | 522 alternate_protocol_map->size()); |
487 http_server_properties_impl_->InitializeAlternateProtocolServers( | 523 http_server_properties_impl_->InitializeAlternateProtocolServers( |
488 alternate_protocol_map); | 524 alternate_protocol_map); |
| 525 http_server_properties_impl_->SetAlternateProtocolExperiment( |
| 526 alternate_protocol_experiment); |
489 | 527 |
490 UMA_HISTOGRAM_COUNTS("Net.CountOfPipelineCapableServers", | 528 UMA_HISTOGRAM_COUNTS("Net.CountOfPipelineCapableServers", |
491 pipeline_capability_map->size()); | 529 pipeline_capability_map->size()); |
492 http_server_properties_impl_->InitializePipelineCapabilities( | 530 http_server_properties_impl_->InitializePipelineCapabilities( |
493 pipeline_capability_map); | 531 pipeline_capability_map); |
494 | 532 |
495 // Update the prefs with what we have read (delete all corrupted prefs). | 533 // Update the prefs with what we have read (delete all corrupted prefs). |
496 if (detected_corrupted_prefs) | 534 if (detected_corrupted_prefs) |
497 ScheduleUpdatePrefsOnIO(); | 535 ScheduleUpdatePrefsOnIO(); |
498 } | 536 } |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
540 it != main_map.end() && count < kMaxSpdySettingsHostsToPersist; | 578 it != main_map.end() && count < kMaxSpdySettingsHostsToPersist; |
541 ++it, ++count) { | 579 ++it, ++count) { |
542 spdy_settings_map->Put(it->first, it->second); | 580 spdy_settings_map->Put(it->first, it->second); |
543 } | 581 } |
544 | 582 |
545 net::AlternateProtocolMap* alternate_protocol_map = | 583 net::AlternateProtocolMap* alternate_protocol_map = |
546 new net::AlternateProtocolMap(kMaxAlternateProtocolHostsToPersist); | 584 new net::AlternateProtocolMap(kMaxAlternateProtocolHostsToPersist); |
547 const net::AlternateProtocolMap& map = | 585 const net::AlternateProtocolMap& map = |
548 http_server_properties_impl_->alternate_protocol_map(); | 586 http_server_properties_impl_->alternate_protocol_map(); |
549 count = 0; | 587 count = 0; |
| 588 typedef std::map<std::string, bool> CanonicalHostPersistedMap; |
| 589 CanonicalHostPersistedMap persisted_map; |
550 for (net::AlternateProtocolMap::const_iterator it = map.begin(); | 590 for (net::AlternateProtocolMap::const_iterator it = map.begin(); |
551 it != map.end() && count < kMaxAlternateProtocolHostsToPersist; | 591 it != map.end() && count < kMaxAlternateProtocolHostsToPersist; |
552 ++it, ++count) { | 592 ++it) { |
553 alternate_protocol_map->Put(it->first, it->second); | 593 const net::HostPortPair& server = it->first; |
| 594 std::string canonical_suffix = |
| 595 http_server_properties_impl_->GetCanonicalSuffix(server); |
| 596 if (!canonical_suffix.empty()) { |
| 597 if (persisted_map.find(canonical_suffix) != persisted_map.end()) |
| 598 continue; |
| 599 persisted_map[canonical_suffix] = true; |
| 600 } |
| 601 alternate_protocol_map->Put(server, it->second); |
| 602 ++count; |
554 } | 603 } |
555 | 604 |
556 net::PipelineCapabilityMap* pipeline_capability_map = | 605 net::PipelineCapabilityMap* pipeline_capability_map = |
557 new net::PipelineCapabilityMap; | 606 new net::PipelineCapabilityMap; |
558 *pipeline_capability_map = | 607 *pipeline_capability_map = |
559 http_server_properties_impl_->GetPipelineCapabilityMap(); | 608 http_server_properties_impl_->GetPipelineCapabilityMap(); |
560 | 609 |
561 // Update the preferences on the UI thread. | 610 // Update the preferences on the UI thread. |
562 BrowserThread::PostTask( | 611 BrowserThread::PostTask( |
563 BrowserThread::UI, | 612 BrowserThread::UI, |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
742 completion.Run(); | 791 completion.Run(); |
743 } | 792 } |
744 | 793 |
745 void HttpServerPropertiesManager::OnHttpServerPropertiesChanged() { | 794 void HttpServerPropertiesManager::OnHttpServerPropertiesChanged() { |
746 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 795 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
747 if (!setting_prefs_) | 796 if (!setting_prefs_) |
748 ScheduleUpdateCacheOnUI(); | 797 ScheduleUpdateCacheOnUI(); |
749 } | 798 } |
750 | 799 |
751 } // namespace chrome_browser_net | 800 } // namespace chrome_browser_net |
OLD | NEW |