| 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 |