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

Side by Side Diff: content/browser/fileapi/fileapi_message_filter.cc

Issue 11410019: ********** Chromium Blob hacking (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 8 years 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) 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 "content/browser/fileapi/fileapi_message_filter.h" 5 #include "content/browser/fileapi/fileapi_message_filter.h"
6 6
7 #include <string> 7 #include <string>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/file_path.h" 11 #include "base/file_path.h"
12 #include "base/memory/scoped_ptr.h" 12 #include "base/memory/scoped_ptr.h"
13 #include "base/platform_file.h" 13 #include "base/platform_file.h"
14 #include "base/threading/thread.h" 14 #include "base/threading/thread.h"
15 #include "base/time.h" 15 #include "base/time.h"
16 #include "content/browser/child_process_security_policy_impl.h" 16 #include "content/browser/child_process_security_policy_impl.h"
17 #include "content/browser/fileapi/chrome_blob_storage_context.h" 17 #include "content/browser/fileapi/chrome_blob_storage_context.h"
18 #include "content/common/fileapi/file_system_messages.h" 18 #include "content/common/fileapi/file_system_messages.h"
19 #include "content/common/fileapi/webblob_messages.h" 19 #include "content/common/fileapi/webblob_messages.h"
20 #include "content/public/browser/user_metrics.h" 20 #include "content/public/browser/user_metrics.h"
21 #include "googleurl/src/gurl.h" 21 #include "googleurl/src/gurl.h"
22 #include "ipc/ipc_platform_file.h" 22 #include "ipc/ipc_platform_file.h"
23 #include "net/base/mime_util.h" 23 #include "net/base/mime_util.h"
24 #include "net/url_request/url_request_context.h" 24 #include "net/url_request/url_request_context.h"
25 #include "net/url_request/url_request_context_getter.h" 25 #include "net/url_request/url_request_context_getter.h"
26 #include "webkit/blob/blob_data.h" 26 #include "webkit/blob/blob_data.h"
27 #include "webkit/blob/blob_storage_controller.h" 27 #include "webkit/blob/blob_storage_context.h"
28 #include "webkit/blob/shareable_file_reference.h" 28 #include "webkit/blob/shareable_file_reference.h"
29 #include "webkit/fileapi/file_observers.h" 29 #include "webkit/fileapi/file_observers.h"
30 #include "webkit/fileapi/file_system_context.h" 30 #include "webkit/fileapi/file_system_context.h"
31 #include "webkit/fileapi/file_system_types.h" 31 #include "webkit/fileapi/file_system_types.h"
32 #include "webkit/fileapi/file_system_util.h" 32 #include "webkit/fileapi/file_system_util.h"
33 #include "webkit/fileapi/isolated_context.h" 33 #include "webkit/fileapi/isolated_context.h"
34 #include "webkit/fileapi/local_file_system_operation.h" 34 #include "webkit/fileapi/local_file_system_operation.h"
35 #include "webkit/fileapi/sandbox_mount_point_provider.h" 35 #include "webkit/fileapi/sandbox_mount_point_provider.h"
36 36
37 using fileapi::FileSystemFileUtil; 37 using fileapi::FileSystemFileUtil;
38 using fileapi::FileSystemMountPointProvider; 38 using fileapi::FileSystemMountPointProvider;
39 using fileapi::FileSystemOperation; 39 using fileapi::FileSystemOperation;
40 using fileapi::FileSystemURL; 40 using fileapi::FileSystemURL;
41 using fileapi::FileUpdateObserver; 41 using fileapi::FileUpdateObserver;
42 using fileapi::LocalFileSystemOperation; 42 using fileapi::LocalFileSystemOperation;
43 using fileapi::UpdateObserverList; 43 using fileapi::UpdateObserverList;
44 using webkit_blob::BlobData; 44 using webkit_blob::BlobData;
45 using webkit_blob::BlobStorageController; 45 using webkit_blob::BlobStorageContext;
46 using webkit_blob::BlobStorageConsumer;
46 47
47 namespace content { 48 namespace content {
48 namespace { 49 namespace {
49 50
50 const int kReadFilePermissions = base::PLATFORM_FILE_OPEN | 51 const int kReadFilePermissions = base::PLATFORM_FILE_OPEN |
51 base::PLATFORM_FILE_READ | 52 base::PLATFORM_FILE_READ |
52 base::PLATFORM_FILE_EXCLUSIVE_READ | 53 base::PLATFORM_FILE_EXCLUSIVE_READ |
53 base::PLATFORM_FILE_ASYNC; 54 base::PLATFORM_FILE_ASYNC;
54 55
55 const int kWriteFilePermissions = base::PLATFORM_FILE_OPEN | 56 const int kWriteFilePermissions = base::PLATFORM_FILE_OPEN |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 108
108 void FileAPIMessageFilter::OnChannelConnected(int32 peer_pid) { 109 void FileAPIMessageFilter::OnChannelConnected(int32 peer_pid) {
109 BrowserMessageFilter::OnChannelConnected(peer_pid); 110 BrowserMessageFilter::OnChannelConnected(peer_pid);
110 111
111 if (request_context_getter_.get()) { 112 if (request_context_getter_.get()) {
112 DCHECK(!request_context_); 113 DCHECK(!request_context_);
113 request_context_ = request_context_getter_->GetURLRequestContext(); 114 request_context_ = request_context_getter_->GetURLRequestContext();
114 request_context_getter_ = NULL; 115 request_context_getter_ = NULL;
115 DCHECK(request_context_); 116 DCHECK(request_context_);
116 } 117 }
118
119 blob_storage_consumer_.reset(
120 new webkit_blob::BlobStorageConsumer(blob_storage_context_->context()));
117 } 121 }
118 122
119 void FileAPIMessageFilter::OnChannelClosing() { 123 void FileAPIMessageFilter::OnChannelClosing() {
120 BrowserMessageFilter::OnChannelClosing(); 124 BrowserMessageFilter::OnChannelClosing();
121 125
122 // Unregister all the blob URLs that are previously registered in this 126 blob_storage_consumer_.reset();
123 // process. 127 in_transit_snapshot_files_.clear();
124 for (base::hash_set<std::string>::const_iterator iter = blob_urls_.begin();
125 iter != blob_urls_.end(); ++iter) {
126 blob_storage_context_->controller()->RemoveBlob(GURL(*iter));
127 }
128 128
129 // Close all files that are previously OpenFile()'ed in this process. 129 // Close all files that are previously OpenFile()'ed in this process.
130 if (!open_filesystem_urls_.empty()) { 130 if (!open_filesystem_urls_.empty()) {
131 DLOG(INFO) 131 DLOG(INFO)
132 << "File API: Renderer process shut down before NotifyCloseFile" 132 << "File API: Renderer process shut down before NotifyCloseFile"
133 << " for " << open_filesystem_urls_.size() << " files opened in PPAPI"; 133 << " for " << open_filesystem_urls_.size() << " files opened in PPAPI";
134 } 134 }
135 for (std::multiset<GURL>::const_iterator iter = 135 for (std::multiset<GURL>::const_iterator iter =
136 open_filesystem_urls_.begin(); 136 open_filesystem_urls_.begin();
137 iter != open_filesystem_urls_.end(); ++iter) { 137 iter != open_filesystem_urls_.end(); ++iter) {
(...skipping 27 matching lines...) Expand all
165 IPC_MESSAGE_HANDLER(FileSystemHostMsg_Exists, OnExists) 165 IPC_MESSAGE_HANDLER(FileSystemHostMsg_Exists, OnExists)
166 IPC_MESSAGE_HANDLER(FileSystemHostMsg_ReadDirectory, OnReadDirectory) 166 IPC_MESSAGE_HANDLER(FileSystemHostMsg_ReadDirectory, OnReadDirectory)
167 IPC_MESSAGE_HANDLER(FileSystemHostMsg_Write, OnWrite) 167 IPC_MESSAGE_HANDLER(FileSystemHostMsg_Write, OnWrite)
168 IPC_MESSAGE_HANDLER(FileSystemHostMsg_Truncate, OnTruncate) 168 IPC_MESSAGE_HANDLER(FileSystemHostMsg_Truncate, OnTruncate)
169 IPC_MESSAGE_HANDLER(FileSystemHostMsg_TouchFile, OnTouchFile) 169 IPC_MESSAGE_HANDLER(FileSystemHostMsg_TouchFile, OnTouchFile)
170 IPC_MESSAGE_HANDLER(FileSystemHostMsg_CancelWrite, OnCancel) 170 IPC_MESSAGE_HANDLER(FileSystemHostMsg_CancelWrite, OnCancel)
171 IPC_MESSAGE_HANDLER(FileSystemHostMsg_OpenFile, OnOpenFile) 171 IPC_MESSAGE_HANDLER(FileSystemHostMsg_OpenFile, OnOpenFile)
172 IPC_MESSAGE_HANDLER(FileSystemHostMsg_NotifyCloseFile, OnNotifyCloseFile) 172 IPC_MESSAGE_HANDLER(FileSystemHostMsg_NotifyCloseFile, OnNotifyCloseFile)
173 IPC_MESSAGE_HANDLER(FileSystemHostMsg_CreateSnapshotFile, 173 IPC_MESSAGE_HANDLER(FileSystemHostMsg_CreateSnapshotFile,
174 OnCreateSnapshotFile) 174 OnCreateSnapshotFile)
175 IPC_MESSAGE_HANDLER(FileSystemHostMsg_DidReceiveSnapshotFile,
176 OnDidReceiveSnapshotFile)
175 IPC_MESSAGE_HANDLER(FileSystemHostMsg_WillUpdate, OnWillUpdate) 177 IPC_MESSAGE_HANDLER(FileSystemHostMsg_WillUpdate, OnWillUpdate)
176 IPC_MESSAGE_HANDLER(FileSystemHostMsg_DidUpdate, OnDidUpdate) 178 IPC_MESSAGE_HANDLER(FileSystemHostMsg_DidUpdate, OnDidUpdate)
177 IPC_MESSAGE_HANDLER(FileSystemHostMsg_SyncGetPlatformPath, 179 IPC_MESSAGE_HANDLER(FileSystemHostMsg_SyncGetPlatformPath,
178 OnSyncGetPlatformPath) 180 OnSyncGetPlatformPath)
179 IPC_MESSAGE_HANDLER(BlobHostMsg_StartBuildingBlob, OnStartBuildingBlob) 181 IPC_MESSAGE_HANDLER(BlobHostMsg_StartBuildingBlob2, OnStartBuildingBlob2)
180 IPC_MESSAGE_HANDLER(BlobHostMsg_AppendBlobDataItem, OnAppendBlobDataItem) 182 IPC_MESSAGE_HANDLER(BlobHostMsg_AppendBlobDataItem2, OnAppendBlobDataItem2)
181 IPC_MESSAGE_HANDLER(BlobHostMsg_SyncAppendSharedMemory, 183 IPC_MESSAGE_HANDLER(BlobHostMsg_AppendSharedMemory2,
182 OnAppendSharedMemory) 184 OnAppendSharedMemory2)
183 IPC_MESSAGE_HANDLER(BlobHostMsg_FinishBuildingBlob, OnFinishBuildingBlob) 185 IPC_MESSAGE_HANDLER(BlobHostMsg_FinishBuildingBlob2, OnFinishBuildingBlob2)
184 IPC_MESSAGE_HANDLER(BlobHostMsg_CloneBlob, OnCloneBlob) 186 IPC_MESSAGE_HANDLER(BlobHostMsg_IncrementBlobRefCount,
185 IPC_MESSAGE_HANDLER(BlobHostMsg_RemoveBlob, OnRemoveBlob) 187 OnIncrementBlobRefCount)
188 IPC_MESSAGE_HANDLER(BlobHostMsg_DecrementBlobRefCount,
189 OnDecrementBlobRefCount)
190 IPC_MESSAGE_HANDLER(BlobHostMsg_RegisterPublicBlobURL,
191 OnRegisterPublicBlobURL)
192 IPC_MESSAGE_HANDLER(BlobHostMsg_RevokePublicBlobURL, OnRevokePublicBlobURL)
186 IPC_MESSAGE_UNHANDLED(handled = false) 193 IPC_MESSAGE_UNHANDLED(handled = false)
187 IPC_END_MESSAGE_MAP_EX() 194 IPC_END_MESSAGE_MAP_EX()
188 return handled; 195 return handled;
189 } 196 }
190 197
191 void FileAPIMessageFilter::UnregisterOperation(int request_id) { 198 void FileAPIMessageFilter::UnregisterOperation(int request_id) {
192 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 199 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
193 DCHECK(operations_.Lookup(request_id)); 200 DCHECK(operations_.Lookup(request_id));
194 operations_.Remove(request_id); 201 operations_.Remove(request_id);
195 } 202 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 base::PlatformFileError error; 236 base::PlatformFileError error;
230 FileSystemURL src_url(src_path); 237 FileSystemURL src_url(src_path);
231 FileSystemURL dest_url(dest_path); 238 FileSystemURL dest_url(dest_path);
232 const int src_permissions = kReadFilePermissions | kWriteFilePermissions; 239 const int src_permissions = kReadFilePermissions | kWriteFilePermissions;
233 if (!HasPermissionsForFile(src_url, src_permissions, &error) || 240 if (!HasPermissionsForFile(src_url, src_permissions, &error) ||
234 !HasPermissionsForFile(dest_url, kCreateFilePermissions, &error)) { 241 !HasPermissionsForFile(dest_url, kCreateFilePermissions, &error)) {
235 Send(new FileSystemMsg_DidFail(request_id, error)); 242 Send(new FileSystemMsg_DidFail(request_id, error));
236 return; 243 return;
237 } 244 }
238 245
239 FileSystemOperation* operation = GetNewOperation(dest_url, request_id); 246 FileSystemOperation* operation = GetNewOperation(src_url, request_id);
kinuko 2013/01/07 08:52:01 note: in the current code this needs to take dest_
michaeln 2013/01/25 21:19:44 Done.
240 if (!operation) 247 if (!operation)
241 return; 248 return;
242 operation->Move( 249 operation->Move(
243 src_url, dest_url, 250 src_url, dest_url,
244 base::Bind(&FileAPIMessageFilter::DidFinish, this, request_id)); 251 base::Bind(&FileAPIMessageFilter::DidFinish, this, request_id));
245 } 252 }
246 253
247 void FileAPIMessageFilter::OnCopy( 254 void FileAPIMessageFilter::OnCopy(
248 int request_id, const GURL& src_path, const GURL& dest_path) { 255 int request_id, const GURL& src_path, const GURL& dest_path) {
249 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 256 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
250 base::PlatformFileError error; 257 base::PlatformFileError error;
251 FileSystemURL src_url(src_path); 258 FileSystemURL src_url(src_path);
252 FileSystemURL dest_url(dest_path); 259 FileSystemURL dest_url(dest_path);
253 if (!HasPermissionsForFile(src_url, kReadFilePermissions, &error) || 260 if (!HasPermissionsForFile(src_url, kReadFilePermissions, &error) ||
254 !HasPermissionsForFile(dest_url, kCreateFilePermissions, &error)) { 261 !HasPermissionsForFile(dest_url, kCreateFilePermissions, &error)) {
255 Send(new FileSystemMsg_DidFail(request_id, error)); 262 Send(new FileSystemMsg_DidFail(request_id, error));
256 return; 263 return;
257 } 264 }
258 265
259 FileSystemOperation* operation = GetNewOperation(dest_url, request_id); 266 FileSystemOperation* operation = GetNewOperation(src_url, request_id);
kinuko 2013/01/07 08:52:01 ditto
michaeln 2013/01/25 21:19:44 Done.
260 if (!operation) 267 if (!operation)
261 return; 268 return;
262 operation->Copy( 269 operation->Copy(
263 src_url, dest_url, 270 src_url, dest_url,
264 base::Bind(&FileAPIMessageFilter::DidFinish, this, request_id)); 271 base::Bind(&FileAPIMessageFilter::DidFinish, this, request_id));
265 } 272 }
266 273
267 void FileAPIMessageFilter::OnRemove( 274 void FileAPIMessageFilter::OnRemove(
268 int request_id, const GURL& path, bool recursive) { 275 int request_id, const GURL& path, bool recursive) {
269 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 276 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 if (!operation) 370 if (!operation)
364 return; 371 return;
365 operation->ReadDirectory( 372 operation->ReadDirectory(
366 url, base::Bind(&FileAPIMessageFilter::DidReadDirectory, 373 url, base::Bind(&FileAPIMessageFilter::DidReadDirectory,
367 this, request_id)); 374 this, request_id));
368 } 375 }
369 376
370 void FileAPIMessageFilter::OnWrite( 377 void FileAPIMessageFilter::OnWrite(
371 int request_id, 378 int request_id,
372 const GURL& path, 379 const GURL& path,
373 const GURL& blob_url, 380 const std::string& blob_uuid,
374 int64 offset) { 381 int64 offset) {
375 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 382 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
376 if (!request_context_) { 383 if (!request_context_) {
377 // We can't write w/o a request context, trying to do so will crash. 384 // We can't write w/o a request context, trying to do so will crash.
378 NOTREACHED(); 385 NOTREACHED();
379 return; 386 return;
380 } 387 }
381 388
382 FileSystemURL url(path); 389 FileSystemURL url(path);
383 base::PlatformFileError error; 390 base::PlatformFileError error;
384 if (!HasPermissionsForFile(url, kWriteFilePermissions, &error)) { 391 if (!HasPermissionsForFile(url, kWriteFilePermissions, &error)) {
385 Send(new FileSystemMsg_DidFail(request_id, error)); 392 Send(new FileSystemMsg_DidFail(request_id, error));
386 return; 393 return;
387 } 394 }
388 395
389 FileSystemOperation* operation = GetNewOperation(url, request_id); 396 FileSystemOperation* operation = GetNewOperation(url, request_id);
390 if (!operation) 397 if (!operation)
391 return; 398 return;
399 scoped_ptr<webkit_blob::BlobDataHandle> blob =
400 blob_storage_context_->context()->GetBlobDataFromUUID(blob_uuid);
392 operation->Write( 401 operation->Write(
393 request_context_, url, blob_url, offset, 402 request_context_, url, blob.Pass(), offset,
394 base::Bind(&FileAPIMessageFilter::DidWrite, this, request_id)); 403 base::Bind(&FileAPIMessageFilter::DidWrite, this, request_id));
395 } 404 }
396 405
397 void FileAPIMessageFilter::OnTruncate( 406 void FileAPIMessageFilter::OnTruncate(
398 int request_id, 407 int request_id,
399 const GURL& path, 408 const GURL& path,
400 int64 length) { 409 int64 length) {
401 base::PlatformFileError error; 410 base::PlatformFileError error;
402 FileSystemURL url(path); 411 FileSystemURL url(path);
403 if (!HasPermissionsForFile(url, kWriteFilePermissions, &error)) { 412 if (!HasPermissionsForFile(url, kWriteFilePermissions, &error)) {
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
536 // (e.g. TEMPORARY or PERSISTENT). 545 // (e.g. TEMPORARY or PERSISTENT).
537 // TODO(kinuko): this hack should go away once appropriate upload-stream 546 // TODO(kinuko): this hack should go away once appropriate upload-stream
538 // handling based on element types is supported. 547 // handling based on element types is supported.
539 LocalFileSystemOperation* operation = 548 LocalFileSystemOperation* operation =
540 context_->CreateFileSystemOperation( 549 context_->CreateFileSystemOperation(
541 url, NULL)->AsLocalFileSystemOperation(); 550 url, NULL)->AsLocalFileSystemOperation();
542 DCHECK(operation); 551 DCHECK(operation);
543 if (!operation) 552 if (!operation)
544 return; 553 return;
545 554
546 operation->SyncGetPlatformPath(url, platform_path); 555 operation->SyncGetPlatformPath(url, platform_path);
kinuko 2013/01/07 08:52:01 nit: indent is off
michaeln 2013/01/25 21:19:44 Done.
547 556
548 // The path is to be attached to URLLoader so we grant read permission 557 // The path is to be attached to URLLoader so we grant read permission
549 // for the file. (We first need to check if it can already be read not to 558 // for the file. (We first need to check if it can already be read not to
550 // overwrite existing permissions) 559 // overwrite existing permissions)
551 if (!ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile( 560 if (!ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
552 process_id_, *platform_path)) { 561 process_id_, *platform_path)) {
553 ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadFile( 562 ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadFile(
554 process_id_, *platform_path); 563 process_id_, *platform_path);
555 } 564 }
556 } 565 }
557 566
558 void FileAPIMessageFilter::OnCreateSnapshotFile( 567 void FileAPIMessageFilter::OnCreateSnapshotFile(
559 int request_id, const GURL& blob_url, const GURL& path) { 568 int request_id, const GURL& path) {
560 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 569 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
561 FileSystemURL url(path); 570 FileSystemURL url(path);
562 base::Callback<void(const FilePath&)> register_file_callback =
563 base::Bind(&FileAPIMessageFilter::RegisterFileAsBlob,
564 this, blob_url, url);
565 571
566 // Make sure if this file can be read by the renderer as this is 572 // Make sure if this file can be read by the renderer as this is
567 // called when the renderer is about to create a new File object 573 // called when the renderer is about to create a new File object
568 // (for reading the file). 574 // (for reading the file).
569 base::PlatformFileError error; 575 base::PlatformFileError error;
570 if (!HasPermissionsForFile(url, kReadFilePermissions, &error)) { 576 if (!HasPermissionsForFile(url, kReadFilePermissions, &error)) {
571 Send(new FileSystemMsg_DidFail(request_id, error)); 577 Send(new FileSystemMsg_DidFail(request_id, error));
572 return; 578 return;
573 } 579 }
574 580
575 FileSystemOperation* operation = GetNewOperation(url, request_id); 581 FileSystemOperation* operation = GetNewOperation(url, request_id);
576 if (!operation) 582 if (!operation)
577 return; 583 return;
578 operation->CreateSnapshotFile( 584 operation->CreateSnapshotFile(
579 url, 585 url,
580 base::Bind(&FileAPIMessageFilter::DidCreateSnapshot, 586 base::Bind(&FileAPIMessageFilter::DidCreateSnapshot,
581 this, request_id, register_file_callback)); 587 this, url, request_id));
582 } 588 }
583 589
584 void FileAPIMessageFilter::OnStartBuildingBlob(const GURL& url) { 590 void FileAPIMessageFilter::OnDidReceiveSnapshotFile(int request_id) {
585 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 591 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
586 blob_storage_context_->controller()->StartBuildingBlob(url); 592 in_transit_snapshot_files_.erase(request_id);
587 blob_urls_.insert(url.spec());
588 } 593 }
589 594
590 void FileAPIMessageFilter::OnAppendBlobDataItem( 595 void FileAPIMessageFilter::OnStartBuildingBlob2(const std::string& uuid) {
591 const GURL& url, const BlobData::Item& item) { 596 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
597 blob_storage_consumer_->StartBuildingBlob(uuid);
598 }
599
600 void FileAPIMessageFilter::OnAppendBlobDataItem2(
601 const std::string& uuid, const webkit_blob::BlobData::Item& item) {
592 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 602 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
593 // TODO(kinuko): We must check permission in TYPE_FILE_FILESYSTEM cases too. 603 // TODO(kinuko): We must check permission in TYPE_FILE_FILESYSTEM cases too.
594 // http://crbug.com/141827 604 // http://crbug.com/141827
595 if (item.type() == BlobData::Item::TYPE_FILE && 605 if (item.type() == BlobData::Item::TYPE_FILE &&
596 !ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile( 606 !ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
597 process_id_, item.path())) { 607 process_id_, item.path())) {
598 OnRemoveBlob(url); 608 blob_storage_consumer_->CancelBuildingBlob(uuid);
599 return; 609 return;
600 } 610 }
601 if (item.length() == 0) { 611 if (item.length() == 0) {
602 BadMessageReceived(); 612 BadMessageReceived();
603 return; 613 return;
604 } 614 }
605 blob_storage_context_->controller()->AppendBlobDataItem(url, item); 615 blob_storage_consumer_->AppendBlobDataItem(uuid, item);
606 } 616 }
607 617
608 void FileAPIMessageFilter::OnAppendSharedMemory( 618 void FileAPIMessageFilter::OnAppendSharedMemory2(
609 const GURL& url, base::SharedMemoryHandle handle, size_t buffer_size) { 619 const std::string& uuid,
620 base::SharedMemoryHandle handle,
621 size_t buffer_size) {
610 DCHECK(base::SharedMemory::IsHandleValid(handle)); 622 DCHECK(base::SharedMemory::IsHandleValid(handle));
611 if (!buffer_size) { 623 if (!buffer_size) {
612 BadMessageReceived(); 624 BadMessageReceived();
613 return; 625 return;
614 } 626 }
615 #if defined(OS_WIN) 627 #if defined(OS_WIN)
616 base::SharedMemory shared_memory(handle, true, peer_handle()); 628 base::SharedMemory shared_memory(handle, true, peer_handle());
617 #else 629 #else
618 base::SharedMemory shared_memory(handle, true); 630 base::SharedMemory shared_memory(handle, true);
619 #endif 631 #endif
620 if (!shared_memory.Map(buffer_size)) { 632 if (!shared_memory.Map(buffer_size)) {
621 OnRemoveBlob(url); 633 blob_storage_consumer_->CancelBuildingBlob(uuid);
622 return; 634 return;
623 } 635 }
624 636
625 BlobData::Item item; 637 BlobData::Item item;
626 item.SetToSharedBytes(static_cast<char*>(shared_memory.memory()), 638 item.SetToSharedBytes(static_cast<char*>(shared_memory.memory()),
627 buffer_size); 639 buffer_size);
628 blob_storage_context_->controller()->AppendBlobDataItem(url, item); 640 blob_storage_consumer_->AppendBlobDataItem(uuid, item);
629 } 641 }
630 642
631 void FileAPIMessageFilter::OnFinishBuildingBlob( 643 void FileAPIMessageFilter::OnFinishBuildingBlob2(const std::string& uuid,
632 const GURL& url, const std::string& content_type) { 644 const std::string& content_type) {
633 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 645 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
634 blob_storage_context_->controller()->FinishBuildingBlob(url, content_type); 646 blob_storage_consumer_->FinishBuildingBlob(uuid, content_type);
635 } 647 }
636 648
637 void FileAPIMessageFilter::OnCloneBlob( 649 void FileAPIMessageFilter::OnIncrementBlobRefCount(const std::string& uuid) {
638 const GURL& url, const GURL& src_url) {
639 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 650 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
640 blob_storage_context_->controller()->CloneBlob(url, src_url); 651 blob_storage_consumer_->IncrementBlobRefCount(uuid);
641 blob_urls_.insert(url.spec());
642 } 652 }
643 653
644 void FileAPIMessageFilter::OnRemoveBlob(const GURL& url) { 654 void FileAPIMessageFilter::OnDecrementBlobRefCount(const std::string& uuid) {
645 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 655 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
646 blob_storage_context_->controller()->RemoveBlob(url); 656 blob_storage_consumer_->DecrementBlobRefCount(uuid);
647 blob_urls_.erase(url.spec()); 657 }
658
659 void FileAPIMessageFilter::OnRegisterPublicBlobURL(
660 const GURL& public_url, const std::string& uuid) {
661 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
662 blob_storage_consumer_->RegisterPublicBlobURL(public_url, uuid);
663 }
664
665 void FileAPIMessageFilter::OnRevokePublicBlobURL(const GURL& public_url) {
666 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
667 blob_storage_consumer_->RevokePublicBlobURL(public_url);
648 } 668 }
649 669
650 void FileAPIMessageFilter::DidFinish(int request_id, 670 void FileAPIMessageFilter::DidFinish(int request_id,
651 base::PlatformFileError result) { 671 base::PlatformFileError result) {
652 if (result == base::PLATFORM_FILE_OK) 672 if (result == base::PLATFORM_FILE_OK)
653 Send(new FileSystemMsg_DidSucceed(request_id)); 673 Send(new FileSystemMsg_DidSucceed(request_id));
654 else 674 else
655 Send(new FileSystemMsg_DidFail(request_id, result)); 675 Send(new FileSystemMsg_DidFail(request_id, result));
656 UnregisterOperation(request_id); 676 UnregisterOperation(request_id);
657 } 677 }
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
741 base::PlatformFileError result) { 761 base::PlatformFileError result) {
742 if (result == base::PLATFORM_FILE_OK) 762 if (result == base::PLATFORM_FILE_OK)
743 Send(new FileSystemMsg_DidSucceed(request_id)); 763 Send(new FileSystemMsg_DidSucceed(request_id));
744 else 764 else
745 Send(new FileSystemMsg_DidFail(request_id, result)); 765 Send(new FileSystemMsg_DidFail(request_id, result));
746 // For DeleteFileSystem we do not create a new operation, 766 // For DeleteFileSystem we do not create a new operation,
747 // so no unregister here. 767 // so no unregister here.
748 } 768 }
749 769
750 void FileAPIMessageFilter::DidCreateSnapshot( 770 void FileAPIMessageFilter::DidCreateSnapshot(
771 const FileSystemURL& url,
751 int request_id, 772 int request_id,
752 const base::Callback<void(const FilePath&)>& register_file_callback,
753 base::PlatformFileError result, 773 base::PlatformFileError result,
754 const base::PlatformFileInfo& info, 774 const base::PlatformFileInfo& info,
755 const FilePath& platform_path, 775 const FilePath& platform_path,
756 const scoped_refptr<webkit_blob::ShareableFileReference>& unused) { 776 const scoped_refptr<webkit_blob::ShareableFileReference>& snaphot_file) {
757 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 777 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
758 if (result != base::PLATFORM_FILE_OK) { 778 if (result != base::PLATFORM_FILE_OK) {
759 Send(new FileSystemMsg_DidFail(request_id, result)); 779 Send(new FileSystemMsg_DidFail(request_id, result));
760 return; 780 return;
761 } 781 }
762 782
763 // Register the created file to the blob registry by calling
764 // RegisterFileAsBlob.
765 // Blob storage automatically finds and refs the file_ref, so we don't
766 // need to do anything for the returned file reference (|unused|) here.
767 register_file_callback.Run(platform_path);
768
769 // Return the file info and platform_path.
770 Send(new FileSystemMsg_DidReadMetadata(request_id, info, platform_path));
771 }
772
773 void FileAPIMessageFilter::RegisterFileAsBlob(const GURL& blob_url,
774 const FileSystemURL& url,
775 const FilePath& platform_path) {
776 // Use the virtual path's extension to determine MIME type.
777 FilePath::StringType extension = url.path().Extension();
778 if (!extension.empty())
779 extension = extension.substr(1); // Strip leading ".".
780
781 scoped_refptr<webkit_blob::ShareableFileReference> shareable_file =
782 webkit_blob::ShareableFileReference::Get(platform_path);
783 if (!ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile( 783 if (!ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
784 process_id_, platform_path)) { 784 process_id_, platform_path)) {
785 // If the underlying file system implementation is returning a new 785 // If the underlying file system implementation is returning a new
786 // (likely temporary) snapshot file or the file is for sandboxed 786 // (likely temporary) snapshot file or the file is for sandboxed
787 // filesystems it's ok to grant permission here. 787 // filesystems it's ok to grant permission here.
788 // (Note that we have also already checked if the renderer has the 788 // (Note that we have also already checked if the renderer has the
789 // read permission for this file in OnCreateSnapshotFile.) 789 // read permission for this file in OnCreateSnapshotFile.)
790 DCHECK(shareable_file || 790 DCHECK(snaphot_file ||
791 fileapi::SandboxMountPointProvider::CanHandleType(url.type())); 791 fileapi::SandboxMountPointProvider::CanHandleType(url.type()));
792 ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadFile( 792 ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadFile(
793 process_id_, platform_path); 793 process_id_, platform_path);
794 if (shareable_file) { 794 if (snaphot_file) {
795 // This will revoke all permissions for the file when the last ref 795 // This will revoke all permissions for the file when the last ref
796 // of the file is dropped (assuming it's ok). 796 // of the file is dropped (assuming it's ok).
797 shareable_file->AddFinalReleaseCallback( 797 snaphot_file->AddFinalReleaseCallback(
798 base::Bind(&RevokeFilePermission, process_id_)); 798 base::Bind(&RevokeFilePermission, process_id_));
799 } 799 }
800 } 800 }
801 801
802 // This may fail, but then we'll be just setting the empty mime type. 802 if (snaphot_file) {
803 std::string mime_type; 803 // This ref is held until OnDidReceiveSnapshotFile is called. By holding
804 net::GetWellKnownMimeTypeFromExtension(extension, &mime_type); 804 // this ref we ensure that the file is not deleted prior to the renderer
805 BlobData::Item item; 805 // having created a webcore blob data handle that refers to this file
806 item.SetToFilePathRange(platform_path, 0, -1, base::Time()); 806 // and takes a ref of its own.
kinuko 2013/01/07 08:52:01 nit: extra space before 'a ref'
michaeln 2013/01/25 21:19:44 Done.
807 BlobStorageController* controller = blob_storage_context_->controller(); 807 in_transit_snapshot_files_[request_id] = snaphot_file;
808 controller->StartBuildingBlob(blob_url); 808 }
809 controller->AppendBlobDataItem(blob_url, item); 809
810 controller->FinishBuildingBlob(blob_url, mime_type); 810 // Return the file info and platform_path.
811 blob_urls_.insert(blob_url.spec()); 811 Send(new FileSystemMsg_DidCreateSnapshotFile(
812 request_id, info, platform_path));
812 } 813 }
813 814
814 bool FileAPIMessageFilter::HasPermissionsForFile( 815 bool FileAPIMessageFilter::HasPermissionsForFile(
815 const FileSystemURL& url, int permissions, base::PlatformFileError* error) { 816 const FileSystemURL& url, int permissions, base::PlatformFileError* error) {
816 DCHECK(error); 817 DCHECK(error);
817 *error = base::PLATFORM_FILE_OK; 818 *error = base::PLATFORM_FILE_OK;
818 819
819 if (!url.is_valid()) { 820 if (!url.is_valid()) {
820 *error = base::PLATFORM_FILE_ERROR_INVALID_URL; 821 *error = base::PLATFORM_FILE_ERROR_INVALID_URL;
821 return false; 822 return false;
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
885 Send(new FileSystemMsg_DidFail(request_id, error_code)); 886 Send(new FileSystemMsg_DidFail(request_id, error_code));
886 return NULL; 887 return NULL;
887 } 888 }
888 889
889 DCHECK(operation); 890 DCHECK(operation);
890 operations_.AddWithID(operation, request_id); 891 operations_.AddWithID(operation, request_id);
891 return operation; 892 return operation;
892 } 893 }
893 894
894 } // namespace content 895 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698