| 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 2d55420e95a9f62ef659daf9e3bb6f8f56a63da6..beda724f08b2ec77b53e38b6cb19b4f0a314f32a 100644
|
| --- a/content/browser/loader/redirect_to_file_resource_handler.cc
|
| +++ b/content/browser/loader/redirect_to_file_resource_handler.cc
|
| @@ -138,7 +138,6 @@ RedirectToFileResourceHandler::RedirectToFileResourceHandler(
|
| write_cursor_(0),
|
| writer_(NULL),
|
| next_buffer_size_(kInitialReadBufSize),
|
| - did_defer_(false),
|
| completed_during_write_(false),
|
| weak_factory_(this) {}
|
|
|
| @@ -156,22 +155,24 @@ void RedirectToFileResourceHandler::
|
| create_temporary_file_stream_ = create_temporary_file_stream;
|
| }
|
|
|
| -bool RedirectToFileResourceHandler::OnResponseStarted(
|
| +void RedirectToFileResourceHandler::OnResponseStarted(
|
| ResourceResponse* response,
|
| - bool* defer) {
|
| + std::unique_ptr<ResourceController> controller) {
|
| DCHECK(writer_);
|
| response->head.download_file_path = writer_->path();
|
| - return next_handler_->OnResponseStarted(response, defer);
|
| + next_handler_->OnResponseStarted(response, std::move(controller));
|
| }
|
|
|
| -bool RedirectToFileResourceHandler::OnWillStart(const GURL& url, bool* defer) {
|
| +void RedirectToFileResourceHandler::OnWillStart(
|
| + const GURL& url,
|
| + std::unique_ptr<ResourceController> controller) {
|
| DCHECK(!writer_);
|
|
|
| // 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;
|
| + set_controller(std::move(controller));
|
| if (create_temporary_file_stream_.is_null()) {
|
| CreateTemporaryFileStream(
|
| base::Bind(&RedirectToFileResourceHandler::DidCreateTemporaryFile,
|
| @@ -181,7 +182,6 @@ bool RedirectToFileResourceHandler::OnWillStart(const GURL& url, bool* defer) {
|
| base::Bind(&RedirectToFileResourceHandler::DidCreateTemporaryFile,
|
| weak_factory_.GetWeakPtr()));
|
| }
|
| - return true;
|
| }
|
|
|
| bool RedirectToFileResourceHandler::OnWillRead(
|
| @@ -203,8 +203,9 @@ bool RedirectToFileResourceHandler::OnWillRead(
|
| return true;
|
| }
|
|
|
| -bool RedirectToFileResourceHandler::OnReadCompleted(int bytes_read,
|
| - bool* defer) {
|
| +void RedirectToFileResourceHandler::OnReadCompleted(
|
| + int bytes_read,
|
| + std::unique_ptr<ResourceController> controller) {
|
| DCHECK(buf_write_pending_);
|
| buf_write_pending_ = false;
|
|
|
| @@ -213,30 +214,35 @@ bool RedirectToFileResourceHandler::OnReadCompleted(int bytes_read,
|
| DCHECK(new_offset <= buf_->capacity());
|
| buf_->set_offset(new_offset);
|
|
|
| + if (!WriteMore()) {
|
| + controller->Cancel();
|
| + return;
|
| + }
|
| +
|
| if (BufIsFull()) {
|
| - did_defer_ = *defer = true;
|
| + set_controller(std::move(controller));
|
|
|
| if (buf_->capacity() == bytes_read) {
|
| // The network layer has saturated our buffer in one read. Next time, we
|
| // should give it a bigger buffer for it to fill.
|
| next_buffer_size_ = std::min(next_buffer_size_ * 2, kMaxReadBufSize);
|
| }
|
| + return;
|
| }
|
|
|
| - return WriteMore();
|
| + controller->Resume();
|
| }
|
|
|
| void RedirectToFileResourceHandler::OnResponseCompleted(
|
| const net::URLRequestStatus& status,
|
| - bool* defer) {
|
| + std::unique_ptr<ResourceController> controller) {
|
| if (writer_ && writer_->is_writing()) {
|
| completed_during_write_ = true;
|
| completed_status_ = status;
|
| - did_defer_ = true;
|
| - *defer = true;
|
| + set_controller(std::move(controller));
|
| return;
|
| }
|
| - next_handler_->OnResponseCompleted(status, defer);
|
| + next_handler_->OnResponseCompleted(status, std::move(controller));
|
| }
|
|
|
| void RedirectToFileResourceHandler::DidCreateTemporaryFile(
|
| @@ -244,24 +250,16 @@ void RedirectToFileResourceHandler::DidCreateTemporaryFile(
|
| std::unique_ptr<net::FileStream> file_stream,
|
| ShareableFileReference* deletable_file) {
|
| DCHECK(!writer_);
|
| + DCHECK(has_controller());
|
| if (error_code != base::File::FILE_OK) {
|
| - controller()->CancelWithError(net::FileErrorToNetError(error_code));
|
| + CancelWithError(net::FileErrorToNetError(error_code));
|
| return;
|
| }
|
|
|
| writer_ = new Writer(this, std::move(file_stream), deletable_file);
|
|
|
| // Resume the request.
|
| - DCHECK(did_defer_);
|
| - bool defer = false;
|
| - if (!next_handler_->OnWillStart(will_start_url_, &defer)) {
|
| - controller()->Cancel();
|
| - } else if (!defer) {
|
| - ResumeIfDeferred();
|
| - } else {
|
| - did_defer_ = false;
|
| - }
|
| - will_start_url_ = GURL();
|
| + next_handler_->OnWillStart(std::move(will_start_url_), TakeController());
|
| }
|
|
|
| void RedirectToFileResourceHandler::DidWriteToFile(int result) {
|
| @@ -284,21 +282,27 @@ void RedirectToFileResourceHandler::DidWriteToFile(int result) {
|
| completed_status_ = net::URLRequestStatus(net::URLRequestStatus::CANCELED,
|
| net::ERR_FAILED);
|
| }
|
| - if (!completed_during_write_)
|
| - controller()->CancelWithError(net::ERR_FAILED);
|
| + if (!completed_during_write_) {
|
| + // TODO(mmenke): Should out of band cancellation be able to set an error
|
| + // code? This case used to return ERR_FAILED. All other out of band
|
| + // cancels are aborts.
|
| + if (has_controller()) {
|
| + // If the write buffer is full, |this| has deferred the request, and
|
| + // can do an in-band cancel.
|
| + Cancel();
|
| + } else {
|
| + OutOfBandCancel(net::ERR_FAILED, true);
|
| + }
|
| + return;
|
| + }
|
| }
|
|
|
| if (completed_during_write_ && !writer_->is_writing()) {
|
| // 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(completed_status_, &defer);
|
| - if (!defer) {
|
| - ResumeIfDeferred();
|
| - } else {
|
| - did_defer_ = false;
|
| - }
|
| + DCHECK(has_controller());
|
| + next_handler_->OnResponseCompleted(completed_status_, TakeController());
|
| }
|
| }
|
|
|
| @@ -357,10 +361,8 @@ bool RedirectToFileResourceHandler::BufIsFull() const {
|
| }
|
|
|
| void RedirectToFileResourceHandler::ResumeIfDeferred() {
|
| - if (did_defer_) {
|
| - did_defer_ = false;
|
| - controller()->Resume();
|
| - }
|
| + if (has_controller())
|
| + Resume();
|
| }
|
|
|
| } // namespace content
|
|
|