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

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

Issue 754433003: Update from https://crrev.com/305340 (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: 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
« no previous file with comments | « net/base/sdch_manager.h ('k') | net/base/sdch_manager_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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::DictionarySet::DictionarySet() {}
215
216 SdchManager::DictionarySet::~DictionarySet() {}
217
218 std::string SdchManager::DictionarySet::GetDictionaryClientHashList() const {
219 std::string result;
220 bool first = true;
221 for (const auto& entry: dictionaries_) {
222 if (!first)
223 result.append(",");
224
225 result.append(entry.second->data.client_hash());
226 first = false;
227 }
228 return result;
229 }
230
231 const SdchManager::Dictionary* SdchManager::DictionarySet::GetDictionary(
232 const std::string& hash) const {
233 auto it = dictionaries_.find(hash);
234 if (it == dictionaries_.end())
235 return NULL;
236
237 return &it->second->data;
238 }
239
240 bool SdchManager::DictionarySet::Empty() const {
241 return dictionaries_.empty();
242 }
243
244 void SdchManager::DictionarySet::AddDictionary(
245 const std::string& server_hash,
246 const scoped_refptr<base::RefCountedData<SdchManager::Dictionary>>&
247 dictionary) {
248 DCHECK(dictionaries_.end() == dictionaries_.find(server_hash));
249
250 dictionaries_[server_hash] = dictionary;
251 }
252
232 SdchManager::SdchManager() { 253 SdchManager::SdchManager() {
233 DCHECK(thread_checker_.CalledOnValidThread()); 254 DCHECK(thread_checker_.CalledOnValidThread());
234 } 255 }
235 256
236 SdchManager::~SdchManager() { 257 SdchManager::~SdchManager() {
237 DCHECK(thread_checker_.CalledOnValidThread()); 258 DCHECK(thread_checker_.CalledOnValidThread());
238 while (!dictionaries_.empty()) { 259 while (!dictionaries_.empty()) {
239 DictionaryMap::iterator it = dictionaries_.begin(); 260 auto it = dictionaries_.begin();
240 dictionaries_.erase(it->first); 261 dictionaries_.erase(it->first);
241 } 262 }
242 } 263 }
243 264
244 void SdchManager::ClearData() { 265 void SdchManager::ClearData() {
245 blacklisted_domains_.clear(); 266 blacklisted_domains_.clear();
246 allow_latency_experiment_.clear(); 267 allow_latency_experiment_.clear();
247 268
248 // Note that this may result in not having dictionaries we've advertised 269 // Note that this may result in not having dictionaries we've advertised
249 // for incoming responses. The window is relatively small (as ClearData() 270 // for incoming responses. The window is relatively small (as ClearData()
250 // is not expected to be called frequently), so we rely on meta-refresh 271 // is not expected to be called frequently), so we rely on meta-refresh
251 // to handle this case. 272 // to handle this case.
252 dictionaries_.clear(); 273 dictionaries_.clear();
253 274
254 FOR_EACH_OBSERVER(SdchObserver, observers_, OnClearDictionaries(this)); 275 FOR_EACH_OBSERVER(SdchObserver, observers_, OnClearDictionaries(this));
255 } 276 }
256 277
257 // static 278 // static
258 void SdchManager::SdchErrorRecovery(SdchProblemCode problem) { 279 void SdchManager::SdchErrorRecovery(SdchProblemCode problem) {
259 UMA_HISTOGRAM_ENUMERATION("Sdch3.ProblemCodes_5", problem, 280 UMA_HISTOGRAM_ENUMERATION("Sdch3.ProblemCodes_5", problem,
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
379 DCHECK(thread_checker_.CalledOnValidThread()); 400 DCHECK(thread_checker_.CalledOnValidThread());
380 /* The user agent may retrieve a dictionary from the dictionary URL if all of 401 /* The user agent may retrieve a dictionary from the dictionary URL if all of
381 the following are true: 402 the following are true:
382 1 The dictionary URL host name matches the referrer URL host name and 403 1 The dictionary URL host name matches the referrer URL host name and
383 scheme. 404 scheme.
384 2 The dictionary URL host name domain matches the parent domain of the 405 2 The dictionary URL host name domain matches the parent domain of the
385 referrer URL host name 406 referrer URL host name
386 3 The parent domain of the referrer URL host name is not a top level 407 3 The parent domain of the referrer URL host name is not a top level
387 domain 408 domain
388 */ 409 */
389 // Item (1) above implies item (2). Spec should be updated. 410 // Item (1) above implies item (2). Spec should be updated.
390 // I take "host name match" to be "is identical to" 411 // I take "host name match" to be "is identical to"
391 if (referring_url.host() != dictionary_url.host() || 412 if (referring_url.host() != dictionary_url.host() ||
392 referring_url.scheme() != dictionary_url.scheme()) 413 referring_url.scheme() != dictionary_url.scheme())
393 return SDCH_DICTIONARY_LOAD_ATTEMPT_FROM_DIFFERENT_HOST; 414 return SDCH_DICTIONARY_LOAD_ATTEMPT_FROM_DIFFERENT_HOST;
394 415
395 if (!secure_scheme_supported() && referring_url.SchemeIsSecure()) 416 if (!secure_scheme_supported() && referring_url.SchemeIsSecure())
396 return SDCH_DICTIONARY_SELECTED_FOR_SSL; 417 return SDCH_DICTIONARY_SELECTED_FOR_SSL;
397 418
398 // TODO(jar): Remove this failsafe conservative hack which is more restrictive 419 // TODO(jar): Remove this failsafe conservative hack which is more restrictive
399 // than current SDCH spec when needed, and justified by security audit. 420 // than current SDCH spec when needed, and justified by security audit.
400 if (!referring_url.SchemeIsHTTPOrHTTPS()) 421 if (!referring_url.SchemeIsHTTPOrHTTPS())
401 return SDCH_DICTIONARY_SELECTED_FROM_NON_HTTP; 422 return SDCH_DICTIONARY_SELECTED_FROM_NON_HTTP;
402 423
403 return SDCH_OK; 424 return SDCH_OK;
404 } 425 }
405 426
406 SdchProblemCode SdchManager::GetVcdiffDictionary( 427 scoped_ptr<SdchManager::DictionarySet>
407 const std::string& server_hash, 428 SdchManager::GetDictionarySet(const GURL& target_url) {
408 const GURL& referring_url, 429 if (IsInSupportedDomain(target_url) != SDCH_OK)
409 scoped_refptr<Dictionary>* dictionary) { 430 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 431
416 scoped_refptr<Dictionary> matching_dictionary = it->second; 432 int count = 0;
433 scoped_ptr<SdchManager::DictionarySet> result(new DictionarySet);
434 for (const auto& entry: dictionaries_) {
435 if (entry.second->data.CanUse(target_url) != SDCH_OK)
436 continue;
437 if (entry.second->data.Expired())
438 continue;
439 ++count;
440 result->AddDictionary(entry.first, entry.second);
441 }
417 442
418 SdchProblemCode rv = IsInSupportedDomain(referring_url); 443 if (count == 0)
419 if (rv != SDCH_OK) 444 return NULL;
420 return rv;
421 445
422 rv = matching_dictionary->CanUse(referring_url); 446 UMA_HISTOGRAM_COUNTS("Sdch3.Advertisement_Count", count);
423 if (rv == SDCH_OK) 447
424 *dictionary = matching_dictionary; 448 return result.Pass();
425 return rv;
426 } 449 }
427 450
428 // TODO(jar): If we have evictions from the dictionaries_, then we need to 451 scoped_ptr<SdchManager::DictionarySet>
429 // change this interface to return a list of reference counted Dictionary 452 SdchManager::GetDictionarySetByHash(
430 // instances that can be used if/when a server specifies one. 453 const GURL& target_url,
431 void SdchManager::GetAvailDictionaryList(const GURL& target_url, 454 const std::string& server_hash,
432 std::string* list) { 455 SdchProblemCode* problem_code) {
433 DCHECK(thread_checker_.CalledOnValidThread()); 456 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 457
441 if (it->second->CanAdvertise(target_url) != SDCH_OK) 458 *problem_code = SDCH_DICTIONARY_HASH_NOT_FOUND;
442 continue; 459 const auto& it = dictionaries_.find(server_hash);
443 ++count; 460 if (it == dictionaries_.end())
444 if (!list->empty()) 461 return result;
445 list->append(","); 462
446 list->append(it->second->client_hash()); 463 *problem_code = it->second->data.CanUse(target_url);
447 } 464 if (*problem_code != SDCH_OK)
448 // Watch to see if we have corrupt or numerous dictionaries. 465 return result;
449 if (count > 0) 466
450 UMA_HISTOGRAM_COUNTS("Sdch3.Advertisement_Count", count); 467 result.reset(new DictionarySet);
468 result->AddDictionary(it->first, it->second);
469 return result;
451 } 470 }
452 471
453 // static 472 // static
454 void SdchManager::GenerateHash(const std::string& dictionary_text, 473 void SdchManager::GenerateHash(const std::string& dictionary_text,
455 std::string* client_hash, std::string* server_hash) { 474 std::string* client_hash, std::string* server_hash) {
456 char binary_hash[32]; 475 char binary_hash[32];
457 crypto::SHA256HashString(dictionary_text, binary_hash, sizeof(binary_hash)); 476 crypto::SHA256HashString(dictionary_text, binary_hash, sizeof(binary_hash));
458 477
459 std::string first_48_bits(&binary_hash[0], 6); 478 std::string first_48_bits(&binary_hash[0], 6);
460 std::string second_48_bits(&binary_hash[6], 6); 479 std::string second_48_bits(&binary_hash[6], 6);
461 UrlSafeBase64Encode(first_48_bits, client_hash); 480 UrlSafeBase64Encode(first_48_bits, client_hash);
462 UrlSafeBase64Encode(second_48_bits, server_hash); 481 UrlSafeBase64Encode(second_48_bits, server_hash);
463 482
464 DCHECK_EQ(server_hash->length(), 8u); 483 DCHECK_EQ(server_hash->length(), 8u);
465 DCHECK_EQ(client_hash->length(), 8u); 484 DCHECK_EQ(client_hash->length(), 8u);
466 } 485 }
467 486
468 //------------------------------------------------------------------------------
469 // Methods for supporting latency experiments. 487 // Methods for supporting latency experiments.
470 488
471 bool SdchManager::AllowLatencyExperiment(const GURL& url) const { 489 bool SdchManager::AllowLatencyExperiment(const GURL& url) const {
472 DCHECK(thread_checker_.CalledOnValidThread()); 490 DCHECK(thread_checker_.CalledOnValidThread());
473 return allow_latency_experiment_.end() != 491 return allow_latency_experiment_.end() !=
474 allow_latency_experiment_.find(url.host()); 492 allow_latency_experiment_.find(url.host());
475 } 493 }
476 494
477 void SdchManager::SetAllowLatencyExperiment(const GURL& url, bool enable) { 495 void SdchManager::SetAllowLatencyExperiment(const GURL& url, bool enable) {
478 DCHECK(thread_checker_.CalledOnValidThread()); 496 DCHECK(thread_checker_.CalledOnValidThread());
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
568 586
569 SdchProblemCode rv = IsInSupportedDomain(dictionary_url_normalized); 587 SdchProblemCode rv = IsInSupportedDomain(dictionary_url_normalized);
570 if (rv != SDCH_OK) 588 if (rv != SDCH_OK)
571 return rv; 589 return rv;
572 590
573 rv = Dictionary::CanSet(domain, path, ports, dictionary_url_normalized); 591 rv = Dictionary::CanSet(domain, path, ports, dictionary_url_normalized);
574 if (rv != SDCH_OK) 592 if (rv != SDCH_OK)
575 return rv; 593 return rv;
576 594
577 // TODO(jar): Remove these hacks to preclude a DOS attack involving piles of 595 // TODO(jar): Remove these hacks to preclude a DOS attack involving piles of
578 // useless dictionaries. We should probably have a cache eviction plan, 596 // useless dictionaries. We should probably have a cache eviction plan,
579 // instead of just blocking additions. For now, with the spec in flux, it 597 // instead of just blocking additions. For now, with the spec in flux, it
580 // is probably not worth doing eviction handling. 598 // is probably not worth doing eviction handling.
581 if (kMaxDictionarySize < dictionary_text.size()) 599 if (kMaxDictionarySize < dictionary_text.size())
582 return SDCH_DICTIONARY_IS_TOO_LARGE; 600 return SDCH_DICTIONARY_IS_TOO_LARGE;
583 601
584 if (kMaxDictionaryCount <= dictionaries_.size()) 602 if (kMaxDictionaryCount <= dictionaries_.size())
585 return SDCH_DICTIONARY_COUNT_EXCEEDED; 603 return SDCH_DICTIONARY_COUNT_EXCEEDED;
586 604
587 UMA_HISTOGRAM_COUNTS("Sdch3.Dictionary size loaded", dictionary_text.size()); 605 UMA_HISTOGRAM_COUNTS("Sdch3.Dictionary size loaded", dictionary_text.size());
588 DVLOG(1) << "Loaded dictionary with client hash " << client_hash 606 DVLOG(1) << "Loaded dictionary with client hash " << client_hash
589 << " and server hash " << server_hash; 607 << " and server hash " << server_hash;
590 Dictionary* dictionary = 608 Dictionary dictionary(dictionary_text, header_end + 2, client_hash,
591 new Dictionary(dictionary_text, header_end + 2, client_hash, 609 dictionary_url_normalized, domain, path, expiration,
592 dictionary_url_normalized, domain, 610 ports);
593 path, expiration, ports); 611 dictionaries_[server_hash] =
594 dictionaries_[server_hash] = dictionary; 612 new base::RefCountedData<Dictionary>(dictionary);
613
595 return SDCH_OK; 614 return SDCH_OK;
596 } 615 }
597 616
598 // static 617 // static
618 scoped_ptr<SdchManager::DictionarySet>
619 SdchManager::CreateEmptyDictionarySetForTesting() {
620 return scoped_ptr<DictionarySet>(new DictionarySet).Pass();
621 }
622
623 // static
599 void SdchManager::UrlSafeBase64Encode(const std::string& input, 624 void SdchManager::UrlSafeBase64Encode(const std::string& input,
600 std::string* output) { 625 std::string* output) {
601 // Since this is only done during a dictionary load, and hashes are only 8 626 // 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. 627 // characters, we just do the simple fixup, rather than rewriting the encoder.
603 base::Base64Encode(input, output); 628 base::Base64Encode(input, output);
604 std::replace(output->begin(), output->end(), '+', '-'); 629 std::replace(output->begin(), output->end(), '+', '-');
605 std::replace(output->begin(), output->end(), '/', '_'); 630 std::replace(output->begin(), output->end(), '/', '_');
606 } 631 }
607 632
608 base::Value* SdchManager::SdchInfoToValue() const { 633 base::Value* SdchManager::SdchInfoToValue() const {
609 base::DictionaryValue* value = new base::DictionaryValue(); 634 base::DictionaryValue* value = new base::DictionaryValue();
610 635
611 value->SetBoolean("sdch_enabled", sdch_enabled()); 636 value->SetBoolean("sdch_enabled", sdch_enabled());
612 value->SetBoolean("secure_scheme_support", secure_scheme_supported()); 637 value->SetBoolean("secure_scheme_support", secure_scheme_supported());
613 638
614 base::ListValue* entry_list = new base::ListValue(); 639 base::ListValue* entry_list = new base::ListValue();
615 for (DictionaryMap::const_iterator it = dictionaries_.begin(); 640 for (const auto& entry: dictionaries_) {
616 it != dictionaries_.end(); ++it) {
617 base::DictionaryValue* entry_dict = new base::DictionaryValue(); 641 base::DictionaryValue* entry_dict = new base::DictionaryValue();
618 entry_dict->SetString("url", it->second->url().spec()); 642 entry_dict->SetString("url", entry.second->data.url().spec());
619 entry_dict->SetString("client_hash", it->second->client_hash()); 643 entry_dict->SetString("client_hash", entry.second->data.client_hash());
620 entry_dict->SetString("domain", it->second->domain()); 644 entry_dict->SetString("domain", entry.second->data.domain());
621 entry_dict->SetString("path", it->second->path()); 645 entry_dict->SetString("path", entry.second->data.path());
622 base::ListValue* port_list = new base::ListValue(); 646 base::ListValue* port_list = new base::ListValue();
623 for (std::set<int>::const_iterator port_it = it->second->ports().begin(); 647 for (std::set<int>::const_iterator port_it =
624 port_it != it->second->ports().end(); ++port_it) { 648 entry.second->data.ports().begin();
649 port_it != entry.second->data.ports().end(); ++port_it) {
625 port_list->AppendInteger(*port_it); 650 port_list->AppendInteger(*port_it);
626 } 651 }
627 entry_dict->Set("ports", port_list); 652 entry_dict->Set("ports", port_list);
628 entry_dict->SetString("server_hash", it->first); 653 entry_dict->SetString("server_hash", entry.first);
629 entry_list->Append(entry_dict); 654 entry_list->Append(entry_dict);
630 } 655 }
631 value->Set("dictionaries", entry_list); 656 value->Set("dictionaries", entry_list);
632 657
633 entry_list = new base::ListValue(); 658 entry_list = new base::ListValue();
634 for (DomainBlacklistInfo::const_iterator it = blacklisted_domains_.begin(); 659 for (DomainBlacklistInfo::const_iterator it = blacklisted_domains_.begin();
635 it != blacklisted_domains_.end(); ++it) { 660 it != blacklisted_domains_.end(); ++it) {
636 if (it->second.count == 0) 661 if (it->second.count == 0)
637 continue; 662 continue;
638 base::DictionaryValue* entry_dict = new base::DictionaryValue(); 663 base::DictionaryValue* entry_dict = new base::DictionaryValue();
639 entry_dict->SetString("domain", it->first); 664 entry_dict->SetString("domain", it->first);
640 if (it->second.count != INT_MAX) 665 if (it->second.count != INT_MAX)
641 entry_dict->SetInteger("tries", it->second.count); 666 entry_dict->SetInteger("tries", it->second.count);
642 entry_dict->SetInteger("reason", it->second.reason); 667 entry_dict->SetInteger("reason", it->second.reason);
643 entry_list->Append(entry_dict); 668 entry_list->Append(entry_dict);
644 } 669 }
645 value->Set("blacklisted", entry_list); 670 value->Set("blacklisted", entry_list);
646 671
647 return value; 672 return value;
648 } 673 }
649 674
650 } // namespace net 675 } // namespace net
OLDNEW
« no previous file with comments | « net/base/sdch_manager.h ('k') | net/base/sdch_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698