OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "chrome/browser/net/chrome_http_server_properties.h" |
| 6 |
| 7 #include "base/bind.h" |
| 8 #include "base/metrics/histogram.h" |
| 9 #include "base/rand_util.h" |
| 10 #include "base/stl_util.h" |
| 11 #include "base/strings/string_number_conversions.h" |
| 12 #include "base/strings/stringprintf.h" |
| 13 #include "base/values.h" |
| 14 #include "chrome/browser/chrome_notification_types.h" |
| 15 #include "chrome/common/pref_names.h" |
| 16 #include "components/pref_registry/pref_registry_syncable.h" |
| 17 #include "content/public/browser/browser_thread.h" |
| 18 #include "content/public/browser/notification_details.h" |
| 19 #include "content/public/browser/notification_source.h" |
| 20 |
| 21 using content::BrowserThread; |
| 22 |
| 23 namespace chrome_browser_net { |
| 24 |
| 25 namespace { |
| 26 |
| 27 // Time to wait before starting an update the preferences from the |
| 28 // http_server_properties_impl_ cache. Scheduling another update during this |
| 29 // period will reset the timer. |
| 30 const int64 kUpdatePrefsDelayMs = 5000; |
| 31 |
| 32 // The version number of persisted http_server_properties. |
| 33 const int kVersionNumber = 3; |
| 34 |
| 35 typedef std::vector<std::string> StringVector; |
| 36 |
| 37 // Persist 1000 MRU AlternateProtocolHostPortPairs. |
| 38 const int kMaxAlternateProtocolHostsToPersist = 1000; |
| 39 |
| 40 // Persist 200 MRU SpdySettingsHostPortPairs. |
| 41 const int kMaxSpdySettingsHostsToPersist = 200; |
| 42 |
| 43 // Persist 300 MRU SupportsSpdyServerHostPortPairs. |
| 44 const int kMaxSupportsSpdyServerHostsToPersist = 300; |
| 45 |
| 46 } // namespace |
| 47 |
| 48 //////////////////////////////////////////////////////////////////////////////// |
| 49 // ChromeHttpServerProperties |
| 50 |
| 51 ChromeHttpServerProperties::ChromeHttpServerProperties( |
| 52 UpdateCallback update_callback) |
| 53 : http_server_properties_impl_(new net::HttpServerPropertiesImpl()), |
| 54 update_callback_(update_callback), |
| 55 prefs_update_timer_(new base::OneShotTimer<ChromeHttpServerProperties>), |
| 56 weak_ptr_factory_( |
| 57 new base::WeakPtrFactory<ChromeHttpServerProperties>(this)) { |
| 58 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 59 } |
| 60 |
| 61 ChromeHttpServerProperties::~ChromeHttpServerProperties() { |
| 62 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 63 weak_ptr_factory_.reset(); |
| 64 } |
| 65 |
| 66 // static |
| 67 void ChromeHttpServerProperties::SetVersion( |
| 68 base::DictionaryValue* http_server_properties_dict, |
| 69 int version_number) { |
| 70 if (version_number < 0) |
| 71 version_number = kVersionNumber; |
| 72 DCHECK_LE(version_number, kVersionNumber); |
| 73 if (version_number <= kVersionNumber) |
| 74 http_server_properties_dict->SetInteger("version", version_number); |
| 75 } |
| 76 |
| 77 // This is required for conformance with the HttpServerProperties interface. |
| 78 base::WeakPtr<net::HttpServerProperties> |
| 79 ChromeHttpServerProperties::GetWeakPtr() { |
| 80 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 81 return weak_ptr_factory_->GetWeakPtr(); |
| 82 } |
| 83 |
| 84 void ChromeHttpServerProperties::Clear() { |
| 85 Clear(base::Closure()); |
| 86 } |
| 87 |
| 88 void ChromeHttpServerProperties::Clear(const base::Closure& completion) { |
| 89 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 90 |
| 91 http_server_properties_impl_->Clear(); |
| 92 UpdatePrefsFromCacheOnIO(completion); |
| 93 } |
| 94 |
| 95 bool ChromeHttpServerProperties::SupportsSpdy( |
| 96 const net::HostPortPair& server) { |
| 97 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 98 return http_server_properties_impl_->SupportsSpdy(server); |
| 99 } |
| 100 |
| 101 void ChromeHttpServerProperties::SetSupportsSpdy( |
| 102 const net::HostPortPair& server, |
| 103 bool support_spdy) { |
| 104 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 105 |
| 106 http_server_properties_impl_->SetSupportsSpdy(server, support_spdy); |
| 107 ScheduleUpdatePrefsOnIO(); |
| 108 } |
| 109 |
| 110 bool ChromeHttpServerProperties::HasAlternateProtocol( |
| 111 const net::HostPortPair& server) { |
| 112 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 113 return http_server_properties_impl_->HasAlternateProtocol(server); |
| 114 } |
| 115 |
| 116 net::PortAlternateProtocolPair |
| 117 ChromeHttpServerProperties::GetAlternateProtocol( |
| 118 const net::HostPortPair& server) { |
| 119 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 120 return http_server_properties_impl_->GetAlternateProtocol(server); |
| 121 } |
| 122 |
| 123 void ChromeHttpServerProperties::SetAlternateProtocol( |
| 124 const net::HostPortPair& server, |
| 125 uint16 alternate_port, |
| 126 net::AlternateProtocol alternate_protocol) { |
| 127 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 128 http_server_properties_impl_->SetAlternateProtocol( |
| 129 server, alternate_port, alternate_protocol); |
| 130 ScheduleUpdatePrefsOnIO(); |
| 131 } |
| 132 |
| 133 void ChromeHttpServerProperties::SetBrokenAlternateProtocol( |
| 134 const net::HostPortPair& server) { |
| 135 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 136 http_server_properties_impl_->SetBrokenAlternateProtocol(server); |
| 137 ScheduleUpdatePrefsOnIO(); |
| 138 } |
| 139 |
| 140 bool ChromeHttpServerProperties::WasAlternateProtocolRecentlyBroken( |
| 141 const net::HostPortPair& server) { |
| 142 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 143 return http_server_properties_impl_->WasAlternateProtocolRecentlyBroken( |
| 144 server); |
| 145 } |
| 146 |
| 147 void ChromeHttpServerProperties::ConfirmAlternateProtocol( |
| 148 const net::HostPortPair& server) { |
| 149 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 150 http_server_properties_impl_->ConfirmAlternateProtocol(server); |
| 151 ScheduleUpdatePrefsOnIO(); |
| 152 } |
| 153 |
| 154 void ChromeHttpServerProperties::ClearAlternateProtocol( |
| 155 const net::HostPortPair& server) { |
| 156 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 157 http_server_properties_impl_->ClearAlternateProtocol(server); |
| 158 ScheduleUpdatePrefsOnIO(); |
| 159 } |
| 160 |
| 161 const net::AlternateProtocolMap& |
| 162 ChromeHttpServerProperties::alternate_protocol_map() const { |
| 163 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 164 return http_server_properties_impl_->alternate_protocol_map(); |
| 165 } |
| 166 |
| 167 void ChromeHttpServerProperties::SetAlternateProtocolExperiment( |
| 168 net::AlternateProtocolExperiment experiment) { |
| 169 http_server_properties_impl_->SetAlternateProtocolExperiment(experiment); |
| 170 } |
| 171 |
| 172 net::AlternateProtocolExperiment |
| 173 ChromeHttpServerProperties::GetAlternateProtocolExperiment() const { |
| 174 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 175 return http_server_properties_impl_->GetAlternateProtocolExperiment(); |
| 176 } |
| 177 |
| 178 const net::SettingsMap& |
| 179 ChromeHttpServerProperties::GetSpdySettings( |
| 180 const net::HostPortPair& host_port_pair) { |
| 181 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 182 return http_server_properties_impl_->GetSpdySettings(host_port_pair); |
| 183 } |
| 184 |
| 185 bool ChromeHttpServerProperties::SetSpdySetting( |
| 186 const net::HostPortPair& host_port_pair, |
| 187 net::SpdySettingsIds id, |
| 188 net::SpdySettingsFlags flags, |
| 189 uint32 value) { |
| 190 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 191 bool persist = http_server_properties_impl_->SetSpdySetting( |
| 192 host_port_pair, id, flags, value); |
| 193 if (persist) |
| 194 ScheduleUpdatePrefsOnIO(); |
| 195 return persist; |
| 196 } |
| 197 |
| 198 void ChromeHttpServerProperties::ClearSpdySettings( |
| 199 const net::HostPortPair& host_port_pair) { |
| 200 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 201 http_server_properties_impl_->ClearSpdySettings(host_port_pair); |
| 202 ScheduleUpdatePrefsOnIO(); |
| 203 } |
| 204 |
| 205 void ChromeHttpServerProperties::ClearAllSpdySettings() { |
| 206 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 207 http_server_properties_impl_->ClearAllSpdySettings(); |
| 208 ScheduleUpdatePrefsOnIO(); |
| 209 } |
| 210 |
| 211 const net::SpdySettingsMap& |
| 212 ChromeHttpServerProperties::spdy_settings_map() const { |
| 213 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 214 return http_server_properties_impl_->spdy_settings_map(); |
| 215 } |
| 216 |
| 217 void ChromeHttpServerProperties::SetServerNetworkStats( |
| 218 const net::HostPortPair& host_port_pair, |
| 219 NetworkStats stats) { |
| 220 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 221 http_server_properties_impl_->SetServerNetworkStats(host_port_pair, stats); |
| 222 } |
| 223 |
| 224 const ChromeHttpServerProperties::NetworkStats* |
| 225 ChromeHttpServerProperties::GetServerNetworkStats( |
| 226 const net::HostPortPair& host_port_pair) const { |
| 227 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 228 return http_server_properties_impl_->GetServerNetworkStats(host_port_pair); |
| 229 } |
| 230 |
| 231 void ChromeHttpServerProperties::UpdateCacheFromPrefsOnIO( |
| 232 StringVector* spdy_servers, |
| 233 net::SpdySettingsMap* spdy_settings_map, |
| 234 net::AlternateProtocolMap* alternate_protocol_map, |
| 235 net::AlternateProtocolExperiment alternate_protocol_experiment, |
| 236 bool detected_corrupted_prefs) { |
| 237 // Preferences have the master data because admins might have pushed new |
| 238 // preferences. Update the cached data with new data from preferences. |
| 239 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 240 |
| 241 UMA_HISTOGRAM_COUNTS("Net.CountOfSpdyServers", spdy_servers->size()); |
| 242 http_server_properties_impl_->InitializeSpdyServers(spdy_servers, true); |
| 243 |
| 244 // Update the cached data and use the new spdy_settings from preferences. |
| 245 UMA_HISTOGRAM_COUNTS("Net.CountOfSpdySettings", spdy_settings_map->size()); |
| 246 http_server_properties_impl_->InitializeSpdySettingsServers( |
| 247 spdy_settings_map); |
| 248 |
| 249 // Update the cached data and use the new Alternate-Protocol server list from |
| 250 // preferences. |
| 251 UMA_HISTOGRAM_COUNTS("Net.CountOfAlternateProtocolServers", |
| 252 alternate_protocol_map->size()); |
| 253 http_server_properties_impl_->InitializeAlternateProtocolServers( |
| 254 alternate_protocol_map); |
| 255 http_server_properties_impl_->SetAlternateProtocolExperiment( |
| 256 alternate_protocol_experiment); |
| 257 |
| 258 // Update the prefs with what we have read (delete all corrupted prefs). |
| 259 if (detected_corrupted_prefs) |
| 260 ScheduleUpdatePrefsOnIO(); |
| 261 } |
| 262 |
| 263 |
| 264 // |
| 265 // Update Preferences with data from the cached data. |
| 266 // |
| 267 void ChromeHttpServerProperties::ScheduleUpdatePrefsOnIO() { |
| 268 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 269 // Cancel pending updates, if any. |
| 270 prefs_update_timer_->Stop(); |
| 271 StartPrefsUpdateTimerOnIO( |
| 272 base::TimeDelta::FromMilliseconds(kUpdatePrefsDelayMs)); |
| 273 } |
| 274 |
| 275 void ChromeHttpServerProperties::StartPrefsUpdateTimerOnIO( |
| 276 base::TimeDelta delay) { |
| 277 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 278 // This is overridden in tests to post the task without the delay. |
| 279 prefs_update_timer_->Start( |
| 280 FROM_HERE, delay, this, |
| 281 &ChromeHttpServerProperties::UpdatePrefsFromCacheOnIO); |
| 282 } |
| 283 |
| 284 // This is required so we can set this as the callback for a timer. |
| 285 void ChromeHttpServerProperties::UpdatePrefsFromCacheOnIO() { |
| 286 UpdatePrefsFromCacheOnIO(base::Closure()); |
| 287 } |
| 288 |
| 289 void ChromeHttpServerProperties::UpdatePrefsFromCacheOnIO( |
| 290 const base::Closure& completion) { |
| 291 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 292 |
| 293 base::ListValue* spdy_server_list = new base::ListValue; |
| 294 http_server_properties_impl_->GetSpdyServerList( |
| 295 spdy_server_list, kMaxSupportsSpdyServerHostsToPersist); |
| 296 |
| 297 net::SpdySettingsMap* spdy_settings_map = |
| 298 new net::SpdySettingsMap(kMaxSpdySettingsHostsToPersist); |
| 299 const net::SpdySettingsMap& main_map = |
| 300 http_server_properties_impl_->spdy_settings_map(); |
| 301 int count = 0; |
| 302 for (net::SpdySettingsMap::const_iterator it = main_map.begin(); |
| 303 it != main_map.end() && count < kMaxSpdySettingsHostsToPersist; |
| 304 ++it, ++count) { |
| 305 spdy_settings_map->Put(it->first, it->second); |
| 306 } |
| 307 |
| 308 net::AlternateProtocolMap* alternate_protocol_map = |
| 309 new net::AlternateProtocolMap(kMaxAlternateProtocolHostsToPersist); |
| 310 const net::AlternateProtocolMap& map = |
| 311 http_server_properties_impl_->alternate_protocol_map(); |
| 312 count = 0; |
| 313 typedef std::map<std::string, bool> CanonicalHostPersistedMap; |
| 314 CanonicalHostPersistedMap persisted_map; |
| 315 for (net::AlternateProtocolMap::const_iterator it = map.begin(); |
| 316 it != map.end() && count < kMaxAlternateProtocolHostsToPersist; |
| 317 ++it) { |
| 318 const net::HostPortPair& server = it->first; |
| 319 std::string canonical_suffix = |
| 320 http_server_properties_impl_->GetCanonicalSuffix(server); |
| 321 if (!canonical_suffix.empty()) { |
| 322 if (persisted_map.find(canonical_suffix) != persisted_map.end()) |
| 323 continue; |
| 324 persisted_map[canonical_suffix] = true; |
| 325 } |
| 326 alternate_protocol_map->Put(server, it->second); |
| 327 ++count; |
| 328 } |
| 329 |
| 330 /* |
| 331 // Update the preferences on the UI thread. |
| 332 BrowserThread::PostTask( |
| 333 BrowserThread::UI, |
| 334 FROM_HERE, |
| 335 base::Bind(&ChromeHttpServerProperties::UpdatePrefsOnUI, |
| 336 manager_, |
| 337 base::Owned(spdy_server_list), |
| 338 base::Owned(spdy_settings_map), |
| 339 base::Owned(alternate_protocol_map), |
| 340 completion)); |
| 341 */ |
| 342 update_callback_.Run(spdy_server_list, spdy_settings_map, |
| 343 alternate_protocol_map, completion); |
| 344 } |
| 345 |
| 346 } // namespace chrome_browser_net |
OLD | NEW |