From: David Turner <dturner@twopensource.com>
To: git@vger.kernel.org
Cc: David Turner <dturner@twopensource.com>
Subject: [PATCH v2] http.c: use CURLOPT_RANGE for range requests
Date: Fri, 30 Oct 2015 18:54:42 -0400 [thread overview]
Message-ID: <1446245682-18087-1-git-send-email-dturner@twopensource.com> (raw)
A HTTP server is permitted to return a non-range response to a HTTP
range request (and Apache httpd in fact does this in some cases).
While libcurl knows how to correctly handle this (by skipping bytes
before and after the requested range), it only turns on this handling
if it is aware that a range request is being made. By manually
setting the range header instead of using CURLOPT_RANGE, we were
hiding the fact that this was a range request from libcurl. This
could cause corruption.
Signed-off-by: David Turner <dturner@twopensource.com>
---
This version applies on top of pu. It also catches all of the range
requests instead of just the one that I happened to notice.
---
http.c | 24 ++++++++----------------
http.h | 1 -
2 files changed, 8 insertions(+), 17 deletions(-)
diff --git a/http.c b/http.c
index 6b89dea..16610b9 100644
--- a/http.c
+++ b/http.c
@@ -30,7 +30,7 @@ static CURL *curl_default;
#endif
#define PREV_BUF_SIZE 4096
-#define RANGE_HEADER_SIZE 30
+#define RANGE_HEADER_SIZE 17
char curl_errorstr[CURL_ERROR_SIZE];
@@ -1213,8 +1213,9 @@ static int http_request(const char *url,
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_addf(&buf, "%ld-", posn);
+ curl_easy_setopt(slot->curl, CURLOPT_RANGE,
+ &buf.buf);
strbuf_reset(&buf);
}
} else
@@ -1526,10 +1527,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);
@@ -1631,10 +1628,8 @@ struct http_pack_request *new_http_pack_request(
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);
+ xsnprintf(range, sizeof(range), "%ld-", prev_posn);
+ curl_easy_setopt(preq->slot->curl, CURLOPT_RANGE, range);
}
return preq;
@@ -1685,7 +1680,6 @@ struct http_object_request *new_http_object_request(const char *base_url,
ssize_t prev_read = 0;
long prev_posn = 0;
char range[RANGE_HEADER_SIZE];
- struct curl_slist *range_header = NULL;
struct http_object_request *freq;
freq = xcalloc(1, sizeof(*freq));
@@ -1791,10 +1785,8 @@ 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);
+ xsnprintf(range, sizeof(range), "%ld-", prev_posn);
+ curl_easy_setopt(freq->slot->curl, CURLOPT_RANGE, range);
}
return freq;
diff --git a/http.h b/http.h
index 49afe39..4f97b60 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;
};
--
2.4.2.691.g714732c-twtrsrc
next reply other threads:[~2015-10-30 22:55 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-10-30 22:54 David Turner [this message]
2015-10-30 23:13 ` [PATCH v2] http.c: use CURLOPT_RANGE for range requests Junio C Hamano
2015-10-31 0:08 ` Jeff King
2015-10-31 17:40 ` Junio C Hamano
2015-10-31 17:43 ` Jeff King
2015-11-01 23:00 ` Daniel Stenberg
2015-11-02 1:51 ` Jeff King
2015-11-02 7:05 ` Daniel Stenberg
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1446245682-18087-1-git-send-email-dturner@twopensource.com \
--to=dturner@twopensource.com \
--cc=git@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).