[WebSocket] Send (request|response)_headers_text to the inspector.
[chromium-blink-merge.git] / content / browser / loader / throttling_resource_handler.cc
blob0de6177842469d8ad983d064a694b3638d9a09a5
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"
10 #include "net/url_request/url_request.h"
12 namespace content {
14 ThrottlingResourceHandler::ThrottlingResourceHandler(
15 scoped_ptr<ResourceHandler> next_handler,
16 net::URLRequest* request,
17 ScopedVector<ResourceThrottle> throttles)
18 : LayeredResourceHandler(request, next_handler.Pass()),
19 deferred_stage_(DEFERRED_NONE),
20 throttles_(throttles.Pass()),
21 next_index_(0),
22 cancelled_by_resource_throttle_(false) {
23 for (size_t i = 0; i < throttles_.size(); ++i) {
24 throttles_[i]->set_controller(this);
25 // Throttles must have a name, as otherwise, bugs where a throttle fails
26 // to resume a request can be very difficult to debug.
27 DCHECK(throttles_[i]->GetNameForLogging());
31 ThrottlingResourceHandler::~ThrottlingResourceHandler() {
34 bool ThrottlingResourceHandler::OnRequestRedirected(int request_id,
35 const GURL& new_url,
36 ResourceResponse* response,
37 bool* defer) {
38 DCHECK(!cancelled_by_resource_throttle_);
40 *defer = false;
41 while (next_index_ < throttles_.size()) {
42 int index = next_index_;
43 throttles_[index]->WillRedirectRequest(new_url, defer);
44 next_index_++;
45 if (cancelled_by_resource_throttle_)
46 return false;
47 if (*defer) {
48 OnRequestDefered(index);
49 deferred_stage_ = DEFERRED_REDIRECT;
50 deferred_url_ = new_url;
51 deferred_response_ = response;
52 return true; // Do not cancel.
56 next_index_ = 0; // Reset for next time.
58 return next_handler_->OnRequestRedirected(request_id, new_url, response,
59 defer);
62 bool ThrottlingResourceHandler::OnWillStart(int request_id,
63 const GURL& url,
64 bool* defer) {
65 DCHECK(!cancelled_by_resource_throttle_);
67 *defer = false;
68 while (next_index_ < throttles_.size()) {
69 int index = next_index_;
70 throttles_[index]->WillStartRequest(defer);
71 next_index_++;
72 if (cancelled_by_resource_throttle_)
73 return false;
74 if (*defer) {
75 OnRequestDefered(index);
76 deferred_stage_ = DEFERRED_START;
77 deferred_url_ = url;
78 return true; // Do not cancel.
82 next_index_ = 0; // Reset for next time.
84 return next_handler_->OnWillStart(request_id, url, defer);
87 bool ThrottlingResourceHandler::OnBeforeNetworkStart(int request_id,
88 const GURL& url,
89 bool* defer) {
90 DCHECK(!cancelled_by_resource_throttle_);
92 *defer = false;
93 while (next_index_ < throttles_.size()) {
94 int index = next_index_;
95 throttles_[index]->OnBeforeNetworkStart(defer);
96 next_index_++;
97 if (cancelled_by_resource_throttle_)
98 return false;
99 if (*defer) {
100 OnRequestDefered(index);
101 deferred_stage_ = DEFERRED_NETWORK_START;
102 deferred_url_ = url;
103 return true; // Do not cancel.
107 next_index_ = 0; // Reset for next time.
109 return next_handler_->OnBeforeNetworkStart(request_id, url, defer);
112 bool ThrottlingResourceHandler::OnResponseStarted(int request_id,
113 ResourceResponse* response,
114 bool* defer) {
115 DCHECK(!cancelled_by_resource_throttle_);
117 while (next_index_ < throttles_.size()) {
118 int index = next_index_;
119 throttles_[index]->WillProcessResponse(defer);
120 next_index_++;
121 if (cancelled_by_resource_throttle_)
122 return false;
123 if (*defer) {
124 OnRequestDefered(index);
125 deferred_stage_ = DEFERRED_RESPONSE;
126 deferred_response_ = response;
127 return true; // Do not cancel.
131 next_index_ = 0; // Reset for next time.
133 return next_handler_->OnResponseStarted(request_id, response, defer);
136 void ThrottlingResourceHandler::Cancel() {
137 cancelled_by_resource_throttle_ = true;
138 controller()->Cancel();
141 void ThrottlingResourceHandler::CancelAndIgnore() {
142 cancelled_by_resource_throttle_ = true;
143 controller()->CancelAndIgnore();
146 void ThrottlingResourceHandler::CancelWithError(int error_code) {
147 cancelled_by_resource_throttle_ = true;
148 controller()->CancelWithError(error_code);
151 void ThrottlingResourceHandler::Resume() {
152 DCHECK(!cancelled_by_resource_throttle_);
154 DeferredStage last_deferred_stage = deferred_stage_;
155 deferred_stage_ = DEFERRED_NONE;
156 // Clear information about the throttle that delayed the request.
157 request()->LogUnblocked();
158 switch (last_deferred_stage) {
159 case DEFERRED_NONE:
160 NOTREACHED();
161 break;
162 case DEFERRED_START:
163 ResumeStart();
164 break;
165 case DEFERRED_NETWORK_START:
166 ResumeNetworkStart();
167 break;
168 case DEFERRED_REDIRECT:
169 ResumeRedirect();
170 break;
171 case DEFERRED_RESPONSE:
172 ResumeResponse();
173 break;
177 void ThrottlingResourceHandler::ResumeStart() {
178 DCHECK(!cancelled_by_resource_throttle_);
180 GURL url = deferred_url_;
181 deferred_url_ = GURL();
183 bool defer = false;
184 if (!OnWillStart(GetRequestID(), url, &defer)) {
185 controller()->Cancel();
186 } else if (!defer) {
187 controller()->Resume();
191 void ThrottlingResourceHandler::ResumeNetworkStart() {
192 DCHECK(!cancelled_by_resource_throttle_);
194 GURL url = deferred_url_;
195 deferred_url_ = GURL();
197 bool defer = false;
198 if (!OnBeforeNetworkStart(GetRequestID(), url, &defer)) {
199 controller()->Cancel();
200 } else if (!defer) {
201 controller()->Resume();
205 void ThrottlingResourceHandler::ResumeRedirect() {
206 DCHECK(!cancelled_by_resource_throttle_);
208 GURL new_url = deferred_url_;
209 deferred_url_ = GURL();
210 scoped_refptr<ResourceResponse> response;
211 deferred_response_.swap(response);
213 bool defer = false;
214 if (!OnRequestRedirected(GetRequestID(), new_url, response.get(), &defer)) {
215 controller()->Cancel();
216 } else if (!defer) {
217 controller()->Resume();
221 void ThrottlingResourceHandler::ResumeResponse() {
222 DCHECK(!cancelled_by_resource_throttle_);
224 scoped_refptr<ResourceResponse> response;
225 deferred_response_.swap(response);
227 bool defer = false;
228 if (!OnResponseStarted(GetRequestID(), response.get(), &defer)) {
229 controller()->Cancel();
230 } else if (!defer) {
231 controller()->Resume();
235 void ThrottlingResourceHandler::OnRequestDefered(int throttle_index) {
236 request()->LogBlockedBy(throttles_[throttle_index]->GetNameForLogging());
239 } // namespace content