| Index: chrome/browser/renderer_host/redirect_to_file_resource_handler.cc
|
| ===================================================================
|
| --- chrome/browser/renderer_host/redirect_to_file_resource_handler.cc (revision 54397)
|
| +++ chrome/browser/renderer_host/redirect_to_file_resource_handler.cc (working copy)
|
| @@ -5,9 +5,13 @@
|
| #include "chrome/browser/renderer_host/redirect_to_file_resource_handler.h"
|
|
|
| #include "base/file_util.h"
|
| +#include "base/logging.h"
|
| #include "base/platform_file.h"
|
| +#include "base/task.h"
|
| +#include "chrome/browser/file_system_proxy.h"
|
| #include "chrome/browser/renderer_host/resource_dispatcher_host.h"
|
| #include "chrome/common/resource_response.h"
|
| +#include "net/base/file_stream.h"
|
| #include "net/base/io_buffer.h"
|
| #include "net/base/mime_sniffer.h"
|
| #include "net/base/net_errors.h"
|
| @@ -19,7 +23,8 @@
|
| ResourceHandler* next_handler,
|
| int process_id,
|
| ResourceDispatcherHost* host)
|
| - : host_(host),
|
| + : callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
|
| + host_(host),
|
| next_handler_(next_handler),
|
| process_id_(process_id),
|
| request_id_(-1),
|
| @@ -50,8 +55,7 @@
|
| int request_id,
|
| ResourceResponse* response) {
|
| if (response->response_head.status.is_success()) {
|
| - // TODO(darin): Move this file creation to a background thread.
|
| - file_util::CreateTemporaryFile(&file_path_);
|
| + DCHECK(!file_path_.empty());
|
| response->response_head.download_file_path = file_path_;
|
| }
|
| return next_handler_->OnResponseStarted(request_id, response);
|
| @@ -60,6 +64,17 @@
|
| bool RedirectToFileResourceHandler::OnWillStart(int request_id,
|
| const GURL& url,
|
| bool* defer) {
|
| + request_id_ = request_id;
|
| + if (file_path_.empty()) {
|
| + // 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.
|
| + *defer = true;
|
| + FileSystemProxy::CreateTemporary(
|
| + callback_factory_.NewCallback(
|
| + &RedirectToFileResourceHandler::DidCreateTemporaryFile));
|
| + return true;
|
| + }
|
| return next_handler_->OnWillStart(request_id, url, defer);
|
| }
|
|
|
| @@ -103,18 +118,9 @@
|
| DCHECK(new_offset <= buf_->capacity());
|
| buf_->set_offset(new_offset);
|
|
|
| - if (!file_stream_.IsOpen()) {
|
| - int rv = file_stream_.Open(file_path_, base::PLATFORM_FILE_OPEN |
|
| - base::PLATFORM_FILE_WRITE |
|
| - base::PLATFORM_FILE_ASYNC);
|
| - if (rv != net::OK)
|
| - return false;
|
| - }
|
| -
|
| if (BufIsFull())
|
| host_->PauseRequest(process_id_, request_id, true);
|
|
|
| - request_id_ = request_id;
|
| return WriteMore();
|
| }
|
|
|
| @@ -127,11 +133,32 @@
|
|
|
| void RedirectToFileResourceHandler::OnRequestClosed() {
|
| next_handler_->OnRequestClosed();
|
| +
|
| + // The renderer no longer has a WebURLLoader open to this request, so we can
|
| + // close and unlink the file.
|
| +
|
| + // We require this explicit call to Close since file_stream_ was constructed
|
| + // directly from a PlatformFile.
|
| + file_stream_->Close();
|
| + file_stream_.reset();
|
| +
|
| + FileSystemProxy::Delete(file_path_, NULL);
|
| }
|
|
|
| RedirectToFileResourceHandler::~RedirectToFileResourceHandler() {
|
| + DCHECK(!file_stream_.get());
|
| }
|
|
|
| +void RedirectToFileResourceHandler::DidCreateTemporaryFile(
|
| + base::PassPlatformFile file_handle,
|
| + FilePath file_path) {
|
| + file_path_ = file_path;
|
| + file_stream_.reset(new net::FileStream(file_handle.ReleaseValue(),
|
| + base::PLATFORM_FILE_WRITE |
|
| + base::PLATFORM_FILE_ASYNC));
|
| + host_->StartDeferredRequest(process_id_, request_id_);
|
| +}
|
| +
|
| void RedirectToFileResourceHandler::DidWriteToFile(int result) {
|
| write_callback_pending_ = false;
|
|
|
| @@ -148,6 +175,7 @@
|
| }
|
|
|
| bool RedirectToFileResourceHandler::WriteMore() {
|
| + DCHECK(file_stream_.get());
|
| for (;;) {
|
| if (write_cursor_ == buf_->offset()) {
|
| // We've caught up to the network load, but it may be in the process of
|
| @@ -163,9 +191,9 @@
|
| if (write_callback_pending_)
|
| return true;
|
| DCHECK(write_cursor_ < buf_->offset());
|
| - int rv = file_stream_.Write(buf_->StartOfBuffer() + write_cursor_,
|
| - buf_->offset() - write_cursor_,
|
| - &write_callback_);
|
| + int rv = file_stream_->Write(buf_->StartOfBuffer() + write_cursor_,
|
| + buf_->offset() - write_cursor_,
|
| + &write_callback_);
|
| if (rv == net::ERR_IO_PENDING) {
|
| write_callback_pending_ = true;
|
| return true;
|
|
|