Skip to content

Commit 848cdba

Browse files
committed
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
2 parents 2c78628 + f8117f5 commit 848cdba

File tree

2 files changed

+16
-26
lines changed

2 files changed

+16
-26
lines changed

http.c

Lines changed: 16 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ static CURL *curl_default;
3030
#endif
3131

3232
#define PREV_BUF_SIZE 4096
33-
#define RANGE_HEADER_SIZE 30
3433

3534
char curl_errorstr[CURL_ERROR_SIZE];
3635

@@ -681,6 +680,7 @@ struct active_request_slot *get_active_slot(void)
681680
curl_easy_setopt(slot->curl, CURLOPT_UPLOAD, 0);
682681
curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1);
683682
curl_easy_setopt(slot->curl, CURLOPT_FAILONERROR, 1);
683+
curl_easy_setopt(slot->curl, CURLOPT_RANGE, NULL);
684684
#ifdef LIBCURL_CAN_HANDLE_AUTH_ANY
685685
curl_easy_setopt(slot->curl, CURLOPT_HTTPAUTH, http_auth_methods);
686686
#endif
@@ -1173,6 +1173,13 @@ static const char *get_accept_language(void)
11731173
return cached_accept_language;
11741174
}
11751175

1176+
static void http_opt_request_remainder(CURL *curl, off_t pos)
1177+
{
1178+
char buf[128];
1179+
xsnprintf(buf, sizeof(buf), "%"PRIuMAX"-", (uintmax_t)pos);
1180+
curl_easy_setopt(curl, CURLOPT_RANGE, buf);
1181+
}
1182+
11761183
/* http_request() targets */
11771184
#define HTTP_REQUEST_STRBUF 0
11781185
#define HTTP_REQUEST_FILE 1
@@ -1198,14 +1205,11 @@ static int http_request(const char *url,
11981205
curl_easy_setopt(slot->curl, CURLOPT_FILE, result);
11991206

12001207
if (target == HTTP_REQUEST_FILE) {
1201-
long posn = ftell(result);
1208+
off_t posn = ftello(result);
12021209
curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION,
12031210
fwrite);
1204-
if (posn > 0) {
1205-
strbuf_addf(&buf, "Range: bytes=%ld-", posn);
1206-
headers = curl_slist_append(headers, buf.buf);
1207-
strbuf_reset(&buf);
1208-
}
1211+
if (posn > 0)
1212+
http_opt_request_remainder(slot->curl, posn);
12091213
} else
12101214
curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION,
12111215
fwrite_buffer);
@@ -1515,10 +1519,6 @@ void release_http_pack_request(struct http_pack_request *preq)
15151519
fclose(preq->packfile);
15161520
preq->packfile = NULL;
15171521
}
1518-
if (preq->range_header != NULL) {
1519-
curl_slist_free_all(preq->range_header);
1520-
preq->range_header = NULL;
1521-
}
15221522
preq->slot = NULL;
15231523
free(preq->url);
15241524
free(preq);
@@ -1581,8 +1581,7 @@ int finish_http_pack_request(struct http_pack_request *preq)
15811581
struct http_pack_request *new_http_pack_request(
15821582
struct packed_git *target, const char *base_url)
15831583
{
1584-
long prev_posn = 0;
1585-
char range[RANGE_HEADER_SIZE];
1584+
off_t prev_posn = 0;
15861585
struct strbuf buf = STRBUF_INIT;
15871586
struct http_pack_request *preq;
15881587

@@ -1614,16 +1613,13 @@ struct http_pack_request *new_http_pack_request(
16141613
* If there is data present from a previous transfer attempt,
16151614
* resume where it left off
16161615
*/
1617-
prev_posn = ftell(preq->packfile);
1616+
prev_posn = ftello(preq->packfile);
16181617
if (prev_posn>0) {
16191618
if (http_is_verbose)
16201619
fprintf(stderr,
16211620
"Resuming fetch of pack %s at byte %ld\n",
16221621
sha1_to_hex(target->sha1), prev_posn);
1623-
xsnprintf(range, sizeof(range), "Range: bytes=%ld-", prev_posn);
1624-
preq->range_header = curl_slist_append(NULL, range);
1625-
curl_easy_setopt(preq->slot->curl, CURLOPT_HTTPHEADER,
1626-
preq->range_header);
1622+
http_opt_request_remainder(preq->slot->curl, prev_posn);
16271623
}
16281624

16291625
return preq;
@@ -1672,9 +1668,7 @@ struct http_object_request *new_http_object_request(const char *base_url,
16721668
int prevlocal;
16731669
char prev_buf[PREV_BUF_SIZE];
16741670
ssize_t prev_read = 0;
1675-
long prev_posn = 0;
1676-
char range[RANGE_HEADER_SIZE];
1677-
struct curl_slist *range_header = NULL;
1671+
off_t prev_posn = 0;
16781672
struct http_object_request *freq;
16791673

16801674
freq = xcalloc(1, sizeof(*freq));
@@ -1780,10 +1774,7 @@ struct http_object_request *new_http_object_request(const char *base_url,
17801774
fprintf(stderr,
17811775
"Resuming fetch of object %s at byte %ld\n",
17821776
hex, prev_posn);
1783-
xsnprintf(range, sizeof(range), "Range: bytes=%ld-", prev_posn);
1784-
range_header = curl_slist_append(range_header, range);
1785-
curl_easy_setopt(freq->slot->curl,
1786-
CURLOPT_HTTPHEADER, range_header);
1777+
http_opt_request_remainder(freq->slot->curl, prev_posn);
17871778
}
17881779

17891780
return freq;

http.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,6 @@ struct http_pack_request {
190190
struct packed_git **lst;
191191
FILE *packfile;
192192
char tmpfile[PATH_MAX];
193-
struct curl_slist *range_header;
194193
struct active_request_slot *slot;
195194
};
196195

0 commit comments

Comments
 (0)