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 |