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

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