| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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_manager.h" | 5 #include "net/http/http_server_properties_manager.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/metrics/histogram_macros.h" | 8 #include "base/metrics/histogram_macros.h" |
| 9 #include "base/prefs/pref_service.h" | 9 #include "base/prefs/pref_service.h" |
| 10 #include "base/single_thread_task_runner.h" | 10 #include "base/single_thread_task_runner.h" |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 // Time to wait before starting an update the preferences from the | 28 // Time to wait before starting an update the preferences from the |
| 29 // http_server_properties_impl_ cache. Scheduling another update during this | 29 // http_server_properties_impl_ cache. Scheduling another update during this |
| 30 // period will reset the timer. | 30 // period will reset the timer. |
| 31 const int64_t kUpdatePrefsDelayMs = 60000; | 31 const int64_t kUpdatePrefsDelayMs = 60000; |
| 32 | 32 |
| 33 // "version" 0 indicates, http_server_properties doesn't have "version" | 33 // "version" 0 indicates, http_server_properties doesn't have "version" |
| 34 // property. | 34 // property. |
| 35 const int kMissingVersion = 0; | 35 const int kMissingVersion = 0; |
| 36 | 36 |
| 37 // The version number of persisted http_server_properties. | 37 // The version number of persisted http_server_properties. |
| 38 const int kVersionNumber = 3; | 38 const int kVersionNumber = 4; |
| 39 | 39 |
| 40 // Persist 200 MRU AlternateProtocolHostPortPairs. | 40 // Persist 200 MRU AlternateProtocolHostPortPairs. |
| 41 const int kMaxAlternateProtocolHostsToPersist = 200; | 41 const int kMaxAlternateProtocolHostsToPersist = 200; |
| 42 | 42 |
| 43 // Persist 200 MRU SpdySettingsHostPortPairs. | 43 // Persist 200 MRU SpdySettingsHostPortPairs. |
| 44 const int kMaxSpdySettingsHostsToPersist = 200; | 44 const int kMaxSpdySettingsHostsToPersist = 200; |
| 45 | 45 |
| 46 // Persist 300 MRU SupportsSpdyServerHostPortPairs. | 46 // Persist 300 MRU SupportsSpdyServerHostPortPairs. |
| 47 const int kMaxSupportsSpdyServerHostsToPersist = 300; | 47 const int kMaxSupportsSpdyServerHostsToPersist = 300; |
| 48 | 48 |
| (...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 438 const base::DictionaryValue& http_server_properties_dict = | 438 const base::DictionaryValue& http_server_properties_dict = |
| 439 *pref_service_->GetDictionary(path_); | 439 *pref_service_->GetDictionary(path_); |
| 440 | 440 |
| 441 int version = kMissingVersion; | 441 int version = kMissingVersion; |
| 442 if (!http_server_properties_dict.GetIntegerWithoutPathExpansion(kVersionKey, | 442 if (!http_server_properties_dict.GetIntegerWithoutPathExpansion(kVersionKey, |
| 443 &version)) { | 443 &version)) { |
| 444 DVLOG(1) << "Missing version. Clearing all properties."; | 444 DVLOG(1) << "Missing version. Clearing all properties."; |
| 445 return; | 445 return; |
| 446 } | 446 } |
| 447 | 447 |
| 448 // The properties for a given server is in | 448 const base::DictionaryValue* servers_dict = nullptr; |
| 449 // http_server_properties_dict["servers"][server]. | 449 const base::ListValue* servers_list = nullptr; |
| 450 // Server data was stored in the following format in alphabetical order. | 450 if (version < 4) { |
| 451 // | 451 // The properties for a given server is in |
| 452 // "http_server_properties": { | 452 // http_server_properties_dict["servers"][server]. |
| 453 // "servers": { | 453 // Before Version 4, server data was stored in the following format in |
| 454 // "accounts.google.com:443": {...}, | 454 // alphabetical order. |
| 455 // "accounts.youtube.com:443": {...}, | 455 // |
| 456 // "android.clients.google.com:443": {...}, | 456 // "http_server_properties": { |
| 457 // ... | 457 // "servers": { |
| 458 // }, ... | 458 // "0-edge-chat.facebook.com:443" : {...}, |
| 459 // }, | 459 // "0.client-channel.google.com:443" : {...}, |
| 460 const base::DictionaryValue* servers_dict = NULL; | 460 // "yt3.ggpht.com:443" : {...}, |
| 461 if (!http_server_properties_dict.GetDictionaryWithoutPathExpansion( | 461 // ... |
| 462 kServersKey, &servers_dict)) { | 462 // }, ... |
| 463 DVLOG(1) << "Malformed http_server_properties for servers."; | 463 // }, |
| 464 return; | 464 if (!http_server_properties_dict.GetDictionaryWithoutPathExpansion( |
| 465 kServersKey, &servers_dict)) { |
| 466 DVLOG(1) << "Malformed http_server_properties for servers."; |
| 467 return; |
| 468 } |
| 469 } else { |
| 470 // From Version 4 onwards, data was stored in the following format. |
| 471 // |servers| are saved in MRU order. |
| 472 // |
| 473 // "http_server_properties": { |
| 474 // "servers": [ |
| 475 // {"yt3.ggpht.com:443" : {...}}, |
| 476 // {"0.client-channel.google.com:443" : {...}}, |
| 477 // {"0-edge-chat.facebook.com:443" : {...}}, |
| 478 // ... |
| 479 // ], ... |
| 480 // }, |
| 481 if (!http_server_properties_dict.GetListWithoutPathExpansion( |
| 482 kServersKey, &servers_list)) { |
| 483 DVLOG(1) << "Malformed http_server_properties for servers list."; |
| 484 return; |
| 485 } |
| 465 } | 486 } |
| 466 | 487 |
| 467 IPAddressNumber* addr = new IPAddressNumber; | 488 IPAddressNumber* addr = new IPAddressNumber; |
| 468 ReadSupportsQuic(http_server_properties_dict, addr); | 489 ReadSupportsQuic(http_server_properties_dict, addr); |
| 469 | 490 |
| 470 // String is host/port pair of spdy server. | 491 // String is host/port pair of spdy server. |
| 471 scoped_ptr<ServerList> spdy_servers(new ServerList); | 492 scoped_ptr<ServerList> spdy_servers(new ServerList); |
| 472 scoped_ptr<SpdySettingsMap> spdy_settings_map( | 493 scoped_ptr<SpdySettingsMap> spdy_settings_map( |
| 473 new SpdySettingsMap(kMaxSpdySettingsHostsToPersist)); | 494 new SpdySettingsMap(kMaxSpdySettingsHostsToPersist)); |
| 474 scoped_ptr<AlternativeServiceMap> alternative_service_map( | 495 scoped_ptr<AlternativeServiceMap> alternative_service_map( |
| 475 new AlternativeServiceMap(kMaxAlternateProtocolHostsToPersist)); | 496 new AlternativeServiceMap(kMaxAlternateProtocolHostsToPersist)); |
| 476 scoped_ptr<ServerNetworkStatsMap> server_network_stats_map( | 497 scoped_ptr<ServerNetworkStatsMap> server_network_stats_map( |
| 477 new ServerNetworkStatsMap(kMaxServerNetworkStatsHostsToPersist)); | 498 new ServerNetworkStatsMap(kMaxServerNetworkStatsHostsToPersist)); |
| 478 scoped_ptr<QuicServerInfoMap> quic_server_info_map( | 499 scoped_ptr<QuicServerInfoMap> quic_server_info_map( |
| 479 new QuicServerInfoMap(kMaxQuicServersToPersist)); | 500 new QuicServerInfoMap(kMaxQuicServersToPersist)); |
| 480 | 501 |
| 481 if (!AddServersData(*servers_dict, spdy_servers.get(), | 502 if (version < 4) { |
| 482 spdy_settings_map.get(), alternative_service_map.get(), | 503 if (!AddServersData(*servers_dict, spdy_servers.get(), |
| 483 server_network_stats_map.get())) { | 504 spdy_settings_map.get(), alternative_service_map.get(), |
| 484 detected_corrupted_prefs = true; | 505 server_network_stats_map.get())) { |
| 506 detected_corrupted_prefs = true; |
| 507 } |
| 508 } else { |
| 509 for (base::ListValue::const_iterator it = servers_list->begin(); |
| 510 it != servers_list->end(); ++it) { |
| 511 if (!(*it)->GetAsDictionary(&servers_dict)) { |
| 512 DVLOG(1) << "Malformed http_server_properties for servers dictionary."; |
| 513 detected_corrupted_prefs = true; |
| 514 continue; |
| 515 } |
| 516 if (!AddServersData( |
| 517 *servers_dict, spdy_servers.get(), spdy_settings_map.get(), |
| 518 alternative_service_map.get(), server_network_stats_map.get())) { |
| 519 detected_corrupted_prefs = true; |
| 520 } |
| 521 } |
| 485 } | 522 } |
| 486 | 523 |
| 487 if (!AddToQuicServerInfoMap(http_server_properties_dict, | 524 if (!AddToQuicServerInfoMap(http_server_properties_dict, |
| 488 quic_server_info_map.get())) { | 525 quic_server_info_map.get())) { |
| 489 detected_corrupted_prefs = true; | 526 detected_corrupted_prefs = true; |
| 490 } | 527 } |
| 491 | 528 |
| 492 network_task_runner_->PostTask( | 529 network_task_runner_->PostTask( |
| 493 FROM_HERE, | 530 FROM_HERE, |
| 494 base::Bind( | 531 base::Bind( |
| (...skipping 15 matching lines...) Expand all Loading... |
| 510 for (base::DictionaryValue::Iterator it(servers_dict); !it.IsAtEnd(); | 547 for (base::DictionaryValue::Iterator it(servers_dict); !it.IsAtEnd(); |
| 511 it.Advance()) { | 548 it.Advance()) { |
| 512 // Get server's host/pair. | 549 // Get server's host/pair. |
| 513 const std::string& server_str = it.key(); | 550 const std::string& server_str = it.key(); |
| 514 HostPortPair server = HostPortPair::FromString(server_str); | 551 HostPortPair server = HostPortPair::FromString(server_str); |
| 515 if (server.host().empty()) { | 552 if (server.host().empty()) { |
| 516 DVLOG(1) << "Malformed http_server_properties for server: " << server_str; | 553 DVLOG(1) << "Malformed http_server_properties for server: " << server_str; |
| 517 return false; | 554 return false; |
| 518 } | 555 } |
| 519 | 556 |
| 520 const base::DictionaryValue* server_pref_dict = NULL; | 557 const base::DictionaryValue* server_pref_dict = nullptr; |
| 521 if (!it.value().GetAsDictionary(&server_pref_dict)) { | 558 if (!it.value().GetAsDictionary(&server_pref_dict)) { |
| 522 DVLOG(1) << "Malformed http_server_properties server: " << server_str; | 559 DVLOG(1) << "Malformed http_server_properties server: " << server_str; |
| 523 return false; | 560 return false; |
| 524 } | 561 } |
| 525 | 562 |
| 526 // Get if server supports Spdy. | 563 // Get if server supports Spdy. |
| 527 bool supports_spdy = false; | 564 bool supports_spdy = false; |
| 528 if ((server_pref_dict->GetBoolean(kSupportsSpdyKey, &supports_spdy)) && | 565 if ((server_pref_dict->GetBoolean(kSupportsSpdyKey, &supports_spdy)) && |
| 529 supports_spdy) { | 566 supports_spdy) { |
| 530 spdy_servers->push_back(server_str); | 567 spdy_servers->push_back(server_str); |
| 531 } | 568 } |
| 532 | 569 |
| 533 AddToSpdySettingsMap(server, *server_pref_dict, spdy_settings_map); | 570 AddToSpdySettingsMap(server, *server_pref_dict, spdy_settings_map); |
| 534 if (!AddToAlternativeServiceMap(server, *server_pref_dict, | 571 if (!AddToAlternativeServiceMap(server, *server_pref_dict, |
| 535 alternative_service_map) || | 572 alternative_service_map) || |
| 536 !AddToNetworkStatsMap(server, *server_pref_dict, network_stats_map)) { | 573 !AddToNetworkStatsMap(server, *server_pref_dict, network_stats_map)) { |
| 537 return false; | 574 return false; |
| 538 } | 575 } |
| 539 } | 576 } |
| 540 return true; | 577 return true; |
| 541 } | 578 } |
| 542 | 579 |
| 543 void HttpServerPropertiesManager::AddToSpdySettingsMap( | 580 void HttpServerPropertiesManager::AddToSpdySettingsMap( |
| 544 const HostPortPair& server, | 581 const HostPortPair& server, |
| 545 const base::DictionaryValue& server_pref_dict, | 582 const base::DictionaryValue& server_pref_dict, |
| 546 SpdySettingsMap* spdy_settings_map) { | 583 SpdySettingsMap* spdy_settings_map) { |
| 547 // Get SpdySettings. | 584 // Get SpdySettings. |
| 548 DCHECK(spdy_settings_map->Peek(server) == spdy_settings_map->end()); | 585 DCHECK(spdy_settings_map->Peek(server) == spdy_settings_map->end()); |
| 549 const base::DictionaryValue* spdy_settings_dict = NULL; | 586 const base::DictionaryValue* spdy_settings_dict = nullptr; |
| 550 if (!server_pref_dict.GetDictionaryWithoutPathExpansion( | 587 if (!server_pref_dict.GetDictionaryWithoutPathExpansion( |
| 551 kSettingsKey, &spdy_settings_dict)) { | 588 kSettingsKey, &spdy_settings_dict)) { |
| 552 return; | 589 return; |
| 553 } | 590 } |
| 554 SettingsMap settings_map; | 591 SettingsMap settings_map; |
| 555 for (base::DictionaryValue::Iterator dict_it(*spdy_settings_dict); | 592 for (base::DictionaryValue::Iterator dict_it(*spdy_settings_dict); |
| 556 !dict_it.IsAtEnd(); dict_it.Advance()) { | 593 !dict_it.IsAtEnd(); dict_it.Advance()) { |
| 557 const std::string& id_str = dict_it.key(); | 594 const std::string& id_str = dict_it.key(); |
| 558 int id = 0; | 595 int id = 0; |
| 559 if (!base::StringToInt(id_str, &id)) { | 596 if (!base::StringToInt(id_str, &id)) { |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 686 return false; | 723 return false; |
| 687 } | 724 } |
| 688 | 725 |
| 689 alternative_service_map->Put(server, alternative_service_info_vector); | 726 alternative_service_map->Put(server, alternative_service_info_vector); |
| 690 return true; | 727 return true; |
| 691 } | 728 } |
| 692 | 729 |
| 693 bool HttpServerPropertiesManager::ReadSupportsQuic( | 730 bool HttpServerPropertiesManager::ReadSupportsQuic( |
| 694 const base::DictionaryValue& http_server_properties_dict, | 731 const base::DictionaryValue& http_server_properties_dict, |
| 695 IPAddressNumber* last_quic_address) { | 732 IPAddressNumber* last_quic_address) { |
| 696 const base::DictionaryValue* supports_quic_dict = NULL; | 733 const base::DictionaryValue* supports_quic_dict = nullptr; |
| 697 if (!http_server_properties_dict.GetDictionaryWithoutPathExpansion( | 734 if (!http_server_properties_dict.GetDictionaryWithoutPathExpansion( |
| 698 kSupportsQuicKey, &supports_quic_dict)) { | 735 kSupportsQuicKey, &supports_quic_dict)) { |
| 699 return true; | 736 return true; |
| 700 } | 737 } |
| 701 bool used_quic = false; | 738 bool used_quic = false; |
| 702 if (!supports_quic_dict->GetBooleanWithoutPathExpansion(kUsedQuicKey, | 739 if (!supports_quic_dict->GetBooleanWithoutPathExpansion(kUsedQuicKey, |
| 703 &used_quic)) { | 740 &used_quic)) { |
| 704 DVLOG(1) << "Malformed SupportsQuic"; | 741 DVLOG(1) << "Malformed SupportsQuic"; |
| 705 return false; | 742 return false; |
| 706 } | 743 } |
| 707 if (!used_quic) | 744 if (!used_quic) |
| 708 return false; | 745 return false; |
| 709 | 746 |
| 710 std::string address; | 747 std::string address; |
| 711 if (!supports_quic_dict->GetStringWithoutPathExpansion(kAddressKey, | 748 if (!supports_quic_dict->GetStringWithoutPathExpansion(kAddressKey, |
| 712 &address) || | 749 &address) || |
| 713 !ParseIPLiteralToNumber(address, last_quic_address)) { | 750 !ParseIPLiteralToNumber(address, last_quic_address)) { |
| 714 DVLOG(1) << "Malformed SupportsQuic"; | 751 DVLOG(1) << "Malformed SupportsQuic"; |
| 715 return false; | 752 return false; |
| 716 } | 753 } |
| 717 return true; | 754 return true; |
| 718 } | 755 } |
| 719 | 756 |
| 720 bool HttpServerPropertiesManager::AddToNetworkStatsMap( | 757 bool HttpServerPropertiesManager::AddToNetworkStatsMap( |
| 721 const HostPortPair& server, | 758 const HostPortPair& server, |
| 722 const base::DictionaryValue& server_pref_dict, | 759 const base::DictionaryValue& server_pref_dict, |
| 723 ServerNetworkStatsMap* network_stats_map) { | 760 ServerNetworkStatsMap* network_stats_map) { |
| 724 DCHECK(network_stats_map->Peek(server) == network_stats_map->end()); | 761 DCHECK(network_stats_map->Peek(server) == network_stats_map->end()); |
| 725 const base::DictionaryValue* server_network_stats_dict = NULL; | 762 const base::DictionaryValue* server_network_stats_dict = nullptr; |
| 726 if (!server_pref_dict.GetDictionaryWithoutPathExpansion( | 763 if (!server_pref_dict.GetDictionaryWithoutPathExpansion( |
| 727 kNetworkStatsKey, &server_network_stats_dict)) { | 764 kNetworkStatsKey, &server_network_stats_dict)) { |
| 728 return true; | 765 return true; |
| 729 } | 766 } |
| 730 int srtt; | 767 int srtt; |
| 731 if (!server_network_stats_dict->GetIntegerWithoutPathExpansion(kSrttKey, | 768 if (!server_network_stats_dict->GetIntegerWithoutPathExpansion(kSrttKey, |
| 732 &srtt)) { | 769 &srtt)) { |
| 733 DVLOG(1) << "Malformed ServerNetworkStats for server: " | 770 DVLOG(1) << "Malformed ServerNetworkStats for server: " |
| 734 << server.ToString(); | 771 << server.ToString(); |
| 735 return false; | 772 return false; |
| 736 } | 773 } |
| 737 ServerNetworkStats server_network_stats; | 774 ServerNetworkStats server_network_stats; |
| 738 server_network_stats.srtt = base::TimeDelta::FromInternalValue(srtt); | 775 server_network_stats.srtt = base::TimeDelta::FromInternalValue(srtt); |
| 739 // TODO(rtenneti): When QUIC starts using bandwidth_estimate, then persist | 776 // TODO(rtenneti): When QUIC starts using bandwidth_estimate, then persist |
| 740 // bandwidth_estimate. | 777 // bandwidth_estimate. |
| 741 network_stats_map->Put(server, server_network_stats); | 778 network_stats_map->Put(server, server_network_stats); |
| 742 return true; | 779 return true; |
| 743 } | 780 } |
| 744 | 781 |
| 745 bool HttpServerPropertiesManager::AddToQuicServerInfoMap( | 782 bool HttpServerPropertiesManager::AddToQuicServerInfoMap( |
| 746 const base::DictionaryValue& http_server_properties_dict, | 783 const base::DictionaryValue& http_server_properties_dict, |
| 747 QuicServerInfoMap* quic_server_info_map) { | 784 QuicServerInfoMap* quic_server_info_map) { |
| 748 const base::DictionaryValue* quic_servers_dict = NULL; | 785 const base::DictionaryValue* quic_servers_dict = nullptr; |
| 749 if (!http_server_properties_dict.GetDictionaryWithoutPathExpansion( | 786 if (!http_server_properties_dict.GetDictionaryWithoutPathExpansion( |
| 750 kQuicServers, &quic_servers_dict)) { | 787 kQuicServers, &quic_servers_dict)) { |
| 751 DVLOG(1) << "Malformed http_server_properties for quic_servers."; | 788 DVLOG(1) << "Malformed http_server_properties for quic_servers."; |
| 752 return true; | 789 return true; |
| 753 } | 790 } |
| 754 | 791 |
| 755 bool detected_corrupted_prefs = false; | 792 bool detected_corrupted_prefs = false; |
| 756 for (base::DictionaryValue::Iterator it(*quic_servers_dict); !it.IsAtEnd(); | 793 for (base::DictionaryValue::Iterator it(*quic_servers_dict); !it.IsAtEnd(); |
| 757 it.Advance()) { | 794 it.Advance()) { |
| 758 // Get quic_server_id. | 795 // Get quic_server_id. |
| 759 const std::string& quic_server_id_str = it.key(); | 796 const std::string& quic_server_id_str = it.key(); |
| 760 QuicServerId quic_server_id = QuicServerId::FromString(quic_server_id_str); | 797 QuicServerId quic_server_id = QuicServerId::FromString(quic_server_id_str); |
| 761 if (quic_server_id.host().empty()) { | 798 if (quic_server_id.host().empty()) { |
| 762 DVLOG(1) << "Malformed http_server_properties for quic server: " | 799 DVLOG(1) << "Malformed http_server_properties for quic server: " |
| 763 << quic_server_id_str; | 800 << quic_server_id_str; |
| 764 detected_corrupted_prefs = true; | 801 detected_corrupted_prefs = true; |
| 765 continue; | 802 continue; |
| 766 } | 803 } |
| 767 | 804 |
| 768 const base::DictionaryValue* quic_server_pref_dict = NULL; | 805 const base::DictionaryValue* quic_server_pref_dict = nullptr; |
| 769 if (!it.value().GetAsDictionary(&quic_server_pref_dict)) { | 806 if (!it.value().GetAsDictionary(&quic_server_pref_dict)) { |
| 770 DVLOG(1) << "Malformed http_server_properties quic server dict: " | 807 DVLOG(1) << "Malformed http_server_properties quic server dict: " |
| 771 << quic_server_id_str; | 808 << quic_server_id_str; |
| 772 detected_corrupted_prefs = true; | 809 detected_corrupted_prefs = true; |
| 773 continue; | 810 continue; |
| 774 } | 811 } |
| 775 | 812 |
| 776 std::string quic_server_info; | 813 std::string quic_server_info; |
| 777 if (!quic_server_pref_dict->GetStringWithoutPathExpansion( | 814 if (!quic_server_pref_dict->GetStringWithoutPathExpansion( |
| 778 kServerInfoKey, &quic_server_info)) { | 815 kServerInfoKey, &quic_server_info)) { |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 854 | 891 |
| 855 // This is required so we can set this as the callback for a timer. | 892 // This is required so we can set this as the callback for a timer. |
| 856 void HttpServerPropertiesManager::UpdatePrefsFromCacheOnNetworkThread() { | 893 void HttpServerPropertiesManager::UpdatePrefsFromCacheOnNetworkThread() { |
| 857 UpdatePrefsFromCacheOnNetworkThread(base::Closure()); | 894 UpdatePrefsFromCacheOnNetworkThread(base::Closure()); |
| 858 } | 895 } |
| 859 | 896 |
| 860 void HttpServerPropertiesManager::UpdatePrefsFromCacheOnNetworkThread( | 897 void HttpServerPropertiesManager::UpdatePrefsFromCacheOnNetworkThread( |
| 861 const base::Closure& completion) { | 898 const base::Closure& completion) { |
| 862 DCHECK(network_task_runner_->RunsTasksOnCurrentThread()); | 899 DCHECK(network_task_runner_->RunsTasksOnCurrentThread()); |
| 863 | 900 |
| 901 // It is in MRU order. |
| 864 base::ListValue* spdy_server_list = new base::ListValue; | 902 base::ListValue* spdy_server_list = new base::ListValue; |
| 865 http_server_properties_impl_->GetSpdyServerList( | 903 http_server_properties_impl_->GetSpdyServerList( |
| 866 spdy_server_list, kMaxSupportsSpdyServerHostsToPersist); | 904 spdy_server_list, kMaxSupportsSpdyServerHostsToPersist); |
| 867 | 905 |
| 868 SpdySettingsMap* spdy_settings_map = | 906 SpdySettingsMap* spdy_settings_map = |
| 869 new SpdySettingsMap(kMaxSpdySettingsHostsToPersist); | 907 new SpdySettingsMap(kMaxSpdySettingsHostsToPersist); |
| 870 const SpdySettingsMap& main_map = | 908 const SpdySettingsMap& main_map = |
| 871 http_server_properties_impl_->spdy_settings_map(); | 909 http_server_properties_impl_->spdy_settings_map(); |
| 872 int count = 0; | 910 int count = 0; |
| 873 for (SpdySettingsMap::const_iterator it = main_map.begin(); | 911 // Maintain MRU order. |
| 874 it != main_map.end() && count < kMaxSpdySettingsHostsToPersist; | 912 for (SpdySettingsMap::const_reverse_iterator it = main_map.rbegin(); |
| 913 it != main_map.rend() && count < kMaxSpdySettingsHostsToPersist; |
| 875 ++it, ++count) { | 914 ++it, ++count) { |
| 876 spdy_settings_map->Put(it->first, it->second); | 915 spdy_settings_map->Put(it->first, it->second); |
| 877 } | 916 } |
| 878 | 917 |
| 879 AlternativeServiceMap* alternative_service_map = | 918 AlternativeServiceMap* alternative_service_map = |
| 880 new AlternativeServiceMap(kMaxAlternateProtocolHostsToPersist); | 919 new AlternativeServiceMap(kMaxAlternateProtocolHostsToPersist); |
| 881 const AlternativeServiceMap& map = | 920 const AlternativeServiceMap& map = |
| 882 http_server_properties_impl_->alternative_service_map(); | 921 http_server_properties_impl_->alternative_service_map(); |
| 883 UMA_HISTOGRAM_COUNTS("Net.CountOfAlternateProtocolServers.Memory", | 922 UMA_HISTOGRAM_COUNTS("Net.CountOfAlternateProtocolServers.Memory", |
| 884 map.size()); | 923 map.size()); |
| 885 count = 0; | 924 count = 0; |
| 886 typedef std::map<std::string, bool> CanonicalHostPersistedMap; | 925 typedef std::map<std::string, bool> CanonicalHostPersistedMap; |
| 887 CanonicalHostPersistedMap persisted_map; | 926 CanonicalHostPersistedMap persisted_map; |
| 888 for (AlternativeServiceMap::const_iterator it = map.begin(); | 927 // Maintain MRU order. |
| 889 it != map.end() && count < kMaxAlternateProtocolHostsToPersist; ++it) { | 928 for (AlternativeServiceMap::const_reverse_iterator it = map.rbegin(); |
| 929 it != map.rend() && count < kMaxAlternateProtocolHostsToPersist; ++it) { |
| 890 const HostPortPair& server = it->first; | 930 const HostPortPair& server = it->first; |
| 891 AlternativeServiceInfoVector notbroken_alternative_service_info_vector; | 931 AlternativeServiceInfoVector notbroken_alternative_service_info_vector; |
| 892 for (const AlternativeServiceInfo& alternative_service_info : it->second) { | 932 for (const AlternativeServiceInfo& alternative_service_info : it->second) { |
| 893 // Do not persist expired entries. | 933 // Do not persist expired entries. |
| 894 if (alternative_service_info.expiration < base::Time::Now()) { | 934 if (alternative_service_info.expiration < base::Time::Now()) { |
| 895 continue; | 935 continue; |
| 896 } | 936 } |
| 897 AlternativeService alternative_service( | 937 AlternativeService alternative_service( |
| 898 alternative_service_info.alternative_service); | 938 alternative_service_info.alternative_service); |
| 899 if (!IsAlternateProtocolValid(alternative_service.protocol)) { | 939 if (!IsAlternateProtocolValid(alternative_service.protocol)) { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 921 alternative_service_map->Put(server, | 961 alternative_service_map->Put(server, |
| 922 notbroken_alternative_service_info_vector); | 962 notbroken_alternative_service_info_vector); |
| 923 ++count; | 963 ++count; |
| 924 } | 964 } |
| 925 | 965 |
| 926 ServerNetworkStatsMap* server_network_stats_map = | 966 ServerNetworkStatsMap* server_network_stats_map = |
| 927 new ServerNetworkStatsMap(kMaxServerNetworkStatsHostsToPersist); | 967 new ServerNetworkStatsMap(kMaxServerNetworkStatsHostsToPersist); |
| 928 const ServerNetworkStatsMap& network_stats_map = | 968 const ServerNetworkStatsMap& network_stats_map = |
| 929 http_server_properties_impl_->server_network_stats_map(); | 969 http_server_properties_impl_->server_network_stats_map(); |
| 930 count = 0; | 970 count = 0; |
| 931 for (ServerNetworkStatsMap::const_iterator it = network_stats_map.begin(); | 971 for (ServerNetworkStatsMap::const_reverse_iterator |
| 932 it != network_stats_map.end() && | 972 it = network_stats_map.rbegin(); |
| 973 it != network_stats_map.rend() && |
| 933 count < kMaxServerNetworkStatsHostsToPersist; | 974 count < kMaxServerNetworkStatsHostsToPersist; |
| 934 ++it, ++count) { | 975 ++it, ++count) { |
| 935 server_network_stats_map->Put(it->first, it->second); | 976 server_network_stats_map->Put(it->first, it->second); |
| 936 } | 977 } |
| 937 | 978 |
| 938 QuicServerInfoMap* quic_server_info_map = NULL; | 979 QuicServerInfoMap* quic_server_info_map = nullptr; |
| 939 const QuicServerInfoMap& main_quic_server_info_map = | 980 const QuicServerInfoMap& main_quic_server_info_map = |
| 940 http_server_properties_impl_->quic_server_info_map(); | 981 http_server_properties_impl_->quic_server_info_map(); |
| 941 if (main_quic_server_info_map.size() > 0) { | 982 if (main_quic_server_info_map.size() > 0) { |
| 942 quic_server_info_map = new QuicServerInfoMap(kMaxQuicServersToPersist); | 983 quic_server_info_map = new QuicServerInfoMap(kMaxQuicServersToPersist); |
| 943 for (const std::pair<const QuicServerId, std::string>& entry : | 984 for (const std::pair<const QuicServerId, std::string>& entry : |
| 944 main_quic_server_info_map) { | 985 main_quic_server_info_map) { |
| 945 quic_server_info_map->Put(entry.first, entry.second); | 986 quic_server_info_map->Put(entry.first, entry.second); |
| 946 } | 987 } |
| 947 } | 988 } |
| 948 | 989 |
| 949 IPAddressNumber* last_quic_addr = new IPAddressNumber; | 990 IPAddressNumber* last_quic_addr = new IPAddressNumber; |
| 950 http_server_properties_impl_->GetSupportsQuic(last_quic_addr); | 991 http_server_properties_impl_->GetSupportsQuic(last_quic_addr); |
| 951 // Update the preferences on the pref thread. | 992 // Update the preferences on the pref thread. |
| 952 pref_task_runner_->PostTask( | 993 pref_task_runner_->PostTask( |
| 953 FROM_HERE, | 994 FROM_HERE, |
| 954 base::Bind( | 995 base::Bind( |
| 955 &HttpServerPropertiesManager::UpdatePrefsOnPrefThread, pref_weak_ptr_, | 996 &HttpServerPropertiesManager::UpdatePrefsOnPrefThread, pref_weak_ptr_, |
| 956 base::Owned(spdy_server_list), base::Owned(spdy_settings_map), | 997 base::Owned(spdy_server_list), base::Owned(spdy_settings_map), |
| 957 base::Owned(alternative_service_map), base::Owned(last_quic_addr), | 998 base::Owned(alternative_service_map), base::Owned(last_quic_addr), |
| 958 base::Owned(server_network_stats_map), | 999 base::Owned(server_network_stats_map), |
| 959 base::Owned(quic_server_info_map), completion)); | 1000 base::Owned(quic_server_info_map), completion)); |
| 960 } | 1001 } |
| 961 | 1002 |
| 962 // A local or temporary data structure to hold |supports_spdy|, SpdySettings, | 1003 // A local or temporary data structure to hold |supports_spdy|, SpdySettings, |
| 963 // AlternativeServiceInfoVector, and SupportsQuic preferences for a server. This | 1004 // AlternativeServiceInfoVector, and SupportsQuic preferences for a server. This |
| 964 // is used only in UpdatePrefsOnPrefThread. | 1005 // is used only in UpdatePrefsOnPrefThread. |
| 965 struct ServerPref { | 1006 struct ServerPref { |
| 966 ServerPref() | 1007 ServerPref() |
| 967 : supports_spdy(false), | 1008 : supports_spdy(false), |
| 968 settings_map(NULL), | 1009 settings_map(nullptr), |
| 969 alternative_service_info_vector(NULL), | 1010 alternative_service_info_vector(nullptr), |
| 970 supports_quic(NULL), | 1011 supports_quic(nullptr), |
| 971 server_network_stats(NULL) {} | 1012 server_network_stats(nullptr) {} |
| 972 ServerPref( | 1013 ServerPref( |
| 973 bool supports_spdy, | 1014 bool supports_spdy, |
| 974 const SettingsMap* settings_map, | 1015 const SettingsMap* settings_map, |
| 975 const AlternativeServiceInfoVector* alternative_service_info_vector, | 1016 const AlternativeServiceInfoVector* alternative_service_info_vector, |
| 976 const SupportsQuic* supports_quic, | 1017 const SupportsQuic* supports_quic, |
| 977 const ServerNetworkStats* server_network_stats) | 1018 const ServerNetworkStats* server_network_stats) |
| 978 : supports_spdy(supports_spdy), | 1019 : supports_spdy(supports_spdy), |
| 979 settings_map(settings_map), | 1020 settings_map(settings_map), |
| 980 alternative_service_info_vector(alternative_service_info_vector), | 1021 alternative_service_info_vector(alternative_service_info_vector), |
| 981 supports_quic(supports_quic), | 1022 supports_quic(supports_quic), |
| 982 server_network_stats(server_network_stats) {} | 1023 server_network_stats(server_network_stats) {} |
| 983 bool supports_spdy; | 1024 bool supports_spdy; |
| 984 const SettingsMap* settings_map; | 1025 const SettingsMap* settings_map; |
| 985 const AlternativeServiceInfoVector* alternative_service_info_vector; | 1026 const AlternativeServiceInfoVector* alternative_service_info_vector; |
| 986 const SupportsQuic* supports_quic; | 1027 const SupportsQuic* supports_quic; |
| 987 const ServerNetworkStats* server_network_stats; | 1028 const ServerNetworkStats* server_network_stats; |
| 988 }; | 1029 }; |
| 989 | 1030 |
| 1031 // All maps and lists are in MRU order. |
| 990 void HttpServerPropertiesManager::UpdatePrefsOnPrefThread( | 1032 void HttpServerPropertiesManager::UpdatePrefsOnPrefThread( |
| 991 base::ListValue* spdy_server_list, | 1033 base::ListValue* spdy_server_list, |
| 992 SpdySettingsMap* spdy_settings_map, | 1034 SpdySettingsMap* spdy_settings_map, |
| 993 AlternativeServiceMap* alternative_service_map, | 1035 AlternativeServiceMap* alternative_service_map, |
| 994 IPAddressNumber* last_quic_address, | 1036 IPAddressNumber* last_quic_address, |
| 995 ServerNetworkStatsMap* server_network_stats_map, | 1037 ServerNetworkStatsMap* server_network_stats_map, |
| 996 QuicServerInfoMap* quic_server_info_map, | 1038 QuicServerInfoMap* quic_server_info_map, |
| 997 const base::Closure& completion) { | 1039 const base::Closure& completion) { |
| 998 typedef std::map<HostPortPair, ServerPref> ServerPrefMap; | 1040 typedef base::MRUCache<HostPortPair, ServerPref> ServerPrefMap; |
| 999 ServerPrefMap server_pref_map; | 1041 ServerPrefMap server_pref_map(ServerPrefMap::NO_AUTO_EVICT); |
| 1000 | 1042 |
| 1001 DCHECK(pref_task_runner_->RunsTasksOnCurrentThread()); | 1043 DCHECK(pref_task_runner_->RunsTasksOnCurrentThread()); |
| 1002 | 1044 |
| 1003 // Add servers that support spdy to server_pref_map. | 1045 // Add servers that support spdy to server_pref_map in the MRU order. |
| 1004 std::string s; | 1046 for (size_t index = spdy_server_list->GetSize(); index > 0; --index) { |
| 1005 for (base::ListValue::const_iterator list_it = spdy_server_list->begin(); | 1047 std::string s; |
| 1006 list_it != spdy_server_list->end(); | 1048 if (spdy_server_list->GetString(index - 1, &s)) { |
| 1007 ++list_it) { | |
| 1008 if ((*list_it)->GetAsString(&s)) { | |
| 1009 HostPortPair server = HostPortPair::FromString(s); | 1049 HostPortPair server = HostPortPair::FromString(s); |
| 1010 server_pref_map[server].supports_spdy = true; | 1050 ServerPrefMap::iterator it = server_pref_map.Get(server); |
| 1051 if (it == server_pref_map.end()) { |
| 1052 ServerPref server_pref; |
| 1053 server_pref.supports_spdy = true; |
| 1054 server_pref_map.Put(server, server_pref); |
| 1055 } else { |
| 1056 it->second.supports_spdy = true; |
| 1057 } |
| 1011 } | 1058 } |
| 1012 } | 1059 } |
| 1013 | 1060 |
| 1014 // Add servers that have SpdySettings to server_pref_map. | 1061 // Add servers that have SpdySettings to server_pref_map in the MRU order. |
| 1015 for (SpdySettingsMap::iterator map_it = spdy_settings_map->begin(); | 1062 for (SpdySettingsMap::reverse_iterator map_it = spdy_settings_map->rbegin(); |
| 1016 map_it != spdy_settings_map->end(); ++map_it) { | 1063 map_it != spdy_settings_map->rend(); ++map_it) { |
| 1017 const HostPortPair& server = map_it->first; | 1064 const HostPortPair& server = map_it->first; |
| 1018 server_pref_map[server].settings_map = &map_it->second; | 1065 ServerPrefMap::iterator it = server_pref_map.Get(server); |
| 1066 if (it == server_pref_map.end()) { |
| 1067 ServerPref server_pref; |
| 1068 server_pref.settings_map = &map_it->second; |
| 1069 server_pref_map.Put(server, server_pref); |
| 1070 } else { |
| 1071 it->second.settings_map = &map_it->second; |
| 1072 } |
| 1019 } | 1073 } |
| 1020 | 1074 |
| 1021 // Add alternative services to server_pref_map. | 1075 // Add alternative services to server_pref_map in the MRU order. |
| 1022 for (AlternativeServiceMap::const_iterator map_it = | 1076 for (AlternativeServiceMap::const_reverse_iterator map_it = |
| 1023 alternative_service_map->begin(); | 1077 alternative_service_map->rbegin(); |
| 1024 map_it != alternative_service_map->end(); ++map_it) { | 1078 map_it != alternative_service_map->rend(); ++map_it) { |
| 1025 server_pref_map[map_it->first].alternative_service_info_vector = | 1079 const HostPortPair& server = map_it->first; |
| 1026 &map_it->second; | 1080 ServerPrefMap::iterator it = server_pref_map.Get(server); |
| 1081 if (it == server_pref_map.end()) { |
| 1082 ServerPref server_pref; |
| 1083 server_pref.alternative_service_info_vector = &map_it->second; |
| 1084 server_pref_map.Put(server, server_pref); |
| 1085 } else { |
| 1086 it->second.alternative_service_info_vector = &map_it->second; |
| 1087 } |
| 1027 } | 1088 } |
| 1028 | 1089 |
| 1029 // Add ServerNetworkStats servers to server_pref_map. | 1090 // Add ServerNetworkStats servers to server_pref_map in the MRU order. |
| 1030 for (ServerNetworkStatsMap::const_iterator map_it = | 1091 for (ServerNetworkStatsMap::const_reverse_iterator map_it = |
| 1031 server_network_stats_map->begin(); | 1092 server_network_stats_map->rbegin(); |
| 1032 map_it != server_network_stats_map->end(); ++map_it) { | 1093 map_it != server_network_stats_map->rend(); ++map_it) { |
| 1033 const HostPortPair& server = map_it->first; | 1094 const HostPortPair& server = map_it->first; |
| 1034 server_pref_map[server].server_network_stats = &map_it->second; | 1095 ServerPrefMap::iterator it = server_pref_map.Get(server); |
| 1096 if (it == server_pref_map.end()) { |
| 1097 ServerPref server_pref; |
| 1098 server_pref.server_network_stats = &map_it->second; |
| 1099 server_pref_map.Put(server, server_pref); |
| 1100 } else { |
| 1101 it->second.server_network_stats = &map_it->second; |
| 1102 } |
| 1035 } | 1103 } |
| 1036 | 1104 |
| 1037 // Persist properties to the |path_|. | 1105 // Persist properties to the |path_| in the MRU order. |
| 1038 base::DictionaryValue http_server_properties_dict; | 1106 base::DictionaryValue http_server_properties_dict; |
| 1039 base::DictionaryValue* servers_dict = new base::DictionaryValue; | 1107 base::ListValue* servers_list = new base::ListValue; |
| 1040 for (ServerPrefMap::const_iterator map_it = server_pref_map.begin(); | 1108 for (ServerPrefMap::const_reverse_iterator map_it = server_pref_map.rbegin(); |
| 1041 map_it != server_pref_map.end(); | 1109 map_it != server_pref_map.rend(); ++map_it) { |
| 1042 ++map_it) { | |
| 1043 const HostPortPair& server = map_it->first; | 1110 const HostPortPair& server = map_it->first; |
| 1044 const ServerPref& server_pref = map_it->second; | 1111 const ServerPref& server_pref = map_it->second; |
| 1045 | 1112 |
| 1113 base::DictionaryValue* servers_dict = new base::DictionaryValue; |
| 1046 base::DictionaryValue* server_pref_dict = new base::DictionaryValue; | 1114 base::DictionaryValue* server_pref_dict = new base::DictionaryValue; |
| 1047 | 1115 |
| 1048 // Save supports_spdy. | 1116 // Save supports_spdy. |
| 1049 if (server_pref.supports_spdy) | 1117 if (server_pref.supports_spdy) |
| 1050 server_pref_dict->SetBoolean(kSupportsSpdyKey, server_pref.supports_spdy); | 1118 server_pref_dict->SetBoolean(kSupportsSpdyKey, server_pref.supports_spdy); |
| 1051 SaveSpdySettingsToServerPrefs(server_pref.settings_map, server_pref_dict); | 1119 SaveSpdySettingsToServerPrefs(server_pref.settings_map, server_pref_dict); |
| 1052 SaveAlternativeServiceToServerPrefs( | 1120 SaveAlternativeServiceToServerPrefs( |
| 1053 server_pref.alternative_service_info_vector, server_pref_dict); | 1121 server_pref.alternative_service_info_vector, server_pref_dict); |
| 1054 SaveNetworkStatsToServerPrefs(server_pref.server_network_stats, | 1122 SaveNetworkStatsToServerPrefs(server_pref.server_network_stats, |
| 1055 server_pref_dict); | 1123 server_pref_dict); |
| 1056 | 1124 |
| 1057 servers_dict->SetWithoutPathExpansion(server.ToString(), server_pref_dict); | 1125 servers_dict->SetWithoutPathExpansion(server.ToString(), server_pref_dict); |
| 1126 bool value = servers_list->AppendIfNotPresent(servers_dict); |
| 1127 DCHECK(value); // Should never happen. |
| 1058 } | 1128 } |
| 1059 | 1129 |
| 1060 http_server_properties_dict.SetWithoutPathExpansion(kServersKey, | 1130 http_server_properties_dict.SetWithoutPathExpansion(kServersKey, |
| 1061 servers_dict); | 1131 servers_list); |
| 1062 SetVersion(&http_server_properties_dict, kVersionNumber); | 1132 SetVersion(&http_server_properties_dict, kVersionNumber); |
| 1063 | 1133 |
| 1064 SaveSupportsQuicToPrefs(last_quic_address, &http_server_properties_dict); | 1134 SaveSupportsQuicToPrefs(last_quic_address, &http_server_properties_dict); |
| 1065 | 1135 |
| 1066 SaveQuicServerInfoMapToServerPrefs(quic_server_info_map, | 1136 SaveQuicServerInfoMapToServerPrefs(quic_server_info_map, |
| 1067 &http_server_properties_dict); | 1137 &http_server_properties_dict); |
| 1068 | 1138 |
| 1069 setting_prefs_ = true; | 1139 setting_prefs_ = true; |
| 1070 pref_service_->Set(path_, http_server_properties_dict); | 1140 pref_service_->Set(path_, http_server_properties_dict); |
| 1071 setting_prefs_ = false; | 1141 setting_prefs_ = false; |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1180 quic_servers_dict); | 1250 quic_servers_dict); |
| 1181 } | 1251 } |
| 1182 | 1252 |
| 1183 void HttpServerPropertiesManager::OnHttpServerPropertiesChanged() { | 1253 void HttpServerPropertiesManager::OnHttpServerPropertiesChanged() { |
| 1184 DCHECK(pref_task_runner_->RunsTasksOnCurrentThread()); | 1254 DCHECK(pref_task_runner_->RunsTasksOnCurrentThread()); |
| 1185 if (!setting_prefs_) | 1255 if (!setting_prefs_) |
| 1186 ScheduleUpdateCacheOnPrefThread(); | 1256 ScheduleUpdateCacheOnPrefThread(); |
| 1187 } | 1257 } |
| 1188 | 1258 |
| 1189 } // namespace net | 1259 } // namespace net |
| OLD | NEW |