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

Side by Side Diff: chrome/browser/net/http_server_properties_manager.cc

Issue 8423028: Persist dynamically learned SPDY settings (like CWND). (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 1 month 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 #include "chrome/browser/net/http_server_properties_manager.h" 4 #include "chrome/browser/net/http_server_properties_manager.h"
5 5
6 #include "base/bind.h" 6 #include "base/bind.h"
7 #include "base/stl_util.h" 7 #include "base/stl_util.h"
8 #include "base/values.h" 8 #include "base/values.h"
9 #include "chrome/browser/prefs/pref_service.h" 9 #include "chrome/browser/prefs/pref_service.h"
10 #include "chrome/common/chrome_notification_types.h" 10 #include "chrome/common/chrome_notification_types.h"
(...skipping 13 matching lines...) Expand all
24 // timer. 24 // timer.
25 const int64 kUpdateCacheDelayMs = 1000; 25 const int64 kUpdateCacheDelayMs = 1000;
26 26
27 // Time to wait before starting an update the preferences from the 27 // Time to wait before starting an update the preferences from the
28 // spdy_servers cache. Scheduling another update during this period will 28 // spdy_servers cache. Scheduling another update during this period will
29 // reset the timer. 29 // reset the timer.
30 const int64 kUpdatePrefsDelayMs = 5000; 30 const int64 kUpdatePrefsDelayMs = 5000;
31 31
32 typedef std::vector<std::string> StringVector; 32 typedef std::vector<std::string> StringVector;
33 33
34 // String is host/port pair of spdy server.
35 StringVector* ListValueToStringVector(const base::ListValue* list) {
36 StringVector* vector = new StringVector;
37
38 if (!list)
39 return vector;
40
41 vector->reserve(list->GetSize());
42 std::string s;
43 for (base::ListValue::const_iterator it = list->begin();
44 it != list->end(); ++it) {
45 if ((*it)->GetAsString(&s))
46 vector->push_back(s);
47 }
48
49 return vector;
50 }
51
52 } // namespace 34 } // namespace
53 35
54 //////////////////////////////////////////////////////////////////////////////// 36 ////////////////////////////////////////////////////////////////////////////////
55 // HttpServerPropertiesManager 37 // HttpServerPropertiesManager
56 38
57 HttpServerPropertiesManager::HttpServerPropertiesManager( 39 HttpServerPropertiesManager::HttpServerPropertiesManager(
58 PrefService* pref_service) 40 PrefService* pref_service)
59 : pref_service_(pref_service), 41 : pref_service_(pref_service),
60 setting_spdy_servers_(false), 42 setting_prefs_(false) {
61 setting_alternate_protocol_servers_(false) {
62 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 43 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
63 DCHECK(pref_service); 44 DCHECK(pref_service);
64 ui_weak_ptr_factory_.reset( 45 ui_weak_ptr_factory_.reset(
65 new base::WeakPtrFactory<HttpServerPropertiesManager>(this)); 46 new base::WeakPtrFactory<HttpServerPropertiesManager>(this));
66 ui_weak_ptr_ = ui_weak_ptr_factory_->GetWeakPtr(); 47 ui_weak_ptr_ = ui_weak_ptr_factory_->GetWeakPtr();
67 ui_spdy_cache_update_timer_.reset( 48 ui_cache_update_timer_.reset(
68 new base::OneShotTimer<HttpServerPropertiesManager>);
69 ui_alternate_protocol_cache_update_timer_.reset(
70 new base::OneShotTimer<HttpServerPropertiesManager>); 49 new base::OneShotTimer<HttpServerPropertiesManager>);
71 pref_change_registrar_.Init(pref_service_); 50 pref_change_registrar_.Init(pref_service_);
72 pref_change_registrar_.Add(prefs::kSpdyServers, this); 51 pref_change_registrar_.Add(prefs::kHttpServerProperties, this);
73 pref_change_registrar_.Add(prefs::kAlternateProtocolServers, this);
74 } 52 }
75 53
76 HttpServerPropertiesManager::~HttpServerPropertiesManager() { 54 HttpServerPropertiesManager::~HttpServerPropertiesManager() {
77 } 55 }
78 56
79 void HttpServerPropertiesManager::InitializeOnIOThread() { 57 void HttpServerPropertiesManager::InitializeOnIOThread() {
80 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 58 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
81 http_server_properties_impl_.reset(new net::HttpServerPropertiesImpl()); 59 http_server_properties_impl_.reset(new net::HttpServerPropertiesImpl());
82 60
83 io_spdy_prefs_update_timer_.reset( 61 io_spdy_prefs_update_timer_.reset(
84 new base::OneShotTimer<HttpServerPropertiesManager>); 62 new base::OneShotTimer<HttpServerPropertiesManager>);
85 io_alternate_protocol_prefs_update_timer_.reset(
86 new base::OneShotTimer<HttpServerPropertiesManager>);
87 63
88 BrowserThread::PostTask( 64 BrowserThread::PostTask(
89 BrowserThread::UI, 65 BrowserThread::UI,
90 FROM_HERE, 66 FROM_HERE,
91 base::Bind(&HttpServerPropertiesManager::UpdateSpdyCacheFromPrefs, 67 base::Bind(&HttpServerPropertiesManager::UpdateCacheFromPrefsOnUI,
92 ui_weak_ptr_)); 68 ui_weak_ptr_));
93 BrowserThread::PostTask(
94 BrowserThread::UI,
95 FROM_HERE,
96 base::Bind(
97 &HttpServerPropertiesManager::UpdateAlternateProtocolCacheFromPrefs,
98 ui_weak_ptr_));
99 } 69 }
100 70
101 void HttpServerPropertiesManager::ShutdownOnUIThread() { 71 void HttpServerPropertiesManager::ShutdownOnUIThread() {
102 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 72 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
103 // Cancel any pending updates, and stop listening for pref change updates. 73 // Cancel any pending updates, and stop listening for pref change updates.
104 ui_spdy_cache_update_timer_->Stop(); 74 ui_cache_update_timer_->Stop();
105 ui_alternate_protocol_cache_update_timer_->Stop();
106 ui_weak_ptr_factory_.reset(); 75 ui_weak_ptr_factory_.reset();
107 pref_change_registrar_.RemoveAll(); 76 pref_change_registrar_.RemoveAll();
108 } 77 }
109 78
110 // static 79 // static
111 void HttpServerPropertiesManager::RegisterPrefs(PrefService* prefs) { 80 void HttpServerPropertiesManager::RegisterPrefs(PrefService* prefs) {
112 prefs->RegisterListPref(prefs::kSpdyServers, PrefService::UNSYNCABLE_PREF); 81 prefs->RegisterDictionaryPref(prefs::kHttpServerProperties,
113 prefs->RegisterDictionaryPref(prefs::kAlternateProtocolServers,
114 PrefService::UNSYNCABLE_PREF); 82 PrefService::UNSYNCABLE_PREF);
115 } 83 }
116 84
117 void HttpServerPropertiesManager::Clear() { 85 void HttpServerPropertiesManager::Clear() {
118 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 86 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
119 87
120 http_server_properties_impl_->Clear(); 88 http_server_properties_impl_->Clear();
121 ScheduleUpdateSpdyPrefsOnIO(); 89 ScheduleUpdatePrefsOnIO();
122 ScheduleUpdateAlternateProtocolPrefsOnIO();
123 } 90 }
124 91
125 bool HttpServerPropertiesManager::SupportsSpdy( 92 bool HttpServerPropertiesManager::SupportsSpdy(
126 const net::HostPortPair& server) const { 93 const net::HostPortPair& server) const {
127 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 94 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
128 return http_server_properties_impl_->SupportsSpdy(server); 95 return http_server_properties_impl_->SupportsSpdy(server);
129 } 96 }
130 97
131 void HttpServerPropertiesManager::SetSupportsSpdy( 98 void HttpServerPropertiesManager::SetSupportsSpdy(
132 const net::HostPortPair& server, 99 const net::HostPortPair& server,
133 bool support_spdy) { 100 bool support_spdy) {
134 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 101 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
135 102
136 http_server_properties_impl_->SetSupportsSpdy(server, support_spdy); 103 http_server_properties_impl_->SetSupportsSpdy(server, support_spdy);
137 ScheduleUpdateSpdyPrefsOnIO(); 104 ScheduleUpdatePrefsOnIO();
138 } 105 }
139 106
140 bool HttpServerPropertiesManager::HasAlternateProtocol( 107 bool HttpServerPropertiesManager::HasAlternateProtocol(
141 const net::HostPortPair& server) const { 108 const net::HostPortPair& server) const {
142 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 109 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
143 return http_server_properties_impl_->HasAlternateProtocol(server); 110 return http_server_properties_impl_->HasAlternateProtocol(server);
144 } 111 }
145 112
146 net::PortAlternateProtocolPair 113 net::PortAlternateProtocolPair
147 HttpServerPropertiesManager::GetAlternateProtocol( 114 HttpServerPropertiesManager::GetAlternateProtocol(
148 const net::HostPortPair& server) const { 115 const net::HostPortPair& server) const {
149 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 116 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
150 return http_server_properties_impl_->GetAlternateProtocol(server); 117 return http_server_properties_impl_->GetAlternateProtocol(server);
151 } 118 }
152 119
153 void HttpServerPropertiesManager::SetAlternateProtocol( 120 void HttpServerPropertiesManager::SetAlternateProtocol(
154 const net::HostPortPair& server, 121 const net::HostPortPair& server,
155 uint16 alternate_port, 122 uint16 alternate_port,
156 net::AlternateProtocol alternate_protocol) { 123 net::AlternateProtocol alternate_protocol) {
157 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 124 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
158 http_server_properties_impl_->SetAlternateProtocol( 125 http_server_properties_impl_->SetAlternateProtocol(
159 server, alternate_port, alternate_protocol); 126 server, alternate_port, alternate_protocol);
160 ScheduleUpdateAlternateProtocolPrefsOnIO(); 127 ScheduleUpdatePrefsOnIO();
161 } 128 }
162 129
163 void HttpServerPropertiesManager::SetBrokenAlternateProtocol( 130 void HttpServerPropertiesManager::SetBrokenAlternateProtocol(
164 const net::HostPortPair& server) { 131 const net::HostPortPair& server) {
165 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 132 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
166 http_server_properties_impl_->SetBrokenAlternateProtocol(server); 133 http_server_properties_impl_->SetBrokenAlternateProtocol(server);
167 ScheduleUpdateAlternateProtocolPrefsOnIO(); 134 ScheduleUpdatePrefsOnIO();
168 } 135 }
169 136
170 const net::AlternateProtocolMap& 137 const net::AlternateProtocolMap&
171 HttpServerPropertiesManager::alternate_protocol_map() const { 138 HttpServerPropertiesManager::alternate_protocol_map() const {
172 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 139 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
173 return http_server_properties_impl_->alternate_protocol_map(); 140 return http_server_properties_impl_->alternate_protocol_map();
174 } 141 }
175 142
176 // 143 const spdy::SpdySettings&
177 // Update spdy_servers (the cached data) with data from preferences. 144 HttpServerPropertiesManager::GetSpdySettings(
178 // 145 const net::HostPortPair& host_port_pair) const {
179 void HttpServerPropertiesManager::ScheduleUpdateSpdyCacheOnUI() { 146 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
147 return http_server_properties_impl_->GetSpdySettings(host_port_pair);
148 }
149
150 // Saves settings for a host.
151 bool HttpServerPropertiesManager::SetSpdySettings(
152 const net::HostPortPair& host_port_pair,
153 const spdy::SpdySettings& settings) {
154 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
155 bool persist = http_server_properties_impl_->SetSpdySettings(
156 host_port_pair, settings);
157 if (persist)
158 ScheduleUpdatePrefsOnIO();
159 return persist;
160 }
161
162 void HttpServerPropertiesManager::ClearSpdySettings() {
163 http_server_properties_impl_->ClearSpdySettings();
164 ScheduleUpdatePrefsOnIO();
165 }
166
167 const net::SpdySettingsMap&
168 HttpServerPropertiesManager::spdy_settings_map() const {
169 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
170 return http_server_properties_impl_->spdy_settings_map();
171 }
172
173 //
174 // Update the HttpServerPropertiesImpl's cache with data from preferences.
175 //
176 void HttpServerPropertiesManager::ScheduleUpdateCacheOnUI() {
180 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 177 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
181 // Cancel pending updates, if any. 178 // Cancel pending updates, if any.
182 ui_spdy_cache_update_timer_->Stop(); 179 ui_cache_update_timer_->Stop();
183 StartSpdyCacheUpdateTimerOnUI( 180 StartCacheUpdateTimerOnUI(
184 base::TimeDelta::FromMilliseconds(kUpdateCacheDelayMs)); 181 base::TimeDelta::FromMilliseconds(kUpdateCacheDelayMs));
185 } 182 }
186 183
187 void HttpServerPropertiesManager::UpdateSpdyCacheFromPrefs() { 184 void HttpServerPropertiesManager::StartCacheUpdateTimerOnUI(
185 base::TimeDelta delay) {
188 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 186 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
189 187 ui_cache_update_timer_->Start(
190 if (!pref_service_->HasPrefPath(prefs::kSpdyServers)) 188 FROM_HERE, delay, this,
189 &HttpServerPropertiesManager::UpdateCacheFromPrefsOnUI);
190 }
191
192 void HttpServerPropertiesManager::UpdateCacheFromPrefsOnUI() {
193 // The preferences can only be read on the UI thread.
194 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
195
196 if (!pref_service_->HasPrefPath(prefs::kHttpServerProperties))
191 return; 197 return;
192 198
193 // The preferences can only be read on the UI thread. 199 // String is host/port pair of spdy server.
194 StringVector* spdy_servers = 200 StringVector* spdy_servers = new StringVector;
195 ListValueToStringVector(pref_service_->GetList(prefs::kSpdyServers)); 201
196 202 // Parse the preferences into a SpdySettingsMap.
197 BrowserThread::PostTask( 203 net::SpdySettingsMap spdy_settings_map;
198 BrowserThread::IO,
199 FROM_HERE,
200 base::Bind(&HttpServerPropertiesManager::UpdateSpdyCacheFromPrefsOnIO,
201 base::Unretained(this), spdy_servers, true));
202 }
203
204 void HttpServerPropertiesManager::UpdateSpdyCacheFromPrefsOnIO(
205 StringVector* spdy_servers,
206 bool support_spdy) {
207 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
208 // Preferences have the master data because admins might have pushed new
209 // preferences. Clear the cached data and use the new spdy server list from
210 // preferences.
211 scoped_ptr<StringVector> scoped_spdy_servers(spdy_servers);
212 http_server_properties_impl_->InitializeSpdyServers(spdy_servers,
213 support_spdy);
214 }
215
216 //
217 // Update Preferences with data from spdy_servers (the cached data).
218 //
219 void HttpServerPropertiesManager::ScheduleUpdateSpdyPrefsOnIO() {
220 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
221 // Cancel pending updates, if any.
222 io_spdy_prefs_update_timer_->Stop();
223 StartSpdyPrefsUpdateTimerOnIO(
224 base::TimeDelta::FromMilliseconds(kUpdatePrefsDelayMs));
225 }
226
227 void HttpServerPropertiesManager::UpdateSpdyPrefsFromCache() {
228 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
229
230 scoped_refptr<RefCountedListValue> spdy_server_list =
231 new RefCountedListValue();
232 http_server_properties_impl_->GetSpdyServerList(&spdy_server_list->data);
233
234 // Update the preferences on the UI thread.
235 BrowserThread::PostTask(
236 BrowserThread::UI,
237 FROM_HERE,
238 base::Bind(&HttpServerPropertiesManager::SetSpdyServersInPrefsOnUI,
239 ui_weak_ptr_, spdy_server_list));
240 }
241
242 void HttpServerPropertiesManager::SetSpdyServersInPrefsOnUI(
243 scoped_refptr<RefCountedListValue> spdy_server_list) {
244 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
245 setting_spdy_servers_ = true;
246 pref_service_->Set(prefs::kSpdyServers, spdy_server_list->data);
247 setting_spdy_servers_ = false;
248 }
249
250 void HttpServerPropertiesManager::ScheduleUpdateAlternateProtocolCacheOnUI() {
251 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
252 // Cancel pending updates, if any.
253 ui_alternate_protocol_cache_update_timer_->Stop();
254 StartAlternateProtocolCacheUpdateTimerOnUI(
255 base::TimeDelta::FromMilliseconds(kUpdateCacheDelayMs));
256 }
257
258 void HttpServerPropertiesManager::UpdateAlternateProtocolCacheFromPrefs() {
259 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
260
261 if (!pref_service_->HasPrefPath(prefs::kAlternateProtocolServers))
262 return;
263 204
264 // Parse the preferences into a AlternateProtocolMap. 205 // Parse the preferences into a AlternateProtocolMap.
265 net::AlternateProtocolMap alternate_protocol_map; 206 net::AlternateProtocolMap alternate_protocol_map;
266 const base::DictionaryValue& alternate_protocol_servers = 207
267 *pref_service_->GetDictionary(prefs::kAlternateProtocolServers); 208 const base::DictionaryValue& http_server_properties_dict =
209 *pref_service_->GetDictionary(prefs::kHttpServerProperties);
268 for (base::DictionaryValue::key_iterator it = 210 for (base::DictionaryValue::key_iterator it =
269 alternate_protocol_servers.begin_keys(); 211 http_server_properties_dict.begin_keys();
270 it != alternate_protocol_servers.end_keys(); ++it) { 212 it != http_server_properties_dict.end_keys(); ++it) {
213 // Get server's host/pair.
271 const std::string& server_str = *it; 214 const std::string& server_str = *it;
272 net::HostPortPair server = net::HostPortPair::FromString(server_str); 215 net::HostPortPair server = net::HostPortPair::FromString(server_str);
273 if (server.host().empty()) { 216 if (server.host().empty()) {
274 VLOG(1) << "Malformed Alternate-Protocol server: " << server_str; 217 VLOG(1) << "Malformed http_server_properties for server: " << server_str;
275 NOTREACHED(); 218 NOTREACHED();
276 continue; 219 continue;
277 } 220 }
278 DCHECK(!ContainsKey(alternate_protocol_map, server)); 221
279 222 base::DictionaryValue* server_pref_dict = NULL;
280 base::DictionaryValue* port_alternate_protocol_dict = NULL; 223 if (!http_server_properties_dict.GetDictionaryWithoutPathExpansion(
281 if (!alternate_protocol_servers.GetDictionaryWithoutPathExpansion( 224 server_str, &server_pref_dict)) {
282 server_str, &port_alternate_protocol_dict)) { 225 VLOG(1) << "Malformed http_server_properties server: " << server_str;
283 VLOG(1) << "Malformed Alternate-Protocol server: " << server_str;
284 NOTREACHED(); 226 NOTREACHED();
285 continue; 227 continue;
286 } 228 }
287 229
288 int port = 0; 230 // Get if server supports Spdy.
289 if (!port_alternate_protocol_dict->GetIntegerWithoutPathExpansion( 231 bool supports_spdy = false;
290 "port", &port) || (port > (1 << 16))) { 232 if ((server_pref_dict->GetBoolean(
291 VLOG(1) << "Malformed Alternate-Protocol server: " << server_str; 233 "supports_spdy", &supports_spdy)) && supports_spdy) {
292 NOTREACHED(); 234 spdy_servers->push_back(server_str);
235 }
236
237 // Get SpdySettings.
238 DCHECK(!ContainsKey(spdy_settings_map, server));
239 base::ListValue* spdy_settings_list = NULL;
240 if (server_pref_dict->GetListWithoutPathExpansion(
241 "settings", &spdy_settings_list)) {
242 spdy::SpdySettings spdy_settings;
243
244 for (base::ListValue::const_iterator list_it =
245 spdy_settings_list->begin();
246 list_it != spdy_settings_list->end(); ++list_it) {
247 if ((*list_it)->GetType() != Value::TYPE_DICTIONARY) {
248 VLOG(1) << "Malformed SpdySettingsList for server: " << server_str;
249 NOTREACHED();
250 continue;
251 }
252
253 const base::DictionaryValue* spdy_setting_dict =
254 static_cast<const base::DictionaryValue*>(*list_it);
255
256 int id = 0;
257 if (!spdy_setting_dict->GetIntegerWithoutPathExpansion("id", &id)) {
258 VLOG(1) << "Malformed id in SpdySettings for server: " << server_str;
259 NOTREACHED();
260 continue;
261 }
262
263 int value = 0;
264 if (!spdy_setting_dict->GetIntegerWithoutPathExpansion("value",
265 &value)) {
266 VLOG(1) << "Malformed value in SpdySettings for server: " <<
267 server_str;
268 NOTREACHED();
269 continue;
270 }
271
272 spdy::SettingsFlagsAndId flags_and_id(0);
273 flags_and_id.set_id(id);
274 flags_and_id.set_flags(spdy::SETTINGS_FLAG_PERSISTED);
275
276 spdy_settings.push_back(spdy::SpdySetting(flags_and_id, value));
277 }
278
279 spdy_settings_map[server] = spdy_settings;
280 }
281
282 // Get alternate_protocol server.
283 DCHECK(!ContainsKey(alternate_protocol_map, server));
284 base::DictionaryValue* port_alternate_protocol_dict = NULL;
285 if (!server_pref_dict->GetDictionaryWithoutPathExpansion(
286 "alternate_protocol", &port_alternate_protocol_dict)) {
293 continue; 287 continue;
294 } 288 }
295 int protocol = 0; 289
296 if (!port_alternate_protocol_dict->GetIntegerWithoutPathExpansion( 290 do {
297 "protocol", &protocol) || (protocol < 0) || 291 int port = 0;
298 (protocol > net::NUM_ALTERNATE_PROTOCOLS)) { 292 if (!port_alternate_protocol_dict->GetIntegerWithoutPathExpansion(
299 VLOG(1) << "Malformed Alternate-Protocol server: " << server_str; 293 "port", &port) || (port > (1 << 16))) {
300 NOTREACHED(); 294 VLOG(1) << "Malformed Alternate-Protocol server: " << server_str;
301 continue; 295 NOTREACHED();
302 } 296 continue;
303 297 }
304 net::PortAlternateProtocolPair port_alternate_protocol; 298 int protocol = 0;
305 port_alternate_protocol.port = port; 299 if (!port_alternate_protocol_dict->GetIntegerWithoutPathExpansion(
306 port_alternate_protocol.protocol = static_cast<net::AlternateProtocol>( 300 "protocol", &protocol) || (protocol < 0) ||
307 protocol); 301 (protocol > net::NUM_ALTERNATE_PROTOCOLS)) {
308 302 VLOG(1) << "Malformed Alternate-Protocol server: " << server_str;
309 alternate_protocol_map[server] = port_alternate_protocol; 303 NOTREACHED();
304 continue;
305 }
306
307 net::PortAlternateProtocolPair port_alternate_protocol;
308 port_alternate_protocol.port = port;
309 port_alternate_protocol.protocol = static_cast<net::AlternateProtocol>(
310 protocol);
311
312 alternate_protocol_map[server] = port_alternate_protocol;
313 } while (false);
310 } 314 }
311 315
312 scoped_refptr<RefCountedAlternateProtocolMap> alternate_protocol_map_arg = 316 scoped_refptr<RefCountedAlternateProtocolMap> alternate_protocol_map_arg =
313 new RefCountedAlternateProtocolMap; 317 new RefCountedAlternateProtocolMap;
314 alternate_protocol_map_arg->data.swap(alternate_protocol_map); 318 alternate_protocol_map_arg->data.swap(alternate_protocol_map);
315 319
320 scoped_refptr<RefCountedSpdySettingsMap> spdy_settings_map_arg =
321 new RefCountedSpdySettingsMap;
322 spdy_settings_map_arg->data.swap(spdy_settings_map);
323
316 BrowserThread::PostTask( 324 BrowserThread::PostTask(
317 BrowserThread::IO, 325 BrowserThread::IO,
318 FROM_HERE, 326 FROM_HERE,
319 base::Bind(&HttpServerPropertiesManager:: 327 base::Bind(&HttpServerPropertiesManager::
320 UpdateAlternateProtocolCacheFromPrefsOnIO, 328 UpdateCacheFromPrefsOnIO,
321 base::Unretained(this), alternate_protocol_map_arg)); 329 base::Unretained(this),
322 } 330 spdy_servers,
323 331 spdy_settings_map_arg,
324 void HttpServerPropertiesManager::UpdateAlternateProtocolCacheFromPrefsOnIO( 332 alternate_protocol_map_arg));
325 RefCountedAlternateProtocolMap* alternate_protocol_map) { 333 }
326 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 334
335 void HttpServerPropertiesManager::UpdateCacheFromPrefsOnIO(
336 StringVector* spdy_servers,
337 RefCountedSpdySettingsMap* spdy_settings_map,
338 RefCountedAlternateProtocolMap* alternate_protocol_map) {
327 // Preferences have the master data because admins might have pushed new 339 // Preferences have the master data because admins might have pushed new
328 // preferences. Clear the cached data and use the new spdy server list from 340 // preferences. Update the cached data with new data from preferences.
341 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
342
343 // Clear the cached data and use the new spdy_servers list from preferences.
344 scoped_ptr<StringVector> scoped_spdy_servers(spdy_servers);
345 http_server_properties_impl_->InitializeSpdyServers(spdy_servers, true);
346
347 // Clear the cached data and use the new spdy_settings from preferences.
348 http_server_properties_impl_->InitializeSpdySettingsServers(
349 &spdy_settings_map->data);
350
351 // Clear the cached data and use the new Alternate-Protocol server list from
329 // preferences. 352 // preferences.
330 http_server_properties_impl_->InitializeAlternateProtocolServers( 353 http_server_properties_impl_->InitializeAlternateProtocolServers(
331 &alternate_protocol_map->data); 354 &alternate_protocol_map->data);
332 } 355 }
333 356
334 // 357
335 // Update Preferences with data from alternate_protocol_servers (the cached 358 //
336 // data). 359 // Update Preferences with data from the cached data.
337 // 360 //
338 void HttpServerPropertiesManager::ScheduleUpdateAlternateProtocolPrefsOnIO() { 361 void HttpServerPropertiesManager::ScheduleUpdatePrefsOnIO() {
339 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 362 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
340 // Cancel pending updates, if any. 363 // Cancel pending updates, if any.
341 io_alternate_protocol_prefs_update_timer_->Stop(); 364 io_spdy_prefs_update_timer_->Stop();
342 StartAlternateProtocolPrefsUpdateTimerOnIO( 365 StartPrefsUpdateTimerOnIO(
343 base::TimeDelta::FromMilliseconds(kUpdatePrefsDelayMs)); 366 base::TimeDelta::FromMilliseconds(kUpdatePrefsDelayMs));
344 } 367 }
345 368
346 void HttpServerPropertiesManager::UpdateAlternateProtocolPrefsFromCache() { 369 void HttpServerPropertiesManager::StartPrefsUpdateTimerOnIO(
347 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 370 base::TimeDelta delay) {
371 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
372 // This is overridden in tests to post the task without the delay.
373 io_spdy_prefs_update_timer_->Start(
374 FROM_HERE, delay, this,
375 &HttpServerPropertiesManager::UpdatePrefsFromCacheOnIO);
376 }
377
378 void HttpServerPropertiesManager::UpdatePrefsFromCacheOnIO() {
379 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
380
381 scoped_refptr<RefCountedListValue> spdy_server_list =
382 new RefCountedListValue();
383 http_server_properties_impl_->GetSpdyServerList(&spdy_server_list->data);
384
385 scoped_refptr<RefCountedSpdySettingsMap> spdy_settings_map =
386 new RefCountedSpdySettingsMap;
387 spdy_settings_map->data =
388 http_server_properties_impl_->spdy_settings_map();
348 389
349 scoped_refptr<RefCountedAlternateProtocolMap> alternate_protocol_map = 390 scoped_refptr<RefCountedAlternateProtocolMap> alternate_protocol_map =
350 new RefCountedAlternateProtocolMap; 391 new RefCountedAlternateProtocolMap;
351 alternate_protocol_map->data = 392 alternate_protocol_map->data =
352 http_server_properties_impl_->alternate_protocol_map(); 393 http_server_properties_impl_->alternate_protocol_map();
353 394
354 // Update the preferences on the UI thread. 395 // Update the preferences on the UI thread.
355 BrowserThread::PostTask( 396 BrowserThread::PostTask(
356 BrowserThread::UI, 397 BrowserThread::UI,
357 FROM_HERE, 398 FROM_HERE,
358 base::Bind(&HttpServerPropertiesManager:: 399 base::Bind(&HttpServerPropertiesManager::UpdatePrefsOnUI,
359 SetAlternateProtocolServersInPrefsOnUI, 400 ui_weak_ptr_, spdy_server_list, spdy_settings_map,
360 ui_weak_ptr_, alternate_protocol_map)); 401 alternate_protocol_map));
361 } 402 }
362 403
363 void HttpServerPropertiesManager::SetAlternateProtocolServersInPrefsOnUI( 404 // A local or temporary data structure to hold supports_spdy, SpdySettings and
405 // PortAlternateProtocolPair preferences for a server. This is used only in
406 // UpdatePrefsOnUI.
407 struct ServerPref {
408 ServerPref()
409 : supports_spdy(false),
410 settings(NULL),
411 alternate_protocol(NULL) {
412 }
413 ServerPref(bool supports_spdy,
414 const spdy::SpdySettings* settings,
415 const net::PortAlternateProtocolPair* alternate_protocol)
416 : supports_spdy(supports_spdy),
417 settings(settings),
418 alternate_protocol(alternate_protocol) {
419 }
420 bool supports_spdy;
421 const spdy::SpdySettings* settings;
422 const net::PortAlternateProtocolPair* alternate_protocol;
423 };
424
425 void HttpServerPropertiesManager::UpdatePrefsOnUI(
426 scoped_refptr<RefCountedListValue> spdy_server_list,
427 RefCountedSpdySettingsMap* spdy_settings_map,
364 RefCountedAlternateProtocolMap* alternate_protocol_map) { 428 RefCountedAlternateProtocolMap* alternate_protocol_map) {
429
430 typedef std::map<net::HostPortPair, ServerPref> ServerPrefMap;
431 ServerPrefMap server_pref_map;
432
365 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 433 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
366 base::DictionaryValue alternate_protocol_dict; 434
367 for (net::AlternateProtocolMap::const_iterator it = 435 // Add servers that support spdy to server_pref_map.
436 std::string s;
437 for (base::ListValue::const_iterator list_it = spdy_server_list->data.begin();
438 list_it != spdy_server_list->data.end(); ++list_it) {
439 if ((*list_it)->GetAsString(&s)) {
440 net::HostPortPair server = net::HostPortPair::FromString(s);
441
442 ServerPrefMap::iterator it = server_pref_map.find(server);
443 if (it == server_pref_map.end()) {
444 ServerPref server_pref(true, NULL, NULL);
445 server_pref_map[server] = server_pref;
446 } else {
447 it->second.supports_spdy = true;
448 }
449 }
450 }
451
452 // Add servers that have SpdySettings to server_pref_map.
453 for (net::SpdySettingsMap::iterator map_it =
454 spdy_settings_map->data.begin();
455 map_it != spdy_settings_map->data.end(); ++map_it) {
456 const net::HostPortPair& server = map_it->first;
457
458 ServerPrefMap::iterator it = server_pref_map.find(server);
459 if (it == server_pref_map.end()) {
460 ServerPref server_pref(false, &map_it->second, NULL);
461 server_pref_map[server] = server_pref;
462 } else {
463 it->second.settings = &map_it->second;
464 }
465 }
466
467 // Add AlternateProtocol servers to server_pref_map.
468 for (net::AlternateProtocolMap::const_iterator map_it =
368 alternate_protocol_map->data.begin(); 469 alternate_protocol_map->data.begin();
369 it != alternate_protocol_map->data.end(); ++it) { 470 map_it != alternate_protocol_map->data.end(); ++map_it) {
370 const net::HostPortPair& server = it->first; 471 const net::HostPortPair& server = map_it->first;
371 const net::PortAlternateProtocolPair& port_alternate_protocol = 472 const net::PortAlternateProtocolPair& port_alternate_protocol =
372 it->second; 473 map_it->second;
373 if (port_alternate_protocol.protocol < 0 || 474 if (port_alternate_protocol.protocol < 0 ||
374 port_alternate_protocol.protocol >= net::NUM_ALTERNATE_PROTOCOLS) { 475 port_alternate_protocol.protocol >= net::NUM_ALTERNATE_PROTOCOLS) {
375 continue; 476 continue;
376 } 477 }
377 base::DictionaryValue* port_alternate_protocol_dict = 478
378 new base::DictionaryValue; 479 ServerPrefMap::iterator it = server_pref_map.find(server);
379 port_alternate_protocol_dict->SetInteger( 480 if (it == server_pref_map.end()) {
380 "port", port_alternate_protocol.port); 481 ServerPref server_pref(false, NULL, &map_it->second);
381 port_alternate_protocol_dict->SetInteger( 482 server_pref_map[server] = server_pref;
382 "protocol", port_alternate_protocol.protocol); 483 } else {
383 alternate_protocol_dict.SetWithoutPathExpansion( 484 it->second.alternate_protocol = &map_it->second;
384 server.ToString(), port_alternate_protocol_dict); 485 }
385 } 486 }
386 setting_alternate_protocol_servers_ = true;
387 pref_service_->Set(prefs::kAlternateProtocolServers,
388 alternate_protocol_dict);
389 setting_alternate_protocol_servers_ = false;
390 }
391 487
392 void HttpServerPropertiesManager::StartSpdyCacheUpdateTimerOnUI( 488 // Persist the prefs::kHttpServerProperties.
393 base::TimeDelta delay) { 489 base::DictionaryValue http_server_properties_dict;
394 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 490 for (ServerPrefMap::const_iterator map_it =
395 ui_spdy_cache_update_timer_->Start( 491 server_pref_map.begin();
396 FROM_HERE, delay, this, 492 map_it != server_pref_map.end(); ++map_it) {
397 &HttpServerPropertiesManager::UpdateSpdyCacheFromPrefs); 493 const net::HostPortPair& server = map_it->first;
398 } 494 const ServerPref& server_pref = map_it->second;
399 495
400 void HttpServerPropertiesManager::StartSpdyPrefsUpdateTimerOnIO( 496 base::DictionaryValue* server_pref_dict = new base::DictionaryValue;
401 base::TimeDelta delay) {
402 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
403 // This is overridden in tests to post the task without the delay.
404 io_spdy_prefs_update_timer_->Start(
405 FROM_HERE, delay, this,
406 &HttpServerPropertiesManager::UpdateSpdyPrefsFromCache);
407 }
408 497
409 void HttpServerPropertiesManager::StartAlternateProtocolCacheUpdateTimerOnUI( 498 // Save supports_spdy.
410 base::TimeDelta delay) { 499 server_pref_dict->SetBoolean("supports_spdy", server_pref.supports_spdy);
411 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
412 ui_alternate_protocol_cache_update_timer_->Start(
413 FROM_HERE, delay, this,
414 &HttpServerPropertiesManager::UpdateAlternateProtocolCacheFromPrefs);
415 }
416 500
417 void HttpServerPropertiesManager::StartAlternateProtocolPrefsUpdateTimerOnIO( 501 // Save SpdySettings.
418 base::TimeDelta delay) { 502 if (server_pref.settings) {
419 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 503 base::ListValue* spdy_settings_list = new ListValue();
420 // This is overridden in tests to post the task without the delay. 504 for (spdy::SpdySettings::const_iterator it =
421 io_alternate_protocol_prefs_update_timer_->Start( 505 server_pref.settings->begin();
422 FROM_HERE, delay, this, 506 it != server_pref.settings->end(); ++it) {
423 &HttpServerPropertiesManager::UpdateAlternateProtocolPrefsFromCache); 507 uint32 id = it->first.id();
508 uint32 value = it->second;
509 base::DictionaryValue* spdy_setting_dict = new base::DictionaryValue;
510 spdy_setting_dict->SetInteger("id", id);
511 spdy_setting_dict->SetInteger("value", value);
512 spdy_settings_list->Append(spdy_setting_dict);
513 }
514 server_pref_dict->Set("settings", spdy_settings_list);
515 }
516
517 // Save alternate_protocol.
518 if (server_pref.alternate_protocol) {
519 base::DictionaryValue* port_alternate_protocol_dict =
520 new base::DictionaryValue;
521 const net::PortAlternateProtocolPair* port_alternate_protocol =
522 server_pref.alternate_protocol;
523 port_alternate_protocol_dict->SetInteger(
524 "port", port_alternate_protocol->port);
525 port_alternate_protocol_dict->SetInteger(
526 "protocol", port_alternate_protocol->protocol);
527 server_pref_dict->SetWithoutPathExpansion(
528 "alternate_protocol", port_alternate_protocol_dict);
529 }
530 http_server_properties_dict.SetWithoutPathExpansion(
531 server.ToString(), server_pref_dict);
532 }
533
534 setting_prefs_ = true;
535 pref_service_->Set(prefs::kHttpServerProperties,
536 http_server_properties_dict);
537 setting_prefs_ = false;
424 } 538 }
425 539
426 void HttpServerPropertiesManager::Observe( 540 void HttpServerPropertiesManager::Observe(
427 int type, 541 int type,
428 const content::NotificationSource& source, 542 const content::NotificationSource& source,
429 const content::NotificationDetails& details) { 543 const content::NotificationDetails& details) {
430 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 544 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
431 DCHECK(type == chrome::NOTIFICATION_PREF_CHANGED); 545 DCHECK(type == chrome::NOTIFICATION_PREF_CHANGED);
432 PrefService* prefs = content::Source<PrefService>(source).ptr(); 546 PrefService* prefs = content::Source<PrefService>(source).ptr();
433 DCHECK(prefs == pref_service_); 547 DCHECK(prefs == pref_service_);
434 std::string* pref_name = content::Details<std::string>(details).ptr(); 548 std::string* pref_name = content::Details<std::string>(details).ptr();
435 if (*pref_name == prefs::kSpdyServers) { 549 if (*pref_name == prefs::kHttpServerProperties) {
436 if (!setting_spdy_servers_) 550 if (!setting_prefs_)
437 ScheduleUpdateSpdyCacheOnUI(); 551 ScheduleUpdateCacheOnUI();
438 } else if (*pref_name == prefs::kAlternateProtocolServers) {
439 if (!setting_alternate_protocol_servers_)
440 ScheduleUpdateAlternateProtocolCacheOnUI();
441 } else { 552 } else {
442 NOTREACHED(); 553 NOTREACHED();
443 } 554 }
444 } 555 }
445 556
446 } // namespace chrome_browser_net 557 } // namespace chrome_browser_net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698