| Index: content/browser/loader/redirect_to_file_resource_handler.cc
|
| diff --git a/content/browser/loader/redirect_to_file_resource_handler.cc b/content/browser/loader/redirect_to_file_resource_handler.cc
|
| index 06f9216e3751226117cfa74c8554238dab8730ac..1b98f1cce41f977184a7fa602ace4992db38e1d2 100644
|
| --- a/content/browser/loader/redirect_to_file_resource_handler.cc
|
| +++ b/content/browser/loader/redirect_to_file_resource_handler.cc
|
| @@ -5,14 +5,11 @@
|
| #include "content/browser/loader/redirect_to_file_resource_handler.h"
|
|
|
| #include "base/bind.h"
|
| -#include "base/files/file_util_proxy.h"
|
| #include "base/logging.h"
|
| -#include "base/message_loop/message_loop_proxy.h"
|
| #include "base/platform_file.h"
|
| #include "base/threading/thread_restrictions.h"
|
| -#include "content/browser/loader/resource_dispatcher_host_impl.h"
|
| #include "content/browser/loader/resource_request_info_impl.h"
|
| -#include "content/public/browser/browser_thread.h"
|
| +#include "content/public/browser/resource_controller.h"
|
| #include "content/public/common/resource_response.h"
|
| #include "net/base/file_stream.h"
|
| #include "net/base/io_buffer.h"
|
| @@ -56,17 +53,17 @@ static const int kMaxReadBufSize = 524288;
|
| RedirectToFileResourceHandler::RedirectToFileResourceHandler(
|
| scoped_ptr<ResourceHandler> next_handler,
|
| net::URLRequest* request,
|
| - ResourceDispatcherHostImpl* host)
|
| + TemporaryFileStreamFactory* file_stream_factory)
|
| : LayeredResourceHandler(request, next_handler.Pass()),
|
| - weak_factory_(this),
|
| - host_(host),
|
| + file_stream_factory_(file_stream_factory),
|
| buf_(new net::GrowableIOBuffer()),
|
| buf_write_pending_(false),
|
| write_cursor_(0),
|
| write_callback_pending_(false),
|
| next_buffer_size_(kInitialReadBufSize),
|
| did_defer_(false),
|
| - completed_during_write_(false) {
|
| + completed_during_write_(false),
|
| + weak_factory_(this) {
|
| }
|
|
|
| RedirectToFileResourceHandler::~RedirectToFileResourceHandler() {
|
| @@ -91,10 +88,11 @@ bool RedirectToFileResourceHandler::OnWillStart(int request_id,
|
| // Defer starting the request until we have created the temporary file.
|
| // TODO(darin): This is sub-optimal. We should not delay starting the
|
| // network request like this.
|
| + will_start_url_ = url;
|
| did_defer_ = *defer = true;
|
| - base::FileUtilProxy::CreateTemporary(
|
| - BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE).get(),
|
| - base::PLATFORM_FILE_ASYNC,
|
| + const ResourceRequestInfo* info = GetRequestInfo();
|
| + file_stream_factory_->CreateTemporary(
|
| + info->GetChildID(), info->GetRequestID(),
|
| base::Bind(&RedirectToFileResourceHandler::DidCreateTemporaryFile,
|
| weak_factory_.GetWeakPtr()));
|
| return true;
|
| @@ -155,28 +153,32 @@ void RedirectToFileResourceHandler::OnResponseCompleted(
|
| completed_during_write_ = true;
|
| completed_status_ = status;
|
| completed_security_info_ = security_info;
|
| - *defer = true;
|
| + did_defer_ = *defer = true;
|
| return;
|
| }
|
| next_handler_->OnResponseCompleted(request_id, status, security_info, defer);
|
| }
|
|
|
| void RedirectToFileResourceHandler::DidCreateTemporaryFile(
|
| - base::PlatformFileError /*error_code*/,
|
| - base::PassPlatformFile file_handle,
|
| - const base::FilePath& file_path) {
|
| - deletable_file_ = ShareableFileReference::GetOrCreate(
|
| - file_path,
|
| - ShareableFileReference::DELETE_ON_FINAL_RELEASE,
|
| - BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE).get());
|
| - file_stream_.reset(
|
| - new net::FileStream(file_handle.ReleaseValue(),
|
| - base::PLATFORM_FILE_WRITE | base::PLATFORM_FILE_ASYNC,
|
| - NULL));
|
| - const ResourceRequestInfo* info = GetRequestInfo();
|
| - host_->RegisterDownloadedTempFile(
|
| - info->GetChildID(), info->GetRequestID(), deletable_file_.get());
|
| - ResumeIfDeferred();
|
| + base::PlatformFileError error_code,
|
| + scoped_ptr<net::FileStream> file_stream,
|
| + scoped_refptr<ShareableFileReference> deletable_file) {
|
| + if (error_code != base::PLATFORM_FILE_OK) {
|
| + controller()->CancelWithError(net::PlatformFileErrorToNetError(error_code));
|
| + return;
|
| + }
|
| +
|
| + deletable_file_ = deletable_file;
|
| + file_stream_ = file_stream.Pass();
|
| +
|
| + // Resume the request.
|
| + bool defer = false;
|
| + if (!next_handler_->OnWillStart(GetRequestID(), will_start_url_, &defer)) {
|
| + controller()->Cancel();
|
| + } else if (!defer) {
|
| + ResumeIfDeferred();
|
| + }
|
| + will_start_url_ = GURL();
|
| }
|
|
|
| void RedirectToFileResourceHandler::DidWriteToFile(int result) {
|
| @@ -193,8 +195,21 @@ void RedirectToFileResourceHandler::DidWriteToFile(int result) {
|
| }
|
|
|
| if (failed) {
|
| - ResumeIfDeferred();
|
| - } else if (completed_during_write_) {
|
| + // TODO(davidben): Recover the error code from WriteMore or |result|, as
|
| + // appropriate.
|
| + if (completed_during_write_ && completed_status_.is_success()) {
|
| + // If the request successfully completed mid-write, but the write failed,
|
| + // convert the status to a failure for downstream.
|
| + completed_status_.set_status(net::URLRequestStatus::CANCELED);
|
| + completed_status_.set_error(net::ERR_FAILED);
|
| + }
|
| + controller()->CancelWithError(net::ERR_FAILED);
|
| + }
|
| +
|
| + if (completed_during_write_ && !write_callback_pending_) {
|
| + // Resume shutdown now that all data has been written to disk. Note that
|
| + // this should run even in the |failed| case above, otherwise a failed write
|
| + // leaves the handler stuck.
|
| bool defer = false;
|
| next_handler_->OnResponseCompleted(request_id,
|
| completed_status_,
|
|
|