OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "components/browsing_data/content/storage_partition_http_cache_data_rem
over.h" | |
6 | |
7 #include "base/location.h" | |
8 #include "base/single_thread_task_runner.h" | |
9 #include "base/threading/thread_task_runner_handle.h" | |
10 #include "components/browsing_data/content/conditional_cache_deletion_helper.h" | |
11 #include "content/public/browser/browser_thread.h" | |
12 #include "content/public/browser/storage_partition.h" | |
13 #include "net/base/sdch_manager.h" | |
14 #include "net/disk_cache/blockfile/backend_impl.h" | |
15 #include "net/disk_cache/disk_cache.h" | |
16 #include "net/disk_cache/memory/mem_backend_impl.h" | |
17 #include "net/disk_cache/simple/simple_backend_impl.h" | |
18 #include "net/http/http_cache.h" | |
19 #include "net/url_request/url_request_context.h" | |
20 #include "net/url_request/url_request_context_getter.h" | |
21 | |
22 using content::BrowserThread; | |
23 | |
24 namespace browsing_data { | |
25 | |
26 StoragePartitionHttpCacheDataRemover::StoragePartitionHttpCacheDataRemover( | |
27 base::Callback<bool(const GURL&)> url_predicate, | |
28 base::Time delete_begin, | |
29 base::Time delete_end, | |
30 net::URLRequestContextGetter* main_context_getter, | |
31 net::URLRequestContextGetter* media_context_getter) | |
32 : url_predicate_(url_predicate), | |
33 delete_begin_(delete_begin), | |
34 delete_end_(delete_end), | |
35 main_context_getter_(main_context_getter), | |
36 media_context_getter_(media_context_getter), | |
37 next_cache_state_(CacheState::NONE), | |
38 cache_(nullptr) {} | |
39 | |
40 StoragePartitionHttpCacheDataRemover::~StoragePartitionHttpCacheDataRemover() { | |
41 } | |
42 | |
43 // static. | |
44 StoragePartitionHttpCacheDataRemover* | |
45 StoragePartitionHttpCacheDataRemover::CreateForRange( | |
46 content::StoragePartition* storage_partition, | |
47 base::Time delete_begin, | |
48 base::Time delete_end) { | |
49 return new StoragePartitionHttpCacheDataRemover( | |
50 base::Callback<bool(const GURL&)>(), // Null callback. | |
51 delete_begin, delete_end, | |
52 storage_partition->GetURLRequestContext(), | |
53 storage_partition->GetMediaURLRequestContext()); | |
54 } | |
55 | |
56 // static. | |
57 StoragePartitionHttpCacheDataRemover* | |
58 StoragePartitionHttpCacheDataRemover::CreateForURLsAndRange( | |
59 content::StoragePartition* storage_partition, | |
60 const base::Callback<bool(const GURL&)>& url_predicate, | |
61 base::Time delete_begin, | |
62 base::Time delete_end) { | |
63 return new StoragePartitionHttpCacheDataRemover( | |
64 url_predicate, delete_begin, delete_end, | |
65 storage_partition->GetURLRequestContext(), | |
66 storage_partition->GetMediaURLRequestContext()); | |
67 } | |
68 | |
69 void StoragePartitionHttpCacheDataRemover::Remove( | |
70 const base::Closure& done_callback) { | |
71 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
72 DCHECK(!done_callback.is_null()); | |
73 done_callback_ = done_callback; | |
74 | |
75 BrowserThread::PostTask( | |
76 BrowserThread::IO, FROM_HERE, | |
77 base::Bind( | |
78 &StoragePartitionHttpCacheDataRemover::ClearHttpCacheOnIOThread, | |
79 base::Unretained(this))); | |
80 } | |
81 | |
82 void StoragePartitionHttpCacheDataRemover::ClearHttpCacheOnIOThread() { | |
83 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
84 next_cache_state_ = CacheState::NONE; | |
85 DCHECK_EQ(CacheState::NONE, next_cache_state_); | |
86 | |
87 next_cache_state_ = CacheState::CREATE_MAIN; | |
88 DoClearCache(net::OK); | |
89 } | |
90 | |
91 void StoragePartitionHttpCacheDataRemover::ClearedHttpCache() { | |
92 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
93 done_callback_.Run(); | |
94 base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this); | |
95 } | |
96 | |
97 // The expected state sequence is CacheState::NONE --> CacheState::CREATE_MAIN | |
98 // --> CacheState::DELETE_MAIN --> CacheState::CREATE_MEDIA --> | |
99 // CacheState::DELETE_MEDIA --> CacheState::DONE, and any errors are ignored. | |
100 void StoragePartitionHttpCacheDataRemover::DoClearCache(int rv) { | |
101 DCHECK_NE(CacheState::NONE, next_cache_state_); | |
102 | |
103 while (rv != net::ERR_IO_PENDING && next_cache_state_ != CacheState::NONE) { | |
104 switch (next_cache_state_) { | |
105 case CacheState::CREATE_MAIN: | |
106 case CacheState::CREATE_MEDIA: { | |
107 // Get a pointer to the cache. | |
108 net::URLRequestContextGetter* getter = | |
109 (next_cache_state_ == CacheState::CREATE_MAIN) | |
110 ? main_context_getter_.get() | |
111 : media_context_getter_.get(); | |
112 | |
113 // Caches might not exist in tests. | |
114 if (!getter) { | |
115 next_cache_state_ = (next_cache_state_ == CacheState::CREATE_MAIN) | |
116 ? CacheState::CREATE_MEDIA | |
117 : CacheState::DONE; | |
118 break; | |
119 } | |
120 | |
121 net::HttpCache* http_cache = getter->GetURLRequestContext() | |
122 ->http_transaction_factory() | |
123 ->GetCache(); | |
124 | |
125 next_cache_state_ = (next_cache_state_ == CacheState::CREATE_MAIN) | |
126 ? CacheState::DELETE_MAIN | |
127 : CacheState::DELETE_MEDIA; | |
128 | |
129 // Clear QUIC server information from memory and the disk cache. | |
130 http_cache->GetSession() | |
131 ->quic_stream_factory() | |
132 ->ClearCachedStatesInCryptoConfig(url_predicate_); | |
133 | |
134 // Clear SDCH dictionary state. | |
135 net::SdchManager* sdch_manager = | |
136 getter->GetURLRequestContext()->sdch_manager(); | |
137 // The test is probably overkill, since chrome should always have an | |
138 // SdchManager. But in general the URLRequestContext is *not* | |
139 // guaranteed to have an SdchManager, so checking is wise. | |
140 if (sdch_manager) | |
141 sdch_manager->ClearData(); | |
142 | |
143 rv = http_cache->GetBackend( | |
144 &cache_, | |
145 base::Bind(&StoragePartitionHttpCacheDataRemover::DoClearCache, | |
146 base::Unretained(this))); | |
147 break; | |
148 } | |
149 case CacheState::DELETE_MAIN: | |
150 case CacheState::DELETE_MEDIA: { | |
151 next_cache_state_ = (next_cache_state_ == CacheState::DELETE_MAIN) | |
152 ? CacheState::CREATE_MEDIA | |
153 : CacheState::DONE; | |
154 | |
155 // |cache_| can be null if it cannot be initialized. | |
156 if (cache_) { | |
157 if (!url_predicate_.is_null()) { | |
158 rv = (new ConditionalCacheDeletionHelper( | |
159 cache_, | |
160 ConditionalCacheDeletionHelper::CreateURLAndTimeCondition( | |
161 url_predicate_, | |
162 delete_begin_, | |
163 delete_end_)))->DeleteAndDestroySelfWhenFinished( | |
164 base::Bind( | |
165 &StoragePartitionHttpCacheDataRemover::DoClearCache, | |
166 base::Unretained(this))); | |
167 } else if (delete_begin_.is_null() && delete_end_.is_max()) { | |
168 rv = cache_->DoomAllEntries(base::Bind( | |
169 &StoragePartitionHttpCacheDataRemover::DoClearCache, | |
170 base::Unretained(this))); | |
171 } else { | |
172 rv = cache_->DoomEntriesBetween( | |
173 delete_begin_, delete_end_, | |
174 base::Bind( | |
175 &StoragePartitionHttpCacheDataRemover::DoClearCache, | |
176 base::Unretained(this))); | |
177 } | |
178 cache_ = NULL; | |
179 } | |
180 break; | |
181 } | |
182 case CacheState::DONE: { | |
183 cache_ = NULL; | |
184 next_cache_state_ = CacheState::NONE; | |
185 | |
186 // Notify the UI thread that we are done. | |
187 BrowserThread::PostTask( | |
188 BrowserThread::UI, FROM_HERE, | |
189 base::Bind(&StoragePartitionHttpCacheDataRemover::ClearedHttpCache, | |
190 base::Unretained(this))); | |
191 return; | |
192 } | |
193 case CacheState::NONE: { | |
194 NOTREACHED() << "bad state"; | |
195 return; | |
196 } | |
197 } | |
198 } | |
199 } | |
200 | |
201 } // namespace browsing_data | |
OLD | NEW |