Chromium Code Reviews| 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" |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 45 file_util::Delete(file_path, false); | 45 file_util::Delete(file_path, false); |
| 46 } | 46 } |
| 47 } | 47 } |
| 48 } | 48 } |
| 49 | 49 |
| 50 } // namespace | 50 } // namespace |
| 51 | 51 |
| 52 const FilePath::CharType DOMStorageContext::kLocalStorageDirectory[] = | 52 const FilePath::CharType DOMStorageContext::kLocalStorageDirectory[] = |
| 53 FILE_PATH_LITERAL("Local Storage"); | 53 FILE_PATH_LITERAL("Local Storage"); |
| 54 | 54 |
| 55 const FilePath::CharType DOMStorageContext::kSessionStorageDirectory[] = | |
| 56 FILE_PATH_LITERAL("Session Storage"); | |
| 57 | |
| 55 const FilePath::CharType DOMStorageContext::kLocalStorageExtension[] = | 58 const FilePath::CharType DOMStorageContext::kLocalStorageExtension[] = |
| 56 FILE_PATH_LITERAL(".localstorage"); | 59 FILE_PATH_LITERAL(".localstorage"); |
| 57 | 60 |
| 58 DOMStorageContext::DOMStorageContext( | 61 DOMStorageContext::DOMStorageContext( |
| 59 WebKitContext* webkit_context, | 62 WebKitContext* webkit_context, |
| 60 quota::SpecialStoragePolicy* special_storage_policy) | 63 quota::SpecialStoragePolicy* special_storage_policy) |
| 61 : last_storage_area_id_(0), | 64 : last_storage_area_id_(0), |
| 62 last_session_storage_namespace_id_on_ui_thread_(kLocalStorageNamespaceId), | 65 last_session_storage_namespace_id_on_ui_thread_(kLocalStorageNamespaceId), |
| 63 last_session_storage_namespace_id_on_io_thread_(kLocalStorageNamespaceId), | 66 last_session_storage_namespace_id_on_io_thread_(kLocalStorageNamespaceId), |
| 64 clear_local_state_on_exit_(false), | 67 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_; | 110 return ++last_session_storage_namespace_id_on_ui_thread_; |
| 108 return --last_session_storage_namespace_id_on_io_thread_; | 111 return --last_session_storage_namespace_id_on_io_thread_; |
| 109 } | 112 } |
| 110 | 113 |
| 111 int64 DOMStorageContext::CloneSessionStorage(int64 original_id) { | 114 int64 DOMStorageContext::CloneSessionStorage(int64 original_id) { |
| 112 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED)); | 115 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED)); |
| 113 int64 clone_id = AllocateSessionStorageNamespaceId(); | 116 int64 clone_id = AllocateSessionStorageNamespaceId(); |
| 114 BrowserThread::PostTask( | 117 BrowserThread::PostTask( |
| 115 BrowserThread::WEBKIT_DEPRECATED, FROM_HERE, | 118 BrowserThread::WEBKIT_DEPRECATED, FROM_HERE, |
| 116 base::Bind(&DOMStorageContext::CompleteCloningSessionStorage, this, | 119 base::Bind(&DOMStorageContext::CompleteCloningSessionStorage, this, |
| 117 original_id, clone_id)); | 120 original_id, clone_id, data_path_)); |
| 118 return clone_id; | 121 return clone_id; |
| 119 } | 122 } |
| 120 | 123 |
| 121 void DOMStorageContext::RegisterStorageArea(DOMStorageArea* storage_area) { | 124 void DOMStorageContext::RegisterStorageArea(DOMStorageArea* storage_area) { |
| 122 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED)); | 125 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED)); |
| 123 int64 id = storage_area->id(); | 126 int64 id = storage_area->id(); |
| 124 DCHECK(!GetStorageArea(id)); | 127 DCHECK(!GetStorageArea(id)); |
| 125 storage_area_map_[id] = storage_area; | 128 storage_area_map_[id] = storage_area; |
| 126 } | 129 } |
| 127 | 130 |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 140 return iter->second; | 143 return iter->second; |
| 141 } | 144 } |
| 142 | 145 |
| 143 void DOMStorageContext::DeleteSessionStorageNamespace(int64 namespace_id) { | 146 void DOMStorageContext::DeleteSessionStorageNamespace(int64 namespace_id) { |
| 144 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED)); | 147 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED)); |
| 145 StorageNamespaceMap::iterator iter = | 148 StorageNamespaceMap::iterator iter = |
| 146 storage_namespace_map_.find(namespace_id); | 149 storage_namespace_map_.find(namespace_id); |
| 147 if (iter == storage_namespace_map_.end()) | 150 if (iter == storage_namespace_map_.end()) |
| 148 return; | 151 return; |
| 149 DCHECK(iter->second->dom_storage_type() == DOM_STORAGE_SESSION); | 152 DCHECK(iter->second->dom_storage_type() == DOM_STORAGE_SESSION); |
| 153 FilePath session_storage_directory = | |
| 154 iter->second->session_storage_directory(); | |
| 150 delete iter->second; | 155 delete iter->second; |
| 151 storage_namespace_map_.erase(iter); | 156 storage_namespace_map_.erase(iter); |
| 157 | |
| 158 if (!save_session_state_ && | |
| 159 !session_storage_directory.empty() && | |
| 160 !data_path_.empty()) { | |
| 161 FilePath to_delete = data_path_.Append(kSessionStorageDirectory) | |
| 162 .Append(session_storage_directory); | |
| 163 } | |
| 152 } | 164 } |
| 153 | 165 |
| 154 DOMStorageNamespace* DOMStorageContext::GetStorageNamespace( | 166 DOMStorageNamespace* DOMStorageContext::GetStorageNamespace( |
| 155 int64 id, bool allocation_allowed) { | 167 int64 id, bool allocation_allowed) { |
| 156 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED)); | 168 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED)); |
| 157 StorageNamespaceMap::iterator iter = storage_namespace_map_.find(id); | 169 StorageNamespaceMap::iterator iter = storage_namespace_map_.find(id); |
| 158 if (iter != storage_namespace_map_.end()) | 170 if (iter != storage_namespace_map_.end()) |
| 159 return iter->second; | 171 return iter->second; |
| 160 if (!allocation_allowed) | 172 if (!allocation_allowed) |
| 161 return NULL; | 173 return NULL; |
| 162 if (id == kLocalStorageNamespaceId) | 174 if (id == kLocalStorageNamespaceId) |
| 163 return CreateLocalStorage(); | 175 return CreateLocalStorage(); |
| 164 return CreateSessionStorage(id); | 176 return CreateSessionStorage(id); |
| 165 } | 177 } |
| 166 | 178 |
| 179 DOMStorageNamespace* DOMStorageContext::RecreateSessionStorageNamespace( | |
| 180 int64 id, | |
| 181 const FilePath& session_storage_directory) { | |
| 182 FilePath dir_path; | |
| 183 if (!data_path_.empty()) { | |
| 184 dir_path = data_path_.Append(kSessionStorageDirectory) | |
| 185 .Append(session_storage_directory); | |
| 186 } | |
| 187 DOMStorageNamespace* new_namespace = | |
| 188 DOMStorageNamespace::CreateSessionStorageNamespace(this, dir_path, id); | |
| 189 RegisterStorageNamespace(new_namespace); | |
| 190 return new_namespace; | |
| 191 } | |
| 192 | |
| 167 void DOMStorageContext::RegisterMessageFilter( | 193 void DOMStorageContext::RegisterMessageFilter( |
| 168 DOMStorageMessageFilter* message_filter) { | 194 DOMStorageMessageFilter* message_filter) { |
| 169 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 195 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 170 DCHECK(message_filter_set_.find(message_filter) == | 196 DCHECK(message_filter_set_.find(message_filter) == |
| 171 message_filter_set_.end()); | 197 message_filter_set_.end()); |
| 172 message_filter_set_.insert(message_filter); | 198 message_filter_set_.insert(message_filter); |
| 173 } | 199 } |
| 174 | 200 |
| 175 void DOMStorageContext::UnregisterMessageFilter( | 201 void DOMStorageContext::UnregisterMessageFilter( |
| 176 DOMStorageMessageFilter* message_filter) { | 202 DOMStorageMessageFilter* message_filter) { |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 188 | 214 |
| 189 void DOMStorageContext::PurgeMemory() { | 215 void DOMStorageContext::PurgeMemory() { |
| 190 // It is only safe to purge the memory from the LocalStorage namespace, | 216 // 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 | 217 // 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 | 218 // SessionStorage namespace, its data will be gone forever, because it isn't |
| 193 // currently backed by disk. | 219 // currently backed by disk. |
| 194 DOMStorageNamespace* local_storage = | 220 DOMStorageNamespace* local_storage = |
| 195 GetStorageNamespace(kLocalStorageNamespaceId, false); | 221 GetStorageNamespace(kLocalStorageNamespaceId, false); |
| 196 if (local_storage) | 222 if (local_storage) |
| 197 local_storage->PurgeMemory(); | 223 local_storage->PurgeMemory(); |
| 224 // In non-incognito profiles, the sessionStorage is backed up on the disk, and | |
| 225 // can be purged. | |
| 226 if (!data_path_.empty()) { | |
| 227 for (StorageNamespaceMap::iterator it = storage_namespace_map_.begin(); | |
| 228 it != storage_namespace_map_.end(); ++it) { | |
| 229 } | |
| 230 } | |
| 198 } | 231 } |
| 199 | 232 |
| 200 void DOMStorageContext::DeleteDataModifiedSince(const base::Time& cutoff) { | 233 void DOMStorageContext::DeleteDataModifiedSince(const base::Time& cutoff) { |
| 201 // Make sure that we don't delete a database that's currently being accessed | 234 // Make sure that we don't delete a database that's currently being accessed |
| 202 // by unloading all of the databases temporarily. | 235 // by unloading all of the databases temporarily. |
| 203 PurgeMemory(); | 236 PurgeMemory(); |
| 204 | 237 |
| 205 file_util::FileEnumerator file_enumerator( | 238 file_util::FileEnumerator file_enumerator( |
| 206 data_path_.Append(kLocalStorageDirectory), false, | 239 data_path_.Append(kLocalStorageDirectory), false, |
| 207 file_util::FileEnumerator::FILES); | 240 file_util::FileEnumerator::FILES); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 258 if (!data_path_.empty()) | 291 if (!data_path_.empty()) |
| 259 dir_path = data_path_.Append(kLocalStorageDirectory); | 292 dir_path = data_path_.Append(kLocalStorageDirectory); |
| 260 DOMStorageNamespace* new_namespace = | 293 DOMStorageNamespace* new_namespace = |
| 261 DOMStorageNamespace::CreateLocalStorageNamespace(this, dir_path); | 294 DOMStorageNamespace::CreateLocalStorageNamespace(this, dir_path); |
| 262 RegisterStorageNamespace(new_namespace); | 295 RegisterStorageNamespace(new_namespace); |
| 263 return new_namespace; | 296 return new_namespace; |
| 264 } | 297 } |
| 265 | 298 |
| 266 DOMStorageNamespace* DOMStorageContext::CreateSessionStorage( | 299 DOMStorageNamespace* DOMStorageContext::CreateSessionStorage( |
| 267 int64 namespace_id) { | 300 int64 namespace_id) { |
| 301 FilePath dir_path; | |
| 302 if (!data_path_.empty()) { | |
| 303 // We cannot derive the directory name for the sessionStorage databases | |
| 304 // directly from |namespace_id|. There is no guarantee that the same | |
| 305 // namespace ID won't be reused before we restore the session. | |
| 306 file_util::CreateDirectory(data_path_.Append(kSessionStorageDirectory)); | |
| 307 file_util::CreateTemporaryDirInDir( | |
| 308 data_path_.Append(kSessionStorageDirectory), "", &dir_path); | |
| 309 } | |
| 268 DOMStorageNamespace* new_namespace = | 310 DOMStorageNamespace* new_namespace = |
| 269 DOMStorageNamespace::CreateSessionStorageNamespace(this, namespace_id); | 311 DOMStorageNamespace::CreateSessionStorageNamespace(this, dir_path, |
| 312 namespace_id); | |
| 270 RegisterStorageNamespace(new_namespace); | 313 RegisterStorageNamespace(new_namespace); |
| 271 return new_namespace; | 314 return new_namespace; |
| 272 } | 315 } |
| 273 | 316 |
| 274 void DOMStorageContext::RegisterStorageNamespace( | 317 void DOMStorageContext::RegisterStorageNamespace( |
| 275 DOMStorageNamespace* storage_namespace) { | 318 DOMStorageNamespace* storage_namespace) { |
| 276 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED)); | 319 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED)); |
| 277 int64 id = storage_namespace->id(); | 320 int64 id = storage_namespace->id(); |
| 278 DCHECK(!GetStorageNamespace(id, false)); | 321 DCHECK(!GetStorageNamespace(id, false)); |
| 279 storage_namespace_map_[id] = storage_namespace; | 322 storage_namespace_map_[id] = storage_namespace; |
| 280 } | 323 } |
| 281 | 324 |
| 282 /* static */ | 325 /* static */ |
| 283 void DOMStorageContext::CompleteCloningSessionStorage( | 326 void DOMStorageContext::CompleteCloningSessionStorage( |
| 284 DOMStorageContext* context, int64 existing_id, int64 clone_id) { | 327 DOMStorageContext* context, int64 existing_id, int64 clone_id, |
| 328 const FilePath& data_path) { | |
| 285 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED)); | 329 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED)); |
| 286 DOMStorageNamespace* existing_namespace = | 330 DOMStorageNamespace* existing_namespace = |
| 287 context->GetStorageNamespace(existing_id, false); | 331 context->GetStorageNamespace(existing_id, false); |
| 288 // If nothing exists, then there's nothing to clone. | 332 // If nothing exists, then there's nothing to clone. |
| 289 if (existing_namespace) | 333 if (existing_namespace) { |
| 290 context->RegisterStorageNamespace(existing_namespace->Copy(clone_id)); | 334 if (data_path.empty()) { |
| 335 // Incognito session storage. | |
| 336 context->RegisterStorageNamespace(existing_namespace->Copy(clone_id)); | |
| 337 } else { | |
| 338 FilePath from_path; | |
| 339 FilePath to_path; | |
| 340 if (!data_path.empty()) { | |
| 341 from_path = data_path.Append(kSessionStorageDirectory).Append( | |
| 342 existing_namespace->session_storage_directory()); | |
| 343 if (!file_util::CreateTemporaryDirInDir( | |
| 344 data_path.Append(kSessionStorageDirectory), "", &to_path)) { | |
| 345 LOG(WARNING) << "Failed to create directory for sessionStorage in " << | |
| 346 data_path.Append(kSessionStorageDirectory).value(); | |
| 347 return; | |
| 348 } | |
| 349 // Copy the files from from_path to to_path. file_util doesn't seem to | |
| 350 // have a simple function for doing this. | |
|
michaeln
2012/01/17 21:25:13
Not sure this approach to cloning session storage
marja
2012/01/19 12:43:43
Ah, true, this was broken, thanks for pointing it
| |
| 351 file_util::FileEnumerator file_enumerator( | |
| 352 from_path, false, file_util::FileEnumerator::FILES); | |
| 353 for (FilePath path = file_enumerator.Next(); !path.value().empty(); | |
| 354 path = file_enumerator.Next()) { | |
| 355 if (!file_util::CopyFile(path, to_path.Append(path.BaseName()))) { | |
| 356 LOG(WARNING) << "Failed to copy sessionStorage file from " << | |
| 357 path.value() << " to " << to_path.value(); | |
| 358 return; | |
| 359 } | |
| 360 } | |
| 361 } | |
| 362 context->RecreateSessionStorageNamespace(clone_id, to_path.BaseName()); | |
| 363 } | |
| 364 } | |
| 291 } | 365 } |
| 292 | 366 |
| 293 FilePath DOMStorageContext::GetLocalStorageFilePath( | 367 FilePath DOMStorageContext::GetLocalStorageFilePath( |
| 294 const string16& origin_id) const { | 368 const string16& origin_id) const { |
| 295 FilePath storageDir = data_path_.Append( | 369 FilePath storageDir = data_path_.Append( |
| 296 DOMStorageContext::kLocalStorageDirectory); | 370 DOMStorageContext::kLocalStorageDirectory); |
| 297 FilePath::StringType id = | 371 FilePath::StringType id = |
| 298 webkit_glue::WebStringToFilePathString(origin_id); | 372 webkit_glue::WebStringToFilePathString(origin_id); |
| 299 return storageDir.Append(id.append(kLocalStorageExtension)); | 373 return storageDir.Append(id.append(kLocalStorageExtension)); |
| 300 } | 374 } |
| 375 | |
| 376 void DOMStorageContext::DeleteUnneededSessionStorages( | |
| 377 const std::set<std::string>& needed_session_storages) { | |
| 378 file_util::FileEnumerator file_enumerator( | |
| 379 data_path_.Append(kSessionStorageDirectory), | |
| 380 false, file_util::FileEnumerator::DIRECTORIES); | |
| 381 for (FilePath file_path = file_enumerator.Next(); !file_path.empty(); | |
| 382 file_path = file_enumerator.Next()) { | |
| 383 if (needed_session_storages.find(file_path.BaseName().value()) == | |
| 384 needed_session_storages.end()) | |
| 385 file_util::Delete(file_path, true); | |
| 386 } | |
| 387 } | |
| OLD | NEW |