1eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Copyright 2013 The Chromium Authors. All rights reserved. 2eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// found in the LICENSE file. 4eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/browser/fileapi/fileapi_message_filter.h" 6eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 7eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <string> 8eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <vector> 9eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 10eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/memory/ref_counted.h" 112385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "base/memory/shared_memory.h" 129ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 132385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "base/process/process.h" 14bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "content/browser/child_process_security_policy_impl.h" 15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/browser/fileapi/chrome_blob_storage_context.h" 162385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "content/browser/streams/stream_registry.h" 17bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "content/common/fileapi/file_system_messages.h" 18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/common/fileapi/webblob_messages.h" 19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/public/browser/browser_thread.h" 20eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/public/common/common_param_traits.h" 21eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/public/test/mock_render_process_host.h" 22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/public/test/test_browser_context.h" 23eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/public/test/test_browser_thread.h" 244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/test/test_file_system_context.h" 252385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "net/base/io_buffer.h" 261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/blob/blob_storage_context.h" 271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_context.h" 281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/common/blob/blob_data.h" 29eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "testing/gtest/include/gtest/gtest.h" 30eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace content { 32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 332385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochnamespace { 342385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 352385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochconst char kFakeBlobInternalUrlSpec[] = 362385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch "blob:blobinternal%3A///dc83ede4-9bbd-453b-be2e-60fd623fcc93"; 372385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochconst char kFakeBlobInternalUrlSpec2[] = 382385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch "blob:blobinternal%3A///d28ae2e7-d233-4dda-9598-d135fe5d403e"; 392385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 402385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochconst char kFakeContentType[] = "fake/type"; 412385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 422385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch} // namespace 432385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass FileAPIMessageFilterTest : public testing::Test { 45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch public: 46eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch FileAPIMessageFilterTest() 47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch : io_browser_thread_(BrowserThread::IO, &message_loop_) { 48eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch protected: 51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual void SetUp() OVERRIDE { 52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch file_system_context_ = 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CreateFileSystemContextForTesting(NULL, base::FilePath()); 54bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 5503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) std::vector<storage::FileSystemType> types; 56bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch file_system_context_->GetFileSystemTypes(&types); 57bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch for (size_t i = 0; i < types.size(); ++i) { 5803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ChildProcessSecurityPolicyImpl::GetInstance() 5903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ->RegisterFileSystemPermissionPolicy( 60bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch types[i], 6103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) storage::FileSystemContext::GetPermissionPolicy(types[i])); 62bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch } 632385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 642385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch stream_context_ = StreamContext::GetFor(&browser_context_); 652385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch blob_storage_context_ = ChromeBlobStorageContext::GetFor(&browser_context_); 662385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 672385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch filter_ = new FileAPIMessageFilter( 682385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 0 /* process_id */, 692385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch browser_context_.GetRequestContext(), 702385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch file_system_context_.get(), 712385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch blob_storage_context_, 722385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch stream_context_); 732385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 742385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch // Complete initialization. 752385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch message_loop_.RunUntilIdle(); 762385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch } 772385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 78eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::MessageLoop message_loop_; 79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TestBrowserThread io_browser_thread_; 80eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 81eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TestBrowserContext browser_context_; 8203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) scoped_refptr<storage::FileSystemContext> file_system_context_; 832385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch StreamContext* stream_context_; 842385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch ChromeBlobStorageContext* blob_storage_context_; 852385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 862385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch scoped_refptr<FileAPIMessageFilter> filter_; 87eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}; 88eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 89bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben MurdochTEST_F(FileAPIMessageFilterTest, CloseChannelWithInflightRequest) { 90bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch scoped_refptr<FileAPIMessageFilter> filter( 91bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch new FileAPIMessageFilter( 92bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 0 /* process_id */, 93bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch browser_context_.GetRequestContext(), 94bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch file_system_context_.get(), 952385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch ChromeBlobStorageContext::GetFor(&browser_context_), 962385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch StreamContext::GetFor(&browser_context_))); 97bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch filter->OnChannelConnected(0); 98bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 99bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // Complete initialization. 100bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch message_loop_.RunUntilIdle(); 101bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 102bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch int request_id = 0; 103bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch const GURL kUrl("filesystem:http://example.com/temporary/foo"); 104bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch FileSystemHostMsg_ReadMetadata read_metadata(request_id++, kUrl); 105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_TRUE(filter->OnMessageReceived(read_metadata)); 106bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 107bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // Close the filter while it has inflight request. 108bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch filter->OnChannelClosing(); 109bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 110bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // This shouldn't cause DCHECK failure. 111bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch message_loop_.RunUntilIdle(); 112bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch} 113bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 114bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben MurdochTEST_F(FileAPIMessageFilterTest, MultipleFilters) { 115bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch scoped_refptr<FileAPIMessageFilter> filter1( 116bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch new FileAPIMessageFilter( 117bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 0 /* process_id */, 118bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch browser_context_.GetRequestContext(), 119bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch file_system_context_.get(), 1202385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch ChromeBlobStorageContext::GetFor(&browser_context_), 1212385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch StreamContext::GetFor(&browser_context_))); 122bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch scoped_refptr<FileAPIMessageFilter> filter2( 123bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch new FileAPIMessageFilter( 124bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 1 /* process_id */, 125bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch browser_context_.GetRequestContext(), 126bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch file_system_context_.get(), 1272385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch ChromeBlobStorageContext::GetFor(&browser_context_), 1282385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch StreamContext::GetFor(&browser_context_))); 129bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch filter1->OnChannelConnected(0); 130bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch filter2->OnChannelConnected(1); 131bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 132bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // Complete initialization. 133bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch message_loop_.RunUntilIdle(); 134bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 135bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch int request_id = 0; 136bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch const GURL kUrl("filesystem:http://example.com/temporary/foo"); 137bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch FileSystemHostMsg_ReadMetadata read_metadata(request_id++, kUrl); 138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_TRUE(filter1->OnMessageReceived(read_metadata)); 139bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 140bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // Close the other filter before the request for filter1 is processed. 141bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch filter2->OnChannelClosing(); 142bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 143bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // This shouldn't cause DCHECK failure. 144bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch message_loop_.RunUntilIdle(); 145bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch} 146bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 1472385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen MurdochTEST_F(FileAPIMessageFilterTest, BuildEmptyStream) { 1482385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch StreamRegistry* stream_registry = stream_context_->registry(); 1492385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 1502385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch const GURL kUrl(kFakeBlobInternalUrlSpec); 1512385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch const GURL kDifferentUrl("blob:barfoo"); 1522385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 1532385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch EXPECT_EQ(NULL, stream_registry->GetStream(kUrl).get()); 1542385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 1552385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch StreamHostMsg_StartBuilding start_message(kUrl, kFakeContentType); 156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_TRUE(filter_->OnMessageReceived(start_message)); 1572385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 1582385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch const int kBufferSize = 10; 1592385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kBufferSize)); 1602385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch int bytes_read = 0; 1612385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 1622385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch scoped_refptr<Stream> stream = stream_registry->GetStream(kUrl); 1632385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch // Stream becomes available for read right after registration. 1642385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch ASSERT_FALSE(stream.get() == NULL); 1652385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch EXPECT_EQ(Stream::STREAM_EMPTY, 1662385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch stream->ReadRawData(buffer.get(), kBufferSize, &bytes_read)); 1672385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch EXPECT_EQ(0, bytes_read); 1682385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch stream = NULL; 1692385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 1702385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch StreamHostMsg_FinishBuilding finish_message(kUrl); 171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_TRUE(filter_->OnMessageReceived(finish_message)); 1722385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 1732385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch stream = stream_registry->GetStream(kUrl); 1742385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch ASSERT_FALSE(stream.get() == NULL); 1752385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch EXPECT_EQ(Stream::STREAM_EMPTY, 1762385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch stream->ReadRawData(buffer.get(), kBufferSize, &bytes_read)); 1772385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch EXPECT_EQ(0, bytes_read); 1782385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 1792385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch // Run loop to finish transfer. 1802385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch message_loop_.RunUntilIdle(); 1812385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 1822385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch EXPECT_EQ(Stream::STREAM_COMPLETE, 1832385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch stream->ReadRawData(buffer.get(), kBufferSize, &bytes_read)); 1842385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch EXPECT_EQ(0, bytes_read); 1852385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 1862385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch // Nothing should be returned for a URL we didn't use. 1872385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch EXPECT_TRUE(stream_registry->GetStream(kDifferentUrl).get() == NULL); 1882385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch} 1892385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 1902385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen MurdochTEST_F(FileAPIMessageFilterTest, BuildNonEmptyStream) { 1912385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch StreamRegistry* stream_registry = stream_context_->registry(); 1922385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 1932385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch const GURL kUrl(kFakeBlobInternalUrlSpec); 1942385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 1952385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch EXPECT_EQ(NULL, stream_registry->GetStream(kUrl).get()); 1962385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 1972385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch StreamHostMsg_StartBuilding start_message(kUrl, kFakeContentType); 198cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_TRUE(filter_->OnMessageReceived(start_message)); 1992385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 20003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) storage::BlobData::Item item; 2012385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch const std::string kFakeData = "foobarbaz"; 2022385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch item.SetToBytes(kFakeData.data(), kFakeData.size()); 2032385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch StreamHostMsg_AppendBlobDataItem append_message(kUrl, item); 204cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_TRUE(filter_->OnMessageReceived(append_message)); 2052385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 2062385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch StreamHostMsg_FinishBuilding finish_message(kUrl); 207cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_TRUE(filter_->OnMessageReceived(finish_message)); 2082385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 2092385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch // Run loop to finish transfer and commit finalize command. 2102385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch message_loop_.RunUntilIdle(); 2112385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 2122385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kFakeData.size())); 2132385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch int bytes_read = 0; 2142385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 2152385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch scoped_refptr<Stream> stream = stream_registry->GetStream(kUrl); 2162385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch ASSERT_FALSE(stream.get() == NULL); 2172385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 2182385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch EXPECT_EQ(Stream::STREAM_HAS_DATA, 2192385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch stream->ReadRawData(buffer.get(), kFakeData.size(), &bytes_read)); 2202385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch EXPECT_EQ(kFakeData.size(), static_cast<size_t>(bytes_read)); 2212385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch EXPECT_EQ(kFakeData, std::string(buffer->data(), bytes_read)); 2222385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 2232385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch EXPECT_EQ(Stream::STREAM_COMPLETE, 2242385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch stream->ReadRawData(buffer.get(), kFakeData.size(), &bytes_read)); 2252385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch EXPECT_EQ(0, bytes_read); 2262385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch} 2272385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 2282385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen MurdochTEST_F(FileAPIMessageFilterTest, BuildStreamWithSharedMemory) { 2292385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch StreamRegistry* stream_registry = stream_context_->registry(); 2302385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 2312385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch const GURL kUrl(kFakeBlobInternalUrlSpec); 2322385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 2332385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch EXPECT_EQ(NULL, stream_registry->GetStream(kUrl).get()); 2342385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 2352385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch // For win, we need to set valid PID to the filter. 2362385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch // OnAppendSharedMemoryToStream passes the peer process's handle to 2372385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch // SharedMemory's constructor. If it's incorrect, DuplicateHandle won't work 2382385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch // correctly. 2394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) filter_->set_peer_pid_for_testing(base::Process::Current().pid()); 2402385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 2412385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch StreamHostMsg_StartBuilding start_message(kUrl, kFakeContentType); 242cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_TRUE(filter_->OnMessageReceived(start_message)); 2432385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 2442385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch const std::string kFakeData = "foobarbaz"; 2452385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 2462385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory); 2472385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch ASSERT_TRUE(shared_memory->CreateAndMapAnonymous(kFakeData.size())); 2482385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch memcpy(shared_memory->memory(), kFakeData.data(), kFakeData.size()); 2492385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch StreamHostMsg_SyncAppendSharedMemory append_message( 2502385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch kUrl, shared_memory->handle(), kFakeData.size()); 251cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_TRUE(filter_->OnMessageReceived(append_message)); 2522385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 2532385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch StreamHostMsg_FinishBuilding finish_message(kUrl); 254cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_TRUE(filter_->OnMessageReceived(finish_message)); 2552385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 2562385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch // Run loop to finish transfer and commit finalize command. 2572385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch message_loop_.RunUntilIdle(); 2582385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 2592385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kFakeData.size())); 2602385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch int bytes_read = 0; 2612385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 2622385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch scoped_refptr<Stream> stream = stream_registry->GetStream(kUrl); 2632385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch ASSERT_FALSE(stream.get() == NULL); 2642385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 2652385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch EXPECT_EQ(Stream::STREAM_HAS_DATA, 2662385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch stream->ReadRawData(buffer.get(), kFakeData.size(), &bytes_read)); 2672385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch EXPECT_EQ(kFakeData.size(), static_cast<size_t>(bytes_read)); 2682385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch EXPECT_EQ(kFakeData, std::string(buffer->data(), bytes_read)); 2692385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 2702385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch EXPECT_EQ(Stream::STREAM_COMPLETE, 2712385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch stream->ReadRawData(buffer.get(), kFakeData.size(), &bytes_read)); 2722385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch EXPECT_EQ(0, bytes_read); 2732385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch} 2742385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 2752385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen MurdochTEST_F(FileAPIMessageFilterTest, BuildStreamAndCallOnChannelClosing) { 2762385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch StreamRegistry* stream_registry = stream_context_->registry(); 2772385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 2782385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch const GURL kUrl(kFakeBlobInternalUrlSpec); 2792385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 2802385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch StreamHostMsg_StartBuilding start_message(kUrl, kFakeContentType); 281cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_TRUE(filter_->OnMessageReceived(start_message)); 2822385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 2832385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch ASSERT_FALSE(stream_registry->GetStream(kUrl).get() == NULL); 2842385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 2852385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch filter_->OnChannelClosing(); 2862385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 2872385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch ASSERT_EQ(NULL, stream_registry->GetStream(kUrl).get()); 2882385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch} 2892385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 2902385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen MurdochTEST_F(FileAPIMessageFilterTest, CloneStream) { 2912385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch StreamRegistry* stream_registry = stream_context_->registry(); 2922385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 2932385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch const GURL kUrl(kFakeBlobInternalUrlSpec); 2942385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch const GURL kDestUrl(kFakeBlobInternalUrlSpec2); 2952385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 2962385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch StreamHostMsg_StartBuilding start_message(kUrl, kFakeContentType); 297cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_TRUE(filter_->OnMessageReceived(start_message)); 2982385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 2992385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch StreamHostMsg_Clone clone_message(kDestUrl, kUrl); 300cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_TRUE(filter_->OnMessageReceived(clone_message)); 3012385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 3022385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch ASSERT_FALSE(stream_registry->GetStream(kUrl).get() == NULL); 3032385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch ASSERT_FALSE(stream_registry->GetStream(kDestUrl).get() == NULL); 3042385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch} 3052385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 3062385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch} // namespace content 307