summaryrefslogtreecommitdiff
path: root/http-fetch.c
diff options
context:
space:
mode:
authorDaniel Barkalow <barkalow@iabervon.org>2005-09-18 18:14:19 (GMT)
committerJunio C Hamano <junkio@cox.net>2005-09-18 21:14:52 (GMT)
commit1b0c1e672a417c3f4a46b36497168d6d61dba0cb (patch)
treee67588db879c7131ab8984b971eeeee22ca1e031 /http-fetch.c
parent3a45f625aef0074a41885f1df335844ec8c04f5e (diff)
downloadgit-1b0c1e672a417c3f4a46b36497168d6d61dba0cb.zip
git-1b0c1e672a417c3f4a46b36497168d6d61dba0cb.tar.gz
git-1b0c1e672a417c3f4a46b36497168d6d61dba0cb.tar.bz2
[PATCH] Support alternates and http-alternates in http-fetch
This allows the remote repository to refer to additional repositories in a file objects/info/http-alternates or objects/info/alternates. Each line may be: a relative path, starting with ../, to get from the objects directory of the starting repository to the objects directory of the added repository. an absolute path of the objects directory of the added repository (on the same server). (only in http-alternates) a full URL of the objects directory of the added repository. Signed-off-by: Daniel Barkalow <barkalow@iabervon.org> Signed-off-by: Junio C Hamano <junkio@cox.net>
Diffstat (limited to 'http-fetch.c')
-rw-r--r--http-fetch.c45
1 files changed, 38 insertions, 7 deletions
diff --git a/http-fetch.c b/http-fetch.c
index 17051fe..77f530c 100644
--- a/http-fetch.c
+++ b/http-fetch.c
@@ -144,10 +144,11 @@ static int fetch_alternates(char *base)
char *url;
char *data;
int i = 0;
+ int http_specific = 1;
if (got_alternates)
return 0;
data = xmalloc(4096);
- buffer.size = 4096;
+ buffer.size = 4095;
buffer.posn = 0;
buffer.buffer = data;
@@ -162,6 +163,8 @@ static int fetch_alternates(char *base)
curl_easy_setopt(curl, CURLOPT_URL, url);
if (curl_easy_perform(curl) || !buffer.posn) {
+ http_specific = 0;
+
sprintf(url, "%s/objects/info/alternates", base);
curl_easy_setopt(curl, CURLOPT_FILE, &buffer);
@@ -173,17 +176,45 @@ static int fetch_alternates(char *base)
}
}
+ data[buffer.posn] = '\0';
+
while (i < buffer.posn) {
int posn = i;
while (posn < buffer.posn && data[posn] != '\n')
posn++;
if (data[posn] == '\n') {
+ int okay = 0;
+ int serverlen = 0;
+ struct alt_base *newalt;
+ char *target = NULL;
if (data[i] == '/') {
- int serverlen = strchr(base + 8, '/') - base;
- // skip 'objects' at end
- char *target =
- xmalloc(serverlen + posn - i - 6);
- struct alt_base *newalt;
+ serverlen = strchr(base + 8, '/') - base;
+ okay = 1;
+ } else if (!memcmp(data + i, "../", 3)) {
+ i += 3;
+ serverlen = strlen(base);
+ while (i + 2 < posn &&
+ !memcmp(data + i, "../", 3)) {
+ do {
+ serverlen--;
+ } while (serverlen &&
+ base[serverlen - 1] != '/');
+ i += 3;
+ }
+ // If the server got removed, give up.
+ okay = strchr(base, ':') - base + 3 <
+ serverlen;
+ } else if (http_specific) {
+ char *colon = strchr(data + i, ':');
+ char *slash = strchr(data + i, '/');
+ if (colon && slash && colon < data + posn &&
+ slash < data + posn && colon < slash) {
+ okay = 1;
+ }
+ }
+ // skip 'objects' at end
+ if (okay) {
+ target = xmalloc(serverlen + posn - i - 6);
strncpy(target, base, serverlen);
strncpy(target + serverlen, data + i,
posn - i - 7);
@@ -235,7 +266,7 @@ static int fetch_indices(struct alt_base *repo)
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, NULL);
if (curl_easy_perform(curl)) {
- return error("Unable to get pack index %s", url);
+ return -1;
}
while (i < buffer.posn) {