1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/loader/throttling_resource_handler.h"
7 #include "content/browser/loader/resource_request_info_impl.h"
8 #include "content/public/browser/resource_throttle.h"
9 #include "content/public/common/resource_response.h"
13 ThrottlingResourceHandler::ThrottlingResourceHandler(
14 scoped_ptr<ResourceHandler> next_handler,
15 net::URLRequest* request,
16 ScopedVector<ResourceThrottle> throttles)
17 : LayeredResourceHandler(request, next_handler.Pass()),
18 deferred_stage_(DEFERRED_NONE),
19 throttles_(throttles.Pass()),
21 cancelled_by_resource_throttle_(false) {
22 for (size_t i = 0; i < throttles_.size(); ++i)
23 throttles_[i]->set_controller(this);
26 ThrottlingResourceHandler::~ThrottlingResourceHandler() {
29 bool ThrottlingResourceHandler::OnRequestRedirected(int request_id,
31 ResourceResponse* response,
33 DCHECK(!cancelled_by_resource_throttle_);
36 while (index_ < throttles_.size()) {
37 throttles_[index_]->WillRedirectRequest(new_url, defer);
39 if (cancelled_by_resource_throttle_)
42 deferred_stage_ = DEFERRED_REDIRECT;
43 deferred_url_ = new_url;
44 deferred_response_ = response;
45 return true; // Do not cancel.
49 index_ = 0; // Reset for next time.
51 return next_handler_->OnRequestRedirected(request_id, new_url, response,
55 bool ThrottlingResourceHandler::OnWillStart(int request_id,
58 DCHECK(!cancelled_by_resource_throttle_);
61 while (index_ < throttles_.size()) {
62 throttles_[index_]->WillStartRequest(defer);
64 if (cancelled_by_resource_throttle_)
67 deferred_stage_ = DEFERRED_START;
69 return true; // Do not cancel.
73 index_ = 0; // Reset for next time.
75 return next_handler_->OnWillStart(request_id, url, defer);
78 bool ThrottlingResourceHandler::OnResponseStarted(int request_id,
79 ResourceResponse* response,
81 DCHECK(!cancelled_by_resource_throttle_);
83 while (index_ < throttles_.size()) {
84 throttles_[index_]->WillProcessResponse(defer);
86 if (cancelled_by_resource_throttle_)
89 deferred_stage_ = DEFERRED_RESPONSE;
90 deferred_response_ = response;
91 return true; // Do not cancel.
95 index_ = 0; // Reset for next time.
97 return next_handler_->OnResponseStarted(request_id, response, defer);
100 void ThrottlingResourceHandler::Cancel() {
101 cancelled_by_resource_throttle_ = true;
102 controller()->Cancel();
105 void ThrottlingResourceHandler::CancelAndIgnore() {
106 cancelled_by_resource_throttle_ = true;
107 controller()->CancelAndIgnore();
110 void ThrottlingResourceHandler::CancelWithError(int error_code) {
111 cancelled_by_resource_throttle_ = true;
112 controller()->CancelWithError(error_code);
115 void ThrottlingResourceHandler::Resume() {
116 DCHECK(!cancelled_by_resource_throttle_);
118 DeferredStage last_deferred_stage = deferred_stage_;
119 deferred_stage_ = DEFERRED_NONE;
120 switch (last_deferred_stage) {
127 case DEFERRED_REDIRECT:
130 case DEFERRED_RESPONSE:
136 void ThrottlingResourceHandler::ResumeStart() {
137 DCHECK(!cancelled_by_resource_throttle_);
139 GURL url = deferred_url_;
140 deferred_url_ = GURL();
143 if (!OnWillStart(GetRequestID(), url, &defer)) {
144 controller()->Cancel();
146 controller()->Resume();
150 void ThrottlingResourceHandler::ResumeRedirect() {
151 DCHECK(!cancelled_by_resource_throttle_);
153 GURL new_url = deferred_url_;
154 deferred_url_ = GURL();
155 scoped_refptr<ResourceResponse> response;
156 deferred_response_.swap(response);
159 if (!OnRequestRedirected(GetRequestID(), new_url, response.get(), &defer)) {
160 controller()->Cancel();
162 controller()->Resume();
166 void ThrottlingResourceHandler::ResumeResponse() {
167 DCHECK(!cancelled_by_resource_throttle_);
169 scoped_refptr<ResourceResponse> response;
170 deferred_response_.swap(response);
173 if (!OnResponseStarted(GetRequestID(), response.get(), &defer)) {
174 controller()->Cancel();
176 controller()->Resume();
180 } // namespace content