| 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
 | 
| 
 |