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

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"
11 #include "chrome/common/pref_names.h" 11 #include "chrome/common/pref_names.h"
12 #include "content/public/browser/browser_thread.h" 12 #include "content/public/browser/browser_thread.h"
13 #include "content/public/browser/notification_details.h" 13 #include "content/public/browser/notification_details.h"
14 #include "content/public/browser/notification_source.h" 14 #include "content/public/browser/notification_source.h"
15 15
16 using content::BrowserThread; 16 using content::BrowserThread;
17 17
18 namespace chrome_browser_net { 18 namespace chrome_browser_net {
19 19
20 namespace { 20 namespace {
21 21
22 // Time to wait before starting an update the spdy_servers_table_ cache from 22 // Time to wait before starting an update the http_server_properties_impl_ cache
23 // preferences. Scheduling another update during this period will reset the 23 // from preferences. Scheduling another update during this period will reset the
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 // http_server_properties_impl_ cache. Scheduling another update during this
29 // reset the timer. 29 // period will 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
143 const spdy::SpdySettings&
144 HttpServerPropertiesManager::GetSpdySettings(
145 const net::HostPortPair& host_port_pair) const {
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() {
willchan no longer on Chromium 2011/11/15 15:44:21 DCHECK(BrowserThread...)?
ramant (doing other things) 2011/11/15 16:43:46 Done.
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
176 // 173 //
177 // Update spdy_servers (the cached data) with data from preferences. 174 // Update the HttpServerPropertiesImpl's cache with data from preferences.
178 // 175 //
179 void HttpServerPropertiesManager::ScheduleUpdateSpdyCacheOnUI() { 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
202 // Parse the preferences into a SpdySettingsMap.
203 net::SpdySettingsMap* spdy_settings_map = new net::SpdySettingsMap;
204
205 // Parse the preferences into a AlternateProtocolMap.
206 net::AlternateProtocolMap* alternate_protocol_map =
207 new net::AlternateProtocolMap;
208
209 const base::DictionaryValue& http_server_properties_dict =
210 *pref_service_->GetDictionary(prefs::kHttpServerProperties);
211 for (base::DictionaryValue::key_iterator it =
212 http_server_properties_dict.begin_keys();
213 it != http_server_properties_dict.end_keys(); ++it) {
214 // Get server's host/pair.
215 const std::string& server_str = *it;
216 net::HostPortPair server = net::HostPortPair::FromString(server_str);
217 if (server.host().empty()) {
218 VLOG(1) << "Malformed http_server_properties for server: " << server_str;
willchan no longer on Chromium 2011/11/15 15:44:21 There's been a lot of cracking down on LOGs. Can y
ramant (doing other things) 2011/11/15 16:43:46 Done.
219 NOTREACHED();
220 continue;
221 }
222
223 base::DictionaryValue* server_pref_dict = NULL;
224 if (!http_server_properties_dict.GetDictionaryWithoutPathExpansion(
225 server_str, &server_pref_dict)) {
226 VLOG(1) << "Malformed http_server_properties server: " << server_str;
227 NOTREACHED();
228 continue;
229 }
230
231 // Get if server supports Spdy.
232 bool supports_spdy = false;
233 if ((server_pref_dict->GetBoolean(
234 "supports_spdy", &supports_spdy)) && supports_spdy) {
235 spdy_servers->push_back(server_str);
236 }
237
238 // Get SpdySettings.
239 DCHECK(!ContainsKey(*spdy_settings_map, server));
240 base::ListValue* spdy_settings_list = NULL;
241 if (server_pref_dict->GetListWithoutPathExpansion(
242 "settings", &spdy_settings_list)) {
243 spdy::SpdySettings spdy_settings;
244
245 for (base::ListValue::const_iterator list_it =
246 spdy_settings_list->begin();
247 list_it != spdy_settings_list->end(); ++list_it) {
248 if ((*list_it)->GetType() != Value::TYPE_DICTIONARY) {
249 VLOG(1) << "Malformed SpdySettingsList for server: " << server_str;
250 NOTREACHED();
251 continue;
252 }
253
254 const base::DictionaryValue* spdy_setting_dict =
255 static_cast<const base::DictionaryValue*>(*list_it);
256
257 int id = 0;
258 if (!spdy_setting_dict->GetIntegerWithoutPathExpansion("id", &id)) {
259 VLOG(1) << "Malformed id in SpdySettings for server: " << server_str;
260 NOTREACHED();
261 continue;
262 }
263
264 int value = 0;
265 if (!spdy_setting_dict->GetIntegerWithoutPathExpansion("value",
266 &value)) {
267 VLOG(1) << "Malformed value in SpdySettings for server: " <<
268 server_str;
269 NOTREACHED();
270 continue;
271 }
272
273 spdy::SettingsFlagsAndId flags_and_id(0);
274 flags_and_id.set_id(id);
275 flags_and_id.set_flags(spdy::SETTINGS_FLAG_PERSISTED);
276
277 spdy_settings.push_back(spdy::SpdySetting(flags_and_id, value));
278 }
279
280 (*spdy_settings_map)[server] = spdy_settings;
281 }
282
283 // Get alternate_protocol server.
284 DCHECK(!ContainsKey(*alternate_protocol_map, server));
285 base::DictionaryValue* port_alternate_protocol_dict = NULL;
286 if (!server_pref_dict->GetDictionaryWithoutPathExpansion(
287 "alternate_protocol", &port_alternate_protocol_dict)) {
288 continue;
289 }
290
291 do {
292 int port = 0;
293 if (!port_alternate_protocol_dict->GetIntegerWithoutPathExpansion(
294 "port", &port) || (port > (1 << 16))) {
295 VLOG(1) << "Malformed Alternate-Protocol server: " << server_str;
296 NOTREACHED();
297 continue;
298 }
299 int protocol = 0;
300 if (!port_alternate_protocol_dict->GetIntegerWithoutPathExpansion(
301 "protocol", &protocol) || (protocol < 0) ||
302 (protocol > net::NUM_ALTERNATE_PROTOCOLS)) {
303 VLOG(1) << "Malformed Alternate-Protocol server: " << server_str;
304 NOTREACHED();
305 continue;
306 }
307
308 net::PortAlternateProtocolPair port_alternate_protocol;
309 port_alternate_protocol.port = port;
310 port_alternate_protocol.protocol = static_cast<net::AlternateProtocol>(
311 protocol);
312
313 (*alternate_protocol_map)[server] = port_alternate_protocol;
314 } while (false);
315 }
196 316
197 BrowserThread::PostTask( 317 BrowserThread::PostTask(
198 BrowserThread::IO, 318 BrowserThread::IO,
199 FROM_HERE, 319 FROM_HERE,
200 base::Bind(&HttpServerPropertiesManager::UpdateSpdyCacheFromPrefsOnIO, 320 base::Bind(&HttpServerPropertiesManager::
201 base::Unretained(this), spdy_servers, true)); 321 UpdateCacheFromPrefsOnIO,
202 } 322 base::Unretained(this),
203 323 base::Owned(spdy_servers),
204 void HttpServerPropertiesManager::UpdateSpdyCacheFromPrefsOnIO( 324 base::Owned(spdy_settings_map),
325 base::Owned(alternate_protocol_map)));
326 }
327
328 void HttpServerPropertiesManager::UpdateCacheFromPrefsOnIO(
205 StringVector* spdy_servers, 329 StringVector* spdy_servers,
206 bool support_spdy) { 330 net::SpdySettingsMap* spdy_settings_map,
207 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 331 net::AlternateProtocolMap* alternate_protocol_map) {
208 // Preferences have the master data because admins might have pushed new 332 // 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 333 // preferences. Update the cached data with new data from preferences.
334 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
335
336 http_server_properties_impl_->InitializeSpdyServers(spdy_servers, true);
337
338 // Clear the cached data and use the new spdy_settings from preferences.
339 http_server_properties_impl_->InitializeSpdySettingsServers(
340 spdy_settings_map);
341
342 // Clear the cached data and use the new Alternate-Protocol server list from
210 // preferences. 343 // preferences.
211 scoped_ptr<StringVector> scoped_spdy_servers(spdy_servers); 344 http_server_properties_impl_->InitializeAlternateProtocolServers(
212 http_server_properties_impl_->InitializeSpdyServers(spdy_servers, 345 alternate_protocol_map);
213 support_spdy); 346 }
214 } 347
215 348
216 // 349 //
217 // Update Preferences with data from spdy_servers (the cached data). 350 // Update Preferences with data from the cached data.
218 // 351 //
219 void HttpServerPropertiesManager::ScheduleUpdateSpdyPrefsOnIO() { 352 void HttpServerPropertiesManager::ScheduleUpdatePrefsOnIO() {
220 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 353 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
221 // Cancel pending updates, if any. 354 // Cancel pending updates, if any.
222 io_spdy_prefs_update_timer_->Stop(); 355 io_spdy_prefs_update_timer_->Stop();
223 StartSpdyPrefsUpdateTimerOnIO( 356 StartPrefsUpdateTimerOnIO(
224 base::TimeDelta::FromMilliseconds(kUpdatePrefsDelayMs)); 357 base::TimeDelta::FromMilliseconds(kUpdatePrefsDelayMs));
225 } 358 }
226 359
227 void HttpServerPropertiesManager::UpdateSpdyPrefsFromCache() { 360 void HttpServerPropertiesManager::StartPrefsUpdateTimerOnIO(
228 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 361 base::TimeDelta delay) {
229 362 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
230 scoped_refptr<RefCountedListValue> spdy_server_list = 363 // This is overridden in tests to post the task without the delay.
231 new RefCountedListValue(); 364 io_spdy_prefs_update_timer_->Start(
232 http_server_properties_impl_->GetSpdyServerList(&spdy_server_list->data); 365 FROM_HERE, delay, this,
366 &HttpServerPropertiesManager::UpdatePrefsFromCacheOnIO);
367 }
368
369 void HttpServerPropertiesManager::UpdatePrefsFromCacheOnIO() {
370 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
371
372 base::ListValue* spdy_server_list = new base::ListValue;
373 http_server_properties_impl_->GetSpdyServerList(spdy_server_list);
374
375 net::SpdySettingsMap* spdy_settings_map = new net::SpdySettingsMap;
376 *spdy_settings_map = http_server_properties_impl_->spdy_settings_map();
377
378 net::AlternateProtocolMap* alternate_protocol_map =
379 new net::AlternateProtocolMap;
380 *alternate_protocol_map =
381 http_server_properties_impl_->alternate_protocol_map();
233 382
234 // Update the preferences on the UI thread. 383 // Update the preferences on the UI thread.
235 BrowserThread::PostTask( 384 BrowserThread::PostTask(
236 BrowserThread::UI, 385 BrowserThread::UI,
237 FROM_HERE, 386 FROM_HERE,
238 base::Bind(&HttpServerPropertiesManager::SetSpdyServersInPrefsOnUI, 387 base::Bind(&HttpServerPropertiesManager::UpdatePrefsOnUI,
239 ui_weak_ptr_, spdy_server_list)); 388 ui_weak_ptr_,
240 } 389 base::Owned(spdy_server_list),
241 390 base::Owned(spdy_settings_map),
242 void HttpServerPropertiesManager::SetSpdyServersInPrefsOnUI( 391 base::Owned(alternate_protocol_map)));
243 scoped_refptr<RefCountedListValue> spdy_server_list) { 392 }
393
394 // A local or temporary data structure to hold supports_spdy, SpdySettings and
395 // PortAlternateProtocolPair preferences for a server. This is used only in
396 // UpdatePrefsOnUI.
397 struct ServerPref {
398 ServerPref()
399 : supports_spdy(false),
400 settings(NULL),
401 alternate_protocol(NULL) {
402 }
403 ServerPref(bool supports_spdy,
404 const spdy::SpdySettings* settings,
405 const net::PortAlternateProtocolPair* alternate_protocol)
406 : supports_spdy(supports_spdy),
407 settings(settings),
408 alternate_protocol(alternate_protocol) {
409 }
410 bool supports_spdy;
411 const spdy::SpdySettings* settings;
412 const net::PortAlternateProtocolPair* alternate_protocol;
413 };
414
415 void HttpServerPropertiesManager::UpdatePrefsOnUI(
416 base::ListValue* spdy_server_list,
417 net::SpdySettingsMap* spdy_settings_map,
418 net::AlternateProtocolMap* alternate_protocol_map) {
419
420 typedef std::map<net::HostPortPair, ServerPref> ServerPrefMap;
421 ServerPrefMap server_pref_map;
422
244 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 423 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
245 setting_spdy_servers_ = true; 424
246 pref_service_->Set(prefs::kSpdyServers, spdy_server_list->data); 425 // Add servers that support spdy to server_pref_map.
247 setting_spdy_servers_ = false; 426 std::string s;
248 } 427 for (base::ListValue::const_iterator list_it = spdy_server_list->begin();
249 428 list_it != spdy_server_list->end(); ++list_it) {
250 void HttpServerPropertiesManager::ScheduleUpdateAlternateProtocolCacheOnUI() { 429 if ((*list_it)->GetAsString(&s)) {
251 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 430 net::HostPortPair server = net::HostPortPair::FromString(s);
252 // Cancel pending updates, if any. 431
253 ui_alternate_protocol_cache_update_timer_->Stop(); 432 ServerPrefMap::iterator it = server_pref_map.find(server);
254 StartAlternateProtocolCacheUpdateTimerOnUI( 433 if (it == server_pref_map.end()) {
255 base::TimeDelta::FromMilliseconds(kUpdateCacheDelayMs)); 434 ServerPref server_pref(true, NULL, NULL);
256 } 435 server_pref_map[server] = server_pref;
257 436 } else {
258 void HttpServerPropertiesManager::UpdateAlternateProtocolCacheFromPrefs() { 437 it->second.supports_spdy = true;
259 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 438 }
260 439 }
261 if (!pref_service_->HasPrefPath(prefs::kAlternateProtocolServers)) 440 }
262 return; 441
263 442 // Add servers that have SpdySettings to server_pref_map.
264 // Parse the preferences into a AlternateProtocolMap. 443 for (net::SpdySettingsMap::iterator map_it =
265 net::AlternateProtocolMap alternate_protocol_map; 444 spdy_settings_map->begin();
266 const base::DictionaryValue& alternate_protocol_servers = 445 map_it != spdy_settings_map->end(); ++map_it) {
267 *pref_service_->GetDictionary(prefs::kAlternateProtocolServers); 446 const net::HostPortPair& server = map_it->first;
268 for (base::DictionaryValue::key_iterator it = 447
269 alternate_protocol_servers.begin_keys(); 448 ServerPrefMap::iterator it = server_pref_map.find(server);
270 it != alternate_protocol_servers.end_keys(); ++it) { 449 if (it == server_pref_map.end()) {
271 const std::string& server_str = *it; 450 ServerPref server_pref(false, &map_it->second, NULL);
272 net::HostPortPair server = net::HostPortPair::FromString(server_str); 451 server_pref_map[server] = server_pref;
273 if (server.host().empty()) { 452 } else {
274 VLOG(1) << "Malformed Alternate-Protocol server: " << server_str; 453 it->second.settings = &map_it->second;
275 NOTREACHED(); 454 }
276 continue; 455 }
277 } 456
278 DCHECK(!ContainsKey(alternate_protocol_map, server)); 457 // Add AlternateProtocol servers to server_pref_map.
279 458 for (net::AlternateProtocolMap::const_iterator map_it =
280 base::DictionaryValue* port_alternate_protocol_dict = NULL; 459 alternate_protocol_map->begin();
281 if (!alternate_protocol_servers.GetDictionaryWithoutPathExpansion( 460 map_it != alternate_protocol_map->end(); ++map_it) {
282 server_str, &port_alternate_protocol_dict)) { 461 const net::HostPortPair& server = map_it->first;
283 VLOG(1) << "Malformed Alternate-Protocol server: " << server_str;
284 NOTREACHED();
285 continue;
286 }
287
288 int port = 0;
289 if (!port_alternate_protocol_dict->GetIntegerWithoutPathExpansion(
290 "port", &port) || (port > (1 << 16))) {
291 VLOG(1) << "Malformed Alternate-Protocol server: " << server_str;
292 NOTREACHED();
293 continue;
294 }
295 int protocol = 0;
296 if (!port_alternate_protocol_dict->GetIntegerWithoutPathExpansion(
297 "protocol", &protocol) || (protocol < 0) ||
298 (protocol > net::NUM_ALTERNATE_PROTOCOLS)) {
299 VLOG(1) << "Malformed Alternate-Protocol server: " << server_str;
300 NOTREACHED();
301 continue;
302 }
303
304 net::PortAlternateProtocolPair port_alternate_protocol;
305 port_alternate_protocol.port = port;
306 port_alternate_protocol.protocol = static_cast<net::AlternateProtocol>(
307 protocol);
308
309 alternate_protocol_map[server] = port_alternate_protocol;
310 }
311
312 scoped_refptr<RefCountedAlternateProtocolMap> alternate_protocol_map_arg =
313 new RefCountedAlternateProtocolMap;
314 alternate_protocol_map_arg->data.swap(alternate_protocol_map);
315
316 BrowserThread::PostTask(
317 BrowserThread::IO,
318 FROM_HERE,
319 base::Bind(&HttpServerPropertiesManager::
320 UpdateAlternateProtocolCacheFromPrefsOnIO,
321 base::Unretained(this), alternate_protocol_map_arg));
322 }
323
324 void HttpServerPropertiesManager::UpdateAlternateProtocolCacheFromPrefsOnIO(
325 RefCountedAlternateProtocolMap* alternate_protocol_map) {
326 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
327 // 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
329 // preferences.
330 http_server_properties_impl_->InitializeAlternateProtocolServers(
331 &alternate_protocol_map->data);
332 }
333
334 //
335 // Update Preferences with data from alternate_protocol_servers (the cached
336 // data).
337 //
338 void HttpServerPropertiesManager::ScheduleUpdateAlternateProtocolPrefsOnIO() {
339 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
340 // Cancel pending updates, if any.
341 io_alternate_protocol_prefs_update_timer_->Stop();
342 StartAlternateProtocolPrefsUpdateTimerOnIO(
343 base::TimeDelta::FromMilliseconds(kUpdatePrefsDelayMs));
344 }
345
346 void HttpServerPropertiesManager::UpdateAlternateProtocolPrefsFromCache() {
347 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
348
349 scoped_refptr<RefCountedAlternateProtocolMap> alternate_protocol_map =
350 new RefCountedAlternateProtocolMap;
351 alternate_protocol_map->data =
352 http_server_properties_impl_->alternate_protocol_map();
353
354 // Update the preferences on the UI thread.
355 BrowserThread::PostTask(
356 BrowserThread::UI,
357 FROM_HERE,
358 base::Bind(&HttpServerPropertiesManager::
359 SetAlternateProtocolServersInPrefsOnUI,
360 ui_weak_ptr_, alternate_protocol_map));
361 }
362
363 void HttpServerPropertiesManager::SetAlternateProtocolServersInPrefsOnUI(
364 RefCountedAlternateProtocolMap* alternate_protocol_map) {
365 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
366 base::DictionaryValue alternate_protocol_dict;
367 for (net::AlternateProtocolMap::const_iterator it =
368 alternate_protocol_map->data.begin();
369 it != alternate_protocol_map->data.end(); ++it) {
370 const net::HostPortPair& server = it->first;
371 const net::PortAlternateProtocolPair& port_alternate_protocol = 462 const net::PortAlternateProtocolPair& port_alternate_protocol =
372 it->second; 463 map_it->second;
373 if (port_alternate_protocol.protocol < 0 || 464 if (port_alternate_protocol.protocol < 0 ||
374 port_alternate_protocol.protocol >= net::NUM_ALTERNATE_PROTOCOLS) { 465 port_alternate_protocol.protocol >= net::NUM_ALTERNATE_PROTOCOLS) {
375 continue; 466 continue;
376 } 467 }
377 base::DictionaryValue* port_alternate_protocol_dict = 468
378 new base::DictionaryValue; 469 ServerPrefMap::iterator it = server_pref_map.find(server);
379 port_alternate_protocol_dict->SetInteger( 470 if (it == server_pref_map.end()) {
380 "port", port_alternate_protocol.port); 471 ServerPref server_pref(false, NULL, &map_it->second);
381 port_alternate_protocol_dict->SetInteger( 472 server_pref_map[server] = server_pref;
382 "protocol", port_alternate_protocol.protocol); 473 } else {
383 alternate_protocol_dict.SetWithoutPathExpansion( 474 it->second.alternate_protocol = &map_it->second;
384 server.ToString(), port_alternate_protocol_dict); 475 }
385 } 476 }
386 setting_alternate_protocol_servers_ = true; 477
387 pref_service_->Set(prefs::kAlternateProtocolServers, 478 // Persist the prefs::kHttpServerProperties.
388 alternate_protocol_dict); 479 base::DictionaryValue http_server_properties_dict;
389 setting_alternate_protocol_servers_ = false; 480 for (ServerPrefMap::const_iterator map_it =
390 } 481 server_pref_map.begin();
391 482 map_it != server_pref_map.end(); ++map_it) {
392 void HttpServerPropertiesManager::StartSpdyCacheUpdateTimerOnUI( 483 const net::HostPortPair& server = map_it->first;
393 base::TimeDelta delay) { 484 const ServerPref& server_pref = map_it->second;
394 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 485
395 ui_spdy_cache_update_timer_->Start( 486 base::DictionaryValue* server_pref_dict = new base::DictionaryValue;
396 FROM_HERE, delay, this, 487
397 &HttpServerPropertiesManager::UpdateSpdyCacheFromPrefs); 488 // Save supports_spdy.
398 } 489 server_pref_dict->SetBoolean("supports_spdy", server_pref.supports_spdy);
399 490
400 void HttpServerPropertiesManager::StartSpdyPrefsUpdateTimerOnIO( 491 // Save SpdySettings.
401 base::TimeDelta delay) { 492 if (server_pref.settings) {
402 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 493 base::ListValue* spdy_settings_list = new ListValue();
403 // This is overridden in tests to post the task without the delay. 494 for (spdy::SpdySettings::const_iterator it =
404 io_spdy_prefs_update_timer_->Start( 495 server_pref.settings->begin();
405 FROM_HERE, delay, this, 496 it != server_pref.settings->end(); ++it) {
406 &HttpServerPropertiesManager::UpdateSpdyPrefsFromCache); 497 uint32 id = it->first.id();
407 } 498 uint32 value = it->second;
408 499 base::DictionaryValue* spdy_setting_dict = new base::DictionaryValue;
409 void HttpServerPropertiesManager::StartAlternateProtocolCacheUpdateTimerOnUI( 500 spdy_setting_dict->SetInteger("id", id);
410 base::TimeDelta delay) { 501 spdy_setting_dict->SetInteger("value", value);
411 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 502 spdy_settings_list->Append(spdy_setting_dict);
412 ui_alternate_protocol_cache_update_timer_->Start( 503 }
413 FROM_HERE, delay, this, 504 server_pref_dict->Set("settings", spdy_settings_list);
414 &HttpServerPropertiesManager::UpdateAlternateProtocolCacheFromPrefs); 505 }
415 } 506
416 507 // Save alternate_protocol.
417 void HttpServerPropertiesManager::StartAlternateProtocolPrefsUpdateTimerOnIO( 508 if (server_pref.alternate_protocol) {
418 base::TimeDelta delay) { 509 base::DictionaryValue* port_alternate_protocol_dict =
419 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 510 new base::DictionaryValue;
420 // This is overridden in tests to post the task without the delay. 511 const net::PortAlternateProtocolPair* port_alternate_protocol =
421 io_alternate_protocol_prefs_update_timer_->Start( 512 server_pref.alternate_protocol;
422 FROM_HERE, delay, this, 513 port_alternate_protocol_dict->SetInteger(
423 &HttpServerPropertiesManager::UpdateAlternateProtocolPrefsFromCache); 514 "port", port_alternate_protocol->port);
515 port_alternate_protocol_dict->SetInteger(
516 "protocol", port_alternate_protocol->protocol);
517 server_pref_dict->SetWithoutPathExpansion(
518 "alternate_protocol", port_alternate_protocol_dict);
519 }
520 http_server_properties_dict.SetWithoutPathExpansion(
521 server.ToString(), server_pref_dict);
522 }
523
524 setting_prefs_ = true;
525 pref_service_->Set(prefs::kHttpServerProperties,
526 http_server_properties_dict);
527 setting_prefs_ = false;
424 } 528 }
425 529
426 void HttpServerPropertiesManager::Observe( 530 void HttpServerPropertiesManager::Observe(
427 int type, 531 int type,
428 const content::NotificationSource& source, 532 const content::NotificationSource& source,
429 const content::NotificationDetails& details) { 533 const content::NotificationDetails& details) {
430 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 534 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
431 DCHECK(type == chrome::NOTIFICATION_PREF_CHANGED); 535 DCHECK(type == chrome::NOTIFICATION_PREF_CHANGED);
432 PrefService* prefs = content::Source<PrefService>(source).ptr(); 536 PrefService* prefs = content::Source<PrefService>(source).ptr();
433 DCHECK(prefs == pref_service_); 537 DCHECK(prefs == pref_service_);
434 std::string* pref_name = content::Details<std::string>(details).ptr(); 538 std::string* pref_name = content::Details<std::string>(details).ptr();
435 if (*pref_name == prefs::kSpdyServers) { 539 if (*pref_name == prefs::kHttpServerProperties) {
436 if (!setting_spdy_servers_) 540 if (!setting_prefs_)
437 ScheduleUpdateSpdyCacheOnUI(); 541 ScheduleUpdateCacheOnUI();
438 } else if (*pref_name == prefs::kAlternateProtocolServers) {
439 if (!setting_alternate_protocol_servers_)
440 ScheduleUpdateAlternateProtocolCacheOnUI();
441 } else { 542 } else {
442 NOTREACHED(); 543 NOTREACHED();
443 } 544 }
444 } 545 }
445 546
446 } // namespace chrome_browser_net 547 } // namespace chrome_browser_net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698