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

Side by Side Diff: net/url_request/url_fetcher_core.cc

Issue 11464028: Introduce ERR_NETWORK_CHANGED and allow URLFetcher to automatically retry on that error. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years 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 | Annotate | Revision Log
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 "net/url_request/url_fetcher_core.h" 5 #include "net/url_request/url_fetcher_core.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/file_util_proxy.h" 8 #include "base/file_util_proxy.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/single_thread_task_runner.h" 10 #include "base/single_thread_task_runner.h"
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 url_request_data_key_(NULL), 280 url_request_data_key_(NULL),
281 was_fetched_via_proxy_(false), 281 was_fetched_via_proxy_(false),
282 is_chunked_upload_(false), 282 is_chunked_upload_(false),
283 num_retries_(0), 283 num_retries_(0),
284 was_cancelled_(false), 284 was_cancelled_(false),
285 response_destination_(STRING), 285 response_destination_(STRING),
286 stop_on_redirect_(false), 286 stop_on_redirect_(false),
287 stopped_on_redirect_(false), 287 stopped_on_redirect_(false),
288 automatically_retry_on_5xx_(true), 288 automatically_retry_on_5xx_(true),
289 max_retries_(0), 289 max_retries_(0),
290 max_retries_on_network_changes_(0),
290 current_upload_bytes_(-1), 291 current_upload_bytes_(-1),
291 current_response_bytes_(0), 292 current_response_bytes_(0),
292 total_response_bytes_(-1) { 293 total_response_bytes_(-1) {
293 CHECK(original_url_.is_valid()); 294 CHECK(original_url_.is_valid());
294 } 295 }
295 296
296 void URLFetcherCore::Start() { 297 void URLFetcherCore::Start() {
297 DCHECK(delegate_task_runner_); 298 DCHECK(delegate_task_runner_);
298 DCHECK(request_context_getter_) << "We need an URLRequestContext!"; 299 DCHECK(request_context_getter_) << "We need an URLRequestContext!";
299 if (network_task_runner_) { 300 if (network_task_runner_) {
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 } 413 }
413 414
414 int URLFetcherCore::GetMaxRetries() const { 415 int URLFetcherCore::GetMaxRetries() const {
415 return max_retries_; 416 return max_retries_;
416 } 417 }
417 418
418 base::TimeDelta URLFetcherCore::GetBackoffDelay() const { 419 base::TimeDelta URLFetcherCore::GetBackoffDelay() const {
419 return backoff_delay_; 420 return backoff_delay_;
420 } 421 }
421 422
423 void URLFetcherCore::SetAutomaticallyRetryOnNetworkChanges(int max_retries) {
424 max_retries_on_network_changes_ = max_retries;
425 }
426
422 void URLFetcherCore::SaveResponseToFileAtPath( 427 void URLFetcherCore::SaveResponseToFileAtPath(
423 const FilePath& file_path, 428 const FilePath& file_path,
424 scoped_refptr<base::TaskRunner> file_task_runner) { 429 scoped_refptr<base::TaskRunner> file_task_runner) {
425 DCHECK(delegate_task_runner_->BelongsToCurrentThread()); 430 DCHECK(delegate_task_runner_->BelongsToCurrentThread());
426 file_task_runner_ = file_task_runner; 431 file_task_runner_ = file_task_runner;
427 response_destination_ = URLFetcherCore::PERMANENT_FILE; 432 response_destination_ = URLFetcherCore::PERMANENT_FILE;
428 response_destination_file_path_ = file_path; 433 response_destination_file_path_ = file_path;
429 } 434 }
430 435
431 void URLFetcherCore::SaveResponseToTemporaryFile( 436 void URLFetcherCore::SaveResponseToTemporaryFile(
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
535 response_code_ = request_->GetResponseCode(); 540 response_code_ = request_->GetResponseCode();
536 was_fetched_via_proxy_ = request_->was_fetched_via_proxy(); 541 was_fetched_via_proxy_ = request_->was_fetched_via_proxy();
537 request->Cancel(); 542 request->Cancel();
538 OnReadCompleted(request, 0); 543 OnReadCompleted(request, 0);
539 } 544 }
540 } 545 }
541 546
542 void URLFetcherCore::OnResponseStarted(URLRequest* request) { 547 void URLFetcherCore::OnResponseStarted(URLRequest* request) {
543 DCHECK_EQ(request, request_.get()); 548 DCHECK_EQ(request, request_.get());
544 DCHECK(network_task_runner_->BelongsToCurrentThread()); 549 DCHECK(network_task_runner_->BelongsToCurrentThread());
550
545 if (request_->status().is_success()) { 551 if (request_->status().is_success()) {
546 response_code_ = request_->GetResponseCode(); 552 response_code_ = request_->GetResponseCode();
547 response_headers_ = request_->response_headers(); 553 response_headers_ = request_->response_headers();
548 socket_address_ = request_->GetSocketAddress(); 554 socket_address_ = request_->GetSocketAddress();
549 was_fetched_via_proxy_ = request_->was_fetched_via_proxy(); 555 was_fetched_via_proxy_ = request_->was_fetched_via_proxy();
550 total_response_bytes_ = request_->GetExpectedContentSize(); 556 total_response_bytes_ = request_->GetExpectedContentSize();
551 } 557 }
552 558
553 ReadResponse(); 559 ReadResponse();
554 } 560 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
599 // If the file is open, close it. After closing the file, 605 // If the file is open, close it. After closing the file,
600 // RetryOrCompleteUrlFetch() will be called. 606 // RetryOrCompleteUrlFetch() will be called.
601 file_writer_->CloseFileAndCompleteRequest(); 607 file_writer_->CloseFileAndCompleteRequest();
602 } else { 608 } else {
603 // Otherwise, complete or retry the URL request directly. 609 // Otherwise, complete or retry the URL request directly.
604 RetryOrCompleteUrlFetch(); 610 RetryOrCompleteUrlFetch();
605 } 611 }
606 } 612 }
607 } 613 }
608 614
615 void URLFetcherCore::OnConnectionTypeChanged(
616 NetworkChangeNotifier::ConnectionType type) {
617 if (NetworkChangeNotifier::IsOffline()) {
pauljensen 2012/12/07 23:00:05 I think it should be: if (type == NetworkChangeN
Joao da Silva 2012/12/10 15:32:42 Done.
618 // Keep waiting.
619 return;
620 }
621
622 // Stop observing and try again now.
623 NetworkChangeNotifier::RemoveConnectionTypeObserver(this);
624 network_task_runner_->PostTask(
625 FROM_HERE, base::Bind(&URLFetcherCore::StartOnIOThread, this));
626 }
627
609 void URLFetcherCore::CancelAll() { 628 void URLFetcherCore::CancelAll() {
610 g_registry.Get().CancelAll(); 629 g_registry.Get().CancelAll();
611 } 630 }
612 631
613 int URLFetcherCore::GetNumFetcherCores() { 632 int URLFetcherCore::GetNumFetcherCores() {
614 return g_registry.Get().size(); 633 return g_registry.Get().size();
615 } 634 }
616 635
617 void URLFetcherCore::SetEnableInterceptionForTests(bool enabled) { 636 void URLFetcherCore::SetEnableInterceptionForTests(bool enabled) {
618 g_interception_enabled = enabled; 637 g_interception_enabled = enabled;
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
850 if (backoff_delay < base::TimeDelta()) 869 if (backoff_delay < base::TimeDelta())
851 backoff_delay = base::TimeDelta(); 870 backoff_delay = base::TimeDelta();
852 871
853 if (automatically_retry_on_5xx_ && num_retries_ <= max_retries_) { 872 if (automatically_retry_on_5xx_ && num_retries_ <= max_retries_) {
854 StartOnIOThread(); 873 StartOnIOThread();
855 return; 874 return;
856 } 875 }
857 } else { 876 } else {
858 backoff_delay = base::TimeDelta(); 877 backoff_delay = base::TimeDelta();
859 } 878 }
879
880 // Retry if the request failed due to network changes.
881 if (status_.error() == ERR_NETWORK_CHANGED &&
882 max_retries_on_network_changes_ > 0) {
883 max_retries_on_network_changes_--;
pauljensen 2012/12/07 23:00:05 I notice the code above uses a counter and a maxim
Joao da Silva 2012/12/10 15:32:42 Done. Having a separate count also allows calling
884
885 if (NetworkChangeNotifier::IsOffline()) {
886 // Retry once we're back online.
887 NetworkChangeNotifier::AddConnectionTypeObserver(this);
888 } else {
889 // Retry soon, after flushing all the current tasks which may include
890 // further network change observers.
891 network_task_runner_->PostTask(
892 FROM_HERE, base::Bind(&URLFetcherCore::StartOnIOThread, this));
893 }
894
895 return;
896 }
897
860 request_context_getter_ = NULL; 898 request_context_getter_ = NULL;
861 first_party_for_cookies_ = GURL(); 899 first_party_for_cookies_ = GURL();
862 url_request_data_key_ = NULL; 900 url_request_data_key_ = NULL;
863 url_request_create_data_callback_.Reset(); 901 url_request_create_data_callback_.Reset();
864 bool posted = delegate_task_runner_->PostTask( 902 bool posted = delegate_task_runner_->PostTask(
865 FROM_HERE, 903 FROM_HERE,
866 base::Bind(&URLFetcherCore::OnCompletedURLRequest, this, backoff_delay)); 904 base::Bind(&URLFetcherCore::OnCompletedURLRequest, this, backoff_delay));
867 905
868 // If the delegate message loop does not exist any more, then the delegate 906 // If the delegate message loop does not exist any more, then the delegate
869 // should be gone too. 907 // should be gone too.
870 DCHECK(posted || !delegate_); 908 DCHECK(posted || !delegate_);
871 } 909 }
872 910
873 void URLFetcherCore::ReleaseRequest() { 911 void URLFetcherCore::ReleaseRequest() {
912 NetworkChangeNotifier::RemoveConnectionTypeObserver(this);
pauljensen 2012/12/07 23:00:05 Would be nice if we didn't always have to do this
Joao da Silva 2012/12/10 15:32:42 Checking that |num_retries_on_network_changes > 0|
pauljensen 2012/12/10 16:09:14 That seems fine.
874 upload_progress_checker_timer_.reset(); 913 upload_progress_checker_timer_.reset();
875 request_.reset(); 914 request_.reset();
876 g_registry.Get().RemoveURLFetcherCore(this); 915 g_registry.Get().RemoveURLFetcherCore(this);
877 } 916 }
878 917
879 base::TimeTicks URLFetcherCore::GetBackoffReleaseTime() { 918 base::TimeTicks URLFetcherCore::GetBackoffReleaseTime() {
880 DCHECK(network_task_runner_->BelongsToCurrentThread()); 919 DCHECK(network_task_runner_->BelongsToCurrentThread());
881 920
882 if (original_url_throttler_entry_) { 921 if (original_url_throttler_entry_) {
883 base::TimeTicks original_url_backoff = 922 base::TimeTicks original_url_backoff =
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
1007 } 1046 }
1008 1047
1009 void URLFetcherCore::InformDelegateDownloadDataInDelegateThread( 1048 void URLFetcherCore::InformDelegateDownloadDataInDelegateThread(
1010 scoped_ptr<std::string> download_data) { 1049 scoped_ptr<std::string> download_data) {
1011 DCHECK(delegate_task_runner_->BelongsToCurrentThread()); 1050 DCHECK(delegate_task_runner_->BelongsToCurrentThread());
1012 if (delegate_) 1051 if (delegate_)
1013 delegate_->OnURLFetchDownloadData(fetcher_, download_data.Pass()); 1052 delegate_->OnURLFetchDownloadData(fetcher_, download_data.Pass());
1014 } 1053 }
1015 1054
1016 } // namespace net 1055 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698