summaryrefslogtreecommitdiffstats
path: root/webkit/blob
diff options
context:
space:
mode:
authorhashimoto@chromium.org <hashimoto@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-22 09:24:30 +0000
committerhashimoto@chromium.org <hashimoto@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-22 09:24:30 +0000
commit1f43442987e3bde6d910b00df216263814fd3626 (patch)
tree7480c9199792acdd4a1945c98875133dc945a025 /webkit/blob
parentd5588b101e0a79dd7f50c06012dd064d3bab9ba7 (diff)
downloadchromium_src-1f43442987e3bde6d910b00df216263814fd3626.zip
chromium_src-1f43442987e3bde6d910b00df216263814fd3626.tar.gz
chromium_src-1f43442987e3bde6d910b00df216263814fd3626.tar.bz2
Support filesystem files from BlobURLRequestJob
BlobURLRequestJob's ctor takes FileSystemContext to create FileSystemFileStreamReader. BUG=141835 TEST=content_unittests --gtest_filter="BlobURLRequestJobTest.*" TBR=jam@chromium.org for content change Review URL: https://chromiumcodereview.appspot.com/11103027 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@163245 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/blob')
-rw-r--r--webkit/blob/blob_url_request_job.cc75
-rw-r--r--webkit/blob/blob_url_request_job.h18
-rw-r--r--webkit/blob/blob_url_request_job_factory.cc8
-rw-r--r--webkit/blob/blob_url_request_job_factory.h11
-rw-r--r--webkit/blob/blob_url_request_job_unittest.cc491
-rw-r--r--webkit/blob/mock_blob_url_request_context.cc14
-rw-r--r--webkit/blob/mock_blob_url_request_context.h6
7 files changed, 345 insertions, 278 deletions
diff --git a/webkit/blob/blob_url_request_job.cc b/webkit/blob/blob_url_request_job.cc
index 07a4fc4..279c1ee 100644
--- a/webkit/blob/blob_url_request_job.cc
+++ b/webkit/blob/blob_url_request_job.cc
@@ -22,6 +22,8 @@
#include "net/url_request/url_request_error_job.h"
#include "net/url_request/url_request_status.h"
#include "webkit/blob/local_file_stream_reader.h"
+#include "webkit/fileapi/file_system_context.h"
+#include "webkit/fileapi/file_system_url.h"
namespace webkit_blob {
@@ -44,16 +46,28 @@ const char kHTTPRequestedRangeNotSatisfiableText[] =
"Requested Range Not Satisfiable";
const char kHTTPInternalErrorText[] = "Internal Server Error";
+bool IsFileType(BlobData::Item::Type type) {
+ switch (type) {
+ case BlobData::Item::TYPE_FILE:
+ case BlobData::Item::TYPE_FILE_FILESYSTEM:
+ return true;
+ default:
+ return false;
+ }
+}
+
} // namespace
BlobURLRequestJob::BlobURLRequestJob(
net::URLRequest* request,
net::NetworkDelegate* network_delegate,
BlobData* blob_data,
+ fileapi::FileSystemContext* file_system_context,
base::MessageLoopProxy* file_thread_proxy)
: net::URLRequestJob(request, network_delegate),
ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
blob_data_(blob_data),
+ file_system_context_(file_system_context),
file_thread_proxy_(file_thread_proxy),
total_size_(0),
remaining_bytes_(0),
@@ -177,7 +191,7 @@ void BlobURLRequestJob::CountSize() {
for (size_t i = 0; i < blob_data_->items().size(); ++i) {
const BlobData::Item& item = blob_data_->items().at(i);
- if (item.type() == BlobData::Item::TYPE_FILE) {
+ if (IsFileType(item.type())) {
++pending_get_file_info_count_;
GetFileStreamReader(i)->GetLength(
base::Bind(&BlobURLRequestJob::DidGetFileItemLength,
@@ -235,7 +249,7 @@ void BlobURLRequestJob::DidGetFileItemLength(size_t index, int64 result) {
DCHECK_LT(index, blob_data_->items().size());
const BlobData::Item& item = blob_data_->items().at(index);
- DCHECK(item.type() == BlobData::Item::TYPE_FILE);
+ DCHECK(IsFileType(item.type()));
// If item length is -1, we need to use the file size being resolved
// in the real time.
@@ -269,7 +283,7 @@ void BlobURLRequestJob::Seek(int64 offset) {
// Adjust the offset of the first stream if it is of file type.
const BlobData::Item& item = blob_data_->items().at(current_item_index_);
- if (item.type() == BlobData::Item::TYPE_FILE) {
+ if (IsFileType(item.type())) {
DeleteCurrentFileReader();
CreateFileStreamReader(current_item_index_, offset);
}
@@ -298,19 +312,14 @@ bool BlobURLRequestJob::ReadItem() {
// Do the reading.
const BlobData::Item& item = blob_data_->items().at(current_item_index_);
- switch (item.type()) {
- case BlobData::Item::TYPE_BYTES:
- return ReadBytesItem(item, bytes_to_read);
- case BlobData::Item::TYPE_FILE:
- return ReadFileItem(GetFileStreamReader(current_item_index_),
- bytes_to_read);
- case BlobData::Item::TYPE_FILE_FILESYSTEM:
- // TODO(kinuko): Support TYPE_FILE_FILESYSTEM case.
- // http://crbug.com/141835
- default:
- DCHECK(false);
- return false;
+ if (item.type() == BlobData::Item::TYPE_BYTES)
+ return ReadBytesItem(item, bytes_to_read);
+ if (IsFileType(item.type())) {
+ return ReadFileItem(GetFileStreamReader(current_item_index_),
+ bytes_to_read);
}
+ NOTREACHED();
+ return false;
}
void BlobURLRequestJob::AdvanceItem() {
@@ -351,7 +360,7 @@ bool BlobURLRequestJob::ReadBytesItem(const BlobData::Item& item,
return true;
}
-bool BlobURLRequestJob::ReadFileItem(LocalFileStreamReader* reader,
+bool BlobURLRequestJob::ReadFileItem(FileStreamReader* reader,
int bytes_to_read) {
DCHECK_GE(read_buf_->BytesRemaining(), bytes_to_read);
DCHECK(reader);
@@ -524,10 +533,10 @@ void BlobURLRequestJob::HeadersCompleted(int status_code,
NotifyHeadersComplete();
}
-LocalFileStreamReader* BlobURLRequestJob::GetFileStreamReader(size_t index) {
+FileStreamReader* BlobURLRequestJob::GetFileStreamReader(size_t index) {
DCHECK_LT(index, blob_data_->items().size());
const BlobData::Item& item = blob_data_->items().at(index);
- if (item.type() != BlobData::Item::TYPE_FILE)
+ if (!IsFileType(item.type()))
return NULL;
if (index_to_reader_.find(index) == index_to_reader_.end())
CreateFileStreamReader(index, 0);
@@ -539,15 +548,29 @@ void BlobURLRequestJob::CreateFileStreamReader(size_t index,
int64 additional_offset) {
DCHECK_LT(index, blob_data_->items().size());
const BlobData::Item& item = blob_data_->items().at(index);
- DCHECK_EQ(BlobData::Item::TYPE_FILE, item.type());
+ DCHECK(IsFileType(item.type()));
DCHECK_EQ(0U, index_to_reader_.count(index));
- // TODO(kinuko): Create appropriate FileStreamReader for TYPE_FILE_FILESYSTEM.
- // http://crbug.com/141835
- index_to_reader_[index] = new LocalFileStreamReader(
- file_thread_proxy_,
- item.path(),
- item.offset() + additional_offset,
- item.expected_modification_time());
+
+ FileStreamReader* reader = NULL;
+ switch (item.type()) {
+ case BlobData::Item::TYPE_FILE:
+ reader = new LocalFileStreamReader(
+ file_thread_proxy_,
+ item.path(),
+ item.offset() + additional_offset,
+ item.expected_modification_time());
+ break;
+ case BlobData::Item::TYPE_FILE_FILESYSTEM:
+ reader = file_system_context_->CreateFileStreamReader(
+ fileapi::FileSystemURL(item.url()),
+ item.offset() + additional_offset,
+ item.expected_modification_time());
+ break;
+ default:
+ NOTREACHED();
+ }
+ DCHECK(reader);
+ index_to_reader_[index] = reader;
}
} // namespace webkit_blob
diff --git a/webkit/blob/blob_url_request_job.h b/webkit/blob/blob_url_request_job.h
index c5bd2ed..437dd3b 100644
--- a/webkit/blob/blob_url_request_job.h
+++ b/webkit/blob/blob_url_request_job.h
@@ -18,6 +18,10 @@ class MessageLoopProxy;
struct PlatformFileInfo;
}
+namespace fileapi {
+class FileSystemContext;
+}
+
namespace net {
class DrainableIOBuffer;
class IOBuffer;
@@ -25,7 +29,7 @@ class IOBuffer;
namespace webkit_blob {
-class LocalFileStreamReader;
+class FileStreamReader;
// A request job that handles reading blob URLs.
class WEBKIT_STORAGE_EXPORT BlobURLRequestJob : public net::URLRequestJob {
@@ -33,6 +37,7 @@ class WEBKIT_STORAGE_EXPORT BlobURLRequestJob : public net::URLRequestJob {
BlobURLRequestJob(net::URLRequest* request,
net::NetworkDelegate* network_delegate,
BlobData* blob_data,
+ fileapi::FileSystemContext* file_system_context,
base::MessageLoopProxy* resolving_message_loop_proxy);
// net::URLRequestJob methods.
@@ -51,7 +56,7 @@ class WEBKIT_STORAGE_EXPORT BlobURLRequestJob : public net::URLRequestJob {
virtual ~BlobURLRequestJob();
private:
- typedef std::map<size_t, LocalFileStreamReader*> IndexToReaderMap;
+ typedef std::map<size_t, FileStreamReader*> IndexToReaderMap;
// For preparing for read: get the size, apply the range and perform seek.
void DidStart();
@@ -66,7 +71,7 @@ class WEBKIT_STORAGE_EXPORT BlobURLRequestJob : public net::URLRequestJob {
void AdvanceItem();
void AdvanceBytesRead(int result);
bool ReadBytesItem(const BlobData::Item& item, int bytes_to_read);
- bool ReadFileItem(LocalFileStreamReader* reader, int bytes_to_read);
+ bool ReadFileItem(FileStreamReader* reader, int bytes_to_read);
void DidReadFile(int result);
void DeleteCurrentFileReader();
@@ -78,15 +83,16 @@ class WEBKIT_STORAGE_EXPORT BlobURLRequestJob : public net::URLRequestJob {
void NotifyFailure(int);
void HeadersCompleted(int status_code, const std::string& status_txt);
- // Returns a LocalFileStreamReader for a blob item at |index|.
- // If the item at |index| is not of TYPE_FILE this returns NULL.
- LocalFileStreamReader* GetFileStreamReader(size_t index);
+ // Returns a FileStreamReader for a blob item at |index|.
+ // If the item at |index| is not of file this returns NULL.
+ FileStreamReader* GetFileStreamReader(size_t index);
// Creates a FileStreamReader for the item at |index| with additional_offset.
void CreateFileStreamReader(size_t index, int64 additional_offset);
base::WeakPtrFactory<BlobURLRequestJob> weak_factory_;
scoped_refptr<BlobData> blob_data_;
+ scoped_refptr<fileapi::FileSystemContext> file_system_context_;
scoped_refptr<base::MessageLoopProxy> file_thread_proxy_;
std::vector<int64> item_length_list_;
int64 total_size_;
diff --git a/webkit/blob/blob_url_request_job_factory.cc b/webkit/blob/blob_url_request_job_factory.cc
index 52f0874..f1dac83 100644
--- a/webkit/blob/blob_url_request_job_factory.cc
+++ b/webkit/blob/blob_url_request_job_factory.cc
@@ -11,15 +11,19 @@
#include "net/url_request/url_request_job_factory.h"
#include "webkit/blob/blob_storage_controller.h"
#include "webkit/blob/blob_url_request_job.h"
+#include "webkit/fileapi/file_system_context.h"
namespace webkit_blob {
BlobProtocolHandler::BlobProtocolHandler(
webkit_blob::BlobStorageController* blob_storage_controller,
+ fileapi::FileSystemContext* file_system_context,
base::MessageLoopProxy* loop_proxy)
: blob_storage_controller_(blob_storage_controller),
+ file_system_context_(file_system_context),
file_loop_proxy_(loop_proxy) {
- DCHECK(blob_storage_controller);
+ DCHECK(blob_storage_controller_);
+ DCHECK(file_system_context_);
DCHECK(file_loop_proxy_);
}
@@ -33,7 +37,7 @@ net::URLRequestJob* BlobProtocolHandler::MaybeCreateJob(
data = blob_storage_controller_->GetBlobDataFromUrl(request->url());
}
return new webkit_blob::BlobURLRequestJob(
- request, network_delegate, data, file_loop_proxy_);
+ request, network_delegate, data, file_system_context_, file_loop_proxy_);
}
scoped_refptr<webkit_blob::BlobData>
diff --git a/webkit/blob/blob_url_request_job_factory.h b/webkit/blob/blob_url_request_job_factory.h
index ddc5742..2473754 100644
--- a/webkit/blob/blob_url_request_job_factory.h
+++ b/webkit/blob/blob_url_request_job_factory.h
@@ -14,6 +14,10 @@ namespace base {
class MessageLoopProxy;
} // namespace base
+namespace fileapi {
+class FileSystemContext;
+} // namespace fileapi
+
namespace net {
class URLRequest;
} // namespace net
@@ -27,9 +31,9 @@ class WEBKIT_STORAGE_EXPORT BlobProtocolHandler
: public net::URLRequestJobFactory::ProtocolHandler {
public:
// |controller|'s lifetime should exceed the lifetime of the ProtocolHandler.
- explicit BlobProtocolHandler(
- BlobStorageController* blob_storage_controller,
- base::MessageLoopProxy* file_loop_proxy);
+ BlobProtocolHandler(BlobStorageController* blob_storage_controller,
+ fileapi::FileSystemContext* file_system_context,
+ base::MessageLoopProxy* file_loop_proxy);
virtual ~BlobProtocolHandler();
virtual net::URLRequestJob* MaybeCreateJob(
@@ -43,6 +47,7 @@ class WEBKIT_STORAGE_EXPORT BlobProtocolHandler
// No scoped_refptr because |blob_storage_controller_| is owned by the
// ProfileIOData, which also owns this ProtocolHandler.
BlobStorageController* const blob_storage_controller_;
+ const scoped_refptr<fileapi::FileSystemContext> file_system_context_;
const scoped_refptr<base::MessageLoopProxy> file_loop_proxy_;
DISALLOW_COPY_AND_ASSIGN(BlobProtocolHandler);
diff --git a/webkit/blob/blob_url_request_job_unittest.cc b/webkit/blob/blob_url_request_job_unittest.cc
index 3afde19..0c60162 100644
--- a/webkit/blob/blob_url_request_job_unittest.cc
+++ b/webkit/blob/blob_url_request_job_unittest.cc
@@ -2,41 +2,48 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include <stack>
-#include <utility>
-
#include "base/bind.h"
-#include "base/bind_helpers.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
-#include "base/message_loop_proxy.h"
+#include "base/message_loop.h"
#include "base/scoped_temp_dir.h"
-#include "base/synchronization/waitable_event.h"
-#include "base/threading/thread.h"
#include "base/time.h"
-#include "net/base/file_stream.h"
#include "net/base/io_buffer.h"
-#include "net/base/net_errors.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_response_headers.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"
-#include "net/url_request/url_request_error_job.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webkit/blob/blob_data.h"
#include "webkit/blob/blob_url_request_job.h"
+#include "webkit/fileapi/file_system_context.h"
+#include "webkit/fileapi/file_system_file_util.h"
+#include "webkit/fileapi/file_system_operation_context.h"
+#include "webkit/fileapi/file_system_task_runners.h"
+#include "webkit/fileapi/file_system_url.h"
+#include "webkit/fileapi/mock_file_system_options.h"
namespace webkit_blob {
-static const int kBufferSize = 1024;
-static const char kTestData1[] = "Hello";
-static const char kTestData2[] = "Here it is data.";
-static const char kTestFileData1[] = "0123456789";
-static const char kTestFileData2[] = "This is sample file.";
-static const char kTestContentType[] = "foo/bar";
-static const char kTestContentDisposition[] = "attachment; filename=foo.txt";
+namespace {
+
+const int kBufferSize = 1024;
+const char kTestData1[] = "Hello";
+const char kTestData2[] = "Here it is data.";
+const char kTestFileData1[] = "0123456789";
+const char kTestFileData2[] = "This is sample file.";
+const char kTestFileSystemFileData1[] = "abcdefghijklmnop";
+const char kTestFileSystemFileData2[] = "File system file test data.";
+const char kTestContentType[] = "foo/bar";
+const char kTestContentDisposition[] = "attachment; filename=foo.txt";
+
+const char kFileSystemURLOrigin[] = "http://remote";
+const fileapi::FileSystemType kFileSystemType =
+ fileapi::kFileSystemTypeTemporary;
+
+} // namespace
class BlobURLRequestJobTest : public testing::Test {
public:
@@ -46,10 +53,8 @@ class BlobURLRequestJobTest : public testing::Test {
class MockURLRequestDelegate : public net::URLRequest::Delegate {
public:
- explicit MockURLRequestDelegate(BlobURLRequestJobTest* test)
- : test_(test),
- received_data_(new net::IOBuffer(kBufferSize)) {
- }
+ MockURLRequestDelegate()
+ : received_data_(new net::IOBuffer(kBufferSize)) {}
virtual void OnResponseStarted(net::URLRequest* request) {
if (request->status().is_success()) {
@@ -98,20 +103,16 @@ class BlobURLRequestJobTest : public testing::Test {
}
void RequestComplete() {
- test_->ScheduleNextTask();
+ MessageLoop::current()->Quit();
}
- BlobURLRequestJobTest* test_;
scoped_refptr<net::IOBuffer> received_data_;
std::string response_data_;
};
- // Helper class run a test on our io_thread. The io_thread
- // is spun up once and reused for all tests.
- template <class Method>
- void MethodWrapper(Method method) {
- SetUpTest();
- (this->*method)();
+ BlobURLRequestJobTest()
+ : message_loop_(MessageLoop::TYPE_IO),
+ expected_status_code_(0) {
}
void SetUp() {
@@ -133,13 +134,17 @@ class BlobURLRequestJobTest : public testing::Test {
file_util::GetFileInfo(temp_file2_, &file_info2);
temp_file_modification_time2_ = file_info2.last_modified;
- io_thread_.reset(new base::Thread("BlobRLRequestJobTest Thread"));
- base::Thread::Options options(MessageLoop::TYPE_IO, 0);
- io_thread_->StartWithOptions(options);
+ net::URLRequest::Deprecated::RegisterProtocolFactory(
+ "blob", &BlobURLRequestJobFactory);
+
+ ASSERT_EQ(static_cast<int>(arraysize(kTestFileData1) - 1),
+ file_util::WriteFile(temp_file1_, kTestFileData1,
+ arraysize(kTestFileData1) - 1));
}
void TearDown() {
- io_thread_.reset(NULL);
+ DCHECK(!blob_url_request_job_);
+ net::URLRequest::Deprecated::RegisterProtocolFactory("blob", NULL);
}
static net::URLRequestJob* BlobURLRequestJobFactory(
@@ -151,105 +156,112 @@ class BlobURLRequestJobTest : public testing::Test {
return temp;
}
- BlobURLRequestJobTest()
- : expected_status_code_(0) {
- }
-
- template <class Method>
- void RunTestOnIOThread(Method method) {
- test_finished_event_ .reset(new base::WaitableEvent(false, false));
- io_thread_->message_loop()->PostTask(
- FROM_HERE, base::Bind(&BlobURLRequestJobTest::MethodWrapper<Method>,
- base::Unretained(this), method));
- test_finished_event_->Wait();
- }
-
- void SetUpTest() {
- DCHECK(MessageLoop::current() == io_thread_->message_loop());
-
- net::URLRequest::Deprecated::RegisterProtocolFactory(
- "blob", &BlobURLRequestJobFactory);
- url_request_delegate_.reset(new MockURLRequestDelegate(this));
- }
-
- void TearDownTest() {
- DCHECK(MessageLoop::current() == io_thread_->message_loop());
-
- request_.reset();
- url_request_delegate_.reset();
-
- DCHECK(!blob_url_request_job_);
- net::URLRequest::Deprecated::RegisterProtocolFactory("blob", NULL);
- }
-
- void TestFinished() {
- // We unwind the stack prior to finishing up to let stack
- // based objects get deleted.
- DCHECK(MessageLoop::current() == io_thread_->message_loop());
- MessageLoop::current()->PostTask(
- FROM_HERE,
- base::Bind(&BlobURLRequestJobTest::TestFinishedUnwound,
+ void SetUpFileSystem() {
+ // Prepare file system.
+ file_system_context_ = new fileapi::FileSystemContext(
+ fileapi::FileSystemTaskRunners::CreateMockTaskRunners(),
+ NULL,
+ NULL,
+ temp_dir_.path(),
+ fileapi::CreateDisallowFileAccessOptions());
+
+ file_system_context_->OpenFileSystem(
+ GURL(kFileSystemURLOrigin),
+ kFileSystemType,
+ true, // create
+ base::Bind(&BlobURLRequestJobTest::OnValidateFileSystem,
base::Unretained(this)));
+ MessageLoop::current()->RunAllPending();
+ ASSERT_TRUE(file_system_root_url_.is_valid());
+
+ // Prepare files on file system.
+ const char kFilename1[] = "FileSystemFile1.dat";
+ temp_file_system_file1_ = GetFileSystemURL(kFilename1);
+ WriteFileSystemFile(kFilename1, kTestFileSystemFileData1,
+ arraysize(kTestFileSystemFileData1),
+ &temp_file_system_file_modification_time1_);
+ const char kFilename2[] = "FileSystemFile2.dat";
+ temp_file_system_file2_ = GetFileSystemURL(kFilename2);
+ WriteFileSystemFile(kFilename2, kTestFileSystemFileData2,
+ arraysize(kTestFileSystemFileData2),
+ &temp_file_system_file_modification_time2_);
}
- void TestFinishedUnwound() {
- TearDownTest();
- test_finished_event_->Signal();
+ GURL GetFileSystemURL(const std::string& filename) {
+ return GURL(file_system_root_url_.spec() + filename);
}
- void PushNextTask(const base::Closure& task) {
- task_stack_.push(std::pair<base::Closure, bool>(task, false));
+ void WriteFileSystemFile(const std::string& filename,
+ const char* buf, int buf_size,
+ base::Time* modification_time) {
+ fileapi::FileSystemURL url(GURL(kFileSystemURLOrigin),
+ kFileSystemType,
+ FilePath().AppendASCII(filename));
+
+ fileapi::FileSystemFileUtil* file_util =
+ file_system_context_->GetFileUtil(kFileSystemType);
+
+ fileapi::FileSystemOperationContext context(file_system_context_);
+ context.set_allowed_bytes_growth(1024);
+
+ base::PlatformFile handle = base::kInvalidPlatformFileValue;
+ bool created = false;
+ ASSERT_EQ(base::PLATFORM_FILE_OK, file_util->CreateOrOpen(
+ &context,
+ url,
+ base::PLATFORM_FILE_CREATE | base::PLATFORM_FILE_WRITE,
+ &handle,
+ &created));
+ EXPECT_TRUE(created);
+ ASSERT_NE(base::kInvalidPlatformFileValue, handle);
+ ASSERT_EQ(buf_size,
+ base::WritePlatformFile(handle, 0 /* offset */, buf, buf_size));
+ base::ClosePlatformFile(handle);
+
+ base::PlatformFileInfo file_info;
+ FilePath platform_path;
+ ASSERT_EQ(base::PLATFORM_FILE_OK,
+ file_util->GetFileInfo(&context, url, &file_info,
+ &platform_path));
+ if (modification_time)
+ *modification_time = file_info.last_modified;
}
- void PushNextTaskAsImmediate(const base::Closure& task) {
- task_stack_.push(std::pair<base::Closure, bool>(task, true));
- }
-
- void ScheduleNextTask() {
- DCHECK(MessageLoop::current() == io_thread_->message_loop());
- if (task_stack_.empty()) {
- TestFinished();
- return;
- }
-
- base::Closure task = task_stack_.top().first;
- bool immediate = task_stack_.top().second;
- task_stack_.pop();
- if (immediate)
- task.Run();
- else
- MessageLoop::current()->PostTask(FROM_HERE, task);
+ void OnValidateFileSystem(base::PlatformFileError result,
+ const std::string& name,
+ const GURL& root) {
+ ASSERT_EQ(base::PLATFORM_FILE_OK, result);
+ ASSERT_TRUE(root.is_valid());
+ file_system_root_url_ = root;
}
void TestSuccessRequest(BlobData* blob_data,
const std::string& expected_response) {
- PushNextTask(base::Bind(&BlobURLRequestJobTest::VerifyResponse,
- base::Unretained(this)));
expected_status_code_ = 200;
expected_response_ = expected_response;
- return TestRequest("GET", net::HttpRequestHeaders(), blob_data);
+ TestRequest("GET", net::HttpRequestHeaders(), blob_data);
}
void TestErrorRequest(BlobData* blob_data,
int expected_status_code) {
- PushNextTask(base::Bind(&BlobURLRequestJobTest::VerifyResponse,
- base::Unretained(this)));
expected_status_code_ = expected_status_code;
expected_response_ = "";
- return TestRequest("GET", net::HttpRequestHeaders(), blob_data);
+ TestRequest("GET", net::HttpRequestHeaders(), blob_data);
}
void TestRequest(const std::string& method,
const net::HttpRequestHeaders& extra_headers,
BlobData* blob_data) {
- // This test has async steps.
+ MockURLRequestDelegate url_request_delegate;
+
request_.reset(empty_context_.CreateRequest(
- GURL("blob:blah"), url_request_delegate_.get()));
+ GURL("blob:blah"), &url_request_delegate));
request_->set_method(method);
blob_url_request_job_ = new BlobURLRequestJob(
request_.get(),
empty_context_.network_delegate(),
blob_data,
+ file_system_context_,
base::MessageLoopProxy::current());
// Start the request.
@@ -257,152 +269,52 @@ class BlobURLRequestJobTest : public testing::Test {
request_->SetExtraRequestHeaders(extra_headers);
request_->Start();
- // Completion is async.
- }
+ MessageLoop::current()->Run();
- void VerifyResponse() {
+ // Verify response.
EXPECT_TRUE(request_->status().is_success());
EXPECT_EQ(expected_status_code_,
request_->response_headers()->response_code());
EXPECT_STREQ(expected_response_.c_str(),
- url_request_delegate_->response_data().c_str());
- TestFinished();
- }
-
- // Test Cases ---------------------------------------------------------------
-
- void TestGetSimpleDataRequest() {
- scoped_refptr<BlobData> blob_data(new BlobData());
- blob_data->AppendData(kTestData1);
- TestSuccessRequest(blob_data, kTestData1);
- }
-
- void TestGetSimpleFileRequest() {
- scoped_refptr<BlobData> blob_data(new BlobData());
- blob_data->AppendFile(temp_file1_, 0, -1, base::Time());
- TestSuccessRequest(blob_data, kTestFileData1);
- }
-
- void TestGetLargeFileRequest() {
- scoped_refptr<BlobData> blob_data(new BlobData());
- FilePath large_temp_file = temp_dir_.path().AppendASCII("LargeBlob.dat");
- std::string large_data;
- large_data.reserve(kBufferSize * 5);
- for (int i = 0; i < kBufferSize * 5; ++i)
- large_data.append(1, static_cast<char>(i % 256));
- ASSERT_EQ(static_cast<int>(large_data.size()),
- file_util::WriteFile(large_temp_file, large_data.data(),
- large_data.size()));
- blob_data->AppendFile(large_temp_file, 0, -1, base::Time());
- TestSuccessRequest(blob_data, large_data);
- }
-
- void TestGetNonExistentFileRequest() {
- FilePath non_existent_file =
- temp_file1_.InsertBeforeExtension(FILE_PATH_LITERAL("-na"));
- scoped_refptr<BlobData> blob_data(new BlobData());
- blob_data->AppendFile(non_existent_file, 0, -1, base::Time());
- TestErrorRequest(blob_data, 404);
- }
-
- void TestGetChangedFileRequest() {
- scoped_refptr<BlobData> blob_data(new BlobData());
- base::Time old_time =
- temp_file_modification_time1_ - base::TimeDelta::FromSeconds(10);
- blob_data->AppendFile(temp_file1_, 0, 3, old_time);
- TestErrorRequest(blob_data, 404);
- }
-
- void TestGetSlicedFileRequest() {
- scoped_refptr<BlobData> blob_data(new BlobData());
- blob_data->AppendFile(temp_file1_, 2, 4, temp_file_modification_time1_);
- std::string result(kTestFileData1 + 2, 4);
- TestSuccessRequest(blob_data, result);
+ url_request_delegate.response_data().c_str());
}
scoped_refptr<BlobData> BuildComplicatedData(std::string* expected_result) {
scoped_refptr<BlobData> blob_data(new BlobData());
blob_data->AppendData(kTestData1 + 1, 2);
blob_data->AppendFile(temp_file1_, 2, 3, temp_file_modification_time1_);
- blob_data->AppendData(kTestData2 + 3, 4);
- blob_data->AppendFile(temp_file2_, 4, 5, temp_file_modification_time2_);
+ blob_data->AppendFileSystemFile(temp_file_system_file1_, 3, 4,
+ temp_file_system_file_modification_time1_);
+ blob_data->AppendData(kTestData2 + 4, 5);
+ blob_data->AppendFile(temp_file2_, 5, 6, temp_file_modification_time2_);
+ blob_data->AppendFileSystemFile(temp_file_system_file2_, 6, 7,
+ temp_file_system_file_modification_time2_);
*expected_result = std::string(kTestData1 + 1, 2);
*expected_result += std::string(kTestFileData1 + 2, 3);
- *expected_result += std::string(kTestData2 + 3, 4);
- *expected_result += std::string(kTestFileData2 + 4, 5);
+ *expected_result += std::string(kTestFileSystemFileData1 + 3, 4);
+ *expected_result += std::string(kTestData2 + 4, 5);
+ *expected_result += std::string(kTestFileData2 + 5, 6);
+ *expected_result += std::string(kTestFileSystemFileData2 + 6, 7);
return blob_data;
}
- void TestGetComplicatedDataAndFileRequest() {
- std::string result;
- scoped_refptr<BlobData> blob_data = BuildComplicatedData(&result);
- TestSuccessRequest(blob_data, result);
- }
-
- void TestGetRangeRequest1() {
- std::string result;
- scoped_refptr<BlobData> blob_data = BuildComplicatedData(&result);
- net::HttpRequestHeaders extra_headers;
- extra_headers.SetHeader(net::HttpRequestHeaders::kRange, "bytes=5-10");
- PushNextTask(base::Bind(&BlobURLRequestJobTest::VerifyResponse,
- base::Unretained(this)));
- expected_status_code_ = 206;
- expected_response_ = result.substr(5, 10 - 5 + 1);
- return TestRequest("GET", extra_headers, blob_data);
- }
-
- void TestGetRangeRequest2() {
- std::string result;
- scoped_refptr<BlobData> blob_data = BuildComplicatedData(&result);
- net::HttpRequestHeaders extra_headers;
- extra_headers.SetHeader(net::HttpRequestHeaders::kRange, "bytes=-10");
- PushNextTask(base::Bind(&BlobURLRequestJobTest::VerifyResponse,
- base::Unretained(this)));
- expected_status_code_ = 206;
- expected_response_ = result.substr(result.length() - 10);
- return TestRequest("GET", extra_headers, blob_data);
- }
-
- void TestExtraHeaders() {
- scoped_refptr<BlobData> blob_data(new BlobData());
- blob_data->set_content_type(kTestContentType);
- blob_data->set_content_disposition(kTestContentDisposition);
- blob_data->AppendData(kTestData1);
- PushNextTask(
- base::Bind(&BlobURLRequestJobTest::VerifyResponseForTestExtraHeaders,
- base::Unretained(this)));
- TestRequest("GET", net::HttpRequestHeaders(), blob_data);
- }
-
- void VerifyResponseForTestExtraHeaders() {
- EXPECT_TRUE(request_->status().is_success());
- EXPECT_EQ(request_->response_headers()->response_code(), 200);
- EXPECT_STREQ(url_request_delegate_->response_data().c_str(), kTestData1);
- std::string content_type;
- EXPECT_TRUE(request_->response_headers()->GetMimeType(&content_type));
- EXPECT_STREQ(content_type.c_str(), kTestContentType);
- void* iter = NULL;
- std::string content_disposition;
- EXPECT_TRUE(request_->response_headers()->EnumerateHeader(
- &iter, "Content-Disposition", &content_disposition));
- EXPECT_STREQ(content_disposition.c_str(), kTestContentDisposition);
- TestFinished();
- }
-
- private:
+ protected:
ScopedTempDir temp_dir_;
FilePath temp_file1_;
FilePath temp_file2_;
base::Time temp_file_modification_time1_;
base::Time temp_file_modification_time2_;
- scoped_ptr<base::Thread> io_thread_;
+ GURL file_system_root_url_;
+ GURL temp_file_system_file1_;
+ GURL temp_file_system_file2_;
+ base::Time temp_file_system_file_modification_time1_;
+ base::Time temp_file_system_file_modification_time2_;
+ MessageLoop message_loop_;
static BlobURLRequestJob* blob_url_request_job_;
- scoped_ptr<base::WaitableEvent> test_finished_event_;
- std::stack<std::pair<base::Closure, bool> > task_stack_;
net::URLRequestContext empty_context_;
scoped_ptr<net::URLRequest> request_;
- scoped_ptr<MockURLRequestDelegate> url_request_delegate_;
+ scoped_refptr<fileapi::FileSystemContext> file_system_context_;
int expected_status_code_;
std::string expected_response_;
};
@@ -411,44 +323,151 @@ class BlobURLRequestJobTest : public testing::Test {
BlobURLRequestJob* BlobURLRequestJobTest::blob_url_request_job_ = NULL;
TEST_F(BlobURLRequestJobTest, TestGetSimpleDataRequest) {
- RunTestOnIOThread(&BlobURLRequestJobTest::TestGetSimpleDataRequest);
+ scoped_refptr<BlobData> blob_data(new BlobData());
+ blob_data->AppendData(kTestData1);
+ TestSuccessRequest(blob_data, kTestData1);
}
TEST_F(BlobURLRequestJobTest, TestGetSimpleFileRequest) {
- RunTestOnIOThread(&BlobURLRequestJobTest::TestGetSimpleFileRequest);
+ scoped_refptr<BlobData> blob_data(new BlobData());
+ blob_data->AppendFile(temp_file1_, 0, -1, base::Time());
+ TestSuccessRequest(blob_data, kTestFileData1);
}
TEST_F(BlobURLRequestJobTest, TestGetLargeFileRequest) {
- RunTestOnIOThread(&BlobURLRequestJobTest::TestGetLargeFileRequest);
+ scoped_refptr<BlobData> blob_data(new BlobData());
+ FilePath large_temp_file = temp_dir_.path().AppendASCII("LargeBlob.dat");
+ std::string large_data;
+ large_data.reserve(kBufferSize * 5);
+ for (int i = 0; i < kBufferSize * 5; ++i)
+ large_data.append(1, static_cast<char>(i % 256));
+ ASSERT_EQ(static_cast<int>(large_data.size()),
+ file_util::WriteFile(large_temp_file, large_data.data(),
+ large_data.size()));
+ blob_data->AppendFile(large_temp_file, 0, -1, base::Time());
+ TestSuccessRequest(blob_data, large_data);
+}
+
+TEST_F(BlobURLRequestJobTest, TestGetNonExistentFileRequest) {
+ FilePath non_existent_file =
+ temp_file1_.InsertBeforeExtension(FILE_PATH_LITERAL("-na"));
+ scoped_refptr<BlobData> blob_data(new BlobData());
+ blob_data->AppendFile(non_existent_file, 0, -1, base::Time());
+ TestErrorRequest(blob_data, 404);
+}
+
+TEST_F(BlobURLRequestJobTest, TestGetChangedFileRequest) {
+ scoped_refptr<BlobData> blob_data(new BlobData());
+ base::Time old_time =
+ temp_file_modification_time1_ - base::TimeDelta::FromSeconds(10);
+ blob_data->AppendFile(temp_file1_, 0, 3, old_time);
+ TestErrorRequest(blob_data, 404);
}
TEST_F(BlobURLRequestJobTest, TestGetSlicedFileRequest) {
- RunTestOnIOThread(&BlobURLRequestJobTest::TestGetSlicedFileRequest);
+ scoped_refptr<BlobData> blob_data(new BlobData());
+ blob_data->AppendFile(temp_file1_, 2, 4, temp_file_modification_time1_);
+ std::string result(kTestFileData1 + 2, 4);
+ TestSuccessRequest(blob_data, result);
}
-TEST_F(BlobURLRequestJobTest, TestGetNonExistentFileRequest) {
- RunTestOnIOThread(&BlobURLRequestJobTest::TestGetNonExistentFileRequest);
+TEST_F(BlobURLRequestJobTest, TestGetSimpleFileSystemFileRequest) {
+ SetUpFileSystem();
+ scoped_refptr<BlobData> blob_data(new BlobData());
+ blob_data->AppendFileSystemFile(temp_file_system_file1_, 0, -1,
+ base::Time());
+ TestSuccessRequest(blob_data, kTestFileSystemFileData1);
}
-TEST_F(BlobURLRequestJobTest, TestGetChangedFileRequest) {
- RunTestOnIOThread(&BlobURLRequestJobTest::TestGetChangedFileRequest);
+TEST_F(BlobURLRequestJobTest, TestGetLargeFileSystemFileRequest) {
+ SetUpFileSystem();
+ std::string large_data;
+ large_data.reserve(kBufferSize * 5);
+ for (int i = 0; i < kBufferSize * 5; ++i)
+ large_data.append(1, static_cast<char>(i % 256));
+
+ const char kFilename[] = "LargeBlob.dat";
+ WriteFileSystemFile(kFilename, large_data.data(), large_data.size(), NULL);
+
+ scoped_refptr<BlobData> blob_data(new BlobData());
+ blob_data->AppendFileSystemFile(GetFileSystemURL(kFilename),
+ 0, -1, base::Time());
+ TestSuccessRequest(blob_data, large_data);
+}
+
+TEST_F(BlobURLRequestJobTest, TestGetNonExistentFileSystemFileRequest) {
+ SetUpFileSystem();
+ GURL non_existent_file = GetFileSystemURL("non-existent.dat");
+ scoped_refptr<BlobData> blob_data(new BlobData());
+ blob_data->AppendFileSystemFile(non_existent_file, 0, -1, base::Time());
+ TestErrorRequest(blob_data, 404);
+}
+
+TEST_F(BlobURLRequestJobTest, TestGetChangedFileSystemFileRequest) {
+ SetUpFileSystem();
+ scoped_refptr<BlobData> blob_data(new BlobData());
+ base::Time old_time =
+ temp_file_system_file_modification_time1_ -
+ base::TimeDelta::FromSeconds(10);
+ blob_data->AppendFileSystemFile(temp_file_system_file1_, 0, 3, old_time);
+ TestErrorRequest(blob_data, 404);
+}
+
+TEST_F(BlobURLRequestJobTest, TestGetSlicedFileSystemFileRequest) {
+ SetUpFileSystem();
+ scoped_refptr<BlobData> blob_data(new BlobData());
+ blob_data->AppendFileSystemFile(temp_file_system_file1_, 2, 4,
+ temp_file_system_file_modification_time1_);
+ std::string result(kTestFileSystemFileData1 + 2, 4);
+ TestSuccessRequest(blob_data, result);
}
TEST_F(BlobURLRequestJobTest, TestGetComplicatedDataAndFileRequest) {
- RunTestOnIOThread(
- &BlobURLRequestJobTest::TestGetComplicatedDataAndFileRequest);
+ SetUpFileSystem();
+ std::string result;
+ scoped_refptr<BlobData> blob_data = BuildComplicatedData(&result);
+ TestSuccessRequest(blob_data, result);
}
TEST_F(BlobURLRequestJobTest, TestGetRangeRequest1) {
- RunTestOnIOThread(&BlobURLRequestJobTest::TestGetRangeRequest1);
+ SetUpFileSystem();
+ std::string result;
+ scoped_refptr<BlobData> blob_data = BuildComplicatedData(&result);
+ net::HttpRequestHeaders extra_headers;
+ extra_headers.SetHeader(net::HttpRequestHeaders::kRange, "bytes=5-10");
+ expected_status_code_ = 206;
+ expected_response_ = result.substr(5, 10 - 5 + 1);
+ TestRequest("GET", extra_headers, blob_data);
}
TEST_F(BlobURLRequestJobTest, TestGetRangeRequest2) {
- RunTestOnIOThread(&BlobURLRequestJobTest::TestGetRangeRequest2);
+ SetUpFileSystem();
+ std::string result;
+ scoped_refptr<BlobData> blob_data = BuildComplicatedData(&result);
+ net::HttpRequestHeaders extra_headers;
+ extra_headers.SetHeader(net::HttpRequestHeaders::kRange, "bytes=-10");
+ expected_status_code_ = 206;
+ expected_response_ = result.substr(result.length() - 10);
+ TestRequest("GET", extra_headers, blob_data);
}
TEST_F(BlobURLRequestJobTest, TestExtraHeaders) {
- RunTestOnIOThread(&BlobURLRequestJobTest::TestExtraHeaders);
+ scoped_refptr<BlobData> blob_data(new BlobData());
+ blob_data->set_content_type(kTestContentType);
+ blob_data->set_content_disposition(kTestContentDisposition);
+ blob_data->AppendData(kTestData1);
+ expected_status_code_ = 200;
+ expected_response_ = kTestData1;
+ TestRequest("GET", net::HttpRequestHeaders(), blob_data);
+
+ std::string content_type;
+ EXPECT_TRUE(request_->response_headers()->GetMimeType(&content_type));
+ EXPECT_STREQ(content_type.c_str(), kTestContentType);
+ void* iter = NULL;
+ std::string content_disposition;
+ EXPECT_TRUE(request_->response_headers()->EnumerateHeader(
+ &iter, "Content-Disposition", &content_disposition));
+ EXPECT_STREQ(content_disposition.c_str(), kTestContentDisposition);
}
} // namespace webkit_blob
diff --git a/webkit/blob/mock_blob_url_request_context.cc b/webkit/blob/mock_blob_url_request_context.cc
index 8cc06bc..78f1e73 100644
--- a/webkit/blob/mock_blob_url_request_context.cc
+++ b/webkit/blob/mock_blob_url_request_context.cc
@@ -16,8 +16,10 @@ class MockBlobProtocolHandler
: public net::URLRequestJobFactory::ProtocolHandler {
public:
explicit MockBlobProtocolHandler(
- BlobStorageController* blob_storage_controller)
- : blob_storage_controller_(blob_storage_controller) {}
+ BlobStorageController* blob_storage_controller,
+ fileapi::FileSystemContext* file_system_context)
+ : blob_storage_controller_(blob_storage_controller),
+ file_system_context_(file_system_context) {}
virtual ~MockBlobProtocolHandler() {}
@@ -28,22 +30,26 @@ class MockBlobProtocolHandler
request,
network_delegate,
blob_storage_controller_->GetBlobDataFromUrl(request->url()),
+ file_system_context_,
base::MessageLoopProxy::current());
}
private:
webkit_blob::BlobStorageController* const blob_storage_controller_;
+ fileapi::FileSystemContext* const file_system_context_;
DISALLOW_COPY_AND_ASSIGN(MockBlobProtocolHandler);
};
} // namespace
-MockBlobURLRequestContext::MockBlobURLRequestContext()
+MockBlobURLRequestContext::MockBlobURLRequestContext(
+ fileapi::FileSystemContext* file_system_context)
: blob_storage_controller_(new BlobStorageController) {
// Job factory owns the protocol handler.
job_factory_.SetProtocolHandler(
- "blob", new MockBlobProtocolHandler(blob_storage_controller_.get()));
+ "blob", new MockBlobProtocolHandler(blob_storage_controller_.get(),
+ file_system_context));
set_job_factory(&job_factory_);
}
diff --git a/webkit/blob/mock_blob_url_request_context.h b/webkit/blob/mock_blob_url_request_context.h
index 9190db9..b89027c 100644
--- a/webkit/blob/mock_blob_url_request_context.h
+++ b/webkit/blob/mock_blob_url_request_context.h
@@ -9,13 +9,17 @@
#include "net/url_request/url_request_job.h"
#include "net/url_request/url_request_job_factory_impl.h"
+namespace fileapi {
+class FileSystemContext;
+}
+
namespace webkit_blob {
class BlobStorageController;
class MockBlobURLRequestContext : public net::URLRequestContext {
public:
- MockBlobURLRequestContext();
+ MockBlobURLRequestContext(fileapi::FileSystemContext* file_system_context);
virtual ~MockBlobURLRequestContext();
BlobStorageController* blob_storage_controller() const {