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 "net/url_request/url_fetcher_core.h" | 5 #include "net/url_request/url_fetcher_core.h" |
6 | 6 |
| 7 #include <stdint.h> |
| 8 |
7 #include "base/bind.h" | 9 #include "base/bind.h" |
8 #include "base/logging.h" | 10 #include "base/logging.h" |
9 #include "base/metrics/histogram.h" | 11 #include "base/metrics/histogram.h" |
10 #include "base/sequenced_task_runner.h" | 12 #include "base/sequenced_task_runner.h" |
11 #include "base/single_thread_task_runner.h" | 13 #include "base/single_thread_task_runner.h" |
12 #include "base/stl_util.h" | 14 #include "base/stl_util.h" |
13 #include "base/thread_task_runner_handle.h" | 15 #include "base/thread_task_runner_handle.h" |
14 #include "base/tracked_objects.h" | 16 #include "base/tracked_objects.h" |
15 #include "net/base/io_buffer.h" | 17 #include "net/base/io_buffer.h" |
16 #include "net/base/load_flags.h" | 18 #include "net/base/load_flags.h" |
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
469 | 471 |
470 void URLFetcherCore::SetEnableInterceptionForTests(bool enabled) { | 472 void URLFetcherCore::SetEnableInterceptionForTests(bool enabled) { |
471 g_interception_enabled = enabled; | 473 g_interception_enabled = enabled; |
472 } | 474 } |
473 | 475 |
474 void URLFetcherCore::SetIgnoreCertificateRequests(bool ignored) { | 476 void URLFetcherCore::SetIgnoreCertificateRequests(bool ignored) { |
475 g_ignore_certificate_requests = ignored; | 477 g_ignore_certificate_requests = ignored; |
476 } | 478 } |
477 | 479 |
478 URLFetcherCore::~URLFetcherCore() { | 480 URLFetcherCore::~URLFetcherCore() { |
479 // |request_| should be NULL. If not, it's unsafe to delete it here since we | 481 // |request_| should be NULL. If not, it's unsafe to delete it here since we |
480 // may not be on the IO thread. | 482 // may not be on the IO thread. |
481 DCHECK(!request_.get()); | 483 DCHECK(!request_.get()); |
482 } | 484 } |
483 | 485 |
484 void URLFetcherCore::StartOnIOThread() { | 486 void URLFetcherCore::StartOnIOThread() { |
485 DCHECK(network_task_runner_->BelongsToCurrentThread()); | 487 DCHECK(network_task_runner_->BelongsToCurrentThread()); |
486 | 488 |
487 if (!response_writer_) | 489 if (!response_writer_) |
488 response_writer_.reset(new URLFetcherStringWriter); | 490 response_writer_.reset(new URLFetcherStringWriter); |
489 | 491 |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
601 } | 603 } |
602 | 604 |
603 void URLFetcherCore::StartURLRequestWhenAppropriate() { | 605 void URLFetcherCore::StartURLRequestWhenAppropriate() { |
604 DCHECK(network_task_runner_->BelongsToCurrentThread()); | 606 DCHECK(network_task_runner_->BelongsToCurrentThread()); |
605 | 607 |
606 if (was_cancelled_) | 608 if (was_cancelled_) |
607 return; | 609 return; |
608 | 610 |
609 DCHECK(request_context_getter_.get()); | 611 DCHECK(request_context_getter_.get()); |
610 | 612 |
611 int64 delay = 0LL; | 613 int64 delay = INT64_C(0); |
612 if (original_url_throttler_entry_.get() == NULL) { | 614 if (!original_url_throttler_entry_.get()) { |
613 URLRequestThrottlerManager* manager = | 615 URLRequestThrottlerManager* manager = |
614 request_context_getter_->GetURLRequestContext()->throttler_manager(); | 616 request_context_getter_->GetURLRequestContext()->throttler_manager(); |
615 if (manager) { | 617 if (manager) { |
616 original_url_throttler_entry_ = | 618 original_url_throttler_entry_ = |
617 manager->RegisterRequestUrl(original_url_); | 619 manager->RegisterRequestUrl(original_url_); |
618 } | 620 } |
619 } | 621 } |
620 if (original_url_throttler_entry_.get() != NULL) { | 622 if (original_url_throttler_entry_.get()) { |
621 delay = original_url_throttler_entry_->ReserveSendingTimeForNextRequest( | 623 delay = original_url_throttler_entry_->ReserveSendingTimeForNextRequest( |
622 GetBackoffReleaseTime()); | 624 GetBackoffReleaseTime()); |
623 } | 625 } |
624 | 626 |
625 if (delay == 0) { | 627 if (delay == INT64_C(0)) { |
626 StartURLRequest(); | 628 StartURLRequest(); |
627 } else { | 629 } else { |
628 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | 630 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
629 FROM_HERE, base::Bind(&URLFetcherCore::StartURLRequest, this), | 631 FROM_HERE, base::Bind(&URLFetcherCore::StartURLRequest, this), |
630 base::TimeDelta::FromMilliseconds(delay)); | 632 base::TimeDelta::FromMilliseconds(delay)); |
631 } | 633 } |
632 } | 634 } |
633 | 635 |
634 void URLFetcherCore::CancelURLRequest(int error) { | 636 void URLFetcherCore::CancelURLRequest(int error) { |
635 DCHECK(network_task_runner_->BelongsToCurrentThread()); | 637 DCHECK(network_task_runner_->BelongsToCurrentThread()); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
671 } | 673 } |
672 | 674 |
673 void URLFetcherCore::InformDelegateFetchIsComplete() { | 675 void URLFetcherCore::InformDelegateFetchIsComplete() { |
674 DCHECK(delegate_task_runner_->BelongsToCurrentThread()); | 676 DCHECK(delegate_task_runner_->BelongsToCurrentThread()); |
675 if (delegate_) | 677 if (delegate_) |
676 delegate_->OnURLFetchComplete(fetcher_); | 678 delegate_->OnURLFetchComplete(fetcher_); |
677 } | 679 } |
678 | 680 |
679 void URLFetcherCore::NotifyMalformedContent() { | 681 void URLFetcherCore::NotifyMalformedContent() { |
680 DCHECK(network_task_runner_->BelongsToCurrentThread()); | 682 DCHECK(network_task_runner_->BelongsToCurrentThread()); |
681 if (url_throttler_entry_.get() != NULL) { | 683 if (url_throttler_entry_.get()) { |
682 int status_code = response_code_; | 684 int status_code = response_code_; |
683 if (status_code == URLFetcher::RESPONSE_CODE_INVALID) { | 685 if (status_code == URLFetcher::RESPONSE_CODE_INVALID) { |
684 // The status code will generally be known by the time clients | 686 // The status code will generally be known by the time clients |
685 // call the |ReceivedContentWasMalformed()| function (which ends up | 687 // call the |ReceivedContentWasMalformed()| function (which ends up |
686 // calling the current function) but if it's not, we need to assume | 688 // calling the current function) but if it's not, we need to assume |
687 // the response was successful so that the total failure count | 689 // the response was successful so that the total failure count |
688 // used to calculate exponential back-off goes up. | 690 // used to calculate exponential back-off goes up. |
689 status_code = 200; | 691 status_code = 200; |
690 } | 692 } |
691 url_throttler_entry_->ReceivedContentWasMalformed(status_code); | 693 url_throttler_entry_->ReceivedContentWasMalformed(status_code); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
761 | 763 |
762 void URLFetcherCore::ReleaseRequest() { | 764 void URLFetcherCore::ReleaseRequest() { |
763 upload_progress_checker_timer_.reset(); | 765 upload_progress_checker_timer_.reset(); |
764 request_.reset(); | 766 request_.reset(); |
765 g_registry.Get().RemoveURLFetcherCore(this); | 767 g_registry.Get().RemoveURLFetcherCore(this); |
766 } | 768 } |
767 | 769 |
768 base::TimeTicks URLFetcherCore::GetBackoffReleaseTime() { | 770 base::TimeTicks URLFetcherCore::GetBackoffReleaseTime() { |
769 DCHECK(network_task_runner_->BelongsToCurrentThread()); | 771 DCHECK(network_task_runner_->BelongsToCurrentThread()); |
770 | 772 |
771 if (original_url_throttler_entry_.get()) { | 773 if (!original_url_throttler_entry_.get()) |
772 base::TimeTicks original_url_backoff = | 774 return base::TimeTicks(); |
773 original_url_throttler_entry_->GetExponentialBackoffReleaseTime(); | |
774 base::TimeTicks destination_url_backoff; | |
775 if (url_throttler_entry_.get() != NULL && | |
776 original_url_throttler_entry_.get() != url_throttler_entry_.get()) { | |
777 destination_url_backoff = | |
778 url_throttler_entry_->GetExponentialBackoffReleaseTime(); | |
779 } | |
780 | 775 |
781 return original_url_backoff > destination_url_backoff ? | 776 base::TimeTicks original_url_backoff = |
782 original_url_backoff : destination_url_backoff; | 777 original_url_throttler_entry_->GetExponentialBackoffReleaseTime(); |
783 } else { | 778 base::TimeTicks destination_url_backoff; |
784 return base::TimeTicks(); | 779 if (url_throttler_entry_.get() && |
| 780 original_url_throttler_entry_.get() != url_throttler_entry_.get()) { |
| 781 destination_url_backoff = |
| 782 url_throttler_entry_->GetExponentialBackoffReleaseTime(); |
785 } | 783 } |
| 784 |
| 785 return original_url_backoff > destination_url_backoff ? |
| 786 original_url_backoff : destination_url_backoff; |
786 } | 787 } |
787 | 788 |
788 void URLFetcherCore::CompleteAddingUploadDataChunk( | 789 void URLFetcherCore::CompleteAddingUploadDataChunk( |
789 const std::string& content, bool is_last_chunk) { | 790 const std::string& content, bool is_last_chunk) { |
790 if (was_cancelled_) { | 791 if (was_cancelled_) { |
791 // Since CompleteAddingUploadDataChunk() is posted as a *delayed* task, it | 792 // Since CompleteAddingUploadDataChunk() is posted as a *delayed* task, it |
792 // may run after the URLFetcher was already stopped. | 793 // may run after the URLFetcher was already stopped. |
793 return; | 794 return; |
794 } | 795 } |
795 DCHECK(is_chunked_upload_); | 796 DCHECK(is_chunked_upload_); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
833 return; | 834 return; |
834 | 835 |
835 // Finished writing buffer_. Read some more, unless the request has been | 836 // Finished writing buffer_. Read some more, unless the request has been |
836 // cancelled and deleted. | 837 // cancelled and deleted. |
837 DCHECK_EQ(0, data->BytesRemaining()); | 838 DCHECK_EQ(0, data->BytesRemaining()); |
838 if (request_.get()) | 839 if (request_.get()) |
839 ReadResponse(); | 840 ReadResponse(); |
840 } | 841 } |
841 | 842 |
842 void URLFetcherCore::ReadResponse() { | 843 void URLFetcherCore::ReadResponse() { |
843 // Some servers may treat HEAD requests as GET requests. To free up the | 844 // Some servers may treat HEAD requests as GET requests. To free up the |
844 // network connection as soon as possible, signal that the request has | 845 // network connection as soon as possible, signal that the request has |
845 // completed immediately, without trying to read any data back (all we care | 846 // completed immediately, without trying to read any data back (all we care |
846 // about is the response code and headers, which we already have). | 847 // about is the response code and headers, which we already have). |
847 int bytes_read = 0; | 848 int bytes_read = 0; |
848 if (request_->status().is_success() && | 849 if (request_->status().is_success() && |
849 (request_type_ != URLFetcher::HEAD)) | 850 (request_type_ != URLFetcher::HEAD)) { |
850 request_->Read(buffer_.get(), kBufferSize, &bytes_read); | 851 if (!request_->Read(buffer_.get(), kBufferSize, &bytes_read)) |
| 852 bytes_read = -1; // Match OnReadCompleted() interface contract. |
| 853 } |
851 OnReadCompleted(request_.get(), bytes_read); | 854 OnReadCompleted(request_.get(), bytes_read); |
852 } | 855 } |
853 | 856 |
854 void URLFetcherCore::InformDelegateUploadProgress() { | 857 void URLFetcherCore::InformDelegateUploadProgress() { |
855 DCHECK(network_task_runner_->BelongsToCurrentThread()); | 858 DCHECK(network_task_runner_->BelongsToCurrentThread()); |
856 if (request_.get()) { | 859 if (request_.get()) { |
857 int64 current = request_->GetUploadProgress().position(); | 860 int64 current = request_->GetUploadProgress().position(); |
858 if (current_upload_bytes_ != current) { | 861 if (current_upload_bytes_ != current) { |
859 current_upload_bytes_ = current; | 862 current_upload_bytes_ = current; |
860 int64 total = -1; | 863 int64 total = -1; |
861 if (!is_chunked_upload_) { | 864 if (!is_chunked_upload_) { |
862 total = static_cast<int64>(request_->GetUploadProgress().size()); | 865 total = static_cast<int64>(request_->GetUploadProgress().size()); |
863 // Total may be zero if the UploadDataStream::Init has not been called | 866 // Total may be zero if the UploadDataStream::Init has not been called |
864 // yet. Don't send the upload progress until the size is initialized. | 867 // yet. Don't send the upload progress until the size is initialized. |
865 if (!total) | 868 if (!total) |
866 return; | 869 return; |
867 } | 870 } |
868 delegate_task_runner_->PostTask( | 871 delegate_task_runner_->PostTask( |
869 FROM_HERE, | 872 FROM_HERE, |
870 base::Bind( | 873 base::Bind( |
871 &URLFetcherCore::InformDelegateUploadProgressInDelegateThread, | 874 &URLFetcherCore::InformDelegateUploadProgressInDelegateThread, |
872 this, current, total)); | 875 this, current, total)); |
873 } | 876 } |
874 } | 877 } |
(...skipping 16 matching lines...) Expand all Loading... |
891 } | 894 } |
892 | 895 |
893 void URLFetcherCore::InformDelegateDownloadProgressInDelegateThread( | 896 void URLFetcherCore::InformDelegateDownloadProgressInDelegateThread( |
894 int64 current, int64 total) { | 897 int64 current, int64 total) { |
895 DCHECK(delegate_task_runner_->BelongsToCurrentThread()); | 898 DCHECK(delegate_task_runner_->BelongsToCurrentThread()); |
896 if (delegate_) | 899 if (delegate_) |
897 delegate_->OnURLFetchDownloadProgress(fetcher_, current, total); | 900 delegate_->OnURLFetchDownloadProgress(fetcher_, current, total); |
898 } | 901 } |
899 | 902 |
900 } // namespace net | 903 } // namespace net |
OLD | NEW |