summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/browsing_data/browsing_data_remover.cc11
-rw-r--r--chrome/browser/net/sdch_dictionary_fetcher.cc14
-rw-r--r--chrome/browser/net/sdch_dictionary_fetcher.h3
-rw-r--r--net/base/sdch_manager.cc38
-rw-r--r--net/base/sdch_manager.h16
-rw-r--r--net/base/sdch_manager_unittest.cc39
-rw-r--r--net/filter/sdch_filter.cc8
7 files changed, 102 insertions, 27 deletions
diff --git a/chrome/browser/browsing_data/browsing_data_remover.cc b/chrome/browser/browsing_data/browsing_data_remover.cc
index ba48751..29bf329 100644
--- a/chrome/browser/browsing_data/browsing_data_remover.cc
+++ b/chrome/browser/browsing_data/browsing_data_remover.cc
@@ -75,6 +75,7 @@
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/user_metrics.h"
#include "net/base/net_errors.h"
+#include "net/base/sdch_manager.h"
#include "net/cookies/cookie_store.h"
#include "net/disk_cache/disk_cache.h"
#include "net/http/http_cache.h"
@@ -929,6 +930,16 @@ void BrowsingDataRemover::DoClearCache(int rv) {
// Clear QUIC server information from memory and the disk cache.
http_cache->GetSession()->quic_stream_factory()->
ClearCachedStatesInCryptoConfig();
+
+ // Clear SDCH dictionary state.
+ net::SdchManager* sdch_manager =
+ getter->GetURLRequestContext()->sdch_manager();
+ // The test is probably overkill, since chrome should always have an
+ // SdchManager. But in general the URLRequestContext is *not*
+ // guaranteed to have an SdchManager, so checking is wise.
+ if (sdch_manager)
+ sdch_manager->ClearData();
+
rv = http_cache->GetBackend(
&cache_, base::Bind(&BrowsingDataRemover::DoClearCache,
base::Unretained(this)));
diff --git a/chrome/browser/net/sdch_dictionary_fetcher.cc b/chrome/browser/net/sdch_dictionary_fetcher.cc
index 1130fe3..0a838bd 100644
--- a/chrome/browser/net/sdch_dictionary_fetcher.cc
+++ b/chrome/browser/net/sdch_dictionary_fetcher.cc
@@ -49,6 +49,16 @@ void SdchDictionaryFetcher::Schedule(const GURL& dictionary_url) {
ScheduleDelayedRun();
}
+void SdchDictionaryFetcher::Cancel() {
+ DCHECK(CalledOnValidThread());
+
+ while (!fetch_queue_.empty())
+ fetch_queue_.pop();
+ attempted_load_.clear();
+ weak_factory_.InvalidateWeakPtrs();
+ current_fetch_.reset(NULL);
+}
+
void SdchDictionaryFetcher::ScheduleDelayedRun() {
if (fetch_queue_.empty() || current_fetch_.get() || task_is_pending_)
return;
@@ -64,6 +74,10 @@ void SdchDictionaryFetcher::StartFetching() {
DCHECK(task_is_pending_);
task_is_pending_ = false;
+ // Handle losing the race against Cancel().
+ if (fetch_queue_.empty())
+ return;
+
DCHECK(context_.get());
current_fetch_.reset(net::URLFetcher::Create(
fetch_queue_.front(), net::URLFetcher::GET, this));
diff --git a/chrome/browser/net/sdch_dictionary_fetcher.h b/chrome/browser/net/sdch_dictionary_fetcher.h
index 7eea42a..968b42e 100644
--- a/chrome/browser/net/sdch_dictionary_fetcher.h
+++ b/chrome/browser/net/sdch_dictionary_fetcher.h
@@ -37,9 +37,8 @@ class SdchDictionaryFetcher
virtual ~SdchDictionaryFetcher();
// Implementation of SdchFetcher class.
- // This method gets the requested dictionary, and then calls back into the
- // SdchManager class with the dictionary's text.
virtual void Schedule(const GURL& dictionary_url) OVERRIDE;
+ virtual void Cancel() OVERRIDE;
private:
// Delay in ms between Schedule and actual download.
diff --git a/net/base/sdch_manager.cc b/net/base/sdch_manager.cc
index ad260a5..3cd838f 100644
--- a/net/base/sdch_manager.cc
+++ b/net/base/sdch_manager.cc
@@ -219,11 +219,24 @@ SdchManager::~SdchManager() {
DCHECK(CalledOnValidThread());
while (!dictionaries_.empty()) {
DictionaryMap::iterator it = dictionaries_.begin();
- it->second->Release();
dictionaries_.erase(it->first);
}
}
+void SdchManager::ClearData() {
+ blacklisted_domains_.clear();
+ exponential_blacklist_count_.clear();
+ allow_latency_experiment_.clear();
+ if (fetcher_.get())
+ fetcher_->Cancel();
+
+ // Note that this may result in not having dictionaries we've advertised
+ // for incoming responses. The window is relatively small (as ClearData()
+ // is not expected to be called frequently), so we rely on meta-refresh
+ // to handle this case.
+ dictionaries_.clear();
+}
+
// static
void SdchManager::SdchErrorRecovery(ProblemCodes problem) {
UMA_HISTOGRAM_ENUMERATION("Sdch3.ProblemCodes_4", problem, MAX_PROBLEM_CODE);
@@ -252,9 +265,9 @@ void SdchManager::BlacklistDomain(const GURL& url) {
if (count > 0)
return; // Domain is already blacklisted.
- count = 1 + 2 * exponential_blacklist_count[domain];
+ count = 1 + 2 * exponential_blacklist_count_[domain];
if (count > 0)
- exponential_blacklist_count[domain] = count;
+ exponential_blacklist_count_[domain] = count;
else
count = INT_MAX;
@@ -265,13 +278,13 @@ void SdchManager::BlacklistDomainForever(const GURL& url) {
SetAllowLatencyExperiment(url, false);
std::string domain(StringToLowerASCII(url.host()));
- exponential_blacklist_count[domain] = INT_MAX;
+ exponential_blacklist_count_[domain] = INT_MAX;
blacklisted_domains_[domain] = INT_MAX;
}
void SdchManager::ClearBlacklistings() {
blacklisted_domains_.clear();
- exponential_blacklist_count.clear();
+ exponential_blacklist_count_.clear();
}
void SdchManager::ClearDomainBlacklisting(const std::string& domain) {
@@ -285,10 +298,10 @@ int SdchManager::BlackListDomainCount(const std::string& domain) {
}
int SdchManager::BlacklistDomainExponential(const std::string& domain) {
- if (exponential_blacklist_count.end() ==
- exponential_blacklist_count.find(domain))
+ if (exponential_blacklist_count_.end() ==
+ exponential_blacklist_count_.find(domain))
return 0;
- return exponential_blacklist_count[StringToLowerASCII(domain)];
+ return exponential_blacklist_count_[StringToLowerASCII(domain)];
}
bool SdchManager::IsInSupportedDomain(const GURL& url) {
@@ -455,20 +468,21 @@ bool SdchManager::AddSdchDictionary(const std::string& dictionary_text,
Dictionary* dictionary =
new Dictionary(dictionary_text, header_end + 2, client_hash,
dictionary_url, domain, path, expiration, ports);
- dictionary->AddRef();
dictionaries_[server_hash] = dictionary;
return true;
}
-void SdchManager::GetVcdiffDictionary(const std::string& server_hash,
- const GURL& referring_url, Dictionary** dictionary) {
+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;
}
- Dictionary* matching_dictionary = it->second;
+ scoped_refptr<Dictionary> matching_dictionary = it->second;
if (!IsInSupportedDomain(referring_url))
return;
if (!matching_dictionary->CanUse(referring_url))
diff --git a/net/base/sdch_manager.h b/net/base/sdch_manager.h
index c760313..37cac1b 100644
--- a/net/base/sdch_manager.h
+++ b/net/base/sdch_manager.h
@@ -49,6 +49,11 @@ class SdchFetcher {
// from a server. The callee is responsible for getting that dictionary_text,
// and then calling back to AddSdchDictionary() to the SdchManager instance.
virtual void Schedule(const GURL& dictionary_url) = 0;
+
+ // The Cancel() method is called to cancel all pending dictionary fetches.
+ // This is used for implementation of ClearData() below.
+ virtual void Cancel() = 0;
+
private:
DISALLOW_COPY_AND_ASSIGN(SdchFetcher);
};
@@ -234,6 +239,9 @@ class NET_EXPORT SdchManager : public NON_EXPORTED_BASE(base::NonThreadSafe) {
SdchManager();
~SdchManager();
+ // Clear data (for browser data removal).
+ void ClearData();
+
// Record stats on various errors.
static void SdchErrorRecovery(ProblemCodes problem);
@@ -304,12 +312,10 @@ class NET_EXPORT SdchManager : public NON_EXPORTED_BASE(base::NonThreadSafe) {
// to use to decompreses data that arrived as SDCH encoded content. Check to
// be sure the returned |dictionary| can be used for decoding content supplied
// in response to a request for |referring_url|.
- // Caller is responsible for AddRef()ing the dictionary, and Release()ing it
- // when done.
// Return null in |dictionary| if there is no matching legal dictionary.
void GetVcdiffDictionary(const std::string& server_hash,
const GURL& referring_url,
- Dictionary** dictionary);
+ scoped_refptr<Dictionary>* dictionary);
// Get list of available (pre-cached) dictionaries that we have already loaded
// into memory. The list is a comma separated list of (client) hashes per
@@ -335,7 +341,7 @@ class NET_EXPORT SdchManager : public NON_EXPORTED_BASE(base::NonThreadSafe) {
typedef std::set<std::string> ExperimentSet;
// A map of dictionaries info indexed by the hash that the server provides.
- typedef std::map<std::string, Dictionary*> DictionaryMap;
+ typedef std::map<std::string, scoped_refptr<Dictionary> > DictionaryMap;
// Support SDCH compression, by advertising in headers.
static bool g_sdch_enabled_;
@@ -358,7 +364,7 @@ class NET_EXPORT SdchManager : public NON_EXPORTED_BASE(base::NonThreadSafe) {
// Support exponential backoff in number of domain accesses before
// blacklisting expires.
- DomainCounter exponential_blacklist_count;
+ DomainCounter exponential_blacklist_count_;
// List of hostnames for which a latency experiment is allowed (because a
// round trip test has recently passed).
diff --git a/net/base/sdch_manager_unittest.cc b/net/base/sdch_manager_unittest.cc
index 6684e4a..87b01f4 100644
--- a/net/base/sdch_manager_unittest.cc
+++ b/net/base/sdch_manager_unittest.cc
@@ -192,7 +192,7 @@ TEST_F(SdchManagerTest, CanUseHTTPSDictionaryOverHTTPSIfEnabled) {
EXPECT_FALSE(dictionary_list.empty());
// Dictionary should be available.
- SdchManager::Dictionary* dictionary = NULL;
+ scoped_refptr<SdchManager::Dictionary> dictionary;
std::string client_hash;
std::string server_hash;
sdch_manager()->GenerateHash(dictionary_text, &client_hash, &server_hash);
@@ -215,7 +215,7 @@ TEST_F(SdchManagerTest, CanNotUseHTTPDictionaryOverHTTPS) {
sdch_manager()->GetAvailDictionaryList(target_url, &dictionary_list);
EXPECT_TRUE(dictionary_list.empty());
- SdchManager::Dictionary* dictionary = NULL;
+ scoped_refptr<SdchManager::Dictionary> dictionary;
std::string client_hash;
std::string server_hash;
sdch_manager()->GenerateHash(dictionary_text, &client_hash, &server_hash);
@@ -401,7 +401,7 @@ TEST_F(SdchManagerTest, CanUseMultipleManagers) {
// can't get them from the other.
EXPECT_TRUE(sdch_manager()->AddSdchDictionary(
dictionary_text_1, GURL("http://" + dictionary_domain_1)));
- SdchManager::Dictionary* dictionary = NULL;
+ scoped_refptr<SdchManager::Dictionary> dictionary;
sdch_manager()->GetVcdiffDictionary(
server_hash_1,
GURL("http://" + dictionary_domain_1 + "/random_url"),
@@ -441,5 +441,38 @@ TEST_F(SdchManagerTest, HttpsCorrectlySupported) {
EXPECT_TRUE(sdch_manager()->IsInSupportedDomain(secure_url));
}
+TEST_F(SdchManagerTest, ClearDictionaryData) {
+ std::string dictionary_domain("x.y.z.google.com");
+ GURL blacklist_url("http://bad.chromium.org");
+
+ std::string dictionary_text(NewSdchDictionary(dictionary_domain));
+ std::string tmp_hash;
+ std::string server_hash;
+
+ SdchManager::GenerateHash(dictionary_text, &tmp_hash, &server_hash);
+
+ EXPECT_TRUE(sdch_manager()->AddSdchDictionary(
+ dictionary_text, GURL("http://" + dictionary_domain)));
+ scoped_refptr<SdchManager::Dictionary> dictionary;
+ sdch_manager()->GetVcdiffDictionary(
+ server_hash,
+ GURL("http://" + dictionary_domain + "/random_url"),
+ &dictionary);
+ EXPECT_TRUE(dictionary);
+
+ sdch_manager()->BlacklistDomain(GURL(blacklist_url));
+ EXPECT_FALSE(sdch_manager()->IsInSupportedDomain(blacklist_url));
+
+ sdch_manager()->ClearData();
+
+ dictionary = NULL;
+ sdch_manager()->GetVcdiffDictionary(
+ server_hash,
+ GURL("http://" + dictionary_domain + "/random_url"),
+ &dictionary);
+ EXPECT_FALSE(dictionary);
+ EXPECT_TRUE(sdch_manager()->IsInSupportedDomain(blacklist_url));
+}
+
} // namespace net
diff --git a/net/filter/sdch_filter.cc b/net/filter/sdch_filter.cc
index 5590821..2ef5ad5 100644
--- a/net/filter/sdch_filter.cc
+++ b/net/filter/sdch_filter.cc
@@ -336,20 +336,19 @@ Filter::FilterStatus SdchFilter::InitializeDictionary() {
else
next_stream_data_ = NULL;
- DCHECK(!dictionary_.get());
+ DCHECK(!dictionary_);
dictionary_hash_is_plausible_ = true; // Assume plausible, but check.
- SdchManager::Dictionary* dictionary = NULL;
if ('\0' == dictionary_hash_[kServerIdLength - 1]) {
SdchManager* manager(url_request_context_->sdch_manager());
manager->GetVcdiffDictionary(
std::string(dictionary_hash_, 0, kServerIdLength - 1),
- url_, &dictionary);
+ url_, &dictionary_);
} else {
dictionary_hash_is_plausible_ = false;
}
- if (!dictionary) {
+ if (!dictionary_) {
DCHECK(dictionary_hash_.size() == kServerIdLength);
// Since dictionary was not found, check to see if hash was even plausible.
for (size_t i = 0; i < kServerIdLength - 1; ++i) {
@@ -366,7 +365,6 @@ Filter::FilterStatus SdchFilter::InitializeDictionary() {
decoding_status_ = DECODING_ERROR;
return FILTER_ERROR;
}
- dictionary_ = dictionary;
vcdiff_streaming_decoder_.reset(new open_vcdiff::VCDiffStreamingDecoder);
vcdiff_streaming_decoder_->SetAllowVcdTarget(false);
vcdiff_streaming_decoder_->StartDecoding(dictionary_->text().data(),