Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(191)

Side by Side Diff: content/browser/loader/detachable_resource_handler.cc

Issue 2526983002: Refactor ResourceHandler API. (Closed)
Patch Set: Response to comments Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/loader/detachable_resource_handler.h" 5 #include "content/browser/loader/detachable_resource_handler.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/memory/ptr_util.h"
10 #include "base/time/time.h" 11 #include "base/time/time.h"
12 #include "content/browser/loader/null_resource_controller.h"
13 #include "content/browser/loader/resource_controller.h"
11 #include "content/browser/loader/resource_request_info_impl.h" 14 #include "content/browser/loader/resource_request_info_impl.h"
12 #include "net/base/io_buffer.h" 15 #include "net/base/io_buffer.h"
13 #include "net/base/net_errors.h" 16 #include "net/base/net_errors.h"
14 #include "net/url_request/url_request.h" 17 #include "net/url_request/url_request.h"
15 #include "net/url_request/url_request_status.h" 18 #include "net/url_request/url_request_status.h"
16 19
17 namespace { 20 namespace {
18 // This matches the maximum allocation size of AsyncResourceHandler. 21 // This matches the maximum allocation size of AsyncResourceHandler.
19 const int kReadBufSize = 32 * 1024; 22 const int kReadBufSize = 32 * 1024;
20 } 23 }
21 24
22 namespace content { 25 namespace content {
23 26
27 // ResourceController that, when invoked, runs the corresponding method on
28 // ResourceHandler.
29 class DetachableResourceHandler::Controller : public ResourceController {
30 public:
31 explicit Controller(DetachableResourceHandler* detachable_handler)
32 : detachable_handler_(detachable_handler){};
33
34 ~Controller() override {}
35
36 // ResourceController implementation:
37 void Resume() override {
38 MarkAsUsed();
39 detachable_handler_->Resume();
40 }
41
42 void Cancel() override {
43 MarkAsUsed();
44 detachable_handler_->Cancel();
45 }
46
47 void CancelAndIgnore() override {
48 MarkAsUsed();
49 detachable_handler_->CancelAndIgnore();
50 }
51
52 void CancelWithError(int error_code) override {
53 MarkAsUsed();
54 detachable_handler_->CancelWithError(error_code);
55 }
56
57 private:
58 void MarkAsUsed() {
59 #if DCHECK_IS_ON()
60 DCHECK(!used_);
61 used_ = true;
62 #endif
63 }
64
65 #if DCHECK_IS_ON()
66 bool used_ = false;
67 #endif
68
69 DetachableResourceHandler* detachable_handler_;
70
71 DISALLOW_COPY_AND_ASSIGN(Controller);
72 };
73
24 DetachableResourceHandler::DetachableResourceHandler( 74 DetachableResourceHandler::DetachableResourceHandler(
25 net::URLRequest* request, 75 net::URLRequest* request,
26 base::TimeDelta cancel_delay, 76 base::TimeDelta cancel_delay,
27 std::unique_ptr<ResourceHandler> next_handler) 77 std::unique_ptr<ResourceHandler> next_handler)
28 : ResourceHandler(request), 78 : ResourceHandler(request),
29 next_handler_(std::move(next_handler)), 79 next_handler_(std::move(next_handler)),
30 cancel_delay_(cancel_delay), 80 cancel_delay_(cancel_delay),
31 is_deferred_(false),
32 is_finished_(false) { 81 is_finished_(false) {
33 GetRequestInfo()->set_detachable_handler(this); 82 GetRequestInfo()->set_detachable_handler(this);
34 } 83 }
35 84
36 DetachableResourceHandler::~DetachableResourceHandler() { 85 DetachableResourceHandler::~DetachableResourceHandler() {
37 // Cleanup back-pointer stored on the request info. 86 // Cleanup back-pointer stored on the request info.
38 GetRequestInfo()->set_detachable_handler(NULL); 87 GetRequestInfo()->set_detachable_handler(NULL);
39 } 88 }
40 89
90 void DetachableResourceHandler::SetDelegate(Delegate* delegate) {
91 ResourceHandler::SetDelegate(delegate);
92 if (next_handler_)
93 next_handler_->SetDelegate(delegate);
94 }
95
41 void DetachableResourceHandler::Detach() { 96 void DetachableResourceHandler::Detach() {
42 if (is_detached()) 97 if (is_detached())
43 return; 98 return;
44 99
45 if (!is_finished_) { 100 if (!is_finished_) {
46 // Simulate a cancel on the next handler before destroying it. 101 // Simulate a cancel on the next handler before destroying it.
47 net::URLRequestStatus status(net::URLRequestStatus::CANCELED, 102 net::URLRequestStatus status(net::URLRequestStatus::CANCELED,
48 net::ERR_ABORTED); 103 net::ERR_ABORTED);
49 bool defer_ignored = false; 104 bool was_resumed;
50 next_handler_->OnResponseCompleted(status, &defer_ignored); 105 // TODO(mmenke): Get rid of NullResourceController and do something more
51 DCHECK(!defer_ignored); 106 // reasonable.
107 next_handler_->OnResponseCompleted(
108 status, base::MakeUnique<NullResourceController>(&was_resumed));
109 DCHECK(was_resumed);
52 // If |next_handler_| were to defer its shutdown in OnResponseCompleted, 110 // If |next_handler_| were to defer its shutdown in OnResponseCompleted,
53 // this would destroy it anyway. Fortunately, AsyncResourceHandler never 111 // this would destroy it anyway. Fortunately, AsyncResourceHandler never
54 // does this anyway, so DCHECK it. MimeTypeResourceHandler and RVH shutdown 112 // does this anyway, so DCHECK it. MimeTypeResourceHandler and RVH shutdown
55 // already ignore deferred ResourceHandler shutdown, but 113 // already ignore deferred ResourceHandler shutdown, but
56 // DetachableResourceHandler and the detach-on-renderer-cancel logic 114 // DetachableResourceHandler and the detach-on-renderer-cancel logic
57 // introduces a case where this occurs when the renderer cancels a resource. 115 // introduces a case where this occurs when the renderer cancels a resource.
58 } 116 }
59 // A OnWillRead / OnReadCompleted pair may still be in progress, but 117 // A OnWillRead / OnReadCompleted pair may still be in progress, but
60 // OnWillRead passes back a scoped_refptr, so downstream handler's buffer will 118 // OnWillRead passes back a scoped_refptr, so downstream handler's buffer will
61 // survive long enough to complete that read. From there, future reads will 119 // survive long enough to complete that read. From there, future reads will
62 // drain into |read_buffer_|. (If |next_handler_| is an AsyncResourceHandler, 120 // drain into |read_buffer_|. (If |next_handler_| is an AsyncResourceHandler,
63 // the net::IOBuffer takes a reference to the ResourceBuffer which owns the 121 // the net::IOBuffer takes a reference to the ResourceBuffer which owns the
64 // shared memory.) 122 // shared memory.)
65 next_handler_.reset(); 123 next_handler_.reset();
66 124
67 // Time the request out if it takes too long. 125 // Time the request out if it takes too long.
68 detached_timer_.reset(new base::OneShotTimer()); 126 detached_timer_.reset(new base::OneShotTimer());
69 detached_timer_->Start( 127 detached_timer_->Start(FROM_HERE, cancel_delay_, this,
70 FROM_HERE, cancel_delay_, this, &DetachableResourceHandler::Cancel); 128 &DetachableResourceHandler::OnTimedOut);
71 129
72 // Resume if necessary. The request may have been deferred, say, waiting on a 130 // Resume if necessary. The request may have been deferred, say, waiting on a
73 // full buffer in AsyncResourceHandler. Now that it has been detached, resume 131 // full buffer in AsyncResourceHandler. Now that it has been detached, resume
74 // and drain it. 132 // and drain it.
75 if (is_deferred_) { 133 if (has_controller()) {
76 // The nested ResourceHandler may have logged that it's blocking the 134 // The nested ResourceHandler may have logged that it's blocking the
77 // request. Log it as no longer doing so, to avoid a DCHECK on resume. 135 // request. Log it as no longer doing so, to avoid a DCHECK on resume.
78 request()->LogUnblocked(); 136 request()->LogUnblocked();
79 Resume(); 137 Resume();
80 } 138 }
81 } 139 }
82 140
83 void DetachableResourceHandler::SetController(ResourceController* controller) { 141 void DetachableResourceHandler::OnRequestRedirected(
84 ResourceHandler::SetController(controller); 142 const net::RedirectInfo& redirect_info,
143 ResourceResponse* response,
144 std::unique_ptr<ResourceController> controller) {
145 DCHECK(!has_controller());
85 146
86 // Intercept the ResourceController for downstream handlers to keep track of 147 if (!next_handler_) {
87 // whether the request is deferred. 148 controller->Resume();
88 if (next_handler_) 149 return;
89 next_handler_->SetController(this); 150 }
151
152 HoldController(std::move(controller));
153 next_handler_->OnRequestRedirected(redirect_info, response,
154 base::MakeUnique<Controller>(this));
90 } 155 }
91 156
92 bool DetachableResourceHandler::OnRequestRedirected( 157 void DetachableResourceHandler::OnResponseStarted(
93 const net::RedirectInfo& redirect_info,
94 ResourceResponse* response, 158 ResourceResponse* response,
95 bool* defer) { 159 std::unique_ptr<ResourceController> controller) {
96 DCHECK(!is_deferred_); 160 DCHECK(!has_controller());
97 161
98 if (!next_handler_) 162 if (!next_handler_) {
99 return true; 163 controller->Resume();
164 return;
165 }
100 166
101 bool ret = next_handler_->OnRequestRedirected( 167 HoldController(std::move(controller));
102 redirect_info, response, &is_deferred_); 168 next_handler_->OnResponseStarted(response,
103 *defer = is_deferred_; 169 base::MakeUnique<Controller>(this));
104 return ret;
105 } 170 }
106 171
107 bool DetachableResourceHandler::OnResponseStarted(ResourceResponse* response, 172 void DetachableResourceHandler::OnWillStart(
108 bool* defer) { 173 const GURL& url,
109 DCHECK(!is_deferred_); 174 std::unique_ptr<ResourceController> controller) {
175 DCHECK(!has_controller());
110 176
111 if (!next_handler_) 177 if (!next_handler_) {
112 return true; 178 controller->Resume();
179 return;
180 }
113 181
114 bool ret = 182 HoldController(std::move(controller));
115 next_handler_->OnResponseStarted(response, &is_deferred_); 183 next_handler_->OnWillStart(url, base::MakeUnique<Controller>(this));
116 *defer = is_deferred_;
117 return ret;
118 }
119
120 bool DetachableResourceHandler::OnWillStart(const GURL& url, bool* defer) {
121 DCHECK(!is_deferred_);
122
123 if (!next_handler_)
124 return true;
125
126 bool ret = next_handler_->OnWillStart(url, &is_deferred_);
127 *defer = is_deferred_;
128 return ret;
129 } 184 }
130 185
131 bool DetachableResourceHandler::OnWillRead(scoped_refptr<net::IOBuffer>* buf, 186 bool DetachableResourceHandler::OnWillRead(scoped_refptr<net::IOBuffer>* buf,
132 int* buf_size, 187 int* buf_size,
133 int min_size) { 188 int min_size) {
134 if (!next_handler_) { 189 if (!next_handler_) {
135 DCHECK_EQ(-1, min_size); 190 DCHECK_EQ(-1, min_size);
136 if (!read_buffer_.get()) 191 if (!read_buffer_.get())
137 read_buffer_ = new net::IOBuffer(kReadBufSize); 192 read_buffer_ = new net::IOBuffer(kReadBufSize);
138 *buf = read_buffer_; 193 *buf = read_buffer_;
139 *buf_size = kReadBufSize; 194 *buf_size = kReadBufSize;
140 return true; 195 return true;
141 } 196 }
142 197
143 return next_handler_->OnWillRead(buf, buf_size, min_size); 198 return next_handler_->OnWillRead(buf, buf_size, min_size);
144 } 199 }
145 200
146 bool DetachableResourceHandler::OnReadCompleted(int bytes_read, bool* defer) { 201 void DetachableResourceHandler::OnReadCompleted(
147 DCHECK(!is_deferred_); 202 int bytes_read,
203 std::unique_ptr<ResourceController> controller) {
204 DCHECK(!has_controller());
148 205
149 if (!next_handler_) 206 if (!next_handler_) {
150 return true; 207 controller->Resume();
208 return;
209 }
151 210
152 bool ret = 211 HoldController(std::move(controller));
153 next_handler_->OnReadCompleted(bytes_read, &is_deferred_); 212 next_handler_->OnReadCompleted(bytes_read,
154 *defer = is_deferred_; 213 base::MakeUnique<Controller>(this));
155 return ret;
156 } 214 }
157 215
158 void DetachableResourceHandler::OnResponseCompleted( 216 void DetachableResourceHandler::OnResponseCompleted(
159 const net::URLRequestStatus& status, 217 const net::URLRequestStatus& status,
160 bool* defer) { 218 std::unique_ptr<ResourceController> controller) {
161 // No DCHECK(!is_deferred_) as the request may have been cancelled while 219 // No DCHECK(!is_deferred_) as the request may have been cancelled while
162 // deferred. 220 // deferred.
163 221
164 if (!next_handler_) 222 if (!next_handler_) {
223 controller->Resume();
165 return; 224 return;
225 }
166 226
167 is_finished_ = true; 227 is_finished_ = true;
168 228
169 next_handler_->OnResponseCompleted(status, &is_deferred_); 229 next_handler_->OnResponseCompleted(status, std::move(controller));
170 *defer = is_deferred_;
171 } 230 }
172 231
173 void DetachableResourceHandler::OnDataDownloaded(int bytes_downloaded) { 232 void DetachableResourceHandler::OnDataDownloaded(int bytes_downloaded) {
174 if (!next_handler_) 233 if (!next_handler_)
175 return; 234 return;
176 235
177 next_handler_->OnDataDownloaded(bytes_downloaded); 236 next_handler_->OnDataDownloaded(bytes_downloaded);
178 } 237 }
179 238
180 void DetachableResourceHandler::Resume() { 239 void DetachableResourceHandler::OnTimedOut() {
181 DCHECK(is_deferred_); 240 // Requests are only timed out after being detached, and shouldn't be deferred
182 is_deferred_ = false; 241 // once detached.
183 controller()->Resume(); 242 DCHECK(!next_handler_);
184 } 243 DCHECK(!has_controller());
185 244
186 void DetachableResourceHandler::Cancel() { 245 OutOfBandCancel(net::ERR_ABORTED, true /* tell_renderer */);
187 controller()->Cancel();
188 }
189
190 void DetachableResourceHandler::CancelAndIgnore() {
191 controller()->CancelAndIgnore();
192 }
193
194 void DetachableResourceHandler::CancelWithError(int error_code) {
195 controller()->CancelWithError(error_code);
196 } 246 }
197 247
198 } // namespace content 248 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/loader/detachable_resource_handler.h ('k') | content/browser/loader/intercepting_resource_handler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698