| Index: chrome/browser/browsing_data/storage_partition_http_cache_data_remover.cc
|
| diff --git a/chrome/browser/browsing_data/storage_partition_http_cache_data_remover.cc b/chrome/browser/browsing_data/storage_partition_http_cache_data_remover.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..d92bf43f37862e77c05ddec560e61f487acb439e
|
| --- /dev/null
|
| +++ b/chrome/browser/browsing_data/storage_partition_http_cache_data_remover.cc
|
| @@ -0,0 +1,156 @@
|
| +// Copyright 2015 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "chrome/browser/browsing_data/storage_partition_http_cache_data_remover.h"
|
| +
|
| +#include "content/public/browser/browser_thread.h"
|
| +#include "content/public/browser/storage_partition.h"
|
| +#include "net/disk_cache/disk_cache.h"
|
| +#include "net/http/http_cache.h"
|
| +#include "net/url_request/url_request_context.h"
|
| +#include "net/url_request/url_request_context_getter.h"
|
| +
|
| +using content::BrowserThread;
|
| +
|
| +StoragePartitionHttpCacheDataRemover::StoragePartitionHttpCacheDataRemover(
|
| + base::Time delete_begin,
|
| + base::Time delete_end,
|
| + net::URLRequestContextGetter* main_context_getter,
|
| + net::URLRequestContextGetter* media_context_getter)
|
| + : delete_begin_(delete_begin),
|
| + delete_end_(delete_end),
|
| + main_context_getter_(main_context_getter),
|
| + media_context_getter_(media_context_getter),
|
| + next_cache_state_(STATE_NONE),
|
| + cache_(nullptr) {
|
| +}
|
| +
|
| +StoragePartitionHttpCacheDataRemover::~StoragePartitionHttpCacheDataRemover() {
|
| +}
|
| +
|
| +// static.
|
| +StoragePartitionHttpCacheDataRemover*
|
| +StoragePartitionHttpCacheDataRemover::CreateForRange(
|
| + content::StoragePartition* storage_partition,
|
| + base::Time delete_begin,
|
| + base::Time delete_end) {
|
| + return new StoragePartitionHttpCacheDataRemover(
|
| + delete_begin, delete_end, storage_partition->GetURLRequestContext(),
|
| + storage_partition->GetMediaURLRequestContext());
|
| +}
|
| +
|
| +void StoragePartitionHttpCacheDataRemover::Remove(
|
| + const base::Closure& done_callback) {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| + DCHECK(!done_callback.is_null());
|
| + done_callback_ = done_callback;
|
| +
|
| + BrowserThread::PostTask(
|
| + BrowserThread::IO, FROM_HERE,
|
| + base::Bind(
|
| + &StoragePartitionHttpCacheDataRemover::ClearHttpCacheOnIOThread,
|
| + base::Unretained(this)));
|
| +}
|
| +
|
| +void StoragePartitionHttpCacheDataRemover::ClearHttpCacheOnIOThread() {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
| + next_cache_state_ = STATE_NONE;
|
| + DCHECK_EQ(STATE_NONE, next_cache_state_);
|
| + DCHECK(main_context_getter_.get());
|
| + DCHECK(media_context_getter_.get());
|
| +
|
| + next_cache_state_ = STATE_CREATE_MAIN;
|
| + DoClearCache(net::OK);
|
| +}
|
| +
|
| +void StoragePartitionHttpCacheDataRemover::ClearedHttpCache() {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| + done_callback_.Run();
|
| + base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
|
| +}
|
| +
|
| +// The expected state sequence is STATE_NONE --> STATE_CREATE_MAIN -->
|
| +// STATE_DELETE_MAIN --> STATE_CREATE_MEDIA --> STATE_DELETE_MEDIA -->
|
| +// STATE_DONE, and any errors are ignored.
|
| +void StoragePartitionHttpCacheDataRemover::DoClearCache(int rv) {
|
| + DCHECK_NE(STATE_NONE, next_cache_state_);
|
| +
|
| + while (rv != net::ERR_IO_PENDING && next_cache_state_ != STATE_NONE) {
|
| + switch (next_cache_state_) {
|
| + case STATE_CREATE_MAIN:
|
| + case STATE_CREATE_MEDIA: {
|
| + // Get a pointer to the cache.
|
| + net::URLRequestContextGetter* getter =
|
| + (next_cache_state_ == STATE_CREATE_MAIN)
|
| + ? main_context_getter_.get()
|
| + : media_context_getter_.get();
|
| + net::HttpCache* http_cache = getter->GetURLRequestContext()
|
| + ->http_transaction_factory()
|
| + ->GetCache();
|
| +
|
| + next_cache_state_ = (next_cache_state_ == STATE_CREATE_MAIN)
|
| + ? STATE_DELETE_MAIN
|
| + : STATE_DELETE_MEDIA;
|
| +
|
| + // 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(&StoragePartitionHttpCacheDataRemover::DoClearCache,
|
| + base::Unretained(this)));
|
| + break;
|
| + }
|
| + case STATE_DELETE_MAIN:
|
| + case STATE_DELETE_MEDIA: {
|
| + next_cache_state_ = (next_cache_state_ == STATE_DELETE_MAIN)
|
| + ? STATE_CREATE_MEDIA
|
| + : STATE_DONE;
|
| +
|
| + // |cache_| can be null if it cannot be initialized.
|
| + if (cache_) {
|
| + if (delete_begin_.is_null()) {
|
| + rv = cache_->DoomAllEntries(
|
| + base::Bind(&StoragePartitionHttpCacheDataRemover::DoClearCache,
|
| + base::Unretained(this)));
|
| + } else {
|
| + rv = cache_->DoomEntriesBetween(
|
| + delete_begin_, delete_end_,
|
| + base::Bind(&StoragePartitionHttpCacheDataRemover::DoClearCache,
|
| + base::Unretained(this)));
|
| + }
|
| + cache_ = NULL;
|
| + }
|
| + break;
|
| + }
|
| + case STATE_DONE: {
|
| + cache_ = NULL;
|
| + next_cache_state_ = STATE_NONE;
|
| +
|
| + // Notify the UI thread that we are done.
|
| + BrowserThread::PostTask(
|
| + BrowserThread::UI, FROM_HERE,
|
| + base::Bind(&StoragePartitionHttpCacheDataRemover::ClearedHttpCache,
|
| + base::Unretained(this)));
|
| + return;
|
| + }
|
| + default: {
|
| + NOTREACHED() << "bad state";
|
| + next_cache_state_ = STATE_NONE; // Stop looping.
|
| + return;
|
| + }
|
| + }
|
| + }
|
| +}
|
|
|