| OLD | NEW |
| (Empty) |
| 1 // Copyright 2013 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 "webkit/browser/fileapi/sandbox_prioritized_origin_database.h" | |
| 6 | |
| 7 #include "base/file_util.h" | |
| 8 #include "base/files/file.h" | |
| 9 #include "base/files/file_path.h" | |
| 10 #include "base/logging.h" | |
| 11 #include "base/pickle.h" | |
| 12 #include "webkit/browser/fileapi/sandbox_isolated_origin_database.h" | |
| 13 #include "webkit/browser/fileapi/sandbox_origin_database.h" | |
| 14 | |
| 15 namespace storage { | |
| 16 | |
| 17 namespace { | |
| 18 | |
| 19 const base::FilePath::CharType kPrimaryDirectory[] = | |
| 20 FILE_PATH_LITERAL("primary"); | |
| 21 const base::FilePath::CharType kPrimaryOriginFile[] = | |
| 22 FILE_PATH_LITERAL("primary.origin"); | |
| 23 | |
| 24 bool WritePrimaryOriginFile(const base::FilePath& path, | |
| 25 const std::string& origin) { | |
| 26 base::File file(path, base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_WRITE); | |
| 27 if (!file.IsValid()) | |
| 28 return false; | |
| 29 if (!file.created()) | |
| 30 file.SetLength(0); | |
| 31 Pickle pickle; | |
| 32 pickle.WriteString(origin); | |
| 33 file.Write(0, static_cast<const char*>(pickle.data()), pickle.size()); | |
| 34 file.Flush(); | |
| 35 return true; | |
| 36 } | |
| 37 | |
| 38 bool ReadPrimaryOriginFile(const base::FilePath& path, | |
| 39 std::string* origin) { | |
| 40 std::string buffer; | |
| 41 if (!base::ReadFileToString(path, &buffer)) | |
| 42 return false; | |
| 43 Pickle pickle(buffer.data(), buffer.size()); | |
| 44 PickleIterator iter(pickle); | |
| 45 return pickle.ReadString(&iter, origin) && !origin->empty(); | |
| 46 } | |
| 47 | |
| 48 } // namespace | |
| 49 | |
| 50 SandboxPrioritizedOriginDatabase::SandboxPrioritizedOriginDatabase( | |
| 51 const base::FilePath& file_system_directory, | |
| 52 leveldb::Env* env_override) | |
| 53 : file_system_directory_(file_system_directory), | |
| 54 env_override_(env_override), | |
| 55 primary_origin_file_( | |
| 56 file_system_directory_.Append(kPrimaryOriginFile)) { | |
| 57 } | |
| 58 | |
| 59 SandboxPrioritizedOriginDatabase::~SandboxPrioritizedOriginDatabase() { | |
| 60 } | |
| 61 | |
| 62 bool SandboxPrioritizedOriginDatabase::InitializePrimaryOrigin( | |
| 63 const std::string& origin) { | |
| 64 if (!primary_origin_database_) { | |
| 65 if (!MaybeLoadPrimaryOrigin() && ResetPrimaryOrigin(origin)) { | |
| 66 MaybeMigrateDatabase(origin); | |
| 67 primary_origin_database_.reset( | |
| 68 new SandboxIsolatedOriginDatabase( | |
| 69 origin, | |
| 70 file_system_directory_, | |
| 71 base::FilePath(kPrimaryDirectory))); | |
| 72 return true; | |
| 73 } | |
| 74 } | |
| 75 | |
| 76 if (primary_origin_database_) | |
| 77 return primary_origin_database_->HasOriginPath(origin); | |
| 78 | |
| 79 return false; | |
| 80 } | |
| 81 | |
| 82 std::string SandboxPrioritizedOriginDatabase::GetPrimaryOrigin() { | |
| 83 MaybeLoadPrimaryOrigin(); | |
| 84 if (primary_origin_database_) | |
| 85 return primary_origin_database_->origin(); | |
| 86 return std::string(); | |
| 87 } | |
| 88 | |
| 89 bool SandboxPrioritizedOriginDatabase::HasOriginPath( | |
| 90 const std::string& origin) { | |
| 91 MaybeInitializeDatabases(false); | |
| 92 if (primary_origin_database_ && | |
| 93 primary_origin_database_->HasOriginPath(origin)) | |
| 94 return true; | |
| 95 if (origin_database_) | |
| 96 return origin_database_->HasOriginPath(origin); | |
| 97 return false; | |
| 98 } | |
| 99 | |
| 100 bool SandboxPrioritizedOriginDatabase::GetPathForOrigin( | |
| 101 const std::string& origin, base::FilePath* directory) { | |
| 102 MaybeInitializeDatabases(true); | |
| 103 if (primary_origin_database_ && | |
| 104 primary_origin_database_->GetPathForOrigin(origin, directory)) | |
| 105 return true; | |
| 106 DCHECK(origin_database_); | |
| 107 return origin_database_->GetPathForOrigin(origin, directory); | |
| 108 } | |
| 109 | |
| 110 bool SandboxPrioritizedOriginDatabase::RemovePathForOrigin( | |
| 111 const std::string& origin) { | |
| 112 MaybeInitializeDatabases(false); | |
| 113 if (primary_origin_database_ && | |
| 114 primary_origin_database_->HasOriginPath(origin)) { | |
| 115 primary_origin_database_.reset(); | |
| 116 base::DeleteFile(file_system_directory_.Append(kPrimaryOriginFile), | |
| 117 true /* recursive */); | |
| 118 return true; | |
| 119 } | |
| 120 if (origin_database_) | |
| 121 return origin_database_->RemovePathForOrigin(origin); | |
| 122 return true; | |
| 123 } | |
| 124 | |
| 125 bool SandboxPrioritizedOriginDatabase::ListAllOrigins( | |
| 126 std::vector<OriginRecord>* origins) { | |
| 127 // SandboxOriginDatabase may clear the |origins|, so call this before | |
| 128 // primary_origin_database_. | |
| 129 MaybeInitializeDatabases(false); | |
| 130 if (origin_database_ && !origin_database_->ListAllOrigins(origins)) | |
| 131 return false; | |
| 132 if (primary_origin_database_) | |
| 133 return primary_origin_database_->ListAllOrigins(origins); | |
| 134 return true; | |
| 135 } | |
| 136 | |
| 137 void SandboxPrioritizedOriginDatabase::DropDatabase() { | |
| 138 primary_origin_database_.reset(); | |
| 139 origin_database_.reset(); | |
| 140 } | |
| 141 | |
| 142 bool SandboxPrioritizedOriginDatabase::MaybeLoadPrimaryOrigin() { | |
| 143 if (primary_origin_database_) | |
| 144 return true; | |
| 145 std::string saved_origin; | |
| 146 if (!ReadPrimaryOriginFile(primary_origin_file_, &saved_origin)) | |
| 147 return false; | |
| 148 primary_origin_database_.reset( | |
| 149 new SandboxIsolatedOriginDatabase( | |
| 150 saved_origin, | |
| 151 file_system_directory_, | |
| 152 base::FilePath(kPrimaryDirectory))); | |
| 153 return true; | |
| 154 } | |
| 155 | |
| 156 bool SandboxPrioritizedOriginDatabase::ResetPrimaryOrigin( | |
| 157 const std::string& origin) { | |
| 158 DCHECK(!primary_origin_database_); | |
| 159 if (!WritePrimaryOriginFile(primary_origin_file_, origin)) | |
| 160 return false; | |
| 161 // We reset the primary origin directory too. | |
| 162 // (This means the origin file corruption causes data loss | |
| 163 // We could keep the directory there as the same origin will likely | |
| 164 // become the primary origin, but let's play conservatively.) | |
| 165 base::DeleteFile(file_system_directory_.Append(kPrimaryDirectory), | |
| 166 true /* recursive */); | |
| 167 return true; | |
| 168 } | |
| 169 | |
| 170 void SandboxPrioritizedOriginDatabase::MaybeMigrateDatabase( | |
| 171 const std::string& origin) { | |
| 172 MaybeInitializeNonPrimaryDatabase(false); | |
| 173 if (!origin_database_) | |
| 174 return; | |
| 175 if (origin_database_->HasOriginPath(origin)) { | |
| 176 base::FilePath directory_name; | |
| 177 if (origin_database_->GetPathForOrigin(origin, &directory_name) && | |
| 178 directory_name != base::FilePath(kPrimaryOriginFile)) { | |
| 179 base::FilePath from_path = file_system_directory_.Append(directory_name); | |
| 180 base::FilePath to_path = file_system_directory_.Append(kPrimaryDirectory); | |
| 181 | |
| 182 if (base::PathExists(to_path)) | |
| 183 base::DeleteFile(to_path, true /* recursive */); | |
| 184 base::Move(from_path, to_path); | |
| 185 } | |
| 186 | |
| 187 origin_database_->RemovePathForOrigin(origin); | |
| 188 } | |
| 189 | |
| 190 std::vector<OriginRecord> origins; | |
| 191 origin_database_->ListAllOrigins(&origins); | |
| 192 if (origins.empty()) { | |
| 193 origin_database_->RemoveDatabase(); | |
| 194 origin_database_.reset(); | |
| 195 } | |
| 196 } | |
| 197 | |
| 198 void SandboxPrioritizedOriginDatabase::MaybeInitializeDatabases( | |
| 199 bool create) { | |
| 200 MaybeLoadPrimaryOrigin(); | |
| 201 MaybeInitializeNonPrimaryDatabase(create); | |
| 202 } | |
| 203 | |
| 204 void SandboxPrioritizedOriginDatabase::MaybeInitializeNonPrimaryDatabase( | |
| 205 bool create) { | |
| 206 if (origin_database_) | |
| 207 return; | |
| 208 | |
| 209 origin_database_.reset(new SandboxOriginDatabase(file_system_directory_, | |
| 210 env_override_)); | |
| 211 if (!create && !base::DirectoryExists(origin_database_->GetDatabasePath())) { | |
| 212 origin_database_.reset(); | |
| 213 return; | |
| 214 } | |
| 215 } | |
| 216 | |
| 217 SandboxOriginDatabase* | |
| 218 SandboxPrioritizedOriginDatabase::GetSandboxOriginDatabase() { | |
| 219 MaybeInitializeNonPrimaryDatabase(true); | |
| 220 return origin_database_.get(); | |
| 221 } | |
| 222 | |
| 223 } // namespace storage | |
| OLD | NEW |