1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/browsing_data/storage_partition_http_cache_data_remover.h"
7 #include "content/public/browser/browser_thread.h"
8 #include "content/public/browser/storage_partition.h"
9 #include "net/base/sdch_manager.h"
10 #include "net/disk_cache/disk_cache.h"
11 #include "net/http/http_cache.h"
12 #include "net/url_request/url_request_context.h"
13 #include "net/url_request/url_request_context_getter.h"
15 using content::BrowserThread
;
17 namespace browsing_data
{
19 StoragePartitionHttpCacheDataRemover::StoragePartitionHttpCacheDataRemover(
20 base::Time delete_begin
,
21 base::Time delete_end
,
22 net::URLRequestContextGetter
* main_context_getter
,
23 net::URLRequestContextGetter
* media_context_getter
)
24 : delete_begin_(delete_begin
),
25 delete_end_(delete_end
),
26 main_context_getter_(main_context_getter
),
27 media_context_getter_(media_context_getter
),
28 next_cache_state_(STATE_NONE
),
32 StoragePartitionHttpCacheDataRemover::~StoragePartitionHttpCacheDataRemover() {
36 StoragePartitionHttpCacheDataRemover
*
37 StoragePartitionHttpCacheDataRemover::CreateForRange(
38 content::StoragePartition
* storage_partition
,
39 base::Time delete_begin
,
40 base::Time delete_end
) {
41 return new StoragePartitionHttpCacheDataRemover(
42 delete_begin
, delete_end
, storage_partition
->GetURLRequestContext(),
43 storage_partition
->GetMediaURLRequestContext());
46 void StoragePartitionHttpCacheDataRemover::Remove(
47 const base::Closure
& done_callback
) {
48 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
49 DCHECK(!done_callback
.is_null());
50 done_callback_
= done_callback
;
52 BrowserThread::PostTask(
53 BrowserThread::IO
, FROM_HERE
,
55 &StoragePartitionHttpCacheDataRemover::ClearHttpCacheOnIOThread
,
56 base::Unretained(this)));
59 void StoragePartitionHttpCacheDataRemover::ClearHttpCacheOnIOThread() {
60 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
61 next_cache_state_
= STATE_NONE
;
62 DCHECK_EQ(STATE_NONE
, next_cache_state_
);
63 DCHECK(main_context_getter_
.get());
64 DCHECK(media_context_getter_
.get());
66 next_cache_state_
= STATE_CREATE_MAIN
;
67 DoClearCache(net::OK
);
70 void StoragePartitionHttpCacheDataRemover::ClearedHttpCache() {
71 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
73 base::MessageLoop::current()->DeleteSoon(FROM_HERE
, this);
76 // The expected state sequence is STATE_NONE --> STATE_CREATE_MAIN -->
77 // STATE_DELETE_MAIN --> STATE_CREATE_MEDIA --> STATE_DELETE_MEDIA -->
78 // STATE_DONE, and any errors are ignored.
79 void StoragePartitionHttpCacheDataRemover::DoClearCache(int rv
) {
80 DCHECK_NE(STATE_NONE
, next_cache_state_
);
82 while (rv
!= net::ERR_IO_PENDING
&& next_cache_state_
!= STATE_NONE
) {
83 switch (next_cache_state_
) {
84 case STATE_CREATE_MAIN
:
85 case STATE_CREATE_MEDIA
: {
86 // Get a pointer to the cache.
87 net::URLRequestContextGetter
* getter
=
88 (next_cache_state_
== STATE_CREATE_MAIN
)
89 ? main_context_getter_
.get()
90 : media_context_getter_
.get();
91 net::HttpCache
* http_cache
= getter
->GetURLRequestContext()
92 ->http_transaction_factory()
95 next_cache_state_
= (next_cache_state_
== STATE_CREATE_MAIN
)
99 // Clear QUIC server information from memory and the disk cache.
100 http_cache
->GetSession()
101 ->quic_stream_factory()
102 ->ClearCachedStatesInCryptoConfig();
104 // Clear SDCH dictionary state.
105 net::SdchManager
* sdch_manager
=
106 getter
->GetURLRequestContext()->sdch_manager();
107 // The test is probably overkill, since chrome should always have an
108 // SdchManager. But in general the URLRequestContext is *not*
109 // guaranteed to have an SdchManager, so checking is wise.
111 sdch_manager
->ClearData();
113 rv
= http_cache
->GetBackend(
115 base::Bind(&StoragePartitionHttpCacheDataRemover::DoClearCache
,
116 base::Unretained(this)));
119 case STATE_DELETE_MAIN
:
120 case STATE_DELETE_MEDIA
: {
121 next_cache_state_
= (next_cache_state_
== STATE_DELETE_MAIN
)
125 // |cache_| can be null if it cannot be initialized.
127 if (delete_begin_
.is_null()) {
128 rv
= cache_
->DoomAllEntries(
129 base::Bind(&StoragePartitionHttpCacheDataRemover::DoClearCache
,
130 base::Unretained(this)));
132 rv
= cache_
->DoomEntriesBetween(
133 delete_begin_
, delete_end_
,
134 base::Bind(&StoragePartitionHttpCacheDataRemover::DoClearCache
,
135 base::Unretained(this)));
143 next_cache_state_
= STATE_NONE
;
145 // Notify the UI thread that we are done.
146 BrowserThread::PostTask(
147 BrowserThread::UI
, FROM_HERE
,
148 base::Bind(&StoragePartitionHttpCacheDataRemover::ClearedHttpCache
,
149 base::Unretained(this)));
153 NOTREACHED() << "bad state";
154 next_cache_state_
= STATE_NONE
; // Stop looping.
161 } // namespace browsing_data