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