| 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 febb62a3401aedf2b9858d73f26efe50f422cd4e..9f8ac50fca5e00b569f3911c47285c50d232baa7 100644
|
| --- a/content/browser/fileapi/fileapi_message_filter.cc
|
| +++ b/content/browser/fileapi/fileapi_message_filter.cc
|
| @@ -12,16 +12,19 @@
|
| #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.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"
|
| #include "googleurl/src/gurl.h"
|
| #include "ipc/ipc_platform_file.h"
|
| +#include "net/base/io_buffer.h"
|
| #include "net/base/mime_util.h"
|
| #include "net/url_request/url_request_context.h"
|
| #include "net/url_request/url_request_context_getter.h"
|
| @@ -64,29 +67,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) {
|
| @@ -100,6 +109,10 @@ void FileAPIMessageFilter::OnChannelConnected(int32 peer_pid) {
|
| }
|
| }
|
|
|
| +scoped_refptr<Stream> FileAPIMessageFilter::GetStreamForURL(const GURL& url) {
|
| + return stream_context_->registry()->GetStream(url);
|
| +}
|
| +
|
| void FileAPIMessageFilter::OnChannelClosing() {
|
| BrowserMessageFilter::OnChannelClosing();
|
|
|
| @@ -107,7 +120,12 @@ void FileAPIMessageFilter::OnChannelClosing() {
|
| // 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));
|
| + const GURL url(*iter);
|
| + // Intercept stream URLs.
|
| + if (GetStreamForURL(url))
|
| + stream_context_->registry()->UnregisterStream(url);
|
| + else
|
| + blob_storage_context_->controller()->RemoveBlob(url);
|
| }
|
|
|
| in_transit_snapshot_files_.clear();
|
| @@ -165,6 +183,7 @@ bool FileAPIMessageFilter::OnMessageReceived(
|
| IPC_MESSAGE_HANDLER(FileSystemHostMsg_SyncGetPlatformPath,
|
| OnSyncGetPlatformPath)
|
| IPC_MESSAGE_HANDLER(BlobHostMsg_StartBuildingBlob, OnStartBuildingBlob)
|
| + IPC_MESSAGE_HANDLER(BlobHostMsg_StartBuildingStream, OnStartBuildingStream)
|
| IPC_MESSAGE_HANDLER(BlobHostMsg_AppendBlobDataItem, OnAppendBlobDataItem)
|
| IPC_MESSAGE_HANDLER(BlobHostMsg_SyncAppendSharedMemory,
|
| OnAppendSharedMemory)
|
| @@ -516,9 +535,42 @@ void FileAPIMessageFilter::OnStartBuildingBlob(const GURL& url) {
|
| blob_urls_.insert(url.spec());
|
| }
|
|
|
| +// Currently |content_type| is ignored inside Chromium.
|
| +//
|
| +// TODO(tyoshino): Set |content_type| to the stream.
|
| +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.
|
| + DCHECK(StartsWithASCII(
|
| + url.path(), "blobinternal:///", true /* case_sensitive*/));
|
| + // 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 */,
|
| + GURL() /* security_origin */,
|
| + url);
|
| + blob_urls_.insert(url.spec());
|
| +}
|
| +
|
| void FileAPIMessageFilter::OnAppendBlobDataItem(
|
| const GURL& url, const BlobData::Item& item) {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| +
|
| + scoped_refptr<Stream> stream(GetStreamForURL(url));
|
| + if (stream.get()) {
|
| + // Data for stream is delivered as TYPE_BYTES item.
|
| + if (item.type() != BlobData::Item::TYPE_BYTES) {
|
| + BadMessageReceived();
|
| + return;
|
| + }
|
| + scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(item.length()));
|
| + memcpy(buffer->data(), item.bytes(), item.length());
|
| + stream->AddData(buffer, item.length());
|
| +
|
| + return;
|
| + }
|
| +
|
| if (item.type() == BlobData::Item::TYPE_FILE_FILESYSTEM) {
|
| base::PlatformFileError error;
|
| FileSystemURL filesystem_url(context_->CrackURL(item.url()));
|
| @@ -558,6 +610,15 @@ void FileAPIMessageFilter::OnAppendSharedMemory(
|
| return;
|
| }
|
|
|
| + scoped_refptr<Stream> stream(GetStreamForURL(url));
|
| + if (stream.get()) {
|
| + scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(buffer_size));
|
| + memcpy(buffer->data(), static_cast<char*>(shared_memory.memory()),
|
| + buffer_size);
|
| + stream->AddData(buffer, buffer_size);
|
| + return;
|
| + }
|
| +
|
| BlobData::Item item;
|
| item.SetToSharedBytes(static_cast<char*>(shared_memory.memory()),
|
| buffer_size);
|
| @@ -567,19 +628,29 @@ void FileAPIMessageFilter::OnAppendSharedMemory(
|
| void FileAPIMessageFilter::OnFinishBuildingBlob(
|
| const GURL& url, const std::string& content_type) {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| - blob_storage_context_->controller()->FinishBuildingBlob(url, content_type);
|
| + scoped_refptr<Stream> stream(GetStreamForURL(url));
|
| + if (stream.get())
|
| + stream->Finalize();
|
| + else
|
| + blob_storage_context_->controller()->FinishBuildingBlob(url, content_type);
|
| }
|
|
|
| void FileAPIMessageFilter::OnCloneBlob(
|
| const GURL& url, const GURL& src_url) {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| - blob_storage_context_->controller()->CloneBlob(url, src_url);
|
| + if (GetStreamForURL(src_url))
|
| + stream_context_->registry()->CloneStream(url, src_url);
|
| + else
|
| + blob_storage_context_->controller()->CloneBlob(url, src_url);
|
| blob_urls_.insert(url.spec());
|
| }
|
|
|
| void FileAPIMessageFilter::OnRemoveBlob(const GURL& url) {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| - blob_storage_context_->controller()->RemoveBlob(url);
|
| + if (GetStreamForURL(url).get())
|
| + stream_context_->registry()->UnregisterStream(url);
|
| + else
|
| + blob_storage_context_->controller()->RemoveBlob(url);
|
| blob_urls_.erase(url.spec());
|
| }
|
|
|
|
|