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)
2671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinet::SupportsQuic
2681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciHttpServerPropertiesManager::GetSupportsQuic(
2691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const net::HostPortPair& host_port_pair) const {
2701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
2711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return http_server_properties_impl_->GetSupportsQuic(host_port_pair);
2721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid HttpServerPropertiesManager::SetSupportsQuic(
2751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const net::HostPortPair& host_port_pair,
2761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    bool used_quic,
2771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const std::string& address) {
2781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
2791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  http_server_properties_impl_->SetSupportsQuic(
2801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      host_port_pair, used_quic, address);
2811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ScheduleUpdatePrefsOnNetworkThread();
2821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst SupportsQuicMap& HttpServerPropertiesManager::supports_quic_map()
2851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const {
2861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
2871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return http_server_properties_impl_->supports_quic_map();
2881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void HttpServerPropertiesManager::SetServerNetworkStats(
2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const net::HostPortPair& host_port_pair,
2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    NetworkStats stats) {
293116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  http_server_properties_impl_->SetServerNetworkStats(host_port_pair, stats);
2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const HttpServerPropertiesManager::NetworkStats*
2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)HttpServerPropertiesManager::GetServerNetworkStats(
2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const net::HostPortPair& host_port_pair) const {
300116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return http_server_properties_impl_->GetServerNetworkStats(host_port_pair);
3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Update the HttpServerPropertiesImpl's cache with data from preferences.
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
307116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid HttpServerPropertiesManager::ScheduleUpdateCacheOnPrefThread() {
308116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(pref_task_runner_->RunsTasksOnCurrentThread());
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Cancel pending updates, if any.
310116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  pref_cache_update_timer_->Stop();
311116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  StartCacheUpdateTimerOnPrefThread(
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::TimeDelta::FromMilliseconds(kUpdateCacheDelayMs));
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid HttpServerPropertiesManager::StartCacheUpdateTimerOnPrefThread(
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::TimeDelta delay) {
317116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(pref_task_runner_->RunsTasksOnCurrentThread());
318116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  pref_cache_update_timer_->Start(
319116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      FROM_HERE,
320116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      delay,
321116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      this,
322116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      &HttpServerPropertiesManager::UpdateCacheFromPrefsOnPrefThread);
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid HttpServerPropertiesManager::UpdateCacheFromPrefsOnPrefThread() {
326116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // The preferences can only be read on the pref thread.
327116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(pref_task_runner_->RunsTasksOnCurrentThread());
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
329116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!pref_service_->HasPrefPath(path_))
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool detected_corrupted_prefs = false;
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const base::DictionaryValue& http_server_properties_dict =
334116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      *pref_service_->GetDictionary(path_);
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int version = kMissingVersion;
337116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!http_server_properties_dict.GetIntegerWithoutPathExpansion("version",
338116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                                  &version)) {
3397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    DVLOG(1) << "Missing version. Clearing all properties.";
3407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
3417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
3427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // The properties for a given server is in
3447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // http_server_properties_dict["servers"][server].
3457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  const base::DictionaryValue* servers_dict = NULL;
3467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!http_server_properties_dict.GetDictionaryWithoutPathExpansion(
347116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          "servers", &servers_dict)) {
3487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    DVLOG(1) << "Malformed http_server_properties for servers.";
3497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
3507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
3517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // String is host/port pair of spdy server.
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<StringVector> spdy_servers(new StringVector);
35423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  scoped_ptr<net::SpdySettingsMap> spdy_settings_map(
35523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      new net::SpdySettingsMap(kMaxSpdySettingsHostsToPersist));
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<net::AlternateProtocolMap> alternate_protocol_map(
357a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      new net::AlternateProtocolMap(kMaxAlternateProtocolHostsToPersist));
3581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<net::SupportsQuicMap> supports_quic_map(
3591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new net::SupportsQuicMap());
360cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // TODO(rtenneti): Delete the following code after the experiment.
361cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int alternate_protocols_to_load = k200AlternateProtocolHostsToLoad;
362cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  net::AlternateProtocolExperiment alternate_protocol_experiment =
363cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      net::ALTERNATE_PROTOCOL_NOT_PART_OF_EXPERIMENT;
364cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (version == kVersionNumber) {
365cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (base::RandInt(0, 99) == 0) {
366cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      alternate_protocol_experiment =
367cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          net::ALTERNATE_PROTOCOL_TRUNCATED_200_SERVERS;
368cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    } else {
369cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      alternate_protocols_to_load = k1000AlternateProtocolHostsToLoad;
370cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      alternate_protocol_experiment =
371cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          net::ALTERNATE_PROTOCOL_TRUNCATED_1000_SERVERS;
372cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
373cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    DVLOG(1) << "# of servers that support alternate_protocol: "
374cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)             << alternate_protocols_to_load;
375cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
377cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int count = 0;
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (base::DictionaryValue::Iterator it(*servers_dict); !it.IsAtEnd();
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       it.Advance()) {
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Get server's host/pair.
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& server_str = it.key();
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::HostPortPair server = net::HostPortPair::FromString(server_str);
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (server.host().empty()) {
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DVLOG(1) << "Malformed http_server_properties for server: " << server_str;
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      detected_corrupted_prefs = true;
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::DictionaryValue* server_pref_dict = NULL;
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!it.value().GetAsDictionary(&server_pref_dict)) {
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DVLOG(1) << "Malformed http_server_properties server: " << server_str;
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      detected_corrupted_prefs = true;
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Get if server supports Spdy.
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool supports_spdy = false;
398116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if ((server_pref_dict->GetBoolean("supports_spdy", &supports_spdy)) &&
399116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        supports_spdy) {
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_servers->push_back(server_str);
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Get SpdySettings.
40423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    DCHECK(spdy_settings_map->Peek(server) == spdy_settings_map->end());
4057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const base::DictionaryValue* spdy_settings_dict = NULL;
4067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (server_pref_dict->GetDictionaryWithoutPathExpansion(
407116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            "settings", &spdy_settings_dict)) {
4087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      net::SettingsMap settings_map;
4097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      for (base::DictionaryValue::Iterator dict_it(*spdy_settings_dict);
410116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch           !dict_it.IsAtEnd();
411116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch           dict_it.Advance()) {
4127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        const std::string& id_str = dict_it.key();
4137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        int id = 0;
4147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        if (!base::StringToInt(id_str, &id)) {
415116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          DVLOG(1) << "Malformed id in SpdySettings for server: " << server_str;
4167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          NOTREACHED();
4177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          continue;
4187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        }
4197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        int value = 0;
4207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        if (!dict_it.value().GetAsInteger(&value)) {
421116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          DVLOG(1) << "Malformed value in SpdySettings for server: "
422116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   << server_str;
4237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          NOTREACHED();
4247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          continue;
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
426116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        net::SettingsFlagsAndValue flags_and_value(net::SETTINGS_FLAG_PERSISTED,
427116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                   value);
4287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        settings_map[static_cast<net::SpdySettingsIds>(id)] = flags_and_value;
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
43023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      spdy_settings_map->Put(server, settings_map);
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Get alternate_protocol server.
434a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DCHECK(alternate_protocol_map->Peek(server) ==
435a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)           alternate_protocol_map->end());
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::DictionaryValue* port_alternate_protocol_dict = NULL;
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!server_pref_dict->GetDictionaryWithoutPathExpansion(
438116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            "alternate_protocol", &port_alternate_protocol_dict)) {
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
442cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (count >= alternate_protocols_to_load)
443cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      continue;
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    do {
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int port = 0;
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!port_alternate_protocol_dict->GetIntegerWithoutPathExpansion(
447116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch              "port", &port) ||
448116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          (port > (1 << 16))) {
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        DVLOG(1) << "Malformed Alternate-Protocol server: " << server_str;
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        detected_corrupted_prefs = true;
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        continue;
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::string protocol_str;
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!port_alternate_protocol_dict->GetStringWithoutPathExpansion(
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "protocol_str", &protocol_str)) {
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        DVLOG(1) << "Malformed Alternate-Protocol server: " << server_str;
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        detected_corrupted_prefs = true;
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        continue;
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      net::AlternateProtocol protocol =
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          net::AlternateProtocolFromString(protocol_str);
4624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      if (!net::IsAlternateProtocolValid(protocol)) {
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        DVLOG(1) << "Malformed Alternate-Protocol server: " << server_str;
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        detected_corrupted_prefs = true;
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        continue;
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
468116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      double probability = 1;
469116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      if (port_alternate_protocol_dict->HasKey("probability") &&
470116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          !port_alternate_protocol_dict->GetDoubleWithoutPathExpansion(
471116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch              "probability", &probability)) {
472116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        DVLOG(1) << "Malformed Alternate-Protocol server: " << server_str;
473116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        detected_corrupted_prefs = true;
474116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        continue;
475116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      }
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
477116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      net::AlternateProtocolInfo port_alternate_protocol(port,
478116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                         protocol,
479116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                         probability);
480a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      alternate_protocol_map->Put(server, port_alternate_protocol);
481cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      ++count;
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } while (false);
4831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Get SupportsQuic.
4851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    DCHECK(supports_quic_map->find(server) == supports_quic_map->end());
4861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const base::DictionaryValue* supports_quic_dict = NULL;
4871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (!server_pref_dict->GetDictionaryWithoutPathExpansion(
4881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            "supports_quic", &supports_quic_dict)) {
4891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      continue;
4901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
4911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    do {
4921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      bool used_quic = 0;
4931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if (!supports_quic_dict->GetBooleanWithoutPathExpansion(
4941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci              "used_quic", &used_quic)) {
4951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        DVLOG(1) << "Malformed SupportsQuic server: " << server_str;
4961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        detected_corrupted_prefs = true;
4971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        continue;
4981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      }
4991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      std::string address;
5001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if (!supports_quic_dict->GetStringWithoutPathExpansion(
5011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci              "address", &address)) {
5021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        DVLOG(1) << "Malformed SupportsQuic server: " << server_str;
5031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        detected_corrupted_prefs = true;
5041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        continue;
5051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      }
5061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      net::SupportsQuic supports_quic(used_quic, address);
5071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      supports_quic_map->insert(std::make_pair(server, supports_quic));
5081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } while (false);
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
511116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  network_task_runner_->PostTask(
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
513116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(
514116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          &HttpServerPropertiesManager::UpdateCacheFromPrefsOnNetworkThread,
515116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          base::Unretained(this),
516116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          base::Owned(spdy_servers.release()),
517116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          base::Owned(spdy_settings_map.release()),
518116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          base::Owned(alternate_protocol_map.release()),
519116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          alternate_protocol_experiment,
5201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          base::Owned(supports_quic_map.release()),
521116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          detected_corrupted_prefs));
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
524116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid HttpServerPropertiesManager::UpdateCacheFromPrefsOnNetworkThread(
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StringVector* spdy_servers,
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::SpdySettingsMap* spdy_settings_map,
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::AlternateProtocolMap* alternate_protocol_map,
528cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    net::AlternateProtocolExperiment alternate_protocol_experiment,
5291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    net::SupportsQuicMap* supports_quic_map,
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool detected_corrupted_prefs) {
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Preferences have the master data because admins might have pushed new
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // preferences. Update the cached data with new data from preferences.
533116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UMA_HISTOGRAM_COUNTS("Net.CountOfSpdyServers", spdy_servers->size());
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_server_properties_impl_->InitializeSpdyServers(spdy_servers, true);
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
538cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Update the cached data and use the new spdy_settings from preferences.
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UMA_HISTOGRAM_COUNTS("Net.CountOfSpdySettings", spdy_settings_map->size());
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_server_properties_impl_->InitializeSpdySettingsServers(
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_settings_map);
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
543cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Update the cached data and use the new Alternate-Protocol server list from
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // preferences.
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UMA_HISTOGRAM_COUNTS("Net.CountOfAlternateProtocolServers",
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       alternate_protocol_map->size());
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_server_properties_impl_->InitializeAlternateProtocolServers(
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      alternate_protocol_map);
549cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  http_server_properties_impl_->SetAlternateProtocolExperiment(
550cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      alternate_protocol_experiment);
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  http_server_properties_impl_->InitializeSupportsQuic(supports_quic_map);
5531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Update the prefs with what we have read (delete all corrupted prefs).
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (detected_corrupted_prefs)
556116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ScheduleUpdatePrefsOnNetworkThread();
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Update Preferences with data from the cached data.
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
562116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid HttpServerPropertiesManager::ScheduleUpdatePrefsOnNetworkThread() {
563116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Cancel pending updates, if any.
565116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  network_prefs_update_timer_->Stop();
566116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  StartPrefsUpdateTimerOnNetworkThread(
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::TimeDelta::FromMilliseconds(kUpdatePrefsDelayMs));
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
570116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid HttpServerPropertiesManager::StartPrefsUpdateTimerOnNetworkThread(
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::TimeDelta delay) {
572116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This is overridden in tests to post the task without the delay.
574116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  network_prefs_update_timer_->Start(
575116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      FROM_HERE,
576116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      delay,
577116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      this,
578116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      &HttpServerPropertiesManager::UpdatePrefsFromCacheOnNetworkThread);
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is required so we can set this as the callback for a timer.
582116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid HttpServerPropertiesManager::UpdatePrefsFromCacheOnNetworkThread() {
583116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  UpdatePrefsFromCacheOnNetworkThread(base::Closure());
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
586116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid HttpServerPropertiesManager::UpdatePrefsFromCacheOnNetworkThread(
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::Closure& completion) {
588116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::ListValue* spdy_server_list = new base::ListValue;
5915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  http_server_properties_impl_->GetSpdyServerList(
5925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      spdy_server_list, kMaxSupportsSpdyServerHostsToPersist);
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  net::SpdySettingsMap* spdy_settings_map =
59523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      new net::SpdySettingsMap(kMaxSpdySettingsHostsToPersist);
59623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  const net::SpdySettingsMap& main_map =
59723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      http_server_properties_impl_->spdy_settings_map();
59823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  int count = 0;
59923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  for (net::SpdySettingsMap::const_iterator it = main_map.begin();
60023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)       it != main_map.end() && count < kMaxSpdySettingsHostsToPersist;
60123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)       ++it, ++count) {
60223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    spdy_settings_map->Put(it->first, it->second);
60323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::AlternateProtocolMap* alternate_protocol_map =
606a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      new net::AlternateProtocolMap(kMaxAlternateProtocolHostsToPersist);
607a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const net::AlternateProtocolMap& map =
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      http_server_properties_impl_->alternate_protocol_map();
60923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  count = 0;
610cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  typedef std::map<std::string, bool> CanonicalHostPersistedMap;
611cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  CanonicalHostPersistedMap persisted_map;
612a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (net::AlternateProtocolMap::const_iterator it = map.begin();
613a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       it != map.end() && count < kMaxAlternateProtocolHostsToPersist;
614cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)       ++it) {
615cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const net::HostPortPair& server = it->first;
616cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    std::string canonical_suffix =
617cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        http_server_properties_impl_->GetCanonicalSuffix(server);
618cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (!canonical_suffix.empty()) {
619cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      if (persisted_map.find(canonical_suffix) != persisted_map.end())
620cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        continue;
621cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      persisted_map[canonical_suffix] = true;
622cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
623cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    alternate_protocol_map->Put(server, it->second);
624cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ++count;
625a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  net::SupportsQuicMap* supports_quic_map = new net::SupportsQuicMap();
6281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const net::SupportsQuicMap& main_supports_quic_map =
6291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      http_server_properties_impl_->supports_quic_map();
6301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (net::SupportsQuicMap::const_iterator it = main_supports_quic_map.begin();
6311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       it != main_supports_quic_map.end(); ++it) {
6321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    supports_quic_map->insert(std::make_pair(it->first, it->second));
6331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
6341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
635116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Update the preferences on the pref thread.
636116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  pref_task_runner_->PostTask(
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
638116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(&HttpServerPropertiesManager::UpdatePrefsOnPrefThread,
639116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 pref_weak_ptr_,
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Owned(spdy_server_list),
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Owned(spdy_settings_map),
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Owned(alternate_protocol_map),
6431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 base::Owned(supports_quic_map),
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 completion));
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A local or temporary data structure to hold |supports_spdy|, SpdySettings,
6481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// AlternateProtocolInfo and SupportsQuic preferences for a server. This is used
6491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// only in UpdatePrefsOnPrefThread.
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ServerPref {
6511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ServerPref() : supports_spdy(false),
6521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 settings_map(NULL),
6531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 alternate_protocol(NULL),
6541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 supports_quic(NULL) {}
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ServerPref(bool supports_spdy,
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             const net::SettingsMap* settings_map,
6571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci             const net::AlternateProtocolInfo* alternate_protocol,
6581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci             const net::SupportsQuic* supports_quic)
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : supports_spdy(supports_spdy),
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        settings_map(settings_map),
6611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        alternate_protocol(alternate_protocol),
6621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        supports_quic(supports_quic) {}
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool supports_spdy;
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const net::SettingsMap* settings_map;
665116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const net::AlternateProtocolInfo* alternate_protocol;
6661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const net::SupportsQuic* supports_quic;
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
669116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid HttpServerPropertiesManager::UpdatePrefsOnPrefThread(
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::ListValue* spdy_server_list,
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::SpdySettingsMap* spdy_settings_map,
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::AlternateProtocolMap* alternate_protocol_map,
6731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    net::SupportsQuicMap* supports_quic_map,
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::Closure& completion) {
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::map<net::HostPortPair, ServerPref> ServerPrefMap;
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ServerPrefMap server_pref_map;
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
678116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(pref_task_runner_->RunsTasksOnCurrentThread());
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add servers that support spdy to server_pref_map.
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string s;
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (base::ListValue::const_iterator list_it = spdy_server_list->begin();
683116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch       list_it != spdy_server_list->end();
684116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch       ++list_it) {
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((*list_it)->GetAsString(&s)) {
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      net::HostPortPair server = net::HostPortPair::FromString(s);
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ServerPrefMap::iterator it = server_pref_map.find(server);
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (it == server_pref_map.end()) {
6901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        ServerPref server_pref(true, NULL, NULL, NULL);
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        server_pref_map[server] = server_pref;
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        it->second.supports_spdy = true;
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add servers that have SpdySettings to server_pref_map.
699a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (net::SpdySettingsMap::iterator map_it = spdy_settings_map->begin();
700116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch       map_it != spdy_settings_map->end();
701116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch       ++map_it) {
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const net::HostPortPair& server = map_it->first;
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ServerPrefMap::iterator it = server_pref_map.find(server);
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (it == server_pref_map.end()) {
7061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ServerPref server_pref(false, &map_it->second, NULL, NULL);
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      server_pref_map[server] = server_pref;
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      it->second.settings_map = &map_it->second;
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add AlternateProtocol servers to server_pref_map.
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (net::AlternateProtocolMap::const_iterator map_it =
715a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)           alternate_protocol_map->begin();
716116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch       map_it != alternate_protocol_map->end();
717116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch       ++map_it) {
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const net::HostPortPair& server = map_it->first;
719116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const net::AlternateProtocolInfo& port_alternate_protocol =
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        map_it->second;
7214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (!net::IsAlternateProtocolValid(port_alternate_protocol.protocol)) {
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ServerPrefMap::iterator it = server_pref_map.find(server);
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (it == server_pref_map.end()) {
7271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ServerPref server_pref(false, NULL, &map_it->second, NULL);
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      server_pref_map[server] = server_pref;
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      it->second.alternate_protocol = &map_it->second;
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Add SupportsQuic servers to server_pref_map.
7351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (net::SupportsQuicMap::const_iterator map_it = supports_quic_map->begin();
7361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       map_it != supports_quic_map->end(); ++map_it) {
7371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const net::HostPortPair& server = map_it->first;
7381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
7391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ServerPrefMap::iterator it = server_pref_map.find(server);
7401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (it == server_pref_map.end()) {
7411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ServerPref server_pref(false, NULL, NULL, &map_it->second);
7421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      server_pref_map[server] = server_pref;
7431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else {
7441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      it->second.supports_quic = &map_it->second;
7451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
7461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
7471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
748116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Persist properties to the |path_|.
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::DictionaryValue http_server_properties_dict;
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::DictionaryValue* servers_dict = new base::DictionaryValue;
751116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  for (ServerPrefMap::const_iterator map_it = server_pref_map.begin();
752116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch       map_it != server_pref_map.end();
753116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch       ++map_it) {
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const net::HostPortPair& server = map_it->first;
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ServerPref& server_pref = map_it->second;
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::DictionaryValue* server_pref_dict = new base::DictionaryValue;
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Save supports_spdy.
7605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    if (server_pref.supports_spdy)
7615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      server_pref_dict->SetBoolean("supports_spdy", server_pref.supports_spdy);
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Save SPDY settings.
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (server_pref.settings_map) {
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::DictionaryValue* spdy_settings_dict = new base::DictionaryValue;
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (net::SettingsMap::const_iterator it =
767116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch               server_pref.settings_map->begin();
768116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch           it != server_pref.settings_map->end();
769116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch           ++it) {
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        net::SpdySettingsIds id = it->first;
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        uint32 value = it->second.second;
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        std::string key = base::StringPrintf("%u", id);
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        spdy_settings_dict->SetInteger(key, value);
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      server_pref_dict->SetWithoutPathExpansion("settings", spdy_settings_dict);
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Save alternate_protocol.
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (server_pref.alternate_protocol) {
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::DictionaryValue* port_alternate_protocol_dict =
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          new base::DictionaryValue;
782116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      const net::AlternateProtocolInfo* port_alternate_protocol =
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          server_pref.alternate_protocol;
784116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      port_alternate_protocol_dict->SetInteger("port",
785116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                               port_alternate_protocol->port);
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const char* protocol_str =
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          net::AlternateProtocolToString(port_alternate_protocol->protocol);
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      port_alternate_protocol_dict->SetString("protocol_str", protocol_str);
789116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      port_alternate_protocol_dict->SetDouble(
790116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          "probability", port_alternate_protocol->probability);
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      server_pref_dict->SetWithoutPathExpansion(
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "alternate_protocol", port_alternate_protocol_dict);
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Save supports_quic.
7961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (server_pref.supports_quic) {
7971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::DictionaryValue* supports_quic_dict = new base::DictionaryValue;
7981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      const net::SupportsQuic* supports_quic = server_pref.supports_quic;
7991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      supports_quic_dict->SetBoolean("used_quic", supports_quic->used_quic);
8001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      supports_quic_dict->SetString("address", supports_quic->address);
8011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      server_pref_dict->SetWithoutPathExpansion(
8021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          "supports_quic", supports_quic_dict);
8031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
8041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    servers_dict->SetWithoutPathExpansion(server.ToString(), server_pref_dict);
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_server_properties_dict.SetWithoutPathExpansion("servers", servers_dict);
8097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  SetVersion(&http_server_properties_dict, kVersionNumber);
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  setting_prefs_ = true;
811116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  pref_service_->Set(path_, http_server_properties_dict);
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  setting_prefs_ = false;
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note that |completion| will be fired after we have written everything to
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the Preferences, but likely before these changes are serialized to disk.
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This is not a problem though, as JSONPrefStore guarantees that this will
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // happen, pretty soon, and even in the case we shut down immediately.
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!completion.is_null())
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    completion.Run();
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void HttpServerPropertiesManager::OnHttpServerPropertiesChanged() {
823116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(pref_task_runner_->RunsTasksOnCurrentThread());
8242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!setting_prefs_)
825116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ScheduleUpdateCacheOnPrefThread();
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
828116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}  // namespace net
829