| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "storage/browser/fileapi/obfuscated_file_util.h" | 5 #include "storage/browser/fileapi/obfuscated_file_util.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <memory> | 10 #include <memory> |
| 11 #include <queue> | 11 #include <queue> |
| 12 #include <tuple> | 12 #include <tuple> |
| 13 | 13 |
| 14 #include "base/files/file_util.h" | 14 #include "base/files/file_util.h" |
| 15 #include "base/format_macros.h" | 15 #include "base/format_macros.h" |
| 16 #include "base/logging.h" | 16 #include "base/logging.h" |
| 17 #include "base/memory/ptr_util.h" |
| 17 #include "base/message_loop/message_loop.h" | 18 #include "base/message_loop/message_loop.h" |
| 18 #include "base/metrics/histogram.h" | 19 #include "base/metrics/histogram.h" |
| 19 #include "base/stl_util.h" | |
| 20 #include "base/strings/string_number_conversions.h" | 20 #include "base/strings/string_number_conversions.h" |
| 21 #include "base/strings/string_util.h" | 21 #include "base/strings/string_util.h" |
| 22 #include "base/strings/stringprintf.h" | 22 #include "base/strings/stringprintf.h" |
| 23 #include "base/strings/sys_string_conversions.h" | 23 #include "base/strings/sys_string_conversions.h" |
| 24 #include "base/strings/utf_string_conversions.h" | 24 #include "base/strings/utf_string_conversions.h" |
| 25 #include "base/time/time.h" | 25 #include "base/time/time.h" |
| 26 #include "storage/browser/fileapi/file_observers.h" | 26 #include "storage/browser/fileapi/file_observers.h" |
| 27 #include "storage/browser/fileapi/file_system_context.h" | 27 #include "storage/browser/fileapi/file_system_context.h" |
| 28 #include "storage/browser/fileapi/file_system_operation_context.h" | 28 #include "storage/browser/fileapi/file_system_operation_context.h" |
| 29 #include "storage/browser/fileapi/native_file_util.h" | 29 #include "storage/browser/fileapi/native_file_util.h" |
| (...skipping 866 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 896 origin_database_->RemovePathForOrigin( | 896 origin_database_->RemovePathForOrigin( |
| 897 storage::GetIdentifierFromOrigin(origin)); | 897 storage::GetIdentifierFromOrigin(origin)); |
| 898 } | 898 } |
| 899 return base::DeleteFile(origin_path, true /* recursive */); | 899 return base::DeleteFile(origin_path, true /* recursive */); |
| 900 } | 900 } |
| 901 | 901 |
| 902 void ObfuscatedFileUtil::CloseFileSystemForOriginAndType( | 902 void ObfuscatedFileUtil::CloseFileSystemForOriginAndType( |
| 903 const GURL& origin, | 903 const GURL& origin, |
| 904 const std::string& type_string) { | 904 const std::string& type_string) { |
| 905 const std::string key_prefix = GetDirectoryDatabaseKey(origin, type_string); | 905 const std::string key_prefix = GetDirectoryDatabaseKey(origin, type_string); |
| 906 for (DirectoryMap::iterator iter = directories_.lower_bound(key_prefix); | 906 for (auto iter = directories_.lower_bound(key_prefix); |
| 907 iter != directories_.end();) { | 907 iter != directories_.end();) { |
| 908 if (!base::StartsWith(iter->first, key_prefix, | 908 if (!base::StartsWith(iter->first, key_prefix, |
| 909 base::CompareCase::SENSITIVE)) | 909 base::CompareCase::SENSITIVE)) |
| 910 break; | 910 break; |
| 911 DCHECK(type_string.empty() || iter->first == key_prefix); | 911 DCHECK(type_string.empty() || iter->first == key_prefix); |
| 912 std::unique_ptr<SandboxDirectoryDatabase> database(iter->second); | |
| 913 directories_.erase(iter++); | 912 directories_.erase(iter++); |
| 914 } | 913 } |
| 915 } | 914 } |
| 916 | 915 |
| 917 ObfuscatedFileUtil::AbstractOriginEnumerator* | 916 ObfuscatedFileUtil::AbstractOriginEnumerator* |
| 918 ObfuscatedFileUtil::CreateOriginEnumerator() { | 917 ObfuscatedFileUtil::CreateOriginEnumerator() { |
| 919 std::vector<SandboxOriginDatabase::OriginRecord> origins; | 918 std::vector<SandboxOriginDatabase::OriginRecord> origins; |
| 920 | 919 |
| 921 InitOriginDatabase(GURL(), false); | 920 InitOriginDatabase(GURL(), false); |
| 922 return new ObfuscatedOriginEnumerator( | 921 return new ObfuscatedOriginEnumerator( |
| 923 origin_database_.get(), file_system_directory_); | 922 origin_database_.get(), file_system_directory_); |
| 924 } | 923 } |
| 925 | 924 |
| 926 void ObfuscatedFileUtil::DestroyDirectoryDatabase( | 925 void ObfuscatedFileUtil::DestroyDirectoryDatabase( |
| 927 const GURL& origin, | 926 const GURL& origin, |
| 928 const std::string& type_string) { | 927 const std::string& type_string) { |
| 929 // If |type_string| is empty, delete all filesystem types under |origin|. | 928 // If |type_string| is empty, delete all filesystem types under |origin|. |
| 930 const std::string key_prefix = GetDirectoryDatabaseKey(origin, type_string); | 929 const std::string key_prefix = GetDirectoryDatabaseKey(origin, type_string); |
| 931 for (DirectoryMap::iterator iter = directories_.lower_bound(key_prefix); | 930 for (auto iter = directories_.lower_bound(key_prefix); |
| 932 iter != directories_.end();) { | 931 iter != directories_.end();) { |
| 933 if (!base::StartsWith(iter->first, key_prefix, | 932 if (!base::StartsWith(iter->first, key_prefix, |
| 934 base::CompareCase::SENSITIVE)) | 933 base::CompareCase::SENSITIVE)) |
| 935 break; | 934 break; |
| 936 DCHECK(type_string.empty() || iter->first == key_prefix); | 935 DCHECK(type_string.empty() || iter->first == key_prefix); |
| 937 std::unique_ptr<SandboxDirectoryDatabase> database(iter->second); | 936 std::unique_ptr<SandboxDirectoryDatabase> database = |
| 937 std::move(iter->second); |
| 938 directories_.erase(iter++); | 938 directories_.erase(iter++); |
| 939 | 939 |
| 940 // Continue to destroy databases even if it failed because it doesn't affect | 940 // Continue to destroy databases even if it failed because it doesn't affect |
| 941 // the final result. | 941 // the final result. |
| 942 database->DestroyDatabase(); | 942 database->DestroyDatabase(); |
| 943 } | 943 } |
| 944 } | 944 } |
| 945 | 945 |
| 946 // static | 946 // static |
| 947 int64_t ObfuscatedFileUtil::ComputeFilePathCost(const base::FilePath& path) { | 947 int64_t ObfuscatedFileUtil::ComputeFilePathCost(const base::FilePath& path) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 962 for (size_t i = 0; i < type_strings_to_prepopulate.size(); ++i) { | 962 for (size_t i = 0; i < type_strings_to_prepopulate.size(); ++i) { |
| 963 const std::string type_string = type_strings_to_prepopulate[i]; | 963 const std::string type_string = type_strings_to_prepopulate[i]; |
| 964 // Only handles known types. | 964 // Only handles known types. |
| 965 if (!base::ContainsKey(known_type_strings_, type_string)) | 965 if (!base::ContainsKey(known_type_strings_, type_string)) |
| 966 continue; | 966 continue; |
| 967 base::File::Error error = base::File::FILE_ERROR_FAILED; | 967 base::File::Error error = base::File::FILE_ERROR_FAILED; |
| 968 base::FilePath path = GetDirectoryForOriginAndType( | 968 base::FilePath path = GetDirectoryForOriginAndType( |
| 969 origin, type_string, false, &error); | 969 origin, type_string, false, &error); |
| 970 if (error != base::File::FILE_OK) | 970 if (error != base::File::FILE_OK) |
| 971 continue; | 971 continue; |
| 972 std::unique_ptr<SandboxDirectoryDatabase> db( | 972 std::unique_ptr<SandboxDirectoryDatabase> db = |
| 973 new SandboxDirectoryDatabase(path, env_override_)); | 973 base::MakeUnique<SandboxDirectoryDatabase>(path, env_override_); |
| 974 if (db->Init(SandboxDirectoryDatabase::FAIL_ON_CORRUPTION)) { | 974 if (db->Init(SandboxDirectoryDatabase::FAIL_ON_CORRUPTION)) { |
| 975 directories_[GetDirectoryDatabaseKey(origin, type_string)] = db.release(); | 975 directories_[GetDirectoryDatabaseKey(origin, type_string)] = |
| 976 std::move(db); |
| 976 MarkUsed(); | 977 MarkUsed(); |
| 977 // Don't populate more than one database, as it may rather hurt | 978 // Don't populate more than one database, as it may rather hurt |
| 978 // performance. | 979 // performance. |
| 979 break; | 980 break; |
| 980 } | 981 } |
| 981 } | 982 } |
| 982 } | 983 } |
| 983 | 984 |
| 984 base::FilePath ObfuscatedFileUtil::GetDirectoryForURL( | 985 base::FilePath ObfuscatedFileUtil::GetDirectoryForURL( |
| 985 const FileSystemURL& url, | 986 const FileSystemURL& url, |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1161 // We may not have quota even to create the database. | 1162 // We may not have quota even to create the database. |
| 1162 // Ah, in that case don't even get here? | 1163 // Ah, in that case don't even get here? |
| 1163 // Still doesn't answer the quota issue, though. | 1164 // Still doesn't answer the quota issue, though. |
| 1164 SandboxDirectoryDatabase* ObfuscatedFileUtil::GetDirectoryDatabase( | 1165 SandboxDirectoryDatabase* ObfuscatedFileUtil::GetDirectoryDatabase( |
| 1165 const FileSystemURL& url, bool create) { | 1166 const FileSystemURL& url, bool create) { |
| 1166 std::string key = GetDirectoryDatabaseKey( | 1167 std::string key = GetDirectoryDatabaseKey( |
| 1167 url.origin(), CallGetTypeStringForURL(url)); | 1168 url.origin(), CallGetTypeStringForURL(url)); |
| 1168 if (key.empty()) | 1169 if (key.empty()) |
| 1169 return NULL; | 1170 return NULL; |
| 1170 | 1171 |
| 1171 DirectoryMap::iterator iter = directories_.find(key); | 1172 auto iter = directories_.find(key); |
| 1172 if (iter != directories_.end()) { | 1173 if (iter != directories_.end()) { |
| 1173 MarkUsed(); | 1174 MarkUsed(); |
| 1174 return iter->second; | 1175 return iter->second.get(); |
| 1175 } | 1176 } |
| 1176 | 1177 |
| 1177 base::File::Error error = base::File::FILE_OK; | 1178 base::File::Error error = base::File::FILE_OK; |
| 1178 base::FilePath path = GetDirectoryForURL(url, create, &error); | 1179 base::FilePath path = GetDirectoryForURL(url, create, &error); |
| 1179 if (error != base::File::FILE_OK) { | 1180 if (error != base::File::FILE_OK) { |
| 1180 LOG(WARNING) << "Failed to get origin+type directory: " | 1181 LOG(WARNING) << "Failed to get origin+type directory: " |
| 1181 << url.DebugString() << " error:" << error; | 1182 << url.DebugString() << " error:" << error; |
| 1182 return NULL; | 1183 return NULL; |
| 1183 } | 1184 } |
| 1184 MarkUsed(); | 1185 MarkUsed(); |
| 1185 SandboxDirectoryDatabase* database = | 1186 directories_[key] = |
| 1186 new SandboxDirectoryDatabase(path, env_override_); | 1187 base::MakeUnique<SandboxDirectoryDatabase>(path, env_override_); |
| 1187 directories_[key] = database; | 1188 return directories_[key].get(); |
| 1188 return database; | |
| 1189 } | 1189 } |
| 1190 | 1190 |
| 1191 base::FilePath ObfuscatedFileUtil::GetDirectoryForOrigin( | 1191 base::FilePath ObfuscatedFileUtil::GetDirectoryForOrigin( |
| 1192 const GURL& origin, bool create, base::File::Error* error_code) { | 1192 const GURL& origin, bool create, base::File::Error* error_code) { |
| 1193 if (!InitOriginDatabase(origin, create)) { | 1193 if (!InitOriginDatabase(origin, create)) { |
| 1194 if (error_code) { | 1194 if (error_code) { |
| 1195 *error_code = create ? | 1195 *error_code = create ? |
| 1196 base::File::FILE_ERROR_FAILED : | 1196 base::File::FILE_ERROR_FAILED : |
| 1197 base::File::FILE_ERROR_NOT_FOUND; | 1197 base::File::FILE_ERROR_NOT_FOUND; |
| 1198 } | 1198 } |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1257 } else { | 1257 } else { |
| 1258 timer_->Start(FROM_HERE, | 1258 timer_->Start(FROM_HERE, |
| 1259 base::TimeDelta::FromSeconds(db_flush_delay_seconds_), | 1259 base::TimeDelta::FromSeconds(db_flush_delay_seconds_), |
| 1260 base::Bind(&ObfuscatedFileUtil::DropDatabases, | 1260 base::Bind(&ObfuscatedFileUtil::DropDatabases, |
| 1261 base::Unretained(this))); | 1261 base::Unretained(this))); |
| 1262 } | 1262 } |
| 1263 } | 1263 } |
| 1264 | 1264 |
| 1265 void ObfuscatedFileUtil::DropDatabases() { | 1265 void ObfuscatedFileUtil::DropDatabases() { |
| 1266 origin_database_.reset(); | 1266 origin_database_.reset(); |
| 1267 base::STLDeleteContainerPairSecondPointers(directories_.begin(), | |
| 1268 directories_.end()); | |
| 1269 directories_.clear(); | 1267 directories_.clear(); |
| 1270 timer_.reset(); | 1268 timer_.reset(); |
| 1271 } | 1269 } |
| 1272 | 1270 |
| 1273 bool ObfuscatedFileUtil::InitOriginDatabase(const GURL& origin_hint, | 1271 bool ObfuscatedFileUtil::InitOriginDatabase(const GURL& origin_hint, |
| 1274 bool create) { | 1272 bool create) { |
| 1275 if (origin_database_) | 1273 if (origin_database_) |
| 1276 return true; | 1274 return true; |
| 1277 | 1275 |
| 1278 if (!create && !base::DirectoryExists(file_system_directory_)) | 1276 if (!create && !base::DirectoryExists(file_system_directory_)) |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1419 } | 1417 } |
| 1420 return file; | 1418 return file; |
| 1421 } | 1419 } |
| 1422 | 1420 |
| 1423 bool ObfuscatedFileUtil::HasIsolatedStorage(const GURL& origin) { | 1421 bool ObfuscatedFileUtil::HasIsolatedStorage(const GURL& origin) { |
| 1424 return special_storage_policy_.get() && | 1422 return special_storage_policy_.get() && |
| 1425 special_storage_policy_->HasIsolatedStorage(origin); | 1423 special_storage_policy_->HasIsolatedStorage(origin); |
| 1426 } | 1424 } |
| 1427 | 1425 |
| 1428 } // namespace storage | 1426 } // namespace storage |
| OLD | NEW |