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 "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_permission_policy.h" | 30 #include "webkit/fileapi/file_permission_policy.h" |
31 #include "webkit/fileapi/file_system_context.h" | 31 #include "webkit/fileapi/file_system_context.h" |
32 #include "webkit/fileapi/file_system_types.h" | 32 #include "webkit/fileapi/file_system_types.h" |
33 #include "webkit/fileapi/file_system_util.h" | 33 #include "webkit/fileapi/file_system_util.h" |
34 #include "webkit/fileapi/isolated_context.h" | 34 #include "webkit/fileapi/isolated_context.h" |
35 #include "webkit/fileapi/local_file_system_operation.h" | 35 #include "webkit/fileapi/local_file_system_operation.h" |
36 #include "webkit/fileapi/sandbox_mount_point_provider.h" | 36 #include "webkit/fileapi/sandbox_mount_point_provider.h" |
37 | 37 |
38 using fileapi::FileSystemFileUtil; | 38 using fileapi::FileSystemFileUtil; |
39 using fileapi::FileSystemMountPointProvider; | 39 using fileapi::FileSystemMountPointProvider; |
40 using fileapi::FileSystemOperation; | 40 using fileapi::FileSystemOperation; |
41 using fileapi::FileSystemURL; | 41 using fileapi::FileSystemURL; |
42 using fileapi::FileUpdateObserver; | 42 using fileapi::FileUpdateObserver; |
43 using fileapi::LocalFileSystemOperation; | 43 using fileapi::LocalFileSystemOperation; |
44 using fileapi::UpdateObserverList; | 44 using fileapi::UpdateObserverList; |
45 using webkit_blob::BlobData; | 45 using webkit_blob::BlobData; |
46 using webkit_blob::BlobStorageController; | 46 using webkit_blob::BlobStorageContext; |
| 47 using webkit_blob::BlobStorageConsumer; |
47 | 48 |
48 namespace content { | 49 namespace content { |
49 | 50 |
50 namespace { | 51 namespace { |
51 | 52 |
52 void RevokeFilePermission(int child_id, const base::FilePath& path) { | 53 void RevokeFilePermission(int child_id, const base::FilePath& path) { |
53 ChildProcessSecurityPolicyImpl::GetInstance()->RevokeAllPermissionsForFile( | 54 ChildProcessSecurityPolicyImpl::GetInstance()->RevokeAllPermissionsForFile( |
54 child_id, path); | 55 child_id, path); |
55 } | 56 } |
56 | 57 |
(...skipping 30 matching lines...) Expand all Loading... |
87 | 88 |
88 void FileAPIMessageFilter::OnChannelConnected(int32 peer_pid) { | 89 void FileAPIMessageFilter::OnChannelConnected(int32 peer_pid) { |
89 BrowserMessageFilter::OnChannelConnected(peer_pid); | 90 BrowserMessageFilter::OnChannelConnected(peer_pid); |
90 | 91 |
91 if (request_context_getter_.get()) { | 92 if (request_context_getter_.get()) { |
92 DCHECK(!request_context_); | 93 DCHECK(!request_context_); |
93 request_context_ = request_context_getter_->GetURLRequestContext(); | 94 request_context_ = request_context_getter_->GetURLRequestContext(); |
94 request_context_getter_ = NULL; | 95 request_context_getter_ = NULL; |
95 DCHECK(request_context_); | 96 DCHECK(request_context_); |
96 } | 97 } |
| 98 |
| 99 blob_storage_consumer_.reset( |
| 100 new webkit_blob::BlobStorageConsumer(blob_storage_context_->context())); |
97 } | 101 } |
98 | 102 |
99 void FileAPIMessageFilter::OnChannelClosing() { | 103 void FileAPIMessageFilter::OnChannelClosing() { |
100 BrowserMessageFilter::OnChannelClosing(); | 104 BrowserMessageFilter::OnChannelClosing(); |
101 | 105 |
102 // Unregister all the blob URLs that are previously registered in this | 106 blob_storage_consumer_.reset(); |
103 // process. | |
104 for (base::hash_set<std::string>::const_iterator iter = blob_urls_.begin(); | |
105 iter != blob_urls_.end(); ++iter) { | |
106 blob_storage_context_->controller()->RemoveBlob(GURL(*iter)); | |
107 } | |
108 | |
109 in_transit_snapshot_files_.clear(); | 107 in_transit_snapshot_files_.clear(); |
110 | 108 |
111 // Close all files that are previously OpenFile()'ed in this process. | 109 // Close all files that are previously OpenFile()'ed in this process. |
112 if (!open_filesystem_urls_.empty()) { | 110 if (!open_filesystem_urls_.empty()) { |
113 DLOG(INFO) | 111 DLOG(INFO) |
114 << "File API: Renderer process shut down before NotifyCloseFile" | 112 << "File API: Renderer process shut down before NotifyCloseFile" |
115 << " for " << open_filesystem_urls_.size() << " files opened in PPAPI"; | 113 << " for " << open_filesystem_urls_.size() << " files opened in PPAPI"; |
116 } | 114 } |
117 for (std::multiset<GURL>::const_iterator iter = | 115 for (std::multiset<GURL>::const_iterator iter = |
118 open_filesystem_urls_.begin(); | 116 open_filesystem_urls_.begin(); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 IPC_MESSAGE_HANDLER(FileSystemHostMsg_CreateSnapshotFile, | 153 IPC_MESSAGE_HANDLER(FileSystemHostMsg_CreateSnapshotFile, |
156 OnCreateSnapshotFile) | 154 OnCreateSnapshotFile) |
157 IPC_MESSAGE_HANDLER(FileSystemHostMsg_DidReceiveSnapshotFile, | 155 IPC_MESSAGE_HANDLER(FileSystemHostMsg_DidReceiveSnapshotFile, |
158 OnDidReceiveSnapshotFile) | 156 OnDidReceiveSnapshotFile) |
159 IPC_MESSAGE_HANDLER(FileSystemHostMsg_CreateSnapshotFile_Deprecated, | 157 IPC_MESSAGE_HANDLER(FileSystemHostMsg_CreateSnapshotFile_Deprecated, |
160 OnCreateSnapshotFile_Deprecated) | 158 OnCreateSnapshotFile_Deprecated) |
161 IPC_MESSAGE_HANDLER(FileSystemHostMsg_WillUpdate, OnWillUpdate) | 159 IPC_MESSAGE_HANDLER(FileSystemHostMsg_WillUpdate, OnWillUpdate) |
162 IPC_MESSAGE_HANDLER(FileSystemHostMsg_DidUpdate, OnDidUpdate) | 160 IPC_MESSAGE_HANDLER(FileSystemHostMsg_DidUpdate, OnDidUpdate) |
163 IPC_MESSAGE_HANDLER(FileSystemHostMsg_SyncGetPlatformPath, | 161 IPC_MESSAGE_HANDLER(FileSystemHostMsg_SyncGetPlatformPath, |
164 OnSyncGetPlatformPath) | 162 OnSyncGetPlatformPath) |
165 IPC_MESSAGE_HANDLER(BlobHostMsg_StartBuildingBlob, OnStartBuildingBlob) | 163 IPC_MESSAGE_HANDLER(BlobHostMsg_StartBuildingBlob2, OnStartBuildingBlob2) |
166 IPC_MESSAGE_HANDLER(BlobHostMsg_AppendBlobDataItem, OnAppendBlobDataItem) | 164 IPC_MESSAGE_HANDLER(BlobHostMsg_AppendBlobDataItem2, OnAppendBlobDataItem2) |
167 IPC_MESSAGE_HANDLER(BlobHostMsg_SyncAppendSharedMemory, | 165 IPC_MESSAGE_HANDLER(BlobHostMsg_AppendSharedMemory2, |
168 OnAppendSharedMemory) | 166 OnAppendSharedMemory2) |
169 IPC_MESSAGE_HANDLER(BlobHostMsg_FinishBuildingBlob, OnFinishBuildingBlob) | 167 IPC_MESSAGE_HANDLER(BlobHostMsg_FinishBuildingBlob2, OnFinishBuildingBlob2) |
170 IPC_MESSAGE_HANDLER(BlobHostMsg_CloneBlob, OnCloneBlob) | 168 IPC_MESSAGE_HANDLER(BlobHostMsg_IncrementBlobRefCount, |
171 IPC_MESSAGE_HANDLER(BlobHostMsg_RemoveBlob, OnRemoveBlob) | 169 OnIncrementBlobRefCount) |
| 170 IPC_MESSAGE_HANDLER(BlobHostMsg_DecrementBlobRefCount, |
| 171 OnDecrementBlobRefCount) |
| 172 IPC_MESSAGE_HANDLER(BlobHostMsg_RegisterPublicBlobURL, |
| 173 OnRegisterPublicBlobURL) |
| 174 IPC_MESSAGE_HANDLER(BlobHostMsg_RevokePublicBlobURL, OnRevokePublicBlobURL) |
172 IPC_MESSAGE_UNHANDLED(handled = false) | 175 IPC_MESSAGE_UNHANDLED(handled = false) |
173 IPC_END_MESSAGE_MAP_EX() | 176 IPC_END_MESSAGE_MAP_EX() |
174 return handled; | 177 return handled; |
175 } | 178 } |
176 | 179 |
177 void FileAPIMessageFilter::UnregisterOperation(int request_id) { | 180 void FileAPIMessageFilter::UnregisterOperation(int request_id) { |
178 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 181 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
179 DCHECK(operations_.Lookup(request_id)); | 182 DCHECK(operations_.Lookup(request_id)); |
180 operations_.Remove(request_id); | 183 operations_.Remove(request_id); |
181 } | 184 } |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
352 if (!operation) | 355 if (!operation) |
353 return; | 356 return; |
354 operation->ReadDirectory( | 357 operation->ReadDirectory( |
355 url, base::Bind(&FileAPIMessageFilter::DidReadDirectory, | 358 url, base::Bind(&FileAPIMessageFilter::DidReadDirectory, |
356 this, request_id)); | 359 this, request_id)); |
357 } | 360 } |
358 | 361 |
359 void FileAPIMessageFilter::OnWrite( | 362 void FileAPIMessageFilter::OnWrite( |
360 int request_id, | 363 int request_id, |
361 const GURL& path, | 364 const GURL& path, |
362 const GURL& blob_url, | 365 const std::string& blob_uuid, |
363 int64 offset) { | 366 int64 offset) { |
364 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 367 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
365 if (!request_context_) { | 368 if (!request_context_) { |
366 // We can't write w/o a request context, trying to do so will crash. | 369 // We can't write w/o a request context, trying to do so will crash. |
367 NOTREACHED(); | 370 NOTREACHED(); |
368 return; | 371 return; |
369 } | 372 } |
370 | 373 |
371 FileSystemURL url(context_->CrackURL(path)); | 374 FileSystemURL url(context_->CrackURL(path)); |
372 base::PlatformFileError error; | 375 base::PlatformFileError error; |
373 if (!HasPermissionsForFile(url, fileapi::kWriteFilePermissions, &error)) { | 376 if (!HasPermissionsForFile(url, fileapi::kWriteFilePermissions, &error)) { |
374 Send(new FileSystemMsg_DidFail(request_id, error)); | 377 Send(new FileSystemMsg_DidFail(request_id, error)); |
375 return; | 378 return; |
376 } | 379 } |
377 | 380 |
378 FileSystemOperation* operation = GetNewOperation(url, request_id); | 381 FileSystemOperation* operation = GetNewOperation(url, request_id); |
379 if (!operation) | 382 if (!operation) |
380 return; | 383 return; |
| 384 scoped_ptr<webkit_blob::BlobDataHandle> blob = |
| 385 blob_storage_context_->context()->GetBlobDataFromUUID(blob_uuid); |
381 operation->Write( | 386 operation->Write( |
382 request_context_, url, blob_url, offset, | 387 request_context_, url, blob.Pass(), offset, |
383 base::Bind(&FileAPIMessageFilter::DidWrite, this, request_id)); | 388 base::Bind(&FileAPIMessageFilter::DidWrite, this, request_id)); |
384 } | 389 } |
385 | 390 |
386 void FileAPIMessageFilter::OnTruncate( | 391 void FileAPIMessageFilter::OnTruncate( |
387 int request_id, | 392 int request_id, |
388 const GURL& path, | 393 const GURL& path, |
389 int64 length) { | 394 int64 length) { |
390 base::PlatformFileError error; | 395 base::PlatformFileError error; |
391 FileSystemURL url(context_->CrackURL(path)); | 396 FileSystemURL url(context_->CrackURL(path)); |
392 if (!HasPermissionsForFile(url, fileapi::kWriteFilePermissions, &error)) { | 397 if (!HasPermissionsForFile(url, fileapi::kWriteFilePermissions, &error)) { |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
591 | 596 |
592 FileSystemOperation* operation = GetNewOperation(url, request_id); | 597 FileSystemOperation* operation = GetNewOperation(url, request_id); |
593 if (!operation) | 598 if (!operation) |
594 return; | 599 return; |
595 operation->CreateSnapshotFile( | 600 operation->CreateSnapshotFile( |
596 url, | 601 url, |
597 base::Bind(&FileAPIMessageFilter::DidCreateSnapshot_Deprecated, | 602 base::Bind(&FileAPIMessageFilter::DidCreateSnapshot_Deprecated, |
598 this, request_id, register_file_callback)); | 603 this, request_id, register_file_callback)); |
599 } | 604 } |
600 | 605 |
601 void FileAPIMessageFilter::OnStartBuildingBlob(const GURL& url) { | 606 void FileAPIMessageFilter::OnStartBuildingBlob2(const std::string& uuid) { |
602 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 607 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
603 blob_storage_context_->controller()->StartBuildingBlob(url); | 608 blob_storage_consumer_->StartBuildingBlob(uuid); |
604 blob_urls_.insert(url.spec()); | |
605 } | 609 } |
606 | 610 |
607 void FileAPIMessageFilter::OnAppendBlobDataItem( | 611 void FileAPIMessageFilter::OnAppendBlobDataItem2( |
608 const GURL& url, const BlobData::Item& item) { | 612 const std::string& uuid, const webkit_blob::BlobData::Item& item) { |
609 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 613 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
610 if (item.type() == BlobData::Item::TYPE_FILE_FILESYSTEM) { | 614 if (item.type() == BlobData::Item::TYPE_FILE_FILESYSTEM) { |
611 // TODO(kinuko): Implement permission check for filesystem files. | 615 // TODO(kinuko): Implement permission check for filesystem files. |
612 // http://crbug.com/169423 | 616 // http://crbug.com/169423 |
613 OnRemoveBlob(url); | 617 blob_storage_consumer_->CancelBuildingBlob(uuid); |
614 return; | 618 return; |
615 } | 619 } |
616 if (item.type() == BlobData::Item::TYPE_FILE && | 620 if (item.type() == BlobData::Item::TYPE_FILE && |
617 !ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile( | 621 !ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile( |
618 process_id_, item.path())) { | 622 process_id_, item.path())) { |
619 OnRemoveBlob(url); | 623 blob_storage_consumer_->CancelBuildingBlob(uuid); |
620 return; | 624 return; |
621 } | 625 } |
622 if (item.length() == 0) { | 626 if (item.length() == 0) { |
623 BadMessageReceived(); | 627 BadMessageReceived(); |
624 return; | 628 return; |
625 } | 629 } |
626 blob_storage_context_->controller()->AppendBlobDataItem(url, item); | 630 blob_storage_consumer_->AppendBlobDataItem(uuid, item); |
627 } | 631 } |
628 | 632 |
629 void FileAPIMessageFilter::OnAppendSharedMemory( | 633 void FileAPIMessageFilter::OnAppendSharedMemory2( |
630 const GURL& url, base::SharedMemoryHandle handle, size_t buffer_size) { | 634 const std::string& uuid, |
| 635 base::SharedMemoryHandle handle, |
| 636 size_t buffer_size) { |
631 DCHECK(base::SharedMemory::IsHandleValid(handle)); | 637 DCHECK(base::SharedMemory::IsHandleValid(handle)); |
632 if (!buffer_size) { | 638 if (!buffer_size) { |
633 BadMessageReceived(); | 639 BadMessageReceived(); |
634 return; | 640 return; |
635 } | 641 } |
636 #if defined(OS_WIN) | 642 #if defined(OS_WIN) |
637 base::SharedMemory shared_memory(handle, true, peer_handle()); | 643 base::SharedMemory shared_memory(handle, true, peer_handle()); |
638 #else | 644 #else |
639 base::SharedMemory shared_memory(handle, true); | 645 base::SharedMemory shared_memory(handle, true); |
640 #endif | 646 #endif |
641 if (!shared_memory.Map(buffer_size)) { | 647 if (!shared_memory.Map(buffer_size)) { |
642 OnRemoveBlob(url); | 648 blob_storage_consumer_->CancelBuildingBlob(uuid); |
643 return; | 649 return; |
644 } | 650 } |
645 | 651 |
646 BlobData::Item item; | 652 BlobData::Item item; |
647 item.SetToSharedBytes(static_cast<char*>(shared_memory.memory()), | 653 item.SetToSharedBytes(static_cast<char*>(shared_memory.memory()), |
648 buffer_size); | 654 buffer_size); |
649 blob_storage_context_->controller()->AppendBlobDataItem(url, item); | 655 blob_storage_consumer_->AppendBlobDataItem(uuid, item); |
650 } | 656 } |
651 | 657 |
652 void FileAPIMessageFilter::OnFinishBuildingBlob( | 658 void FileAPIMessageFilter::OnFinishBuildingBlob2(const std::string& uuid, |
653 const GURL& url, const std::string& content_type) { | 659 const std::string& content_type) { |
654 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 660 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
655 blob_storage_context_->controller()->FinishBuildingBlob(url, content_type); | 661 blob_storage_consumer_->FinishBuildingBlob(uuid, content_type); |
656 } | 662 } |
657 | 663 |
658 void FileAPIMessageFilter::OnCloneBlob( | 664 void FileAPIMessageFilter::OnIncrementBlobRefCount(const std::string& uuid) { |
659 const GURL& url, const GURL& src_url) { | |
660 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 665 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
661 blob_storage_context_->controller()->CloneBlob(url, src_url); | 666 blob_storage_consumer_->IncrementBlobRefCount(uuid); |
662 blob_urls_.insert(url.spec()); | |
663 } | 667 } |
664 | 668 |
665 void FileAPIMessageFilter::OnRemoveBlob(const GURL& url) { | 669 void FileAPIMessageFilter::OnDecrementBlobRefCount(const std::string& uuid) { |
666 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 670 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
667 blob_storage_context_->controller()->RemoveBlob(url); | 671 blob_storage_consumer_->DecrementBlobRefCount(uuid); |
668 blob_urls_.erase(url.spec()); | 672 } |
| 673 |
| 674 void FileAPIMessageFilter::OnRegisterPublicBlobURL( |
| 675 const GURL& public_url, const std::string& uuid) { |
| 676 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 677 blob_storage_consumer_->RegisterPublicBlobURL(public_url, uuid); |
| 678 } |
| 679 |
| 680 void FileAPIMessageFilter::OnRevokePublicBlobURL(const GURL& public_url) { |
| 681 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 682 blob_storage_consumer_->RevokePublicBlobURL(public_url); |
669 } | 683 } |
670 | 684 |
671 void FileAPIMessageFilter::DidFinish(int request_id, | 685 void FileAPIMessageFilter::DidFinish(int request_id, |
672 base::PlatformFileError result) { | 686 base::PlatformFileError result) { |
673 if (result == base::PLATFORM_FILE_OK) | 687 if (result == base::PLATFORM_FILE_OK) |
674 Send(new FileSystemMsg_DidSucceed(request_id)); | 688 Send(new FileSystemMsg_DidSucceed(request_id)); |
675 else | 689 else |
676 Send(new FileSystemMsg_DidFail(request_id, result)); | 690 Send(new FileSystemMsg_DidFail(request_id, result)); |
677 UnregisterOperation(request_id); | 691 UnregisterOperation(request_id); |
678 } | 692 } |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
820 } | 834 } |
821 | 835 |
822 void FileAPIMessageFilter::DidCreateSnapshot_Deprecated( | 836 void FileAPIMessageFilter::DidCreateSnapshot_Deprecated( |
823 int request_id, | 837 int request_id, |
824 const base::Callback<void(const base::FilePath&)>& register_file_callback, | 838 const base::Callback<void(const base::FilePath&)>& register_file_callback, |
825 base::PlatformFileError result, | 839 base::PlatformFileError result, |
826 const base::PlatformFileInfo& info, | 840 const base::PlatformFileInfo& info, |
827 const base::FilePath& platform_path, | 841 const base::FilePath& platform_path, |
828 const scoped_refptr<webkit_blob::ShareableFileReference>& unused) { | 842 const scoped_refptr<webkit_blob::ShareableFileReference>& unused) { |
829 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 843 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
830 if (result != base::PLATFORM_FILE_OK) { | 844 NOTREACHED(); |
831 Send(new FileSystemMsg_DidFail(request_id, result)); | |
832 return; | |
833 } | |
834 | |
835 // Register the created file to the blob registry by calling | |
836 // RegisterFileAsBlob. | |
837 // Blob storage automatically finds and refs the file_ref, so we don't | |
838 // need to do anything for the returned file reference (|unused|) here. | |
839 register_file_callback.Run(platform_path); | |
840 | |
841 // Return the file info and platform_path. | |
842 Send(new FileSystemMsg_DidReadMetadata(request_id, info, platform_path)); | |
843 } | 845 } |
844 | 846 |
845 void FileAPIMessageFilter::RegisterFileAsBlob( | 847 void FileAPIMessageFilter::RegisterFileAsBlob( |
846 const GURL& blob_url, | 848 const GURL& blob_url, |
847 const FileSystemURL& url, | 849 const FileSystemURL& url, |
848 const base::FilePath& platform_path) { | 850 const base::FilePath& platform_path) { |
849 // Use the virtual path's extension to determine MIME type. | 851 NOTREACHED(); |
850 base::FilePath::StringType extension = url.path().Extension(); | |
851 if (!extension.empty()) | |
852 extension = extension.substr(1); // Strip leading ".". | |
853 | |
854 scoped_refptr<webkit_blob::ShareableFileReference> shareable_file = | |
855 webkit_blob::ShareableFileReference::Get(platform_path); | |
856 if (!ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile( | |
857 process_id_, platform_path)) { | |
858 // In order for the renderer to be able to read the file, it must be granted | |
859 // read permission for the file's platform path. By now, it has already been | |
860 // verified that the renderer has sufficient permissions to read the file. | |
861 // It is still possible that ChildProcessSecurityPolicyImpl doesn't reflect | |
862 // that the renderer can read the file's platform path. If this is the case | |
863 // the renderer should be granted read permission for the file's platform | |
864 // path. This can happen in the following situations: | |
865 // - the file comes from sandboxed filesystem. Reading sandboxed files is | |
866 // always permitted, but only implicitly. | |
867 // - the underlying filesystem returned newly created snapshot file. | |
868 // - the file comes from an external drive filesystem. The renderer has | |
869 // already been granted read permission for the file's nominal path, but | |
870 // for drive files, platform paths differ from the nominal paths. | |
871 DCHECK(shareable_file || | |
872 fileapi::SandboxMountPointProvider::CanHandleType(url.type()) || | |
873 url.type() == fileapi::kFileSystemTypeDrive); | |
874 ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadFile( | |
875 process_id_, platform_path); | |
876 if (shareable_file) { | |
877 // This will revoke all permissions for the file when the last ref | |
878 // of the file is dropped (assuming it's ok). | |
879 shareable_file->AddFinalReleaseCallback( | |
880 base::Bind(&RevokeFilePermission, process_id_)); | |
881 } | |
882 } | |
883 | |
884 // This may fail, but then we'll be just setting the empty mime type. | |
885 std::string mime_type; | |
886 net::GetWellKnownMimeTypeFromExtension(extension, &mime_type); | |
887 BlobData::Item item; | |
888 item.SetToFilePathRange(platform_path, 0, -1, base::Time()); | |
889 BlobStorageController* controller = blob_storage_context_->controller(); | |
890 controller->StartBuildingBlob(blob_url); | |
891 controller->AppendBlobDataItem(blob_url, item); | |
892 controller->FinishBuildingBlob(blob_url, mime_type); | |
893 blob_urls_.insert(blob_url.spec()); | |
894 } | 852 } |
895 | 853 |
896 bool FileAPIMessageFilter::HasPermissionsForFile( | 854 bool FileAPIMessageFilter::HasPermissionsForFile( |
897 const FileSystemURL& url, int permissions, base::PlatformFileError* error) { | 855 const FileSystemURL& url, int permissions, base::PlatformFileError* error) { |
898 DCHECK(error); | 856 DCHECK(error); |
899 *error = base::PLATFORM_FILE_OK; | 857 *error = base::PLATFORM_FILE_OK; |
900 | 858 |
901 if (!url.is_valid()) { | 859 if (!url.is_valid()) { |
902 *error = base::PLATFORM_FILE_ERROR_INVALID_URL; | 860 *error = base::PLATFORM_FILE_ERROR_INVALID_URL; |
903 return false; | 861 return false; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
951 Send(new FileSystemMsg_DidFail(request_id, error_code)); | 909 Send(new FileSystemMsg_DidFail(request_id, error_code)); |
952 return NULL; | 910 return NULL; |
953 } | 911 } |
954 | 912 |
955 DCHECK(operation); | 913 DCHECK(operation); |
956 operations_.AddWithID(operation, request_id); | 914 operations_.AddWithID(operation, request_id); |
957 return operation; | 915 return operation; |
958 } | 916 } |
959 | 917 |
960 } // namespace content | 918 } // namespace content |
OLD | NEW |