| Index: content/browser/fileapi/fileapi_message_filter.cc
|
| diff --git a/content/browser/fileapi/fileapi_message_filter.cc b/content/browser/fileapi/fileapi_message_filter.cc
|
| index cf95b02332447173230973534b586618a9014140..d5e903b3e9a2fad3ac4a1f4d6c4a4b004a2aaa8c 100644
|
| --- a/content/browser/fileapi/fileapi_message_filter.cc
|
| +++ b/content/browser/fileapi/fileapi_message_filter.cc
|
| @@ -9,14 +9,17 @@
|
|
|
| #include "base/bind.h"
|
| #include "base/files/file_path.h"
|
| +#include "base/logging.h"
|
| #include "base/memory/scoped_ptr.h"
|
| #include "base/platform_file.h"
|
| #include "base/sequenced_task_runner.h"
|
| +#include "base/strings/string_util.h"
|
| #include "base/threading/thread.h"
|
| #include "base/time/time.h"
|
| #include "content/browser/child_process_security_policy_impl.h"
|
| #include "content/browser/fileapi/browser_file_system_helper.h"
|
| #include "content/browser/fileapi/chrome_blob_storage_context.h"
|
| +#include "content/browser/streams/stream_registry.h"
|
| #include "content/common/fileapi/file_system_messages.h"
|
| #include "content/common/fileapi/webblob_messages.h"
|
| #include "content/public/browser/user_metrics.h"
|
| @@ -61,29 +64,35 @@ FileAPIMessageFilter::FileAPIMessageFilter(
|
| int process_id,
|
| net::URLRequestContextGetter* request_context_getter,
|
| fileapi::FileSystemContext* file_system_context,
|
| - ChromeBlobStorageContext* blob_storage_context)
|
| + ChromeBlobStorageContext* blob_storage_context,
|
| + StreamContext* stream_context)
|
| : process_id_(process_id),
|
| context_(file_system_context),
|
| request_context_getter_(request_context_getter),
|
| request_context_(NULL),
|
| - blob_storage_context_(blob_storage_context) {
|
| + blob_storage_context_(blob_storage_context),
|
| + stream_context_(stream_context) {
|
| DCHECK(context_);
|
| DCHECK(request_context_getter_.get());
|
| DCHECK(blob_storage_context);
|
| + DCHECK(stream_context);
|
| }
|
|
|
| FileAPIMessageFilter::FileAPIMessageFilter(
|
| int process_id,
|
| net::URLRequestContext* request_context,
|
| fileapi::FileSystemContext* file_system_context,
|
| - ChromeBlobStorageContext* blob_storage_context)
|
| + ChromeBlobStorageContext* blob_storage_context,
|
| + StreamContext* stream_context)
|
| : process_id_(process_id),
|
| context_(file_system_context),
|
| request_context_(request_context),
|
| - blob_storage_context_(blob_storage_context) {
|
| + blob_storage_context_(blob_storage_context),
|
| + stream_context_(stream_context) {
|
| DCHECK(context_);
|
| DCHECK(request_context_);
|
| DCHECK(blob_storage_context);
|
| + DCHECK(stream_context);
|
| }
|
|
|
| void FileAPIMessageFilter::OnChannelConnected(int32 peer_pid) {
|
| @@ -104,12 +113,16 @@ void FileAPIMessageFilter::OnChannelClosing() {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| BrowserMessageFilter::OnChannelClosing();
|
|
|
| - // Unregister all the blob URLs that are previously registered in this
|
| - // process.
|
| + // Unregister all the blob and stream URLs that are previously registered in
|
| + // this process.
|
| for (base::hash_set<std::string>::const_iterator iter = blob_urls_.begin();
|
| iter != blob_urls_.end(); ++iter) {
|
| blob_storage_context_->controller()->RemoveBlob(GURL(*iter));
|
| }
|
| + for (base::hash_set<std::string>::const_iterator iter = stream_urls_.begin();
|
| + iter != stream_urls_.end(); ++iter) {
|
| + stream_context_->registry()->UnregisterStream(GURL(*iter));
|
| + }
|
|
|
| in_transit_snapshot_files_.clear();
|
|
|
| @@ -168,13 +181,22 @@ bool FileAPIMessageFilter::OnMessageReceived(
|
| IPC_MESSAGE_HANDLER(FileSystemHostMsg_DidUpdate, OnDidUpdate)
|
| IPC_MESSAGE_HANDLER(FileSystemHostMsg_SyncGetPlatformPath,
|
| OnSyncGetPlatformPath)
|
| - IPC_MESSAGE_HANDLER(BlobHostMsg_StartBuildingBlob, OnStartBuildingBlob)
|
| - IPC_MESSAGE_HANDLER(BlobHostMsg_AppendBlobDataItem, OnAppendBlobDataItem)
|
| + IPC_MESSAGE_HANDLER(BlobHostMsg_StartBuilding, OnStartBuildingBlob)
|
| + IPC_MESSAGE_HANDLER(BlobHostMsg_AppendBlobDataItem,
|
| + OnAppendBlobDataItemToBlob)
|
| IPC_MESSAGE_HANDLER(BlobHostMsg_SyncAppendSharedMemory,
|
| - OnAppendSharedMemory)
|
| - IPC_MESSAGE_HANDLER(BlobHostMsg_FinishBuildingBlob, OnFinishBuildingBlob)
|
| - IPC_MESSAGE_HANDLER(BlobHostMsg_CloneBlob, OnCloneBlob)
|
| - IPC_MESSAGE_HANDLER(BlobHostMsg_RemoveBlob, OnRemoveBlob)
|
| + OnAppendSharedMemoryToBlob)
|
| + IPC_MESSAGE_HANDLER(BlobHostMsg_FinishBuilding, OnFinishBuildingBlob)
|
| + IPC_MESSAGE_HANDLER(BlobHostMsg_Clone, OnCloneBlob)
|
| + IPC_MESSAGE_HANDLER(BlobHostMsg_Remove, OnRemoveBlob)
|
| + IPC_MESSAGE_HANDLER(StreamHostMsg_StartBuilding, OnStartBuildingStream)
|
| + IPC_MESSAGE_HANDLER(StreamHostMsg_AppendBlobDataItem,
|
| + OnAppendBlobDataItemToStream)
|
| + IPC_MESSAGE_HANDLER(StreamHostMsg_SyncAppendSharedMemory,
|
| + OnAppendSharedMemoryToStream)
|
| + IPC_MESSAGE_HANDLER(StreamHostMsg_FinishBuilding, OnFinishBuildingStream)
|
| + IPC_MESSAGE_HANDLER(StreamHostMsg_Clone, OnCloneStream)
|
| + IPC_MESSAGE_HANDLER(StreamHostMsg_Remove, OnRemoveStream)
|
| IPC_MESSAGE_UNHANDLED(handled = false)
|
| IPC_END_MESSAGE_MAP_EX()
|
| return handled;
|
| @@ -520,7 +542,7 @@ void FileAPIMessageFilter::OnStartBuildingBlob(const GURL& url) {
|
| blob_urls_.insert(url.spec());
|
| }
|
|
|
| -void FileAPIMessageFilter::OnAppendBlobDataItem(
|
| +void FileAPIMessageFilter::OnAppendBlobDataItemToBlob(
|
| const GURL& url, const BlobData::Item& item) {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| if (item.type() == BlobData::Item::TYPE_FILE_FILESYSTEM) {
|
| @@ -545,7 +567,7 @@ void FileAPIMessageFilter::OnAppendBlobDataItem(
|
| blob_storage_context_->controller()->AppendBlobDataItem(url, item);
|
| }
|
|
|
| -void FileAPIMessageFilter::OnAppendSharedMemory(
|
| +void FileAPIMessageFilter::OnAppendSharedMemoryToBlob(
|
| const GURL& url, base::SharedMemoryHandle handle, size_t buffer_size) {
|
| DCHECK(base::SharedMemory::IsHandleValid(handle));
|
| if (!buffer_size) {
|
| @@ -587,6 +609,101 @@ void FileAPIMessageFilter::OnRemoveBlob(const GURL& url) {
|
| blob_urls_.erase(url.spec());
|
| }
|
|
|
| +void FileAPIMessageFilter::OnStartBuildingStream(
|
| + const GURL& url, const std::string& content_type) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + // Only an internal Blob URL is expected here. See the BlobURL of the Blink.
|
| + if (!StartsWithASCII(
|
| + url.path(), "blobinternal%3A///", true /* case_sensitive */)) {
|
| + NOTREACHED() << "Malformed Stream URL: " << url.spec();
|
| + BadMessageReceived();
|
| + return;
|
| + }
|
| + // Use an empty security origin for now. Stream accepts a security origin
|
| + // but how it's handled is not fixed yet.
|
| + new Stream(stream_context_->registry(),
|
| + NULL /* write_observer */,
|
| + url);
|
| + stream_urls_.insert(url.spec());
|
| +}
|
| +
|
| +void FileAPIMessageFilter::OnAppendBlobDataItemToStream(
|
| + const GURL& url, const BlobData::Item& item) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| +
|
| + scoped_refptr<Stream> stream(GetStreamForURL(url));
|
| + if (!stream.get()) {
|
| + NOTREACHED();
|
| + return;
|
| + }
|
| +
|
| + // Data for stream is delivered as TYPE_BYTES item.
|
| + if (item.type() != BlobData::Item::TYPE_BYTES) {
|
| + BadMessageReceived();
|
| + return;
|
| + }
|
| + stream->AddData(item.bytes(), item.length());
|
| +}
|
| +
|
| +void FileAPIMessageFilter::OnAppendSharedMemoryToStream(
|
| + const GURL& url, base::SharedMemoryHandle handle, size_t buffer_size) {
|
| + DCHECK(base::SharedMemory::IsHandleValid(handle));
|
| + if (!buffer_size) {
|
| + BadMessageReceived();
|
| + return;
|
| + }
|
| +#if defined(OS_WIN)
|
| + base::SharedMemory shared_memory(handle, true, PeerHandle());
|
| +#else
|
| + base::SharedMemory shared_memory(handle, true);
|
| +#endif
|
| + if (!shared_memory.Map(buffer_size)) {
|
| + OnRemoveStream(url);
|
| + return;
|
| + }
|
| +
|
| + scoped_refptr<Stream> stream(GetStreamForURL(url));
|
| + if (!stream.get()) {
|
| + NOTREACHED();
|
| + return;
|
| + }
|
| +
|
| + stream->AddData(static_cast<char*>(shared_memory.memory()), buffer_size);
|
| +}
|
| +
|
| +void FileAPIMessageFilter::OnFinishBuildingStream(const GURL& url) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + scoped_refptr<Stream> stream(GetStreamForURL(url));
|
| + if (stream.get())
|
| + stream->Finalize();
|
| + else
|
| + NOTREACHED();
|
| +}
|
| +
|
| +void FileAPIMessageFilter::OnCloneStream(
|
| + const GURL& url, const GURL& src_url) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + if (!GetStreamForURL(src_url)) {
|
| + NOTREACHED();
|
| + return;
|
| + }
|
| +
|
| + stream_context_->registry()->CloneStream(url, src_url);
|
| + stream_urls_.insert(url.spec());
|
| +}
|
| +
|
| +void FileAPIMessageFilter::OnRemoveStream(const GURL& url) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| +
|
| + if (!GetStreamForURL(url).get()) {
|
| + NOTREACHED();
|
| + return;
|
| + }
|
| +
|
| + stream_context_->registry()->UnregisterStream(url);
|
| + stream_urls_.erase(url.spec());
|
| +}
|
| +
|
| void FileAPIMessageFilter::DidFinish(int request_id,
|
| base::PlatformFileError result) {
|
| if (result == base::PLATFORM_FILE_OK)
|
| @@ -739,4 +856,8 @@ bool FileAPIMessageFilter::HasPermissionsForFile(
|
| permissions, error);
|
| }
|
|
|
| +scoped_refptr<Stream> FileAPIMessageFilter::GetStreamForURL(const GURL& url) {
|
| + return stream_context_->registry()->GetStream(url);
|
| +}
|
| +
|
| } // namespace content
|
|
|