Chromium Code Reviews| 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/files/file_path.h" | 11 #include "base/files/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/sequenced_task_runner.h" | 14 #include "base/sequenced_task_runner.h" |
| 15 #include "base/strings/string_util.h" | |
| 15 #include "base/threading/thread.h" | 16 #include "base/threading/thread.h" |
| 16 #include "base/time/time.h" | 17 #include "base/time/time.h" |
| 17 #include "content/browser/child_process_security_policy_impl.h" | 18 #include "content/browser/child_process_security_policy_impl.h" |
| 18 #include "content/browser/fileapi/browser_file_system_helper.h" | 19 #include "content/browser/fileapi/browser_file_system_helper.h" |
| 19 #include "content/browser/fileapi/chrome_blob_storage_context.h" | 20 #include "content/browser/fileapi/chrome_blob_storage_context.h" |
| 21 #include "content/browser/streams/stream_registry.h" | |
| 20 #include "content/common/fileapi/file_system_messages.h" | 22 #include "content/common/fileapi/file_system_messages.h" |
| 21 #include "content/common/fileapi/webblob_messages.h" | 23 #include "content/common/fileapi/webblob_messages.h" |
| 22 #include "content/public/browser/user_metrics.h" | 24 #include "content/public/browser/user_metrics.h" |
| 23 #include "googleurl/src/gurl.h" | 25 #include "googleurl/src/gurl.h" |
| 24 #include "ipc/ipc_platform_file.h" | 26 #include "ipc/ipc_platform_file.h" |
| 27 #include "net/base/io_buffer.h" | |
| 25 #include "net/base/mime_util.h" | 28 #include "net/base/mime_util.h" |
| 26 #include "net/url_request/url_request_context.h" | 29 #include "net/url_request/url_request_context.h" |
| 27 #include "net/url_request/url_request_context_getter.h" | 30 #include "net/url_request/url_request_context_getter.h" |
| 28 #include "webkit/browser/blob/blob_storage_controller.h" | 31 #include "webkit/browser/blob/blob_storage_controller.h" |
| 29 #include "webkit/browser/fileapi/file_observers.h" | 32 #include "webkit/browser/fileapi/file_observers.h" |
| 30 #include "webkit/browser/fileapi/file_permission_policy.h" | 33 #include "webkit/browser/fileapi/file_permission_policy.h" |
| 31 #include "webkit/browser/fileapi/file_system_context.h" | 34 #include "webkit/browser/fileapi/file_system_context.h" |
| 32 #include "webkit/browser/fileapi/file_system_task_runners.h" | 35 #include "webkit/browser/fileapi/file_system_task_runners.h" |
| 33 #include "webkit/browser/fileapi/isolated_context.h" | 36 #include "webkit/browser/fileapi/isolated_context.h" |
| 34 #include "webkit/browser/fileapi/local_file_system_operation.h" | 37 #include "webkit/browser/fileapi/local_file_system_operation.h" |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 57 ChildProcessSecurityPolicyImpl::GetInstance()->RevokeAllPermissionsForFile( | 60 ChildProcessSecurityPolicyImpl::GetInstance()->RevokeAllPermissionsForFile( |
| 58 child_id, path); | 61 child_id, path); |
| 59 } | 62 } |
| 60 | 63 |
| 61 } // namespace | 64 } // namespace |
| 62 | 65 |
| 63 FileAPIMessageFilter::FileAPIMessageFilter( | 66 FileAPIMessageFilter::FileAPIMessageFilter( |
| 64 int process_id, | 67 int process_id, |
| 65 net::URLRequestContextGetter* request_context_getter, | 68 net::URLRequestContextGetter* request_context_getter, |
| 66 fileapi::FileSystemContext* file_system_context, | 69 fileapi::FileSystemContext* file_system_context, |
| 67 ChromeBlobStorageContext* blob_storage_context) | 70 ChromeBlobStorageContext* blob_storage_context, |
| 71 StreamContext* stream_context) | |
| 68 : process_id_(process_id), | 72 : process_id_(process_id), |
| 69 context_(file_system_context), | 73 context_(file_system_context), |
| 70 request_context_getter_(request_context_getter), | 74 request_context_getter_(request_context_getter), |
| 71 request_context_(NULL), | 75 request_context_(NULL), |
| 72 blob_storage_context_(blob_storage_context) { | 76 blob_storage_context_(blob_storage_context), |
| 77 stream_context_(stream_context) { | |
| 73 DCHECK(context_); | 78 DCHECK(context_); |
| 74 DCHECK(request_context_getter_.get()); | 79 DCHECK(request_context_getter_.get()); |
| 75 DCHECK(blob_storage_context); | 80 DCHECK(blob_storage_context); |
| 81 DCHECK(stream_context); | |
| 76 } | 82 } |
| 77 | 83 |
| 78 FileAPIMessageFilter::FileAPIMessageFilter( | 84 FileAPIMessageFilter::FileAPIMessageFilter( |
| 79 int process_id, | 85 int process_id, |
| 80 net::URLRequestContext* request_context, | 86 net::URLRequestContext* request_context, |
| 81 fileapi::FileSystemContext* file_system_context, | 87 fileapi::FileSystemContext* file_system_context, |
| 82 ChromeBlobStorageContext* blob_storage_context) | 88 ChromeBlobStorageContext* blob_storage_context, |
| 89 StreamContext* stream_context) | |
| 83 : process_id_(process_id), | 90 : process_id_(process_id), |
| 84 context_(file_system_context), | 91 context_(file_system_context), |
| 85 request_context_(request_context), | 92 request_context_(request_context), |
| 86 blob_storage_context_(blob_storage_context) { | 93 blob_storage_context_(blob_storage_context), |
| 94 stream_context_(stream_context) { | |
| 87 DCHECK(context_); | 95 DCHECK(context_); |
| 88 DCHECK(request_context_); | 96 DCHECK(request_context_); |
| 89 DCHECK(blob_storage_context); | 97 DCHECK(blob_storage_context); |
| 98 DCHECK(stream_context); | |
| 90 } | 99 } |
| 91 | 100 |
| 92 void FileAPIMessageFilter::OnChannelConnected(int32 peer_pid) { | 101 void FileAPIMessageFilter::OnChannelConnected(int32 peer_pid) { |
| 93 BrowserMessageFilter::OnChannelConnected(peer_pid); | 102 BrowserMessageFilter::OnChannelConnected(peer_pid); |
| 94 | 103 |
| 95 if (request_context_getter_.get()) { | 104 if (request_context_getter_.get()) { |
| 96 DCHECK(!request_context_); | 105 DCHECK(!request_context_); |
| 97 request_context_ = request_context_getter_->GetURLRequestContext(); | 106 request_context_ = request_context_getter_->GetURLRequestContext(); |
| 98 request_context_getter_ = NULL; | 107 request_context_getter_ = NULL; |
| 99 DCHECK(request_context_); | 108 DCHECK(request_context_); |
| 100 } | 109 } |
| 101 } | 110 } |
| 102 | 111 |
| 112 scoped_refptr<Stream> FileAPIMessageFilter::GetStreamForURL(const GURL& url) { | |
| 113 return stream_context_->registry()->GetStream(url); | |
| 114 } | |
| 115 | |
| 103 void FileAPIMessageFilter::OnChannelClosing() { | 116 void FileAPIMessageFilter::OnChannelClosing() { |
| 104 BrowserMessageFilter::OnChannelClosing(); | 117 BrowserMessageFilter::OnChannelClosing(); |
| 105 | 118 |
| 106 // Unregister all the blob URLs that are previously registered in this | 119 // Unregister all the blob URLs that are previously registered in this |
| 107 // process. | 120 // process. |
| 108 for (base::hash_set<std::string>::const_iterator iter = blob_urls_.begin(); | 121 for (base::hash_set<std::string>::const_iterator iter = blob_urls_.begin(); |
| 109 iter != blob_urls_.end(); ++iter) { | 122 iter != blob_urls_.end(); ++iter) { |
| 110 blob_storage_context_->controller()->RemoveBlob(GURL(*iter)); | 123 const GURL url(*iter); |
| 124 // Intercept stream URLs. | |
| 125 if (GetStreamForURL(url)) | |
| 126 stream_context_->registry()->UnregisterStream(url); | |
| 127 else | |
| 128 blob_storage_context_->controller()->RemoveBlob(url); | |
| 111 } | 129 } |
| 112 | 130 |
| 113 in_transit_snapshot_files_.clear(); | 131 in_transit_snapshot_files_.clear(); |
| 114 | 132 |
| 115 // Close all files that are previously OpenFile()'ed in this process. | 133 // Close all files that are previously OpenFile()'ed in this process. |
| 116 if (!on_close_callbacks_.IsEmpty()) { | 134 if (!on_close_callbacks_.IsEmpty()) { |
| 117 DLOG(INFO) | 135 DLOG(INFO) |
| 118 << "File API: Renderer process shut down before NotifyCloseFile" | 136 << "File API: Renderer process shut down before NotifyCloseFile" |
| 119 << " for " << on_close_callbacks_.size() << " files opened in PPAPI"; | 137 << " for " << on_close_callbacks_.size() << " files opened in PPAPI"; |
| 120 } | 138 } |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 158 IPC_MESSAGE_HANDLER(FileSystemHostMsg_NotifyCloseFile, OnNotifyCloseFile) | 176 IPC_MESSAGE_HANDLER(FileSystemHostMsg_NotifyCloseFile, OnNotifyCloseFile) |
| 159 IPC_MESSAGE_HANDLER(FileSystemHostMsg_CreateSnapshotFile, | 177 IPC_MESSAGE_HANDLER(FileSystemHostMsg_CreateSnapshotFile, |
| 160 OnCreateSnapshotFile) | 178 OnCreateSnapshotFile) |
| 161 IPC_MESSAGE_HANDLER(FileSystemHostMsg_DidReceiveSnapshotFile, | 179 IPC_MESSAGE_HANDLER(FileSystemHostMsg_DidReceiveSnapshotFile, |
| 162 OnDidReceiveSnapshotFile) | 180 OnDidReceiveSnapshotFile) |
| 163 IPC_MESSAGE_HANDLER(FileSystemHostMsg_WillUpdate, OnWillUpdate) | 181 IPC_MESSAGE_HANDLER(FileSystemHostMsg_WillUpdate, OnWillUpdate) |
| 164 IPC_MESSAGE_HANDLER(FileSystemHostMsg_DidUpdate, OnDidUpdate) | 182 IPC_MESSAGE_HANDLER(FileSystemHostMsg_DidUpdate, OnDidUpdate) |
| 165 IPC_MESSAGE_HANDLER(FileSystemHostMsg_SyncGetPlatformPath, | 183 IPC_MESSAGE_HANDLER(FileSystemHostMsg_SyncGetPlatformPath, |
| 166 OnSyncGetPlatformPath) | 184 OnSyncGetPlatformPath) |
| 167 IPC_MESSAGE_HANDLER(BlobHostMsg_StartBuildingBlob, OnStartBuildingBlob) | 185 IPC_MESSAGE_HANDLER(BlobHostMsg_StartBuildingBlob, OnStartBuildingBlob) |
| 186 IPC_MESSAGE_HANDLER(BlobHostMsg_StartBuildingStream, OnStartBuildingStream) | |
|
kinuko
2013/07/18 06:06:55
Sometimes we interchangeably use the term 'blob' a
tyoshino (SeeGerritForStatus)
2013/07/23 07:27:34
Darin's idea was making Blob a subclass of the Str
kinuko
2013/07/23 08:07:42
This sounds good to me.
(I initially thought we c
tyoshino (SeeGerritForStatus)
2013/07/23 11:54:38
Done
| |
| 168 IPC_MESSAGE_HANDLER(BlobHostMsg_AppendBlobDataItem, OnAppendBlobDataItem) | 187 IPC_MESSAGE_HANDLER(BlobHostMsg_AppendBlobDataItem, OnAppendBlobDataItem) |
| 169 IPC_MESSAGE_HANDLER(BlobHostMsg_SyncAppendSharedMemory, | 188 IPC_MESSAGE_HANDLER(BlobHostMsg_SyncAppendSharedMemory, |
| 170 OnAppendSharedMemory) | 189 OnAppendSharedMemory) |
| 171 IPC_MESSAGE_HANDLER(BlobHostMsg_FinishBuildingBlob, OnFinishBuildingBlob) | 190 IPC_MESSAGE_HANDLER(BlobHostMsg_FinishBuildingBlob, OnFinishBuildingBlob) |
| 172 IPC_MESSAGE_HANDLER(BlobHostMsg_CloneBlob, OnCloneBlob) | 191 IPC_MESSAGE_HANDLER(BlobHostMsg_CloneBlob, OnCloneBlob) |
| 173 IPC_MESSAGE_HANDLER(BlobHostMsg_RemoveBlob, OnRemoveBlob) | 192 IPC_MESSAGE_HANDLER(BlobHostMsg_RemoveBlob, OnRemoveBlob) |
| 174 IPC_MESSAGE_UNHANDLED(handled = false) | 193 IPC_MESSAGE_UNHANDLED(handled = false) |
| 175 IPC_END_MESSAGE_MAP_EX() | 194 IPC_END_MESSAGE_MAP_EX() |
| 176 return handled; | 195 return handled; |
| 177 } | 196 } |
| (...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 509 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 528 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 510 in_transit_snapshot_files_.erase(request_id); | 529 in_transit_snapshot_files_.erase(request_id); |
| 511 } | 530 } |
| 512 | 531 |
| 513 void FileAPIMessageFilter::OnStartBuildingBlob(const GURL& url) { | 532 void FileAPIMessageFilter::OnStartBuildingBlob(const GURL& url) { |
| 514 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 533 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 515 blob_storage_context_->controller()->StartBuildingBlob(url); | 534 blob_storage_context_->controller()->StartBuildingBlob(url); |
| 516 blob_urls_.insert(url.spec()); | 535 blob_urls_.insert(url.spec()); |
| 517 } | 536 } |
| 518 | 537 |
| 538 // Currently |content_type| is ignored inside Chromium. | |
| 539 // | |
| 540 // TODO(tyoshino): Set |content_type| to the stream. | |
| 541 void FileAPIMessageFilter::OnStartBuildingStream( | |
| 542 const GURL& url, const std::string& content_type) { | |
| 543 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 544 // Only an internal Blob URL is expected here. See the BlobURL of the Blink. | |
| 545 DCHECK(StartsWithASCII( | |
| 546 url.path(), "blobinternal%3A///", true /* case_sensitive*/)); | |
| 547 // Use an empty security origin for now. Stream accepts a security origin | |
| 548 // but how it's handled is not fixed yet. | |
| 549 new Stream(stream_context_->registry(), | |
| 550 NULL /* write_observer */, | |
| 551 GURL() /* security_origin */, | |
| 552 url); | |
| 553 blob_urls_.insert(url.spec()); | |
| 554 } | |
| 555 | |
| 519 void FileAPIMessageFilter::OnAppendBlobDataItem( | 556 void FileAPIMessageFilter::OnAppendBlobDataItem( |
| 520 const GURL& url, const BlobData::Item& item) { | 557 const GURL& url, const BlobData::Item& item) { |
| 521 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 558 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 559 | |
| 560 scoped_refptr<Stream> stream(GetStreamForURL(url)); | |
| 561 if (stream.get()) { | |
| 562 // Data for stream is delivered as TYPE_BYTES item. | |
| 563 if (item.type() != BlobData::Item::TYPE_BYTES) { | |
| 564 BadMessageReceived(); | |
| 565 return; | |
| 566 } | |
| 567 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(item.length())); | |
| 568 memcpy(buffer->data(), item.bytes(), item.length()); | |
| 569 stream->AddData(buffer, item.length()); | |
| 570 | |
| 571 return; | |
| 572 } | |
| 573 | |
| 522 if (item.type() == BlobData::Item::TYPE_FILE_FILESYSTEM) { | 574 if (item.type() == BlobData::Item::TYPE_FILE_FILESYSTEM) { |
| 523 base::PlatformFileError error; | 575 base::PlatformFileError error; |
| 524 FileSystemURL filesystem_url(context_->CrackURL(item.url())); | 576 FileSystemURL filesystem_url(context_->CrackURL(item.url())); |
| 525 if (!HasPermissionsForFile(filesystem_url, | 577 if (!HasPermissionsForFile(filesystem_url, |
| 526 fileapi::kReadFilePermissions, &error)) { | 578 fileapi::kReadFilePermissions, &error)) { |
| 527 OnRemoveBlob(url); | 579 OnRemoveBlob(url); |
| 528 return; | 580 return; |
| 529 } | 581 } |
| 530 } | 582 } |
| 531 if (item.type() == BlobData::Item::TYPE_FILE && | 583 if (item.type() == BlobData::Item::TYPE_FILE && |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 551 #if defined(OS_WIN) | 603 #if defined(OS_WIN) |
| 552 base::SharedMemory shared_memory(handle, true, peer_handle()); | 604 base::SharedMemory shared_memory(handle, true, peer_handle()); |
| 553 #else | 605 #else |
| 554 base::SharedMemory shared_memory(handle, true); | 606 base::SharedMemory shared_memory(handle, true); |
| 555 #endif | 607 #endif |
| 556 if (!shared_memory.Map(buffer_size)) { | 608 if (!shared_memory.Map(buffer_size)) { |
| 557 OnRemoveBlob(url); | 609 OnRemoveBlob(url); |
| 558 return; | 610 return; |
| 559 } | 611 } |
| 560 | 612 |
| 613 scoped_refptr<Stream> stream(GetStreamForURL(url)); | |
| 614 if (stream.get()) { | |
| 615 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(buffer_size)); | |
| 616 memcpy(buffer->data(), static_cast<char*>(shared_memory.memory()), | |
| 617 buffer_size); | |
| 618 stream->AddData(buffer, buffer_size); | |
|
kinuko
2013/07/18 06:06:55
nit: it might be easier to read if Stream class ju
tyoshino (SeeGerritForStatus)
2013/07/23 11:54:38
Done.
| |
| 619 return; | |
| 620 } | |
| 621 | |
| 561 BlobData::Item item; | 622 BlobData::Item item; |
| 562 item.SetToSharedBytes(static_cast<char*>(shared_memory.memory()), | 623 item.SetToSharedBytes(static_cast<char*>(shared_memory.memory()), |
| 563 buffer_size); | 624 buffer_size); |
| 564 blob_storage_context_->controller()->AppendBlobDataItem(url, item); | 625 blob_storage_context_->controller()->AppendBlobDataItem(url, item); |
| 565 } | 626 } |
| 566 | 627 |
| 567 void FileAPIMessageFilter::OnFinishBuildingBlob( | 628 void FileAPIMessageFilter::OnFinishBuildingBlob( |
| 568 const GURL& url, const std::string& content_type) { | 629 const GURL& url, const std::string& content_type) { |
| 569 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 630 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 570 blob_storage_context_->controller()->FinishBuildingBlob(url, content_type); | 631 scoped_refptr<Stream> stream(GetStreamForURL(url)); |
| 632 if (stream.get()) | |
| 633 stream->Finalize(); | |
| 634 else | |
| 635 blob_storage_context_->controller()->FinishBuildingBlob(url, content_type); | |
| 571 } | 636 } |
| 572 | 637 |
| 573 void FileAPIMessageFilter::OnCloneBlob( | 638 void FileAPIMessageFilter::OnCloneBlob( |
| 574 const GURL& url, const GURL& src_url) { | 639 const GURL& url, const GURL& src_url) { |
| 575 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 640 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 576 blob_storage_context_->controller()->CloneBlob(url, src_url); | 641 if (GetStreamForURL(src_url)) |
| 642 stream_context_->registry()->CloneStream(url, src_url); | |
| 643 else | |
| 644 blob_storage_context_->controller()->CloneBlob(url, src_url); | |
| 577 blob_urls_.insert(url.spec()); | 645 blob_urls_.insert(url.spec()); |
| 578 } | 646 } |
| 579 | 647 |
| 580 void FileAPIMessageFilter::OnRemoveBlob(const GURL& url) { | 648 void FileAPIMessageFilter::OnRemoveBlob(const GURL& url) { |
| 581 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 649 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 582 blob_storage_context_->controller()->RemoveBlob(url); | 650 if (GetStreamForURL(url).get()) |
| 651 stream_context_->registry()->UnregisterStream(url); | |
| 652 else | |
| 653 blob_storage_context_->controller()->RemoveBlob(url); | |
| 583 blob_urls_.erase(url.spec()); | 654 blob_urls_.erase(url.spec()); |
| 584 } | 655 } |
| 585 | 656 |
| 586 void FileAPIMessageFilter::DidFinish(int request_id, | 657 void FileAPIMessageFilter::DidFinish(int request_id, |
| 587 base::PlatformFileError result) { | 658 base::PlatformFileError result) { |
| 588 if (result == base::PLATFORM_FILE_OK) | 659 if (result == base::PLATFORM_FILE_OK) |
| 589 Send(new FileSystemMsg_DidSucceed(request_id)); | 660 Send(new FileSystemMsg_DidSucceed(request_id)); |
| 590 else | 661 else |
| 591 Send(new FileSystemMsg_DidFail(request_id, result)); | 662 Send(new FileSystemMsg_DidFail(request_id, result)); |
| 592 operations_.erase(request_id); | 663 operations_.erase(request_id); |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 740 const FileSystemURL& url, int permissions, base::PlatformFileError* error) { | 811 const FileSystemURL& url, int permissions, base::PlatformFileError* error) { |
| 741 return CheckFileSystemPermissionsForProcess(context_, process_id_, url, | 812 return CheckFileSystemPermissionsForProcess(context_, process_id_, url, |
| 742 permissions, error); | 813 permissions, error); |
| 743 } | 814 } |
| 744 | 815 |
| 745 fileapi::FileSystemOperationRunner* FileAPIMessageFilter::operation_runner() { | 816 fileapi::FileSystemOperationRunner* FileAPIMessageFilter::operation_runner() { |
| 746 return context_->operation_runner(); | 817 return context_->operation_runner(); |
| 747 } | 818 } |
| 748 | 819 |
| 749 } // namespace content | 820 } // namespace content |
| OLD | NEW |