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

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

Issue 706203003: Update from https://crrev.com/303153 (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 "crypto/sha2.h" 12 #include "crypto/sha2.h"
13 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" 13 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
14 #include "net/base/sdch_observer.h"
14 #include "net/url_request/url_request_http_job.h" 15 #include "net/url_request/url_request_http_job.h"
15 16
16 namespace { 17 namespace {
17 18
18 void StripTrailingDot(GURL* gurl) { 19 void StripTrailingDot(GURL* gurl) {
19 std::string host(gurl->host()); 20 std::string host(gurl->host());
20 21
21 if (host.empty()) 22 if (host.empty())
22 return; 23 return;
23 24
(...skipping 20 matching lines...) Expand all
44 // static 45 // static
45 const size_t SdchManager::kMaxDictionaryCount = 1; 46 const size_t SdchManager::kMaxDictionaryCount = 1;
46 const size_t SdchManager::kMaxDictionarySize = 500 * 1000; 47 const size_t SdchManager::kMaxDictionarySize = 500 * 1000;
47 #else 48 #else
48 // static 49 // static
49 const size_t SdchManager::kMaxDictionaryCount = 20; 50 const size_t SdchManager::kMaxDictionaryCount = 20;
50 const size_t SdchManager::kMaxDictionarySize = 1000 * 1000; 51 const size_t SdchManager::kMaxDictionarySize = 1000 * 1000;
51 #endif 52 #endif
52 53
53 // static 54 // static
54 #if defined(OS_IOS)
55 // Workaround for http://crbug.com/418975; remove when fixed.
56 bool SdchManager::g_sdch_enabled_ = false;
57 #else
58 bool SdchManager::g_sdch_enabled_ = true; 55 bool SdchManager::g_sdch_enabled_ = true;
59 #endif
60 56
61 // static 57 // static
62 bool SdchManager::g_secure_scheme_supported_ = true; 58 bool SdchManager::g_secure_scheme_supported_ = true;
63 59
64 //------------------------------------------------------------------------------ 60 //------------------------------------------------------------------------------
65 SdchManager::Dictionary::Dictionary(const std::string& dictionary_text, 61 SdchManager::Dictionary::Dictionary(const std::string& dictionary_text,
66 size_t offset, 62 size_t offset,
67 const std::string& client_hash, 63 const std::string& client_hash,
68 const GURL& gurl, 64 const GURL& gurl,
69 const std::string& domain, 65 const std::string& domain,
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 } 235 }
240 236
241 // static 237 // static
242 bool SdchManager::Dictionary::DomainMatch(const GURL& gurl, 238 bool SdchManager::Dictionary::DomainMatch(const GURL& gurl,
243 const std::string& restriction) { 239 const std::string& restriction) {
244 // TODO(jar): This is not precisely a domain match definition. 240 // TODO(jar): This is not precisely a domain match definition.
245 return gurl.DomainIs(restriction.data(), restriction.size()); 241 return gurl.DomainIs(restriction.data(), restriction.size());
246 } 242 }
247 243
248 //------------------------------------------------------------------------------ 244 //------------------------------------------------------------------------------
249 SdchManager::SdchManager() 245 SdchManager::SdchManager() {
250 : fetches_count_for_testing_(0) { 246 DCHECK(thread_checker_.CalledOnValidThread());
251 DCHECK(CalledOnValidThread());
252 } 247 }
253 248
254 SdchManager::~SdchManager() { 249 SdchManager::~SdchManager() {
255 DCHECK(CalledOnValidThread()); 250 DCHECK(thread_checker_.CalledOnValidThread());
256 while (!dictionaries_.empty()) { 251 while (!dictionaries_.empty()) {
257 DictionaryMap::iterator it = dictionaries_.begin(); 252 DictionaryMap::iterator it = dictionaries_.begin();
258 dictionaries_.erase(it->first); 253 dictionaries_.erase(it->first);
259 } 254 }
260 } 255 }
261 256
262 void SdchManager::ClearData() { 257 void SdchManager::ClearData() {
263 blacklisted_domains_.clear(); 258 blacklisted_domains_.clear();
264 allow_latency_experiment_.clear(); 259 allow_latency_experiment_.clear();
265 if (fetcher_.get())
266 fetcher_->Cancel();
267 260
268 // Note that this may result in not having dictionaries we've advertised 261 // Note that this may result in not having dictionaries we've advertised
269 // for incoming responses. The window is relatively small (as ClearData() 262 // for incoming responses. The window is relatively small (as ClearData()
270 // is not expected to be called frequently), so we rely on meta-refresh 263 // is not expected to be called frequently), so we rely on meta-refresh
271 // to handle this case. 264 // to handle this case.
272 dictionaries_.clear(); 265 dictionaries_.clear();
266
267 FOR_EACH_OBSERVER(SdchObserver, observers_, OnClearDictionaries(this));
273 } 268 }
274 269
275 // static 270 // static
276 void SdchManager::SdchErrorRecovery(ProblemCodes problem) { 271 void SdchManager::SdchErrorRecovery(ProblemCodes problem) {
277 UMA_HISTOGRAM_ENUMERATION("Sdch3.ProblemCodes_4", problem, MAX_PROBLEM_CODE); 272 UMA_HISTOGRAM_ENUMERATION("Sdch3.ProblemCodes_4", problem, MAX_PROBLEM_CODE);
278 } 273 }
279 274
280 void SdchManager::set_sdch_fetcher(scoped_ptr<SdchFetcher> fetcher) {
281 DCHECK(CalledOnValidThread());
282 fetcher_ = fetcher.Pass();
283 }
284
285 // static 275 // static
286 void SdchManager::EnableSdchSupport(bool enabled) { 276 void SdchManager::EnableSdchSupport(bool enabled) {
287 g_sdch_enabled_ = enabled; 277 g_sdch_enabled_ = enabled;
288 } 278 }
289 279
290 // static 280 // static
291 void SdchManager::EnableSecureSchemeSupport(bool enabled) { 281 void SdchManager::EnableSecureSchemeSupport(bool enabled) {
292 g_secure_scheme_supported_ = enabled; 282 g_secure_scheme_supported_ = enabled;
293 } 283 }
294 284
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 335
346 int SdchManager::BlacklistDomainExponential(const std::string& domain) { 336 int SdchManager::BlacklistDomainExponential(const std::string& domain) {
347 std::string domain_lower(base::StringToLowerASCII(domain)); 337 std::string domain_lower(base::StringToLowerASCII(domain));
348 338
349 if (blacklisted_domains_.end() == blacklisted_domains_.find(domain_lower)) 339 if (blacklisted_domains_.end() == blacklisted_domains_.find(domain_lower))
350 return 0; 340 return 0;
351 return blacklisted_domains_[domain_lower].exponential_count; 341 return blacklisted_domains_[domain_lower].exponential_count;
352 } 342 }
353 343
354 bool SdchManager::IsInSupportedDomain(const GURL& url) { 344 bool SdchManager::IsInSupportedDomain(const GURL& url) {
355 DCHECK(CalledOnValidThread()); 345 DCHECK(thread_checker_.CalledOnValidThread());
356 if (!g_sdch_enabled_ ) 346 if (!g_sdch_enabled_ )
357 return false; 347 return false;
358 348
359 if (!secure_scheme_supported() && url.SchemeIsSecure()) 349 if (!secure_scheme_supported() && url.SchemeIsSecure())
360 return false; 350 return false;
361 351
362 if (blacklisted_domains_.empty()) 352 if (blacklisted_domains_.empty())
363 return true; 353 return true;
364 354
365 DomainBlacklistInfo::iterator it = 355 DomainBlacklistInfo::iterator it =
366 blacklisted_domains_.find(base::StringToLowerASCII(url.host())); 356 blacklisted_domains_.find(base::StringToLowerASCII(url.host()));
367 if (blacklisted_domains_.end() == it || it->second.count == 0) 357 if (blacklisted_domains_.end() == it || it->second.count == 0)
368 return true; 358 return true;
369 359
370 UMA_HISTOGRAM_ENUMERATION("Sdch3.BlacklistReason", it->second.reason, 360 UMA_HISTOGRAM_ENUMERATION("Sdch3.BlacklistReason", it->second.reason,
371 MAX_PROBLEM_CODE); 361 MAX_PROBLEM_CODE);
372 SdchErrorRecovery(DOMAIN_BLACKLIST_INCLUDES_TARGET); 362 SdchErrorRecovery(DOMAIN_BLACKLIST_INCLUDES_TARGET);
373 363
374 int count = it->second.count - 1; 364 int count = it->second.count - 1;
375 if (count > 0) { 365 if (count > 0) {
376 it->second.count = count; 366 it->second.count = count;
377 } else { 367 } else {
378 it->second.count = 0; 368 it->second.count = 0;
379 it->second.reason = MIN_PROBLEM_CODE; 369 it->second.reason = MIN_PROBLEM_CODE;
380 } 370 }
381 371
382 return false; 372 return false;
383 } 373 }
384 374
385 void SdchManager::FetchDictionary(const GURL& request_url, 375 void SdchManager::OnGetDictionary(const GURL& request_url,
386 const GURL& dictionary_url) { 376 const GURL& dictionary_url) {
387 DCHECK(CalledOnValidThread()); 377 if (!CanFetchDictionary(request_url, dictionary_url))
388 if (CanFetchDictionary(request_url, dictionary_url) && fetcher_.get()) { 378 return;
389 ++fetches_count_for_testing_; 379
390 fetcher_->Schedule(dictionary_url); 380 FOR_EACH_OBSERVER(SdchObserver,
391 } 381 observers_,
382 OnGetDictionary(this, request_url, dictionary_url));
392 } 383 }
393 384
394 bool SdchManager::CanFetchDictionary(const GURL& referring_url, 385 bool SdchManager::CanFetchDictionary(const GURL& referring_url,
395 const GURL& dictionary_url) const { 386 const GURL& dictionary_url) const {
396 DCHECK(CalledOnValidThread()); 387 DCHECK(thread_checker_.CalledOnValidThread());
397 /* The user agent may retrieve a dictionary from the dictionary URL if all of 388 /* The user agent may retrieve a dictionary from the dictionary URL if all of
398 the following are true: 389 the following are true:
399 1 The dictionary URL host name matches the referrer URL host name and 390 1 The dictionary URL host name matches the referrer URL host name and
400 scheme. 391 scheme.
401 2 The dictionary URL host name domain matches the parent domain of the 392 2 The dictionary URL host name domain matches the parent domain of the
402 referrer URL host name 393 referrer URL host name
403 3 The parent domain of the referrer URL host name is not a top level 394 3 The parent domain of the referrer URL host name is not a top level
404 domain 395 domain
405 4 The dictionary URL is not an HTTPS URL.
406 */ 396 */
407 // Item (1) above implies item (2). Spec should be updated. 397 // Item (1) above implies item (2). Spec should be updated.
408 // I take "host name match" to be "is identical to" 398 // I take "host name match" to be "is identical to"
409 if (referring_url.host() != dictionary_url.host() || 399 if (referring_url.host() != dictionary_url.host() ||
410 referring_url.scheme() != dictionary_url.scheme()) { 400 referring_url.scheme() != dictionary_url.scheme()) {
411 SdchErrorRecovery(DICTIONARY_LOAD_ATTEMPT_FROM_DIFFERENT_HOST); 401 SdchErrorRecovery(DICTIONARY_LOAD_ATTEMPT_FROM_DIFFERENT_HOST);
412 return false; 402 return false;
413 } 403 }
414 if (!secure_scheme_supported() && referring_url.SchemeIsSecure()) { 404 if (!secure_scheme_supported() && referring_url.SchemeIsSecure()) {
415 SdchErrorRecovery(DICTIONARY_SELECTED_FOR_SSL); 405 SdchErrorRecovery(DICTIONARY_SELECTED_FOR_SSL);
416 return false; 406 return false;
417 } 407 }
418 408
419 // TODO(jar): Remove this failsafe conservative hack which is more restrictive 409 // TODO(jar): Remove this failsafe conservative hack which is more restrictive
420 // than current SDCH spec when needed, and justified by security audit. 410 // than current SDCH spec when needed, and justified by security audit.
421 if (!referring_url.SchemeIsHTTPOrHTTPS()) { 411 if (!referring_url.SchemeIsHTTPOrHTTPS()) {
422 SdchErrorRecovery(DICTIONARY_SELECTED_FROM_NON_HTTP); 412 SdchErrorRecovery(DICTIONARY_SELECTED_FROM_NON_HTTP);
423 return false; 413 return false;
424 } 414 }
425 415
426 return true; 416 return true;
427 } 417 }
428 418
429 void SdchManager::GetVcdiffDictionary( 419 void SdchManager::GetVcdiffDictionary(
430 const std::string& server_hash, 420 const std::string& server_hash,
431 const GURL& referring_url, 421 const GURL& referring_url,
432 scoped_refptr<Dictionary>* dictionary) { 422 scoped_refptr<Dictionary>* dictionary) {
433 DCHECK(CalledOnValidThread()); 423 DCHECK(thread_checker_.CalledOnValidThread());
434 *dictionary = NULL; 424 *dictionary = NULL;
435 DictionaryMap::iterator it = dictionaries_.find(server_hash); 425 DictionaryMap::iterator it = dictionaries_.find(server_hash);
436 if (it == dictionaries_.end()) { 426 if (it == dictionaries_.end()) {
437 return; 427 return;
438 } 428 }
439 scoped_refptr<Dictionary> matching_dictionary = it->second; 429 scoped_refptr<Dictionary> matching_dictionary = it->second;
440 if (!IsInSupportedDomain(referring_url)) 430 if (!IsInSupportedDomain(referring_url))
441 return; 431 return;
442 if (!matching_dictionary->CanUse(referring_url)) 432 if (!matching_dictionary->CanUse(referring_url))
443 return; 433 return;
444 *dictionary = matching_dictionary; 434 *dictionary = matching_dictionary;
445 } 435 }
446 436
447 // TODO(jar): If we have evictions from the dictionaries_, then we need to 437 // TODO(jar): If we have evictions from the dictionaries_, then we need to
448 // change this interface to return a list of reference counted Dictionary 438 // change this interface to return a list of reference counted Dictionary
449 // instances that can be used if/when a server specifies one. 439 // instances that can be used if/when a server specifies one.
450 void SdchManager::GetAvailDictionaryList(const GURL& target_url, 440 void SdchManager::GetAvailDictionaryList(const GURL& target_url,
451 std::string* list) { 441 std::string* list) {
452 DCHECK(CalledOnValidThread()); 442 DCHECK(thread_checker_.CalledOnValidThread());
453 int count = 0; 443 int count = 0;
454 for (DictionaryMap::iterator it = dictionaries_.begin(); 444 for (DictionaryMap::iterator it = dictionaries_.begin();
455 it != dictionaries_.end(); ++it) { 445 it != dictionaries_.end(); ++it) {
456 if (!IsInSupportedDomain(target_url)) 446 if (!IsInSupportedDomain(target_url))
457 continue; 447 continue;
458 if (!it->second->CanAdvertise(target_url)) 448 if (!it->second->CanAdvertise(target_url))
459 continue; 449 continue;
460 ++count; 450 ++count;
461 if (!list->empty()) 451 if (!list->empty())
462 list->append(","); 452 list->append(",");
(...skipping 16 matching lines...) Expand all
479 UrlSafeBase64Encode(second_48_bits, server_hash); 469 UrlSafeBase64Encode(second_48_bits, server_hash);
480 470
481 DCHECK_EQ(server_hash->length(), 8u); 471 DCHECK_EQ(server_hash->length(), 8u);
482 DCHECK_EQ(client_hash->length(), 8u); 472 DCHECK_EQ(client_hash->length(), 8u);
483 } 473 }
484 474
485 //------------------------------------------------------------------------------ 475 //------------------------------------------------------------------------------
486 // Methods for supporting latency experiments. 476 // Methods for supporting latency experiments.
487 477
488 bool SdchManager::AllowLatencyExperiment(const GURL& url) const { 478 bool SdchManager::AllowLatencyExperiment(const GURL& url) const {
489 DCHECK(CalledOnValidThread()); 479 DCHECK(thread_checker_.CalledOnValidThread());
490 return allow_latency_experiment_.end() != 480 return allow_latency_experiment_.end() !=
491 allow_latency_experiment_.find(url.host()); 481 allow_latency_experiment_.find(url.host());
492 } 482 }
493 483
494 void SdchManager::SetAllowLatencyExperiment(const GURL& url, bool enable) { 484 void SdchManager::SetAllowLatencyExperiment(const GURL& url, bool enable) {
495 DCHECK(CalledOnValidThread()); 485 DCHECK(thread_checker_.CalledOnValidThread());
496 if (enable) { 486 if (enable) {
497 allow_latency_experiment_.insert(url.host()); 487 allow_latency_experiment_.insert(url.host());
498 return; 488 return;
499 } 489 }
500 ExperimentSet::iterator it = allow_latency_experiment_.find(url.host()); 490 ExperimentSet::iterator it = allow_latency_experiment_.find(url.host());
501 if (allow_latency_experiment_.end() == it) 491 if (allow_latency_experiment_.end() == it)
502 return; // It was already erased, or never allowed. 492 return; // It was already erased, or never allowed.
503 SdchErrorRecovery(LATENCY_TEST_DISALLOWED); 493 SdchErrorRecovery(LATENCY_TEST_DISALLOWED);
504 allow_latency_experiment_.erase(it); 494 allow_latency_experiment_.erase(it);
505 } 495 }
506 496
497 void SdchManager::AddObserver(SdchObserver* observer) {
498 observers_.AddObserver(observer);
499 }
500
501 void SdchManager::RemoveObserver(SdchObserver* observer) {
502 observers_.RemoveObserver(observer);
503 }
504
507 void SdchManager::AddSdchDictionary(const std::string& dictionary_text, 505 void SdchManager::AddSdchDictionary(const std::string& dictionary_text,
508 const GURL& dictionary_url) { 506 const GURL& dictionary_url) {
509 DCHECK(CalledOnValidThread()); 507 DCHECK(thread_checker_.CalledOnValidThread());
510 std::string client_hash; 508 std::string client_hash;
511 std::string server_hash; 509 std::string server_hash;
512 GenerateHash(dictionary_text, &client_hash, &server_hash); 510 GenerateHash(dictionary_text, &client_hash, &server_hash);
513 if (dictionaries_.find(server_hash) != dictionaries_.end()) { 511 if (dictionaries_.find(server_hash) != dictionaries_.end()) {
514 SdchErrorRecovery(DICTIONARY_ALREADY_LOADED); 512 SdchErrorRecovery(DICTIONARY_ALREADY_LOADED);
515 return; // Already loaded. 513 return; // Already loaded.
516 } 514 }
517 515
518 std::string domain, path; 516 std::string domain, path;
519 std::set<int> ports; 517 std::set<int> ports;
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
614 void SdchManager::UrlSafeBase64Encode(const std::string& input, 612 void SdchManager::UrlSafeBase64Encode(const std::string& input,
615 std::string* output) { 613 std::string* output) {
616 // Since this is only done during a dictionary load, and hashes are only 8 614 // Since this is only done during a dictionary load, and hashes are only 8
617 // characters, we just do the simple fixup, rather than rewriting the encoder. 615 // characters, we just do the simple fixup, rather than rewriting the encoder.
618 base::Base64Encode(input, output); 616 base::Base64Encode(input, output);
619 std::replace(output->begin(), output->end(), '+', '-'); 617 std::replace(output->begin(), output->end(), '+', '-');
620 std::replace(output->begin(), output->end(), '/', '_'); 618 std::replace(output->begin(), output->end(), '/', '_');
621 } 619 }
622 620
623 } // namespace net 621 } // 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