AU multi-range fetcher requests properly closed ranges when their length
is known.
* HttpFetcher allows to set the length of data to be fetched.
LibcurlHttpFetcher uses this value in applying the appropriate libcurl
option (CURLOPT_RANGE). MultiHttpFetcher sets the desired payload
length in the underlying fetcher accordingly.
* Improved functionality of test_http_server: (a) correctly parses
closed range intervals; (b) generalized response header generation;
(c) unified and generalized get handling for both stable and flaky
cases.
* Small scale refactoring, improved logging and readability.
BUG=chromium-os:24666
TEST=unit tests
Change-Id: I1727710ca747088c67a68305f355da683b07b6a3
Reviewed-on: https://gerrit.chromium.org/gerrit/13594
Reviewed-by: Gilad Arnold <garnold@chromium.org>
Tested-by: Gilad Arnold <garnold@chromium.org>
Commit-Ready: Gilad Arnold <garnold@chromium.org>
diff --git a/multi_range_http_fetcher.cc b/multi_range_http_fetcher.cc
index 40ef1e8..f19b9c3 100644
--- a/multi_range_http_fetcher.cc
+++ b/multi_range_http_fetcher.cc
@@ -2,8 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "update_engine/multi_range_http_fetcher.h"
+#include <base/stringprintf.h>
+#include "update_engine/multi_range_http_fetcher.h"
#include "update_engine/utils.h"
namespace chromeos_update_engine {
@@ -51,12 +52,18 @@
if (current_index_ >= ranges_.size()) {
return;
}
- LOG(INFO) << "Starting a transfer @" << ranges_[current_index_].first << "("
- << ranges_[current_index_].second << ")";
+
+ Range range = ranges_[current_index_];
+ LOG(INFO) << "starting transfer of range " << range.ToString();
+
bytes_received_this_range_ = 0;
- base_fetcher_->SetOffset(ranges_[current_index_].first);
+ base_fetcher_->SetOffset(range.offset());
+ if (range.HasLength())
+ base_fetcher_->SetLength(range.length());
+ else
+ base_fetcher_->UnsetLength();
if (delegate_)
- delegate_->SeekToOffset(ranges_[current_index_].first);
+ delegate_->SeekToOffset(range.offset());
base_fetcher_active_ = true;
base_fetcher_->BeginTransfer(url_);
}
@@ -68,19 +75,18 @@
CHECK_LT(current_index_, ranges_.size());
CHECK_EQ(fetcher, base_fetcher_.get());
CHECK(!pending_transfer_ended_);
- off_t next_size = length;
- if (ranges_[current_index_].second >= 0) {
+ size_t next_size = length;
+ Range range = ranges_[current_index_];
+ if (range.HasLength()) {
next_size = std::min(next_size,
- ranges_[current_index_].second -
- bytes_received_this_range_);
+ range.length() - bytes_received_this_range_);
}
LOG_IF(WARNING, next_size <= 0) << "Asked to write length <= 0";
if (delegate_) {
delegate_->ReceivedBytes(this, bytes, next_size);
}
bytes_received_this_range_ += length;
- if (ranges_[current_index_].second >= 0 &&
- bytes_received_this_range_ >= ranges_[current_index_].second) {
+ if (range.HasLength() && bytes_received_this_range_ >= range.length()) {
// Terminates the current fetcher. Waits for its TransferTerminated
// callback before starting the next range so that we don't end up
// signalling the delegate that the whole multi-transfer is complete
@@ -109,8 +115,9 @@
}
// If we didn't get enough bytes, it's failure
- if (ranges_[current_index_].second >= 0) {
- if (bytes_received_this_range_ < ranges_[current_index_].second) {
+ Range range = ranges_[current_index_];
+ if (range.HasLength()) {
+ if (bytes_received_this_range_ < range.length()) {
// Failure
LOG(INFO) << "Didn't get enough bytes. Ending w/ failure.";
Reset();
@@ -155,4 +162,13 @@
bytes_received_this_range_ = 0;
}
+std::string MultiRangeHttpFetcher::Range::ToString() const {
+ std::string range_str = StringPrintf("%jd+", offset());
+ if (HasLength())
+ base::StringAppendF(&range_str, "%zu", length());
+ else
+ base::StringAppendF(&range_str, "?");
+ return range_str;
+}
+
} // namespace chromeos_update_engine