| 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 |