| 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 |