Chromium Code Reviews| Index: libcurl_http_fetcher.cc |
| diff --git a/libcurl_http_fetcher.cc b/libcurl_http_fetcher.cc |
| index 7a032fe460fb18cd54f49be99c71c1a65917c6ae..e2f18afcb66c0c5e3f71c8ca81fe97fe67193cc4 100644 |
| --- a/libcurl_http_fetcher.cc |
| +++ b/libcurl_http_fetcher.cc |
| @@ -14,6 +14,10 @@ using std::make_pair; |
| namespace chromeos_update_engine { |
| +namespace { |
| +const int kMaxRetriesCount = 20; |
| +} |
| + |
| LibcurlHttpFetcher::~LibcurlHttpFetcher() { |
| CleanUp(); |
| } |
| @@ -66,9 +70,9 @@ void LibcurlHttpFetcher::BeginTransfer(const std::string& url) { |
| transfer_size_ = -1; |
| bytes_downloaded_ = 0; |
| resume_offset_ = 0; |
| - do { |
| - ResumeTransfer(url); |
| - } while (CurlPerformOnce()); |
| + retry_count_ = 0; |
| + ResumeTransfer(url); |
| + CurlPerformOnce(); |
| } |
| void LibcurlHttpFetcher::TerminateTransfer() { |
| @@ -86,15 +90,37 @@ bool LibcurlHttpFetcher::CurlPerformOnce() { |
| retcode = curl_multi_perform(curl_multi_handle_, &running_handles); |
| } |
| if (0 == running_handles) { |
| + long http_response_code = 0; |
| + if (curl_easy_getinfo(curl_handle_, |
|
petkov
2010/07/16 21:47:45
This is definitely better than the CHECK_EQ...
|
| + CURLINFO_RESPONSE_CODE, |
| + &http_response_code) == CURLE_OK) { |
| + LOG(INFO) << "HTTP response code: " << http_response_code; |
| + } else { |
| + LOG(ERROR) << "Unable to get http response code."; |
| + } |
| + |
| // we're done! |
| CleanUp(); |
| if ((transfer_size_ >= 0) && (bytes_downloaded_ < transfer_size_)) { |
| // Need to restart transfer |
| - return true; |
| + retry_count_++; |
| + LOG(INFO) << "Restarting transfer b/c we finished, had downloaded " |
| + << bytes_downloaded_ << " bytes, but transfer_size_ is " |
| + << transfer_size_ << ". retry_count: " << retry_count_; |
| + if (retry_count_ > kMaxRetriesCount) { |
| + if (delegate_) |
| + delegate_->TransferComplete(this, false); // success |
| + } else { |
| + g_timeout_add(5 * 1000, |
| + &LibcurlHttpFetcher::StaticRetryTimeoutCallback, |
| + this); |
| + } |
| + return false; |
| } else { |
| if (delegate_) { |
| - delegate_->TransferComplete(this, true); // success |
| + // success is when http_response_code is 200 |
| + delegate_->TransferComplete(this, http_response_code == 200); |
| } |
| } |
| } else { |
| @@ -217,9 +243,7 @@ void LibcurlHttpFetcher::SetupMainloopSources() { |
| bool LibcurlHttpFetcher::FDCallback(GIOChannel *source, |
| GIOCondition condition) { |
| - while (CurlPerformOnce()) { |
| - ResumeTransfer(url_); |
| - } |
| + CurlPerformOnce(); |
| // We handle removing of this source elsewhere, so we always return true. |
| // The docs say, "the function should return FALSE if the event source |
| // should be removed." |
| @@ -227,6 +251,12 @@ bool LibcurlHttpFetcher::FDCallback(GIOChannel *source, |
| return true; |
| } |
| +gboolean LibcurlHttpFetcher::RetryTimeoutCallback() { |
| + ResumeTransfer(url_); |
| + CurlPerformOnce(); |
| + return FALSE; // Don't have glib auto call this callback again |
| +} |
| + |
| gboolean LibcurlHttpFetcher::TimeoutCallback() { |
| if (!transfer_in_progress_) |
| return TRUE; |
| @@ -236,9 +266,7 @@ gboolean LibcurlHttpFetcher::TimeoutCallback() { |
| // timeout callback then. |
| // TODO(adlr): optimize by checking if we can keep this timeout callback. |
| //timeout_source_ = NULL; |
| - while (CurlPerformOnce()) { |
| - ResumeTransfer(url_); |
| - } |
| + CurlPerformOnce(); |
| return TRUE; |
| } |