diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-03-08 13:07:32 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-03-08 13:40:10 +0000 |
commit | 818d9aed569afd192f6d4f6d9b28b72912df8b93 (patch) | |
tree | fa30cbdffa3e8fdc09dbbe37ffc0a721b40fced1 /chromium/storage | |
parent | 66a2147d838e293f4a5db7711c8eba4e6faaaf0f (diff) | |
download | qtwebengine-chromium-818d9aed569afd192f6d4f6d9b28b72912df8b93.tar.gz |
BASELINE: Update Chromium to 65.0.3325.151
Change-Id: I3c71dd500483eb29491ac3eee4123714dda52da9
Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/storage')
3 files changed, 124 insertions, 37 deletions
diff --git a/chromium/storage/browser/fileapi/file_writer_delegate.cc b/chromium/storage/browser/fileapi/file_writer_delegate.cc index 5b942687c0c..2cba8b51a9e 100644 --- a/chromium/storage/browser/fileapi/file_writer_delegate.cc +++ b/chromium/storage/browser/fileapi/file_writer_delegate.cc @@ -69,27 +69,27 @@ void FileWriterDelegate::OnReceivedRedirect( const net::RedirectInfo& redirect_info, bool* defer_redirect) { NOTREACHED(); - OnError(base::File::FILE_ERROR_SECURITY); + OnReadError(base::File::FILE_ERROR_SECURITY); } void FileWriterDelegate::OnAuthRequired(net::URLRequest* request, net::AuthChallengeInfo* auth_info) { NOTREACHED(); - OnError(base::File::FILE_ERROR_SECURITY); + OnReadError(base::File::FILE_ERROR_SECURITY); } void FileWriterDelegate::OnCertificateRequested( net::URLRequest* request, net::SSLCertRequestInfo* cert_request_info) { NOTREACHED(); - OnError(base::File::FILE_ERROR_SECURITY); + OnReadError(base::File::FILE_ERROR_SECURITY); } void FileWriterDelegate::OnSSLCertificateError(net::URLRequest* request, const net::SSLInfo& ssl_info, bool fatal) { NOTREACHED(); - OnError(base::File::FILE_ERROR_SECURITY); + OnReadError(base::File::FILE_ERROR_SECURITY); } void FileWriterDelegate::OnResponseStarted(net::URLRequest* request, @@ -98,7 +98,7 @@ void FileWriterDelegate::OnResponseStarted(net::URLRequest* request, DCHECK_EQ(request_.get(), request); if (net_error != net::OK || request->GetResponseCode() != 200) { - OnError(base::File::FILE_ERROR_FAILED); + OnReadError(base::File::FILE_ERROR_FAILED); return; } Read(); @@ -110,7 +110,7 @@ void FileWriterDelegate::OnReadCompleted(net::URLRequest* request, DCHECK_EQ(request_.get(), request); if (bytes_read < 0) { - OnError(base::File::FILE_ERROR_FAILED); + OnReadError(base::File::FILE_ERROR_FAILED); return; } OnDataReceived(bytes_read); @@ -127,7 +127,7 @@ void FileWriterDelegate::Read() { FROM_HERE, base::Bind(&FileWriterDelegate::OnDataReceived, weak_factory_.GetWeakPtr(), bytes_read_)); } else { - OnError(base::File::FILE_ERROR_FAILED); + OnReadError(base::File::FILE_ERROR_FAILED); } } @@ -157,11 +157,19 @@ void FileWriterDelegate::Write() { FROM_HERE, base::Bind(&FileWriterDelegate::OnDataWritten, weak_factory_.GetWeakPtr(), write_response)); } else if (net::ERR_IO_PENDING != write_response) { - OnError(NetErrorToFileError(write_response)); + OnWriteError(NetErrorToFileError(write_response)); + } else { + async_write_in_progress_ = true; } } void FileWriterDelegate::OnDataWritten(int write_response) { + async_write_in_progress_ = false; + if (saved_read_error_ != base::File::FILE_OK) { + OnReadError(saved_read_error_); + return; + } + if (write_response > 0) { OnProgress(write_response, false); cursor_->DidConsume(write_response); @@ -171,7 +179,7 @@ void FileWriterDelegate::OnDataWritten(int write_response) { else Write(); } else { - OnError(NetErrorToFileError(write_response)); + OnWriteError(NetErrorToFileError(write_response)); } } @@ -180,7 +188,14 @@ FileWriterDelegate::GetCompletionStatusOnError() const { return writing_started_ ? ERROR_WRITE_STARTED : ERROR_WRITE_NOT_STARTED; } -void FileWriterDelegate::OnError(base::File::Error error) { +void FileWriterDelegate::OnReadError(base::File::Error error) { + if (async_write_in_progress_) { + // Error signaled by the URLRequest while writing. This will be processed + // when the write completes. + saved_read_error_ = error; + return; + } + // Destroy the request and invalidate weak ptrs to prevent pending callbacks. request_.reset(); weak_factory_.InvalidateWeakPtrs(); @@ -191,6 +206,17 @@ void FileWriterDelegate::OnError(base::File::Error error) { write_callback_.Run(error, 0, ERROR_WRITE_NOT_STARTED); } +void FileWriterDelegate::OnWriteError(base::File::Error error) { + // Destroy the request and invalidate weak ptrs to prevent pending callbacks. + request_.reset(); + weak_factory_.InvalidateWeakPtrs(); + + // Errors when writing are not recoverable, so don't bother flushing. + write_callback_.Run( + error, 0, + writing_started_ ? ERROR_WRITE_STARTED : ERROR_WRITE_NOT_STARTED); +} + void FileWriterDelegate::OnProgress(int bytes_written, bool done) { DCHECK(bytes_written + bytes_written_backlog_ >= bytes_written_backlog_); static const int kMinProgressDelayMS = 200; diff --git a/chromium/storage/browser/fileapi/file_writer_delegate.h b/chromium/storage/browser/fileapi/file_writer_delegate.h index 7520dc1811d..3bac3a6f91d 100644 --- a/chromium/storage/browser/fileapi/file_writer_delegate.h +++ b/chromium/storage/browser/fileapi/file_writer_delegate.h @@ -64,15 +64,19 @@ class STORAGE_EXPORT FileWriterDelegate : public net::URLRequest::Delegate { void OnResponseStarted(net::URLRequest* request, int net_error) override; void OnReadCompleted(net::URLRequest* request, int bytes_read) override; + protected: + // Virtual for tests. + virtual void OnDataReceived(int bytes_read); + private: void OnGetFileInfoAndStartRequest(std::unique_ptr<net::URLRequest> request, base::File::Error error, const base::File::Info& file_info); void Read(); - void OnDataReceived(int bytes_read); void Write(); void OnDataWritten(int write_response); - void OnError(base::File::Error error); + void OnReadError(base::File::Error error); + void OnWriteError(base::File::Error error); void OnProgress(int bytes_read, bool done); void OnWriteCancelled(int status); void MaybeFlushForCompletion(base::File::Error error, @@ -93,6 +97,8 @@ class STORAGE_EXPORT FileWriterDelegate : public net::URLRequest::Delegate { int bytes_written_backlog_; int bytes_written_; int bytes_read_; + bool async_write_in_progress_ = false; + base::File::Error saved_read_error_ = base::File::FILE_OK; scoped_refptr<net::IOBufferWithSize> io_buffer_; scoped_refptr<net::DrainableIOBuffer> cursor_; std::unique_ptr<net::URLRequest> request_; diff --git a/chromium/storage/browser/fileapi/file_writer_delegate_unittest.cc b/chromium/storage/browser/fileapi/file_writer_delegate_unittest.cc index fd25f1f7bdf..0b88688103e 100644 --- a/chromium/storage/browser/fileapi/file_writer_delegate_unittest.cc +++ b/chromium/storage/browser/fileapi/file_writer_delegate_unittest.cc @@ -106,8 +106,8 @@ class FileWriterDelegateTest : public PlatformTest { int64_t GetFileSizeOnDisk(const char* test_file_path) { // There might be in-flight flush/write. - base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, - base::Bind(&base::DoNothing)); + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(&base::DoNothing)); base::RunLoop().RunUntilIdle(); FileSystemURL url = GetFileSystemURL(test_file_path); @@ -123,23 +123,28 @@ class FileWriterDelegateTest : public PlatformTest { kOrigin, kFileSystemType, base::FilePath().FromUTF8Unsafe(file_name)); } - FileWriterDelegate* CreateWriterDelegate(const char* test_file_path, - int64_t offset, - int64_t allowed_growth) { - storage::SandboxFileStreamWriter* writer = - new storage::SandboxFileStreamWriter( - file_system_context_.get(), - GetFileSystemURL(test_file_path), - offset, - *file_system_context_->GetUpdateObservers(kFileSystemType)); + std::unique_ptr<storage::SandboxFileStreamWriter> CreateWriter( + const char* test_file_path, + int64_t offset, + int64_t allowed_growth) { + auto writer = std::make_unique<storage::SandboxFileStreamWriter>( + file_system_context_.get(), GetFileSystemURL(test_file_path), offset, + *file_system_context_->GetUpdateObservers(kFileSystemType)); writer->set_default_quota(allowed_growth); - return new FileWriterDelegate( - std::unique_ptr<storage::FileStreamWriter>(writer), - storage::FlushPolicy::FLUSH_ON_COMPLETION); + return writer; + } + + std::unique_ptr<FileWriterDelegate> CreateWriterDelegate( + const char* test_file_path, + int64_t offset, + int64_t allowed_growth) { + auto writer = CreateWriter(test_file_path, offset, allowed_growth); + return std::make_unique<FileWriterDelegate>( + std::move(writer), storage::FlushPolicy::FLUSH_ON_COMPLETION); } FileWriterDelegate::DelegateWriteCallback GetWriteCallback(Result* result) { - return base::Bind(&Result::DidWrite, base::Unretained(result)); + return base::BindRepeating(&Result::DidWrite, base::Unretained(result)); } // Creates and sets up a FileWriterDelegate for writing the given |blob_url|, @@ -148,8 +153,8 @@ class FileWriterDelegateTest : public PlatformTest { const GURL& blob_url, int64_t offset, int64_t allowed_growth) { - file_writer_delegate_.reset( - CreateWriterDelegate(test_file_path, offset, allowed_growth)); + file_writer_delegate_ = + CreateWriterDelegate(test_file_path, offset, allowed_growth); request_ = empty_context_.CreateRequest(blob_url, net::DEFAULT_PRIORITY, file_writer_delegate_.get(), TRAFFIC_ANNOTATION_FOR_TESTS); @@ -189,8 +194,9 @@ class FileWriterDelegateTestJob : public net::URLRequestJob { void Start() override { base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&FileWriterDelegateTestJob::NotifyHeadersComplete, - weak_factory_.GetWeakPtr())); + FROM_HERE, + base::BindOnce(&FileWriterDelegateTestJob::NotifyHeadersComplete, + weak_factory_.GetWeakPtr())); } int ReadRawData(net::IOBuffer* buf, int buf_size) override { @@ -233,8 +239,8 @@ class BlobURLRequestJobFactory : public net::URLRequestJobFactory { const std::string& scheme, net::URLRequest* request, net::NetworkDelegate* network_delegate) const override { - return new FileWriterDelegateTestJob( - request, network_delegate, *content_data_); + return new FileWriterDelegateTestJob(request, network_delegate, + *content_data_); } net::URLRequestJob* MaybeInterceptRedirect( @@ -274,7 +280,7 @@ void FileWriterDelegateTest::SetUp() { ASSERT_EQ(base::File::FILE_OK, AsyncFileTestHelper::CreateFile(file_system_context_.get(), GetFileSystemURL("test"))); - job_factory_.reset(new BlobURLRequestJobFactory(&content_)); + job_factory_ = std::make_unique<BlobURLRequestJobFactory>(&content_); empty_context_.set_job_factory(job_factory_.get()); } @@ -379,9 +385,9 @@ TEST_F(FileWriterDelegateTest, WriteSuccessWithoutQuotaLimitConcurrent) { PrepareForWrite("test", kBlobURL, 0, std::numeric_limits<int64_t>::max()); - // Credate another FileWriterDelegate for concurrent write. - file_writer_delegate2.reset( - CreateWriterDelegate("test2", 0, std::numeric_limits<int64_t>::max())); + // Create another FileWriterDelegate for concurrent write. + file_writer_delegate2 = + CreateWriterDelegate("test2", 0, std::numeric_limits<int64_t>::max()); request2 = empty_context_.CreateRequest(kBlobURL2, net::DEFAULT_PRIORITY, file_writer_delegate2.get(), TRAFFIC_ANNOTATION_FOR_TESTS); @@ -513,4 +519,53 @@ TEST_F(FileWriterDelegateTest, WritesWithQuotaAndOffset) { } } +class InterruptedFileWriterDelegate : public FileWriterDelegate { + public: + InterruptedFileWriterDelegate( + std::unique_ptr<storage::FileStreamWriter> file_writer, + storage::FlushPolicy flush_policy) + : FileWriterDelegate(std::move(file_writer), flush_policy) {} + ~InterruptedFileWriterDelegate() override = default; + + void OnDataReceived(int bytes_read) override { + // The base class will respond to OnDataReceived by performing an + // asynchronous write. Schedule a task now that will execute before the + // write completes which terminates the URLRequestJob. + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(IgnoreResult(&net::URLRequest::Cancel), + base::Unretained(request_))); + FileWriterDelegate::OnDataReceived(bytes_read); + } + + void set_request(net::URLRequest* request) { request_ = request; } + + private: + // The request is owned by the base class as a private member. + net::URLRequest* request_ = nullptr; +}; + +TEST_F(FileWriterDelegateTest, ReadFailureDuringAsyncWrite) { + const GURL kBlobURL("blob:async-fail"); + content_ = kData; + + auto writer = CreateWriter("test", 0, std::numeric_limits<int64_t>::max()); + auto file_writer_delegate = std::make_unique<InterruptedFileWriterDelegate>( + std::move(writer), storage::FlushPolicy::FLUSH_ON_COMPLETION); + auto request = empty_context_.CreateRequest(kBlobURL, net::DEFAULT_PRIORITY, + file_writer_delegate.get(), + TRAFFIC_ANNOTATION_FOR_TESTS); + file_writer_delegate->set_request(request.get()); + + Result result; + file_writer_delegate->Start(std::move(request), GetWriteCallback(&result)); + base::RunLoop().Run(); + + ASSERT_EQ(FileWriterDelegate::ERROR_WRITE_STARTED, result.write_status()); + file_writer_delegate_.reset(); + + // The write should still have flushed. + ASSERT_EQ(kDataSize, usage()); + EXPECT_EQ(GetFileSizeOnDisk("test"), usage()); +} + } // namespace content |