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

Side by Side Diff: libcurl_http_fetcher.cc

Issue 3591018: AU: MultiHttpFetcher, an HttpFetcher for specific byte ranges (Closed) Base URL: ssh://git@chromiumos-git/update_engine.git
Patch Set: fixes for rewview Created 10 years, 2 months 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
« no previous file with comments | « libcurl_http_fetcher.h ('k') | mock_http_fetcher.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009 The Chromium OS Authors. All rights reserved. 1 // Copyright (c) 2009 The Chromium OS 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 "update_engine/libcurl_http_fetcher.h" 5 #include "update_engine/libcurl_http_fetcher.h"
6 #include <algorithm> 6 #include <algorithm>
7 #include "base/logging.h" 7 #include "base/logging.h"
8 8
9 using std::max; 9 using std::max;
10 using std::make_pair; 10 using std::make_pair;
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_CAPATH, kCACertificatesPath), 74 CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_CAPATH, kCACertificatesPath),
75 CURLE_OK); 75 CURLE_OK);
76 76
77 CHECK_EQ(curl_multi_add_handle(curl_multi_handle_, curl_handle_), CURLM_OK); 77 CHECK_EQ(curl_multi_add_handle(curl_multi_handle_, curl_handle_), CURLM_OK);
78 transfer_in_progress_ = true; 78 transfer_in_progress_ = true;
79 } 79 }
80 80
81 // Begins the transfer, which must not have already been started. 81 // Begins the transfer, which must not have already been started.
82 void LibcurlHttpFetcher::BeginTransfer(const std::string& url) { 82 void LibcurlHttpFetcher::BeginTransfer(const std::string& url) {
83 transfer_size_ = -1; 83 transfer_size_ = -1;
84 bytes_downloaded_ = 0;
85 resume_offset_ = 0; 84 resume_offset_ = 0;
86 retry_count_ = 0; 85 retry_count_ = 0;
87 http_response_code_ = 0; 86 http_response_code_ = 0;
88 ResumeTransfer(url); 87 ResumeTransfer(url);
89 CurlPerformOnce(); 88 CurlPerformOnce();
90 } 89 }
91 90
92 void LibcurlHttpFetcher::TerminateTransfer() { 91 void LibcurlHttpFetcher::TerminateTransfer() {
93 CleanUp(); 92 if (in_write_callback_)
93 terminate_requested_ = true;
94 else
95 CleanUp();
94 } 96 }
95 97
96 void LibcurlHttpFetcher::CurlPerformOnce() { 98 void LibcurlHttpFetcher::CurlPerformOnce() {
97 CHECK(transfer_in_progress_); 99 CHECK(transfer_in_progress_);
98 int running_handles = 0; 100 int running_handles = 0;
99 CURLMcode retcode = CURLM_CALL_MULTI_PERFORM; 101 CURLMcode retcode = CURLM_CALL_MULTI_PERFORM;
100 102
101 // libcurl may request that we immediately call curl_multi_perform after it 103 // libcurl may request that we immediately call curl_multi_perform after it
102 // returns, so we do. libcurl promises that curl_multi_perform will not block. 104 // returns, so we do. libcurl promises that curl_multi_perform will not block.
103 while (CURLM_CALL_MULTI_PERFORM == retcode) { 105 while (CURLM_CALL_MULTI_PERFORM == retcode) {
104 retcode = curl_multi_perform(curl_multi_handle_, &running_handles); 106 retcode = curl_multi_perform(curl_multi_handle_, &running_handles);
107 if (terminate_requested_) {
108 CleanUp();
109 return;
110 }
105 } 111 }
106 if (0 == running_handles) { 112 if (0 == running_handles) {
107 long http_response_code = 0; 113 GetHttpResponseCode();
108 if (curl_easy_getinfo(curl_handle_, 114 if (http_response_code_) {
109 CURLINFO_RESPONSE_CODE, 115 LOG(INFO) << "HTTP response code: " << http_response_code_;
110 &http_response_code) == CURLE_OK) {
111 LOG(INFO) << "HTTP response code: " << http_response_code;
112 } else { 116 } else {
113 LOG(ERROR) << "Unable to get http response code."; 117 LOG(ERROR) << "Unable to get http response code.";
114 } 118 }
115 http_response_code_ = static_cast<int>(http_response_code);
116 119
117 // we're done! 120 // we're done!
118 CleanUp(); 121 CleanUp();
119 122
120 if ((transfer_size_ >= 0) && (bytes_downloaded_ < transfer_size_)) { 123 if ((transfer_size_ >= 0) && (bytes_downloaded_ < transfer_size_)) {
121 // Need to restart transfer 124 // Need to restart transfer
122 retry_count_++; 125 retry_count_++;
123 LOG(INFO) << "Restarting transfer b/c we finished, had downloaded " 126 LOG(INFO) << "Restarting transfer b/c we finished, had downloaded "
124 << bytes_downloaded_ << " bytes, but transfer_size_ is " 127 << bytes_downloaded_ << " bytes, but transfer_size_ is "
125 << transfer_size_ << ". retry_count: " << retry_count_; 128 << transfer_size_ << ". retry_count: " << retry_count_;
126 if (retry_count_ > kMaxRetriesCount) { 129 if (retry_count_ > kMaxRetriesCount) {
127 if (delegate_) 130 if (delegate_)
128 delegate_->TransferComplete(this, false); // success 131 delegate_->TransferComplete(this, false); // success
129 } else { 132 } else {
130 g_timeout_add_seconds(retry_seconds_, 133 g_timeout_add_seconds(retry_seconds_,
131 &LibcurlHttpFetcher::StaticRetryTimeoutCallback, 134 &LibcurlHttpFetcher::StaticRetryTimeoutCallback,
132 this); 135 this);
133 } 136 }
134 return; 137 return;
135 } else { 138 } else {
136 if (delegate_) { 139 if (delegate_) {
137 // success is when http_response_code is 2xx 140 // success is when http_response_code is 2xx
138 bool success = (http_response_code >= 200) && 141 bool success = (http_response_code_ >= 200) &&
139 (http_response_code < 300); 142 (http_response_code_ < 300);
140 delegate_->TransferComplete(this, success); 143 delegate_->TransferComplete(this, success);
141 } 144 }
142 } 145 }
143 } else { 146 } else {
144 // set up callback 147 // set up callback
145 SetupMainloopSources(); 148 SetupMainloopSources();
146 } 149 }
147 } 150 }
148 151
149 size_t LibcurlHttpFetcher::LibcurlWrite(void *ptr, size_t size, size_t nmemb) { 152 size_t LibcurlHttpFetcher::LibcurlWrite(void *ptr, size_t size, size_t nmemb) {
153 GetHttpResponseCode();
150 { 154 {
151 double transfer_size_double; 155 double transfer_size_double;
152 CHECK_EQ(curl_easy_getinfo(curl_handle_, 156 CHECK_EQ(curl_easy_getinfo(curl_handle_,
153 CURLINFO_CONTENT_LENGTH_DOWNLOAD, 157 CURLINFO_CONTENT_LENGTH_DOWNLOAD,
154 &transfer_size_double), CURLE_OK); 158 &transfer_size_double), CURLE_OK);
155 off_t new_transfer_size = static_cast<off_t>(transfer_size_double); 159 off_t new_transfer_size = static_cast<off_t>(transfer_size_double);
156 if (new_transfer_size > 0) { 160 if (new_transfer_size > 0) {
157 transfer_size_ = resume_offset_ + new_transfer_size; 161 transfer_size_ = resume_offset_ + new_transfer_size;
158 } 162 }
159 } 163 }
160 bytes_downloaded_ += size * nmemb; 164 bytes_downloaded_ += size * nmemb;
165 in_write_callback_ = true;
161 if (delegate_) 166 if (delegate_)
162 delegate_->ReceivedBytes(this, reinterpret_cast<char*>(ptr), size * nmemb); 167 delegate_->ReceivedBytes(this, reinterpret_cast<char*>(ptr), size * nmemb);
168 in_write_callback_ = false;
163 return size * nmemb; 169 return size * nmemb;
164 } 170 }
165 171
166 void LibcurlHttpFetcher::Pause() { 172 void LibcurlHttpFetcher::Pause() {
167 CHECK(curl_handle_); 173 CHECK(curl_handle_);
168 CHECK(transfer_in_progress_); 174 CHECK(transfer_in_progress_);
169 CHECK_EQ(curl_easy_pause(curl_handle_, CURLPAUSE_ALL), CURLE_OK); 175 CHECK_EQ(curl_easy_pause(curl_handle_, CURLPAUSE_ALL), CURLE_OK);
170 } 176 }
171 177
172 void LibcurlHttpFetcher::Unpause() { 178 void LibcurlHttpFetcher::Unpause() {
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 curl_easy_cleanup(curl_handle_); 293 curl_easy_cleanup(curl_handle_);
288 curl_handle_ = NULL; 294 curl_handle_ = NULL;
289 } 295 }
290 if (curl_multi_handle_) { 296 if (curl_multi_handle_) {
291 CHECK_EQ(curl_multi_cleanup(curl_multi_handle_), CURLM_OK); 297 CHECK_EQ(curl_multi_cleanup(curl_multi_handle_), CURLM_OK);
292 curl_multi_handle_ = NULL; 298 curl_multi_handle_ = NULL;
293 } 299 }
294 transfer_in_progress_ = false; 300 transfer_in_progress_ = false;
295 } 301 }
296 302
303 void LibcurlHttpFetcher::GetHttpResponseCode() {
304 long http_response_code = 0;
305 if (curl_easy_getinfo(curl_handle_,
306 CURLINFO_RESPONSE_CODE,
307 &http_response_code) == CURLE_OK) {
308 http_response_code_ = static_cast<int>(http_response_code);
309 }
310 }
311
297 } // namespace chromeos_update_engine 312 } // namespace chromeos_update_engine
OLDNEW
« no previous file with comments | « libcurl_http_fetcher.h ('k') | mock_http_fetcher.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698