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

Side by Side Diff: net/base/sdch_manager.cc

Issue 711753003: Pin dictionaries from being deleted while request is outstanding. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Incorporated comments. Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/base/sdch_manager.h" 5 #include "net/base/sdch_manager.h"
6 6
7 #include "base/base64.h" 7 #include "base/base64.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/metrics/histogram.h" 9 #include "base/metrics/histogram.h"
10 #include "base/strings/string_number_conversions.h" 10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/string_util.h" 11 #include "base/strings/string_util.h"
12 #include "base/time/default_clock.h"
12 #include "base/values.h" 13 #include "base/values.h"
13 #include "crypto/sha2.h" 14 #include "crypto/sha2.h"
14 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" 15 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
15 #include "net/base/sdch_observer.h" 16 #include "net/base/sdch_observer.h"
16 #include "net/url_request/url_request_http_job.h" 17 #include "net/url_request/url_request_http_job.h"
17 18
18 namespace { 19 namespace {
19 20
20 void StripTrailingDot(GURL* gurl) { 21 void StripTrailingDot(GURL* gurl) {
21 std::string host(gurl->host()); 22 std::string host(gurl->host());
22 23
23 if (host.empty()) 24 if (host.empty())
24 return; 25 return;
25 26
26 if (*host.rbegin() != '.') 27 if (*host.rbegin() != '.')
27 return; 28 return;
28 29
29 host.resize(host.size() - 1); 30 host.resize(host.size() - 1);
30 31
31 GURL::Replacements replacements; 32 GURL::Replacements replacements;
32 replacements.SetHostStr(host); 33 replacements.SetHostStr(host);
33 *gurl = gurl->ReplaceComponents(replacements); 34 *gurl = gurl->ReplaceComponents(replacements);
34 return; 35 return;
35 } 36 }
36 37
37 } // namespace 38 } // namespace
38 39
39 namespace net { 40 namespace net {
40 41
41 //------------------------------------------------------------------------------
42 // static
43
44 // Adjust SDCH limits downwards for mobile. 42 // Adjust SDCH limits downwards for mobile.
45 #if defined(OS_ANDROID) || defined(OS_IOS) 43 #if defined(OS_ANDROID) || defined(OS_IOS)
46 // static 44 // static
47 const size_t SdchManager::kMaxDictionaryCount = 1; 45 const size_t SdchManager::kMaxDictionaryCount = 1;
48 const size_t SdchManager::kMaxDictionarySize = 500 * 1000; 46 const size_t SdchManager::kMaxDictionarySize = 500 * 1000;
49 #else 47 #else
50 // static 48 // static
51 const size_t SdchManager::kMaxDictionaryCount = 20; 49 const size_t SdchManager::kMaxDictionaryCount = 20;
52 const size_t SdchManager::kMaxDictionarySize = 1000 * 1000; 50 const size_t SdchManager::kMaxDictionarySize = 1000 * 1000;
53 #endif 51 #endif
54 52
55 // static 53 // static
56 bool SdchManager::g_sdch_enabled_ = true; 54 bool SdchManager::g_sdch_enabled_ = true;
57 55
58 // static 56 // static
59 bool SdchManager::g_secure_scheme_supported_ = true; 57 bool SdchManager::g_secure_scheme_supported_ = true;
60 58
61 //------------------------------------------------------------------------------
62 SdchManager::Dictionary::Dictionary(const std::string& dictionary_text, 59 SdchManager::Dictionary::Dictionary(const std::string& dictionary_text,
63 size_t offset, 60 size_t offset,
64 const std::string& client_hash, 61 const std::string& client_hash,
65 const GURL& gurl, 62 const GURL& gurl,
66 const std::string& domain, 63 const std::string& domain,
67 const std::string& path, 64 const std::string& path,
68 const base::Time& expiration, 65 const base::Time& expiration,
69 const std::set<int>& ports) 66 const std::set<int>& ports)
70 : text_(dictionary_text, offset), 67 : text_(dictionary_text, offset),
71 client_hash_(client_hash), 68 client_hash_(client_hash),
72 url_(gurl), 69 url_(gurl),
73 domain_(domain), 70 domain_(domain),
74 path_(path), 71 path_(path),
75 expiration_(expiration), 72 expiration_(expiration),
76 ports_(ports) { 73 ports_(ports),
74 clock_(new base::DefaultClock) {
77 } 75 }
78 76
79 SdchManager::Dictionary::~Dictionary() { 77 SdchManager::Dictionary::Dictionary(const SdchManager::Dictionary& rhs)
80 } 78 : text_(rhs.text_),
79 client_hash_(rhs.client_hash_),
80 url_(rhs.url_),
81 domain_(rhs.domain_),
82 path_(rhs.path_),
83 expiration_(rhs.expiration_),
84 ports_(rhs.ports_),
85 clock_(new base::DefaultClock) {}
81 86
82 SdchProblemCode SdchManager::Dictionary::CanAdvertise( 87 SdchManager::Dictionary::~Dictionary() {}
83 const GURL& target_url) const {
84 /* The specific rules of when a dictionary should be advertised in an
85 Avail-Dictionary header are modeled after the rules for cookie scoping. The
86 terms "domain-match" and "pathmatch" are defined in RFC 2965 [6]. A
87 dictionary may be advertised in the Avail-Dictionaries header exactly when
88 all of the following are true:
89 1. The server's effective host name domain-matches the Domain attribute of
90 the dictionary.
91 2. If the dictionary has a Port attribute, the request port is one of the
92 ports listed in the Port attribute.
93 3. The request URI path-matches the path header of the dictionary.
94 4. The request is not an HTTPS request.
95 We can override (ignore) item (4) only when we have explicitly enabled
96 HTTPS support AND the dictionary acquisition scheme matches the target
97 url scheme.
98 */
99 if (!DomainMatch(target_url, domain_))
100 return SDCH_DICTIONARY_FOUND_HAS_WRONG_DOMAIN;
101 if (!ports_.empty() && 0 == ports_.count(target_url.EffectiveIntPort()))
102 return SDCH_DICTIONARY_FOUND_HAS_WRONG_PORT_LIST;
103 if (path_.size() && !PathMatch(target_url.path(), path_))
104 return SDCH_DICTIONARY_FOUND_HAS_WRONG_PATH;
105 if (!SdchManager::secure_scheme_supported() && target_url.SchemeIsSecure())
106 return SDCH_DICTIONARY_FOUND_HAS_WRONG_SCHEME;
107 if (target_url.SchemeIsSecure() != url_.SchemeIsSecure())
108 return SDCH_DICTIONARY_FOUND_HAS_WRONG_SCHEME;
109 if (base::Time::Now() > expiration_)
110 return SDCH_DICTIONARY_FOUND_EXPIRED;
111 return SDCH_OK;
112 }
113 88
114 //------------------------------------------------------------------------------
115 // Security functions restricting loads and use of dictionaries. 89 // Security functions restricting loads and use of dictionaries.
116 90
117 // static 91 // static
118 SdchProblemCode SdchManager::Dictionary::CanSet(const std::string& domain, 92 SdchProblemCode SdchManager::Dictionary::CanSet(const std::string& domain,
119 const std::string& path, 93 const std::string& path,
120 const std::set<int>& ports, 94 const std::set<int>& ports,
121 const GURL& dictionary_url) { 95 const GURL& dictionary_url) {
122 /* 96 /*
123 A dictionary is invalid and must not be stored if any of the following are 97 A dictionary is invalid and must not be stored if any of the following are
124 true: 98 true:
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 } 135 }
162 } 136 }
163 137
164 if (!ports.empty() && 0 == ports.count(dictionary_url.EffectiveIntPort())) 138 if (!ports.empty() && 0 == ports.count(dictionary_url.EffectiveIntPort()))
165 return SDCH_DICTIONARY_PORT_NOT_MATCHING_SOURCE_URL; 139 return SDCH_DICTIONARY_PORT_NOT_MATCHING_SOURCE_URL;
166 140
167 return SDCH_OK; 141 return SDCH_OK;
168 } 142 }
169 143
170 SdchProblemCode SdchManager::Dictionary::CanUse( 144 SdchProblemCode SdchManager::Dictionary::CanUse(
171 const GURL& referring_url) const { 145 const GURL& target_url) const {
172 /* 146 /*
173 1. The request URL's host name domain-matches the Domain attribute of the 147 1. The request URL's host name domain-matches the Domain attribute of the
174 dictionary. 148 dictionary.
175 2. If the dictionary has a Port attribute, the request port is one of the 149 2. If the dictionary has a Port attribute, the request port is one of the
176 ports listed in the Port attribute. 150 ports listed in the Port attribute.
177 3. The request URL path-matches the path attribute of the dictionary. 151 3. The request URL path-matches the path attribute of the dictionary.
178 4. The request is not an HTTPS request. 152 4. The request is not an HTTPS request.
179 We can override (ignore) item (4) only when we have explicitly enabled 153 We can override (ignore) item (4) only when we have explicitly enabled
180 HTTPS support AND the dictionary acquisition scheme matches the target 154 HTTPS support AND the dictionary acquisition scheme matches the target
181 url scheme. 155 url scheme.
182 */ 156 */
183 if (!DomainMatch(referring_url, domain_)) 157 if (!DomainMatch(target_url, domain_))
184 return SDCH_DICTIONARY_FOUND_HAS_WRONG_DOMAIN; 158 return SDCH_DICTIONARY_FOUND_HAS_WRONG_DOMAIN;
185 159
186 if (!ports_.empty() && 0 == ports_.count(referring_url.EffectiveIntPort())) 160 if (!ports_.empty() && 0 == ports_.count(target_url.EffectiveIntPort()))
187 return SDCH_DICTIONARY_FOUND_HAS_WRONG_PORT_LIST; 161 return SDCH_DICTIONARY_FOUND_HAS_WRONG_PORT_LIST;
188 162
189 if (path_.size() && !PathMatch(referring_url.path(), path_)) 163 if (path_.size() && !PathMatch(target_url.path(), path_))
190 return SDCH_DICTIONARY_FOUND_HAS_WRONG_PATH; 164 return SDCH_DICTIONARY_FOUND_HAS_WRONG_PATH;
191 165
192 if (!SdchManager::secure_scheme_supported() && referring_url.SchemeIsSecure()) 166 if (!SdchManager::secure_scheme_supported() && target_url.SchemeIsSecure())
193 return SDCH_DICTIONARY_FOUND_HAS_WRONG_SCHEME; 167 return SDCH_DICTIONARY_FOUND_HAS_WRONG_SCHEME;
194 168
195 if (referring_url.SchemeIsSecure() != url_.SchemeIsSecure()) 169 if (target_url.SchemeIsSecure() != url_.SchemeIsSecure())
196 return SDCH_DICTIONARY_FOUND_HAS_WRONG_SCHEME; 170 return SDCH_DICTIONARY_FOUND_HAS_WRONG_SCHEME;
197 171
198 // TODO(jar): Remove overly restrictive failsafe test (added per security 172 // TODO(jar): Remove overly restrictive failsafe test (added per security
199 // review) when we have a need to be more general. 173 // review) when we have a need to be more general.
200 if (!referring_url.SchemeIsHTTPOrHTTPS()) 174 if (!target_url.SchemeIsHTTPOrHTTPS())
201 return SDCH_ATTEMPT_TO_DECODE_NON_HTTP_DATA; 175 return SDCH_ATTEMPT_TO_DECODE_NON_HTTP_DATA;
202 176
203 return SDCH_OK; 177 return SDCH_OK;
204 } 178 }
205 179
206 // static 180 // static
207 bool SdchManager::Dictionary::PathMatch(const std::string& path, 181 bool SdchManager::Dictionary::PathMatch(const std::string& path,
208 const std::string& restriction) { 182 const std::string& restriction) {
209 /* Must be either: 183 /* Must be either:
210 1. P2 is equal to P1 184 1. P2 is equal to P1
(...skipping 10 matching lines...) Expand all
221 return restriction[prefix_length - 1] == '/' || path[prefix_length] == '/'; 195 return restriction[prefix_length - 1] == '/' || path[prefix_length] == '/';
222 } 196 }
223 197
224 // static 198 // static
225 bool SdchManager::Dictionary::DomainMatch(const GURL& gurl, 199 bool SdchManager::Dictionary::DomainMatch(const GURL& gurl,
226 const std::string& restriction) { 200 const std::string& restriction) {
227 // TODO(jar): This is not precisely a domain match definition. 201 // TODO(jar): This is not precisely a domain match definition.
228 return gurl.DomainIs(restriction.data(), restriction.size()); 202 return gurl.DomainIs(restriction.data(), restriction.size());
229 } 203 }
230 204
231 //------------------------------------------------------------------------------ 205 bool SdchManager::Dictionary::Expired() const {
206 return clock_->Now() > expiration_;
207 }
208
209 void SdchManager::Dictionary::SetClockForTesting(
210 scoped_ptr<base::Clock> clock) {
211 clock_ = clock.Pass();
212 }
213
214 SdchManager::DictionaryWrapper::DictionaryWrapper(
215 scoped_ptr<SdchManager::Dictionary> dictionary)
216 : dictionary_(dictionary.Pass()) {}
217
218 SdchManager::DictionaryWrapper::~DictionaryWrapper() {}
219
220 SdchManager::DictionarySet::DictionarySet() {}
221
222 SdchManager::DictionarySet::~DictionarySet() {}
223
224 std::string SdchManager::DictionarySet::GetDictionaryClientHashList() const {
225 std::string result;
226 bool first = true;
227 for (const auto& entry: dictionaries_) {
228 if (!first)
229 result.append(",");
230
231 result.append(entry.second->data.client_hash());
232 first = false;
233 }
234 return result;
235 }
236
237 const SdchManager::Dictionary* SdchManager::DictionarySet::Dictionary(
238 const std::string& hash) const {
239 auto it = dictionaries_.find(hash);
240 if (it == dictionaries_.end())
241 return NULL;
242
243 return &it->second->data;
244 }
245
246 bool SdchManager::DictionarySet::Empty() const {
247 return dictionaries_.empty();
248 }
249
250 void SdchManager::DictionarySet::AddDictionary(
251 const std::string& server_hash,
252 scoped_refptr<base::RefCountedData<SdchManager::Dictionary>> dictionary) {
253 DCHECK(dictionaries_.end() == dictionaries_.find(server_hash));
254
255 dictionaries_[server_hash] = dictionary;
256 }
257
232 SdchManager::SdchManager() { 258 SdchManager::SdchManager() {
233 DCHECK(thread_checker_.CalledOnValidThread()); 259 DCHECK(thread_checker_.CalledOnValidThread());
234 } 260 }
235 261
236 SdchManager::~SdchManager() { 262 SdchManager::~SdchManager() {
237 DCHECK(thread_checker_.CalledOnValidThread()); 263 DCHECK(thread_checker_.CalledOnValidThread());
238 while (!dictionaries_.empty()) { 264 while (!dictionaries_.empty()) {
239 DictionaryMap::iterator it = dictionaries_.begin(); 265 auto it = dictionaries_.begin();
240 dictionaries_.erase(it->first); 266 dictionaries_.erase(it->first);
241 } 267 }
242 } 268 }
243 269
244 void SdchManager::ClearData() { 270 void SdchManager::ClearData() {
245 blacklisted_domains_.clear(); 271 blacklisted_domains_.clear();
246 allow_latency_experiment_.clear(); 272 allow_latency_experiment_.clear();
247 273
248 // Note that this may result in not having dictionaries we've advertised 274 // Note that this may result in not having dictionaries we've advertised
249 // for incoming responses. The window is relatively small (as ClearData() 275 // for incoming responses. The window is relatively small (as ClearData()
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
396 return SDCH_DICTIONARY_SELECTED_FOR_SSL; 422 return SDCH_DICTIONARY_SELECTED_FOR_SSL;
397 423
398 // TODO(jar): Remove this failsafe conservative hack which is more restrictive 424 // TODO(jar): Remove this failsafe conservative hack which is more restrictive
399 // than current SDCH spec when needed, and justified by security audit. 425 // than current SDCH spec when needed, and justified by security audit.
400 if (!referring_url.SchemeIsHTTPOrHTTPS()) 426 if (!referring_url.SchemeIsHTTPOrHTTPS())
401 return SDCH_DICTIONARY_SELECTED_FROM_NON_HTTP; 427 return SDCH_DICTIONARY_SELECTED_FROM_NON_HTTP;
402 428
403 return SDCH_OK; 429 return SDCH_OK;
404 } 430 }
405 431
406 SdchProblemCode SdchManager::GetVcdiffDictionary( 432 scoped_ptr<SdchManager::DictionarySet>
407 const std::string& server_hash, 433 SdchManager::GetDictionarySet(const GURL& target_url) {
408 const GURL& referring_url, 434 if (IsInSupportedDomain(target_url) != SDCH_OK)
409 scoped_refptr<Dictionary>* dictionary) { 435 return NULL;
410 DCHECK(thread_checker_.CalledOnValidThread());
411 *dictionary = NULL;
412 DictionaryMap::iterator it = dictionaries_.find(server_hash);
413 if (it == dictionaries_.end())
414 return SDCH_DICTIONARY_HASH_NOT_FOUND;
415 436
416 scoped_refptr<Dictionary> matching_dictionary = it->second; 437 int count = 0;
438 scoped_ptr<SdchManager::DictionarySet> result(new DictionarySet);
439 for (const auto& entry: dictionaries_) {
440 if (entry.second->data.CanUse(target_url) != SDCH_OK)
441 continue;
442 if (entry.second->data.Expired())
443 continue;
444 ++count;
445 result->AddDictionary(entry.first, entry.second);
446 }
417 447
418 SdchProblemCode rv = IsInSupportedDomain(referring_url); 448 if (count == 0)
419 if (rv != SDCH_OK) 449 return NULL;
420 return rv;
421 450
422 rv = matching_dictionary->CanUse(referring_url); 451 UMA_HISTOGRAM_COUNTS("Sdch3.Advertisement_Count", count);
423 if (rv == SDCH_OK) 452
424 *dictionary = matching_dictionary; 453 return result.Pass();
425 return rv;
426 } 454 }
427 455
428 // TODO(jar): If we have evictions from the dictionaries_, then we need to 456 scoped_ptr<SdchManager::DictionarySet>
429 // change this interface to return a list of reference counted Dictionary 457 SdchManager::GetDictionarySetByHash(
430 // instances that can be used if/when a server specifies one. 458 const GURL& target_url,
431 void SdchManager::GetAvailDictionaryList(const GURL& target_url, 459 const std::string& server_hash,
432 std::string* list) { 460 SdchProblemCode* problem_code) {
433 DCHECK(thread_checker_.CalledOnValidThread()); 461 scoped_ptr<SdchManager::DictionarySet> result;
434 int count = 0;
435 for (DictionaryMap::iterator it = dictionaries_.begin();
436 it != dictionaries_.end(); ++it) {
437 SdchProblemCode rv = IsInSupportedDomain(target_url);
438 if (rv != SDCH_OK)
439 continue;
440 462
441 if (it->second->CanAdvertise(target_url) != SDCH_OK) 463 *problem_code = SDCH_DICTIONARY_HASH_NOT_FOUND;
442 continue; 464 auto it = dictionaries_.find(server_hash);
Ryan Sleevi 2014/11/20 22:50:29 Should this be a const auto&? Doesn't seem like yo
Randy Smith (Not in Mondays) 2014/11/20 23:44:28 Done.
443 ++count; 465 if (it == dictionaries_.end())
444 if (!list->empty()) 466 return result;
445 list->append(","); 467
446 list->append(it->second->client_hash()); 468 *problem_code = it->second->data.CanUse(target_url);
447 } 469 if (*problem_code != SDCH_OK)
448 // Watch to see if we have corrupt or numerous dictionaries. 470 return result;
449 if (count > 0) 471
450 UMA_HISTOGRAM_COUNTS("Sdch3.Advertisement_Count", count); 472 result.reset(new DictionarySet);
473 result->AddDictionary(it->first, it->second);
474 return result;
451 } 475 }
452 476
453 // static 477 // static
454 void SdchManager::GenerateHash(const std::string& dictionary_text, 478 void SdchManager::GenerateHash(const std::string& dictionary_text,
455 std::string* client_hash, std::string* server_hash) { 479 std::string* client_hash, std::string* server_hash) {
456 char binary_hash[32]; 480 char binary_hash[32];
457 crypto::SHA256HashString(dictionary_text, binary_hash, sizeof(binary_hash)); 481 crypto::SHA256HashString(dictionary_text, binary_hash, sizeof(binary_hash));
458 482
459 std::string first_48_bits(&binary_hash[0], 6); 483 std::string first_48_bits(&binary_hash[0], 6);
460 std::string second_48_bits(&binary_hash[6], 6); 484 std::string second_48_bits(&binary_hash[6], 6);
461 UrlSafeBase64Encode(first_48_bits, client_hash); 485 UrlSafeBase64Encode(first_48_bits, client_hash);
462 UrlSafeBase64Encode(second_48_bits, server_hash); 486 UrlSafeBase64Encode(second_48_bits, server_hash);
463 487
464 DCHECK_EQ(server_hash->length(), 8u); 488 DCHECK_EQ(server_hash->length(), 8u);
465 DCHECK_EQ(client_hash->length(), 8u); 489 DCHECK_EQ(client_hash->length(), 8u);
466 } 490 }
467 491
468 //------------------------------------------------------------------------------
469 // Methods for supporting latency experiments. 492 // Methods for supporting latency experiments.
470 493
471 bool SdchManager::AllowLatencyExperiment(const GURL& url) const { 494 bool SdchManager::AllowLatencyExperiment(const GURL& url) const {
472 DCHECK(thread_checker_.CalledOnValidThread()); 495 DCHECK(thread_checker_.CalledOnValidThread());
473 return allow_latency_experiment_.end() != 496 return allow_latency_experiment_.end() !=
474 allow_latency_experiment_.find(url.host()); 497 allow_latency_experiment_.find(url.host());
475 } 498 }
476 499
477 void SdchManager::SetAllowLatencyExperiment(const GURL& url, bool enable) { 500 void SdchManager::SetAllowLatencyExperiment(const GURL& url, bool enable) {
478 DCHECK(thread_checker_.CalledOnValidThread()); 501 DCHECK(thread_checker_.CalledOnValidThread());
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
580 // is probably not worth doing eviction handling. 603 // is probably not worth doing eviction handling.
581 if (kMaxDictionarySize < dictionary_text.size()) 604 if (kMaxDictionarySize < dictionary_text.size())
582 return SDCH_DICTIONARY_IS_TOO_LARGE; 605 return SDCH_DICTIONARY_IS_TOO_LARGE;
583 606
584 if (kMaxDictionaryCount <= dictionaries_.size()) 607 if (kMaxDictionaryCount <= dictionaries_.size())
585 return SDCH_DICTIONARY_COUNT_EXCEEDED; 608 return SDCH_DICTIONARY_COUNT_EXCEEDED;
586 609
587 UMA_HISTOGRAM_COUNTS("Sdch3.Dictionary size loaded", dictionary_text.size()); 610 UMA_HISTOGRAM_COUNTS("Sdch3.Dictionary size loaded", dictionary_text.size());
588 DVLOG(1) << "Loaded dictionary with client hash " << client_hash 611 DVLOG(1) << "Loaded dictionary with client hash " << client_hash
589 << " and server hash " << server_hash; 612 << " and server hash " << server_hash;
590 Dictionary* dictionary = 613 Dictionary dictionary(dictionary_text, header_end + 2, client_hash,
591 new Dictionary(dictionary_text, header_end + 2, client_hash, 614 dictionary_url_normalized, domain, path, expiration,
592 dictionary_url_normalized, domain, 615 ports);
593 path, expiration, ports); 616 dictionaries_[server_hash] =
594 dictionaries_[server_hash] = dictionary; 617 new base::RefCountedData<Dictionary>(dictionary);
618
595 return SDCH_OK; 619 return SDCH_OK;
596 } 620 }
597 621
598 // static 622 // static
623 scoped_ptr<SdchManager::DictionarySet>
624 SdchManager::CreateEmptyDictionarySetForTesting() {
625 return scoped_ptr<DictionarySet>(new DictionarySet).Pass();
626 }
627
628 // static
599 void SdchManager::UrlSafeBase64Encode(const std::string& input, 629 void SdchManager::UrlSafeBase64Encode(const std::string& input,
600 std::string* output) { 630 std::string* output) {
601 // Since this is only done during a dictionary load, and hashes are only 8 631 // Since this is only done during a dictionary load, and hashes are only 8
602 // characters, we just do the simple fixup, rather than rewriting the encoder. 632 // characters, we just do the simple fixup, rather than rewriting the encoder.
603 base::Base64Encode(input, output); 633 base::Base64Encode(input, output);
604 std::replace(output->begin(), output->end(), '+', '-'); 634 std::replace(output->begin(), output->end(), '+', '-');
605 std::replace(output->begin(), output->end(), '/', '_'); 635 std::replace(output->begin(), output->end(), '/', '_');
606 } 636 }
607 637
608 base::Value* SdchManager::SdchInfoToValue() const { 638 base::Value* SdchManager::SdchInfoToValue() const {
609 base::DictionaryValue* value = new base::DictionaryValue(); 639 base::DictionaryValue* value = new base::DictionaryValue();
610 640
611 value->SetBoolean("sdch_enabled", sdch_enabled()); 641 value->SetBoolean("sdch_enabled", sdch_enabled());
612 value->SetBoolean("secure_scheme_support", secure_scheme_supported()); 642 value->SetBoolean("secure_scheme_support", secure_scheme_supported());
613 643
614 base::ListValue* entry_list = new base::ListValue(); 644 base::ListValue* entry_list = new base::ListValue();
615 for (DictionaryMap::const_iterator it = dictionaries_.begin(); 645 for (const auto& entry: dictionaries_) {
616 it != dictionaries_.end(); ++it) {
617 base::DictionaryValue* entry_dict = new base::DictionaryValue(); 646 base::DictionaryValue* entry_dict = new base::DictionaryValue();
618 entry_dict->SetString("url", it->second->url().spec()); 647 entry_dict->SetString("url", entry.second->data.url().spec());
619 entry_dict->SetString("client_hash", it->second->client_hash()); 648 entry_dict->SetString("client_hash", entry.second->data.client_hash());
620 entry_dict->SetString("domain", it->second->domain()); 649 entry_dict->SetString("domain", entry.second->data.domain());
621 entry_dict->SetString("path", it->second->path()); 650 entry_dict->SetString("path", entry.second->data.path());
622 base::ListValue* port_list = new base::ListValue(); 651 base::ListValue* port_list = new base::ListValue();
623 for (std::set<int>::const_iterator port_it = it->second->ports().begin(); 652 for (std::set<int>::const_iterator port_it =
624 port_it != it->second->ports().end(); ++port_it) { 653 entry.second->data.ports().begin();
654 port_it != entry.second->data.ports().end(); ++port_it) {
625 port_list->AppendInteger(*port_it); 655 port_list->AppendInteger(*port_it);
626 } 656 }
627 entry_dict->Set("ports", port_list); 657 entry_dict->Set("ports", port_list);
628 entry_dict->SetString("server_hash", it->first); 658 entry_dict->SetString("server_hash", entry.first);
629 entry_list->Append(entry_dict); 659 entry_list->Append(entry_dict);
630 } 660 }
631 value->Set("dictionaries", entry_list); 661 value->Set("dictionaries", entry_list);
632 662
633 entry_list = new base::ListValue(); 663 entry_list = new base::ListValue();
634 for (DomainBlacklistInfo::const_iterator it = blacklisted_domains_.begin(); 664 for (DomainBlacklistInfo::const_iterator it = blacklisted_domains_.begin();
635 it != blacklisted_domains_.end(); ++it) { 665 it != blacklisted_domains_.end(); ++it) {
636 if (it->second.count == 0) 666 if (it->second.count == 0)
637 continue; 667 continue;
638 base::DictionaryValue* entry_dict = new base::DictionaryValue(); 668 base::DictionaryValue* entry_dict = new base::DictionaryValue();
639 entry_dict->SetString("domain", it->first); 669 entry_dict->SetString("domain", it->first);
640 if (it->second.count != INT_MAX) 670 if (it->second.count != INT_MAX)
641 entry_dict->SetInteger("tries", it->second.count); 671 entry_dict->SetInteger("tries", it->second.count);
642 entry_dict->SetInteger("reason", it->second.reason); 672 entry_dict->SetInteger("reason", it->second.reason);
643 entry_list->Append(entry_dict); 673 entry_list->Append(entry_dict);
644 } 674 }
645 value->Set("blacklisted", entry_list); 675 value->Set("blacklisted", entry_list);
646 676
647 return value; 677 return value;
648 } 678 }
649 679
650 } // namespace net 680 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698