| Index: net/base/sdch_manager.cc
|
| diff --git a/net/base/sdch_manager.cc b/net/base/sdch_manager.cc
|
| index 1285ad9383aa1784d92ebd3481c910f69454b091..e064e525a76ba545df687c01066760d083966ec5 100644
|
| --- a/net/base/sdch_manager.cc
|
| +++ b/net/base/sdch_manager.cc
|
| @@ -78,37 +78,6 @@ SdchManager::Dictionary::Dictionary(const std::string& dictionary_text,
|
| SdchManager::Dictionary::~Dictionary() {
|
| }
|
|
|
| -bool SdchManager::Dictionary::CanAdvertise(const GURL& target_url) {
|
| - /* The specific rules of when a dictionary should be advertised in an
|
| - Avail-Dictionary header are modeled after the rules for cookie scoping. The
|
| - terms "domain-match" and "pathmatch" are defined in RFC 2965 [6]. A
|
| - dictionary may be advertised in the Avail-Dictionaries header exactly when
|
| - all of the following are true:
|
| - 1. The server's effective host name domain-matches the Domain attribute of
|
| - the dictionary.
|
| - 2. If the dictionary has a Port attribute, the request port is one of the
|
| - ports listed in the Port attribute.
|
| - 3. The request URI path-matches the path header of the dictionary.
|
| - 4. The request is not an HTTPS request.
|
| - We can override (ignore) item (4) only when we have explicitly enabled
|
| - HTTPS support AND the dictionary acquisition scheme matches the target
|
| - url scheme.
|
| - */
|
| - if (!DomainMatch(target_url, domain_))
|
| - return false;
|
| - if (!ports_.empty() && 0 == ports_.count(target_url.EffectiveIntPort()))
|
| - return false;
|
| - if (path_.size() && !PathMatch(target_url.path(), path_))
|
| - return false;
|
| - if (!SdchManager::secure_scheme_supported() && target_url.SchemeIsSecure())
|
| - return false;
|
| - if (target_url.SchemeIsSecure() != url_.SchemeIsSecure())
|
| - return false;
|
| - if (base::Time::Now() > expiration_)
|
| - return false;
|
| - return true;
|
| -}
|
| -
|
| //------------------------------------------------------------------------------
|
| // Security functions restricting loads and use of dictionaries.
|
|
|
| @@ -171,8 +140,8 @@ bool SdchManager::Dictionary::CanSet(const std::string& domain,
|
| return true;
|
| }
|
|
|
| -// static
|
| -bool SdchManager::Dictionary::CanUse(const GURL& referring_url) {
|
| +SdchManager::ProblemCodes
|
| +SdchManager::Dictionary::CanUse(const GURL& target_url) {
|
| /*
|
| 1. The request URL's host name domain-matches the Domain attribute of the
|
| dictionary.
|
| @@ -184,37 +153,23 @@ bool SdchManager::Dictionary::CanUse(const GURL& referring_url) {
|
| HTTPS support AND the dictionary acquisition scheme matches the target
|
| url scheme.
|
| */
|
| - if (!DomainMatch(referring_url, domain_)) {
|
| - SdchErrorRecovery(DICTIONARY_FOUND_HAS_WRONG_DOMAIN);
|
| - return false;
|
| - }
|
| - if (!ports_.empty()
|
| - && 0 == ports_.count(referring_url.EffectiveIntPort())) {
|
| - SdchErrorRecovery(DICTIONARY_FOUND_HAS_WRONG_PORT_LIST);
|
| - return false;
|
| - }
|
| - if (path_.size() && !PathMatch(referring_url.path(), path_)) {
|
| - SdchErrorRecovery(DICTIONARY_FOUND_HAS_WRONG_PATH);
|
| - return false;
|
| - }
|
| - if (!SdchManager::secure_scheme_supported() &&
|
| - referring_url.SchemeIsSecure()) {
|
| - SdchErrorRecovery(DICTIONARY_FOUND_HAS_WRONG_SCHEME);
|
| - return false;
|
| - }
|
| - if (referring_url.SchemeIsSecure() != url_.SchemeIsSecure()) {
|
| - SdchErrorRecovery(DICTIONARY_FOUND_HAS_WRONG_SCHEME);
|
| - return false;
|
| - }
|
| + if (!DomainMatch(target_url, domain_))
|
| + return DICTIONARY_FOUND_HAS_WRONG_DOMAIN;
|
| + if (!ports_.empty() && 0 == ports_.count(target_url.EffectiveIntPort()))
|
| + return DICTIONARY_FOUND_HAS_WRONG_PORT_LIST;
|
| + if (path_.size() && !PathMatch(target_url.path(), path_))
|
| + return DICTIONARY_FOUND_HAS_WRONG_PATH;
|
| + if (!SdchManager::secure_scheme_supported() && target_url.SchemeIsSecure())
|
| + return DICTIONARY_FOUND_HAS_WRONG_SCHEME;
|
| + if (target_url.SchemeIsSecure() != url_.SchemeIsSecure())
|
| + return DICTIONARY_FOUND_HAS_WRONG_SCHEME;
|
|
|
| // TODO(jar): Remove overly restrictive failsafe test (added per security
|
| // review) when we have a need to be more general.
|
| - if (!referring_url.SchemeIsHTTPOrHTTPS()) {
|
| - SdchErrorRecovery(ATTEMPT_TO_DECODE_NON_HTTP_DATA);
|
| - return false;
|
| - }
|
| + if (!target_url.SchemeIsHTTPOrHTTPS())
|
| + return ATTEMPT_TO_DECODE_NON_HTTP_DATA;
|
|
|
| - return true;
|
| + return OK;
|
| }
|
|
|
| bool SdchManager::Dictionary::PathMatch(const std::string& path,
|
| @@ -241,6 +196,53 @@ bool SdchManager::Dictionary::DomainMatch(const GURL& gurl,
|
| return gurl.DomainIs(restriction.data(), restriction.size());
|
| }
|
|
|
| +bool SdchManager::Dictionary::Expired() const {
|
| + return base::Time::Now() > expiration_;
|
| +}
|
| +
|
| +//------------------------------------------------------------------------------
|
| +SdchManager::DictionaryWrapper::DictionaryWrapper(
|
| + scoped_ptr<SdchManager::Dictionary> dictionary)
|
| + : dictionary_(dictionary.Pass()) {}
|
| +
|
| +SdchManager::DictionaryWrapper::~DictionaryWrapper() {}
|
| +
|
| +//------------------------------------------------------------------------------
|
| +SdchManager::DictionarySet::DictionarySet() {}
|
| +
|
| +SdchManager::DictionarySet::~DictionarySet() {}
|
| +
|
| +void SdchManager::DictionarySet::GetDictionaryClientHashList(
|
| + std::string* client_hashes) const {
|
| + for (auto it = dictionaries_.begin(); it != dictionaries_.end(); ++it) {
|
| + if (it != dictionaries_.begin())
|
| + client_hashes->append(",");
|
| +
|
| + client_hashes->append(it->second->dictionary()->client_hash());
|
| + }
|
| +}
|
| +
|
| +const SdchManager::Dictionary* SdchManager::DictionarySet::Dictionary(
|
| + const std::string& hash) const {
|
| + auto it = dictionaries_.find(hash);
|
| + if (it == dictionaries_.end())
|
| + return NULL;
|
| +
|
| + return it->second->dictionary();
|
| +}
|
| +
|
| +bool SdchManager::DictionarySet::Empty() const {
|
| + return dictionaries_.empty();
|
| +}
|
| +
|
| +void SdchManager::DictionarySet::AddDictionary(
|
| + const std::string& server_hash,
|
| + scoped_refptr<SdchManager::DictionaryWrapper> dictionary) {
|
| + DCHECK(dictionaries_.end() == dictionaries_.find(server_hash));
|
| +
|
| + dictionaries_[server_hash] = dictionary;
|
| +}
|
| +
|
| //------------------------------------------------------------------------------
|
| SdchManager::SdchManager() {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
| @@ -249,7 +251,7 @@ SdchManager::SdchManager() {
|
| SdchManager::~SdchManager() {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
| while (!dictionaries_.empty()) {
|
| - DictionaryMap::iterator it = dictionaries_.begin();
|
| + auto it = dictionaries_.begin();
|
| dictionaries_.erase(it->first);
|
| }
|
| }
|
| @@ -322,7 +324,7 @@ void SdchManager::ClearDomainBlacklisting(const std::string& domain) {
|
| BlacklistInfo* blacklist_info = &blacklisted_domains_[
|
| base::StringToLowerASCII(domain)];
|
| blacklist_info->count = 0;
|
| - blacklist_info->reason = MIN_PROBLEM_CODE;
|
| + blacklist_info->reason = OK;
|
| }
|
|
|
| int SdchManager::BlackListDomainCount(const std::string& domain) {
|
| @@ -366,7 +368,7 @@ bool SdchManager::IsInSupportedDomain(const GURL& url) {
|
| it->second.count = count;
|
| } else {
|
| it->second.count = 0;
|
| - it->second.reason = MIN_PROBLEM_CODE;
|
| + it->second.reason = OK;
|
| }
|
|
|
| return false;
|
| @@ -416,45 +418,49 @@ bool SdchManager::CanFetchDictionary(const GURL& referring_url,
|
| return true;
|
| }
|
|
|
| -void SdchManager::GetVcdiffDictionary(
|
| - const std::string& server_hash,
|
| - const GURL& referring_url,
|
| - scoped_refptr<Dictionary>* dictionary) {
|
| - DCHECK(thread_checker_.CalledOnValidThread());
|
| - *dictionary = NULL;
|
| - DictionaryMap::iterator it = dictionaries_.find(server_hash);
|
| - if (it == dictionaries_.end()) {
|
| - return;
|
| - }
|
| - scoped_refptr<Dictionary> matching_dictionary = it->second;
|
| - if (!IsInSupportedDomain(referring_url))
|
| - return;
|
| - if (!matching_dictionary->CanUse(referring_url))
|
| - return;
|
| - *dictionary = matching_dictionary;
|
| -}
|
| +scoped_ptr<SdchManager::DictionarySet>
|
| +SdchManager::GetDictionarySet(const GURL& target_url) {
|
| + if (!IsInSupportedDomain(target_url))
|
| + return NULL;
|
|
|
| -// TODO(jar): If we have evictions from the dictionaries_, then we need to
|
| -// change this interface to return a list of reference counted Dictionary
|
| -// instances that can be used if/when a server specifies one.
|
| -void SdchManager::GetAvailDictionaryList(const GURL& target_url,
|
| - std::string* list) {
|
| - DCHECK(thread_checker_.CalledOnValidThread());
|
| int count = 0;
|
| - for (DictionaryMap::iterator it = dictionaries_.begin();
|
| + scoped_ptr<SdchManager::DictionarySet> result(new DictionarySet);
|
| + for (auto it = dictionaries_.begin();
|
| it != dictionaries_.end(); ++it) {
|
| - if (!IsInSupportedDomain(target_url))
|
| + if (it->second->dictionary()->CanUse(target_url) != OK)
|
| continue;
|
| - if (!it->second->CanAdvertise(target_url))
|
| + if (it->second->dictionary()->Expired())
|
| continue;
|
| ++count;
|
| - if (!list->empty())
|
| - list->append(",");
|
| - list->append(it->second->client_hash());
|
| + result->AddDictionary(it->first, it->second);
|
| }
|
| - // Watch to see if we have corrupt or numerous dictionaries.
|
| - if (count > 0)
|
| - UMA_HISTOGRAM_COUNTS("Sdch3.Advertisement_Count", count);
|
| +
|
| + if (count == 0)
|
| + return NULL;
|
| +
|
| + UMA_HISTOGRAM_COUNTS("Sdch3.Advertisement_Count", count);
|
| +
|
| + return result.Pass();
|
| +}
|
| +
|
| +scoped_ptr<SdchManager::DictionarySet>
|
| +SdchManager::GetDictionarySetByHash(
|
| + const GURL& target_url, const std::string& server_hash) {
|
| + scoped_ptr<SdchManager::DictionarySet> result;
|
| +
|
| + auto it = dictionaries_.find(server_hash);
|
| + if (it == dictionaries_.end())
|
| + return result;
|
| +
|
| + ProblemCodes ret = it->second->dictionary()->CanUse(target_url);
|
| + if (ret != OK) {
|
| + SdchErrorRecovery(ret);
|
| + return result;
|
| + }
|
| +
|
| + result.reset(new DictionarySet);
|
| + result->AddDictionary(it->first, it->second);
|
| + return result;
|
| }
|
|
|
| // static
|
| @@ -600,15 +606,21 @@ void SdchManager::AddSdchDictionary(const std::string& dictionary_text,
|
| UMA_HISTOGRAM_COUNTS("Sdch3.Dictionary size loaded", dictionary_text.size());
|
| DVLOG(1) << "Loaded dictionary with client hash " << client_hash
|
| << " and server hash " << server_hash;
|
| - Dictionary* dictionary =
|
| + scoped_ptr<Dictionary> dictionary(
|
| new Dictionary(dictionary_text, header_end + 2, client_hash,
|
| dictionary_url_normalized, domain,
|
| - path, expiration, ports);
|
| - dictionaries_[server_hash] = dictionary;
|
| + path, expiration, ports));
|
| + dictionaries_[server_hash] = new DictionaryWrapper(dictionary.Pass());
|
| return;
|
| }
|
|
|
| // static
|
| +scoped_ptr<SdchManager::DictionarySet>
|
| +SdchManager::CreateNullDictionarySetForTesting() {
|
| + return scoped_ptr<DictionarySet>(new DictionarySet).Pass();
|
| +}
|
| +
|
| +// static
|
| void SdchManager::UrlSafeBase64Encode(const std::string& input,
|
| std::string* output) {
|
| // Since this is only done during a dictionary load, and hashes are only 8
|
|
|