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 |