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/async_resource_handler.h" | 5 #include "content/browser/loader/async_resource_handler.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
289 new ResourceMsg_UploadProgress(GetRequestID(), | 289 new ResourceMsg_UploadProgress(GetRequestID(), |
290 progress.position(), | 290 progress.position(), |
291 progress.size())); | 291 progress.size())); |
292 } | 292 } |
293 waiting_for_upload_progress_ack_ = true; | 293 waiting_for_upload_progress_ack_ = true; |
294 last_upload_ticks_ = TimeTicks::Now(); | 294 last_upload_ticks_ = TimeTicks::Now(); |
295 last_upload_position_ = progress.position(); | 295 last_upload_position_ = progress.position(); |
296 } | 296 } |
297 } | 297 } |
298 | 298 |
299 bool AsyncResourceHandler::OnRequestRedirected( | 299 void AsyncResourceHandler::OnRequestRedirected( |
300 const net::RedirectInfo& redirect_info, | 300 const net::RedirectInfo& redirect_info, |
301 ResourceResponse* response, | 301 ResourceResponse* response, |
302 bool* defer) { | 302 std::unique_ptr<ResourceController> controller) { |
303 DCHECK(!has_controller()); | |
304 | |
303 const ResourceRequestInfoImpl* info = GetRequestInfo(); | 305 const ResourceRequestInfoImpl* info = GetRequestInfo(); |
304 if (!info->filter()) | 306 if (!info->filter()) { |
305 return false; | 307 controller->Cancel(); |
306 | 308 return; |
307 *defer = did_defer_ = true; | 309 } |
308 OnDefer(); | |
309 | 310 |
310 NetLogObserver::PopulateResponseInfo(request(), response); | 311 NetLogObserver::PopulateResponseInfo(request(), response); |
311 response->head.encoded_data_length = request()->GetTotalReceivedBytes(); | 312 response->head.encoded_data_length = request()->GetTotalReceivedBytes(); |
312 reported_transfer_size_ = 0; | 313 reported_transfer_size_ = 0; |
313 response->head.request_start = request()->creation_time(); | 314 response->head.request_start = request()->creation_time(); |
314 response->head.response_start = TimeTicks::Now(); | 315 response->head.response_start = TimeTicks::Now(); |
315 // TODO(davidben): Is it necessary to pass the new first party URL for | 316 // TODO(davidben): Is it necessary to pass the new first party URL for |
316 // cookies? The only case where it can change is top-level navigation requests | 317 // cookies? The only case where it can change is top-level navigation requests |
317 // and hopefully those will eventually all be owned by the browser. It's | 318 // and hopefully those will eventually all be owned by the browser. It's |
318 // possible this is still needed while renderer-owned ones exist. | 319 // possible this is still needed while renderer-owned ones exist. |
319 return info->filter()->Send(new ResourceMsg_ReceivedRedirect( | 320 if (!info->filter()->Send(new ResourceMsg_ReceivedRedirect( |
320 GetRequestID(), redirect_info, response->head)); | 321 GetRequestID(), redirect_info, response->head))) { |
322 controller->Cancel(); | |
323 } else { | |
324 did_defer_ = true; | |
325 OnDefer(); | |
326 set_controller(std::move(controller)); | |
327 } | |
321 } | 328 } |
322 | 329 |
323 bool AsyncResourceHandler::OnResponseStarted(ResourceResponse* response, | 330 void AsyncResourceHandler::OnResponseStarted( |
324 bool* defer) { | 331 ResourceResponse* response, |
332 std::unique_ptr<ResourceController> controller) { | |
325 // For changes to the main frame, inform the renderer of the new URL's | 333 // For changes to the main frame, inform the renderer of the new URL's |
326 // per-host settings before the request actually commits. This way the | 334 // per-host settings before the request actually commits. This way the |
327 // renderer will be able to set these precisely at the time the | 335 // renderer will be able to set these precisely at the time the |
328 // request commits, avoiding the possibility of e.g. zooming the old content | 336 // request commits, avoiding the possibility of e.g. zooming the old content |
329 // or of having to layout the new content twice. | 337 // or of having to layout the new content twice. |
338 DCHECK(!has_controller()); | |
330 | 339 |
331 response_started_ticks_ = base::TimeTicks::Now(); | 340 response_started_ticks_ = base::TimeTicks::Now(); |
332 | 341 |
333 progress_timer_.Stop(); | 342 progress_timer_.Stop(); |
334 const ResourceRequestInfoImpl* info = GetRequestInfo(); | 343 const ResourceRequestInfoImpl* info = GetRequestInfo(); |
335 if (!info->filter()) | 344 if (!info->filter()) { |
336 return false; | 345 Cancel(); |
346 return; | |
347 } | |
337 | 348 |
338 // We want to send a final upload progress message prior to sending the | 349 // We want to send a final upload progress message prior to sending the |
339 // response complete message even if we're waiting for an ack to to a | 350 // response complete message even if we're waiting for an ack to to a |
340 // previous upload progress message. | 351 // previous upload progress message. |
341 if (info->is_upload_progress_enabled()) { | 352 if (info->is_upload_progress_enabled()) { |
342 waiting_for_upload_progress_ack_ = false; | 353 waiting_for_upload_progress_ack_ = false; |
343 ReportUploadProgress(); | 354 ReportUploadProgress(); |
344 } | 355 } |
345 | 356 |
346 if (rdh_->delegate()) { | 357 if (rdh_->delegate()) { |
(...skipping 20 matching lines...) Expand all Loading... | |
367 | 378 |
368 if (request()->response_info().metadata.get()) { | 379 if (request()->response_info().metadata.get()) { |
369 std::vector<char> copy(request()->response_info().metadata->data(), | 380 std::vector<char> copy(request()->response_info().metadata->data(), |
370 request()->response_info().metadata->data() + | 381 request()->response_info().metadata->data() + |
371 request()->response_info().metadata->size()); | 382 request()->response_info().metadata->size()); |
372 info->filter()->Send(new ResourceMsg_ReceivedCachedMetadata(GetRequestID(), | 383 info->filter()->Send(new ResourceMsg_ReceivedCachedMetadata(GetRequestID(), |
373 copy)); | 384 copy)); |
374 } | 385 } |
375 | 386 |
376 inlining_helper_->OnResponseReceived(*response); | 387 inlining_helper_->OnResponseReceived(*response); |
377 return true; | 388 controller->Resume(); |
378 } | 389 } |
379 | 390 |
380 bool AsyncResourceHandler::OnWillStart(const GURL& url, bool* defer) { | 391 void AsyncResourceHandler::OnWillStart( |
392 const GURL& url, | |
393 std::unique_ptr<ResourceController> controller) { | |
381 if (GetRequestInfo()->is_upload_progress_enabled() && | 394 if (GetRequestInfo()->is_upload_progress_enabled() && |
382 request()->has_upload()) { | 395 request()->has_upload()) { |
383 ReportUploadProgress(); | 396 ReportUploadProgress(); |
384 progress_timer_.Start( | 397 progress_timer_.Start( |
385 FROM_HERE, | 398 FROM_HERE, |
386 base::TimeDelta::FromMilliseconds(kUploadProgressIntervalMsec), | 399 base::TimeDelta::FromMilliseconds(kUploadProgressIntervalMsec), |
387 this, | 400 this, |
388 &AsyncResourceHandler::ReportUploadProgress); | 401 &AsyncResourceHandler::ReportUploadProgress); |
389 } | 402 } |
390 return true; | 403 controller->Resume(); |
391 } | 404 } |
392 | 405 |
393 bool AsyncResourceHandler::OnWillRead(scoped_refptr<net::IOBuffer>* buf, | 406 bool AsyncResourceHandler::OnWillRead(scoped_refptr<net::IOBuffer>* buf, |
394 int* buf_size, | 407 int* buf_size, |
395 int min_size) { | 408 int min_size) { |
409 DCHECK(!has_controller()); | |
396 DCHECK_EQ(-1, min_size); | 410 DCHECK_EQ(-1, min_size); |
397 | 411 |
412 // TODO(mmenke): Should fail with ERR_INSUFFICIENT_RESOURCES here. | |
Randy Smith (Not in Mondays)
2016/12/16 21:37:26
Is there a reason why CancelWithError() can't be c
mmenke
2016/12/22 16:29:35
We don't have a ResourceController to call it on.
| |
398 if (!CheckForSufficientResource()) | 413 if (!CheckForSufficientResource()) |
399 return false; | 414 return false; |
400 | 415 |
401 // Return early if InliningHelper allocates the buffer, so that we should | 416 // Return early if InliningHelper allocates the buffer, so that we should |
402 // inline the data into the IPC message without allocating SharedMemory. | 417 // inline the data into the IPC message without allocating SharedMemory. |
403 if (inlining_helper_->PrepareInlineBufferIfApplicable(buf, buf_size)) | 418 if (inlining_helper_->PrepareInlineBufferIfApplicable(buf, buf_size)) |
404 return true; | 419 return true; |
405 | 420 |
406 if (!EnsureResourceBufferIsInitialized()) | 421 if (!EnsureResourceBufferIsInitialized()) |
407 return false; | 422 return false; |
408 | 423 |
409 DCHECK(buffer_->CanAllocate()); | 424 DCHECK(buffer_->CanAllocate()); |
410 char* memory = buffer_->Allocate(&allocation_size_); | 425 char* memory = buffer_->Allocate(&allocation_size_); |
411 CHECK(memory); | 426 CHECK(memory); |
412 | 427 |
413 *buf = new DependentIOBuffer(buffer_.get(), memory); | 428 *buf = new DependentIOBuffer(buffer_.get(), memory); |
414 *buf_size = allocation_size_; | 429 *buf_size = allocation_size_; |
415 | 430 |
416 return true; | 431 return true; |
417 } | 432 } |
418 | 433 |
419 bool AsyncResourceHandler::OnReadCompleted(int bytes_read, bool* defer) { | 434 void AsyncResourceHandler::OnReadCompleted( |
435 int bytes_read, | |
436 std::unique_ptr<ResourceController> controller) { | |
437 DCHECK(!has_controller()); | |
420 DCHECK_GE(bytes_read, 0); | 438 DCHECK_GE(bytes_read, 0); |
421 | 439 |
422 if (!bytes_read) | 440 if (!bytes_read) { |
423 return true; | 441 controller->Resume(); |
442 return; | |
443 } | |
424 | 444 |
425 ResourceMessageFilter* filter = GetFilter(); | 445 ResourceMessageFilter* filter = GetFilter(); |
426 if (!filter) | 446 if (!filter) { |
427 return false; | 447 controller->Cancel(); |
448 return; | |
449 } | |
428 | 450 |
429 int encoded_data_length = CalculateEncodedDataLengthToReport(); | 451 int encoded_data_length = CalculateEncodedDataLengthToReport(); |
430 if (!first_chunk_read_) | 452 if (!first_chunk_read_) |
431 encoded_data_length -= request()->raw_header_size(); | 453 encoded_data_length -= request()->raw_header_size(); |
432 | 454 |
433 int encoded_body_length = CalculateEncodedBodyLengthToReport(); | 455 int encoded_body_length = CalculateEncodedBodyLengthToReport(); |
434 first_chunk_read_ = true; | 456 first_chunk_read_ = true; |
435 | 457 |
436 // Return early if InliningHelper handled the received data. | 458 // Return early if InliningHelper handled the received data. |
437 if (inlining_helper_->SendInlinedDataIfApplicable( | 459 if (inlining_helper_->SendInlinedDataIfApplicable( |
438 bytes_read, encoded_data_length, encoded_body_length, filter, | 460 bytes_read, encoded_data_length, encoded_body_length, filter, |
439 GetRequestID())) | 461 GetRequestID())) { |
440 return true; | 462 controller->Resume(); |
463 return; | |
464 } | |
441 | 465 |
442 buffer_->ShrinkLastAllocation(bytes_read); | 466 buffer_->ShrinkLastAllocation(bytes_read); |
443 | 467 |
444 if (!sent_data_buffer_msg_) { | 468 if (!sent_data_buffer_msg_) { |
445 base::SharedMemoryHandle handle = base::SharedMemory::DuplicateHandle( | 469 base::SharedMemoryHandle handle = base::SharedMemory::DuplicateHandle( |
446 buffer_->GetSharedMemory().handle()); | 470 buffer_->GetSharedMemory().handle()); |
447 if (!base::SharedMemory::IsHandleValid(handle)) | 471 if (!base::SharedMemory::IsHandleValid(handle)) { |
448 return false; | 472 controller->Cancel(); |
473 return; | |
474 } | |
449 filter->Send(new ResourceMsg_SetDataBuffer( | 475 filter->Send(new ResourceMsg_SetDataBuffer( |
450 GetRequestID(), handle, buffer_->GetSharedMemory().mapped_size(), | 476 GetRequestID(), handle, buffer_->GetSharedMemory().mapped_size(), |
451 filter->peer_pid())); | 477 filter->peer_pid())); |
452 sent_data_buffer_msg_ = true; | 478 sent_data_buffer_msg_ = true; |
453 } | 479 } |
454 | 480 |
455 int data_offset = buffer_->GetLastAllocationOffset(); | 481 int data_offset = buffer_->GetLastAllocationOffset(); |
456 | 482 |
457 filter->Send(new ResourceMsg_DataReceived(GetRequestID(), data_offset, | 483 filter->Send(new ResourceMsg_DataReceived(GetRequestID(), data_offset, |
458 bytes_read, encoded_data_length, | 484 bytes_read, encoded_data_length, |
459 encoded_body_length)); | 485 encoded_body_length)); |
460 ++pending_data_count_; | 486 ++pending_data_count_; |
461 | 487 |
462 if (!buffer_->CanAllocate()) { | 488 if (!buffer_->CanAllocate()) { |
463 *defer = did_defer_ = true; | 489 did_defer_ = true; |
464 OnDefer(); | 490 OnDefer(); |
491 set_controller(std::move(controller)); | |
492 } else { | |
493 controller->Resume(); | |
465 } | 494 } |
466 | |
467 return true; | |
468 } | 495 } |
469 | 496 |
470 void AsyncResourceHandler::OnDataDownloaded(int bytes_downloaded) { | 497 void AsyncResourceHandler::OnDataDownloaded(int bytes_downloaded) { |
471 int encoded_data_length = CalculateEncodedDataLengthToReport(); | 498 int encoded_data_length = CalculateEncodedDataLengthToReport(); |
472 | 499 |
473 ResourceMessageFilter* filter = GetFilter(); | 500 ResourceMessageFilter* filter = GetFilter(); |
474 if (filter) { | 501 if (filter) { |
475 filter->Send(new ResourceMsg_DataDownloaded( | 502 filter->Send(new ResourceMsg_DataDownloaded( |
476 GetRequestID(), bytes_downloaded, encoded_data_length)); | 503 GetRequestID(), bytes_downloaded, encoded_data_length)); |
477 } | 504 } |
478 } | 505 } |
479 | 506 |
480 void AsyncResourceHandler::OnResponseCompleted( | 507 void AsyncResourceHandler::OnResponseCompleted( |
481 const net::URLRequestStatus& status, | 508 const net::URLRequestStatus& status, |
482 bool* defer) { | 509 std::unique_ptr<ResourceController> controller) { |
483 const ResourceRequestInfoImpl* info = GetRequestInfo(); | 510 const ResourceRequestInfoImpl* info = GetRequestInfo(); |
484 if (!info->filter()) | 511 if (!info->filter()) { |
512 controller->Resume(); | |
485 return; | 513 return; |
514 } | |
486 | 515 |
487 // If we crash here, figure out what URL the renderer was requesting. | 516 // If we crash here, figure out what URL the renderer was requesting. |
488 // http://crbug.com/107692 | 517 // http://crbug.com/107692 |
489 char url_buf[128]; | 518 char url_buf[128]; |
490 base::strlcpy(url_buf, request()->url().spec().c_str(), arraysize(url_buf)); | 519 base::strlcpy(url_buf, request()->url().spec().c_str(), arraysize(url_buf)); |
491 base::debug::Alias(url_buf); | 520 base::debug::Alias(url_buf); |
492 | 521 |
493 // TODO(gavinp): Remove this CHECK when we figure out the cause of | 522 // TODO(gavinp): Remove this CHECK when we figure out the cause of |
494 // http://crbug.com/124680 . This check mirrors closely check in | 523 // http://crbug.com/124680 . This check mirrors closely check in |
495 // WebURLLoaderImpl::OnCompletedRequest that routes this message to a WebCore | 524 // WebURLLoaderImpl::OnCompletedRequest that routes this message to a WebCore |
(...skipping 16 matching lines...) Expand all Loading... | |
512 request_complete_data.was_ignored_by_handler = was_ignored_by_handler; | 541 request_complete_data.was_ignored_by_handler = was_ignored_by_handler; |
513 request_complete_data.exists_in_cache = request()->response_info().was_cached; | 542 request_complete_data.exists_in_cache = request()->response_info().was_cached; |
514 request_complete_data.completion_time = TimeTicks::Now(); | 543 request_complete_data.completion_time = TimeTicks::Now(); |
515 request_complete_data.encoded_data_length = | 544 request_complete_data.encoded_data_length = |
516 request()->GetTotalReceivedBytes(); | 545 request()->GetTotalReceivedBytes(); |
517 info->filter()->Send( | 546 info->filter()->Send( |
518 new ResourceMsg_RequestComplete(GetRequestID(), request_complete_data)); | 547 new ResourceMsg_RequestComplete(GetRequestID(), request_complete_data)); |
519 | 548 |
520 if (status.is_success()) | 549 if (status.is_success()) |
521 RecordHistogram(); | 550 RecordHistogram(); |
551 controller->Resume(); | |
522 } | 552 } |
523 | 553 |
524 bool AsyncResourceHandler::EnsureResourceBufferIsInitialized() { | 554 bool AsyncResourceHandler::EnsureResourceBufferIsInitialized() { |
525 DCHECK(has_checked_for_sufficient_resources_); | 555 DCHECK(has_checked_for_sufficient_resources_); |
526 | 556 |
527 if (buffer_.get() && buffer_->IsInitialized()) | 557 if (buffer_.get() && buffer_->IsInitialized()) |
528 return true; | 558 return true; |
529 | 559 |
530 buffer_ = new ResourceBuffer(); | 560 buffer_ = new ResourceBuffer(); |
531 return buffer_->Initialize(kBufferSize, | 561 return buffer_->Initialize(kBufferSize, |
532 kMinAllocationSize, | 562 kMinAllocationSize, |
533 kMaxAllocationSize); | 563 kMaxAllocationSize); |
534 } | 564 } |
535 | 565 |
536 void AsyncResourceHandler::ResumeIfDeferred() { | 566 void AsyncResourceHandler::ResumeIfDeferred() { |
537 if (did_defer_) { | 567 if (did_defer_) { |
538 did_defer_ = false; | 568 did_defer_ = false; |
539 request()->LogUnblocked(); | 569 request()->LogUnblocked(); |
540 controller()->Resume(); | 570 Resume(); |
541 } | 571 } |
542 } | 572 } |
543 | 573 |
544 void AsyncResourceHandler::OnDefer() { | 574 void AsyncResourceHandler::OnDefer() { |
545 request()->LogBlockedBy("AsyncResourceHandler"); | 575 request()->LogBlockedBy("AsyncResourceHandler"); |
546 } | 576 } |
547 | 577 |
548 bool AsyncResourceHandler::CheckForSufficientResource() { | 578 bool AsyncResourceHandler::CheckForSufficientResource() { |
549 if (has_checked_for_sufficient_resources_) | 579 if (has_checked_for_sufficient_resources_) |
550 return true; | 580 return true; |
551 has_checked_for_sufficient_resources_ = true; | 581 has_checked_for_sufficient_resources_ = true; |
552 | 582 |
553 if (rdh_->HasSufficientResourcesForRequest(request())) | 583 if (rdh_->HasSufficientResourcesForRequest(request())) |
554 return true; | 584 return true; |
555 | 585 |
556 controller()->CancelWithError(net::ERR_INSUFFICIENT_RESOURCES); | |
557 return false; | 586 return false; |
558 } | 587 } |
559 | 588 |
560 int AsyncResourceHandler::CalculateEncodedDataLengthToReport() { | 589 int AsyncResourceHandler::CalculateEncodedDataLengthToReport() { |
561 return TrackDifference(request()->GetTotalReceivedBytes(), | 590 return TrackDifference(request()->GetTotalReceivedBytes(), |
562 &reported_transfer_size_); | 591 &reported_transfer_size_); |
563 } | 592 } |
564 | 593 |
565 int AsyncResourceHandler::CalculateEncodedBodyLengthToReport() { | 594 int AsyncResourceHandler::CalculateEncodedBodyLengthToReport() { |
566 return TrackDifference(request()->GetRawBodyBytes(), | 595 return TrackDifference(request()->GetRawBodyBytes(), |
(...skipping 20 matching lines...) Expand all Loading... | |
587 } else { | 616 } else { |
588 UMA_HISTOGRAM_CUSTOM_COUNTS( | 617 UMA_HISTOGRAM_CUSTOM_COUNTS( |
589 "Net.ResourceLoader.ResponseStartToEnd.Over_512kB", | 618 "Net.ResourceLoader.ResponseStartToEnd.Over_512kB", |
590 elapsed_time, 1, 100000, 100); | 619 elapsed_time, 1, 100000, 100); |
591 } | 620 } |
592 | 621 |
593 inlining_helper_->RecordHistogram(elapsed_time); | 622 inlining_helper_->RecordHistogram(elapsed_time); |
594 } | 623 } |
595 | 624 |
596 } // namespace content | 625 } // namespace content |
OLD | NEW |