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

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

Issue 2526983002: Refactor ResourceHandler API. (Closed)
Patch Set: More fixes... 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 (c) 2012 The Chromium Authors. All rights reserved. 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 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/resource_loader.h" 5 #include "content/browser/loader/resource_loader.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/callback_helpers.h" 9 #include "base/callback_helpers.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
11 #include "base/location.h" 11 #include "base/location.h"
12 #include "base/memory/ptr_util.h"
12 #include "base/metrics/histogram_macros.h" 13 #include "base/metrics/histogram_macros.h"
13 #include "base/profiler/scoped_tracker.h" 14 #include "base/profiler/scoped_tracker.h"
14 #include "base/single_thread_task_runner.h" 15 #include "base/single_thread_task_runner.h"
15 #include "base/threading/thread_task_runner_handle.h" 16 #include "base/threading/thread_task_runner_handle.h"
16 #include "base/trace_event/trace_event.h" 17 #include "base/trace_event/trace_event.h"
17 #include "content/browser/appcache/appcache_interceptor.h" 18 #include "content/browser/appcache/appcache_interceptor.h"
18 #include "content/browser/child_process_security_policy_impl.h" 19 #include "content/browser/child_process_security_policy_impl.h"
19 #include "content/browser/loader/detachable_resource_handler.h" 20 #include "content/browser/loader/detachable_resource_handler.h"
21 #include "content/browser/loader/resource_controller.h"
20 #include "content/browser/loader/resource_handler.h" 22 #include "content/browser/loader/resource_handler.h"
21 #include "content/browser/loader/resource_loader_delegate.h" 23 #include "content/browser/loader/resource_loader_delegate.h"
22 #include "content/browser/loader/resource_request_info_impl.h" 24 #include "content/browser/loader/resource_request_info_impl.h"
23 #include "content/browser/service_worker/service_worker_request_handler.h" 25 #include "content/browser/service_worker/service_worker_request_handler.h"
24 #include "content/browser/service_worker/service_worker_response_info.h" 26 #include "content/browser/service_worker/service_worker_response_info.h"
25 #include "content/browser/ssl/ssl_client_auth_handler.h" 27 #include "content/browser/ssl/ssl_client_auth_handler.h"
26 #include "content/browser/ssl/ssl_manager.h" 28 #include "content/browser/ssl/ssl_manager.h"
27 #include "content/public/browser/resource_dispatcher_host_login_delegate.h" 29 #include "content/public/browser/resource_dispatcher_host_login_delegate.h"
28 #include "content/public/common/browser_side_navigation_policy.h" 30 #include "content/public/common/browser_side_navigation_policy.h"
29 #include "content/public/common/content_client.h" 31 #include "content/public/common/content_client.h"
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 // We should not have any SSL state. 125 // We should not have any SSL state.
124 DCHECK(!request->ssl_info().cert_status); 126 DCHECK(!request->ssl_info().cert_status);
125 DCHECK_EQ(request->ssl_info().security_bits, -1); 127 DCHECK_EQ(request->ssl_info().security_bits, -1);
126 DCHECK_EQ(request->ssl_info().key_exchange_group, 0); 128 DCHECK_EQ(request->ssl_info().key_exchange_group, 0);
127 DCHECK(!request->ssl_info().connection_status); 129 DCHECK(!request->ssl_info().connection_status);
128 } 130 }
129 } 131 }
130 132
131 } // namespace 133 } // namespace
132 134
135 class ResourceLoader::Controller : public ResourceController {
136 public:
137 explicit Controller(ResourceLoader* resource_loader)
138 : resource_loader_(resource_loader){};
139
140 ~Controller() override {}
141
142 // ResourceController implementation:
143 void Resume() override {
144 MarkAsUsed();
145 resource_loader_->Resume(true /* called_from_resource_controller */);
146 }
147
148 void Cancel() override {
149 MarkAsUsed();
150 resource_loader_->Cancel();
151 }
152
153 void CancelAndIgnore() override {
154 MarkAsUsed();
155 resource_loader_->CancelAndIgnore();
156 }
157
158 void CancelWithError(int error_code) override {
159 MarkAsUsed();
160 resource_loader_->CancelWithError(error_code);
161 }
162
163 private:
164 void MarkAsUsed() {
165 #if DCHECK_IS_ON()
166 DCHECK(!used_);
167 used_ = true;
168 #endif
169 }
170
171 ResourceLoader* const resource_loader_;
172
173 #if DCHECK_IS_ON()
174 // Set to true once one of the ResourceContoller methods has been invoked.
175 bool used_ = false;
176 #endif
177
178 DISALLOW_COPY_AND_ASSIGN(Controller);
179 };
180
181 // Helper class. Sets the stage of a ResourceLoader to DEFERRED_SYNC on
182 // construction, and on destruction does one of the following:
183 // 1) If the ResourceLoader has a deferred stage of DEFERRED_NONE, sets the
184 // ResourceLoader's stage to the stage specified on construction and resumes it.
185 // 2) If the ResourceLoader still has a deferred stage of DEFERRED_SYNC, sets
186 // the ResourceLoader's stage to the stage specified on construction. The
187 // ResourceLoader will be resumed at some point in the future.
188 class ResourceLoader::ScopedDeferral {
189 public:
190 ScopedDeferral(ResourceLoader* resource_loader,
191 ResourceLoader::DeferredStage deferred_stage)
192 : resource_loader_(resource_loader), deferred_stage_(deferred_stage) {
193 resource_loader_->deferred_stage_ = DEFERRED_SYNC;
194 }
195
196 ~ScopedDeferral() {
197 DeferredStage old_deferred_stage = resource_loader_->deferred_stage_;
198 // On destruction, either the stage is still DEFERRED_SYNC, or Resume() was
199 // called once, and it advanced to DEFERRED_NONE.
200 DCHECK(old_deferred_stage == DEFERRED_NONE ||
201 old_deferred_stage == DEFERRED_SYNC);
202 resource_loader_->deferred_stage_ = deferred_stage_;
203 // If Resume() was called, it just advanced the state without doing
204 // anything. Go ahead and resume the request now.
205 if (old_deferred_stage == DEFERRED_NONE)
206 resource_loader_->Resume(false /* called_from_resource_controller */);
207 }
208
209 private:
210 ResourceLoader* const resource_loader_;
211 const DeferredStage deferred_stage_;
212
213 DISALLOW_COPY_AND_ASSIGN(ScopedDeferral);
214 };
215
133 ResourceLoader::ResourceLoader(std::unique_ptr<net::URLRequest> request, 216 ResourceLoader::ResourceLoader(std::unique_ptr<net::URLRequest> request,
134 std::unique_ptr<ResourceHandler> handler, 217 std::unique_ptr<ResourceHandler> handler,
135 ResourceLoaderDelegate* delegate) 218 ResourceLoaderDelegate* delegate)
136 : deferred_stage_(DEFERRED_NONE), 219 : deferred_stage_(DEFERRED_NONE),
137 request_(std::move(request)), 220 request_(std::move(request)),
138 handler_(std::move(handler)), 221 handler_(std::move(handler)),
139 delegate_(delegate), 222 delegate_(delegate),
140 is_transferring_(false), 223 is_transferring_(false),
141 times_cancelled_before_request_start_(0), 224 times_cancelled_before_request_start_(0),
142 started_request_(false), 225 started_request_(false),
143 times_cancelled_after_request_start_(0), 226 times_cancelled_after_request_start_(0),
144 weak_ptr_factory_(this) { 227 weak_ptr_factory_(this) {
145 request_->set_delegate(this); 228 request_->set_delegate(this);
146 handler_->SetController(this); 229 handler_->SetDelegate(this);
147 } 230 }
148 231
149 ResourceLoader::~ResourceLoader() { 232 ResourceLoader::~ResourceLoader() {
150 if (login_delegate_.get()) 233 if (login_delegate_.get())
151 login_delegate_->OnRequestCancelled(); 234 login_delegate_->OnRequestCancelled();
152 ssl_client_auth_handler_.reset(); 235 ssl_client_auth_handler_.reset();
153 236
154 // Run ResourceHandler destructor before we tear-down the rest of our state 237 // Run ResourceHandler destructor before we tear-down the rest of our state
155 // as the ResourceHandler may want to inspect the URLRequest and other state. 238 // as the ResourceHandler may want to inspect the URLRequest and other state.
156 handler_.reset(); 239 handler_.reset();
157 } 240 }
158 241
159 void ResourceLoader::StartRequest() { 242 void ResourceLoader::StartRequest() {
160 // Give the handler a chance to delay the URLRequest from being started.
161 bool defer_start = false;
162 if (!handler_->OnWillStart(request_->url(), &defer_start)) {
163 Cancel();
164 return;
165 }
166
167 TRACE_EVENT_WITH_FLOW0("loading", "ResourceLoader::StartRequest", this, 243 TRACE_EVENT_WITH_FLOW0("loading", "ResourceLoader::StartRequest", this,
168 TRACE_EVENT_FLAG_FLOW_OUT); 244 TRACE_EVENT_FLAG_FLOW_OUT);
169 if (defer_start) { 245
170 deferred_stage_ = DEFERRED_START; 246 ScopedDeferral scoped_deferral(this, DEFERRED_START);
171 } else { 247 handler_->OnWillStart(request_->url(), base::MakeUnique<Controller>(this));
172 StartRequestInternal();
173 }
174 } 248 }
175 249
176 void ResourceLoader::CancelRequest(bool from_renderer) { 250 void ResourceLoader::CancelRequest(bool from_renderer) {
177 TRACE_EVENT_WITH_FLOW0("loading", "ResourceLoader::CancelRequest", this, 251 TRACE_EVENT_WITH_FLOW0("loading", "ResourceLoader::CancelRequest", this,
178 TRACE_EVENT_FLAG_FLOW_IN); 252 TRACE_EVENT_FLAG_FLOW_IN);
179 CancelRequestInternal(net::ERR_ABORTED, from_renderer); 253 CancelRequestInternal(net::ERR_ABORTED, from_renderer);
180 } 254 }
181 255
182 void ResourceLoader::CancelAndIgnore() { 256 void ResourceLoader::CancelAndIgnore() {
183 ResourceRequestInfoImpl* info = GetRequestInfo(); 257 ResourceRequestInfoImpl* info = GetRequestInfo();
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
232 } 306 }
233 307
234 ResourceRequestInfoImpl* ResourceLoader::GetRequestInfo() { 308 ResourceRequestInfoImpl* ResourceLoader::GetRequestInfo() {
235 return ResourceRequestInfoImpl::ForRequest(request_.get()); 309 return ResourceRequestInfoImpl::ForRequest(request_.get());
236 } 310 }
237 311
238 void ResourceLoader::ClearLoginDelegate() { 312 void ResourceLoader::ClearLoginDelegate() {
239 login_delegate_ = NULL; 313 login_delegate_ = NULL;
240 } 314 }
241 315
316 void ResourceLoader::OutOfBandCancel(int error_code, bool tell_renderer) {
317 CancelRequestInternal(error_code, !tell_renderer);
318 }
319
242 void ResourceLoader::OnReceivedRedirect(net::URLRequest* unused, 320 void ResourceLoader::OnReceivedRedirect(net::URLRequest* unused,
243 const net::RedirectInfo& redirect_info, 321 const net::RedirectInfo& redirect_info,
244 bool* defer) { 322 bool* defer) {
245 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("loading"), 323 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("loading"),
246 "ResourceLoader::OnReceivedRedirect"); 324 "ResourceLoader::OnReceivedRedirect");
247 DCHECK_EQ(request_.get(), unused); 325 DCHECK_EQ(request_.get(), unused);
248 326
249 DVLOG(1) << "OnReceivedRedirect: " << request_->url().spec(); 327 DVLOG(1) << "OnReceivedRedirect: " << request_->url().spec();
250 DCHECK(request_->status().is_success()); 328 DCHECK(request_->status().is_success());
251 329
(...skipping 12 matching lines...) Expand all
264 342
265 // Tell the renderer that this request was disallowed. 343 // Tell the renderer that this request was disallowed.
266 Cancel(); 344 Cancel();
267 return; 345 return;
268 } 346 }
269 } 347 }
270 348
271 scoped_refptr<ResourceResponse> response = new ResourceResponse(); 349 scoped_refptr<ResourceResponse> response = new ResourceResponse();
272 PopulateResourceResponse(info, request_.get(), response.get()); 350 PopulateResourceResponse(info, request_.get(), response.get());
273 delegate_->DidReceiveRedirect(this, redirect_info.new_url, response.get()); 351 delegate_->DidReceiveRedirect(this, redirect_info.new_url, response.get());
274 if (!handler_->OnRequestRedirected(redirect_info, response.get(), defer)) { 352
275 Cancel(); 353 // Can't used ScopedDeferral here, because on sync completion, need to set
276 } else if (*defer) { 354 // |defer| to false instead of calling back into the URLRequest.
277 deferred_stage_ = DEFERRED_REDIRECT; // Follow redirect when resumed. 355 deferred_stage_ = DEFERRED_SYNC;
278 DCHECK(deferred_redirect_url_.is_empty()); 356 handler_->OnRequestRedirected(redirect_info, response.get(),
357 base::MakeUnique<Controller>(this));
358 if (is_deferred()) {
359 *defer = true;
279 deferred_redirect_url_ = redirect_info.new_url; 360 deferred_redirect_url_ = redirect_info.new_url;
280 } else if (delegate_->HandleExternalProtocol(this, redirect_info.new_url)) { 361 deferred_stage_ = DEFERRED_REDIRECT;
281 // The request is complete so we can remove it. 362 } else {
282 CancelAndIgnore(); 363 *defer = false;
283 return; 364 if (delegate_->HandleExternalProtocol(this, redirect_info.new_url))
365 CancelAndIgnore();
284 } 366 }
285 } 367 }
286 368
287 void ResourceLoader::OnAuthRequired(net::URLRequest* unused, 369 void ResourceLoader::OnAuthRequired(net::URLRequest* unused,
288 net::AuthChallengeInfo* auth_info) { 370 net::AuthChallengeInfo* auth_info) {
289 DCHECK_EQ(request_.get(), unused); 371 DCHECK_EQ(request_.get(), unused);
290 372
291 ResourceRequestInfoImpl* info = GetRequestInfo(); 373 ResourceRequestInfoImpl* info = GetRequestInfo();
292 if (info->do_not_prompt_for_login()) { 374 if (info->do_not_prompt_for_login()) {
293 request_->CancelAuth(); 375 request_->CancelAuth();
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 DCHECK_EQ(request_.get(), unused); 419 DCHECK_EQ(request_.get(), unused);
338 420
339 DVLOG(1) << "OnResponseStarted: " << request_->url().spec(); 421 DVLOG(1) << "OnResponseStarted: " << request_->url().spec();
340 422
341 if (!request_->status().is_success()) { 423 if (!request_->status().is_success()) {
342 ResponseCompleted(); 424 ResponseCompleted();
343 return; 425 return;
344 } 426 }
345 427
346 CompleteResponseStarted(); 428 CompleteResponseStarted();
347
348 // If the handler deferred the request, it will resume the request later. If
349 // the request was cancelled, the request will call back into |this| with a
350 // bogus read completed error.
351 if (is_deferred() || !request_->status().is_success())
352 return;
353
354 ReadMore(false); // Read the first chunk.
355 } 429 }
356 430
357 void ResourceLoader::OnReadCompleted(net::URLRequest* unused, int bytes_read) { 431 void ResourceLoader::OnReadCompleted(net::URLRequest* unused, int bytes_read) {
358 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("loading"), 432 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("loading"),
359 "ResourceLoader::OnReadCompleted"); 433 "ResourceLoader::OnReadCompleted");
360 DCHECK_EQ(request_.get(), unused); 434 DCHECK_EQ(request_.get(), unused);
361 DVLOG(1) << "OnReadCompleted: \"" << request_->url().spec() << "\"" 435 DVLOG(1) << "OnReadCompleted: \"" << request_->url().spec() << "\""
362 << " bytes_read = " << bytes_read; 436 << " bytes_read = " << bytes_read;
363 437
364 // bytes_read == -1 always implies an error. 438 // bytes_read == -1 always implies an error.
365 if (bytes_read == -1 || !request_->status().is_success()) { 439 if (bytes_read == -1 || !request_->status().is_success()) {
366 ResponseCompleted(); 440 ResponseCompleted();
367 return; 441 return;
368 } 442 }
369 443
370 CompleteRead(bytes_read); 444 CompleteRead(bytes_read);
371
372 // If the handler cancelled or deferred the request, do not continue
373 // processing the read. If canceled, either the request will call into |this|
374 // with a bogus read error, or, if the request was completed, a task posted
375 // from ResourceLoader::CancelREquestInternal will run OnResponseCompleted.
376 if (is_deferred() || !request_->status().is_success())
377 return;
378
379 if (bytes_read > 0) {
380 ReadMore(true); // Read the next chunk.
381 } else {
382 // TODO(darin): Remove ScopedTracker below once crbug.com/475761 is fixed.
383 tracked_objects::ScopedTracker tracking_profile(
384 FROM_HERE_WITH_EXPLICIT_FUNCTION("475761 ResponseCompleted()"));
385
386 // URLRequest reported an EOF. Call ResponseCompleted.
387 DCHECK_EQ(0, bytes_read);
388 ResponseCompleted();
389 }
390 } 445 }
391 446
392 void ResourceLoader::CancelSSLRequest(int error, 447 void ResourceLoader::CancelSSLRequest(int error,
393 const net::SSLInfo* ssl_info) { 448 const net::SSLInfo* ssl_info) {
394 DCHECK_CURRENTLY_ON(BrowserThread::IO); 449 DCHECK_CURRENTLY_ON(BrowserThread::IO);
395 450
396 // The request can be NULL if it was cancelled by the renderer (as the 451 // The request can be NULL if it was cancelled by the renderer (as the
397 // request of the user navigating to a new page from the location bar). 452 // request of the user navigating to a new page from the location bar).
398 if (!request_->is_pending()) 453 if (!request_->is_pending())
399 return; 454 return;
(...skipping 25 matching lines...) Expand all
425 net::FetchClientCertPrivateKey(cert); 480 net::FetchClientCertPrivateKey(cert);
426 request_->ContinueWithCertificate(cert, private_key.get()); 481 request_->ContinueWithCertificate(cert, private_key.get());
427 } 482 }
428 483
429 void ResourceLoader::CancelCertificateSelection() { 484 void ResourceLoader::CancelCertificateSelection() {
430 DCHECK(ssl_client_auth_handler_); 485 DCHECK(ssl_client_auth_handler_);
431 ssl_client_auth_handler_.reset(); 486 ssl_client_auth_handler_.reset();
432 request_->CancelWithError(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED); 487 request_->CancelWithError(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
433 } 488 }
434 489
435 void ResourceLoader::Resume() { 490 void ResourceLoader::Resume(bool called_from_resource_controller) {
436 DCHECK(!is_transferring_); 491 DCHECK(!is_transferring_);
437 492
438 DeferredStage stage = deferred_stage_; 493 DeferredStage stage = deferred_stage_;
439 deferred_stage_ = DEFERRED_NONE; 494 deferred_stage_ = DEFERRED_NONE;
440 switch (stage) { 495 switch (stage) {
441 case DEFERRED_NONE: 496 case DEFERRED_NONE:
442 NOTREACHED(); 497 NOTREACHED();
443 break; 498 break;
499 case DEFERRED_SYNC:
500 DCHECK(called_from_resource_controller);
501 // Request will be resumed when the stack unwinds.
502 break;
444 case DEFERRED_START: 503 case DEFERRED_START:
504 // URLRequest::Start completes asynchronously, so starting the request now
505 // won't result in synchronously calling into a ResourceHandler, if this
506 // was called from Resume().
445 StartRequestInternal(); 507 StartRequestInternal();
446 break; 508 break;
447 case DEFERRED_REDIRECT: 509 case DEFERRED_REDIRECT:
510 // URLRequest::Start completes asynchronously, so starting the request now
511 // won't result in synchronously calling into a ResourceHandler, if this
512 // was called from Resume().
448 FollowDeferredRedirectInternal(); 513 FollowDeferredRedirectInternal();
449 break; 514 break;
450 case DEFERRED_READ: 515 case DEFERRED_READ:
451 base::ThreadTaskRunnerHandle::Get()->PostTask( 516 if (called_from_resource_controller) {
452 FROM_HERE, base::Bind(&ResourceLoader::ResumeReading, 517 // TODO(mmenke): Call ReadMore instead? Strange that this is the only
453 weak_ptr_factory_.GetWeakPtr())); 518 // path which calls different methods, depending on the path.
519 base::ThreadTaskRunnerHandle::Get()->PostTask(
520 FROM_HERE, base::Bind(&ResourceLoader::ResumeReading,
521 weak_ptr_factory_.GetWeakPtr()));
522 } else {
523 // If this was called as a result of a handler succeeding synchronously,
524 // force the result of the next read to be handled asynchronously, to
525 // aboid blocking the IO thread.
Charlie Harrison 2017/01/27 22:48:05 avoid
mmenke 2017/01/27 23:02:15 Done.
526 ReadMore(true /* handle_result_asynchronously */);
527 }
454 break; 528 break;
455 case DEFERRED_RESPONSE_COMPLETE: 529 case DEFERRED_RESPONSE_COMPLETE:
456 base::ThreadTaskRunnerHandle::Get()->PostTask( 530 if (called_from_resource_controller) {
457 FROM_HERE, base::Bind(&ResourceLoader::ResponseCompleted, 531 base::ThreadTaskRunnerHandle::Get()->PostTask(
458 weak_ptr_factory_.GetWeakPtr())); 532 FROM_HERE, base::Bind(&ResourceLoader::ResponseCompleted,
533 weak_ptr_factory_.GetWeakPtr()));
534 } else {
535 ResponseCompleted();
536 }
459 break; 537 break;
460 case DEFERRED_FINISH: 538 case DEFERRED_FINISH:
461 // Delay self-destruction since we don't know how we were reached. 539 if (called_from_resource_controller) {
462 base::ThreadTaskRunnerHandle::Get()->PostTask( 540 // Delay self-destruction since we don't know how we were reached.
463 FROM_HERE, base::Bind(&ResourceLoader::CallDidFinishLoading, 541 base::ThreadTaskRunnerHandle::Get()->PostTask(
464 weak_ptr_factory_.GetWeakPtr())); 542 FROM_HERE, base::Bind(&ResourceLoader::CallDidFinishLoading,
543 weak_ptr_factory_.GetWeakPtr()));
544 } else {
545 CallDidFinishLoading();
546 }
465 break; 547 break;
466 } 548 }
467 } 549 }
468 550
469 void ResourceLoader::Cancel() { 551 void ResourceLoader::Cancel() {
470 CancelRequest(false); 552 CancelRequest(false);
471 } 553 }
472 554
473 void ResourceLoader::StartRequestInternal() { 555 void ResourceLoader::StartRequestInternal() {
474 DCHECK(!request_->is_pending()); 556 DCHECK(!request_->is_pending());
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
551 ResourceRequestInfoImpl* info = GetRequestInfo(); 633 ResourceRequestInfoImpl* info = GetRequestInfo();
552 scoped_refptr<ResourceResponse> response = new ResourceResponse(); 634 scoped_refptr<ResourceResponse> response = new ResourceResponse();
553 PopulateResourceResponse(info, request_.get(), response.get()); 635 PopulateResourceResponse(info, request_.get(), response.get());
554 636
555 delegate_->DidReceiveResponse(this); 637 delegate_->DidReceiveResponse(this);
556 638
557 // TODO(darin): Remove ScopedTracker below once crbug.com/475761 is fixed. 639 // TODO(darin): Remove ScopedTracker below once crbug.com/475761 is fixed.
558 tracked_objects::ScopedTracker tracking_profile( 640 tracked_objects::ScopedTracker tracking_profile(
559 FROM_HERE_WITH_EXPLICIT_FUNCTION("475761 OnResponseStarted()")); 641 FROM_HERE_WITH_EXPLICIT_FUNCTION("475761 OnResponseStarted()"));
560 642
561 bool defer = false; 643 read_deferral_start_time_ = base::TimeTicks::Now();
562 if (!handler_->OnResponseStarted(response.get(), &defer)) { 644 ScopedDeferral scoped_deferral(this, DEFERRED_READ);
563 Cancel(); 645 handler_->OnResponseStarted(response.get(),
564 } else if (defer) { 646 base::MakeUnique<Controller>(this));
565 read_deferral_start_time_ = base::TimeTicks::Now();
566 deferred_stage_ = DEFERRED_READ; // Read first chunk when resumed.
567 }
568 } 647 }
569 648
570 void ResourceLoader::ReadMore(bool is_continuation) { 649 void ResourceLoader::ReadMore(bool handle_result_asyncronously) {
571 TRACE_EVENT_WITH_FLOW0("loading", "ResourceLoader::ReadMore", this, 650 TRACE_EVENT_WITH_FLOW0("loading", "ResourceLoader::ReadMore", this,
572 TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); 651 TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
573 DCHECK(!is_deferred()); 652 DCHECK(!is_deferred());
574 653
575 // Make sure we track the buffer in at least one place. This ensures it gets 654 // Make sure we track the buffer in at least one place. This ensures it gets
576 // deleted even in the case the request has already finished its job and 655 // deleted even in the case the request has already finished its job and
577 // doesn't use the buffer. 656 // doesn't use the buffer.
578 scoped_refptr<net::IOBuffer> buf; 657 scoped_refptr<net::IOBuffer> buf;
579 int buf_size; 658 int buf_size;
580 { 659 {
(...skipping 10 matching lines...) Expand all
591 } 670 }
592 671
593 DCHECK(buf.get()); 672 DCHECK(buf.get());
594 DCHECK(buf_size > 0); 673 DCHECK(buf_size > 0);
595 674
596 int result = request_->Read(buf.get(), buf_size); 675 int result = request_->Read(buf.get(), buf_size);
597 676
598 if (result == net::ERR_IO_PENDING) 677 if (result == net::ERR_IO_PENDING)
599 return; 678 return;
600 679
601 if (!is_continuation || result <= 0) { 680 if (handle_result_asyncronously || result <= 0) {
Charlie Harrison 2017/01/27 22:48:05 Do you mean !handle_result_asynchronously? This lo
mmenke 2017/01/27 23:02:15 Yes I do... Worth noting this wasn't caught by te
mmenke 2017/01/27 23:05:10 Actually, this can't be tested - it's just to avoi
602 OnReadCompleted(request_.get(), result); 681 OnReadCompleted(request_.get(), result);
603 } else { 682 } else {
604 // Else, trigger OnReadCompleted asynchronously to avoid starving the IO 683 // Else, trigger OnReadCompleted asynchronously to avoid starving the IO
605 // thread in case the URLRequest can provide data synchronously. 684 // thread in case the URLRequest can provide data synchronously.
606 base::ThreadTaskRunnerHandle::Get()->PostTask( 685 base::ThreadTaskRunnerHandle::Get()->PostTask(
607 FROM_HERE, 686 FROM_HERE,
608 base::Bind(&ResourceLoader::OnReadCompleted, 687 base::Bind(&ResourceLoader::OnReadCompleted,
609 weak_ptr_factory_.GetWeakPtr(), request_.get(), result)); 688 weak_ptr_factory_.GetWeakPtr(), request_.get(), result));
610 } 689 }
611 } 690 }
612 691
613 void ResourceLoader::ResumeReading() { 692 void ResourceLoader::ResumeReading() {
614 DCHECK(!is_deferred()); 693 DCHECK(!is_deferred());
615 694
616 if (!read_deferral_start_time_.is_null()) { 695 if (!read_deferral_start_time_.is_null()) {
617 UMA_HISTOGRAM_TIMES("Net.ResourceLoader.ReadDeferral", 696 UMA_HISTOGRAM_TIMES("Net.ResourceLoader.ReadDeferral",
618 base::TimeTicks::Now() - read_deferral_start_time_); 697 base::TimeTicks::Now() - read_deferral_start_time_);
619 read_deferral_start_time_ = base::TimeTicks(); 698 read_deferral_start_time_ = base::TimeTicks();
620 } 699 }
621 if (request_->status().is_success()) { 700 if (request_->status().is_success()) {
622 ReadMore(false); // Read the next chunk (OK to complete synchronously). 701 ReadMore(false); // Read the next chunk (OK to complete synchronously).
Charlie Harrison 2017/01/27 22:48:05 Remove "(Ok to complete synchronously)" and add /*
mmenke 2017/01/27 23:02:15 Done.
623 } else { 702 } else {
624 ResponseCompleted(); 703 ResponseCompleted();
625 } 704 }
626 } 705 }
627 706
628 void ResourceLoader::CompleteRead(int bytes_read) { 707 void ResourceLoader::CompleteRead(int bytes_read) {
629 TRACE_EVENT_WITH_FLOW0("loading", "ResourceLoader::CompleteRead", this, 708 TRACE_EVENT_WITH_FLOW0("loading", "ResourceLoader::CompleteRead", this,
630 TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); 709 TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
631 710
632 DCHECK(bytes_read >= 0); 711 DCHECK(bytes_read >= 0);
633 DCHECK(request_->status().is_success()); 712 DCHECK(request_->status().is_success());
634 713
635 // TODO(darin): Remove ScopedTracker below once crbug.com/475761 is fixed. 714 // TODO(darin): Remove ScopedTracker below once crbug.com/475761 is fixed.
636 tracked_objects::ScopedTracker tracking_profile( 715 tracked_objects::ScopedTracker tracking_profile(
637 FROM_HERE_WITH_EXPLICIT_FUNCTION("475761 OnReadCompleted()")); 716 FROM_HERE_WITH_EXPLICIT_FUNCTION("475761 OnReadCompleted()"));
638 717
639 bool defer = false; 718 ScopedDeferral scoped_deferral(
640 if (!handler_->OnReadCompleted(bytes_read, &defer)) { 719 this, bytes_read > 0 ? DEFERRED_READ : DEFERRED_RESPONSE_COMPLETE);
641 Cancel(); 720 handler_->OnReadCompleted(bytes_read, base::MakeUnique<Controller>(this));
642 } else if (defer) {
643 deferred_stage_ =
644 bytes_read > 0 ? DEFERRED_READ : DEFERRED_RESPONSE_COMPLETE;
645 }
646
647 // Note: the request may still have been cancelled while OnReadCompleted
648 // returns true if OnReadCompleted caused request to get cancelled
649 // out-of-band. (In AwResourceDispatcherHostDelegate::DownloadStarting, for
650 // instance.)
651 } 721 }
652 722
653 void ResourceLoader::ResponseCompleted() { 723 void ResourceLoader::ResponseCompleted() {
654 TRACE_EVENT_WITH_FLOW0("loading", "ResourceLoader::ResponseCompleted", this, 724 TRACE_EVENT_WITH_FLOW0("loading", "ResourceLoader::ResponseCompleted", this,
655 TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); 725 TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
656 726
657 DVLOG(1) << "ResponseCompleted: " << request_->url().spec(); 727 DVLOG(1) << "ResponseCompleted: " << request_->url().spec();
658 RecordHistograms(); 728 RecordHistograms();
659 729
660 bool defer = false; 730 // TODO(darin): Remove ScopedTracker below once crbug.com/475761 is fixed.
661 { 731 tracked_objects::ScopedTracker tracking_profile(
662 // TODO(darin): Remove ScopedTracker below once crbug.com/475761 is fixed. 732 FROM_HERE_WITH_EXPLICIT_FUNCTION("475761 OnResponseCompleted()"));
663 tracked_objects::ScopedTracker tracking_profile(
664 FROM_HERE_WITH_EXPLICIT_FUNCTION("475761 OnResponseCompleted()"));
665 733
666 handler_->OnResponseCompleted(request_->status(), &defer); 734 ScopedDeferral scoped_deferral(this, DEFERRED_FINISH);
667 } 735 handler_->OnResponseCompleted(request_->status(),
668 if (defer) { 736 base::MakeUnique<Controller>(this));
669 // The handler is not ready to die yet. We will call DidFinishLoading when
670 // we resume.
671 deferred_stage_ = DEFERRED_FINISH;
672 } else {
673 // This will result in our destruction.
674 CallDidFinishLoading();
675 }
676 } 737 }
677 738
678 void ResourceLoader::CallDidFinishLoading() { 739 void ResourceLoader::CallDidFinishLoading() {
679 TRACE_EVENT_WITH_FLOW0("loading", "ResourceLoader::CallDidFinishLoading", 740 TRACE_EVENT_WITH_FLOW0("loading", "ResourceLoader::CallDidFinishLoading",
680 this, TRACE_EVENT_FLAG_FLOW_IN); 741 this, TRACE_EVENT_FLAG_FLOW_IN);
681 delegate_->DidFinishLoading(this); 742 delegate_->DidFinishLoading(this);
682 } 743 }
683 744
684 void ResourceLoader::RecordHistograms() { 745 void ResourceLoader::RecordHistograms() {
685 ResourceRequestInfoImpl* info = GetRequestInfo(); 746 ResourceRequestInfoImpl* info = GetRequestInfo();
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
740 UMA_HISTOGRAM_ENUMERATION("Net.Prefetch.Pattern", prefetch_status, 801 UMA_HISTOGRAM_ENUMERATION("Net.Prefetch.Pattern", prefetch_status,
741 STATUS_MAX); 802 STATUS_MAX);
742 } 803 }
743 } else if (request_->response_info().unused_since_prefetch) { 804 } else if (request_->response_info().unused_since_prefetch) {
744 TimeDelta total_time = base::TimeTicks::Now() - request_->creation_time(); 805 TimeDelta total_time = base::TimeTicks::Now() - request_->creation_time();
745 UMA_HISTOGRAM_TIMES("Net.Prefetch.TimeSpentOnPrefetchHit", total_time); 806 UMA_HISTOGRAM_TIMES("Net.Prefetch.TimeSpentOnPrefetchHit", total_time);
746 } 807 }
747 } 808 }
748 809
749 } // namespace content 810 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/loader/resource_loader.h ('k') | content/browser/loader/resource_loader_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698