Skip to content

Commit

Permalink
http*: add http_get_info_packs
Browse files Browse the repository at this point in the history
http-push.c and http-walker.c no longer have to use fetch_index or
setup_index; they simply need to use http_get_info_packs, a new http
method, in their fetch_indices implementations.

Move fetch_index() and rename to fetch_pack_index() in http.c; this
method is not meant to be used outside of http.c. It invokes
end_url_with_slash with base_url; apart from that change, the code is
identical.

Move setup_index() and rename to fetch_and_setup_pack_index() in
http.c; this method is not meant to be used outside of http.c.

Do not immediately set ret to 0 in http-walker.c::fetch_indices();
instead do it in the HTTP_MISSING_TARGET case, to make it clear that
the HTTP_OK and HTTP_MISSING_TARGET cases both return 0.

Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
rctay authored and gitster committed Jun 6, 2009
1 parent 9af5abd commit b8caac2
Show file tree
Hide file tree
Showing 4 changed files with 186 additions and 345 deletions.
179 changes: 9 additions & 170 deletions http-push.c
Expand Up @@ -953,184 +953,23 @@ static int add_send_request(struct object *obj, struct remote_lock *lock)
return 1;
}

static int fetch_index(unsigned char *sha1)
{
int ret = 0;
char *hex = xstrdup(sha1_to_hex(sha1));
char *filename;
char *url;
char tmpfile[PATH_MAX];
long prev_posn = 0;
char range[RANGE_HEADER_SIZE];
struct curl_slist *range_header = NULL;

FILE *indexfile;
struct active_request_slot *slot;
struct slot_results results;

/* Don't use the index if the pack isn't there */
url = xmalloc(strlen(repo->url) + 64);
sprintf(url, "%sobjects/pack/pack-%s.pack", repo->url, hex);
slot = get_active_slot();
slot->results = &results;
curl_easy_setopt(slot->curl, CURLOPT_URL, url);
curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 1);
if (start_active_slot(slot)) {
run_active_slot(slot);
if (results.curl_result != CURLE_OK) {
ret = error("Unable to verify pack %s is available",
hex);
goto cleanup_pack;
}
} else {
ret = error("Unable to start request");
goto cleanup_pack;
}

if (has_pack_index(sha1)) {
ret = 0;
goto cleanup_pack;
}

if (push_verbosely)
fprintf(stderr, "Getting index for pack %s\n", hex);

sprintf(url, "%sobjects/pack/pack-%s.idx", repo->url, hex);

filename = sha1_pack_index_name(sha1);
snprintf(tmpfile, sizeof(tmpfile), "%s.temp", filename);
indexfile = fopen(tmpfile, "a");
if (!indexfile) {
ret = error("Unable to open local file %s for pack index",
tmpfile);
goto cleanup_pack;
}

slot = get_active_slot();
slot->results = &results;
curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 0);
curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1);
curl_easy_setopt(slot->curl, CURLOPT_FILE, indexfile);
curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite);
curl_easy_setopt(slot->curl, CURLOPT_URL, url);
curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, no_pragma_header);
slot->local = indexfile;

/*
* If there is data present from a previous transfer attempt,
* resume where it left off
*/
prev_posn = ftell(indexfile);
if (prev_posn>0) {
if (push_verbosely)
fprintf(stderr,
"Resuming fetch of index for pack %s at byte %ld\n",
hex, prev_posn);
sprintf(range, "Range: bytes=%ld-", prev_posn);
range_header = curl_slist_append(range_header, range);
curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, range_header);
}

if (start_active_slot(slot)) {
run_active_slot(slot);
if (results.curl_result != CURLE_OK) {
ret = error("Unable to get pack index %s\n%s", url,
curl_errorstr);
goto cleanup_index;
}
} else {
ret = error("Unable to start request");
goto cleanup_index;
}

ret = move_temp_to_file(tmpfile, filename);

cleanup_index:
fclose(indexfile);
slot->local = NULL;
cleanup_pack:
free(url);
free(hex);
return ret;
}

static int setup_index(unsigned char *sha1)
{
struct packed_git *new_pack;

if (fetch_index(sha1))
return -1;

new_pack = parse_pack_index(sha1);
if (!new_pack)
return -1; /* parse_pack_index() already issued error message */
new_pack->next = repo->packs;
repo->packs = new_pack;
return 0;
}

static int fetch_indices(void)
{
unsigned char sha1[20];
char *url;
struct strbuf buffer = STRBUF_INIT;
char *data;
int i = 0;

struct active_request_slot *slot;
struct slot_results results;
int ret;

if (push_verbosely)
fprintf(stderr, "Getting pack list\n");

url = xmalloc(strlen(repo->url) + 20);
sprintf(url, "%sobjects/info/packs", repo->url);

slot = get_active_slot();
slot->results = &results;
curl_easy_setopt(slot->curl, CURLOPT_FILE, &buffer);
curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer);
curl_easy_setopt(slot->curl, CURLOPT_URL, url);
curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, NULL);
if (start_active_slot(slot)) {
run_active_slot(slot);
if (results.curl_result != CURLE_OK) {
strbuf_release(&buffer);
free(url);
if (results.http_code == 404)
return 0;
else
return error("%s", curl_errorstr);
}
} else {
strbuf_release(&buffer);
free(url);
return error("Unable to start request");
}
free(url);

data = buffer.buf;
while (i < buffer.len) {
switch (data[i]) {
case 'P':
i++;
if (i + 52 < buffer.len &&
!prefixcmp(data + i, " pack-") &&
!prefixcmp(data + i + 46, ".pack\n")) {
get_sha1_hex(data + i + 6, sha1);
setup_index(sha1);
i += 51;
break;
}
default:
while (data[i] != '\n')
i++;
}
i++;
switch (http_get_info_packs(repo->url, &repo->packs)) {
case HTTP_OK:
case HTTP_MISSING_TARGET:
ret = 0;
break;
default:
ret = -1;
}

strbuf_release(&buffer);
return 0;
return ret;
}

static void one_remote_object(const char *hex)
Expand Down

0 comments on commit b8caac2

Please sign in to comment.