Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(414)

Side by Side Diff: content/browser/in_process_webkit/dom_storage_context.cc

Issue 8929007: Restore sessionStorage when chrome restarts. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix: cloning storage areas. Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698