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

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

Issue 2932953002: Persist broken and recently-broken alt-svcs to prefs in HttpServerPropertiesManager (Closed)
Patch Set: Fixed rch's comments from PS14 Created 3 years, 5 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 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 <utility> 7 #include <utility>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/memory/ptr_util.h" 10 #include "base/memory/ptr_util.h"
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 42
43 // Persist 200 MRU AlternateProtocolHostPortPairs. 43 // Persist 200 MRU AlternateProtocolHostPortPairs.
44 const int kMaxAlternateProtocolHostsToPersist = 200; 44 const int kMaxAlternateProtocolHostsToPersist = 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
49 // Persist 200 ServerNetworkStats. 49 // Persist 200 ServerNetworkStats.
50 const int kMaxServerNetworkStatsHostsToPersist = 200; 50 const int kMaxServerNetworkStatsHostsToPersist = 200;
51 51
52 // TODO (wangyix): update values for how many broken alt svcs to persist after
53 // looking at histograms showing how many are persisted in the real world.
54
55 const int kMaxBrokenAlternativeServicesToPersist =
56 std::numeric_limits<int>::max();
57
58 const int kMaxRecentlyBrokenAlternativeServicesToPersist =
59 std::numeric_limits<int>::max();
60
52 const char kVersionKey[] = "version"; 61 const char kVersionKey[] = "version";
53 const char kServersKey[] = "servers"; 62 const char kServersKey[] = "servers";
54 const char kSupportsSpdyKey[] = "supports_spdy"; 63 const char kSupportsSpdyKey[] = "supports_spdy";
55 const char kSupportsQuicKey[] = "supports_quic"; 64 const char kSupportsQuicKey[] = "supports_quic";
56 const char kQuicServers[] = "quic_servers"; 65 const char kQuicServers[] = "quic_servers";
57 const char kServerInfoKey[] = "server_info"; 66 const char kServerInfoKey[] = "server_info";
58 const char kUsedQuicKey[] = "used_quic"; 67 const char kUsedQuicKey[] = "used_quic";
59 const char kAddressKey[] = "address"; 68 const char kAddressKey[] = "address";
60 const char kAlternativeServiceKey[] = "alternative_service"; 69 const char kAlternativeServiceKey[] = "alternative_service";
61 const char kProtocolKey[] = "protocol_str"; 70 const char kProtocolKey[] = "protocol_str";
62 const char kHostKey[] = "host"; 71 const char kHostKey[] = "host";
63 const char kPortKey[] = "port"; 72 const char kPortKey[] = "port";
64 const char kExpirationKey[] = "expiration"; 73 const char kExpirationKey[] = "expiration";
65 const char kNetworkStatsKey[] = "network_stats"; 74 const char kNetworkStatsKey[] = "network_stats";
66 const char kSrttKey[] = "srtt"; 75 const char kSrttKey[] = "srtt";
76 const char kBrokenAlternativeServicesKey[] = "broken_alternative_services";
77 const char kBrokenUntilKey[] = "broken_until";
78 const char kBrokenCountKey[] = "broken_count";
79
80 void AddAlternativeServiceFieldsToDictionaryValue(
81 const AlternativeService& alternative_service,
82 base::DictionaryValue* dict) {
83 dict->SetInteger(kPortKey, alternative_service.port);
84 if (!alternative_service.host.empty()) {
85 dict->SetString(kHostKey, alternative_service.host);
86 }
87 dict->SetString(kProtocolKey,
88 NextProtoToString(alternative_service.protocol));
89 }
67 90
68 std::unique_ptr<base::Value> NetLogCallback( 91 std::unique_ptr<base::Value> NetLogCallback(
69 const base::DictionaryValue& http_server_properties_dict, 92 const base::DictionaryValue& http_server_properties_dict,
70 NetLogCaptureMode capture_mode) { 93 NetLogCaptureMode capture_mode) {
71 return base::WrapUnique<base::DictionaryValue>( 94 return base::WrapUnique<base::DictionaryValue>(
72 http_server_properties_dict.DeepCopy()); 95 http_server_properties_dict.DeepCopy());
73 } 96 }
74 97
75 } // namespace 98 } // namespace
76 99
77 //////////////////////////////////////////////////////////////////////////////// 100 ////////////////////////////////////////////////////////////////////////////////
78 // HttpServerPropertiesManager 101 // HttpServerPropertiesManager
79 102
80 HttpServerPropertiesManager::PrefDelegate::~PrefDelegate() {} 103 HttpServerPropertiesManager::PrefDelegate::~PrefDelegate() {}
81 104
82 HttpServerPropertiesManager::HttpServerPropertiesManager( 105 HttpServerPropertiesManager::HttpServerPropertiesManager(
83 PrefDelegate* pref_delegate, 106 PrefDelegate* pref_delegate,
84 scoped_refptr<base::SingleThreadTaskRunner> pref_task_runner, 107 scoped_refptr<base::SingleThreadTaskRunner> pref_task_runner,
85 scoped_refptr<base::SingleThreadTaskRunner> network_task_runner, 108 scoped_refptr<base::SingleThreadTaskRunner> network_task_runner,
86 NetLog* net_log) 109 NetLog* net_log)
110 : HttpServerPropertiesManager(pref_delegate,
111 pref_task_runner,
112 network_task_runner,
113 net_log,
114 nullptr) {}
115
116 HttpServerPropertiesManager::HttpServerPropertiesManager(
117 PrefDelegate* pref_delegate,
118 scoped_refptr<base::SingleThreadTaskRunner> pref_task_runner,
119 scoped_refptr<base::SingleThreadTaskRunner> network_task_runner,
120 NetLog* net_log,
121 base::TickClock* clock)
87 : pref_task_runner_(std::move(pref_task_runner)), 122 : pref_task_runner_(std::move(pref_task_runner)),
88 pref_delegate_(pref_delegate), 123 pref_delegate_(pref_delegate),
89 setting_prefs_(false), 124 setting_prefs_(false),
125 clock_(clock ? clock : &default_clock_),
90 is_initialized_(false), 126 is_initialized_(false),
91 network_task_runner_(std::move(network_task_runner)), 127 network_task_runner_(std::move(network_task_runner)),
92 net_log_( 128 net_log_(
93 NetLogWithSource::Make(net_log, 129 NetLogWithSource::Make(net_log,
94 NetLogSourceType::HTTP_SERVER_PROPERTIES)) { 130 NetLogSourceType::HTTP_SERVER_PROPERTIES)) {
95 DCHECK(pref_task_runner_->RunsTasksInCurrentSequence()); 131 DCHECK(pref_task_runner_->RunsTasksInCurrentSequence());
96 DCHECK(pref_delegate_); 132 DCHECK(pref_delegate_);
133 DCHECK(clock_);
97 pref_weak_ptr_factory_.reset( 134 pref_weak_ptr_factory_.reset(
98 new base::WeakPtrFactory<HttpServerPropertiesManager>(this)); 135 new base::WeakPtrFactory<HttpServerPropertiesManager>(this));
99 pref_weak_ptr_ = pref_weak_ptr_factory_->GetWeakPtr(); 136 pref_weak_ptr_ = pref_weak_ptr_factory_->GetWeakPtr();
100 pref_cache_update_timer_.reset(new base::OneShotTimer); 137 pref_cache_update_timer_.reset(new base::OneShotTimer);
101 pref_cache_update_timer_->SetTaskRunner(pref_task_runner_); 138 pref_cache_update_timer_->SetTaskRunner(pref_task_runner_);
102 pref_delegate_->StartListeningForUpdates( 139 pref_delegate_->StartListeningForUpdates(
103 base::Bind(&HttpServerPropertiesManager::OnHttpServerPropertiesChanged, 140 base::Bind(&HttpServerPropertiesManager::OnHttpServerPropertiesChanged,
104 base::Unretained(this))); 141 base::Unretained(this)));
105 } 142 }
106 143
107 HttpServerPropertiesManager::~HttpServerPropertiesManager() { 144 HttpServerPropertiesManager::~HttpServerPropertiesManager() {
108 DCHECK(network_task_runner_->RunsTasksInCurrentSequence()); 145 DCHECK(network_task_runner_->RunsTasksInCurrentSequence());
109 network_weak_ptr_factory_.reset(); 146 network_weak_ptr_factory_.reset();
110 } 147 }
111 148
112 void HttpServerPropertiesManager::InitializeOnNetworkSequence() { 149 void HttpServerPropertiesManager::InitializeOnNetworkSequence() {
113 DCHECK(network_task_runner_->RunsTasksInCurrentSequence()); 150 DCHECK(network_task_runner_->RunsTasksInCurrentSequence());
114 net_log_.BeginEvent(NetLogEventType::HTTP_SERVER_PROPERTIES_INITIALIZATION); 151 net_log_.BeginEvent(NetLogEventType::HTTP_SERVER_PROPERTIES_INITIALIZATION);
115 152
116 network_weak_ptr_factory_.reset( 153 network_weak_ptr_factory_.reset(
117 new base::WeakPtrFactory<HttpServerPropertiesManager>(this)); 154 new base::WeakPtrFactory<HttpServerPropertiesManager>(this));
118 http_server_properties_impl_.reset(new HttpServerPropertiesImpl()); 155 http_server_properties_impl_.reset(new HttpServerPropertiesImpl(clock_));
119 156
120 network_prefs_update_timer_.reset(new base::OneShotTimer); 157 network_prefs_update_timer_.reset(new base::OneShotTimer);
121 network_prefs_update_timer_->SetTaskRunner(network_task_runner_); 158 network_prefs_update_timer_->SetTaskRunner(network_task_runner_);
122 // UpdateCacheFromPrefsOnPrefSequence() will post a task to network thread to 159 // UpdateCacheFromPrefsOnPrefSequence() will post a task to network thread to
123 // update server properties. SetInitialized() will be run after that task is 160 // update server properties. SetInitialized() will be run after that task is
124 // run as |network_task_runner_| is single threaded. 161 // run as |network_task_runner_| is single threaded.
125 pref_task_runner_->PostTaskAndReply( 162 pref_task_runner_->PostTaskAndReply(
126 FROM_HERE, 163 FROM_HERE,
127 base::Bind( 164 base::Bind(
128 &HttpServerPropertiesManager::UpdateCacheFromPrefsOnPrefSequence, 165 &HttpServerPropertiesManager::UpdateCacheFromPrefsOnPrefSequence,
(...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after
526 detected_corrupted_prefs = true; 563 detected_corrupted_prefs = true;
527 } 564 }
528 } 565 }
529 } 566 }
530 567
531 if (!AddToQuicServerInfoMap(http_server_properties_dict, 568 if (!AddToQuicServerInfoMap(http_server_properties_dict,
532 quic_server_info_map.get())) { 569 quic_server_info_map.get())) {
533 detected_corrupted_prefs = true; 570 detected_corrupted_prefs = true;
534 } 571 }
535 572
573 // Read broken alternnative services list if it exists.
574 std::unique_ptr<BrokenAlternativeServiceList> broken_alternative_service_list;
575 std::unique_ptr<RecentlyBrokenAlternativeServices>
576 recently_broken_alternative_services;
577 const base::ListValue* broken_alt_svc_list;
578 if (http_server_properties_dict.GetListWithoutPathExpansion(
579 kBrokenAlternativeServicesKey, &broken_alt_svc_list)) {
580 broken_alternative_service_list =
581 base::MakeUnique<BrokenAlternativeServiceList>();
582 recently_broken_alternative_services =
583 base::MakeUnique<RecentlyBrokenAlternativeServices>(
584 RecentlyBrokenAlternativeServices::NO_AUTO_EVICT);
585
586 // Iterate list in reverse-MRU order
587 for (base::ListValue::const_iterator it = broken_alt_svc_list->end();
588 it != broken_alt_svc_list->begin();) {
589 --it;
590 const base::DictionaryValue* entry_dict;
591 if (!it->GetAsDictionary(&entry_dict)) {
592 DVLOG(1) << "Malformed broken alterantive service entry.";
593 detected_corrupted_prefs = true;
594 continue;
595 }
596 if (!AddToBrokenAlternativeServices(
597 *entry_dict, broken_alternative_service_list.get(),
598 recently_broken_alternative_services.get())) {
599 detected_corrupted_prefs = true;
600 continue;
601 }
602 }
603 }
604
536 network_task_runner_->PostTask( 605 network_task_runner_->PostTask(
537 FROM_HERE, 606 FROM_HERE,
538 base::Bind( 607 base::Bind(
539 &HttpServerPropertiesManager::UpdateCacheFromPrefsOnNetworkSequence, 608 &HttpServerPropertiesManager::UpdateCacheFromPrefsOnNetworkSequence,
540 base::Unretained(this), base::Passed(&spdy_servers_map), 609 base::Unretained(this), base::Passed(&spdy_servers_map),
541 base::Passed(&alternative_service_map), base::Passed(&addr), 610 base::Passed(&alternative_service_map), base::Passed(&addr),
542 base::Passed(&server_network_stats_map), 611 base::Passed(&server_network_stats_map),
543 base::Passed(&quic_server_info_map), detected_corrupted_prefs)); 612 base::Passed(&quic_server_info_map),
613 base::Passed(&broken_alternative_service_list),
614 base::Passed(&recently_broken_alternative_services),
615 detected_corrupted_prefs));
616 }
617
618 bool HttpServerPropertiesManager::AddToBrokenAlternativeServices(
619 const base::DictionaryValue& broken_alt_svc_entry_dict,
620 BrokenAlternativeServiceList* broken_alternative_service_list,
621 RecentlyBrokenAlternativeServices* recently_broken_alternative_services) {
622 AlternativeService alt_service;
623 if (!ParseAlternativeServiceDict(broken_alt_svc_entry_dict, true,
624 "broken alternative services",
625 &alt_service)) {
626 return false;
627 }
628
629 // Read broken-count and add an entry for |alt_service| into
630 // |recently_broken_alternative_services|.
631 int broken_count;
632 if (!broken_alt_svc_entry_dict.GetIntegerWithoutPathExpansion(
633 kBrokenCountKey, &broken_count)) {
634 DVLOG(1) << "Recently broken alternative service is missing "
635 << "broken-count.";
636 return false;
637 }
638 if (broken_count < 0) {
639 DVLOG(1) << "Broken alternative service has negative broken-count.";
640 return false;
641 }
642 recently_broken_alternative_services->Put(alt_service, broken_count);
643
644 // Read broken-until (optional) and if it exists, add an entry for
645 // |alt_service| in |broken_alternative_service_list|.
646 if (broken_alt_svc_entry_dict.HasKey(kBrokenUntilKey)) {
647 std::string expiration_string;
648 int64_t expiration_int64;
649 if (broken_alt_svc_entry_dict.GetStringWithoutPathExpansion(
650 kBrokenUntilKey, &expiration_string) &&
651 base::StringToInt64(expiration_string, &expiration_int64)) {
652 time_t expiration_time_t = static_cast<time_t>(expiration_int64);
653 // Convert expiration from time_t to Time to TimeTicks
654 base::TimeTicks expiration_time_ticks =
655 clock_->NowTicks() +
656 (base::Time::FromTimeT(expiration_time_t) - base::Time::Now());
657 broken_alternative_service_list->push_back(
658 std::make_pair(alt_service, expiration_time_ticks));
659 } else {
660 DVLOG(1) << "Broken alternative service has malformed broken-until "
661 << "string.";
662 return false;
663 }
664 }
665
666 return true;
544 } 667 }
545 668
546 bool HttpServerPropertiesManager::AddServersData( 669 bool HttpServerPropertiesManager::AddServersData(
547 const base::DictionaryValue& servers_dict, 670 const base::DictionaryValue& servers_dict,
548 SpdyServersMap* spdy_servers_map, 671 SpdyServersMap* spdy_servers_map,
549 AlternativeServiceMap* alternative_service_map, 672 AlternativeServiceMap* alternative_service_map,
550 ServerNetworkStatsMap* network_stats_map, 673 ServerNetworkStatsMap* network_stats_map,
551 int version) { 674 int version) {
552 for (base::DictionaryValue::Iterator it(servers_dict); !it.IsAtEnd(); 675 for (base::DictionaryValue::Iterator it(servers_dict); !it.IsAtEnd();
553 it.Advance()) { 676 it.Advance()) {
(...skipping 27 matching lines...) Expand all
581 alternative_service_map) || 704 alternative_service_map) ||
582 !AddToNetworkStatsMap(spdy_server, *server_pref_dict, 705 !AddToNetworkStatsMap(spdy_server, *server_pref_dict,
583 network_stats_map)) { 706 network_stats_map)) {
584 return false; 707 return false;
585 } 708 }
586 } 709 }
587 return true; 710 return true;
588 } 711 }
589 712
590 bool HttpServerPropertiesManager::ParseAlternativeServiceDict( 713 bool HttpServerPropertiesManager::ParseAlternativeServiceDict(
591 const base::DictionaryValue& alternative_service_dict, 714 const base::DictionaryValue& dict,
592 const std::string& server_str, 715 bool host_required,
593 AlternativeServiceInfo* alternative_service_info) { 716 const std::string& parsing_under,
717 AlternativeService* alternative_service) {
594 // Protocol is mandatory. 718 // Protocol is mandatory.
595 std::string protocol_str; 719 std::string protocol_str;
596 if (!alternative_service_dict.GetStringWithoutPathExpansion(kProtocolKey, 720 if (!dict.GetStringWithoutPathExpansion(kProtocolKey, &protocol_str)) {
597 &protocol_str)) { 721 DVLOG(1) << "Malformed alternative service protocol string under: "
598 DVLOG(1) << "Malformed alternative service protocol string for server: " 722 << parsing_under;
599 << server_str;
600 return false; 723 return false;
601 } 724 }
602 NextProto protocol = NextProtoFromString(protocol_str); 725 NextProto protocol = NextProtoFromString(protocol_str);
603 if (!IsAlternateProtocolValid(protocol)) { 726 if (!IsAlternateProtocolValid(protocol)) {
604 DVLOG(1) << "Invalid alternative service protocol string for server: " 727 DVLOG(1) << "Invalid alternative service protocol string \"" << protocol_str
605 << server_str; 728 << "\" under: " << parsing_under;
606 return false; 729 return false;
607 } 730 }
608 alternative_service_info->set_protocol(protocol); 731 alternative_service->protocol = protocol;
609 732
610 // Host is optional, defaults to "". 733 // If host is optional, it defaults to "".
611 std::string host = ""; 734 std::string host = "";
612 if (alternative_service_dict.HasKey(kHostKey) && 735 if (dict.HasKey(kHostKey)) {
613 !alternative_service_dict.GetStringWithoutPathExpansion(kHostKey, 736 if (!dict.GetStringWithoutPathExpansion(kHostKey, &host)) {
614 &host)) { 737 DVLOG(1) << "Malformed alternative service host string under: "
615 DVLOG(1) << "Malformed alternative service host string for server: " 738 << parsing_under;
616 << server_str; 739 return false;
740 }
741 } else if (host_required) {
742 DVLOG(1) << "alternative service missing host string under: "
743 << parsing_under;
617 return false; 744 return false;
618 } 745 }
619 alternative_service_info->set_host(host); 746 alternative_service->host = host;
620 747
621 // Port is mandatory. 748 // Port is mandatory.
622 int port = 0; 749 int port = 0;
623 if (!alternative_service_dict.GetInteger(kPortKey, &port) || 750 if (!dict.GetInteger(kPortKey, &port) || !IsPortValid(port)) {
624 !IsPortValid(port)) { 751 DVLOG(1) << "Malformed alternative service port under: " << parsing_under;
625 DVLOG(1) << "Malformed alternative service port for server: " << server_str;
626 return false; 752 return false;
627 } 753 }
628 alternative_service_info->set_port(static_cast<uint32_t>(port)); 754 alternative_service->port = static_cast<uint32_t>(port);
629 755
756 return true;
757 }
758
759 bool HttpServerPropertiesManager::ParseAlternativeServiceInfoExpiration(
760 const base::DictionaryValue& dict,
761 const std::string& server_str,
762 AlternativeServiceInfo* alternative_service_info) {
630 // Expiration is optional, defaults to one day. 763 // Expiration is optional, defaults to one day.
631 base::Time expiration; 764 base::Time expiration;
632 if (!alternative_service_dict.HasKey(kExpirationKey)) { 765 if (!dict.HasKey(kExpirationKey)) {
633 alternative_service_info->set_expiration(base::Time::Now() + 766 alternative_service_info->set_expiration(base::Time::Now() +
634 base::TimeDelta::FromDays(1)); 767 base::TimeDelta::FromDays(1));
635 return true; 768 return true;
636 } 769 }
637 770
638 std::string expiration_string; 771 std::string expiration_string;
639 if (alternative_service_dict.GetStringWithoutPathExpansion( 772 if (dict.GetStringWithoutPathExpansion(kExpirationKey, &expiration_string)) {
640 kExpirationKey, &expiration_string)) {
641 int64_t expiration_int64 = 0; 773 int64_t expiration_int64 = 0;
642 if (!base::StringToInt64(expiration_string, &expiration_int64)) { 774 if (!base::StringToInt64(expiration_string, &expiration_int64)) {
643 DVLOG(1) << "Malformed alternative service expiration for server: " 775 DVLOG(1) << "Malformed alternative service expiration for server: "
644 << server_str; 776 << server_str;
645 return false; 777 return false;
646 } 778 }
647 alternative_service_info->set_expiration( 779 alternative_service_info->set_expiration(
648 base::Time::FromInternalValue(expiration_int64)); 780 base::Time::FromInternalValue(expiration_int64));
649 return true; 781 return true;
650 } 782 }
(...skipping 18 matching lines...) Expand all
669 return false; 801 return false;
670 } 802 }
671 803
672 AlternativeServiceInfoVector alternative_service_info_vector; 804 AlternativeServiceInfoVector alternative_service_info_vector;
673 for (const auto& alternative_service_list_item : *alternative_service_list) { 805 for (const auto& alternative_service_list_item : *alternative_service_list) {
674 const base::DictionaryValue* alternative_service_dict; 806 const base::DictionaryValue* alternative_service_dict;
675 if (!alternative_service_list_item.GetAsDictionary( 807 if (!alternative_service_list_item.GetAsDictionary(
676 &alternative_service_dict)) 808 &alternative_service_dict))
677 return false; 809 return false;
678 AlternativeServiceInfo alternative_service_info; 810 AlternativeServiceInfo alternative_service_info;
679 if (!ParseAlternativeServiceDict(*alternative_service_dict, 811 AlternativeService alternative_service;
812 if (!ParseAlternativeServiceDict(*alternative_service_dict, false,
680 server.Serialize(), 813 server.Serialize(),
681 &alternative_service_info)) { 814 &alternative_service) ||
815 !ParseAlternativeServiceInfoExpiration(*alternative_service_dict,
816 server.Serialize(),
817 &alternative_service_info)) {
682 return false; 818 return false;
683 } 819 }
820 alternative_service_info.set_alternative_service(alternative_service);
821
684 if (base::Time::Now() < alternative_service_info.expiration()) { 822 if (base::Time::Now() < alternative_service_info.expiration()) {
685 alternative_service_info_vector.push_back(alternative_service_info); 823 alternative_service_info_vector.push_back(alternative_service_info);
686 } 824 }
687 } 825 }
688 826
689 if (alternative_service_info_vector.empty()) { 827 if (alternative_service_info_vector.empty()) {
690 return false; 828 return false;
691 } 829 }
692 830
693 alternative_service_map->Put(server, alternative_service_info_vector); 831 alternative_service_map->Put(server, alternative_service_info_vector);
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
791 } 929 }
792 return !detected_corrupted_prefs; 930 return !detected_corrupted_prefs;
793 } 931 }
794 932
795 void HttpServerPropertiesManager::UpdateCacheFromPrefsOnNetworkSequence( 933 void HttpServerPropertiesManager::UpdateCacheFromPrefsOnNetworkSequence(
796 std::unique_ptr<SpdyServersMap> spdy_servers_map, 934 std::unique_ptr<SpdyServersMap> spdy_servers_map,
797 std::unique_ptr<AlternativeServiceMap> alternative_service_map, 935 std::unique_ptr<AlternativeServiceMap> alternative_service_map,
798 std::unique_ptr<IPAddress> last_quic_address, 936 std::unique_ptr<IPAddress> last_quic_address,
799 std::unique_ptr<ServerNetworkStatsMap> server_network_stats_map, 937 std::unique_ptr<ServerNetworkStatsMap> server_network_stats_map,
800 std::unique_ptr<QuicServerInfoMap> quic_server_info_map, 938 std::unique_ptr<QuicServerInfoMap> quic_server_info_map,
939 std::unique_ptr<BrokenAlternativeServiceList>
940 broken_alternative_service_list,
941 std::unique_ptr<RecentlyBrokenAlternativeServices>
942 recently_broken_alternative_services,
801 bool detected_corrupted_prefs) { 943 bool detected_corrupted_prefs) {
802 // Preferences have the master data because admins might have pushed new 944 // Preferences have the master data because admins might have pushed new
803 // preferences. Update the cached data with new data from preferences. 945 // preferences. Update the cached data with new data from preferences.
804 DCHECK(network_task_runner_->RunsTasksInCurrentSequence()); 946 DCHECK(network_task_runner_->RunsTasksInCurrentSequence());
805 947
806 UMA_HISTOGRAM_COUNTS("Net.CountOfSpdyServers", spdy_servers_map->size()); 948 UMA_HISTOGRAM_COUNTS("Net.CountOfSpdyServers", spdy_servers_map->size());
807 http_server_properties_impl_->SetSpdyServers(std::move(spdy_servers_map)); 949 http_server_properties_impl_->SetSpdyServers(std::move(spdy_servers_map));
808 950
809 // Update the cached data and use the new alternative service list from 951 // Update the cached data and use the new alternative service list from
810 // preferences. 952 // preferences.
811 UMA_HISTOGRAM_COUNTS("Net.CountOfAlternateProtocolServers", 953 UMA_HISTOGRAM_COUNTS("Net.CountOfAlternateProtocolServers",
812 alternative_service_map->size()); 954 alternative_service_map->size());
813 http_server_properties_impl_->SetAlternativeServiceServers( 955 http_server_properties_impl_->SetAlternativeServiceServers(
814 std::move(alternative_service_map)); 956 std::move(alternative_service_map));
815 957
816 http_server_properties_impl_->SetSupportsQuic(*last_quic_address); 958 http_server_properties_impl_->SetSupportsQuic(*last_quic_address);
817 959
818 http_server_properties_impl_->SetServerNetworkStats( 960 http_server_properties_impl_->SetServerNetworkStats(
819 std::move(server_network_stats_map)); 961 std::move(server_network_stats_map));
820 962
821 UMA_HISTOGRAM_COUNTS_1000("Net.CountOfQuicServerInfos", 963 UMA_HISTOGRAM_COUNTS_1000("Net.CountOfQuicServerInfos",
822 quic_server_info_map->size()); 964 quic_server_info_map->size());
823 965
824 http_server_properties_impl_->SetQuicServerInfoMap( 966 http_server_properties_impl_->SetQuicServerInfoMap(
825 std::move(quic_server_info_map)); 967 std::move(quic_server_info_map));
826 968
969 if (recently_broken_alternative_services) {
970 DCHECK(broken_alternative_service_list);
971
972 UMA_HISTOGRAM_COUNTS_1000("Net.CountOfBrokenAlternativeServices",
973 broken_alternative_service_list->size());
974 UMA_HISTOGRAM_COUNTS_1000("Net.CountOfRecentlyBrokenAlternativeServices",
975 recently_broken_alternative_services->size());
976
977 http_server_properties_impl_->SetBrokenAndRecentlyBrokenAlternativeServices(
978 std::move(broken_alternative_service_list),
979 std::move(recently_broken_alternative_services));
980 }
981
827 // Update the prefs with what we have read (delete all corrupted prefs). 982 // Update the prefs with what we have read (delete all corrupted prefs).
828 if (detected_corrupted_prefs) 983 if (detected_corrupted_prefs)
829 ScheduleUpdatePrefsOnNetworkSequence(DETECTED_CORRUPTED_PREFS); 984 ScheduleUpdatePrefsOnNetworkSequence(DETECTED_CORRUPTED_PREFS);
830 } 985 }
831 986
832 // 987 //
833 // Update Preferences with data from the cached data. 988 // Update Preferences with data from the cached data.
834 // 989 //
835 void HttpServerPropertiesManager::ScheduleUpdatePrefsOnNetworkSequence( 990 void HttpServerPropertiesManager::ScheduleUpdatePrefsOnNetworkSequence(
836 Location location) { 991 Location location) {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
884 continue; 1039 continue;
885 } 1040 }
886 AlternativeService alternative_service( 1041 AlternativeService alternative_service(
887 alternative_service_info.alternative_service()); 1042 alternative_service_info.alternative_service());
888 if (!IsAlternateProtocolValid(alternative_service.protocol)) { 1043 if (!IsAlternateProtocolValid(alternative_service.protocol)) {
889 continue; 1044 continue;
890 } 1045 }
891 if (alternative_service.host.empty()) { 1046 if (alternative_service.host.empty()) {
892 alternative_service.host = server.host(); 1047 alternative_service.host = server.host();
893 } 1048 }
894 if (IsAlternativeServiceBroken(alternative_service)) {
895 continue;
896 }
897 notbroken_alternative_service_info_vector.push_back( 1049 notbroken_alternative_service_info_vector.push_back(
898 alternative_service_info); 1050 alternative_service_info);
899 } 1051 }
900 if (notbroken_alternative_service_info_vector.empty()) { 1052 if (notbroken_alternative_service_info_vector.empty()) {
901 continue; 1053 continue;
902 } 1054 }
903 const std::string* canonical_suffix = 1055 const std::string* canonical_suffix =
904 http_server_properties_impl_->GetCanonicalSuffix(server.host()); 1056 http_server_properties_impl_->GetCanonicalSuffix(server.host());
905 if (canonical_suffix != nullptr) { 1057 if (canonical_suffix != nullptr) {
906 if (persisted_map.find(*canonical_suffix) != persisted_map.end()) 1058 if (persisted_map.find(*canonical_suffix) != persisted_map.end())
(...skipping 25 matching lines...) Expand all
932 if (main_quic_server_info_map.size() > 0) { 1084 if (main_quic_server_info_map.size() > 0) {
933 quic_server_info_map = base::MakeUnique<QuicServerInfoMap>( 1085 quic_server_info_map = base::MakeUnique<QuicServerInfoMap>(
934 max_server_configs_stored_in_properties()); 1086 max_server_configs_stored_in_properties());
935 for (QuicServerInfoMap::const_reverse_iterator it = 1087 for (QuicServerInfoMap::const_reverse_iterator it =
936 main_quic_server_info_map.rbegin(); 1088 main_quic_server_info_map.rbegin();
937 it != main_quic_server_info_map.rend(); ++it) { 1089 it != main_quic_server_info_map.rend(); ++it) {
938 quic_server_info_map->Put(it->first, it->second); 1090 quic_server_info_map->Put(it->first, it->second);
939 } 1091 }
940 } 1092 }
941 1093
1094 // Make copy of list of broken alternative services stored in
1095 // |http_server_properties_impl_|
1096 std::unique_ptr<BrokenAlternativeServiceList> broken_alt_svc_list_copy;
1097 const BrokenAlternativeServiceList& broken_alternative_service_list =
1098 http_server_properties_impl_->broken_alternative_service_list();
1099 if (broken_alternative_service_list.size() > 0) {
1100 broken_alt_svc_list_copy = base::MakeUnique<BrokenAlternativeServiceList>();
1101 size_t count = 0;
1102 for (auto it = broken_alternative_service_list.begin();
1103 it != broken_alternative_service_list.end() &&
1104 count < kMaxBrokenAlternativeServicesToPersist;
1105 ++it) {
1106 broken_alt_svc_list_copy->push_back(*it);
1107 ++count;
1108 }
1109 }
1110
1111 // Make copy of RecentlyBrokenAternativeServices stored in
1112 // |http_server_properties_impl_|.
1113 std::unique_ptr<RecentlyBrokenAlternativeServices>
1114 recently_broken_alt_svc_copy;
1115 const RecentlyBrokenAlternativeServices& recently_broken_alt_services =
1116 http_server_properties_impl_->recently_broken_alternative_services();
1117 if (recently_broken_alt_services.size() > 0) {
1118 recently_broken_alt_svc_copy =
1119 base::MakeUnique<RecentlyBrokenAlternativeServices>(
1120 kMaxRecentlyBrokenAlternativeServicesToPersist);
1121 size_t count = 0;
1122 for (auto it = recently_broken_alt_services.rbegin();
1123 it != recently_broken_alt_services.rend() &&
1124 count < kMaxRecentlyBrokenAlternativeServicesToPersist;
1125 ++it) {
1126 recently_broken_alt_svc_copy->Put(it->first, it->second);
1127 ++count;
1128 }
1129 }
1130
942 std::unique_ptr<IPAddress> last_quic_addr = base::MakeUnique<IPAddress>(); 1131 std::unique_ptr<IPAddress> last_quic_addr = base::MakeUnique<IPAddress>();
943 http_server_properties_impl_->GetSupportsQuic(last_quic_addr.get()); 1132 http_server_properties_impl_->GetSupportsQuic(last_quic_addr.get());
944 // Update the preferences on the pref thread. 1133 // Update the preferences on the pref thread.
945 pref_task_runner_->PostTask( 1134 pref_task_runner_->PostTask(
946 FROM_HERE, 1135 FROM_HERE,
947 base::Bind(&HttpServerPropertiesManager::UpdatePrefsOnPrefThread, 1136 base::Bind(&HttpServerPropertiesManager::UpdatePrefsOnPrefThread,
948 pref_weak_ptr_, base::Passed(&spdy_servers), 1137 pref_weak_ptr_, base::Passed(&spdy_servers),
949 base::Passed(&alternative_service_map), 1138 base::Passed(&alternative_service_map),
950 base::Passed(&last_quic_addr), 1139 base::Passed(&last_quic_addr),
951 base::Passed(&server_network_stats_map), 1140 base::Passed(&server_network_stats_map),
952 base::Passed(&quic_server_info_map), completion)); 1141 base::Passed(&quic_server_info_map),
1142 base::Passed(&broken_alt_svc_list_copy),
1143 base::Passed(&recently_broken_alt_svc_copy), completion));
953 } 1144 }
954 1145
955 // A local or temporary data structure to hold |supports_spdy|, SpdySettings, 1146 // A local or temporary data structure to hold |supports_spdy|, SpdySettings,
956 // AlternativeServiceInfoVector, and SupportsQuic preferences for a server. This 1147 // AlternativeServiceInfoVector, and SupportsQuic preferences for a server. This
957 // is used only in UpdatePrefsOnPrefThread. 1148 // is used only in UpdatePrefsOnPrefThread.
958 struct ServerPref { 1149 struct ServerPref {
959 ServerPref() 1150 ServerPref()
960 : supports_spdy(false), 1151 : supports_spdy(false),
961 settings_map(nullptr), 1152 settings_map(nullptr),
962 alternative_service_info_vector(nullptr), 1153 alternative_service_info_vector(nullptr),
(...skipping 17 matching lines...) Expand all
980 const ServerNetworkStats* server_network_stats; 1171 const ServerNetworkStats* server_network_stats;
981 }; 1172 };
982 1173
983 // All maps and lists are in MRU order. 1174 // All maps and lists are in MRU order.
984 void HttpServerPropertiesManager::UpdatePrefsOnPrefThread( 1175 void HttpServerPropertiesManager::UpdatePrefsOnPrefThread(
985 std::unique_ptr<std::vector<std::string>> spdy_servers, 1176 std::unique_ptr<std::vector<std::string>> spdy_servers,
986 std::unique_ptr<AlternativeServiceMap> alternative_service_map, 1177 std::unique_ptr<AlternativeServiceMap> alternative_service_map,
987 std::unique_ptr<IPAddress> last_quic_address, 1178 std::unique_ptr<IPAddress> last_quic_address,
988 std::unique_ptr<ServerNetworkStatsMap> server_network_stats_map, 1179 std::unique_ptr<ServerNetworkStatsMap> server_network_stats_map,
989 std::unique_ptr<QuicServerInfoMap> quic_server_info_map, 1180 std::unique_ptr<QuicServerInfoMap> quic_server_info_map,
1181 std::unique_ptr<BrokenAlternativeServiceList>
1182 broken_alternative_service_list,
1183 std::unique_ptr<RecentlyBrokenAlternativeServices>
1184 recently_broken_alternative_services,
990 const base::Closure& completion) { 1185 const base::Closure& completion) {
991 typedef base::MRUCache<url::SchemeHostPort, ServerPref> ServerPrefMap; 1186 typedef base::MRUCache<url::SchemeHostPort, ServerPref> ServerPrefMap;
992 ServerPrefMap server_pref_map(ServerPrefMap::NO_AUTO_EVICT); 1187 ServerPrefMap server_pref_map(ServerPrefMap::NO_AUTO_EVICT);
993 1188
994 DCHECK(pref_task_runner_->RunsTasksInCurrentSequence()); 1189 DCHECK(pref_task_runner_->RunsTasksInCurrentSequence());
995 1190
996 // Add servers that support spdy to server_pref_map in the MRU order. 1191 // Add servers that support spdy to server_pref_map in the MRU order.
997 DCHECK(spdy_servers); 1192 DCHECK(spdy_servers);
998 for (size_t i = spdy_servers->size(); i > 0; --i) { 1193 for (size_t i = spdy_servers->size(); i > 0; --i) {
999 url::SchemeHostPort server((GURL(spdy_servers->at(i - 1)))); 1194 url::SchemeHostPort server((GURL(spdy_servers->at(i - 1))));
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
1074 SetVersion(&http_server_properties_dict, kVersionNumber); 1269 SetVersion(&http_server_properties_dict, kVersionNumber);
1075 1270
1076 DCHECK(last_quic_address); 1271 DCHECK(last_quic_address);
1077 SaveSupportsQuicToPrefs(*last_quic_address, &http_server_properties_dict); 1272 SaveSupportsQuicToPrefs(*last_quic_address, &http_server_properties_dict);
1078 1273
1079 if (quic_server_info_map) { 1274 if (quic_server_info_map) {
1080 SaveQuicServerInfoMapToServerPrefs(*quic_server_info_map, 1275 SaveQuicServerInfoMapToServerPrefs(*quic_server_info_map,
1081 &http_server_properties_dict); 1276 &http_server_properties_dict);
1082 } 1277 }
1083 1278
1279 SaveBrokenAlternativeServicesToPrefs(
1280 broken_alternative_service_list.get(),
1281 recently_broken_alternative_services.get(), &http_server_properties_dict);
1282
1084 setting_prefs_ = true; 1283 setting_prefs_ = true;
1085 pref_delegate_->SetServerProperties(http_server_properties_dict); 1284 pref_delegate_->SetServerProperties(http_server_properties_dict);
1086 setting_prefs_ = false; 1285 setting_prefs_ = false;
1087 1286
1088 net_log_.AddEvent(NetLogEventType::HTTP_SERVER_PROPERTIES_UPDATE_PREFS, 1287 net_log_.AddEvent(NetLogEventType::HTTP_SERVER_PROPERTIES_UPDATE_PREFS,
1089 base::Bind(&NetLogCallback, http_server_properties_dict)); 1288 base::Bind(&NetLogCallback, http_server_properties_dict));
1090 // Note that |completion| will be fired after we have written everything to 1289 // Note that |completion| will be fired after we have written everything to
1091 // the Preferences, but likely before these changes are serialized to disk. 1290 // the Preferences, but likely before these changes are serialized to disk.
1092 // This is not a problem though, as JSONPrefStore guarantees that this will 1291 // This is not a problem though, as JSONPrefStore guarantees that this will
1093 // happen, pretty soon, and even in the case we shut down immediately. 1292 // happen, pretty soon, and even in the case we shut down immediately.
1094 if (!completion.is_null()) 1293 if (!completion.is_null())
1095 completion.Run(); 1294 completion.Run();
1096 } 1295 }
1097 1296
1098 void HttpServerPropertiesManager::SaveAlternativeServiceToServerPrefs( 1297 void HttpServerPropertiesManager::SaveAlternativeServiceToServerPrefs(
1099 const AlternativeServiceInfoVector& alternative_service_info_vector, 1298 const AlternativeServiceInfoVector& alternative_service_info_vector,
1100 base::DictionaryValue* server_pref_dict) { 1299 base::DictionaryValue* server_pref_dict) {
1101 if (alternative_service_info_vector.empty()) { 1300 if (alternative_service_info_vector.empty()) {
1102 return; 1301 return;
1103 } 1302 }
1104 std::unique_ptr<base::ListValue> alternative_service_list( 1303 std::unique_ptr<base::ListValue> alternative_service_list(
1105 new base::ListValue); 1304 new base::ListValue);
1106 for (const AlternativeServiceInfo& alternative_service_info : 1305 for (const AlternativeServiceInfo& alternative_service_info :
1107 alternative_service_info_vector) { 1306 alternative_service_info_vector) {
1108 const AlternativeService alternative_service = 1307 const AlternativeService& alternative_service =
1109 alternative_service_info.alternative_service(); 1308 alternative_service_info.alternative_service();
1110 DCHECK(IsAlternateProtocolValid(alternative_service.protocol)); 1309 DCHECK(IsAlternateProtocolValid(alternative_service.protocol));
1111 std::unique_ptr<base::DictionaryValue> alternative_service_dict( 1310 std::unique_ptr<base::DictionaryValue> alternative_service_dict(
1112 new base::DictionaryValue); 1311 new base::DictionaryValue);
1113 alternative_service_dict->SetInteger(kPortKey, alternative_service.port); 1312 AddAlternativeServiceFieldsToDictionaryValue(
1114 if (!alternative_service.host.empty()) { 1313 alternative_service, alternative_service_dict.get());
1115 alternative_service_dict->SetString(kHostKey, alternative_service.host);
1116 }
1117 alternative_service_dict->SetString(
1118 kProtocolKey, NextProtoToString(alternative_service.protocol));
1119 // JSON cannot store int64_t, so expiration is converted to a string. 1314 // JSON cannot store int64_t, so expiration is converted to a string.
1120 alternative_service_dict->SetString( 1315 alternative_service_dict->SetString(
1121 kExpirationKey, 1316 kExpirationKey,
1122 base::Int64ToString( 1317 base::Int64ToString(
1123 alternative_service_info.expiration().ToInternalValue())); 1318 alternative_service_info.expiration().ToInternalValue()));
1124 alternative_service_list->Append(std::move(alternative_service_dict)); 1319 alternative_service_list->Append(std::move(alternative_service_dict));
1125 } 1320 }
1126 if (alternative_service_list->GetSize() == 0) 1321 if (alternative_service_list->GetSize() == 0)
1127 return; 1322 return;
1128 server_pref_dict->SetWithoutPathExpansion( 1323 server_pref_dict->SetWithoutPathExpansion(
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1166 auto quic_server_pref_dict = base::MakeUnique<base::DictionaryValue>(); 1361 auto quic_server_pref_dict = base::MakeUnique<base::DictionaryValue>();
1167 quic_server_pref_dict->SetStringWithoutPathExpansion(kServerInfoKey, 1362 quic_server_pref_dict->SetStringWithoutPathExpansion(kServerInfoKey,
1168 it->second); 1363 it->second);
1169 quic_servers_dict->SetWithoutPathExpansion( 1364 quic_servers_dict->SetWithoutPathExpansion(
1170 server_id.ToString(), std::move(quic_server_pref_dict)); 1365 server_id.ToString(), std::move(quic_server_pref_dict));
1171 } 1366 }
1172 http_server_properties_dict->SetWithoutPathExpansion( 1367 http_server_properties_dict->SetWithoutPathExpansion(
1173 kQuicServers, std::move(quic_servers_dict)); 1368 kQuicServers, std::move(quic_servers_dict));
1174 } 1369 }
1175 1370
1371 void HttpServerPropertiesManager::SaveBrokenAlternativeServicesToPrefs(
1372 const BrokenAlternativeServiceList* broken_alternative_service_list,
1373 const RecentlyBrokenAlternativeServices*
1374 recently_broken_alternative_services,
1375 base::DictionaryValue* http_server_properties_dict) {
1376 if (!recently_broken_alternative_services) {
1377 DCHECK(!broken_alternative_service_list);
1378 return;
1379 }
1380
1381 // JSON list will be in MRU order according to
1382 // |recently_broken_alternative_services|.
1383 base::ListValue* json_list = new base::ListValue;
1384 // Maps an alternative service to the index where it's stored in |json_list|.
1385 std::unordered_map<AlternativeService, size_t, AlternativeServiceHash>
1386 json_list_index_map;
1387 for (auto it = recently_broken_alternative_services->rbegin();
1388 it != recently_broken_alternative_services->rend(); ++it) {
1389 const AlternativeService& alt_service = it->first;
1390 int broken_count = it->second;
1391 base::DictionaryValue entry_dict;
1392 AddAlternativeServiceFieldsToDictionaryValue(alt_service, &entry_dict);
1393 entry_dict.SetIntegerWithoutPathExpansion(kBrokenCountKey, broken_count);
1394 json_list_index_map[alt_service] = json_list->GetList().size();
1395 json_list->GetList().push_back(std::move(entry_dict));
1396 }
1397
1398 if (!broken_alternative_service_list)
1399 return;
1400
1401 // Add expiration time info from |broken_alternative_service_list| to
1402 // the JSON list.
1403 for (auto entry : *broken_alternative_service_list) {
1404 const AlternativeService& alt_service = entry.first;
1405 base::TimeTicks expiration_time_ticks = entry.second;
1406 // Convert expiration from TimeTicks to Time to time_t
1407 time_t expiration_time_t =
1408 (base::Time::Now() + (expiration_time_ticks - clock_->NowTicks()))
1409 .ToTimeT();
1410 int64_t expiration_int64 = static_cast<int64_t>(expiration_time_t);
1411
1412 size_t json_list_index = json_list_index_map[alt_service];
1413 base::DictionaryValue* entry_dict;
1414 DCHECK(json_list->GetDictionary(json_list_index, &entry_dict));
1415 entry_dict->SetStringWithoutPathExpansion(
1416 kBrokenUntilKey, base::Int64ToString(expiration_int64));
1417 }
1418
1419 http_server_properties_dict->SetWithoutPathExpansion(
1420 kBrokenAlternativeServicesKey,
1421 base::WrapUnique<base::ListValue>(json_list));
1422 }
1423
1176 void HttpServerPropertiesManager::OnHttpServerPropertiesChanged() { 1424 void HttpServerPropertiesManager::OnHttpServerPropertiesChanged() {
1177 DCHECK(pref_task_runner_->RunsTasksInCurrentSequence()); 1425 DCHECK(pref_task_runner_->RunsTasksInCurrentSequence());
1178 if (!setting_prefs_) 1426 if (!setting_prefs_)
1179 ScheduleUpdateCacheOnPrefThread(); 1427 ScheduleUpdateCacheOnPrefThread();
1180 } 1428 }
1181 1429
1182 void HttpServerPropertiesManager::SetInitialized() { 1430 void HttpServerPropertiesManager::SetInitialized() {
1183 DCHECK(network_task_runner_->RunsTasksInCurrentSequence()); 1431 DCHECK(network_task_runner_->RunsTasksInCurrentSequence());
1184 is_initialized_ = true; 1432 is_initialized_ = true;
1185 net_log_.EndEvent(NetLogEventType::HTTP_SERVER_PROPERTIES_INITIALIZATION); 1433 net_log_.EndEvent(NetLogEventType::HTTP_SERVER_PROPERTIES_INITIALIZATION);
1186 } 1434 }
1187 1435
1188 } // namespace net 1436 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698