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

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

Issue 2476163003: Refactor ResourceHandler API. (Closed)
Patch Set: Minor cleanups, one real fix Created 4 years, 1 month 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"
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 // as the ResourceHandler may want to inspect the URLRequest and other state. 156 // as the ResourceHandler may want to inspect the URLRequest and other state.
157 handler_.reset(); 157 handler_.reset();
158 } 158 }
159 159
160 void ResourceLoader::StartRequest() { 160 void ResourceLoader::StartRequest() {
161 if (delegate_->HandleExternalProtocol(this, request_->url())) { 161 if (delegate_->HandleExternalProtocol(this, request_->url())) {
162 CancelAndIgnore(); 162 CancelAndIgnore();
163 return; 163 return;
164 } 164 }
165 165
166 // Give the handler a chance to delay the URLRequest from being started.
167 bool defer_start = false;
168 if (!handler_->OnWillStart(request_->url(), &defer_start)) {
169 Cancel();
170 return;
171 }
172
173 TRACE_EVENT_WITH_FLOW0("loading", "ResourceLoader::StartRequest", this, 166 TRACE_EVENT_WITH_FLOW0("loading", "ResourceLoader::StartRequest", this,
174 TRACE_EVENT_FLAG_FLOW_OUT); 167 TRACE_EVENT_FLAG_FLOW_OUT);
175 if (defer_start) { 168
169 // Give the handler a chance to delay the URLRequest from being started.
170 bool defer_or_cancel = false;
171 handler_->OnWillStart(request_->url(), &defer_or_cancel);
172 if (defer_or_cancel) {
176 deferred_stage_ = DEFERRED_START; 173 deferred_stage_ = DEFERRED_START;
177 } else { 174 } else {
178 StartRequestInternal(); 175 StartRequestInternal();
179 } 176 }
180 } 177 }
181 178
182 void ResourceLoader::CancelRequest(bool from_renderer) { 179 void ResourceLoader::CancelRequest(bool from_renderer) {
183 TRACE_EVENT_WITH_FLOW0("loading", "ResourceLoader::CancelRequest", this, 180 TRACE_EVENT_WITH_FLOW0("loading", "ResourceLoader::CancelRequest", this,
184 TRACE_EVENT_FLAG_FLOW_IN); 181 TRACE_EVENT_FLAG_FLOW_IN);
185 CancelRequestInternal(net::ERR_ABORTED, from_renderer); 182 CancelRequestInternal(net::ERR_ABORTED, from_renderer, false);
186 }
187
188 void ResourceLoader::CancelAndIgnore() {
189 ResourceRequestInfoImpl* info = GetRequestInfo();
190 info->set_was_ignored_by_handler(true);
191 CancelRequest(false);
192 }
193
194 void ResourceLoader::CancelWithError(int error_code) {
195 TRACE_EVENT_WITH_FLOW0("loading", "ResourceLoader::CancelWithError", this,
196 TRACE_EVENT_FLAG_FLOW_IN);
197 CancelRequestInternal(error_code, false);
198 } 183 }
199 184
200 void ResourceLoader::MarkAsTransferring( 185 void ResourceLoader::MarkAsTransferring(
201 const base::Closure& on_transfer_complete_callback) { 186 const base::Closure& on_transfer_complete_callback) {
202 CHECK(IsResourceTypeFrame(GetRequestInfo()->GetResourceType())) 187 CHECK(IsResourceTypeFrame(GetRequestInfo()->GetResourceType()))
203 << "Can only transfer for navigations"; 188 << "Can only transfer for navigations";
204 is_transferring_ = true; 189 is_transferring_ = true;
205 on_transfer_complete_callback_ = on_transfer_complete_callback; 190 on_transfer_complete_callback_ = on_transfer_complete_callback;
206 191
207 int child_id = GetRequestInfo()->GetChildID(); 192 int child_id = GetRequestInfo()->GetChildID();
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 261
277 if (delegate_->HandleExternalProtocol(this, redirect_info.new_url)) { 262 if (delegate_->HandleExternalProtocol(this, redirect_info.new_url)) {
278 // The request is complete so we can remove it. 263 // The request is complete so we can remove it.
279 CancelAndIgnore(); 264 CancelAndIgnore();
280 return; 265 return;
281 } 266 }
282 267
283 scoped_refptr<ResourceResponse> response = new ResourceResponse(); 268 scoped_refptr<ResourceResponse> response = new ResourceResponse();
284 PopulateResourceResponse(info, request_.get(), response.get()); 269 PopulateResourceResponse(info, request_.get(), response.get());
285 delegate_->DidReceiveRedirect(this, redirect_info.new_url, response.get()); 270 delegate_->DidReceiveRedirect(this, redirect_info.new_url, response.get());
286 if (!handler_->OnRequestRedirected(redirect_info, response.get(), defer)) { 271
287 Cancel(); 272 // Cancellations are treated much like defers, so ignore the difference.
288 } else if (*defer) { 273 handler_->OnRequestRedirected(redirect_info, response.get(), defer);
274 if (*defer)
289 deferred_stage_ = DEFERRED_REDIRECT; // Follow redirect when resumed. 275 deferred_stage_ = DEFERRED_REDIRECT; // Follow redirect when resumed.
290 }
291 } 276 }
292 277
293 void ResourceLoader::OnAuthRequired(net::URLRequest* unused, 278 void ResourceLoader::OnAuthRequired(net::URLRequest* unused,
294 net::AuthChallengeInfo* auth_info) { 279 net::AuthChallengeInfo* auth_info) {
295 DCHECK_EQ(request_.get(), unused); 280 DCHECK_EQ(request_.get(), unused);
296 281
297 ResourceRequestInfoImpl* info = GetRequestInfo(); 282 ResourceRequestInfoImpl* info = GetRequestInfo();
298 if (info->do_not_prompt_for_login()) { 283 if (info->do_not_prompt_for_login()) {
299 request_->CancelAuth(); 284 request_->CancelAuth();
300 return; 285 return;
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 case DEFERRED_FINISH: 454 case DEFERRED_FINISH:
470 // Delay self-destruction since we don't know how we were reached. 455 // Delay self-destruction since we don't know how we were reached.
471 base::ThreadTaskRunnerHandle::Get()->PostTask( 456 base::ThreadTaskRunnerHandle::Get()->PostTask(
472 FROM_HERE, base::Bind(&ResourceLoader::CallDidFinishLoading, 457 FROM_HERE, base::Bind(&ResourceLoader::CallDidFinishLoading,
473 weak_ptr_factory_.GetWeakPtr())); 458 weak_ptr_factory_.GetWeakPtr()));
474 break; 459 break;
475 } 460 }
476 } 461 }
477 462
478 void ResourceLoader::Cancel() { 463 void ResourceLoader::Cancel() {
479 CancelRequest(false); 464 CancelWithError(net::ERR_ABORTED);
465 }
466
467 void ResourceLoader::CancelAndIgnore() {
468 CancelRequestInternal(net::ERR_ABORTED, false, true);
469 }
470
471 void ResourceLoader::CancelWithError(int error_code) {
472 TRACE_EVENT_WITH_FLOW0("loading", "ResourceLoader::CancelWithError", this,
473 TRACE_EVENT_FLAG_FLOW_IN);
474 CancelRequestInternal(error_code, false, false);
480 } 475 }
481 476
482 void ResourceLoader::StartRequestInternal() { 477 void ResourceLoader::StartRequestInternal() {
483 DCHECK(!request_->is_pending()); 478 DCHECK(!request_->is_pending());
484 479
485 if (!request_->status().is_success()) { 480 if (!request_->status().is_success()) {
486 return; 481 return;
487 } 482 }
488 483
489 started_request_ = true; 484 started_request_ = true;
490 request_->Start(); 485 request_->Start();
491 486
492 delegate_->DidStartRequest(this); 487 delegate_->DidStartRequest(this);
493 } 488 }
494 489
495 void ResourceLoader::CancelRequestInternal(int error, bool from_renderer) { 490 void ResourceLoader::CancelRequestInternal(int error,
491 bool from_renderer,
492 bool ignore) {
496 DVLOG(1) << "CancelRequestInternal: " << request_->url().spec(); 493 DVLOG(1) << "CancelRequestInternal: " << request_->url().spec();
497 494
498 ResourceRequestInfoImpl* info = GetRequestInfo(); 495 ResourceRequestInfoImpl* info = GetRequestInfo();
496 if (ignore)
497 info->set_was_ignored_by_handler(true);
499 498
500 // WebKit will send us a cancel for downloads since it no longer handles 499 // WebKit will send us a cancel for downloads since it no longer handles
501 // them. In this case, ignore the cancel since we handle downloads in the 500 // them. In this case, ignore the cancel since we handle downloads in the
502 // browser. 501 // browser.
503 if (from_renderer && (info->IsDownload() || info->is_stream())) 502 if (from_renderer && (info->IsDownload() || info->is_stream()))
504 return; 503 return;
505 504
506 if (from_renderer && info->detachable_handler()) { 505 if (from_renderer && info->detachable_handler()) {
507 // TODO(davidben): Fix Blink handling of prefetches so they are not 506 // TODO(davidben): Fix Blink handling of prefetches so they are not
508 // cancelled on navigate away and end up in the local cache. 507 // cancelled on navigate away and end up in the local cache.
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 ResourceRequestInfoImpl* info = GetRequestInfo(); 541 ResourceRequestInfoImpl* info = GetRequestInfo();
543 scoped_refptr<ResourceResponse> response = new ResourceResponse(); 542 scoped_refptr<ResourceResponse> response = new ResourceResponse();
544 PopulateResourceResponse(info, request_.get(), response.get()); 543 PopulateResourceResponse(info, request_.get(), response.get());
545 544
546 delegate_->DidReceiveResponse(this); 545 delegate_->DidReceiveResponse(this);
547 546
548 // TODO(darin): Remove ScopedTracker below once crbug.com/475761 is fixed. 547 // TODO(darin): Remove ScopedTracker below once crbug.com/475761 is fixed.
549 tracked_objects::ScopedTracker tracking_profile( 548 tracked_objects::ScopedTracker tracking_profile(
550 FROM_HERE_WITH_EXPLICIT_FUNCTION("475761 OnResponseStarted()")); 549 FROM_HERE_WITH_EXPLICIT_FUNCTION("475761 OnResponseStarted()"));
551 550
552 bool defer = false; 551 bool defer_or_cancel = false;
553 if (!handler_->OnResponseStarted(response.get(), &defer)) { 552 handler_->OnResponseStarted(response.get(), &defer_or_cancel);
554 Cancel(); 553 if (defer_or_cancel) {
555 } else if (defer) {
556 read_deferral_start_time_ = base::TimeTicks::Now(); 554 read_deferral_start_time_ = base::TimeTicks::Now();
557 deferred_stage_ = DEFERRED_READ; // Read first chunk when resumed. 555 deferred_stage_ = DEFERRED_READ; // Read first chunk when resumed.
558 } 556 }
559 } 557 }
560 558
561 void ResourceLoader::StartReading(bool is_continuation) { 559 void ResourceLoader::StartReading(bool is_continuation) {
560 TRACE_EVENT_WITH_FLOW0("loading", "ResourceLoader::StartReading", this,
561 TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
562 DCHECK(!is_deferred());
562 int bytes_read = 0; 563 int bytes_read = 0;
563 ReadMore(&bytes_read); 564
565 // Make sure we track the buffer in at least one place. This ensures it gets
566 // deleted even in the case the request has already finished its job and
567 // doesn't use the buffer.
568 scoped_refptr<net::IOBuffer> buf;
569 int buf_size;
570 {
571 // TODO(darin): Remove ScopedTracker below once crbug.com/475761 is fixed.
572 tracked_objects::ScopedTracker tracking_profile2(
573 FROM_HERE_WITH_EXPLICIT_FUNCTION("475761 OnWillRead()"));
574
575 if (!handler_->OnWillRead(&buf, &buf_size, -1)) {
576 Cancel();
577 return;
578 }
579 }
580
581 DCHECK(buf.get());
582 DCHECK(buf_size > 0);
583
584 // No need to check the return value here. Instead, detect errors below by
585 // inspecting the URLRequest's status.
586 request_->Read(buf.get(), buf_size, &bytes_read);
564 587
565 // If IO is pending, wait for the URLRequest to call OnReadCompleted. 588 // If IO is pending, wait for the URLRequest to call OnReadCompleted.
566 if (request_->status().is_io_pending()) 589 if (request_->status().is_io_pending())
567 return; 590 return;
568 591
569 if (!is_continuation || bytes_read <= 0) { 592 if (!is_continuation || bytes_read <= 0) {
570 OnReadCompleted(request_.get(), bytes_read); 593 OnReadCompleted(request_.get(), bytes_read);
571 } else { 594 } else {
572 // Else, trigger OnReadCompleted asynchronously to avoid starving the IO 595 // Else, trigger OnReadCompleted asynchronously to avoid starving the IO
573 // thread in case the URLRequest can provide data synchronously. 596 // thread in case the URLRequest can provide data synchronously.
(...skipping 12 matching lines...) Expand all
586 base::TimeTicks::Now() - read_deferral_start_time_); 609 base::TimeTicks::Now() - read_deferral_start_time_);
587 read_deferral_start_time_ = base::TimeTicks(); 610 read_deferral_start_time_ = base::TimeTicks();
588 } 611 }
589 if (request_->status().is_success()) { 612 if (request_->status().is_success()) {
590 StartReading(false); // Read the next chunk (OK to complete synchronously). 613 StartReading(false); // Read the next chunk (OK to complete synchronously).
591 } else { 614 } else {
592 ResponseCompleted(); 615 ResponseCompleted();
593 } 616 }
594 } 617 }
595 618
596 void ResourceLoader::ReadMore(int* bytes_read) {
597 TRACE_EVENT_WITH_FLOW0("loading", "ResourceLoader::ReadMore", this,
598 TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
599 DCHECK(!is_deferred());
600
601 // Make sure we track the buffer in at least one place. This ensures it gets
602 // deleted even in the case the request has already finished its job and
603 // doesn't use the buffer.
604 scoped_refptr<net::IOBuffer> buf;
605 int buf_size;
606 {
607 // TODO(darin): Remove ScopedTracker below once crbug.com/475761 is fixed.
608 tracked_objects::ScopedTracker tracking_profile2(
609 FROM_HERE_WITH_EXPLICIT_FUNCTION("475761 OnWillRead()"));
610
611 if (!handler_->OnWillRead(&buf, &buf_size, -1)) {
612 Cancel();
613 return;
614 }
615 }
616
617 DCHECK(buf.get());
618 DCHECK(buf_size > 0);
619
620 request_->Read(buf.get(), buf_size, bytes_read);
621
622 // No need to check the return value here as we'll detect errors by
623 // inspecting the URLRequest's status.
624 }
625
626 void ResourceLoader::CompleteRead(int bytes_read) { 619 void ResourceLoader::CompleteRead(int bytes_read) {
627 TRACE_EVENT_WITH_FLOW0("loading", "ResourceLoader::CompleteRead", this, 620 TRACE_EVENT_WITH_FLOW0("loading", "ResourceLoader::CompleteRead", this,
628 TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); 621 TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
629 622
630 DCHECK(bytes_read >= 0); 623 DCHECK(bytes_read >= 0);
631 DCHECK(request_->status().is_success()); 624 DCHECK(request_->status().is_success());
632 625
633 // TODO(darin): Remove ScopedTracker below once crbug.com/475761 is fixed. 626 // TODO(darin): Remove ScopedTracker below once crbug.com/475761 is fixed.
634 tracked_objects::ScopedTracker tracking_profile( 627 tracked_objects::ScopedTracker tracking_profile(
635 FROM_HERE_WITH_EXPLICIT_FUNCTION("475761 OnReadCompleted()")); 628 FROM_HERE_WITH_EXPLICIT_FUNCTION("475761 OnReadCompleted()"));
636 629
637 bool defer = false; 630 bool defer_or_cancel = false;
638 if (!handler_->OnReadCompleted(bytes_read, &defer)) { 631 handler_->OnReadCompleted(bytes_read, &defer_or_cancel);
639 Cancel(); 632 if (defer_or_cancel) {
640 } else if (defer) {
641 deferred_stage_ = 633 deferred_stage_ =
642 bytes_read > 0 ? DEFERRED_READ : DEFERRED_RESPONSE_COMPLETE; 634 bytes_read > 0 ? DEFERRED_READ : DEFERRED_RESPONSE_COMPLETE;
643 } 635 }
644 636
645 // Note: the request may still have been cancelled while OnReadCompleted 637 // Note: the request may still have been cancelled while OnReadCompleted
646 // returns true if OnReadCompleted caused request to get cancelled 638 // returns true if OnReadCompleted caused request to get cancelled
647 // out-of-band. (In AwResourceDispatcherHostDelegate::DownloadStarting, for 639 // out-of-band. (In AwResourceDispatcherHostDelegate::DownloadStarting, for
648 // instance.) 640 // instance.)
649 } 641 }
650 642
651 void ResourceLoader::ResponseCompleted() { 643 void ResourceLoader::ResponseCompleted() {
652 TRACE_EVENT_WITH_FLOW0("loading", "ResourceLoader::ResponseCompleted", this, 644 TRACE_EVENT_WITH_FLOW0("loading", "ResourceLoader::ResponseCompleted", this,
653 TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); 645 TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
654 646
655 DVLOG(1) << "ResponseCompleted: " << request_->url().spec(); 647 DVLOG(1) << "ResponseCompleted: " << request_->url().spec();
656 RecordHistograms(); 648 RecordHistograms();
657 649
658 bool defer = false; 650 bool defer = false;
659 { 651 {
660 // TODO(darin): Remove ScopedTracker below once crbug.com/475761 is fixed. 652 // TODO(darin): Remove ScopedTracker below once crbug.com/475761 is fixed.
661 tracked_objects::ScopedTracker tracking_profile( 653 tracked_objects::ScopedTracker tracking_profile(
662 FROM_HERE_WITH_EXPLICIT_FUNCTION("475761 OnResponseCompleted()")); 654 FROM_HERE_WITH_EXPLICIT_FUNCTION("475761 OnResponseCompleted()"));
663 655
664 handler_->OnResponseCompleted(request_->status(), &defer); 656 handler_->OnResponseCompleted(request_->status(), &defer);
665 } 657 }
666 if (defer) { 658 if (defer) {
667 // The handler is not ready to die yet. We will call DidFinishLoading when 659 // The handler is not ready to die yet. DidFinishLoading will be called on
668 // we resume. 660 // resume.
669 deferred_stage_ = DEFERRED_FINISH; 661 deferred_stage_ = DEFERRED_FINISH;
670 } else { 662 } else {
671 // This will result in our destruction. 663 // This will result in destroying |this|.
672 CallDidFinishLoading(); 664 CallDidFinishLoading();
673 } 665 }
674 } 666 }
675 667
676 void ResourceLoader::CallDidFinishLoading() { 668 void ResourceLoader::CallDidFinishLoading() {
677 TRACE_EVENT_WITH_FLOW0("loading", "ResourceLoader::CallDidFinishLoading", 669 TRACE_EVENT_WITH_FLOW0("loading", "ResourceLoader::CallDidFinishLoading",
678 this, TRACE_EVENT_FLAG_FLOW_IN); 670 this, TRACE_EVENT_FLAG_FLOW_IN);
679 delegate_->DidFinishLoading(this); 671 delegate_->DidFinishLoading(this);
680 } 672 }
681 673
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
721 } 713 }
722 714
723 UMA_HISTOGRAM_ENUMERATION("Net.Prefetch.Pattern", status, STATUS_MAX); 715 UMA_HISTOGRAM_ENUMERATION("Net.Prefetch.Pattern", status, STATUS_MAX);
724 } else if (request_->response_info().unused_since_prefetch) { 716 } else if (request_->response_info().unused_since_prefetch) {
725 TimeDelta total_time = base::TimeTicks::Now() - request_->creation_time(); 717 TimeDelta total_time = base::TimeTicks::Now() - request_->creation_time();
726 UMA_HISTOGRAM_TIMES("Net.Prefetch.TimeSpentOnPrefetchHit", total_time); 718 UMA_HISTOGRAM_TIMES("Net.Prefetch.TimeSpentOnPrefetchHit", total_time);
727 } 719 }
728 } 720 }
729 721
730 } // namespace content 722 } // 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