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 a30d9dc68e2a3e4363d634b9cd6eff428d7061dd..b80288ff7aac0cf2e8657f4dd13631512ea2092e 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; |
+ HoldController(std::move(controller)); |
request()->LogBlockedBy("RedirectToFileResourceHandler"); |
if (create_temporary_file_stream_.is_null()) { |
CreateTemporaryFileStream( |
@@ -182,7 +183,6 @@ bool RedirectToFileResourceHandler::OnWillStart(const GURL& url, bool* defer) { |
base::Bind(&RedirectToFileResourceHandler::DidCreateTemporaryFile, |
weak_factory_.GetWeakPtr())); |
} |
- return true; |
} |
bool RedirectToFileResourceHandler::OnWillRead( |
@@ -204,8 +204,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; |
@@ -214,32 +215,32 @@ bool RedirectToFileResourceHandler::OnReadCompleted(int bytes_read, |
DCHECK(new_offset <= buf_->capacity()); |
buf_->set_offset(new_offset); |
- if (BufIsFull()) { |
- did_defer_ = *defer = true; |
- request()->LogBlockedBy("RedirectToFileResourceHandler"); |
+ HoldController(std::move(controller)); |
+ request()->LogBlockedBy("RedirectToFileResourceHandler"); |
- 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); |
- } |
+ if (BufIsFull() && 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 WriteMore(); |
+ if (!WriteMore()) { |
Charlie Harrison
2017/01/25 20:23:00
Can you comment that WriteMore will resume the req
mmenke
2017/01/25 22:07:59
Done.
|
+ Cancel(); |
+ return; |
+ } |
} |
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; |
+ HoldController(std::move(controller)); |
request()->LogBlockedBy("RedirectToFileResourceHandler"); |
return; |
} |
- next_handler_->OnResponseCompleted(status, defer); |
+ next_handler_->OnResponseCompleted(status, std::move(controller)); |
} |
void RedirectToFileResourceHandler::DidCreateTemporaryFile( |
@@ -247,25 +248,17 @@ 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; |
request()->LogUnblocked(); |
- if (!next_handler_->OnWillStart(will_start_url_, &defer)) { |
- controller()->Cancel(); |
- } else if (!defer) { |
- Resume(); |
- } else { |
- did_defer_ = false; |
- } |
- will_start_url_ = GURL(); |
+ next_handler_->OnWillStart(std::move(will_start_url_), ReleaseController()); |
} |
void RedirectToFileResourceHandler::DidWriteToFile(int result) { |
@@ -288,22 +281,25 @@ 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_) { |
+ if (has_controller()) { |
+ // If the write buffer is full, |this| has deferred the request, and |
+ // can do an in-band cancel. |
+ CancelWithError(net::ERR_FAILED); |
+ } 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; |
+ DCHECK(has_controller()); |
request()->LogUnblocked(); |
- next_handler_->OnResponseCompleted(completed_status_, &defer); |
- if (!defer) { |
- Resume(); |
- } else { |
- did_defer_ = false; |
- } |
+ next_handler_->OnResponseCompleted(completed_status_, ReleaseController()); |
} |
} |
@@ -314,17 +310,13 @@ bool RedirectToFileResourceHandler::WriteMore() { |
// We've caught up to the network load, but it may be in the process of |
// appending more data to the buffer. |
if (!buf_write_pending_) { |
- if (BufIsFull()) { |
- request()->LogUnblocked(); |
- Resume(); |
- } |
buf_->set_offset(0); |
write_cursor_ = 0; |
} |
- return true; |
+ break; |
} |
if (writer_->is_writing()) |
- return true; |
+ break; |
DCHECK(write_cursor_ < buf_->offset()); |
// Create a temporary buffer pointing to a subsection of the data buffer so |
@@ -347,12 +339,18 @@ bool RedirectToFileResourceHandler::WriteMore() { |
int rv = writer_->Write(wrapped.get(), write_len); |
if (rv == net::ERR_IO_PENDING) |
- return true; |
+ break; |
if (rv <= 0) |
return false; |
next_handler_->OnDataDownloaded(rv); |
write_cursor_ += rv; |
} |
+ |
+ if (has_controller() && !BufIsFull() && !completed_during_write_) { |
+ request()->LogUnblocked(); |
+ Resume(); |
+ } |
+ return true; |
} |
bool RedirectToFileResourceHandler::BufIsFull() const { |
@@ -363,10 +361,4 @@ bool RedirectToFileResourceHandler::BufIsFull() const { |
return buf_->RemainingCapacity() <= (2 * net::kMaxBytesToSniff); |
} |
-void RedirectToFileResourceHandler::Resume() { |
- DCHECK(did_defer_); |
- did_defer_ = false; |
- controller()->Resume(); |
-} |
- |
} // namespace content |