| 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 |