http*: add helper methods for fetching packs
The code handling the fetching of packs in http-push.c and http-walker.c have been refactored into new methods and a new struct (http_pack_request) in http.c. They are not meant to be invoked elsewhere. The new methods in http.c are - new_http_pack_request - finish_http_pack_request - release_http_pack_request and the new struct is http_pack_request. Add a function, new_http_pack_request(), that deals with the details of coming up with the filename to store the retrieved packfile, resuming a previously aborted request, and making a new curl request. Update http-push.c::start_fetch_packed() and http-walker.c::fetch_pack() to use this. Add a function, finish_http_pack_request(), that deals with renaming the pack, advancing the pack list, and installing the pack. Update http-push.c::finish_request() and http-walker.c::fetch_pack to use this. Update release_request() in http-push.c and http-walker.c to invoke release_http_pack_request() to clean up pack request helper data. The local_stream member of the transfer_request struct in http-push.c has been removed, as the packfile pointer will be managed in the struct http_pack_request. Signed-off-by: Tay Ray Chuan <rctay89@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:

committed by
Junio C Hamano

parent
39dc52cf4f
commit
2264dfa5c4
@ -1,6 +1,5 @@
|
||||
#include "cache.h"
|
||||
#include "commit.h"
|
||||
#include "pack.h"
|
||||
#include "walker.h"
|
||||
#include "http.h"
|
||||
|
||||
@ -590,19 +589,10 @@ static int fetch_indices(struct walker *walker, struct alt_base *repo)
|
||||
|
||||
static int fetch_pack(struct walker *walker, struct alt_base *repo, unsigned char *sha1)
|
||||
{
|
||||
char *url;
|
||||
struct packed_git *target;
|
||||
struct packed_git **lst;
|
||||
FILE *packfile;
|
||||
char *filename;
|
||||
char tmpfile[PATH_MAX];
|
||||
int ret;
|
||||
long prev_posn = 0;
|
||||
char range[RANGE_HEADER_SIZE];
|
||||
struct curl_slist *range_header = NULL;
|
||||
|
||||
struct active_request_slot *slot;
|
||||
struct slot_results results;
|
||||
struct http_pack_request *preq;
|
||||
|
||||
if (fetch_indices(walker, repo))
|
||||
return -1;
|
||||
@ -617,72 +607,33 @@ static int fetch_pack(struct walker *walker, struct alt_base *repo, unsigned cha
|
||||
sha1_to_hex(sha1));
|
||||
}
|
||||
|
||||
url = xmalloc(strlen(repo->base) + 65);
|
||||
sprintf(url, "%s/objects/pack/pack-%s.pack",
|
||||
repo->base, sha1_to_hex(target->sha1));
|
||||
preq = new_http_pack_request(target, repo->base);
|
||||
if (preq == NULL)
|
||||
goto abort;
|
||||
preq->lst = &repo->packs;
|
||||
preq->slot->results = &results;
|
||||
|
||||
filename = sha1_pack_name(target->sha1);
|
||||
snprintf(tmpfile, sizeof(tmpfile), "%s.temp", filename);
|
||||
packfile = fopen(tmpfile, "a");
|
||||
if (!packfile)
|
||||
return error("Unable to open local file %s for pack",
|
||||
tmpfile);
|
||||
|
||||
slot = get_active_slot();
|
||||
slot->results = &results;
|
||||
curl_easy_setopt(slot->curl, CURLOPT_FILE, packfile);
|
||||
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 = packfile;
|
||||
|
||||
/*
|
||||
* If there is data present from a previous transfer attempt,
|
||||
* resume where it left off
|
||||
*/
|
||||
prev_posn = ftell(packfile);
|
||||
if (prev_posn>0) {
|
||||
if (walker->get_verbosely)
|
||||
fprintf(stderr,
|
||||
"Resuming fetch of pack %s at byte %ld\n",
|
||||
sha1_to_hex(target->sha1), 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 (start_active_slot(preq->slot)) {
|
||||
run_active_slot(preq->slot);
|
||||
if (results.curl_result != CURLE_OK) {
|
||||
fclose(packfile);
|
||||
slot->local = NULL;
|
||||
return error("Unable to get pack file %s\n%s", url,
|
||||
curl_errorstr);
|
||||
error("Unable to get pack file %s\n%s", preq->url,
|
||||
curl_errorstr);
|
||||
goto abort;
|
||||
}
|
||||
} else {
|
||||
fclose(packfile);
|
||||
slot->local = NULL;
|
||||
return error("Unable to start request");
|
||||
error("Unable to start request");
|
||||
goto abort;
|
||||
}
|
||||
|
||||
target->pack_size = ftell(packfile);
|
||||
fclose(packfile);
|
||||
slot->local = NULL;
|
||||
|
||||
ret = move_temp_to_file(tmpfile, filename);
|
||||
ret = finish_http_pack_request(preq);
|
||||
release_http_pack_request(preq);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
lst = &repo->packs;
|
||||
while (*lst != target)
|
||||
lst = &((*lst)->next);
|
||||
*lst = (*lst)->next;
|
||||
|
||||
if (verify_pack(target))
|
||||
return -1;
|
||||
install_packed_git(target);
|
||||
|
||||
return 0;
|
||||
|
||||
abort:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void abort_object_request(struct object_request *obj_req)
|
||||
|
Reference in New Issue
Block a user