diff options
author | Junio C Hamano <gitster@pobox.com> | 2015-11-05 15:24:27 -0800 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2015-11-05 15:24:27 -0800 |
commit | 848cdba579f81eda41267ee7e4333ab9db8a594a (patch) | |
tree | 5f8aae23e6cc971184b525b291752c39cb95d413 | |
parent | 2c78628255b8cc7f0b5d47981acea138db8716d2 (diff) | |
parent | f8117f550b900b0bc93364ecadbed237b0ffe25e (diff) | |
download | git-848cdba579f81eda41267ee7e4333ab9db8a594a.tar.gz git-848cdba579f81eda41267ee7e4333ab9db8a594a.tar.xz |
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.c | 41 | ||||
-rw-r--r-- | http.h | 1 |
2 files changed, 16 insertions, 26 deletions
@@ -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; @@ -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; }; |