OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/in_process_webkit/dom_storage_context.h" | 5 #include "content/browser/in_process_webkit/dom_storage_context.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/file_path.h" | 10 #include "base/file_path.h" |
11 #include "base/file_util.h" | 11 #include "base/file_util.h" |
12 #include "base/string_util.h" | 12 #include "base/string_util.h" |
13 #include "content/browser/in_process_webkit/dom_storage_area.h" | 13 #include "content/browser/in_process_webkit/dom_storage_area.h" |
| 14 #include "content/browser/in_process_webkit/dom_storage_message_filter.h" |
14 #include "content/browser/in_process_webkit/dom_storage_namespace.h" | 15 #include "content/browser/in_process_webkit/dom_storage_namespace.h" |
15 #include "content/browser/in_process_webkit/webkit_context.h" | 16 #include "content/browser/in_process_webkit/webkit_context.h" |
16 #include "content/common/dom_storage_common.h" | 17 #include "content/common/dom_storage_common.h" |
17 #include "content/public/browser/browser_thread.h" | 18 #include "content/public/browser/browser_thread.h" |
18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h" | 19 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h" |
19 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h" | 20 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h" |
20 #include "webkit/glue/webkit_glue.h" | 21 #include "webkit/glue/webkit_glue.h" |
21 #include "webkit/quota/special_storage_policy.h" | 22 #include "webkit/quota/special_storage_policy.h" |
22 | 23 |
23 using content::BrowserThread; | 24 using content::BrowserThread; |
(...skipping 21 matching lines...) Expand all Loading... |
45 file_util::Delete(file_path, false); | 46 file_util::Delete(file_path, false); |
46 } | 47 } |
47 } | 48 } |
48 } | 49 } |
49 | 50 |
50 } // namespace | 51 } // namespace |
51 | 52 |
52 const FilePath::CharType DOMStorageContext::kLocalStorageDirectory[] = | 53 const FilePath::CharType DOMStorageContext::kLocalStorageDirectory[] = |
53 FILE_PATH_LITERAL("Local Storage"); | 54 FILE_PATH_LITERAL("Local Storage"); |
54 | 55 |
| 56 const FilePath::CharType DOMStorageContext::kSessionStorageDirectory[] = |
| 57 FILE_PATH_LITERAL("Session Storage"); |
| 58 |
55 const FilePath::CharType DOMStorageContext::kLocalStorageExtension[] = | 59 const FilePath::CharType DOMStorageContext::kLocalStorageExtension[] = |
56 FILE_PATH_LITERAL(".localstorage"); | 60 FILE_PATH_LITERAL(".localstorage"); |
57 | 61 |
58 DOMStorageContext::DOMStorageContext( | 62 DOMStorageContext::DOMStorageContext( |
59 WebKitContext* webkit_context, | 63 WebKitContext* webkit_context, |
60 quota::SpecialStoragePolicy* special_storage_policy) | 64 quota::SpecialStoragePolicy* special_storage_policy) |
61 : last_storage_area_id_(0), | 65 : last_storage_area_id_(0), |
62 last_session_storage_namespace_id_on_ui_thread_(kLocalStorageNamespaceId), | 66 last_session_storage_namespace_id_on_ui_thread_(kLocalStorageNamespaceId), |
63 last_session_storage_namespace_id_on_io_thread_(kLocalStorageNamespaceId), | 67 last_session_storage_namespace_id_on_io_thread_(kLocalStorageNamespaceId), |
64 clear_local_state_on_exit_(false), | 68 clear_local_state_on_exit_(false), |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
107 return ++last_session_storage_namespace_id_on_ui_thread_; | 111 return ++last_session_storage_namespace_id_on_ui_thread_; |
108 return --last_session_storage_namespace_id_on_io_thread_; | 112 return --last_session_storage_namespace_id_on_io_thread_; |
109 } | 113 } |
110 | 114 |
111 int64 DOMStorageContext::CloneSessionStorage(int64 original_id) { | 115 int64 DOMStorageContext::CloneSessionStorage(int64 original_id) { |
112 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED)); | 116 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED)); |
113 int64 clone_id = AllocateSessionStorageNamespaceId(); | 117 int64 clone_id = AllocateSessionStorageNamespaceId(); |
114 BrowserThread::PostTask( | 118 BrowserThread::PostTask( |
115 BrowserThread::WEBKIT_DEPRECATED, FROM_HERE, | 119 BrowserThread::WEBKIT_DEPRECATED, FROM_HERE, |
116 base::Bind(&DOMStorageContext::CompleteCloningSessionStorage, this, | 120 base::Bind(&DOMStorageContext::CompleteCloningSessionStorage, this, |
117 original_id, clone_id)); | 121 original_id, clone_id, data_path_)); |
118 return clone_id; | 122 return clone_id; |
119 } | 123 } |
120 | 124 |
121 void DOMStorageContext::RegisterStorageArea(DOMStorageArea* storage_area) { | 125 void DOMStorageContext::RegisterStorageArea(DOMStorageArea* storage_area) { |
122 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED)); | 126 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED)); |
123 int64 id = storage_area->id(); | 127 int64 id = storage_area->id(); |
124 DCHECK(!GetStorageArea(id)); | 128 DCHECK(!GetStorageArea(id)); |
125 storage_area_map_[id] = storage_area; | 129 storage_area_map_[id] = storage_area; |
126 } | 130 } |
127 | 131 |
(...skipping 12 matching lines...) Expand all Loading... |
140 return iter->second; | 144 return iter->second; |
141 } | 145 } |
142 | 146 |
143 void DOMStorageContext::DeleteSessionStorageNamespace(int64 namespace_id) { | 147 void DOMStorageContext::DeleteSessionStorageNamespace(int64 namespace_id) { |
144 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED)); | 148 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED)); |
145 StorageNamespaceMap::iterator iter = | 149 StorageNamespaceMap::iterator iter = |
146 storage_namespace_map_.find(namespace_id); | 150 storage_namespace_map_.find(namespace_id); |
147 if (iter == storage_namespace_map_.end()) | 151 if (iter == storage_namespace_map_.end()) |
148 return; | 152 return; |
149 DCHECK(iter->second->dom_storage_type() == DOM_STORAGE_SESSION); | 153 DCHECK(iter->second->dom_storage_type() == DOM_STORAGE_SESSION); |
| 154 FilePath session_storage_directory = |
| 155 iter->second->session_storage_directory(); |
150 delete iter->second; | 156 delete iter->second; |
151 storage_namespace_map_.erase(iter); | 157 storage_namespace_map_.erase(iter); |
| 158 |
| 159 if (!save_session_state_ && |
| 160 !session_storage_directory.empty() && |
| 161 !data_path_.empty()) { |
| 162 FilePath to_delete = data_path_.Append(kSessionStorageDirectory) |
| 163 .Append(session_storage_directory); |
| 164 } |
152 } | 165 } |
153 | 166 |
154 DOMStorageNamespace* DOMStorageContext::GetStorageNamespace( | 167 DOMStorageNamespace* DOMStorageContext::GetStorageNamespace( |
155 int64 id, bool allocation_allowed) { | 168 int64 id, bool allocation_allowed) { |
156 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED)); | 169 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED)); |
157 StorageNamespaceMap::iterator iter = storage_namespace_map_.find(id); | 170 StorageNamespaceMap::iterator iter = storage_namespace_map_.find(id); |
158 if (iter != storage_namespace_map_.end()) | 171 if (iter != storage_namespace_map_.end()) |
159 return iter->second; | 172 return iter->second; |
160 if (!allocation_allowed) | 173 if (!allocation_allowed) |
161 return NULL; | 174 return NULL; |
162 if (id == kLocalStorageNamespaceId) | 175 if (id == kLocalStorageNamespaceId) |
163 return CreateLocalStorage(); | 176 return CreateLocalStorage(); |
164 return CreateSessionStorage(id); | 177 return CreateSessionStorage(id); |
165 } | 178 } |
166 | 179 |
| 180 DOMStorageNamespace* DOMStorageContext::RecreateSessionStorageNamespace( |
| 181 int64 id, |
| 182 const FilePath& session_storage_directory) { |
| 183 FilePath dir_path; |
| 184 if (!data_path_.empty()) { |
| 185 dir_path = data_path_.Append(kSessionStorageDirectory) |
| 186 .Append(session_storage_directory); |
| 187 } |
| 188 DOMStorageNamespace* new_namespace = |
| 189 DOMStorageNamespace::CreateSessionStorageNamespace(this, dir_path, id); |
| 190 RegisterStorageNamespace(new_namespace); |
| 191 return new_namespace; |
| 192 } |
| 193 |
167 void DOMStorageContext::RegisterMessageFilter( | 194 void DOMStorageContext::RegisterMessageFilter( |
168 DOMStorageMessageFilter* message_filter) { | 195 DOMStorageMessageFilter* message_filter) { |
169 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 196 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
170 DCHECK(message_filter_set_.find(message_filter) == | 197 DCHECK(message_filter_set_.find(message_filter) == |
171 message_filter_set_.end()); | 198 message_filter_set_.end()); |
172 message_filter_set_.insert(message_filter); | 199 message_filter_set_.insert(message_filter); |
173 } | 200 } |
174 | 201 |
175 void DOMStorageContext::UnregisterMessageFilter( | 202 void DOMStorageContext::UnregisterMessageFilter( |
176 DOMStorageMessageFilter* message_filter) { | 203 DOMStorageMessageFilter* message_filter) { |
(...skipping 11 matching lines...) Expand all Loading... |
188 | 215 |
189 void DOMStorageContext::PurgeMemory() { | 216 void DOMStorageContext::PurgeMemory() { |
190 // It is only safe to purge the memory from the LocalStorage namespace, | 217 // It is only safe to purge the memory from the LocalStorage namespace, |
191 // because it is backed by disk and can be reloaded later. If we purge a | 218 // because it is backed by disk and can be reloaded later. If we purge a |
192 // SessionStorage namespace, its data will be gone forever, because it isn't | 219 // SessionStorage namespace, its data will be gone forever, because it isn't |
193 // currently backed by disk. | 220 // currently backed by disk. |
194 DOMStorageNamespace* local_storage = | 221 DOMStorageNamespace* local_storage = |
195 GetStorageNamespace(kLocalStorageNamespaceId, false); | 222 GetStorageNamespace(kLocalStorageNamespaceId, false); |
196 if (local_storage) | 223 if (local_storage) |
197 local_storage->PurgeMemory(); | 224 local_storage->PurgeMemory(); |
| 225 // In non-incognito profiles, the sessionStorage is backed up on the disk, and |
| 226 // can be purged. |
| 227 if (!data_path_.empty()) { |
| 228 for (StorageNamespaceMap::iterator it = storage_namespace_map_.begin(); |
| 229 it != storage_namespace_map_.end(); ++it) { |
| 230 } |
| 231 } |
198 } | 232 } |
199 | 233 |
200 void DOMStorageContext::DeleteDataModifiedSince(const base::Time& cutoff) { | 234 void DOMStorageContext::DeleteDataModifiedSince(const base::Time& cutoff) { |
201 // Make sure that we don't delete a database that's currently being accessed | 235 // Make sure that we don't delete a database that's currently being accessed |
202 // by unloading all of the databases temporarily. | 236 // by unloading all of the databases temporarily. |
203 PurgeMemory(); | 237 PurgeMemory(); |
204 | 238 |
205 file_util::FileEnumerator file_enumerator( | 239 file_util::FileEnumerator file_enumerator( |
206 data_path_.Append(kLocalStorageDirectory), false, | 240 data_path_.Append(kLocalStorageDirectory), false, |
207 file_util::FileEnumerator::FILES); | 241 file_util::FileEnumerator::FILES); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
258 if (!data_path_.empty()) | 292 if (!data_path_.empty()) |
259 dir_path = data_path_.Append(kLocalStorageDirectory); | 293 dir_path = data_path_.Append(kLocalStorageDirectory); |
260 DOMStorageNamespace* new_namespace = | 294 DOMStorageNamespace* new_namespace = |
261 DOMStorageNamespace::CreateLocalStorageNamespace(this, dir_path); | 295 DOMStorageNamespace::CreateLocalStorageNamespace(this, dir_path); |
262 RegisterStorageNamespace(new_namespace); | 296 RegisterStorageNamespace(new_namespace); |
263 return new_namespace; | 297 return new_namespace; |
264 } | 298 } |
265 | 299 |
266 DOMStorageNamespace* DOMStorageContext::CreateSessionStorage( | 300 DOMStorageNamespace* DOMStorageContext::CreateSessionStorage( |
267 int64 namespace_id) { | 301 int64 namespace_id) { |
| 302 FilePath dir_path; |
| 303 if (!data_path_.empty()) { |
| 304 // We cannot derive the directory name for the sessionStorage databases |
| 305 // directly from |namespace_id|. There is no guarantee that the same |
| 306 // namespace ID won't be reused before we restore the session. |
| 307 file_util::CreateDirectory(data_path_.Append(kSessionStorageDirectory)); |
| 308 file_util::CreateTemporaryDirInDir( |
| 309 data_path_.Append(kSessionStorageDirectory), "", &dir_path); |
| 310 } |
268 DOMStorageNamespace* new_namespace = | 311 DOMStorageNamespace* new_namespace = |
269 DOMStorageNamespace::CreateSessionStorageNamespace(this, namespace_id); | 312 DOMStorageNamespace::CreateSessionStorageNamespace(this, dir_path, |
| 313 namespace_id); |
270 RegisterStorageNamespace(new_namespace); | 314 RegisterStorageNamespace(new_namespace); |
271 return new_namespace; | 315 return new_namespace; |
272 } | 316 } |
273 | 317 |
274 void DOMStorageContext::RegisterStorageNamespace( | 318 void DOMStorageContext::RegisterStorageNamespace( |
275 DOMStorageNamespace* storage_namespace) { | 319 DOMStorageNamespace* storage_namespace) { |
276 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED)); | 320 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED)); |
277 int64 id = storage_namespace->id(); | 321 int64 id = storage_namespace->id(); |
278 DCHECK(!GetStorageNamespace(id, false)); | 322 DCHECK(!GetStorageNamespace(id, false)); |
279 storage_namespace_map_[id] = storage_namespace; | 323 storage_namespace_map_[id] = storage_namespace; |
280 } | 324 } |
281 | 325 |
282 /* static */ | 326 /* static */ |
283 void DOMStorageContext::CompleteCloningSessionStorage( | 327 void DOMStorageContext::CompleteCloningSessionStorage( |
284 DOMStorageContext* context, int64 existing_id, int64 clone_id) { | 328 DOMStorageContext* context, int64 existing_id, int64 clone_id, |
| 329 const FilePath& data_path) { |
285 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED)); | 330 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED)); |
286 DOMStorageNamespace* existing_namespace = | 331 DOMStorageNamespace* existing_namespace = |
287 context->GetStorageNamespace(existing_id, false); | 332 context->GetStorageNamespace(existing_id, false); |
288 // If nothing exists, then there's nothing to clone. | 333 // If nothing exists, then there's nothing to clone. |
289 if (existing_namespace) | 334 if (existing_namespace) { |
290 context->RegisterStorageNamespace(existing_namespace->Copy(clone_id)); | 335 if (data_path.empty()) { |
| 336 // Incognito session storage. |
| 337 context->RegisterStorageNamespace(existing_namespace->Copy(clone_id)); |
| 338 } else { |
| 339 DOMStorageNamespace* clone_namespace = |
| 340 context->CreateSessionStorage(clone_id); |
| 341 // Copy (in-memory) data from the existing namespace to the clone. Rely on |
| 342 // lazy writing to sync the data eventually on disk. |
| 343 DOMStorageNamespace* existing_namespace = |
| 344 context->GetStorageNamespace(existing_id, false); |
| 345 DCHECK(existing_namespace); |
| 346 |
| 347 // Ensure the copying won't cause storage events. |
| 348 DOMStorageMessageFilter::SetIgnoreStorageEvents(true); |
| 349 |
| 350 existing_namespace->CopyDataTo(clone_namespace); |
| 351 |
| 352 DOMStorageMessageFilter::SetIgnoreStorageEvents(false); |
| 353 } |
| 354 } |
291 } | 355 } |
292 | 356 |
293 FilePath DOMStorageContext::GetLocalStorageFilePath( | 357 FilePath DOMStorageContext::GetLocalStorageFilePath( |
294 const string16& origin_id) const { | 358 const string16& origin_id) const { |
295 FilePath storageDir = data_path_.Append( | 359 FilePath storageDir = data_path_.Append( |
296 DOMStorageContext::kLocalStorageDirectory); | 360 DOMStorageContext::kLocalStorageDirectory); |
297 FilePath::StringType id = | 361 FilePath::StringType id = |
298 webkit_glue::WebStringToFilePathString(origin_id); | 362 webkit_glue::WebStringToFilePathString(origin_id); |
299 return storageDir.Append(id.append(kLocalStorageExtension)); | 363 return storageDir.Append(id.append(kLocalStorageExtension)); |
300 } | 364 } |
| 365 |
| 366 void DOMStorageContext::DeleteUnneededSessionStorages( |
| 367 const std::set<std::string>& needed_session_storages) { |
| 368 file_util::FileEnumerator file_enumerator( |
| 369 data_path_.Append(kSessionStorageDirectory), |
| 370 false, file_util::FileEnumerator::DIRECTORIES); |
| 371 for (FilePath file_path = file_enumerator.Next(); !file_path.empty(); |
| 372 file_path = file_enumerator.Next()) { |
| 373 if (needed_session_storages.find(file_path.BaseName().value()) == |
| 374 needed_session_storages.end()) |
| 375 file_util::Delete(file_path, true); |
| 376 } |
| 377 } |
OLD | NEW |