| Index: content/browser/loader/detachable_resource_handler.cc
|
| diff --git a/content/browser/loader/detachable_resource_handler.cc b/content/browser/loader/detachable_resource_handler.cc
|
| index 2e1af5e7c6c396821e762203c1d9628012f1093b..e886f394b51779a73e7ac6780b7f4d4a095711d9 100644
|
| --- a/content/browser/loader/detachable_resource_handler.cc
|
| +++ b/content/browser/loader/detachable_resource_handler.cc
|
| @@ -7,8 +7,11 @@
|
| #include <utility>
|
|
|
| #include "base/logging.h"
|
| +#include "base/memory/ptr_util.h"
|
| #include "base/time/time.h"
|
| +#include "content/browser/loader/null_resource_controller.h"
|
| #include "content/browser/loader/resource_request_info_impl.h"
|
| +#include "content/public/browser/resource_controller.h"
|
| #include "net/base/io_buffer.h"
|
| #include "net/base/net_errors.h"
|
| #include "net/url_request/url_request.h"
|
| @@ -21,6 +24,32 @@ const int kReadBufSize = 32 * 1024;
|
|
|
| namespace content {
|
|
|
| +// ResourceController that, when invoked, runs the corresponding method on
|
| +// ResourceHandler.
|
| +class DetachableResourceHandler::Controller : public ResourceController {
|
| + public:
|
| + explicit Controller(DetachableResourceHandler* detachable_handler)
|
| + : detachable_handler_(detachable_handler){};
|
| +
|
| + ~Controller() override {}
|
| +
|
| + // ResourceController implementation:
|
| + void Resume() override { detachable_handler_->Resume(); }
|
| +
|
| + void Cancel() override { detachable_handler_->Cancel(); }
|
| +
|
| + void CancelAndIgnore() override { detachable_handler_->CancelAndIgnore(); }
|
| +
|
| + void CancelWithError(int error_code) override {
|
| + detachable_handler_->CancelWithError(error_code);
|
| + }
|
| +
|
| + private:
|
| + DetachableResourceHandler* detachable_handler_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(Controller);
|
| +};
|
| +
|
| DetachableResourceHandler::DetachableResourceHandler(
|
| net::URLRequest* request,
|
| base::TimeDelta cancel_delay,
|
| @@ -28,7 +57,6 @@ DetachableResourceHandler::DetachableResourceHandler(
|
| : ResourceHandler(request),
|
| next_handler_(std::move(next_handler)),
|
| cancel_delay_(cancel_delay),
|
| - is_deferred_(false),
|
| is_finished_(false) {
|
| GetRequestInfo()->set_detachable_handler(this);
|
| }
|
| @@ -46,9 +74,10 @@ void DetachableResourceHandler::Detach() {
|
| // Simulate a cancel on the next handler before destroying it.
|
| net::URLRequestStatus status(net::URLRequestStatus::CANCELED,
|
| net::ERR_ABORTED);
|
| - bool defer_ignored = false;
|
| - next_handler_->OnResponseCompleted(status, &defer_ignored);
|
| - DCHECK(!defer_ignored);
|
| + bool was_resumed;
|
| + next_handler_->OnResponseCompleted(
|
| + status, base::MakeUnique<NullResourceController>(&was_resumed));
|
| + DCHECK(!was_resumed);
|
| // If |next_handler_| were to defer its shutdown in OnResponseCompleted,
|
| // this would destroy it anyway. Fortunately, AsyncResourceHandler never
|
| // does this anyway, so DCHECK it. MimeTypeResourceHandler and RVH shutdown
|
| @@ -66,66 +95,65 @@ void DetachableResourceHandler::Detach() {
|
|
|
| // Time the request out if it takes too long.
|
| detached_timer_.reset(new base::OneShotTimer());
|
| - detached_timer_->Start(
|
| - FROM_HERE, cancel_delay_, this, &DetachableResourceHandler::Cancel);
|
| + detached_timer_->Start(FROM_HERE, cancel_delay_, this,
|
| + &DetachableResourceHandler::OnTimedOut);
|
|
|
| // Resume if necessary. The request may have been deferred, say, waiting on a
|
| // full buffer in AsyncResourceHandler. Now that it has been detached, resume
|
| // and drain it.
|
| - if (is_deferred_) {
|
| + if (has_controller()) {
|
| // The nested ResourceHandler may have logged that it's blocking the
|
| // request. Log it as no longer doing so, to avoid a DCHECK on resume.
|
| request()->LogUnblocked();
|
| +
|
| + // Resume.
|
| Resume();
|
| }
|
| }
|
|
|
| -void DetachableResourceHandler::SetController(ResourceController* controller) {
|
| - ResourceHandler::SetController(controller);
|
| -
|
| - // Intercept the ResourceController for downstream handlers to keep track of
|
| - // whether the request is deferred.
|
| - if (next_handler_)
|
| - next_handler_->SetController(this);
|
| -}
|
| -
|
| -bool DetachableResourceHandler::OnRequestRedirected(
|
| +void DetachableResourceHandler::OnRequestRedirected(
|
| const net::RedirectInfo& redirect_info,
|
| ResourceResponse* response,
|
| - bool* defer) {
|
| - DCHECK(!is_deferred_);
|
| + std::unique_ptr<ResourceController> controller) {
|
| + DCHECK(!has_controller());
|
|
|
| - if (!next_handler_)
|
| - return true;
|
| + if (!next_handler_) {
|
| + controller->Resume();
|
| + return;
|
| + }
|
|
|
| - bool ret = next_handler_->OnRequestRedirected(
|
| - redirect_info, response, &is_deferred_);
|
| - *defer = is_deferred_;
|
| - return ret;
|
| + set_controller(std::move(controller));
|
| + next_handler_->OnRequestRedirected(redirect_info, response,
|
| + base::MakeUnique<Controller>(this));
|
| }
|
|
|
| -bool DetachableResourceHandler::OnResponseStarted(ResourceResponse* response,
|
| - bool* defer) {
|
| - DCHECK(!is_deferred_);
|
| +void DetachableResourceHandler::OnResponseStarted(
|
| + ResourceResponse* response,
|
| + std::unique_ptr<ResourceController> controller) {
|
| + DCHECK(!has_controller());
|
|
|
| - if (!next_handler_)
|
| - return true;
|
| + if (!next_handler_) {
|
| + controller->Resume();
|
| + return;
|
| + }
|
|
|
| - bool ret =
|
| - next_handler_->OnResponseStarted(response, &is_deferred_);
|
| - *defer = is_deferred_;
|
| - return ret;
|
| + set_controller(std::move(controller));
|
| + next_handler_->OnResponseStarted(response,
|
| + base::MakeUnique<Controller>(this));
|
| }
|
|
|
| -bool DetachableResourceHandler::OnWillStart(const GURL& url, bool* defer) {
|
| - DCHECK(!is_deferred_);
|
| +void DetachableResourceHandler::OnWillStart(
|
| + const GURL& url,
|
| + std::unique_ptr<ResourceController> controller) {
|
| + DCHECK(!has_controller());
|
|
|
| - if (!next_handler_)
|
| - return true;
|
| + if (!next_handler_) {
|
| + controller->Resume();
|
| + return;
|
| + }
|
|
|
| - bool ret = next_handler_->OnWillStart(url, &is_deferred_);
|
| - *defer = is_deferred_;
|
| - return ret;
|
| + set_controller(std::move(controller));
|
| + next_handler_->OnWillStart(url, base::MakeUnique<Controller>(this));
|
| }
|
|
|
| bool DetachableResourceHandler::OnWillRead(scoped_refptr<net::IOBuffer>* buf,
|
| @@ -143,31 +171,35 @@ bool DetachableResourceHandler::OnWillRead(scoped_refptr<net::IOBuffer>* buf,
|
| return next_handler_->OnWillRead(buf, buf_size, min_size);
|
| }
|
|
|
| -bool DetachableResourceHandler::OnReadCompleted(int bytes_read, bool* defer) {
|
| - DCHECK(!is_deferred_);
|
| +void DetachableResourceHandler::OnReadCompleted(
|
| + int bytes_read,
|
| + std::unique_ptr<ResourceController> controller) {
|
| + DCHECK(!has_controller());
|
|
|
| - if (!next_handler_)
|
| - return true;
|
| + if (!next_handler_) {
|
| + controller->Resume();
|
| + return;
|
| + }
|
|
|
| - bool ret =
|
| - next_handler_->OnReadCompleted(bytes_read, &is_deferred_);
|
| - *defer = is_deferred_;
|
| - return ret;
|
| + set_controller(std::move(controller));
|
| + next_handler_->OnReadCompleted(bytes_read,
|
| + base::MakeUnique<Controller>(this));
|
| }
|
|
|
| void DetachableResourceHandler::OnResponseCompleted(
|
| const net::URLRequestStatus& status,
|
| - bool* defer) {
|
| + std::unique_ptr<ResourceController> controller) {
|
| // No DCHECK(!is_deferred_) as the request may have been cancelled while
|
| // deferred.
|
|
|
| - if (!next_handler_)
|
| + if (!next_handler_) {
|
| + controller->Resume();
|
| return;
|
| + }
|
|
|
| is_finished_ = true;
|
|
|
| - next_handler_->OnResponseCompleted(status, &is_deferred_);
|
| - *defer = is_deferred_;
|
| + next_handler_->OnResponseCompleted(status, std::move(controller));
|
| }
|
|
|
| void DetachableResourceHandler::OnDataDownloaded(int bytes_downloaded) {
|
| @@ -177,22 +209,13 @@ void DetachableResourceHandler::OnDataDownloaded(int bytes_downloaded) {
|
| next_handler_->OnDataDownloaded(bytes_downloaded);
|
| }
|
|
|
| -void DetachableResourceHandler::Resume() {
|
| - DCHECK(is_deferred_);
|
| - is_deferred_ = false;
|
| - controller()->Resume();
|
| -}
|
| -
|
| -void DetachableResourceHandler::Cancel() {
|
| - controller()->Cancel();
|
| -}
|
| -
|
| -void DetachableResourceHandler::CancelAndIgnore() {
|
| - controller()->CancelAndIgnore();
|
| -}
|
| +void DetachableResourceHandler::OnTimedOut() {
|
| + // Requests are only timed out after being detached, and shouldn't be deferred
|
| + // once detached.
|
| + DCHECK(!next_handler_);
|
| + DCHECK(!has_controller());
|
|
|
| -void DetachableResourceHandler::CancelWithError(int error_code) {
|
| - controller()->CancelWithError(error_code);
|
| + OutOfBandCancel();
|
| }
|
|
|
| } // namespace content
|
|
|