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

Side by Side Diff: webkit/browser/fileapi/sandbox_context.cc

Issue 21116008: FileAPI: Move FileSystemQuotaUtil related functions into SandboxContext (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: clean up Created 7 years, 4 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 2013 The Chromium Authors. All rights reserved. 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 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 "webkit/browser/fileapi/sandbox_context.h" 5 #include "webkit/browser/fileapi/sandbox_context.h"
6 6
7 #include "base/command_line.h"
8 #include "base/file_util.h"
9 #include "base/stl_util.h"
7 #include "base/task_runner_util.h" 10 #include "base/task_runner_util.h"
11 #include "net/base/net_util.h"
8 #include "webkit/browser/fileapi/async_file_util_adapter.h" 12 #include "webkit/browser/fileapi/async_file_util_adapter.h"
13 #include "webkit/browser/fileapi/file_system_context.h"
14 #include "webkit/browser/fileapi/file_system_operation_context.h"
15 #include "webkit/browser/fileapi/file_system_url.h"
9 #include "webkit/browser/fileapi/file_system_usage_cache.h" 16 #include "webkit/browser/fileapi/file_system_usage_cache.h"
10 #include "webkit/browser/fileapi/obfuscated_file_util.h" 17 #include "webkit/browser/fileapi/obfuscated_file_util.h"
11 #include "webkit/browser/fileapi/sandbox_quota_observer.h" 18 #include "webkit/browser/fileapi/sandbox_quota_observer.h"
12 #include "webkit/browser/quota/quota_manager.h" 19 #include "webkit/browser/quota/quota_manager.h"
20 #include "webkit/common/fileapi/file_system_util.h"
13 21
14 namespace fileapi { 22 namespace fileapi {
15 23
24 namespace {
25
26 // A command line switch to disable usage tracking.
27 const char kDisableUsageTracking[] = "disable-file-system-usage-tracking";
kinuko 2013/07/31 07:35:53 Wasn't this deleted?
nhiroki 2013/07/31 07:52:08 Oops, good catch! I deleted this in the previous c
28
29 // Restricted names.
30 // http://dev.w3.org/2009/dap/file-system/file-dir-sys.html#naming-restrictions
31 const base::FilePath::CharType* const kRestrictedNames[] = {
32 FILE_PATH_LITERAL("."), FILE_PATH_LITERAL(".."),
33 };
34
35 // Restricted chars.
36 const base::FilePath::CharType kRestrictedChars[] = {
37 FILE_PATH_LITERAL('/'), FILE_PATH_LITERAL('\\'),
38 };
39
40 class ObfuscatedOriginEnumerator
41 : public SandboxContext::OriginEnumerator {
42 public:
43 explicit ObfuscatedOriginEnumerator(ObfuscatedFileUtil* file_util) {
44 enum_.reset(file_util->CreateOriginEnumerator());
45 }
46 virtual ~ObfuscatedOriginEnumerator() {}
47
48 virtual GURL Next() OVERRIDE {
49 return enum_->Next();
50 }
51
52 virtual bool HasFileSystemType(fileapi::FileSystemType type) const OVERRIDE {
53 return enum_->HasFileSystemType(type);
54 }
55
56 private:
57 scoped_ptr<ObfuscatedFileUtil::AbstractOriginEnumerator> enum_;
58 };
59
60 } // namespace
61
16 const base::FilePath::CharType 62 const base::FilePath::CharType
17 SandboxContext::kFileSystemDirectory[] = FILE_PATH_LITERAL("File System"); 63 SandboxContext::kFileSystemDirectory[] = FILE_PATH_LITERAL("File System");
18 64
19 SandboxContext::SandboxContext( 65 SandboxContext::SandboxContext(
20 quota::QuotaManagerProxy* quota_manager_proxy, 66 quota::QuotaManagerProxy* quota_manager_proxy,
21 base::SequencedTaskRunner* file_task_runner, 67 base::SequencedTaskRunner* file_task_runner,
22 const base::FilePath& profile_path, 68 const base::FilePath& profile_path,
23 quota::SpecialStoragePolicy* special_storage_policy) 69 quota::SpecialStoragePolicy* special_storage_policy,
70 const FileSystemOptions& file_system_options)
24 : file_task_runner_(file_task_runner), 71 : file_task_runner_(file_task_runner),
25 sandbox_file_util_(new AsyncFileUtilAdapter( 72 sandbox_file_util_(new AsyncFileUtilAdapter(
26 new ObfuscatedFileUtil( 73 new ObfuscatedFileUtil(
27 special_storage_policy, 74 special_storage_policy,
28 profile_path.Append(kFileSystemDirectory), 75 profile_path.Append(kFileSystemDirectory),
29 file_task_runner))), 76 file_task_runner))),
30 file_system_usage_cache_(new FileSystemUsageCache(file_task_runner)), 77 file_system_usage_cache_(new FileSystemUsageCache(file_task_runner)),
31 quota_observer_(new SandboxQuotaObserver( 78 quota_observer_(new SandboxQuotaObserver(
32 quota_manager_proxy, 79 quota_manager_proxy,
33 file_task_runner, 80 file_task_runner,
34 sync_file_util(), 81 sync_file_util(),
35 usage_cache())), 82 usage_cache())),
36 special_storage_policy_(special_storage_policy) { 83 special_storage_policy_(special_storage_policy),
84 file_system_options_(file_system_options) {
37 } 85 }
38 86
39 SandboxContext::~SandboxContext() { 87 SandboxContext::~SandboxContext() {
40 if (!file_task_runner_->RunsTasksOnCurrentThread()) { 88 if (!file_task_runner_->RunsTasksOnCurrentThread()) {
41 AsyncFileUtilAdapter* sandbox_file_util = sandbox_file_util_.release(); 89 AsyncFileUtilAdapter* sandbox_file_util = sandbox_file_util_.release();
42 SandboxQuotaObserver* quota_observer = quota_observer_.release(); 90 SandboxQuotaObserver* quota_observer = quota_observer_.release();
43 FileSystemUsageCache* file_system_usage_cache = 91 FileSystemUsageCache* file_system_usage_cache =
44 file_system_usage_cache_.release(); 92 file_system_usage_cache_.release();
45 if (!file_task_runner_->DeleteSoon(FROM_HERE, sandbox_file_util)) 93 if (!file_task_runner_->DeleteSoon(FROM_HERE, sandbox_file_util))
46 delete sandbox_file_util; 94 delete sandbox_file_util;
47 if (!file_task_runner_->DeleteSoon(FROM_HERE, quota_observer)) 95 if (!file_task_runner_->DeleteSoon(FROM_HERE, quota_observer))
48 delete quota_observer; 96 delete quota_observer;
49 if (!file_task_runner_->DeleteSoon(FROM_HERE, file_system_usage_cache)) 97 if (!file_task_runner_->DeleteSoon(FROM_HERE, file_system_usage_cache))
50 delete file_system_usage_cache; 98 delete file_system_usage_cache;
51 } 99 }
52 } 100 }
53 101
102 bool SandboxContext::IsAccessValid(const FileSystemURL& url) const {
103 if (!IsAllowedScheme(url.origin()))
104 return false;
105
106 if (url.path().ReferencesParent())
107 return false;
108
109 // Return earlier if the path is '/', because VirtualPath::BaseName()
110 // returns '/' for '/' and we fail the "basename != '/'" check below.
111 // (We exclude '.' because it's disallowed by spec.)
112 if (VirtualPath::IsRootPath(url.path()) &&
113 url.path() != base::FilePath(base::FilePath::kCurrentDirectory))
114 return true;
115
116 // Restricted names specified in
117 // http://dev.w3.org/2009/dap/file-system/file-dir-sys.html#naming-restriction s
118 base::FilePath filename = VirtualPath::BaseName(url.path());
119 // See if the name is allowed to create.
120 for (size_t i = 0; i < arraysize(kRestrictedNames); ++i) {
121 if (filename.value() == kRestrictedNames[i])
122 return false;
123 }
124 for (size_t i = 0; i < arraysize(kRestrictedChars); ++i) {
125 if (filename.value().find(kRestrictedChars[i]) !=
126 base::FilePath::StringType::npos)
127 return false;
128 }
129
130 return true;
131 }
132
133 bool SandboxContext::IsAllowedScheme(const GURL& url) const {
134 // Basically we only accept http or https. We allow file:// URLs
135 // only if --allow-file-access-from-files flag is given.
136 if (url.SchemeIs("http") || url.SchemeIs("https"))
137 return true;
138 if (url.SchemeIsFileSystem())
139 return url.inner_url() && IsAllowedScheme(*url.inner_url());
140
141 for (size_t i = 0;
142 i < file_system_options_.additional_allowed_schemes().size();
143 ++i) {
144 if (url.SchemeIs(
145 file_system_options_.additional_allowed_schemes()[i].c_str()))
146 return true;
147 }
148 return false;
149 }
150
151 SandboxContext::OriginEnumerator* SandboxContext::CreateOriginEnumerator() {
152 return new ObfuscatedOriginEnumerator(sync_file_util());
153 }
154
155 base::FilePath SandboxContext::GetBaseDirectoryForOriginAndType(
156 const GURL& origin_url, fileapi::FileSystemType type, bool create) {
157 base::PlatformFileError error = base::PLATFORM_FILE_OK;
158 base::FilePath path = sync_file_util()->GetDirectoryForOriginAndType(
159 origin_url, type, create, &error);
160 if (error != base::PLATFORM_FILE_OK)
161 return base::FilePath();
162 return path;
163 }
164
165 base::PlatformFileError SandboxContext::DeleteOriginDataOnFileThread(
166 FileSystemContext* file_system_context,
167 quota::QuotaManagerProxy* proxy,
168 const GURL& origin_url,
169 fileapi::FileSystemType type) {
170 int64 usage = GetOriginUsageOnFileThread(file_system_context,
171 origin_url, type);
kinuko 2013/07/31 07:35:53 nit: indent
nhiroki 2013/07/31 07:52:08 Done.
172 usage_cache()->CloseCacheFiles();
173 bool result = sync_file_util()->DeleteDirectoryForOriginAndType(
174 origin_url, type);
175 if (result && proxy) {
176 proxy->NotifyStorageModified(
177 quota::QuotaClient::kFileSystem,
178 origin_url,
179 FileSystemTypeToQuotaStorageType(type),
180 -usage);
181 }
182
183 if (result)
184 return base::PLATFORM_FILE_OK;
185 return base::PLATFORM_FILE_ERROR_FAILED;
186 }
187
188 void SandboxContext::GetOriginsForTypeOnFileThread(
189 fileapi::FileSystemType type, std::set<GURL>* origins) {
190 DCHECK(origins);
191 scoped_ptr<OriginEnumerator> enumerator(CreateOriginEnumerator());
192 GURL origin;
193 while (!(origin = enumerator->Next()).is_empty()) {
194 if (enumerator->HasFileSystemType(type))
195 origins->insert(origin);
196 }
197 }
198
199 void SandboxContext::GetOriginsForHostOnFileThread(
200 fileapi::FileSystemType type, const std::string& host,
201 std::set<GURL>* origins) {
202 DCHECK(origins);
203 scoped_ptr<OriginEnumerator> enumerator(CreateOriginEnumerator());
204 GURL origin;
205 while (!(origin = enumerator->Next()).is_empty()) {
206 if (host == net::GetHostOrSpecFromURL(origin) &&
207 enumerator->HasFileSystemType(type))
208 origins->insert(origin);
209 }
210 }
211
212 int64 SandboxContext::GetOriginUsageOnFileThread(
213 FileSystemContext* file_system_context,
214 const GURL& origin_url,
215 fileapi::FileSystemType type) {
216 // Don't use usage cache and return recalculated usage for sticky invalidated
217 // origins.
218 if (ContainsKey(sticky_dirty_origins_, std::make_pair(origin_url, type)))
219 return RecalculateUsage(file_system_context, origin_url, type);
220
221 base::FilePath base_path =
222 GetBaseDirectoryForOriginAndType(origin_url, type, false);
223 if (base_path.empty() || !base::DirectoryExists(base_path))
224 return 0;
225 base::FilePath usage_file_path =
226 base_path.Append(FileSystemUsageCache::kUsageFileName);
227
228 bool is_valid = usage_cache()->IsValid(usage_file_path);
229 uint32 dirty_status = 0;
230 bool dirty_status_available =
231 usage_cache()->GetDirty(usage_file_path, &dirty_status);
232 bool visited = !visited_origins_.insert(origin_url).second;
233 if (is_valid && (dirty_status == 0 || (dirty_status_available && visited))) {
234 // The usage cache is clean (dirty == 0) or the origin is already
235 // initialized and running. Read the cache file to get the usage.
236 int64 usage = 0;
237 return usage_cache()->GetUsage(usage_file_path, &usage) ? usage : -1;
238 }
239 // The usage cache has not been initialized or the cache is dirty.
240 // Get the directory size now and update the cache.
241 usage_cache()->Delete(usage_file_path);
242
243 int64 usage = RecalculateUsage(file_system_context, origin_url, type);
244
245 // This clears the dirty flag too.
246 usage_cache()->UpdateUsage(usage_file_path, usage);
247 return usage;
248 }
249
250 void SandboxContext::InvalidateUsageCache(
251 const GURL& origin,
252 fileapi::FileSystemType type) {
253 base::PlatformFileError error = base::PLATFORM_FILE_OK;
254 base::FilePath usage_file_path = GetUsageCachePathForOriginAndType(
255 sync_file_util(), origin, type, &error);
256 if (error != base::PLATFORM_FILE_OK)
257 return;
258 usage_cache()->IncrementDirty(usage_file_path);
259 }
260
261 void SandboxContext::StickyInvalidateUsageCache(
262 const GURL& origin,
263 fileapi::FileSystemType type) {
264 sticky_dirty_origins_.insert(std::make_pair(origin, type));
265 quota_observer()->SetUsageCacheEnabled(origin, type, false);
266 InvalidateUsageCache(origin, type);
267 }
268
269 base::FilePath SandboxContext::GetUsageCachePathForOriginAndType(
270 const GURL& origin_url,
271 FileSystemType type) {
272 base::PlatformFileError error;
273 base::FilePath path = GetUsageCachePathForOriginAndType(
274 sync_file_util(), origin_url, type, &error);
275 if (error != base::PLATFORM_FILE_OK)
276 return base::FilePath();
277 return path;
278 }
279
280 // static
281 base::FilePath SandboxContext::GetUsageCachePathForOriginAndType(
282 ObfuscatedFileUtil* sandbox_file_util,
283 const GURL& origin_url,
284 fileapi::FileSystemType type,
285 base::PlatformFileError* error_out) {
286 DCHECK(error_out);
287 *error_out = base::PLATFORM_FILE_OK;
288 base::FilePath base_path = sandbox_file_util->GetDirectoryForOriginAndType(
289 origin_url, type, false /* create */, error_out);
290 if (*error_out != base::PLATFORM_FILE_OK)
291 return base::FilePath();
292 return base_path.Append(FileSystemUsageCache::kUsageFileName);
293 }
294
295 int64 SandboxContext::RecalculateUsage(FileSystemContext* context,
296 const GURL& origin,
297 FileSystemType type) {
298 FileSystemOperationContext operation_context(context);
299 FileSystemURL url = context->CreateCrackedFileSystemURL(
300 origin, type, base::FilePath());
301 scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> enumerator(
302 sync_file_util()->CreateFileEnumerator(&operation_context, url, true));
303
304 base::FilePath file_path_each;
305 int64 usage = 0;
306
307 while (!(file_path_each = enumerator->Next()).empty()) {
308 usage += enumerator->Size();
309 usage += ObfuscatedFileUtil::ComputeFilePathCost(file_path_each);
310 }
311
312 return usage;
313 }
314
54 ObfuscatedFileUtil* SandboxContext::sync_file_util() { 315 ObfuscatedFileUtil* SandboxContext::sync_file_util() {
55 return static_cast<ObfuscatedFileUtil*>(file_util()->sync_file_util()); 316 return static_cast<ObfuscatedFileUtil*>(file_util()->sync_file_util());
56 } 317 }
57 318
58 } // namespace fileapi 319 } // namespace fileapi
OLDNEW
« no previous file with comments | « webkit/browser/fileapi/sandbox_context.h ('k') | webkit/browser/fileapi/sandbox_context_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698