- add sources.
[platform/framework/web/crosswalk.git] / src / content / browser / loader / throttling_resource_handler.cc
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.
4
5 #include "content/browser/loader/throttling_resource_handler.h"
6
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
11 namespace content {
12
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()),
20       index_(0),
21       cancelled_by_resource_throttle_(false) {
22   for (size_t i = 0; i < throttles_.size(); ++i)
23     throttles_[i]->set_controller(this);
24 }
25
26 ThrottlingResourceHandler::~ThrottlingResourceHandler() {
27 }
28
29 bool ThrottlingResourceHandler::OnRequestRedirected(int request_id,
30                                                     const GURL& new_url,
31                                                     ResourceResponse* response,
32                                                     bool* defer) {
33   DCHECK(!cancelled_by_resource_throttle_);
34
35   *defer = false;
36   while (index_ < throttles_.size()) {
37     throttles_[index_]->WillRedirectRequest(new_url, defer);
38     index_++;
39     if (cancelled_by_resource_throttle_)
40       return false;
41     if (*defer) {
42       deferred_stage_ = DEFERRED_REDIRECT;
43       deferred_url_ = new_url;
44       deferred_response_ = response;
45       return true;  // Do not cancel.
46     }
47   }
48
49   index_ = 0;  // Reset for next time.
50
51   return next_handler_->OnRequestRedirected(request_id, new_url, response,
52                                             defer);
53 }
54
55 bool ThrottlingResourceHandler::OnWillStart(int request_id,
56                                             const GURL& url,
57                                             bool* defer) {
58   DCHECK(!cancelled_by_resource_throttle_);
59
60   *defer = false;
61   while (index_ < throttles_.size()) {
62     throttles_[index_]->WillStartRequest(defer);
63     index_++;
64     if (cancelled_by_resource_throttle_)
65       return false;
66     if (*defer) {
67       deferred_stage_ = DEFERRED_START;
68       deferred_url_ = url;
69       return true;  // Do not cancel.
70     }
71   }
72
73   index_ = 0;  // Reset for next time.
74
75   return next_handler_->OnWillStart(request_id, url, defer);
76 }
77
78 bool ThrottlingResourceHandler::OnResponseStarted(int request_id,
79                                                   ResourceResponse* response,
80                                                   bool* defer) {
81   DCHECK(!cancelled_by_resource_throttle_);
82
83   while (index_ < throttles_.size()) {
84     throttles_[index_]->WillProcessResponse(defer);
85     index_++;
86     if (cancelled_by_resource_throttle_)
87       return false;
88     if (*defer) {
89       deferred_stage_ = DEFERRED_RESPONSE;
90       deferred_response_ = response;
91       return true;  // Do not cancel.
92     }
93   }
94
95   index_ = 0;  // Reset for next time.
96
97   return next_handler_->OnResponseStarted(request_id, response, defer);
98 }
99
100 void ThrottlingResourceHandler::Cancel() {
101   cancelled_by_resource_throttle_ = true;
102   controller()->Cancel();
103 }
104
105 void ThrottlingResourceHandler::CancelAndIgnore() {
106   cancelled_by_resource_throttle_ = true;
107   controller()->CancelAndIgnore();
108 }
109
110 void ThrottlingResourceHandler::CancelWithError(int error_code) {
111   cancelled_by_resource_throttle_ = true;
112   controller()->CancelWithError(error_code);
113 }
114
115 void ThrottlingResourceHandler::Resume() {
116   DCHECK(!cancelled_by_resource_throttle_);
117
118   DeferredStage last_deferred_stage = deferred_stage_;
119   deferred_stage_ = DEFERRED_NONE;
120   switch (last_deferred_stage) {
121     case DEFERRED_NONE:
122       NOTREACHED();
123       break;
124     case DEFERRED_START:
125       ResumeStart();
126       break;
127     case DEFERRED_REDIRECT:
128       ResumeRedirect();
129       break;
130     case DEFERRED_RESPONSE:
131       ResumeResponse();
132       break;
133   }
134 }
135
136 void ThrottlingResourceHandler::ResumeStart() {
137   DCHECK(!cancelled_by_resource_throttle_);
138
139   GURL url = deferred_url_;
140   deferred_url_ = GURL();
141
142   bool defer = false;
143   if (!OnWillStart(GetRequestID(), url, &defer)) {
144     controller()->Cancel();
145   } else if (!defer) {
146     controller()->Resume();
147   }
148 }
149
150 void ThrottlingResourceHandler::ResumeRedirect() {
151   DCHECK(!cancelled_by_resource_throttle_);
152
153   GURL new_url = deferred_url_;
154   deferred_url_ = GURL();
155   scoped_refptr<ResourceResponse> response;
156   deferred_response_.swap(response);
157
158   bool defer = false;
159   if (!OnRequestRedirected(GetRequestID(), new_url, response.get(), &defer)) {
160     controller()->Cancel();
161   } else if (!defer) {
162     controller()->Resume();
163   }
164 }
165
166 void ThrottlingResourceHandler::ResumeResponse() {
167   DCHECK(!cancelled_by_resource_throttle_);
168
169   scoped_refptr<ResourceResponse> response;
170   deferred_response_.swap(response);
171
172   bool defer = false;
173   if (!OnResponseStarted(GetRequestID(), response.get(), &defer)) {
174     controller()->Cancel();
175   } else if (!defer) {
176     controller()->Resume();
177   }
178 }
179
180 }  // namespace content