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

Unified Diff: src/platform/update_engine/libcurl_http_fetcher.cc

Issue 466036: AU: Beginnings of delta support (Closed)
Patch Set: Created 11 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/platform/update_engine/libcurl_http_fetcher.h ('k') | src/platform/update_engine/main.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/platform/update_engine/libcurl_http_fetcher.cc
diff --git a/src/platform/update_engine/libcurl_http_fetcher.cc b/src/platform/update_engine/libcurl_http_fetcher.cc
index 624e6a9539db633e8b78307521c2bb04f1bd8318..9ed0c64b90341eaeb17777e24bc84293da5e4b56 100644
--- a/src/platform/update_engine/libcurl_http_fetcher.cc
+++ b/src/platform/update_engine/libcurl_http_fetcher.cc
@@ -2,8 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/logging.h"
#include "update_engine/libcurl_http_fetcher.h"
+#include <algorithm>
+#include "chromeos/obsolete_logging.h"
+
+using std::max;
+using std::make_pair;
// This is a concrete implementation of HttpFetcher that uses libcurl to do the
// http work.
@@ -14,8 +18,7 @@ LibcurlHttpFetcher::~LibcurlHttpFetcher() {
CleanUp();
}
-// Begins the transfer, which must not have already been started.
-void LibcurlHttpFetcher::BeginTransfer(const std::string& url) {
+void LibcurlHttpFetcher::ResumeTransfer(const std::string& url) {
CHECK(!transfer_in_progress_);
url_ = url;
curl_multi_handle_ = curl_multi_init();
@@ -25,22 +28,40 @@ void LibcurlHttpFetcher::BeginTransfer(const std::string& url) {
CHECK(curl_handle_);
if (post_data_set_) {
- CHECK_EQ(CURLE_OK, curl_easy_setopt(curl_handle_, CURLOPT_POST, 1));
- CHECK_EQ(CURLE_OK, curl_easy_setopt(curl_handle_, CURLOPT_POSTFIELDS,
- &post_data_[0]));
- CHECK_EQ(CURLE_OK, curl_easy_setopt(curl_handle_, CURLOPT_POSTFIELDSIZE,
- post_data_.size()));
+ CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_POST, 1), CURLE_OK);
+ CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_POSTFIELDS,
+ &post_data_[0]),
+ CURLE_OK);
+ CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_POSTFIELDSIZE,
+ post_data_.size()),
+ CURLE_OK);
}
- CHECK_EQ(CURLE_OK, curl_easy_setopt(curl_handle_, CURLOPT_WRITEDATA, this));
- CHECK_EQ(CURLE_OK, curl_easy_setopt(curl_handle_, CURLOPT_WRITEFUNCTION,
- StaticLibcurlWrite));
- CHECK_EQ(CURLE_OK, curl_easy_setopt(curl_handle_, CURLOPT_URL, url_.c_str()));
- CHECK_EQ(CURLM_OK, curl_multi_add_handle(curl_multi_handle_, curl_handle_));
+ if (bytes_downloaded_ > 0) {
+ // Resume from where we left off
+ resume_offset_ = bytes_downloaded_;
+ CHECK_EQ(curl_easy_setopt(curl_handle_,
+ CURLOPT_RESUME_FROM_LARGE,
+ bytes_downloaded_), CURLE_OK);
+ }
+
+ CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_WRITEDATA, this), CURLE_OK);
+ CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_WRITEFUNCTION,
+ StaticLibcurlWrite), CURLE_OK);
+ CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_URL, url_.c_str()), CURLE_OK);
+ CHECK_EQ(curl_multi_add_handle(curl_multi_handle_, curl_handle_), CURLM_OK);
transfer_in_progress_ = true;
CurlPerformOnce();
}
+// Begins the transfer, which must not have already been started.
+void LibcurlHttpFetcher::BeginTransfer(const std::string& url) {
+ transfer_size_ = -1;
+ bytes_downloaded_ = 0;
+ resume_offset_ = 0;
+ ResumeTransfer(url);
+}
+
void LibcurlHttpFetcher::TerminateTransfer() {
CleanUp();
}
@@ -59,8 +80,14 @@ void LibcurlHttpFetcher::CurlPerformOnce() {
if (0 == running_handles) {
// we're done!
CleanUp();
- if (delegate_)
- delegate_->TransferComplete(this, true); // success
+
+ if ((transfer_size_ >= 0) && (bytes_downloaded_ < transfer_size_)) {
+ ResumeTransfer(url_);
+ } else {
+ if (delegate_) {
+ delegate_->TransferComplete(this, true); // success
+ }
+ }
} else {
// set up callback
SetupMainloopSources();
@@ -68,6 +95,17 @@ void LibcurlHttpFetcher::CurlPerformOnce() {
}
size_t LibcurlHttpFetcher::LibcurlWrite(void *ptr, size_t size, size_t nmemb) {
+ {
+ double transfer_size_double;
+ CHECK_EQ(curl_easy_getinfo(curl_handle_,
+ CURLINFO_CONTENT_LENGTH_DOWNLOAD,
+ &transfer_size_double), CURLE_OK);
+ off_t new_transfer_size = static_cast<off_t>(transfer_size_double);
+ if (new_transfer_size > 0) {
+ transfer_size_ = resume_offset_ + new_transfer_size;
+ }
+ }
+ bytes_downloaded_ += size * nmemb;
if (delegate_)
delegate_->ReceivedBytes(this, reinterpret_cast<char*>(ptr), size * nmemb);
return size * nmemb;
@@ -76,13 +114,13 @@ size_t LibcurlHttpFetcher::LibcurlWrite(void *ptr, size_t size, size_t nmemb) {
void LibcurlHttpFetcher::Pause() {
CHECK(curl_handle_);
CHECK(transfer_in_progress_);
- CHECK_EQ(CURLE_OK, curl_easy_pause(curl_handle_, CURLPAUSE_ALL));
+ CHECK_EQ(curl_easy_pause(curl_handle_, CURLPAUSE_ALL), CURLE_OK);
}
void LibcurlHttpFetcher::Unpause() {
CHECK(curl_handle_);
CHECK(transfer_in_progress_);
- CHECK_EQ(CURLE_OK, curl_easy_pause(curl_handle_, CURLPAUSE_CONT));
+ CHECK_EQ(curl_easy_pause(curl_handle_, CURLPAUSE_CONT), CURLE_OK);
}
// This method sets up callbacks with the glib main loop.
@@ -99,8 +137,8 @@ void LibcurlHttpFetcher::SetupMainloopSources() {
// Ask libcurl for the set of file descriptors we should track on its
// behalf.
- CHECK_EQ(CURLM_OK, curl_multi_fdset(curl_multi_handle_, &fd_read, &fd_write,
- &fd_exec, &fd_max));
+ CHECK_EQ(curl_multi_fdset(curl_multi_handle_, &fd_read, &fd_write,
+ &fd_exec, &fd_max), CURLM_OK);
// We should iterate through all file descriptors up to libcurl's fd_max or
// the highest one we're tracking, whichever is larger
@@ -113,7 +151,7 @@ void LibcurlHttpFetcher::SetupMainloopSources() {
// in io_channels_ as there are fds that we're tracking.
for (int i = 0; i <= fd_max; i++) {
if (!(FD_ISSET(i, &fd_read) || FD_ISSET(i, &fd_write) ||
- FD_ISSET(i, &fd_exec))) {
+ FD_ISSET(i, &fd_exec))) {
// if we have an outstanding io_channel, remove it
if (io_channels_.find(i) != io_channels_.end()) {
g_source_remove(io_channels_[i].second);
@@ -139,7 +177,7 @@ void LibcurlHttpFetcher::SetupMainloopSources() {
// Wet up a timeout callback for libcurl
long ms = 0;
- CHECK_EQ(CURLM_OK, curl_multi_timeout(curl_multi_handle_, &ms));
+ CHECK_EQ(curl_multi_timeout(curl_multi_handle_, &ms), CURLM_OK);
if (ms < 0) {
// From http://curl.haxx.se/libcurl/c/curl_multi_timeout.html:
// if libcurl returns a -1 timeout here, it just means that libcurl
@@ -210,14 +248,14 @@ void LibcurlHttpFetcher::CleanUp() {
if (curl_handle_) {
if (curl_multi_handle_) {
- CHECK_EQ(CURLM_OK,
- curl_multi_remove_handle(curl_multi_handle_, curl_handle_));
+ CHECK_EQ(curl_multi_remove_handle(curl_multi_handle_, curl_handle_),
+ CURLM_OK);
}
curl_easy_cleanup(curl_handle_);
curl_handle_ = NULL;
}
if (curl_multi_handle_) {
- CHECK_EQ(CURLM_OK, curl_multi_cleanup(curl_multi_handle_));
+ CHECK_EQ(curl_multi_cleanup(curl_multi_handle_), CURLM_OK);
curl_multi_handle_ = NULL;
}
transfer_in_progress_ = false;
« no previous file with comments | « src/platform/update_engine/libcurl_http_fetcher.h ('k') | src/platform/update_engine/main.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698