AU: Don't request data ranges beyond the end of the payload.

This avoids 416 HTTP response error codes from the server. Note that even
without this change update would eventually succeed due to more than 10 resume
failures (so the safety net actually worked).

BUG=8017
TEST=unit tests; tested on device by first reproducing the issue by
interrupting an update during the finalizing step and then getting 416,
then verified the patch resumes the update. Also, verified updates
interrupted in the middle of the download resume correctly.

Change-Id: Iede50a8f8a9d6c000cfeb03308e9ea4f3db74e1b

Review URL: http://codereview.chromium.org/3962005
diff --git a/update_attempter.cc b/update_attempter.cc
index 1e3bf5d..7c32475 100644
--- a/update_attempter.cc
+++ b/update_attempter.cc
@@ -535,12 +535,19 @@
           download_action_->http_fetcher());
   MultiHttpFetcher<LibcurlHttpFetcher>::RangesVect ranges;
   if (response_handler_action_->install_plan().is_resume) {
+    // Resuming an update so fetch the update manifest metadata first.
     int64_t manifest_metadata_size = 0;
     prefs_->GetInt64(kPrefsManifestMetadataSize, &manifest_metadata_size);
+    ranges.push_back(make_pair(0, manifest_metadata_size));
+    // If there're remaining unprocessed data blobs, fetch them. Be careful not
+    // to request data beyond the end of the payload to avoid 416 HTTP response
+    // error codes.
     int64_t next_data_offset = 0;
     prefs_->GetInt64(kPrefsUpdateStateNextDataOffset, &next_data_offset);
-    ranges.push_back(make_pair(0, manifest_metadata_size));
-    ranges.push_back(make_pair(manifest_metadata_size + next_data_offset, -1));
+    uint64_t resume_offset = manifest_metadata_size + next_data_offset;
+    if (resume_offset < response_handler_action_->install_plan().size) {
+      ranges.push_back(make_pair(resume_offset, -1));
+    }
   } else {
     ranges.push_back(make_pair(0, -1));
   }