Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1290)

Unified Diff: content/browser/loader/redirect_to_file_resource_handler.cc

Issue 82273002: Fix various issues in RedirectToFileResourceHandler. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: UUUUNIT TESTS Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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_,

Powered by Google App Engine
This is Rietveld 408576698