http_server_properties_manager.cc revision 116680a4aac90f2aa7413d9095a592090648e557
1116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "net/http/http_server_properties_manager.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/metrics/histogram.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h"
10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/rand_util.h"
11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/single_thread_task_runner.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h"
15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/thread_task_runner_handle.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace net {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Time to wait before starting an update the http_server_properties_impl_ cache
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// from preferences. Scheduling another update during this period will reset the
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// timer.
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int64 kUpdateCacheDelayMs = 1000;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Time to wait before starting an update the preferences from the
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http_server_properties_impl_ cache. Scheduling another update during this
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// period will reset the timer.
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int64 kUpdatePrefsDelayMs = 5000;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "version" 0 indicates, http_server_properties doesn't have "version"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// property.
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMissingVersion = 0;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The version number of persisted http_server_properties.
37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const int kVersionNumber = 3;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef std::vector<std::string> StringVector;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Load either 200 or 1000 servers based on a coin flip.
42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const int k200AlternateProtocolHostsToLoad = 200;
43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const int k1000AlternateProtocolHostsToLoad = 1000;
44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Persist 1000 MRU AlternateProtocolHostPortPairs.
45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const int kMaxAlternateProtocolHostsToPersist = 1000;
46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
4723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// Persist 200 MRU SpdySettingsHostPortPairs.
4823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)const int kMaxSpdySettingsHostsToPersist = 200;
4923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Persist 300 MRU SupportsSpdyServerHostPortPairs.
515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuconst int kMaxSupportsSpdyServerHostsToPersist = 300;
525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  HttpServerPropertiesManager
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpServerPropertiesManager::HttpServerPropertiesManager(
59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    PrefService* pref_service,
60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const char* pref_path,
61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    scoped_refptr<base::SequencedTaskRunner> network_task_runner)
62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    : pref_task_runner_(base::ThreadTaskRunnerHandle::Get()),
63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      pref_service_(pref_service),
64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      setting_prefs_(false),
65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      path_(pref_path),
66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      network_task_runner_(network_task_runner) {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(pref_service);
68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  pref_weak_ptr_factory_.reset(
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new base::WeakPtrFactory<HttpServerPropertiesManager>(this));
70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  pref_weak_ptr_ = pref_weak_ptr_factory_->GetWeakPtr();
71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  pref_cache_update_timer_.reset(
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new base::OneShotTimer<HttpServerPropertiesManager>);
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pref_change_registrar_.Init(pref_service_);
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  pref_change_registrar_.Add(
75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      path_,
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&HttpServerPropertiesManager::OnHttpServerPropertiesChanged,
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 base::Unretained(this)));
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpServerPropertiesManager::~HttpServerPropertiesManager() {
81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  network_weak_ptr_factory_.reset();
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid HttpServerPropertiesManager::InitializeOnNetworkThread() {
86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
87116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  network_weak_ptr_factory_.reset(
88ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      new base::WeakPtrFactory<HttpServerPropertiesManager>(this));
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_server_properties_impl_.reset(new net::HttpServerPropertiesImpl());
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  network_prefs_update_timer_.reset(
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new base::OneShotTimer<HttpServerPropertiesManager>);
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
94116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  pref_task_runner_->PostTask(
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(&HttpServerPropertiesManager::UpdateCacheFromPrefsOnPrefThread,
97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 pref_weak_ptr_));
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid HttpServerPropertiesManager::ShutdownOnPrefThread() {
101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(pref_task_runner_->RunsTasksOnCurrentThread());
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Cancel any pending updates, and stop listening for pref change updates.
103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  pref_cache_update_timer_->Stop();
104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  pref_weak_ptr_factory_.reset();
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pref_change_registrar_.RemoveAll();
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid HttpServerPropertiesManager::SetVersion(
1107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    base::DictionaryValue* http_server_properties_dict,
1117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    int version_number) {
1127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (version_number < 0)
113116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    version_number = kVersionNumber;
1147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK_LE(version_number, kVersionNumber);
1157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (version_number <= kVersionNumber)
1167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    http_server_properties_dict->SetInteger("version", version_number);
1177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is required for conformance with the HttpServerProperties interface.
120ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochbase::WeakPtr<net::HttpServerProperties>
121116680a4aac90f2aa7413d9095a592090648e557Ben MurdochHttpServerPropertiesManager::GetWeakPtr() {
122116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
123116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return network_weak_ptr_factory_->GetWeakPtr();
124ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
125ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpServerPropertiesManager::Clear() {
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Clear(base::Closure());
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpServerPropertiesManager::Clear(const base::Closure& completion) {
131116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_server_properties_impl_->Clear();
134116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  UpdatePrefsFromCacheOnNetworkThread(completion);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HttpServerPropertiesManager::SupportsSpdy(
1385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    const net::HostPortPair& server) {
139116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return http_server_properties_impl_->SupportsSpdy(server);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpServerPropertiesManager::SetSupportsSpdy(
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const net::HostPortPair& server,
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool support_spdy) {
146116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_server_properties_impl_->SetSupportsSpdy(server, support_spdy);
149116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ScheduleUpdatePrefsOnNetworkThread();
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HttpServerPropertiesManager::HasAlternateProtocol(
153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const net::HostPortPair& server) {
154116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return http_server_properties_impl_->HasAlternateProtocol(server);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
158116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnet::AlternateProtocolInfo
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpServerPropertiesManager::GetAlternateProtocol(
160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const net::HostPortPair& server) {
161116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return http_server_properties_impl_->GetAlternateProtocol(server);
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpServerPropertiesManager::SetAlternateProtocol(
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const net::HostPortPair& server,
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint16 alternate_port,
168116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    AlternateProtocol alternate_protocol,
169116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    double alternate_probability) {
170116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_server_properties_impl_->SetAlternateProtocol(
172116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      server, alternate_port, alternate_protocol, alternate_probability);
173116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ScheduleUpdatePrefsOnNetworkThread();
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpServerPropertiesManager::SetBrokenAlternateProtocol(
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const net::HostPortPair& server) {
178116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_server_properties_impl_->SetBrokenAlternateProtocol(server);
180116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ScheduleUpdatePrefsOnNetworkThread();
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochbool HttpServerPropertiesManager::WasAlternateProtocolRecentlyBroken(
1840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const net::HostPortPair& server) {
185116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
1860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return http_server_properties_impl_->WasAlternateProtocolRecentlyBroken(
1870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      server);
1880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
1890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid HttpServerPropertiesManager::ConfirmAlternateProtocol(
1910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const net::HostPortPair& server) {
192116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
1930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  http_server_properties_impl_->ConfirmAlternateProtocol(server);
194116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ScheduleUpdatePrefsOnNetworkThread();
1950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
1960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void HttpServerPropertiesManager::ClearAlternateProtocol(
198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const net::HostPortPair& server) {
199116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  http_server_properties_impl_->ClearAlternateProtocol(server);
201116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ScheduleUpdatePrefsOnNetworkThread();
202a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
203a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const net::AlternateProtocolMap&
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpServerPropertiesManager::alternate_protocol_map() const {
206116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return http_server_properties_impl_->alternate_protocol_map();
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
210cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void HttpServerPropertiesManager::SetAlternateProtocolExperiment(
211116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    AlternateProtocolExperiment experiment) {
212116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
213cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  http_server_properties_impl_->SetAlternateProtocolExperiment(experiment);
214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
215cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
216116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid HttpServerPropertiesManager::SetAlternateProtocolProbabilityThreshold(
217116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    double threshold) {
218116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
219116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  http_server_properties_impl_->SetAlternateProtocolProbabilityThreshold(
220116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      threshold);
221116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
222116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
223116680a4aac90f2aa7413d9095a592090648e557Ben MurdochAlternateProtocolExperiment
224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)HttpServerPropertiesManager::GetAlternateProtocolExperiment() const {
225116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
226cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return http_server_properties_impl_->GetAlternateProtocolExperiment();
227cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
228cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
229116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst SettingsMap& HttpServerPropertiesManager::GetSpdySettings(
230116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const HostPortPair& host_port_pair) {
231116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return http_server_properties_impl_->GetSpdySettings(host_port_pair);
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HttpServerPropertiesManager::SetSpdySetting(
236116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const HostPortPair& host_port_pair,
237116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    SpdySettingsIds id,
238116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    SpdySettingsFlags flags,
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint32 value) {
240116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool persist = http_server_properties_impl_->SetSpdySetting(
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      host_port_pair, id, flags, value);
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (persist)
244116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ScheduleUpdatePrefsOnNetworkThread();
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return persist;
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void HttpServerPropertiesManager::ClearSpdySettings(
249116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const HostPortPair& host_port_pair) {
250116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  http_server_properties_impl_->ClearSpdySettings(host_port_pair);
252116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ScheduleUpdatePrefsOnNetworkThread();
253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void HttpServerPropertiesManager::ClearAllSpdySettings() {
256116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  http_server_properties_impl_->ClearAllSpdySettings();
258116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ScheduleUpdatePrefsOnNetworkThread();
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
261116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst SpdySettingsMap& HttpServerPropertiesManager::spdy_settings_map()
262116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const {
263116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return http_server_properties_impl_->spdy_settings_map();
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void HttpServerPropertiesManager::SetServerNetworkStats(
2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const net::HostPortPair& host_port_pair,
2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    NetworkStats stats) {
270116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  http_server_properties_impl_->SetServerNetworkStats(host_port_pair, stats);
2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const HttpServerPropertiesManager::NetworkStats*
2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)HttpServerPropertiesManager::GetServerNetworkStats(
2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const net::HostPortPair& host_port_pair) const {
277116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return http_server_properties_impl_->GetServerNetworkStats(host_port_pair);
2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Update the HttpServerPropertiesImpl's cache with data from preferences.
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
284116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid HttpServerPropertiesManager::ScheduleUpdateCacheOnPrefThread() {
285116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(pref_task_runner_->RunsTasksOnCurrentThread());
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Cancel pending updates, if any.
287116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  pref_cache_update_timer_->Stop();
288116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  StartCacheUpdateTimerOnPrefThread(
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::TimeDelta::FromMilliseconds(kUpdateCacheDelayMs));
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
292116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid HttpServerPropertiesManager::StartCacheUpdateTimerOnPrefThread(
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::TimeDelta delay) {
294116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(pref_task_runner_->RunsTasksOnCurrentThread());
295116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  pref_cache_update_timer_->Start(
296116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      FROM_HERE,
297116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      delay,
298116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      this,
299116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      &HttpServerPropertiesManager::UpdateCacheFromPrefsOnPrefThread);
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
302116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid HttpServerPropertiesManager::UpdateCacheFromPrefsOnPrefThread() {
303116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // The preferences can only be read on the pref thread.
304116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(pref_task_runner_->RunsTasksOnCurrentThread());
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
306116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!pref_service_->HasPrefPath(path_))
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool detected_corrupted_prefs = false;
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const base::DictionaryValue& http_server_properties_dict =
311116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      *pref_service_->GetDictionary(path_);
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int version = kMissingVersion;
314116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!http_server_properties_dict.GetIntegerWithoutPathExpansion("version",
315116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                                  &version)) {
3167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    DVLOG(1) << "Missing version. Clearing all properties.";
3177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
3187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
3197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // The properties for a given server is in
3217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // http_server_properties_dict["servers"][server].
3227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  const base::DictionaryValue* servers_dict = NULL;
3237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!http_server_properties_dict.GetDictionaryWithoutPathExpansion(
324116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          "servers", &servers_dict)) {
3257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    DVLOG(1) << "Malformed http_server_properties for servers.";
3267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
3277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
3287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // String is host/port pair of spdy server.
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<StringVector> spdy_servers(new StringVector);
33123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  scoped_ptr<net::SpdySettingsMap> spdy_settings_map(
33223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      new net::SpdySettingsMap(kMaxSpdySettingsHostsToPersist));
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<net::AlternateProtocolMap> alternate_protocol_map(
334a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      new net::AlternateProtocolMap(kMaxAlternateProtocolHostsToPersist));
335cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // TODO(rtenneti): Delete the following code after the experiment.
336cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int alternate_protocols_to_load = k200AlternateProtocolHostsToLoad;
337cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  net::AlternateProtocolExperiment alternate_protocol_experiment =
338cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      net::ALTERNATE_PROTOCOL_NOT_PART_OF_EXPERIMENT;
339cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (version == kVersionNumber) {
340cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (base::RandInt(0, 99) == 0) {
341cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      alternate_protocol_experiment =
342cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          net::ALTERNATE_PROTOCOL_TRUNCATED_200_SERVERS;
343cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    } else {
344cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      alternate_protocols_to_load = k1000AlternateProtocolHostsToLoad;
345cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      alternate_protocol_experiment =
346cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          net::ALTERNATE_PROTOCOL_TRUNCATED_1000_SERVERS;
347cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
348cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    DVLOG(1) << "# of servers that support alternate_protocol: "
349cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)             << alternate_protocols_to_load;
350cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
352cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int count = 0;
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (base::DictionaryValue::Iterator it(*servers_dict); !it.IsAtEnd();
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       it.Advance()) {
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Get server's host/pair.
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& server_str = it.key();
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::HostPortPair server = net::HostPortPair::FromString(server_str);
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (server.host().empty()) {
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DVLOG(1) << "Malformed http_server_properties for server: " << server_str;
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      detected_corrupted_prefs = true;
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::DictionaryValue* server_pref_dict = NULL;
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!it.value().GetAsDictionary(&server_pref_dict)) {
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DVLOG(1) << "Malformed http_server_properties server: " << server_str;
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      detected_corrupted_prefs = true;
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Get if server supports Spdy.
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool supports_spdy = false;
373116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if ((server_pref_dict->GetBoolean("supports_spdy", &supports_spdy)) &&
374116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        supports_spdy) {
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_servers->push_back(server_str);
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Get SpdySettings.
37923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    DCHECK(spdy_settings_map->Peek(server) == spdy_settings_map->end());
3807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const base::DictionaryValue* spdy_settings_dict = NULL;
3817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (server_pref_dict->GetDictionaryWithoutPathExpansion(
382116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            "settings", &spdy_settings_dict)) {
3837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      net::SettingsMap settings_map;
3847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      for (base::DictionaryValue::Iterator dict_it(*spdy_settings_dict);
385116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch           !dict_it.IsAtEnd();
386116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch           dict_it.Advance()) {
3877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        const std::string& id_str = dict_it.key();
3887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        int id = 0;
3897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        if (!base::StringToInt(id_str, &id)) {
390116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          DVLOG(1) << "Malformed id in SpdySettings for server: " << server_str;
3917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          NOTREACHED();
3927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          continue;
3937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        }
3947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        int value = 0;
3957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        if (!dict_it.value().GetAsInteger(&value)) {
396116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          DVLOG(1) << "Malformed value in SpdySettings for server: "
397116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   << server_str;
3987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          NOTREACHED();
3997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          continue;
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
401116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        net::SettingsFlagsAndValue flags_and_value(net::SETTINGS_FLAG_PERSISTED,
402116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                   value);
4037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        settings_map[static_cast<net::SpdySettingsIds>(id)] = flags_and_value;
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
40523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      spdy_settings_map->Put(server, settings_map);
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Get alternate_protocol server.
409a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DCHECK(alternate_protocol_map->Peek(server) ==
410a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)           alternate_protocol_map->end());
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::DictionaryValue* port_alternate_protocol_dict = NULL;
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!server_pref_dict->GetDictionaryWithoutPathExpansion(
413116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            "alternate_protocol", &port_alternate_protocol_dict)) {
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
417cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (count >= alternate_protocols_to_load)
418cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      continue;
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    do {
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int port = 0;
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!port_alternate_protocol_dict->GetIntegerWithoutPathExpansion(
422116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch              "port", &port) ||
423116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          (port > (1 << 16))) {
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        DVLOG(1) << "Malformed Alternate-Protocol server: " << server_str;
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        detected_corrupted_prefs = true;
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        continue;
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::string protocol_str;
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!port_alternate_protocol_dict->GetStringWithoutPathExpansion(
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "protocol_str", &protocol_str)) {
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        DVLOG(1) << "Malformed Alternate-Protocol server: " << server_str;
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        detected_corrupted_prefs = true;
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        continue;
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      net::AlternateProtocol protocol =
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          net::AlternateProtocolFromString(protocol_str);
4374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      if (!net::IsAlternateProtocolValid(protocol)) {
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        DVLOG(1) << "Malformed Alternate-Protocol server: " << server_str;
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        detected_corrupted_prefs = true;
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        continue;
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
443116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      double probability = 1;
444116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      if (port_alternate_protocol_dict->HasKey("probability") &&
445116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          !port_alternate_protocol_dict->GetDoubleWithoutPathExpansion(
446116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch              "probability", &probability)) {
447116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        DVLOG(1) << "Malformed Alternate-Protocol server: " << server_str;
448116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        detected_corrupted_prefs = true;
449116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        continue;
450116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      }
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
452116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      net::AlternateProtocolInfo port_alternate_protocol(port,
453116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                         protocol,
454116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                         probability);
455a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      alternate_protocol_map->Put(server, port_alternate_protocol);
456cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      ++count;
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } while (false);
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
460116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  network_task_runner_->PostTask(
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
462116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(
463116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          &HttpServerPropertiesManager::UpdateCacheFromPrefsOnNetworkThread,
464116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          base::Unretained(this),
465116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          base::Owned(spdy_servers.release()),
466116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          base::Owned(spdy_settings_map.release()),
467116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          base::Owned(alternate_protocol_map.release()),
468116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          alternate_protocol_experiment,
469116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          detected_corrupted_prefs));
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
472116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid HttpServerPropertiesManager::UpdateCacheFromPrefsOnNetworkThread(
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StringVector* spdy_servers,
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::SpdySettingsMap* spdy_settings_map,
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::AlternateProtocolMap* alternate_protocol_map,
476cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    net::AlternateProtocolExperiment alternate_protocol_experiment,
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool detected_corrupted_prefs) {
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Preferences have the master data because admins might have pushed new
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // preferences. Update the cached data with new data from preferences.
480116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UMA_HISTOGRAM_COUNTS("Net.CountOfSpdyServers", spdy_servers->size());
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_server_properties_impl_->InitializeSpdyServers(spdy_servers, true);
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Update the cached data and use the new spdy_settings from preferences.
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UMA_HISTOGRAM_COUNTS("Net.CountOfSpdySettings", spdy_settings_map->size());
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_server_properties_impl_->InitializeSpdySettingsServers(
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_settings_map);
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
490cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Update the cached data and use the new Alternate-Protocol server list from
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // preferences.
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UMA_HISTOGRAM_COUNTS("Net.CountOfAlternateProtocolServers",
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       alternate_protocol_map->size());
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_server_properties_impl_->InitializeAlternateProtocolServers(
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      alternate_protocol_map);
496cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  http_server_properties_impl_->SetAlternateProtocolExperiment(
497cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      alternate_protocol_experiment);
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Update the prefs with what we have read (delete all corrupted prefs).
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (detected_corrupted_prefs)
501116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ScheduleUpdatePrefsOnNetworkThread();
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Update Preferences with data from the cached data.
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
507116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid HttpServerPropertiesManager::ScheduleUpdatePrefsOnNetworkThread() {
508116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Cancel pending updates, if any.
510116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  network_prefs_update_timer_->Stop();
511116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  StartPrefsUpdateTimerOnNetworkThread(
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::TimeDelta::FromMilliseconds(kUpdatePrefsDelayMs));
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid HttpServerPropertiesManager::StartPrefsUpdateTimerOnNetworkThread(
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::TimeDelta delay) {
517116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This is overridden in tests to post the task without the delay.
519116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  network_prefs_update_timer_->Start(
520116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      FROM_HERE,
521116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      delay,
522116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      this,
523116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      &HttpServerPropertiesManager::UpdatePrefsFromCacheOnNetworkThread);
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is required so we can set this as the callback for a timer.
527116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid HttpServerPropertiesManager::UpdatePrefsFromCacheOnNetworkThread() {
528116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  UpdatePrefsFromCacheOnNetworkThread(base::Closure());
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
531116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid HttpServerPropertiesManager::UpdatePrefsFromCacheOnNetworkThread(
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::Closure& completion) {
533116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::ListValue* spdy_server_list = new base::ListValue;
5365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  http_server_properties_impl_->GetSpdyServerList(
5375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      spdy_server_list, kMaxSupportsSpdyServerHostsToPersist);
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  net::SpdySettingsMap* spdy_settings_map =
54023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      new net::SpdySettingsMap(kMaxSpdySettingsHostsToPersist);
54123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  const net::SpdySettingsMap& main_map =
54223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      http_server_properties_impl_->spdy_settings_map();
54323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  int count = 0;
54423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  for (net::SpdySettingsMap::const_iterator it = main_map.begin();
54523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)       it != main_map.end() && count < kMaxSpdySettingsHostsToPersist;
54623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)       ++it, ++count) {
54723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    spdy_settings_map->Put(it->first, it->second);
54823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::AlternateProtocolMap* alternate_protocol_map =
551a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      new net::AlternateProtocolMap(kMaxAlternateProtocolHostsToPersist);
552a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const net::AlternateProtocolMap& map =
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      http_server_properties_impl_->alternate_protocol_map();
55423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  count = 0;
555cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  typedef std::map<std::string, bool> CanonicalHostPersistedMap;
556cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  CanonicalHostPersistedMap persisted_map;
557a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (net::AlternateProtocolMap::const_iterator it = map.begin();
558a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       it != map.end() && count < kMaxAlternateProtocolHostsToPersist;
559cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)       ++it) {
560cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const net::HostPortPair& server = it->first;
561cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    std::string canonical_suffix =
562cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        http_server_properties_impl_->GetCanonicalSuffix(server);
563cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (!canonical_suffix.empty()) {
564cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      if (persisted_map.find(canonical_suffix) != persisted_map.end())
565cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        continue;
566cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      persisted_map[canonical_suffix] = true;
567cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
568cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    alternate_protocol_map->Put(server, it->second);
569cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ++count;
570a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
572116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Update the preferences on the pref thread.
573116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  pref_task_runner_->PostTask(
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
575116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(&HttpServerPropertiesManager::UpdatePrefsOnPrefThread,
576116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 pref_weak_ptr_,
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Owned(spdy_server_list),
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Owned(spdy_settings_map),
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Owned(alternate_protocol_map),
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 completion));
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A local or temporary data structure to hold |supports_spdy|, SpdySettings,
584116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// and AlternateProtocolInfo preferences for a server. This is used only in
585116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// UpdatePrefsOnPrefThread.
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ServerPref {
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ServerPref()
588116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      : supports_spdy(false), settings_map(NULL), alternate_protocol(NULL) {}
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ServerPref(bool supports_spdy,
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             const net::SettingsMap* settings_map,
591116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch             const net::AlternateProtocolInfo* alternate_protocol)
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : supports_spdy(supports_spdy),
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        settings_map(settings_map),
594116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        alternate_protocol(alternate_protocol) {}
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool supports_spdy;
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const net::SettingsMap* settings_map;
597116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const net::AlternateProtocolInfo* alternate_protocol;
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
600116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid HttpServerPropertiesManager::UpdatePrefsOnPrefThread(
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::ListValue* spdy_server_list,
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::SpdySettingsMap* spdy_settings_map,
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::AlternateProtocolMap* alternate_protocol_map,
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::Closure& completion) {
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::map<net::HostPortPair, ServerPref> ServerPrefMap;
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ServerPrefMap server_pref_map;
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
608116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(pref_task_runner_->RunsTasksOnCurrentThread());
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add servers that support spdy to server_pref_map.
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string s;
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (base::ListValue::const_iterator list_it = spdy_server_list->begin();
613116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch       list_it != spdy_server_list->end();
614116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch       ++list_it) {
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((*list_it)->GetAsString(&s)) {
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      net::HostPortPair server = net::HostPortPair::FromString(s);
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ServerPrefMap::iterator it = server_pref_map.find(server);
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (it == server_pref_map.end()) {
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ServerPref server_pref(true, NULL, NULL);
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        server_pref_map[server] = server_pref;
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        it->second.supports_spdy = true;
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add servers that have SpdySettings to server_pref_map.
629a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (net::SpdySettingsMap::iterator map_it = spdy_settings_map->begin();
630116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch       map_it != spdy_settings_map->end();
631116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch       ++map_it) {
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const net::HostPortPair& server = map_it->first;
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ServerPrefMap::iterator it = server_pref_map.find(server);
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (it == server_pref_map.end()) {
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ServerPref server_pref(false, &map_it->second, NULL);
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      server_pref_map[server] = server_pref;
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      it->second.settings_map = &map_it->second;
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add AlternateProtocol servers to server_pref_map.
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (net::AlternateProtocolMap::const_iterator map_it =
645a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)           alternate_protocol_map->begin();
646116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch       map_it != alternate_protocol_map->end();
647116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch       ++map_it) {
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const net::HostPortPair& server = map_it->first;
649116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const net::AlternateProtocolInfo& port_alternate_protocol =
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        map_it->second;
6514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (!net::IsAlternateProtocolValid(port_alternate_protocol.protocol)) {
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ServerPrefMap::iterator it = server_pref_map.find(server);
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (it == server_pref_map.end()) {
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ServerPref server_pref(false, NULL, &map_it->second);
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      server_pref_map[server] = server_pref;
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      it->second.alternate_protocol = &map_it->second;
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
664116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Persist properties to the |path_|.
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::DictionaryValue http_server_properties_dict;
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::DictionaryValue* servers_dict = new base::DictionaryValue;
667116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  for (ServerPrefMap::const_iterator map_it = server_pref_map.begin();
668116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch       map_it != server_pref_map.end();
669116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch       ++map_it) {
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const net::HostPortPair& server = map_it->first;
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ServerPref& server_pref = map_it->second;
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::DictionaryValue* server_pref_dict = new base::DictionaryValue;
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Save supports_spdy.
6765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    if (server_pref.supports_spdy)
6775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      server_pref_dict->SetBoolean("supports_spdy", server_pref.supports_spdy);
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Save SPDY settings.
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (server_pref.settings_map) {
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::DictionaryValue* spdy_settings_dict = new base::DictionaryValue;
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (net::SettingsMap::const_iterator it =
683116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch               server_pref.settings_map->begin();
684116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch           it != server_pref.settings_map->end();
685116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch           ++it) {
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        net::SpdySettingsIds id = it->first;
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        uint32 value = it->second.second;
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        std::string key = base::StringPrintf("%u", id);
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        spdy_settings_dict->SetInteger(key, value);
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      server_pref_dict->SetWithoutPathExpansion("settings", spdy_settings_dict);
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Save alternate_protocol.
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (server_pref.alternate_protocol) {
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::DictionaryValue* port_alternate_protocol_dict =
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          new base::DictionaryValue;
698116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      const net::AlternateProtocolInfo* port_alternate_protocol =
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          server_pref.alternate_protocol;
700116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      port_alternate_protocol_dict->SetInteger("port",
701116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                               port_alternate_protocol->port);
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const char* protocol_str =
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          net::AlternateProtocolToString(port_alternate_protocol->protocol);
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      port_alternate_protocol_dict->SetString("protocol_str", protocol_str);
705116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      port_alternate_protocol_dict->SetDouble(
706116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          "probability", port_alternate_protocol->probability);
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      server_pref_dict->SetWithoutPathExpansion(
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "alternate_protocol", port_alternate_protocol_dict);
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    servers_dict->SetWithoutPathExpansion(server.ToString(), server_pref_dict);
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_server_properties_dict.SetWithoutPathExpansion("servers", servers_dict);
7157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  SetVersion(&http_server_properties_dict, kVersionNumber);
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  setting_prefs_ = true;
717116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  pref_service_->Set(path_, http_server_properties_dict);
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  setting_prefs_ = false;
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note that |completion| will be fired after we have written everything to
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the Preferences, but likely before these changes are serialized to disk.
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This is not a problem though, as JSONPrefStore guarantees that this will
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // happen, pretty soon, and even in the case we shut down immediately.
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!completion.is_null())
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    completion.Run();
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void HttpServerPropertiesManager::OnHttpServerPropertiesChanged() {
729116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(pref_task_runner_->RunsTasksOnCurrentThread());
7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!setting_prefs_)
731116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ScheduleUpdateCacheOnPrefThread();
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
734116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}  // namespace net
735