AU: MultiHttpFetcher, an HttpFetcher for specific byte ranges
MultiHttpFetcher takes an HttpFetcher class via template parameter,
and a collection of byte ranges. It hits up the URL multiple times,
once per range specified. For each time, it uses a new HttpFetcher of
the type specified and fast-forwards to the offset requested, and
aborting after enough bytes have been downloaded. Any range many
specify a length of -1, which means until the end of the file (as
dictated by the server). Thus, a single range of [0, -1] makes
MultiHttpFetcher a pass-through.
HttpFetcher change: ability to supply an offset.
LibcurlHttpFetcher changes: offset support (from HttpFetcher API),
ability to be terminted in a write-callback.
test_http_fetcher: support for failures in write() on the socket (at
least in the /big url case).
BUG=7391
TEST=unittests
Review URL: http://codereview.chromium.org/3591018
diff --git a/libcurl_http_fetcher.h b/libcurl_http_fetcher.h
index 8908638..69e794f 100644
--- a/libcurl_http_fetcher.h
+++ b/libcurl_http_fetcher.h
@@ -27,13 +27,20 @@
curl_handle_(NULL),
timeout_source_(NULL),
transfer_in_progress_(false),
+ transfer_size_(0),
+ bytes_downloaded_(0),
+ resume_offset_(0),
retry_count_(0),
retry_seconds_(60),
- idle_seconds_(1) {}
+ idle_seconds_(1),
+ in_write_callback_(false),
+ terminate_requested_(false) {}
// Cleans up all internal state. Does not notify delegate
~LibcurlHttpFetcher();
+ void SetOffset(off_t offset) { bytes_downloaded_ = offset; }
+
// Begins the transfer if it hasn't already begun.
virtual void BeginTransfer(const std::string& url);
@@ -62,6 +69,9 @@
void set_retry_seconds(int seconds) { retry_seconds_ = seconds; }
private:
+ // Asks libcurl for the http response code and stores it in the object.
+ void GetHttpResponseCode();
+
// Resumes a transfer where it left off. This will use the
// HTTP Range: header to make a new connection from where the last
// left off.
@@ -135,6 +145,8 @@
// 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,
+ // not to resuming an interrupted download.
off_t resume_offset_;
// Number of resumes performed.
@@ -146,6 +158,13 @@
// Seconds to wait before asking libcurl to "perform".
int idle_seconds_;
+ // If true, we are currently performing a write callback on the delegate.
+ bool in_write_callback_;
+
+ // We can't clean everything up while we're in a write callback, so
+ // if we get a terminate request, queue it until we can handle it.
+ bool terminate_requested_;
+
DISALLOW_COPY_AND_ASSIGN(LibcurlHttpFetcher);
};