| OLD | NEW |
| (Empty) |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include <stdint.h> | |
| 6 | |
| 7 #include <limits> | |
| 8 #include <memory> | |
| 9 | |
| 10 #include "base/bind.h" | |
| 11 #include "base/files/file_path.h" | |
| 12 #include "base/files/file_util.h" | |
| 13 #include "base/files/scoped_temp_dir.h" | |
| 14 #include "base/macros.h" | |
| 15 #include "base/memory/ptr_util.h" | |
| 16 #include "base/memory/ref_counted.h" | |
| 17 #include "base/numerics/safe_conversions.h" | |
| 18 #include "base/run_loop.h" | |
| 19 #include "base/threading/thread_task_runner_handle.h" | |
| 20 #include "base/time/time.h" | |
| 21 #include "content/browser/fileapi/mock_url_request_delegate.h" | |
| 22 #include "content/public/test/async_file_test_helper.h" | |
| 23 #include "content/public/test/test_file_system_context.h" | |
| 24 #include "net/base/net_errors.h" | |
| 25 #include "net/base/request_priority.h" | |
| 26 #include "net/base/test_completion_callback.h" | |
| 27 #include "net/disk_cache/disk_cache.h" | |
| 28 #include "net/http/http_byte_range.h" | |
| 29 #include "net/http/http_request_headers.h" | |
| 30 #include "net/http/http_response_headers.h" | |
| 31 #include "net/url_request/url_request.h" | |
| 32 #include "net/url_request/url_request_context.h" | |
| 33 #include "net/url_request/url_request_job_factory_impl.h" | |
| 34 #include "storage/browser/blob/blob_data_builder.h" | |
| 35 #include "storage/browser/blob/blob_data_handle.h" | |
| 36 #include "storage/browser/blob/blob_data_snapshot.h" | |
| 37 #include "storage/browser/blob/blob_storage_context.h" | |
| 38 #include "storage/browser/blob/blob_url_request_job.h" | |
| 39 #include "storage/browser/fileapi/file_system_context.h" | |
| 40 #include "storage/browser/fileapi/file_system_operation_context.h" | |
| 41 #include "storage/browser/fileapi/file_system_url.h" | |
| 42 #include "testing/gtest/include/gtest/gtest.h" | |
| 43 | |
| 44 using storage::BlobDataSnapshot; | |
| 45 using storage::BlobDataBuilder; | |
| 46 using storage::BlobURLRequestJob; | |
| 47 | |
| 48 namespace content { | |
| 49 | |
| 50 namespace { | |
| 51 | |
| 52 const int kBufferSize = 1024; | |
| 53 const char kTestData1[] = "Hello"; | |
| 54 const char kTestData2[] = "Here it is data."; | |
| 55 const char kTestFileData1[] = "0123456789"; | |
| 56 const char kTestFileData2[] = "This is sample file."; | |
| 57 const char kTestFileSystemFileData1[] = "abcdefghijklmnop"; | |
| 58 const char kTestFileSystemFileData2[] = "File system file test data."; | |
| 59 const char kTestDiskCacheKey1[] = "key1"; | |
| 60 const char kTestDiskCacheKey2[] = "key2"; | |
| 61 const char kTestDiskCacheData1[] = "disk cache test data1."; | |
| 62 const char kTestDiskCacheData2[] = "disk cache test data2."; | |
| 63 const char kTestDiskCacheSideData[] = "test side data"; | |
| 64 const char kTestContentType[] = "foo/bar"; | |
| 65 const char kTestContentDisposition[] = "attachment; filename=foo.txt"; | |
| 66 | |
| 67 const char kFileSystemURLOrigin[] = "http://remote"; | |
| 68 const storage::FileSystemType kFileSystemType = | |
| 69 storage::kFileSystemTypeTemporary; | |
| 70 | |
| 71 const int kTestDiskCacheStreamIndex = 0; | |
| 72 const int kTestDiskCacheSideStreamIndex = 1; | |
| 73 | |
| 74 // Our disk cache tests don't need a real data handle since the tests themselves | |
| 75 // scope the disk cache and entries. | |
| 76 class EmptyDataHandle : public storage::BlobDataBuilder::DataHandle { | |
| 77 private: | |
| 78 ~EmptyDataHandle() override {} | |
| 79 }; | |
| 80 | |
| 81 std::unique_ptr<disk_cache::Backend> CreateInMemoryDiskCache() { | |
| 82 std::unique_ptr<disk_cache::Backend> cache; | |
| 83 net::TestCompletionCallback callback; | |
| 84 int rv = disk_cache::CreateCacheBackend(net::MEMORY_CACHE, | |
| 85 net::CACHE_BACKEND_DEFAULT, | |
| 86 base::FilePath(), 0, | |
| 87 false, nullptr, nullptr, &cache, | |
| 88 callback.callback()); | |
| 89 EXPECT_EQ(net::OK, callback.GetResult(rv)); | |
| 90 | |
| 91 return cache; | |
| 92 } | |
| 93 | |
| 94 disk_cache::ScopedEntryPtr CreateDiskCacheEntry(disk_cache::Backend* cache, | |
| 95 const char* key, | |
| 96 const std::string& data) { | |
| 97 disk_cache::Entry* temp_entry = nullptr; | |
| 98 net::TestCompletionCallback callback; | |
| 99 int rv = cache->CreateEntry(key, &temp_entry, callback.callback()); | |
| 100 if (callback.GetResult(rv) != net::OK) | |
| 101 return nullptr; | |
| 102 disk_cache::ScopedEntryPtr entry(temp_entry); | |
| 103 | |
| 104 scoped_refptr<net::StringIOBuffer> iobuffer = new net::StringIOBuffer(data); | |
| 105 rv = entry->WriteData(kTestDiskCacheStreamIndex, 0, iobuffer.get(), | |
| 106 iobuffer->size(), callback.callback(), false); | |
| 107 EXPECT_EQ(static_cast<int>(data.size()), callback.GetResult(rv)); | |
| 108 return entry; | |
| 109 } | |
| 110 | |
| 111 disk_cache::ScopedEntryPtr CreateDiskCacheEntryWithSideData( | |
| 112 disk_cache::Backend* cache, | |
| 113 const char* key, | |
| 114 const std::string& data, | |
| 115 const std::string& side_data) { | |
| 116 disk_cache::ScopedEntryPtr entry = CreateDiskCacheEntry(cache, key, data); | |
| 117 scoped_refptr<net::StringIOBuffer> iobuffer = | |
| 118 new net::StringIOBuffer(side_data); | |
| 119 net::TestCompletionCallback callback; | |
| 120 int rv = entry->WriteData(kTestDiskCacheSideStreamIndex, 0, iobuffer.get(), | |
| 121 iobuffer->size(), callback.callback(), false); | |
| 122 EXPECT_EQ(static_cast<int>(side_data.size()), callback.GetResult(rv)); | |
| 123 return entry; | |
| 124 } | |
| 125 | |
| 126 } // namespace | |
| 127 | |
| 128 class BlobURLRequestJobTest : public testing::Test { | |
| 129 public: | |
| 130 // A simple ProtocolHandler implementation to create BlobURLRequestJob. | |
| 131 class MockProtocolHandler : | |
| 132 public net::URLRequestJobFactory::ProtocolHandler { | |
| 133 public: | |
| 134 MockProtocolHandler(BlobURLRequestJobTest* test) : test_(test) {} | |
| 135 | |
| 136 // net::URLRequestJobFactory::ProtocolHandler override. | |
| 137 net::URLRequestJob* MaybeCreateJob( | |
| 138 net::URLRequest* request, | |
| 139 net::NetworkDelegate* network_delegate) const override { | |
| 140 return new BlobURLRequestJob(request, network_delegate, | |
| 141 test_->GetHandleFromBuilder(), | |
| 142 test_->file_system_context_.get(), | |
| 143 base::ThreadTaskRunnerHandle::Get().get()); | |
| 144 } | |
| 145 | |
| 146 private: | |
| 147 BlobURLRequestJobTest* test_; | |
| 148 }; | |
| 149 | |
| 150 BlobURLRequestJobTest() | |
| 151 : blob_data_(new BlobDataBuilder("uuid")), expected_status_code_(0) {} | |
| 152 | |
| 153 void SetUp() override { | |
| 154 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); | |
| 155 | |
| 156 temp_file1_ = temp_dir_.GetPath().AppendASCII("BlobFile1.dat"); | |
| 157 ASSERT_EQ(static_cast<int>(arraysize(kTestFileData1) - 1), | |
| 158 base::WriteFile(temp_file1_, kTestFileData1, | |
| 159 arraysize(kTestFileData1) - 1)); | |
| 160 base::File::Info file_info1; | |
| 161 base::GetFileInfo(temp_file1_, &file_info1); | |
| 162 temp_file_modification_time1_ = file_info1.last_modified; | |
| 163 | |
| 164 temp_file2_ = temp_dir_.GetPath().AppendASCII("BlobFile2.dat"); | |
| 165 ASSERT_EQ(static_cast<int>(arraysize(kTestFileData2) - 1), | |
| 166 base::WriteFile(temp_file2_, kTestFileData2, | |
| 167 arraysize(kTestFileData2) - 1)); | |
| 168 base::File::Info file_info2; | |
| 169 base::GetFileInfo(temp_file2_, &file_info2); | |
| 170 temp_file_modification_time2_ = file_info2.last_modified; | |
| 171 | |
| 172 disk_cache_backend_ = CreateInMemoryDiskCache(); | |
| 173 disk_cache_entry_ = CreateDiskCacheEntry( | |
| 174 disk_cache_backend_.get(), kTestDiskCacheKey1, kTestDiskCacheData1); | |
| 175 | |
| 176 url_request_job_factory_.SetProtocolHandler( | |
| 177 "blob", base::MakeUnique<MockProtocolHandler>(this)); | |
| 178 url_request_context_.set_job_factory(&url_request_job_factory_); | |
| 179 } | |
| 180 | |
| 181 void TearDown() override { | |
| 182 blob_handle_.reset(); | |
| 183 request_.reset(); | |
| 184 // Clean up for ASAN | |
| 185 base::RunLoop run_loop; | |
| 186 run_loop.RunUntilIdle(); | |
| 187 } | |
| 188 | |
| 189 void SetUpFileSystem() { | |
| 190 // Prepare file system. | |
| 191 file_system_context_ = | |
| 192 CreateFileSystemContextForTesting(NULL, temp_dir_.GetPath()); | |
| 193 | |
| 194 file_system_context_->OpenFileSystem( | |
| 195 GURL(kFileSystemURLOrigin), | |
| 196 kFileSystemType, | |
| 197 storage::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT, | |
| 198 base::Bind(&BlobURLRequestJobTest::OnValidateFileSystem, | |
| 199 base::Unretained(this))); | |
| 200 base::RunLoop().RunUntilIdle(); | |
| 201 ASSERT_TRUE(file_system_root_url_.is_valid()); | |
| 202 | |
| 203 // Prepare files on file system. | |
| 204 const char kFilename1[] = "FileSystemFile1.dat"; | |
| 205 temp_file_system_file1_ = GetFileSystemURL(kFilename1); | |
| 206 WriteFileSystemFile(kFilename1, kTestFileSystemFileData1, | |
| 207 arraysize(kTestFileSystemFileData1) - 1, | |
| 208 &temp_file_system_file_modification_time1_); | |
| 209 const char kFilename2[] = "FileSystemFile2.dat"; | |
| 210 temp_file_system_file2_ = GetFileSystemURL(kFilename2); | |
| 211 WriteFileSystemFile(kFilename2, kTestFileSystemFileData2, | |
| 212 arraysize(kTestFileSystemFileData2) - 1, | |
| 213 &temp_file_system_file_modification_time2_); | |
| 214 } | |
| 215 | |
| 216 GURL GetFileSystemURL(const std::string& filename) { | |
| 217 return GURL(file_system_root_url_.spec() + filename); | |
| 218 } | |
| 219 | |
| 220 void WriteFileSystemFile(const std::string& filename, | |
| 221 const char* buf, int buf_size, | |
| 222 base::Time* modification_time) { | |
| 223 storage::FileSystemURL url = | |
| 224 file_system_context_->CreateCrackedFileSystemURL( | |
| 225 GURL(kFileSystemURLOrigin), | |
| 226 kFileSystemType, | |
| 227 base::FilePath().AppendASCII(filename)); | |
| 228 | |
| 229 ASSERT_EQ(base::File::FILE_OK, | |
| 230 content::AsyncFileTestHelper::CreateFileWithData( | |
| 231 file_system_context_.get(), url, buf, buf_size)); | |
| 232 | |
| 233 base::File::Info file_info; | |
| 234 ASSERT_EQ(base::File::FILE_OK, | |
| 235 content::AsyncFileTestHelper::GetMetadata( | |
| 236 file_system_context_.get(), url, &file_info)); | |
| 237 if (modification_time) | |
| 238 *modification_time = file_info.last_modified; | |
| 239 } | |
| 240 | |
| 241 void OnValidateFileSystem(const GURL& root, | |
| 242 const std::string& name, | |
| 243 base::File::Error result) { | |
| 244 ASSERT_EQ(base::File::FILE_OK, result); | |
| 245 ASSERT_TRUE(root.is_valid()); | |
| 246 file_system_root_url_ = root; | |
| 247 } | |
| 248 | |
| 249 void TestSuccessNonrangeRequest(const std::string& expected_response, | |
| 250 int64_t expected_content_length) { | |
| 251 expected_status_code_ = 200; | |
| 252 expected_response_ = expected_response; | |
| 253 TestRequest("GET", net::HttpRequestHeaders()); | |
| 254 EXPECT_EQ(expected_content_length, | |
| 255 request_->response_headers()->GetContentLength()); | |
| 256 } | |
| 257 | |
| 258 void TestErrorRequest(int expected_status_code) { | |
| 259 expected_status_code_ = expected_status_code; | |
| 260 expected_response_ = ""; | |
| 261 TestRequest("GET", net::HttpRequestHeaders()); | |
| 262 EXPECT_FALSE(url_request_delegate_.metadata()); | |
| 263 } | |
| 264 | |
| 265 void TestRequest(const std::string& method, | |
| 266 const net::HttpRequestHeaders& extra_headers) { | |
| 267 request_ = url_request_context_.CreateRequest( | |
| 268 GURL("blob:blah"), net::DEFAULT_PRIORITY, &url_request_delegate_); | |
| 269 request_->set_method(method); | |
| 270 if (!extra_headers.IsEmpty()) | |
| 271 request_->SetExtraRequestHeaders(extra_headers); | |
| 272 request_->Start(); | |
| 273 | |
| 274 base::RunLoop().Run(); | |
| 275 | |
| 276 // Verify response. | |
| 277 EXPECT_TRUE(request_->status().is_success()); | |
| 278 EXPECT_EQ(expected_status_code_, | |
| 279 request_->response_headers()->response_code()); | |
| 280 EXPECT_EQ(expected_response_, url_request_delegate_.response_data()); | |
| 281 } | |
| 282 | |
| 283 void BuildComplicatedData(std::string* expected_result) { | |
| 284 blob_data_->AppendData(kTestData1 + 1, 2); | |
| 285 *expected_result = std::string(kTestData1 + 1, 2); | |
| 286 | |
| 287 blob_data_->AppendFile(temp_file1_, 2, 3, temp_file_modification_time1_); | |
| 288 *expected_result += std::string(kTestFileData1 + 2, 3); | |
| 289 | |
| 290 blob_data_->AppendDiskCacheEntry(new EmptyDataHandle(), | |
| 291 disk_cache_entry_.get(), | |
| 292 kTestDiskCacheStreamIndex); | |
| 293 *expected_result += std::string(kTestDiskCacheData1); | |
| 294 | |
| 295 blob_data_->AppendFileSystemFile(temp_file_system_file1_, 3, 4, | |
| 296 temp_file_system_file_modification_time1_); | |
| 297 *expected_result += std::string(kTestFileSystemFileData1 + 3, 4); | |
| 298 | |
| 299 blob_data_->AppendData(kTestData2 + 4, 5); | |
| 300 *expected_result += std::string(kTestData2 + 4, 5); | |
| 301 | |
| 302 blob_data_->AppendFile(temp_file2_, 5, 6, temp_file_modification_time2_); | |
| 303 *expected_result += std::string(kTestFileData2 + 5, 6); | |
| 304 | |
| 305 blob_data_->AppendFileSystemFile(temp_file_system_file2_, 6, 7, | |
| 306 temp_file_system_file_modification_time2_); | |
| 307 *expected_result += std::string(kTestFileSystemFileData2 + 6, 7); | |
| 308 } | |
| 309 | |
| 310 storage::BlobDataHandle* GetHandleFromBuilder() { | |
| 311 if (!blob_handle_) { | |
| 312 blob_handle_ = blob_context_.AddFinishedBlob(blob_data_.get()); | |
| 313 } | |
| 314 return blob_handle_.get(); | |
| 315 } | |
| 316 | |
| 317 // This only works if all the Blob items have a definite pre-computed length. | |
| 318 // Otherwise, this will fail a CHECK. | |
| 319 int64_t GetTotalBlobLength() { | |
| 320 int64_t total = 0; | |
| 321 std::unique_ptr<BlobDataSnapshot> data = | |
| 322 GetHandleFromBuilder()->CreateSnapshot(); | |
| 323 const auto& items = data->items(); | |
| 324 for (const auto& item : items) { | |
| 325 int64_t length = base::checked_cast<int64_t>(item->length()); | |
| 326 CHECK(length <= std::numeric_limits<int64_t>::max() - total); | |
| 327 total += length; | |
| 328 } | |
| 329 return total; | |
| 330 } | |
| 331 | |
| 332 protected: | |
| 333 base::ScopedTempDir temp_dir_; | |
| 334 base::FilePath temp_file1_; | |
| 335 base::FilePath temp_file2_; | |
| 336 base::Time temp_file_modification_time1_; | |
| 337 base::Time temp_file_modification_time2_; | |
| 338 GURL file_system_root_url_; | |
| 339 GURL temp_file_system_file1_; | |
| 340 GURL temp_file_system_file2_; | |
| 341 base::Time temp_file_system_file_modification_time1_; | |
| 342 base::Time temp_file_system_file_modification_time2_; | |
| 343 | |
| 344 std::unique_ptr<disk_cache::Backend> disk_cache_backend_; | |
| 345 disk_cache::ScopedEntryPtr disk_cache_entry_; | |
| 346 | |
| 347 base::MessageLoopForIO message_loop_; | |
| 348 scoped_refptr<storage::FileSystemContext> file_system_context_; | |
| 349 | |
| 350 storage::BlobStorageContext blob_context_; | |
| 351 std::unique_ptr<storage::BlobDataHandle> blob_handle_; | |
| 352 std::unique_ptr<BlobDataBuilder> blob_data_; | |
| 353 std::unique_ptr<BlobDataSnapshot> blob_data_snapshot_; | |
| 354 net::URLRequestJobFactoryImpl url_request_job_factory_; | |
| 355 net::URLRequestContext url_request_context_; | |
| 356 MockURLRequestDelegate url_request_delegate_; | |
| 357 std::unique_ptr<net::URLRequest> request_; | |
| 358 | |
| 359 int expected_status_code_; | |
| 360 std::string expected_response_; | |
| 361 }; | |
| 362 | |
| 363 TEST_F(BlobURLRequestJobTest, TestGetSimpleDataRequest) { | |
| 364 blob_data_->AppendData(kTestData1); | |
| 365 TestSuccessNonrangeRequest(kTestData1, arraysize(kTestData1) - 1); | |
| 366 } | |
| 367 | |
| 368 TEST_F(BlobURLRequestJobTest, TestGetSimpleFileRequest) { | |
| 369 blob_data_->AppendFile(temp_file1_, 0, std::numeric_limits<uint64_t>::max(), | |
| 370 base::Time()); | |
| 371 TestSuccessNonrangeRequest(kTestFileData1, arraysize(kTestFileData1) - 1); | |
| 372 } | |
| 373 | |
| 374 TEST_F(BlobURLRequestJobTest, TestGetLargeFileRequest) { | |
| 375 base::FilePath large_temp_file = | |
| 376 temp_dir_.GetPath().AppendASCII("LargeBlob.dat"); | |
| 377 std::string large_data; | |
| 378 large_data.reserve(kBufferSize * 5); | |
| 379 for (int i = 0; i < kBufferSize * 5; ++i) | |
| 380 large_data.append(1, static_cast<char>(i % 256)); | |
| 381 ASSERT_EQ(static_cast<int>(large_data.size()), | |
| 382 base::WriteFile(large_temp_file, large_data.data(), | |
| 383 large_data.size())); | |
| 384 blob_data_->AppendFile(large_temp_file, 0, | |
| 385 std::numeric_limits<uint64_t>::max(), base::Time()); | |
| 386 TestSuccessNonrangeRequest(large_data, large_data.size()); | |
| 387 } | |
| 388 | |
| 389 TEST_F(BlobURLRequestJobTest, TestGetNonExistentFileRequest) { | |
| 390 base::FilePath non_existent_file = | |
| 391 temp_file1_.InsertBeforeExtension(FILE_PATH_LITERAL("-na")); | |
| 392 blob_data_->AppendFile(non_existent_file, 0, | |
| 393 std::numeric_limits<uint64_t>::max(), base::Time()); | |
| 394 TestErrorRequest(404); | |
| 395 } | |
| 396 | |
| 397 TEST_F(BlobURLRequestJobTest, TestGetChangedFileRequest) { | |
| 398 base::Time old_time = | |
| 399 temp_file_modification_time1_ - base::TimeDelta::FromSeconds(10); | |
| 400 blob_data_->AppendFile(temp_file1_, 0, 3, old_time); | |
| 401 TestErrorRequest(404); | |
| 402 } | |
| 403 | |
| 404 TEST_F(BlobURLRequestJobTest, TestGetSlicedFileRequest) { | |
| 405 blob_data_->AppendFile(temp_file1_, 2, 4, temp_file_modification_time1_); | |
| 406 std::string result(kTestFileData1 + 2, 4); | |
| 407 TestSuccessNonrangeRequest(result, 4); | |
| 408 } | |
| 409 | |
| 410 TEST_F(BlobURLRequestJobTest, TestGetSimpleFileSystemFileRequest) { | |
| 411 SetUpFileSystem(); | |
| 412 blob_data_->AppendFileSystemFile(temp_file_system_file1_, 0, | |
| 413 std::numeric_limits<uint64_t>::max(), | |
| 414 base::Time()); | |
| 415 TestSuccessNonrangeRequest(kTestFileSystemFileData1, | |
| 416 arraysize(kTestFileSystemFileData1) - 1); | |
| 417 } | |
| 418 | |
| 419 TEST_F(BlobURLRequestJobTest, TestGetLargeFileSystemFileRequest) { | |
| 420 SetUpFileSystem(); | |
| 421 std::string large_data; | |
| 422 large_data.reserve(kBufferSize * 5); | |
| 423 for (int i = 0; i < kBufferSize * 5; ++i) | |
| 424 large_data.append(1, static_cast<char>(i % 256)); | |
| 425 | |
| 426 const char kFilename[] = "LargeBlob.dat"; | |
| 427 WriteFileSystemFile(kFilename, large_data.data(), large_data.size(), NULL); | |
| 428 | |
| 429 blob_data_->AppendFileSystemFile(GetFileSystemURL(kFilename), 0, | |
| 430 std::numeric_limits<uint64_t>::max(), | |
| 431 base::Time()); | |
| 432 TestSuccessNonrangeRequest(large_data, large_data.size()); | |
| 433 } | |
| 434 | |
| 435 TEST_F(BlobURLRequestJobTest, TestGetNonExistentFileSystemFileRequest) { | |
| 436 SetUpFileSystem(); | |
| 437 GURL non_existent_file = GetFileSystemURL("non-existent.dat"); | |
| 438 blob_data_->AppendFileSystemFile( | |
| 439 non_existent_file, 0, std::numeric_limits<uint64_t>::max(), base::Time()); | |
| 440 TestErrorRequest(404); | |
| 441 } | |
| 442 | |
| 443 TEST_F(BlobURLRequestJobTest, TestGetInvalidFileSystemFileRequest) { | |
| 444 SetUpFileSystem(); | |
| 445 GURL invalid_file; | |
| 446 blob_data_->AppendFileSystemFile( | |
| 447 invalid_file, 0, std::numeric_limits<uint64_t>::max(), base::Time()); | |
| 448 TestErrorRequest(500); | |
| 449 } | |
| 450 | |
| 451 TEST_F(BlobURLRequestJobTest, TestGetChangedFileSystemFileRequest) { | |
| 452 SetUpFileSystem(); | |
| 453 base::Time old_time = | |
| 454 temp_file_system_file_modification_time1_ - | |
| 455 base::TimeDelta::FromSeconds(10); | |
| 456 blob_data_->AppendFileSystemFile(temp_file_system_file1_, 0, 3, old_time); | |
| 457 TestErrorRequest(404); | |
| 458 } | |
| 459 | |
| 460 TEST_F(BlobURLRequestJobTest, TestGetSlicedFileSystemFileRequest) { | |
| 461 SetUpFileSystem(); | |
| 462 blob_data_->AppendFileSystemFile(temp_file_system_file1_, 2, 4, | |
| 463 temp_file_system_file_modification_time1_); | |
| 464 std::string result(kTestFileSystemFileData1 + 2, 4); | |
| 465 TestSuccessNonrangeRequest(result, 4); | |
| 466 } | |
| 467 | |
| 468 TEST_F(BlobURLRequestJobTest, TestGetSimpleDiskCacheRequest) { | |
| 469 blob_data_->AppendDiskCacheEntry(new EmptyDataHandle(), | |
| 470 disk_cache_entry_.get(), | |
| 471 kTestDiskCacheStreamIndex); | |
| 472 TestSuccessNonrangeRequest(kTestDiskCacheData1, | |
| 473 arraysize(kTestDiskCacheData1) - 1); | |
| 474 } | |
| 475 | |
| 476 TEST_F(BlobURLRequestJobTest, TestGetComplicatedDataFileAndDiskCacheRequest) { | |
| 477 SetUpFileSystem(); | |
| 478 std::string result; | |
| 479 BuildComplicatedData(&result); | |
| 480 TestSuccessNonrangeRequest(result, GetTotalBlobLength()); | |
| 481 } | |
| 482 | |
| 483 TEST_F(BlobURLRequestJobTest, TestGetRangeRequest1) { | |
| 484 SetUpFileSystem(); | |
| 485 std::string result; | |
| 486 BuildComplicatedData(&result); | |
| 487 net::HttpRequestHeaders extra_headers; | |
| 488 extra_headers.SetHeader(net::HttpRequestHeaders::kRange, | |
| 489 net::HttpByteRange::Bounded(5, 10).GetHeaderValue()); | |
| 490 expected_status_code_ = 206; | |
| 491 expected_response_ = result.substr(5, 10 - 5 + 1); | |
| 492 TestRequest("GET", extra_headers); | |
| 493 | |
| 494 EXPECT_EQ(6, request_->response_headers()->GetContentLength()); | |
| 495 EXPECT_FALSE(url_request_delegate_.metadata()); | |
| 496 | |
| 497 int64_t first = 0, last = 0, length = 0; | |
| 498 EXPECT_TRUE( | |
| 499 request_->response_headers()->GetContentRange(&first, &last, &length)); | |
| 500 EXPECT_EQ(5, first); | |
| 501 EXPECT_EQ(10, last); | |
| 502 EXPECT_EQ(GetTotalBlobLength(), length); | |
| 503 } | |
| 504 | |
| 505 TEST_F(BlobURLRequestJobTest, TestGetRangeRequest2) { | |
| 506 SetUpFileSystem(); | |
| 507 std::string result; | |
| 508 BuildComplicatedData(&result); | |
| 509 net::HttpRequestHeaders extra_headers; | |
| 510 extra_headers.SetHeader(net::HttpRequestHeaders::kRange, | |
| 511 net::HttpByteRange::Suffix(10).GetHeaderValue()); | |
| 512 expected_status_code_ = 206; | |
| 513 expected_response_ = result.substr(result.length() - 10); | |
| 514 TestRequest("GET", extra_headers); | |
| 515 | |
| 516 EXPECT_EQ(10, request_->response_headers()->GetContentLength()); | |
| 517 EXPECT_FALSE(url_request_delegate_.metadata()); | |
| 518 | |
| 519 int64_t total = GetTotalBlobLength(); | |
| 520 int64_t first = 0, last = 0, length = 0; | |
| 521 EXPECT_TRUE( | |
| 522 request_->response_headers()->GetContentRange(&first, &last, &length)); | |
| 523 EXPECT_EQ(total - 10, first); | |
| 524 EXPECT_EQ(total - 1, last); | |
| 525 EXPECT_EQ(total, length); | |
| 526 } | |
| 527 | |
| 528 TEST_F(BlobURLRequestJobTest, TestGetRangeRequest3) { | |
| 529 SetUpFileSystem(); | |
| 530 std::string result; | |
| 531 BuildComplicatedData(&result); | |
| 532 net::HttpRequestHeaders extra_headers; | |
| 533 extra_headers.SetHeader(net::HttpRequestHeaders::kRange, | |
| 534 net::HttpByteRange::Bounded(0, 2).GetHeaderValue()); | |
| 535 expected_status_code_ = 206; | |
| 536 expected_response_ = result.substr(0, 3); | |
| 537 TestRequest("GET", extra_headers); | |
| 538 | |
| 539 EXPECT_EQ(3, request_->response_headers()->GetContentLength()); | |
| 540 EXPECT_FALSE(url_request_delegate_.metadata()); | |
| 541 | |
| 542 int64_t first = 0, last = 0, length = 0; | |
| 543 EXPECT_TRUE( | |
| 544 request_->response_headers()->GetContentRange(&first, &last, &length)); | |
| 545 EXPECT_EQ(0, first); | |
| 546 EXPECT_EQ(2, last); | |
| 547 EXPECT_EQ(GetTotalBlobLength(), length); | |
| 548 } | |
| 549 | |
| 550 TEST_F(BlobURLRequestJobTest, TestExtraHeaders) { | |
| 551 blob_data_->set_content_type(kTestContentType); | |
| 552 blob_data_->set_content_disposition(kTestContentDisposition); | |
| 553 blob_data_->AppendData(kTestData1); | |
| 554 expected_status_code_ = 200; | |
| 555 expected_response_ = kTestData1; | |
| 556 TestRequest("GET", net::HttpRequestHeaders()); | |
| 557 | |
| 558 std::string content_type; | |
| 559 EXPECT_TRUE(request_->response_headers()->GetMimeType(&content_type)); | |
| 560 EXPECT_EQ(kTestContentType, content_type); | |
| 561 EXPECT_FALSE(url_request_delegate_.metadata()); | |
| 562 size_t iter = 0; | |
| 563 std::string content_disposition; | |
| 564 EXPECT_TRUE(request_->response_headers()->EnumerateHeader( | |
| 565 &iter, "Content-Disposition", &content_disposition)); | |
| 566 EXPECT_EQ(kTestContentDisposition, content_disposition); | |
| 567 } | |
| 568 | |
| 569 TEST_F(BlobURLRequestJobTest, TestSideData) { | |
| 570 disk_cache::ScopedEntryPtr disk_cache_entry_with_side_data = | |
| 571 CreateDiskCacheEntryWithSideData(disk_cache_backend_.get(), | |
| 572 kTestDiskCacheKey2, kTestDiskCacheData2, | |
| 573 kTestDiskCacheSideData); | |
| 574 blob_data_->AppendDiskCacheEntryWithSideData( | |
| 575 new EmptyDataHandle(), disk_cache_entry_with_side_data.get(), | |
| 576 kTestDiskCacheStreamIndex, kTestDiskCacheSideStreamIndex); | |
| 577 expected_status_code_ = 200; | |
| 578 expected_response_ = kTestDiskCacheData2; | |
| 579 TestRequest("GET", net::HttpRequestHeaders()); | |
| 580 EXPECT_EQ(static_cast<int>(arraysize(kTestDiskCacheData2) - 1), | |
| 581 request_->response_headers()->GetContentLength()); | |
| 582 | |
| 583 EXPECT_TRUE(url_request_delegate_.metadata()); | |
| 584 std::string metadata(url_request_delegate_.metadata()->data(), | |
| 585 url_request_delegate_.metadata()->size()); | |
| 586 EXPECT_EQ(std::string(kTestDiskCacheSideData), metadata); | |
| 587 } | |
| 588 | |
| 589 TEST_F(BlobURLRequestJobTest, TestZeroSizeSideData) { | |
| 590 disk_cache::ScopedEntryPtr disk_cache_entry_with_side_data = | |
| 591 CreateDiskCacheEntryWithSideData(disk_cache_backend_.get(), | |
| 592 kTestDiskCacheKey2, kTestDiskCacheData2, | |
| 593 ""); | |
| 594 blob_data_->AppendDiskCacheEntryWithSideData( | |
| 595 new EmptyDataHandle(), disk_cache_entry_with_side_data.get(), | |
| 596 kTestDiskCacheStreamIndex, kTestDiskCacheSideStreamIndex); | |
| 597 expected_status_code_ = 200; | |
| 598 expected_response_ = kTestDiskCacheData2; | |
| 599 TestRequest("GET", net::HttpRequestHeaders()); | |
| 600 EXPECT_EQ(static_cast<int>(arraysize(kTestDiskCacheData2) - 1), | |
| 601 request_->response_headers()->GetContentLength()); | |
| 602 | |
| 603 EXPECT_FALSE(url_request_delegate_.metadata()); | |
| 604 } | |
| 605 | |
| 606 } // namespace content | |
| OLD | NEW |