Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/url_request/url_request_http_job.h" | 14 #include "net/url_request/url_request_http_job.h" |
| 15 | 15 |
| 16 namespace { | |
| 17 | |
| 18 // Canonicalize a URL from possibly containing a FQDN to the HDN format | |
| 19 // specified in RFC 2965 so that trailing periods for (e.g.) domain matching | |
| 20 // are not a concern. | |
| 21 bool FQDNToHDN(std::string* host) { | |
|
Ryan Sleevi
2014/09/18 01:22:31
1) Naming: "HDN" is not common
2) RFC 2965 is obso
Randy Smith (Not in Mondays)
2014/09/22 19:22:10
Changed to "StripTrailingDot" and edited the expla
| |
| 22 if (host->at(host->size() - 1) != '.') | |
|
Ryan Sleevi
2014/09/18 01:22:31
Why are you using at (which throws) vs [] (which d
Randy Smith (Not in Mondays)
2014/09/22 19:22:10
Because I found (*host)[] awkward and wasn't aware
| |
| 23 return false; | |
| 24 | |
| 25 host->resize(host->size() - 1); | |
| 26 return true; | |
| 27 } | |
| 28 | |
| 29 void FQDNToHDNURL(GURL* gurl) { | |
| 30 std::string host(gurl->host()); | |
| 31 | |
| 32 if (!FQDNToHDN(&host)) | |
| 33 return; | |
| 34 | |
| 35 GURL::Replacements replacements; | |
| 36 replacements.SetHostStr(host); | |
| 37 *gurl = gurl->ReplaceComponents(replacements); | |
| 38 return; | |
| 39 } | |
| 40 | |
| 41 } // namespace | |
| 42 | |
| 16 namespace net { | 43 namespace net { |
| 17 | 44 |
| 18 //------------------------------------------------------------------------------ | 45 //------------------------------------------------------------------------------ |
| 19 // static | 46 // static |
| 20 | 47 |
| 21 // Adjust SDCH limits downwards for mobile. | 48 // Adjust SDCH limits downwards for mobile. |
| 22 #if defined(OS_ANDROID) || defined(OS_IOS) | 49 #if defined(OS_ANDROID) || defined(OS_IOS) |
| 23 // static | 50 // static |
| 24 const size_t SdchManager::kMaxDictionaryCount = 1; | 51 const size_t SdchManager::kMaxDictionaryCount = 1; |
| 25 const size_t SdchManager::kMaxDictionarySize = 500 * 1000; | 52 const size_t SdchManager::kMaxDictionarySize = 500 * 1000; |
| (...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 398 } | 425 } |
| 399 | 426 |
| 400 return true; | 427 return true; |
| 401 } | 428 } |
| 402 | 429 |
| 403 void SdchManager::GetVcdiffDictionary( | 430 void SdchManager::GetVcdiffDictionary( |
| 404 const std::string& server_hash, | 431 const std::string& server_hash, |
| 405 const GURL& referring_url, | 432 const GURL& referring_url, |
| 406 scoped_refptr<Dictionary>* dictionary) { | 433 scoped_refptr<Dictionary>* dictionary) { |
| 407 DCHECK(CalledOnValidThread()); | 434 DCHECK(CalledOnValidThread()); |
| 435 | |
| 436 GURL referring_url_hdn(referring_url); | |
| 437 FQDNToHDNURL(&referring_url_hdn); | |
| 438 | |
| 408 *dictionary = NULL; | 439 *dictionary = NULL; |
| 409 DictionaryMap::iterator it = dictionaries_.find(server_hash); | 440 DictionaryMap::iterator it = dictionaries_.find(server_hash); |
| 410 if (it == dictionaries_.end()) { | 441 if (it == dictionaries_.end()) { |
| 411 return; | 442 return; |
| 412 } | 443 } |
| 413 scoped_refptr<Dictionary> matching_dictionary = it->second; | 444 scoped_refptr<Dictionary> matching_dictionary = it->second; |
| 414 if (!IsInSupportedDomain(referring_url)) | 445 if (!IsInSupportedDomain(referring_url_hdn)) |
| 415 return; | 446 return; |
| 416 if (!matching_dictionary->CanUse(referring_url)) | 447 if (!matching_dictionary->CanUse(referring_url_hdn)) |
|
Ryan Sleevi
2014/09/18 01:22:30
1) Why do these functions use GURLs, rather than j
Randy Smith (Not in Mondays)
2014/09/22 19:22:10
I'm presuming you mean IsInSupportedDomain() and C
| |
| 417 return; | 448 return; |
| 418 *dictionary = matching_dictionary; | 449 *dictionary = matching_dictionary; |
| 419 } | 450 } |
| 420 | 451 |
| 421 // TODO(jar): If we have evictions from the dictionaries_, then we need to | 452 // TODO(jar): If we have evictions from the dictionaries_, then we need to |
| 422 // change this interface to return a list of reference counted Dictionary | 453 // change this interface to return a list of reference counted Dictionary |
| 423 // instances that can be used if/when a server specifies one. | 454 // instances that can be used if/when a server specifies one. |
| 424 void SdchManager::GetAvailDictionaryList(const GURL& target_url, | 455 void SdchManager::GetAvailDictionaryList(const GURL& target_url, |
| 425 std::string* list) { | 456 std::string* list) { |
| 426 DCHECK(CalledOnValidThread()); | 457 DCHECK(CalledOnValidThread()); |
| 458 | |
| 459 GURL target_url_hdn(target_url); | |
| 460 FQDNToHDNURL(&target_url_hdn); | |
| 461 | |
| 427 int count = 0; | 462 int count = 0; |
| 428 for (DictionaryMap::iterator it = dictionaries_.begin(); | 463 for (DictionaryMap::iterator it = dictionaries_.begin(); |
| 429 it != dictionaries_.end(); ++it) { | 464 it != dictionaries_.end(); ++it) { |
| 430 if (!IsInSupportedDomain(target_url)) | 465 if (!IsInSupportedDomain(target_url_hdn)) |
| 431 continue; | 466 continue; |
| 432 if (!it->second->CanAdvertise(target_url)) | 467 if (!it->second->CanAdvertise(target_url_hdn)) |
| 433 continue; | 468 continue; |
| 434 ++count; | 469 ++count; |
| 435 if (!list->empty()) | 470 if (!list->empty()) |
| 436 list->append(","); | 471 list->append(","); |
| 437 list->append(it->second->client_hash()); | 472 list->append(it->second->client_hash()); |
| 438 } | 473 } |
| 439 // Watch to see if we have corrupt or numerous dictionaries. | 474 // Watch to see if we have corrupt or numerous dictionaries. |
| 440 if (count > 0) | 475 if (count > 0) |
| 441 UMA_HISTOGRAM_COUNTS("Sdch3.Advertisement_Count", count); | 476 UMA_HISTOGRAM_COUNTS("Sdch3.Advertisement_Count", count); |
| 442 } | 477 } |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 543 if (port >= 0) | 578 if (port >= 0) |
| 544 ports.insert(port); | 579 ports.insert(port); |
| 545 } | 580 } |
| 546 } | 581 } |
| 547 | 582 |
| 548 if (line_end >= header_end) | 583 if (line_end >= header_end) |
| 549 break; | 584 break; |
| 550 line_start = line_end + 1; | 585 line_start = line_end + 1; |
| 551 } | 586 } |
| 552 | 587 |
| 553 if (!IsInSupportedDomain(dictionary_url)) | 588 // Convert away from FQDN to the HDN format described in RFC 2695. |
| 589 FQDNToHDN(&domain); | |
| 590 GURL dictionary_url_hdn(dictionary_url); | |
| 591 FQDNToHDNURL(&dictionary_url_hdn); | |
| 592 | |
| 593 if (!IsInSupportedDomain(dictionary_url_hdn)) | |
| 554 return; | 594 return; |
| 555 | 595 |
| 556 if (!Dictionary::CanSet(domain, path, ports, dictionary_url)) | 596 if (!Dictionary::CanSet(domain, path, ports, dictionary_url_hdn)) |
| 557 return; | 597 return; |
| 558 | 598 |
| 559 // TODO(jar): Remove these hacks to preclude a DOS attack involving piles of | 599 // TODO(jar): Remove these hacks to preclude a DOS attack involving piles of |
| 560 // useless dictionaries. We should probably have a cache eviction plan, | 600 // useless dictionaries. We should probably have a cache eviction plan, |
| 561 // instead of just blocking additions. For now, with the spec in flux, it | 601 // instead of just blocking additions. For now, with the spec in flux, it |
| 562 // is probably not worth doing eviction handling. | 602 // is probably not worth doing eviction handling. |
| 563 if (kMaxDictionarySize < dictionary_text.size()) { | 603 if (kMaxDictionarySize < dictionary_text.size()) { |
| 564 SdchErrorRecovery(DICTIONARY_IS_TOO_LARGE); | 604 SdchErrorRecovery(DICTIONARY_IS_TOO_LARGE); |
| 565 return; | 605 return; |
| 566 } | 606 } |
| 567 if (kMaxDictionaryCount <= dictionaries_.size()) { | 607 if (kMaxDictionaryCount <= dictionaries_.size()) { |
| 568 SdchErrorRecovery(DICTIONARY_COUNT_EXCEEDED); | 608 SdchErrorRecovery(DICTIONARY_COUNT_EXCEEDED); |
| 569 return; | 609 return; |
| 570 } | 610 } |
| 571 | 611 |
| 572 UMA_HISTOGRAM_COUNTS("Sdch3.Dictionary size loaded", dictionary_text.size()); | 612 UMA_HISTOGRAM_COUNTS("Sdch3.Dictionary size loaded", dictionary_text.size()); |
| 573 DVLOG(1) << "Loaded dictionary with client hash " << client_hash | 613 DVLOG(1) << "Loaded dictionary with client hash " << client_hash |
| 574 << " and server hash " << server_hash; | 614 << " and server hash " << server_hash; |
| 575 Dictionary* dictionary = | 615 Dictionary* dictionary = |
| 576 new Dictionary(dictionary_text, header_end + 2, client_hash, | 616 new Dictionary(dictionary_text, header_end + 2, client_hash, |
| 577 dictionary_url, domain, path, expiration, ports); | 617 dictionary_url_hdn, domain, path, expiration, ports); |
| 578 dictionaries_[server_hash] = dictionary; | 618 dictionaries_[server_hash] = dictionary; |
| 579 return; | 619 return; |
| 580 } | 620 } |
| 581 | 621 |
| 582 // static | 622 // static |
| 583 void SdchManager::UrlSafeBase64Encode(const std::string& input, | 623 void SdchManager::UrlSafeBase64Encode(const std::string& input, |
| 584 std::string* output) { | 624 std::string* output) { |
| 585 // Since this is only done during a dictionary load, and hashes are only 8 | 625 // Since this is only done during a dictionary load, and hashes are only 8 |
| 586 // characters, we just do the simple fixup, rather than rewriting the encoder. | 626 // characters, we just do the simple fixup, rather than rewriting the encoder. |
| 587 base::Base64Encode(input, output); | 627 base::Base64Encode(input, output); |
| 588 std::replace(output->begin(), output->end(), '+', '-'); | 628 std::replace(output->begin(), output->end(), '+', '-'); |
| 589 std::replace(output->begin(), output->end(), '/', '_'); | 629 std::replace(output->begin(), output->end(), '/', '_'); |
| 590 } | 630 } |
| 591 | 631 |
| 592 } // namespace net | 632 } // namespace net |
| OLD | NEW |