| Index: net/base/sdch_manager.cc | 
| diff --git a/net/base/sdch_manager.cc b/net/base/sdch_manager.cc | 
| index bd687970297c6642a8d8598e62a4e6773cff84d7..59589fb544723d386fa37019dd30a574cd8432d0 100644 | 
| --- a/net/base/sdch_manager.cc | 
| +++ b/net/base/sdch_manager.cc | 
| @@ -400,7 +400,85 @@ bool SdchManager::CanFetchDictionary(const GURL& referring_url, | 
| return true; | 
| } | 
|  | 
| -bool SdchManager::AddSdchDictionary(const std::string& dictionary_text, | 
| +void SdchManager::GetVcdiffDictionary( | 
| +    const std::string& server_hash, | 
| +    const GURL& referring_url, | 
| +    scoped_refptr<Dictionary>* dictionary) { | 
| +  DCHECK(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; | 
| +} | 
| + | 
| +// 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(CalledOnValidThread()); | 
| +  int count = 0; | 
| +  for (DictionaryMap::iterator it = dictionaries_.begin(); | 
| +       it != dictionaries_.end(); ++it) { | 
| +    if (!IsInSupportedDomain(target_url)) | 
| +      continue; | 
| +    if (!it->second->CanAdvertise(target_url)) | 
| +      continue; | 
| +    ++count; | 
| +    if (!list->empty()) | 
| +      list->append(","); | 
| +    list->append(it->second->client_hash()); | 
| +  } | 
| +  // Watch to see if we have corrupt or numerous dictionaries. | 
| +  if (count > 0) | 
| +    UMA_HISTOGRAM_COUNTS("Sdch3.Advertisement_Count", count); | 
| +} | 
| + | 
| +// static | 
| +void SdchManager::GenerateHash(const std::string& dictionary_text, | 
| +    std::string* client_hash, std::string* server_hash) { | 
| +  char binary_hash[32]; | 
| +  crypto::SHA256HashString(dictionary_text, binary_hash, sizeof(binary_hash)); | 
| + | 
| +  std::string first_48_bits(&binary_hash[0], 6); | 
| +  std::string second_48_bits(&binary_hash[6], 6); | 
| +  UrlSafeBase64Encode(first_48_bits, client_hash); | 
| +  UrlSafeBase64Encode(second_48_bits, server_hash); | 
| + | 
| +  DCHECK_EQ(server_hash->length(), 8u); | 
| +  DCHECK_EQ(client_hash->length(), 8u); | 
| +} | 
| + | 
| +//------------------------------------------------------------------------------ | 
| +// Methods for supporting latency experiments. | 
| + | 
| +bool SdchManager::AllowLatencyExperiment(const GURL& url) const { | 
| +  DCHECK(CalledOnValidThread()); | 
| +  return allow_latency_experiment_.end() != | 
| +      allow_latency_experiment_.find(url.host()); | 
| +} | 
| + | 
| +void SdchManager::SetAllowLatencyExperiment(const GURL& url, bool enable) { | 
| +  DCHECK(CalledOnValidThread()); | 
| +  if (enable) { | 
| +    allow_latency_experiment_.insert(url.host()); | 
| +    return; | 
| +  } | 
| +  ExperimentSet::iterator it = allow_latency_experiment_.find(url.host()); | 
| +  if (allow_latency_experiment_.end() == it) | 
| +    return;  // It was already erased, or never allowed. | 
| +  SdchErrorRecovery(LATENCY_TEST_DISALLOWED); | 
| +  allow_latency_experiment_.erase(it); | 
| +} | 
| + | 
| +void SdchManager::AddSdchDictionary(const std::string& dictionary_text, | 
| const GURL& dictionary_url) { | 
| DCHECK(CalledOnValidThread()); | 
| std::string client_hash; | 
| @@ -408,7 +486,7 @@ bool SdchManager::AddSdchDictionary(const std::string& dictionary_text, | 
| GenerateHash(dictionary_text, &client_hash, &server_hash); | 
| if (dictionaries_.find(server_hash) != dictionaries_.end()) { | 
| SdchErrorRecovery(DICTIONARY_ALREADY_LOADED); | 
| -    return false;  // Already loaded. | 
| +    return;                             // Already loaded. | 
| } | 
|  | 
| std::string domain, path; | 
| @@ -417,13 +495,13 @@ bool SdchManager::AddSdchDictionary(const std::string& dictionary_text, | 
|  | 
| if (dictionary_text.empty()) { | 
| SdchErrorRecovery(DICTIONARY_HAS_NO_TEXT); | 
| -    return false;  // Missing header. | 
| +    return;                             // Missing header. | 
| } | 
|  | 
| size_t header_end = dictionary_text.find("\n\n"); | 
| if (std::string::npos == header_end) { | 
| SdchErrorRecovery(DICTIONARY_HAS_NO_HEADER); | 
| -    return false;  // Missing header. | 
| +    return;                             // Missing header. | 
| } | 
| size_t line_start = 0;  // Start of line being parsed. | 
| while (1) { | 
| @@ -434,7 +512,7 @@ bool SdchManager::AddSdchDictionary(const std::string& dictionary_text, | 
| size_t colon_index = dictionary_text.find(':', line_start); | 
| if (std::string::npos == colon_index) { | 
| SdchErrorRecovery(DICTIONARY_HEADER_LINE_MISSING_COLON); | 
| -      return false;  // Illegal line missing a colon. | 
| +      return;                         // Illegal line missing a colon. | 
| } | 
|  | 
| if (colon_index > line_end) | 
| @@ -454,7 +532,7 @@ bool SdchManager::AddSdchDictionary(const std::string& dictionary_text, | 
| path = value; | 
| } else if (name == "format-version") { | 
| if (value != "1.0") | 
| -          return false; | 
| +          return; | 
| } else if (name == "max-age") { | 
| int64 seconds; | 
| base::StringToInt64(value, &seconds); | 
| @@ -473,10 +551,10 @@ bool SdchManager::AddSdchDictionary(const std::string& dictionary_text, | 
| } | 
|  | 
| if (!IsInSupportedDomain(dictionary_url)) | 
| -    return false; | 
| +    return; | 
|  | 
| if (!Dictionary::CanSet(domain, path, ports, dictionary_url)) | 
| -    return false; | 
| +    return; | 
|  | 
| // TODO(jar): Remove these hacks to preclude a DOS attack involving piles of | 
| // useless dictionaries.  We should probably have a cache eviction plan, | 
| @@ -484,11 +562,11 @@ bool SdchManager::AddSdchDictionary(const std::string& dictionary_text, | 
| // is probably not worth doing eviction handling. | 
| if (kMaxDictionarySize < dictionary_text.size()) { | 
| SdchErrorRecovery(DICTIONARY_IS_TOO_LARGE); | 
| -    return false; | 
| +    return; | 
| } | 
| if (kMaxDictionaryCount <= dictionaries_.size()) { | 
| SdchErrorRecovery(DICTIONARY_COUNT_EXCEEDED); | 
| -    return false; | 
| +    return; | 
| } | 
|  | 
| UMA_HISTOGRAM_COUNTS("Sdch3.Dictionary size loaded", dictionary_text.size()); | 
| @@ -498,85 +576,7 @@ bool SdchManager::AddSdchDictionary(const std::string& dictionary_text, | 
| new Dictionary(dictionary_text, header_end + 2, client_hash, | 
| dictionary_url, domain, path, expiration, ports); | 
| dictionaries_[server_hash] = dictionary; | 
| -  return true; | 
| -} | 
| - | 
| -void SdchManager::GetVcdiffDictionary( | 
| -    const std::string& server_hash, | 
| -    const GURL& referring_url, | 
| -    scoped_refptr<Dictionary>* dictionary) { | 
| -  DCHECK(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; | 
| -} | 
| - | 
| -// 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(CalledOnValidThread()); | 
| -  int count = 0; | 
| -  for (DictionaryMap::iterator it = dictionaries_.begin(); | 
| -       it != dictionaries_.end(); ++it) { | 
| -    if (!IsInSupportedDomain(target_url)) | 
| -      continue; | 
| -    if (!it->second->CanAdvertise(target_url)) | 
| -      continue; | 
| -    ++count; | 
| -    if (!list->empty()) | 
| -      list->append(","); | 
| -    list->append(it->second->client_hash()); | 
| -  } | 
| -  // Watch to see if we have corrupt or numerous dictionaries. | 
| -  if (count > 0) | 
| -    UMA_HISTOGRAM_COUNTS("Sdch3.Advertisement_Count", count); | 
| -} | 
| - | 
| -// static | 
| -void SdchManager::GenerateHash(const std::string& dictionary_text, | 
| -    std::string* client_hash, std::string* server_hash) { | 
| -  char binary_hash[32]; | 
| -  crypto::SHA256HashString(dictionary_text, binary_hash, sizeof(binary_hash)); | 
| - | 
| -  std::string first_48_bits(&binary_hash[0], 6); | 
| -  std::string second_48_bits(&binary_hash[6], 6); | 
| -  UrlSafeBase64Encode(first_48_bits, client_hash); | 
| -  UrlSafeBase64Encode(second_48_bits, server_hash); | 
| - | 
| -  DCHECK_EQ(server_hash->length(), 8u); | 
| -  DCHECK_EQ(client_hash->length(), 8u); | 
| -} | 
| - | 
| -//------------------------------------------------------------------------------ | 
| -// Methods for supporting latency experiments. | 
| - | 
| -bool SdchManager::AllowLatencyExperiment(const GURL& url) const { | 
| -  DCHECK(CalledOnValidThread()); | 
| -  return allow_latency_experiment_.end() != | 
| -      allow_latency_experiment_.find(url.host()); | 
| -} | 
| - | 
| -void SdchManager::SetAllowLatencyExperiment(const GURL& url, bool enable) { | 
| -  DCHECK(CalledOnValidThread()); | 
| -  if (enable) { | 
| -    allow_latency_experiment_.insert(url.host()); | 
| -    return; | 
| -  } | 
| -  ExperimentSet::iterator it = allow_latency_experiment_.find(url.host()); | 
| -  if (allow_latency_experiment_.end() == it) | 
| -    return;  // It was already erased, or never allowed. | 
| -  SdchErrorRecovery(LATENCY_TEST_DISALLOWED); | 
| -  allow_latency_experiment_.erase(it); | 
| +  return; | 
| } | 
|  | 
| // static | 
|  |