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

Side by Side Diff: chrome/browser/file_system/file_system_dispatcher_host.cc

Issue 4054003: FileSystem code cleanup 2nd cut - introduce SandboxedFileSystemOperation (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebased Created 10 years, 1 month 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 (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 "chrome/browser/file_system/file_system_dispatcher_host.h" 5 #include "chrome/browser/file_system/file_system_dispatcher_host.h"
6 6
7 #include "base/file_path.h" 7 #include "base/file_path.h"
8 #include "base/thread.h" 8 #include "base/thread.h"
9 #include "base/time.h" 9 #include "base/time.h"
10 #include "chrome/browser/browser_process.h" 10 #include "chrome/browser/browser_process.h"
11 #include "chrome/browser/browser_thread.h" 11 #include "chrome/browser/browser_thread.h"
12 #include "chrome/browser/file_system/browser_file_system_callback_dispatcher.h" 12 #include "chrome/browser/file_system/browser_file_system_callback_dispatcher.h"
13 #include "chrome/browser/file_system/browser_file_system_context.h" 13 #include "chrome/browser/file_system/browser_file_system_context.h"
14 #include "chrome/browser/host_content_settings_map.h" 14 #include "chrome/browser/host_content_settings_map.h"
15 #include "chrome/browser/net/chrome_url_request_context.h" 15 #include "chrome/browser/net/chrome_url_request_context.h"
16 #include "chrome/browser/profile.h" 16 #include "chrome/browser/profile.h"
17 #include "chrome/browser/renderer_host/browser_render_process_host.h" 17 #include "chrome/browser/renderer_host/browser_render_process_host.h"
18 #include "chrome/common/net/url_request_context_getter.h" 18 #include "chrome/common/net/url_request_context_getter.h"
19 #include "chrome/common/render_messages.h" 19 #include "chrome/common/render_messages.h"
20 #include "chrome/common/render_messages_params.h" 20 #include "chrome/common/render_messages_params.h"
21 #include "googleurl/src/gurl.h" 21 #include "googleurl/src/gurl.h"
22 #include "net/url_request/url_request_context.h" 22 #include "net/url_request/url_request_context.h"
23 #include "webkit/fileapi/file_system_operation.h"
23 #include "webkit/fileapi/file_system_path_manager.h" 24 #include "webkit/fileapi/file_system_path_manager.h"
24 #include "webkit/fileapi/file_system_quota_manager.h" 25 #include "webkit/fileapi/file_system_quota_manager.h"
26 #include "webkit/fileapi/sandboxed_file_system_operation.h"
25 27
26 using fileapi::FileSystemQuotaManager; 28 using fileapi::FileSystemQuotaManager;
27 29 using fileapi::SandboxedFileSystemOperation;
28 class FileSystemDispatcherHost::OpenFileSystemTask {
29 public:
30 static void Start(
31 int request_id,
32 const GURL& origin_url,
33 fileapi::FileSystemType type,
34 bool create,
35 FileSystemDispatcherHost* dispatcher_host) {
36 // The task is self-destructed.
37 new OpenFileSystemTask(
38 request_id, origin_url, type, create, dispatcher_host);
39 }
40
41 private:
42 void DidGetRootPath(bool success, const FilePath& root_path,
43 const std::string& name) {
44 if (success)
45 dispatcher_host_->Send(
46 new ViewMsg_OpenFileSystemRequest_Complete(
47 request_id_, true, name, root_path));
48 else
49 dispatcher_host_->Send(
50 new ViewMsg_OpenFileSystemRequest_Complete(
51 request_id_, false, std::string(), FilePath()));
52 delete this;
53 }
54
55 OpenFileSystemTask(
56 int request_id,
57 const GURL& origin_url,
58 fileapi::FileSystemType type,
59 bool create,
60 FileSystemDispatcherHost* dispatcher_host)
61 : request_id_(request_id),
62 dispatcher_host_(dispatcher_host),
63 callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
64 dispatcher_host->context_->path_manager()->GetFileSystemRootPath(
65 origin_url, type, create,
66 callback_factory_.NewCallback(&OpenFileSystemTask::DidGetRootPath));
67 }
68
69 int request_id_;
70 std::string name_;
71 FilePath root_path_;
72 scoped_refptr<FileSystemDispatcherHost> dispatcher_host_;
73 base::ScopedCallbackFactory<OpenFileSystemTask> callback_factory_;
74 };
75 30
76 FileSystemDispatcherHost::FileSystemDispatcherHost( 31 FileSystemDispatcherHost::FileSystemDispatcherHost(
77 IPC::Message::Sender* sender, Profile* profile) 32 IPC::Message::Sender* sender, Profile* profile)
78 : message_sender_(sender), 33 : message_sender_(sender),
79 process_handle_(0), 34 process_handle_(0),
80 shutdown_(false), 35 shutdown_(false),
81 context_(profile->GetFileSystemContext()), 36 context_(profile->GetFileSystemContext()),
82 host_content_settings_map_(profile->GetHostContentSettingsMap()), 37 host_content_settings_map_(profile->GetHostContentSettingsMap()),
83 request_context_getter_(profile->GetRequestContext()) { 38 request_context_getter_(profile->GetRequestContext()) {
84 DCHECK(message_sender_); 39 DCHECK(message_sender_);
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
149 (content_setting == CONTENT_SETTING_BLOCK) || 104 (content_setting == CONTENT_SETTING_BLOCK) ||
150 (content_setting == CONTENT_SETTING_SESSION_ONLY)); 105 (content_setting == CONTENT_SETTING_SESSION_ONLY));
151 if (content_setting == CONTENT_SETTING_BLOCK) { 106 if (content_setting == CONTENT_SETTING_BLOCK) {
152 // TODO(kinuko): Need to notify the UI thread to indicate that 107 // TODO(kinuko): Need to notify the UI thread to indicate that
153 // there's a blocked content. 108 // there's a blocked content.
154 Send(new ViewMsg_OpenFileSystemRequest_Complete( 109 Send(new ViewMsg_OpenFileSystemRequest_Complete(
155 request_id, false, std::string(), FilePath())); 110 request_id, false, std::string(), FilePath()));
156 return; 111 return;
157 } 112 }
158 113
159 OpenFileSystemTask::Start(request_id, origin_url, type, create, this); 114 GetNewOperation(request_id)->OpenFileSystem(origin_url, type, create);
160 } 115 }
161 116
162 void FileSystemDispatcherHost::OnMove( 117 void FileSystemDispatcherHost::OnMove(
163 int request_id, const FilePath& src_path, const FilePath& dest_path) { 118 int request_id, const FilePath& src_path, const FilePath& dest_path) {
164 if (!VerifyFileSystemPathForRead(src_path, request_id) ||
165 !VerifyFileSystemPathForWrite(dest_path, request_id, true /* create */,
166 FileSystemQuotaManager::kUnknownSize))
167 return;
168
169 GetNewOperation(request_id)->Move(src_path, dest_path); 119 GetNewOperation(request_id)->Move(src_path, dest_path);
170 } 120 }
171 121
172 void FileSystemDispatcherHost::OnCopy( 122 void FileSystemDispatcherHost::OnCopy(
173 int request_id, const FilePath& src_path, const FilePath& dest_path) { 123 int request_id, const FilePath& src_path, const FilePath& dest_path) {
174 if (!VerifyFileSystemPathForRead(src_path, request_id) ||
175 !VerifyFileSystemPathForWrite(dest_path, request_id, true /* create */,
176 FileSystemQuotaManager::kUnknownSize))
177 return;
178
179 GetNewOperation(request_id)->Copy(src_path, dest_path); 124 GetNewOperation(request_id)->Copy(src_path, dest_path);
180 } 125 }
181 126
182 void FileSystemDispatcherHost::OnRemove( 127 void FileSystemDispatcherHost::OnRemove(
183 int request_id, const FilePath& path, bool recursive) { 128 int request_id, const FilePath& path, bool recursive) {
184 if (!VerifyFileSystemPathForWrite(path, request_id, false /* create */, 0))
185 return;
186 GetNewOperation(request_id)->Remove(path, recursive); 129 GetNewOperation(request_id)->Remove(path, recursive);
187 } 130 }
188 131
189 void FileSystemDispatcherHost::OnReadMetadata( 132 void FileSystemDispatcherHost::OnReadMetadata(
190 int request_id, const FilePath& path) { 133 int request_id, const FilePath& path) {
191 if (!VerifyFileSystemPathForRead(path, request_id))
192 return;
193 GetNewOperation(request_id)->GetMetadata(path); 134 GetNewOperation(request_id)->GetMetadata(path);
194 } 135 }
195 136
196 void FileSystemDispatcherHost::OnCreate( 137 void FileSystemDispatcherHost::OnCreate(
197 int request_id, const FilePath& path, bool exclusive, 138 int request_id, const FilePath& path, bool exclusive,
198 bool is_directory, bool recursive) { 139 bool is_directory, bool recursive) {
199 if (!VerifyFileSystemPathForWrite(path, request_id, true /* create */, 0))
200 return;
201 if (is_directory) 140 if (is_directory)
202 GetNewOperation(request_id)->CreateDirectory(path, exclusive, recursive); 141 GetNewOperation(request_id)->CreateDirectory(path, exclusive, recursive);
203 else 142 else
204 GetNewOperation(request_id)->CreateFile(path, exclusive); 143 GetNewOperation(request_id)->CreateFile(path, exclusive);
205 } 144 }
206 145
207 void FileSystemDispatcherHost::OnExists( 146 void FileSystemDispatcherHost::OnExists(
208 int request_id, const FilePath& path, bool is_directory) { 147 int request_id, const FilePath& path, bool is_directory) {
209 if (!VerifyFileSystemPathForRead(path, request_id))
210 return;
211 if (is_directory) 148 if (is_directory)
212 GetNewOperation(request_id)->DirectoryExists(path); 149 GetNewOperation(request_id)->DirectoryExists(path);
213 else 150 else
214 GetNewOperation(request_id)->FileExists(path); 151 GetNewOperation(request_id)->FileExists(path);
215 } 152 }
216 153
217 void FileSystemDispatcherHost::OnReadDirectory( 154 void FileSystemDispatcherHost::OnReadDirectory(
218 int request_id, const FilePath& path) { 155 int request_id, const FilePath& path) {
219 if (!VerifyFileSystemPathForRead(path, request_id))
220 return;
221 GetNewOperation(request_id)->ReadDirectory(path); 156 GetNewOperation(request_id)->ReadDirectory(path);
222 } 157 }
223 158
224 void FileSystemDispatcherHost::OnWrite( 159 void FileSystemDispatcherHost::OnWrite(
225 int request_id, 160 int request_id,
226 const FilePath& path, 161 const FilePath& path,
227 const GURL& blob_url, 162 const GURL& blob_url,
228 int64 offset) { 163 int64 offset) {
229 if (!VerifyFileSystemPathForWrite(path, request_id, true /* create */,
230 FileSystemQuotaManager::kUnknownSize))
231 return;
232 GetNewOperation(request_id)->Write( 164 GetNewOperation(request_id)->Write(
233 request_context_, path, blob_url, offset); 165 request_context_, path, blob_url, offset);
234 } 166 }
235 167
236 void FileSystemDispatcherHost::OnTruncate( 168 void FileSystemDispatcherHost::OnTruncate(
237 int request_id, 169 int request_id,
238 const FilePath& path, 170 const FilePath& path,
239 int64 length) { 171 int64 length) {
240 if (!VerifyFileSystemPathForWrite(path, request_id, false /* create */, 0))
241 return;
242 GetNewOperation(request_id)->Truncate(path, length); 172 GetNewOperation(request_id)->Truncate(path, length);
243 } 173 }
244 174
245 void FileSystemDispatcherHost::OnTouchFile( 175 void FileSystemDispatcherHost::OnTouchFile(
246 int request_id, 176 int request_id,
247 const FilePath& path, 177 const FilePath& path,
248 const base::Time& last_access_time, 178 const base::Time& last_access_time,
249 const base::Time& last_modified_time) { 179 const base::Time& last_modified_time) {
250 if (!VerifyFileSystemPathForWrite(path, request_id, true /* create */, 0))
251 return;
252 GetNewOperation(request_id)->TouchFile( 180 GetNewOperation(request_id)->TouchFile(
253 path, last_access_time, last_modified_time); 181 path, last_access_time, last_modified_time);
254 } 182 }
255 183
256 void FileSystemDispatcherHost::OnCancel( 184 void FileSystemDispatcherHost::OnCancel(
257 int request_id, 185 int request_id,
258 int request_id_to_cancel) { 186 int request_id_to_cancel) {
259 fileapi::FileSystemOperation* write = 187 SandboxedFileSystemOperation* write = operations_.Lookup(
260 operations_.Lookup(request_id_to_cancel); 188 request_id_to_cancel);
261 if (write) { 189 if (write) {
262 // The cancel will eventually send both the write failure and the cancel 190 // The cancel will eventually send both the write failure and the cancel
263 // success. 191 // success.
264 write->Cancel(GetNewOperation(request_id)); 192 write->Cancel(GetNewOperation(request_id));
265 } else { 193 } else {
266 // The write already finished; report that we failed to stop it. 194 // The write already finished; report that we failed to stop it.
267 Send(new ViewMsg_FileSystem_DidFail( 195 Send(new ViewMsg_FileSystem_DidFail(
268 request_id, base::PLATFORM_FILE_ERROR_INVALID_OPERATION)); 196 request_id, base::PLATFORM_FILE_ERROR_INVALID_OPERATION));
269 } 197 }
270 } 198 }
271 199
272 void FileSystemDispatcherHost::Send(IPC::Message* message) { 200 void FileSystemDispatcherHost::Send(IPC::Message* message) {
273 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 201 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
274 if (!shutdown_ && message_sender_) 202 if (!shutdown_ && message_sender_)
275 message_sender_->Send(message); 203 message_sender_->Send(message);
276 else 204 else
277 delete message; 205 delete message;
278 } 206 }
279 207
280 bool FileSystemDispatcherHost::VerifyFileSystemPathForRead( 208 SandboxedFileSystemOperation* FileSystemDispatcherHost::GetNewOperation(
281 const FilePath& path, int request_id) {
282 // We may want do more checks, but for now it just checks if the given
283 // |path| is under the valid FileSystem root path for this host context.
284 if (!context_->path_manager()->CrackFileSystemPath(
285 path, NULL, NULL, NULL)) {
286 Send(new ViewMsg_FileSystem_DidFail(
287 request_id, base::PLATFORM_FILE_ERROR_SECURITY));
288 return false;
289 }
290 return true;
291 }
292
293 bool FileSystemDispatcherHost::VerifyFileSystemPathForWrite(
294 const FilePath& path, int request_id, bool create, int64 growth) {
295 GURL origin_url;
296 FilePath virtual_path;
297 if (!context_->path_manager()->CrackFileSystemPath(
298 path, &origin_url, NULL, &virtual_path)) {
299 Send(new ViewMsg_FileSystem_DidFail(
300 request_id, base::PLATFORM_FILE_ERROR_SECURITY));
301 return false;
302 }
303 // Any write access is disallowed on the root path.
304 if (virtual_path.value().length() == 0 ||
305 virtual_path.DirName().value() == virtual_path.value()) {
306 Send(new ViewMsg_FileSystem_DidFail(
307 request_id, base::PLATFORM_FILE_ERROR_SECURITY));
308 return false;
309 }
310 if (create && context_->path_manager()->IsRestrictedFileName(
311 path.BaseName())) {
312 Send(new ViewMsg_FileSystem_DidFail(
313 request_id, base::PLATFORM_FILE_ERROR_SECURITY));
314 return false;
315 }
316 // TODO(kinuko): For operations with kUnknownSize we'll eventually
317 // need to resolve what amount of size it's going to write.
318 if (!context_->CheckOriginQuota(origin_url, growth)) {
319 Send(new ViewMsg_FileSystem_DidFail(
320 request_id, base::PLATFORM_FILE_ERROR_NO_SPACE));
321 return false;
322 }
323 return true;
324 }
325
326 bool FileSystemDispatcherHost::CheckIfFilePathIsSafe(
327 const FilePath& path, int request_id) {
328 if (context_->path_manager()->IsRestrictedFileName(path.BaseName())) {
329 Send(new ViewMsg_FileSystem_DidFail(
330 request_id, base::PLATFORM_FILE_ERROR_SECURITY));
331 return false;
332 }
333 return true;
334 }
335
336 fileapi::FileSystemOperation* FileSystemDispatcherHost::GetNewOperation(
337 int request_id) { 209 int request_id) {
338 BrowserFileSystemCallbackDispatcher* dispatcher = 210 BrowserFileSystemCallbackDispatcher* dispatcher =
339 new BrowserFileSystemCallbackDispatcher(this, request_id); 211 new BrowserFileSystemCallbackDispatcher(this, request_id);
340 fileapi::FileSystemOperation* operation = new fileapi::FileSystemOperation( 212 SandboxedFileSystemOperation* operation = new SandboxedFileSystemOperation(
341 dispatcher, 213 dispatcher,
342 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)); 214 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE),
215 context_.get());
343 operations_.AddWithID(operation, request_id); 216 operations_.AddWithID(operation, request_id);
344 return operation; 217 return operation;
345 } 218 }
346 219
347 void FileSystemDispatcherHost::RemoveCompletedOperation(int request_id) { 220 void FileSystemDispatcherHost::RemoveCompletedOperation(int request_id) {
348 DCHECK(operations_.Lookup(request_id)); 221 DCHECK(operations_.Lookup(request_id));
349 operations_.Remove(request_id); 222 operations_.Remove(request_id);
350 } 223 }
OLDNEW
« no previous file with comments | « chrome/browser/file_system/file_system_dispatcher_host.h ('k') | webkit/fileapi/file_system_operation.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698