OLD | NEW |
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" |
20 #include "content/browser/loader/resource_handler.h" | 21 #include "content/browser/loader/resource_handler.h" |
21 #include "content/browser/loader/resource_loader_delegate.h" | 22 #include "content/browser/loader/resource_loader_delegate.h" |
22 #include "content/browser/loader/resource_request_info_impl.h" | 23 #include "content/browser/loader/resource_request_info_impl.h" |
23 #include "content/browser/service_worker/service_worker_request_handler.h" | 24 #include "content/browser/service_worker/service_worker_request_handler.h" |
24 #include "content/browser/service_worker/service_worker_response_info.h" | 25 #include "content/browser/service_worker/service_worker_response_info.h" |
25 #include "content/browser/ssl/ssl_client_auth_handler.h" | 26 #include "content/browser/ssl/ssl_client_auth_handler.h" |
26 #include "content/browser/ssl/ssl_manager.h" | 27 #include "content/browser/ssl/ssl_manager.h" |
| 28 #include "content/public/browser/resource_controller.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" |
30 #include "content/public/common/content_switches.h" | 32 #include "content/public/common/content_switches.h" |
31 #include "content/public/common/process_type.h" | 33 #include "content/public/common/process_type.h" |
32 #include "content/public/common/resource_response.h" | 34 #include "content/public/common/resource_response.h" |
33 #include "content/public/common/resource_type.h" | 35 #include "content/public/common/resource_type.h" |
34 #include "net/base/io_buffer.h" | 36 #include "net/base/io_buffer.h" |
35 #include "net/base/load_flags.h" | 37 #include "net/base/load_flags.h" |
36 #include "net/http/http_response_headers.h" | 38 #include "net/http/http_response_headers.h" |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
124 // We should not have any SSL state. | 126 // We should not have any SSL state. |
125 DCHECK(!request->ssl_info().cert_status); | 127 DCHECK(!request->ssl_info().cert_status); |
126 DCHECK_EQ(request->ssl_info().security_bits, -1); | 128 DCHECK_EQ(request->ssl_info().security_bits, -1); |
127 DCHECK_EQ(request->ssl_info().key_exchange_group, 0); | 129 DCHECK_EQ(request->ssl_info().key_exchange_group, 0); |
128 DCHECK(!request->ssl_info().connection_status); | 130 DCHECK(!request->ssl_info().connection_status); |
129 } | 131 } |
130 } | 132 } |
131 | 133 |
132 } // namespace | 134 } // namespace |
133 | 135 |
| 136 class ResourceLoader::Controller : public ResourceController { |
| 137 public: |
| 138 explicit Controller(ResourceLoader* resource_loader) |
| 139 : resource_loader_(resource_loader){}; |
| 140 |
| 141 ~Controller() override {} |
| 142 |
| 143 // ResourceController implementation: |
| 144 void Resume() override { |
| 145 DCHECK(!done_); |
| 146 done_ = true; |
| 147 resource_loader_->Resume(false); |
| 148 } |
| 149 |
| 150 void Cancel() override { |
| 151 DCHECK(!done_); |
| 152 done_ = true; |
| 153 resource_loader_->Cancel(); |
| 154 } |
| 155 |
| 156 void CancelAndIgnore() override { |
| 157 DCHECK(!done_); |
| 158 done_ = true; |
| 159 resource_loader_->CancelAndIgnore(); |
| 160 } |
| 161 |
| 162 void CancelWithError(int error_code) override { |
| 163 DCHECK(!done_); |
| 164 done_ = true; |
| 165 resource_loader_->CancelWithError(error_code); |
| 166 } |
| 167 |
| 168 private: |
| 169 ResourceLoader* const resource_loader_; |
| 170 |
| 171 // Set to true once one of the ResourceContoller methods has been invoked. |
| 172 bool done_ = false; |
| 173 |
| 174 DISALLOW_COPY_AND_ASSIGN(ResourceLoader::Controller); |
| 175 }; |
| 176 |
| 177 // Helper class. Sets the stage of a ResourceLoader to DEFERRED_SYNC on |
| 178 // construction, and on destruction does one of the following: |
| 179 // 1) If the ResourceLoader has a deferred stage of DEFERRED_NONE, sets the |
| 180 // ResourceLoader's stage to the stage specified on construction and resumes it. |
| 181 // 2) If the ResourceLoader still has a deferred stage of DEFERRED_SYNC, sets |
| 182 // the ResourceLoader's stage to the stage specified on construction. The |
| 183 // ResourceLoader will be resumed at some point in the future. |
| 184 class ResourceLoader::ScopedDeferral { |
| 185 public: |
| 186 ScopedDeferral(ResourceLoader* resource_loader, |
| 187 ResourceLoader::DeferredStage deferred_stage) |
| 188 : resource_loader_(resource_loader), deferred_stage_(deferred_stage) { |
| 189 resource_loader_->deferred_stage_ = DEFERRED_SYNC; |
| 190 } |
| 191 |
| 192 ~ScopedDeferral() { |
| 193 DeferredStage old_deferred_stage = resource_loader_->deferred_stage_; |
| 194 resource_loader_->deferred_stage_ = deferred_stage_; |
| 195 if (old_deferred_stage == DEFERRED_NONE) |
| 196 resource_loader_->Resume(true); |
| 197 } |
| 198 |
| 199 private: |
| 200 ResourceLoader* const resource_loader_; |
| 201 const DeferredStage deferred_stage_; |
| 202 |
| 203 DISALLOW_COPY_AND_ASSIGN(ScopedDeferral); |
| 204 }; |
| 205 |
134 ResourceLoader::ResourceLoader(std::unique_ptr<net::URLRequest> request, | 206 ResourceLoader::ResourceLoader(std::unique_ptr<net::URLRequest> request, |
135 std::unique_ptr<ResourceHandler> handler, | 207 std::unique_ptr<ResourceHandler> handler, |
136 ResourceLoaderDelegate* delegate) | 208 ResourceLoaderDelegate* delegate) |
137 : deferred_stage_(DEFERRED_NONE), | 209 : deferred_stage_(DEFERRED_NONE), |
138 request_(std::move(request)), | 210 request_(std::move(request)), |
139 handler_(std::move(handler)), | 211 handler_(std::move(handler)), |
140 delegate_(delegate), | 212 delegate_(delegate), |
141 is_transferring_(false), | 213 is_transferring_(false), |
142 times_cancelled_before_request_start_(0), | 214 times_cancelled_before_request_start_(0), |
143 started_request_(false), | 215 started_request_(false), |
144 times_cancelled_after_request_start_(0), | 216 times_cancelled_after_request_start_(0), |
145 weak_ptr_factory_(this) { | 217 weak_ptr_factory_(this) { |
146 request_->set_delegate(this); | 218 request_->set_delegate(this); |
147 handler_->SetController(this); | |
148 } | 219 } |
149 | 220 |
150 ResourceLoader::~ResourceLoader() { | 221 ResourceLoader::~ResourceLoader() { |
151 if (login_delegate_.get()) | 222 if (login_delegate_.get()) |
152 login_delegate_->OnRequestCancelled(); | 223 login_delegate_->OnRequestCancelled(); |
153 ssl_client_auth_handler_.reset(); | 224 ssl_client_auth_handler_.reset(); |
154 | 225 |
155 // Run ResourceHandler destructor before we tear-down the rest of our state | 226 // Run ResourceHandler destructor before we tear-down the rest of our state |
156 // as the ResourceHandler may want to inspect the URLRequest and other state. | 227 // as the ResourceHandler may want to inspect the URLRequest and other state. |
157 handler_.reset(); | 228 handler_.reset(); |
158 } | 229 } |
159 | 230 |
160 void ResourceLoader::StartRequest() { | 231 void ResourceLoader::StartRequest() { |
161 if (delegate_->HandleExternalProtocol(this, request_->url())) { | 232 if (delegate_->HandleExternalProtocol(this, request_->url())) { |
162 CancelAndIgnore(); | 233 CancelAndIgnore(); |
163 return; | 234 return; |
164 } | 235 } |
165 | 236 |
166 // Give the handler a chance to delay the URLRequest from being started. | 237 std::unique_ptr<ScopedDeferral> deferral( |
167 bool defer_start = false; | 238 new ScopedDeferral(this, DEFERRED_START)); |
168 if (!handler_->OnWillStart(request_->url(), &defer_start)) { | 239 handler_->OnWillStart(request_->url(), base::MakeUnique<Controller>(this)); |
169 Cancel(); | |
170 return; | |
171 } | |
172 | |
173 TRACE_EVENT_WITH_FLOW0("loading", "ResourceLoader::StartRequest", this, | |
174 TRACE_EVENT_FLAG_FLOW_OUT); | |
175 if (defer_start) { | |
176 deferred_stage_ = DEFERRED_START; | |
177 } else { | |
178 StartRequestInternal(); | |
179 } | |
180 } | 240 } |
181 | 241 |
182 void ResourceLoader::CancelRequest(bool from_renderer) { | 242 void ResourceLoader::CancelRequest(bool from_renderer) { |
183 TRACE_EVENT_WITH_FLOW0("loading", "ResourceLoader::CancelRequest", this, | 243 TRACE_EVENT_WITH_FLOW0("loading", "ResourceLoader::CancelRequest", this, |
184 TRACE_EVENT_FLAG_FLOW_IN); | 244 TRACE_EVENT_FLAG_FLOW_IN); |
185 CancelRequestInternal(net::ERR_ABORTED, from_renderer); | 245 CancelRequestInternal(net::ERR_ABORTED, from_renderer); |
186 } | 246 } |
187 | 247 |
188 void ResourceLoader::CancelAndIgnore() { | 248 void ResourceLoader::CancelAndIgnore() { |
189 ResourceRequestInfoImpl* info = GetRequestInfo(); | 249 ResourceRequestInfoImpl* info = GetRequestInfo(); |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
276 | 336 |
277 if (delegate_->HandleExternalProtocol(this, redirect_info.new_url)) { | 337 if (delegate_->HandleExternalProtocol(this, redirect_info.new_url)) { |
278 // The request is complete so we can remove it. | 338 // The request is complete so we can remove it. |
279 CancelAndIgnore(); | 339 CancelAndIgnore(); |
280 return; | 340 return; |
281 } | 341 } |
282 | 342 |
283 scoped_refptr<ResourceResponse> response = new ResourceResponse(); | 343 scoped_refptr<ResourceResponse> response = new ResourceResponse(); |
284 PopulateResourceResponse(info, request_.get(), response.get()); | 344 PopulateResourceResponse(info, request_.get(), response.get()); |
285 delegate_->DidReceiveRedirect(this, redirect_info.new_url, response.get()); | 345 delegate_->DidReceiveRedirect(this, redirect_info.new_url, response.get()); |
286 if (!handler_->OnRequestRedirected(redirect_info, response.get(), defer)) { | 346 |
287 Cancel(); | 347 // Can't used ScopedDeferral here, because on sync completion, need to set |
288 } else if (*defer) { | 348 // |defer| to false instead of calling back into the URLRequest. |
289 deferred_stage_ = DEFERRED_REDIRECT; // Follow redirect when resumed. | 349 deferred_stage_ = DEFERRED_SYNC; |
| 350 handler_->OnRequestRedirected(redirect_info, response.get(), |
| 351 base::MakeUnique<Controller>(this)); |
| 352 if (!is_deferred()) { |
| 353 *defer = false; |
| 354 return; |
290 } | 355 } |
| 356 |
| 357 *defer = true; |
| 358 deferred_stage_ = DEFERRED_REDIRECT; |
291 } | 359 } |
292 | 360 |
293 void ResourceLoader::OnAuthRequired(net::URLRequest* unused, | 361 void ResourceLoader::OnAuthRequired(net::URLRequest* unused, |
294 net::AuthChallengeInfo* auth_info) { | 362 net::AuthChallengeInfo* auth_info) { |
295 DCHECK_EQ(request_.get(), unused); | 363 DCHECK_EQ(request_.get(), unused); |
296 | 364 |
297 ResourceRequestInfoImpl* info = GetRequestInfo(); | 365 ResourceRequestInfoImpl* info = GetRequestInfo(); |
298 if (info->do_not_prompt_for_login()) { | 366 if (info->do_not_prompt_for_login()) { |
299 request_->CancelAuth(); | 367 request_->CancelAuth(); |
300 return; | 368 return; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 DCHECK_EQ(request_.get(), unused); | 411 DCHECK_EQ(request_.get(), unused); |
344 | 412 |
345 DVLOG(1) << "OnResponseStarted: " << request_->url().spec(); | 413 DVLOG(1) << "OnResponseStarted: " << request_->url().spec(); |
346 | 414 |
347 if (!request_->status().is_success()) { | 415 if (!request_->status().is_success()) { |
348 ResponseCompleted(); | 416 ResponseCompleted(); |
349 return; | 417 return; |
350 } | 418 } |
351 | 419 |
352 CompleteResponseStarted(); | 420 CompleteResponseStarted(); |
353 | |
354 if (is_deferred()) | |
355 return; | |
356 | |
357 if (request_->status().is_success()) | |
358 StartReading(false); // Read the first chunk. | |
359 else | |
360 ResponseCompleted(); | |
361 } | 421 } |
362 | 422 |
363 void ResourceLoader::OnReadCompleted(net::URLRequest* unused, int bytes_read) { | 423 void ResourceLoader::OnReadCompleted(net::URLRequest* unused, int bytes_read) { |
364 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("loading"), | 424 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("loading"), |
365 "ResourceLoader::OnReadCompleted"); | 425 "ResourceLoader::OnReadCompleted"); |
366 DCHECK_EQ(request_.get(), unused); | 426 DCHECK_EQ(request_.get(), unused); |
367 DVLOG(1) << "OnReadCompleted: \"" << request_->url().spec() << "\"" | 427 DVLOG(1) << "OnReadCompleted: \"" << request_->url().spec() << "\"" |
368 << " bytes_read = " << bytes_read; | 428 << " bytes_read = " << bytes_read; |
369 | 429 |
370 // bytes_read == -1 always implies an error. | 430 // bytes_read == -1 always implies an error. |
371 if (bytes_read == -1 || !request_->status().is_success()) { | 431 if (bytes_read == -1 || !request_->status().is_success()) { |
372 ResponseCompleted(); | 432 ResponseCompleted(); |
373 return; | 433 return; |
374 } | 434 } |
375 | 435 |
376 CompleteRead(bytes_read); | 436 CompleteRead(bytes_read); |
377 | |
378 // If the handler cancelled or deferred the request, do not continue | |
379 // processing the read. If cancelled, the URLRequest has already been | |
380 // cancelled and will schedule an erroring OnReadCompleted later. If deferred, | |
381 // do nothing until resumed. | |
382 // | |
383 // Note: if bytes_read is 0 (EOF) and the handler defers, resumption will call | |
384 // ResponseCompleted(). | |
385 if (is_deferred() || !request_->status().is_success()) | |
386 return; | |
387 | |
388 if (bytes_read > 0) { | |
389 StartReading(true); // Read the next chunk. | |
390 } else { | |
391 // TODO(darin): Remove ScopedTracker below once crbug.com/475761 is fixed. | |
392 tracked_objects::ScopedTracker tracking_profile( | |
393 FROM_HERE_WITH_EXPLICIT_FUNCTION("475761 ResponseCompleted()")); | |
394 | |
395 // URLRequest reported an EOF. Call ResponseCompleted. | |
396 DCHECK_EQ(0, bytes_read); | |
397 ResponseCompleted(); | |
398 } | |
399 } | 437 } |
400 | 438 |
401 void ResourceLoader::CancelSSLRequest(int error, | 439 void ResourceLoader::CancelSSLRequest(int error, |
402 const net::SSLInfo* ssl_info) { | 440 const net::SSLInfo* ssl_info) { |
403 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 441 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
404 | 442 |
405 // The request can be NULL if it was cancelled by the renderer (as the | 443 // The request can be NULL if it was cancelled by the renderer (as the |
406 // request of the user navigating to a new page from the location bar). | 444 // request of the user navigating to a new page from the location bar). |
407 if (!request_->is_pending()) | 445 if (!request_->is_pending()) |
408 return; | 446 return; |
(...skipping 25 matching lines...) Expand all Loading... |
434 net::FetchClientCertPrivateKey(cert); | 472 net::FetchClientCertPrivateKey(cert); |
435 request_->ContinueWithCertificate(cert, private_key.get()); | 473 request_->ContinueWithCertificate(cert, private_key.get()); |
436 } | 474 } |
437 | 475 |
438 void ResourceLoader::CancelCertificateSelection() { | 476 void ResourceLoader::CancelCertificateSelection() { |
439 DCHECK(ssl_client_auth_handler_); | 477 DCHECK(ssl_client_auth_handler_); |
440 ssl_client_auth_handler_.reset(); | 478 ssl_client_auth_handler_.reset(); |
441 request_->CancelWithError(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED); | 479 request_->CancelWithError(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED); |
442 } | 480 } |
443 | 481 |
444 void ResourceLoader::Resume() { | 482 void ResourceLoader::Resume(bool is_continuation) { |
445 DCHECK(!is_transferring_); | 483 DCHECK(!is_transferring_); |
446 | 484 |
447 DeferredStage stage = deferred_stage_; | 485 DeferredStage stage = deferred_stage_; |
448 deferred_stage_ = DEFERRED_NONE; | 486 deferred_stage_ = DEFERRED_NONE; |
449 switch (stage) { | 487 switch (stage) { |
450 case DEFERRED_NONE: | 488 case DEFERRED_NONE: |
451 NOTREACHED(); | 489 NOTREACHED(); |
452 break; | 490 break; |
| 491 case DEFERRED_SYNC: |
| 492 DCHECK(!is_continuation); |
| 493 // Request will be resumed when the stack unwinds. |
| 494 break; |
453 case DEFERRED_START: | 495 case DEFERRED_START: |
454 StartRequestInternal(); | 496 StartRequestInternal(); |
455 break; | 497 break; |
456 case DEFERRED_REDIRECT: | 498 case DEFERRED_REDIRECT: |
457 request_->FollowDeferredRedirect(); | 499 request_->FollowDeferredRedirect(); |
458 break; | 500 break; |
459 case DEFERRED_READ: | 501 case DEFERRED_READ: |
460 base::ThreadTaskRunnerHandle::Get()->PostTask( | 502 if (is_continuation) { |
461 FROM_HERE, base::Bind(&ResourceLoader::ResumeReading, | 503 StartReading(is_continuation); |
462 weak_ptr_factory_.GetWeakPtr())); | 504 } else { |
| 505 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 506 FROM_HERE, base::Bind(&ResourceLoader::ResumeReading, |
| 507 weak_ptr_factory_.GetWeakPtr())); |
| 508 } |
463 break; | 509 break; |
464 case DEFERRED_RESPONSE_COMPLETE: | 510 case DEFERRED_RESPONSE_COMPLETE: |
465 base::ThreadTaskRunnerHandle::Get()->PostTask( | 511 if (is_continuation) { |
466 FROM_HERE, base::Bind(&ResourceLoader::ResponseCompleted, | 512 ResponseCompleted(); |
467 weak_ptr_factory_.GetWeakPtr())); | 513 } else { |
| 514 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 515 FROM_HERE, base::Bind(&ResourceLoader::ResponseCompleted, |
| 516 weak_ptr_factory_.GetWeakPtr())); |
| 517 } |
468 break; | 518 break; |
469 case DEFERRED_FINISH: | 519 case DEFERRED_FINISH: |
470 // Delay self-destruction since we don't know how we were reached. | 520 // Delay self-destruction since we don't know how we were reached. |
471 base::ThreadTaskRunnerHandle::Get()->PostTask( | 521 if (!is_continuation) { |
472 FROM_HERE, base::Bind(&ResourceLoader::CallDidFinishLoading, | 522 CallDidFinishLoading(); |
473 weak_ptr_factory_.GetWeakPtr())); | 523 } else { |
| 524 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 525 FROM_HERE, base::Bind(&ResourceLoader::CallDidFinishLoading, |
| 526 weak_ptr_factory_.GetWeakPtr())); |
| 527 } |
474 break; | 528 break; |
475 } | 529 } |
476 } | 530 } |
477 | 531 |
478 void ResourceLoader::Cancel() { | 532 void ResourceLoader::Cancel() { |
479 CancelRequest(false); | 533 CancelRequest(false); |
480 } | 534 } |
481 | 535 |
482 void ResourceLoader::StartRequestInternal() { | 536 void ResourceLoader::StartRequestInternal() { |
483 DCHECK(!request_->is_pending()); | 537 DCHECK(!request_->is_pending()); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
542 ResourceRequestInfoImpl* info = GetRequestInfo(); | 596 ResourceRequestInfoImpl* info = GetRequestInfo(); |
543 scoped_refptr<ResourceResponse> response = new ResourceResponse(); | 597 scoped_refptr<ResourceResponse> response = new ResourceResponse(); |
544 PopulateResourceResponse(info, request_.get(), response.get()); | 598 PopulateResourceResponse(info, request_.get(), response.get()); |
545 | 599 |
546 delegate_->DidReceiveResponse(this); | 600 delegate_->DidReceiveResponse(this); |
547 | 601 |
548 // TODO(darin): Remove ScopedTracker below once crbug.com/475761 is fixed. | 602 // TODO(darin): Remove ScopedTracker below once crbug.com/475761 is fixed. |
549 tracked_objects::ScopedTracker tracking_profile( | 603 tracked_objects::ScopedTracker tracking_profile( |
550 FROM_HERE_WITH_EXPLICIT_FUNCTION("475761 OnResponseStarted()")); | 604 FROM_HERE_WITH_EXPLICIT_FUNCTION("475761 OnResponseStarted()")); |
551 | 605 |
552 bool defer = false; | 606 read_deferral_start_time_ = base::TimeTicks::Now(); |
553 if (!handler_->OnResponseStarted(response.get(), &defer)) { | 607 std::unique_ptr<ScopedDeferral> deferral( |
554 Cancel(); | 608 new ScopedDeferral(this, DEFERRED_READ)); |
555 } else if (defer) { | 609 handler_->OnResponseStarted(response.get(), |
556 read_deferral_start_time_ = base::TimeTicks::Now(); | 610 base::MakeUnique<Controller>(this)); |
557 deferred_stage_ = DEFERRED_READ; // Read first chunk when resumed. | |
558 } | |
559 } | 611 } |
560 | 612 |
561 void ResourceLoader::StartReading(bool is_continuation) { | 613 void ResourceLoader::StartReading(bool is_continuation) { |
562 int bytes_read = 0; | 614 int bytes_read = 0; |
563 ReadMore(&bytes_read); | 615 ReadMore(&bytes_read); |
564 | 616 |
565 // If IO is pending, wait for the URLRequest to call OnReadCompleted. | 617 // If IO is pending, wait for the URLRequest to call OnReadCompleted. |
566 if (request_->status().is_io_pending()) | 618 if (request_->status().is_io_pending()) |
567 return; | 619 return; |
568 | 620 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
627 TRACE_EVENT_WITH_FLOW0("loading", "ResourceLoader::CompleteRead", this, | 679 TRACE_EVENT_WITH_FLOW0("loading", "ResourceLoader::CompleteRead", this, |
628 TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); | 680 TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); |
629 | 681 |
630 DCHECK(bytes_read >= 0); | 682 DCHECK(bytes_read >= 0); |
631 DCHECK(request_->status().is_success()); | 683 DCHECK(request_->status().is_success()); |
632 | 684 |
633 // TODO(darin): Remove ScopedTracker below once crbug.com/475761 is fixed. | 685 // TODO(darin): Remove ScopedTracker below once crbug.com/475761 is fixed. |
634 tracked_objects::ScopedTracker tracking_profile( | 686 tracked_objects::ScopedTracker tracking_profile( |
635 FROM_HERE_WITH_EXPLICIT_FUNCTION("475761 OnReadCompleted()")); | 687 FROM_HERE_WITH_EXPLICIT_FUNCTION("475761 OnReadCompleted()")); |
636 | 688 |
637 bool defer = false; | 689 std::unique_ptr<ScopedDeferral> deferral(new ScopedDeferral( |
638 if (!handler_->OnReadCompleted(bytes_read, &defer)) { | 690 this, bytes_read > 0 ? DEFERRED_READ : DEFERRED_RESPONSE_COMPLETE)); |
639 Cancel(); | 691 handler_->OnReadCompleted(bytes_read, base::MakeUnique<Controller>(this)); |
640 } else if (defer) { | |
641 deferred_stage_ = | |
642 bytes_read > 0 ? DEFERRED_READ : DEFERRED_RESPONSE_COMPLETE; | |
643 } | |
644 | |
645 // Note: the request may still have been cancelled while OnReadCompleted | |
646 // returns true if OnReadCompleted caused request to get cancelled | |
647 // out-of-band. (In AwResourceDispatcherHostDelegate::DownloadStarting, for | |
648 // instance.) | |
649 } | 692 } |
650 | 693 |
651 void ResourceLoader::ResponseCompleted() { | 694 void ResourceLoader::ResponseCompleted() { |
652 TRACE_EVENT_WITH_FLOW0("loading", "ResourceLoader::ResponseCompleted", this, | 695 TRACE_EVENT_WITH_FLOW0("loading", "ResourceLoader::ResponseCompleted", this, |
653 TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); | 696 TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); |
654 | 697 |
655 DVLOG(1) << "ResponseCompleted: " << request_->url().spec(); | 698 DVLOG(1) << "ResponseCompleted: " << request_->url().spec(); |
656 RecordHistograms(); | 699 RecordHistograms(); |
657 | 700 |
658 bool defer = false; | 701 // TODO(darin): Remove ScopedTracker below once crbug.com/475761 is fixed. |
659 { | 702 tracked_objects::ScopedTracker tracking_profile( |
660 // TODO(darin): Remove ScopedTracker below once crbug.com/475761 is fixed. | 703 FROM_HERE_WITH_EXPLICIT_FUNCTION("475761 OnResponseCompleted()")); |
661 tracked_objects::ScopedTracker tracking_profile( | |
662 FROM_HERE_WITH_EXPLICIT_FUNCTION("475761 OnResponseCompleted()")); | |
663 | 704 |
664 handler_->OnResponseCompleted(request_->status(), &defer); | 705 std::unique_ptr<ScopedDeferral> deferral( |
665 } | 706 new ScopedDeferral(this, DEFERRED_FINISH)); |
666 if (defer) { | 707 handler_->OnResponseCompleted(request_->status(), |
667 // The handler is not ready to die yet. We will call DidFinishLoading when | 708 base::MakeUnique<Controller>(this)); |
668 // we resume. | |
669 deferred_stage_ = DEFERRED_FINISH; | |
670 } else { | |
671 // This will result in our destruction. | |
672 CallDidFinishLoading(); | |
673 } | |
674 } | 709 } |
675 | 710 |
676 void ResourceLoader::CallDidFinishLoading() { | 711 void ResourceLoader::CallDidFinishLoading() { |
677 TRACE_EVENT_WITH_FLOW0("loading", "ResourceLoader::CallDidFinishLoading", | 712 TRACE_EVENT_WITH_FLOW0("loading", "ResourceLoader::CallDidFinishLoading", |
678 this, TRACE_EVENT_FLAG_FLOW_IN); | 713 this, TRACE_EVENT_FLAG_FLOW_IN); |
679 delegate_->DidFinishLoading(this); | 714 delegate_->DidFinishLoading(this); |
680 } | 715 } |
681 | 716 |
682 void ResourceLoader::RecordHistograms() { | 717 void ResourceLoader::RecordHistograms() { |
683 ResourceRequestInfoImpl* info = GetRequestInfo(); | 718 ResourceRequestInfoImpl* info = GetRequestInfo(); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
721 } | 756 } |
722 | 757 |
723 UMA_HISTOGRAM_ENUMERATION("Net.Prefetch.Pattern", status, STATUS_MAX); | 758 UMA_HISTOGRAM_ENUMERATION("Net.Prefetch.Pattern", status, STATUS_MAX); |
724 } else if (request_->response_info().unused_since_prefetch) { | 759 } else if (request_->response_info().unused_since_prefetch) { |
725 TimeDelta total_time = base::TimeTicks::Now() - request_->creation_time(); | 760 TimeDelta total_time = base::TimeTicks::Now() - request_->creation_time(); |
726 UMA_HISTOGRAM_TIMES("Net.Prefetch.TimeSpentOnPrefetchHit", total_time); | 761 UMA_HISTOGRAM_TIMES("Net.Prefetch.TimeSpentOnPrefetchHit", total_time); |
727 } | 762 } |
728 } | 763 } |
729 | 764 |
730 } // namespace content | 765 } // namespace content |
OLD | NEW |