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/libcurl_http_fetcher.h b/libcurl_http_fetcher.h
index d9d1697..ff8589b 100644
--- a/libcurl_http_fetcher.h
+++ b/libcurl_http_fetcher.h
@@ -33,6 +33,7 @@
         transfer_in_progress_(false),
         transfer_size_(0),
         bytes_downloaded_(0),
+        download_length_(0),
         resume_offset_(0),
         retry_count_(0),
         retry_seconds_(60),
@@ -51,7 +52,10 @@
   // Cleans up all internal state. Does not notify delegate
   ~LibcurlHttpFetcher();
 
-  void SetOffset(off_t offset) { bytes_downloaded_ = offset; }
+  virtual void SetOffset(off_t offset) { bytes_downloaded_ = offset; }
+
+  virtual void SetLength(size_t length) { download_length_ = length; }
+  virtual void UnsetLength() { SetLength(0); }
 
   // Begins the transfer if it hasn't already begun.
   virtual void BeginTransfer(const std::string& url);
@@ -207,6 +211,10 @@
   // How many bytes have been downloaded and sent to the delegate.
   off_t bytes_downloaded_;
 
+  // The remaining maximum number of bytes to download. Zero represents an
+  // unspecified length.
+  size_t download_length_;
+
   // If we resumed an earlier transfer, data offset that we used for the
   // new connection.  0 otherwise.
   // In this class, resume refers to resuming a dropped HTTP connection,