summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2015-11-05 15:24:27 -0800
committerJunio C Hamano <gitster@pobox.com>2015-11-05 15:24:27 -0800
commit848cdba579f81eda41267ee7e4333ab9db8a594a (patch)
tree5f8aae23e6cc971184b525b291752c39cb95d413
parent2c78628255b8cc7f0b5d47981acea138db8716d2 (diff)
parentf8117f550b900b0bc93364ecadbed237b0ffe25e (diff)
downloadgit-848cdba579f81eda41267ee7e4333ab9db8a594a.tar.gz
Merge branch 'dt/http-range'
A Range: request can be responded with a full response and when asked properly libcurl knows how to strip the result down to the requested range. However, we were hand-crafting a range request and it did not kick in. * dt/http-range: http: use off_t to store partial file size http.c: use CURLOPT_RANGE for range requests
-rw-r--r--http.c41
-rw-r--r--http.h1
2 files changed, 16 insertions, 26 deletions
diff --git a/http.c b/http.c
index 7da76edda1..42f29ce0aa 100644
--- a/http.c
+++ b/http.c
@@ -30,7 +30,6 @@ static CURL *curl_default;
#endif
#define PREV_BUF_SIZE 4096
-#define RANGE_HEADER_SIZE 30
char curl_errorstr[CURL_ERROR_SIZE];
@@ -681,6 +680,7 @@ struct active_request_slot *get_active_slot(void)
curl_easy_setopt(slot->curl, CURLOPT_UPLOAD, 0);
curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1);
curl_easy_setopt(slot->curl, CURLOPT_FAILONERROR, 1);
+ curl_easy_setopt(slot->curl, CURLOPT_RANGE, NULL);
#ifdef LIBCURL_CAN_HANDLE_AUTH_ANY
curl_easy_setopt(slot->curl, CURLOPT_HTTPAUTH, http_auth_methods);
#endif
@@ -1173,6 +1173,13 @@ static const char *get_accept_language(void)
return cached_accept_language;
}
+static void http_opt_request_remainder(CURL *curl, off_t pos)
+{
+ char buf[128];
+ xsnprintf(buf, sizeof(buf), "%"PRIuMAX"-", (uintmax_t)pos);
+ curl_easy_setopt(curl, CURLOPT_RANGE, buf);
+}
+
/* http_request() targets */
#define HTTP_REQUEST_STRBUF 0
#define HTTP_REQUEST_FILE 1
@@ -1198,14 +1205,11 @@ static int http_request(const char *url,
curl_easy_setopt(slot->curl, CURLOPT_FILE, result);
if (target == HTTP_REQUEST_FILE) {
- long posn = ftell(result);
+ off_t posn = ftello(result);
curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION,
fwrite);
- if (posn > 0) {
- strbuf_addf(&buf, "Range: bytes=%ld-", posn);
- headers = curl_slist_append(headers, buf.buf);
- strbuf_reset(&buf);
- }
+ if (posn > 0)
+ http_opt_request_remainder(slot->curl, posn);
} else
curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION,
fwrite_buffer);
@@ -1515,10 +1519,6 @@ void release_http_pack_request(struct http_pack_request *preq)
fclose(preq->packfile);
preq->packfile = NULL;
}
- if (preq->range_header != NULL) {
- curl_slist_free_all(preq->range_header);
- preq->range_header = NULL;
- }
preq->slot = NULL;
free(preq->url);
free(preq);
@@ -1581,8 +1581,7 @@ int finish_http_pack_request(struct http_pack_request *preq)
struct http_pack_request *new_http_pack_request(
struct packed_git *target, const char *base_url)
{
- long prev_posn = 0;
- char range[RANGE_HEADER_SIZE];
+ off_t prev_posn = 0;
struct strbuf buf = STRBUF_INIT;
struct http_pack_request *preq;
@@ -1614,16 +1613,13 @@ struct http_pack_request *new_http_pack_request(
* If there is data present from a previous transfer attempt,
* resume where it left off
*/
- prev_posn = ftell(preq->packfile);
+ prev_posn = ftello(preq->packfile);
if (prev_posn>0) {
if (http_is_verbose)
fprintf(stderr,
"Resuming fetch of pack %s at byte %ld\n",
sha1_to_hex(target->sha1), prev_posn);
- xsnprintf(range, sizeof(range), "Range: bytes=%ld-", prev_posn);
- preq->range_header = curl_slist_append(NULL, range);
- curl_easy_setopt(preq->slot->curl, CURLOPT_HTTPHEADER,
- preq->range_header);
+ http_opt_request_remainder(preq->slot->curl, prev_posn);
}
return preq;
@@ -1672,9 +1668,7 @@ struct http_object_request *new_http_object_request(const char *base_url,
int prevlocal;
char prev_buf[PREV_BUF_SIZE];
ssize_t prev_read = 0;
- long prev_posn = 0;
- char range[RANGE_HEADER_SIZE];
- struct curl_slist *range_header = NULL;
+ off_t prev_posn = 0;
struct http_object_request *freq;
freq = xcalloc(1, sizeof(*freq));
@@ -1780,10 +1774,7 @@ struct http_object_request *new_http_object_request(const char *base_url,
fprintf(stderr,
"Resuming fetch of object %s at byte %ld\n",
hex, prev_posn);
- xsnprintf(range, sizeof(range), "Range: bytes=%ld-", prev_posn);
- range_header = curl_slist_append(range_header, range);
- curl_easy_setopt(freq->slot->curl,
- CURLOPT_HTTPHEADER, range_header);
+ http_opt_request_remainder(freq->slot->curl, prev_posn);
}
return freq;
diff --git a/http.h b/http.h
index 49afe39279..4f97b60b5c 100644
--- a/http.h
+++ b/http.h
@@ -190,7 +190,6 @@ struct http_pack_request {
struct packed_git **lst;
FILE *packfile;
char tmpfile[PATH_MAX];
- struct curl_slist *range_header;
struct active_request_slot *slot;
};