Skip to content

Commit 2264dfa

Browse files
rctaygitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 39dc52c commit 2264dfa

File tree

4 files changed

+167
-151
lines changed

4 files changed

+167
-151
lines changed

http-push.c

Lines changed: 26 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#include "cache.h"
22
#include "commit.h"
3-
#include "pack.h"
43
#include "tag.h"
54
#include "blob.h"
65
#include "http.h"
@@ -119,7 +118,6 @@ struct transfer_request
119118
char filename[PATH_MAX];
120119
char tmpfile[PATH_MAX];
121120
int local_fileno;
122-
FILE *local_stream;
123121
enum transfer_state state;
124122
CURLcode curl_result;
125123
char errorstr[CURL_ERROR_SIZE];
@@ -452,16 +450,10 @@ static void start_mkcol(struct transfer_request *request)
452450

453451
static void start_fetch_packed(struct transfer_request *request)
454452
{
455-
char *url;
456453
struct packed_git *target;
457-
FILE *packfile;
458-
char *filename;
459-
long prev_posn = 0;
460-
char range[RANGE_HEADER_SIZE];
461-
struct curl_slist *range_header = NULL;
462454

463455
struct transfer_request *check_request = request_queue_head;
464-
struct active_request_slot *slot;
456+
struct http_pack_request *preq;
465457

466458
target = find_sha1_pack(request->obj->sha1, repo->packs);
467459
if (!target) {
@@ -474,68 +466,35 @@ static void start_fetch_packed(struct transfer_request *request)
474466
fprintf(stderr, "Fetching pack %s\n", sha1_to_hex(target->sha1));
475467
fprintf(stderr, " which contains %s\n", sha1_to_hex(request->obj->sha1));
476468

477-
filename = sha1_pack_name(target->sha1);
478-
snprintf(request->filename, sizeof(request->filename), "%s", filename);
479-
snprintf(request->tmpfile, sizeof(request->tmpfile),
480-
"%s.temp", filename);
481-
482-
url = xmalloc(strlen(repo->url) + 64);
483-
sprintf(url, "%sobjects/pack/pack-%s.pack",
484-
repo->url, sha1_to_hex(target->sha1));
469+
preq = new_http_pack_request(target, repo->url);
470+
if (preq == NULL) {
471+
release_http_pack_request(preq);
472+
repo->can_update_info_refs = 0;
473+
return;
474+
}
475+
preq->lst = &repo->packs;
485476

486477
/* Make sure there isn't another open request for this pack */
487478
while (check_request) {
488479
if (check_request->state == RUN_FETCH_PACKED &&
489-
!strcmp(check_request->url, url)) {
490-
free(url);
480+
!strcmp(check_request->url, preq->url)) {
481+
release_http_pack_request(preq);
491482
release_request(request);
492483
return;
493484
}
494485
check_request = check_request->next;
495486
}
496487

497-
packfile = fopen(request->tmpfile, "a");
498-
if (!packfile) {
499-
fprintf(stderr, "Unable to open local file %s for pack",
500-
request->tmpfile);
501-
repo->can_update_info_refs = 0;
502-
free(url);
503-
return;
504-
}
505-
506-
slot = get_active_slot();
507-
slot->callback_func = process_response;
508-
slot->callback_data = request;
509-
request->slot = slot;
510-
request->local_stream = packfile;
511-
request->userData = target;
512-
513-
request->url = url;
514-
curl_easy_setopt(slot->curl, CURLOPT_FILE, packfile);
515-
curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite);
516-
curl_easy_setopt(slot->curl, CURLOPT_URL, url);
517-
curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, no_pragma_header);
518-
slot->local = packfile;
519-
520-
/*
521-
* If there is data present from a previous transfer attempt,
522-
* resume where it left off
523-
*/
524-
prev_posn = ftell(packfile);
525-
if (prev_posn>0) {
526-
if (push_verbosely)
527-
fprintf(stderr,
528-
"Resuming fetch of pack %s at byte %ld\n",
529-
sha1_to_hex(target->sha1), prev_posn);
530-
sprintf(range, "Range: bytes=%ld-", prev_posn);
531-
range_header = curl_slist_append(range_header, range);
532-
curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, range_header);
533-
}
488+
preq->slot->callback_func = process_response;
489+
preq->slot->callback_data = request;
490+
request->slot = preq->slot;
491+
request->userData = preq;
534492

535493
/* Try to get the request started, abort the request on error */
536494
request->state = RUN_FETCH_PACKED;
537-
if (!start_active_slot(slot)) {
495+
if (!start_active_slot(preq->slot)) {
538496
fprintf(stderr, "Unable to start GET request\n");
497+
release_http_pack_request(preq);
539498
repo->can_update_info_refs = 0;
540499
release_request(request);
541500
}
@@ -718,22 +677,17 @@ static void release_request(struct transfer_request *request)
718677

719678
if (request->local_fileno != -1)
720679
close(request->local_fileno);
721-
if (request->local_stream)
722-
fclose(request->local_stream);
723680
free(request->url);
724681
free(request);
725682
}
726683

727684
static void finish_request(struct transfer_request *request)
728685
{
729686
struct stat st;
730-
struct packed_git *target;
731-
struct packed_git **lst;
732-
struct active_request_slot *slot;
687+
struct http_pack_request *preq;
733688

734689
request->curl_result = request->slot->curl_result;
735690
request->http_code = request->slot->http_code;
736-
slot = request->slot;
737691
request->slot = NULL;
738692

739693
/* Keep locks active */
@@ -821,31 +775,21 @@ static void finish_request(struct transfer_request *request)
821775
start_fetch_packed(request);
822776

823777
} else if (request->state == RUN_FETCH_PACKED) {
778+
int fail = 1;
824779
if (request->curl_result != CURLE_OK) {
825780
fprintf(stderr, "Unable to get pack file %s\n%s",
826781
request->url, curl_errorstr);
827-
repo->can_update_info_refs = 0;
828782
} else {
829-
off_t pack_size = ftell(request->local_stream);
830-
831-
fclose(request->local_stream);
832-
request->local_stream = NULL;
833-
slot->local = NULL;
834-
if (!move_temp_to_file(request->tmpfile,
835-
request->filename)) {
836-
target = (struct packed_git *)request->userData;
837-
target->pack_size = pack_size;
838-
lst = &repo->packs;
839-
while (*lst != target)
840-
lst = &((*lst)->next);
841-
*lst = (*lst)->next;
842-
843-
if (!verify_pack(target))
844-
install_packed_git(target);
845-
else
846-
repo->can_update_info_refs = 0;
783+
preq = (struct http_pack_request *)request->userData;
784+
785+
if (preq) {
786+
if (finish_http_pack_request(preq) > 0)
787+
fail = 0;
788+
release_http_pack_request(preq);
847789
}
848790
}
791+
if (fail)
792+
repo->can_update_info_refs = 0;
849793
release_request(request);
850794
}
851795
}
@@ -900,7 +844,6 @@ static void add_fetch_request(struct object *obj)
900844
request->lock = NULL;
901845
request->headers = NULL;
902846
request->local_fileno = -1;
903-
request->local_stream = NULL;
904847
request->state = NEED_FETCH;
905848
request->next = request_queue_head;
906849
request_queue_head = request;
@@ -940,7 +883,6 @@ static int add_send_request(struct object *obj, struct remote_lock *lock)
940883
request->lock = lock;
941884
request->headers = NULL;
942885
request->local_fileno = -1;
943-
request->local_stream = NULL;
944886
request->state = NEED_PUSH;
945887
request->next = request_queue_head;
946888
request_queue_head = request;

http-walker.c

Lines changed: 18 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#include "cache.h"
22
#include "commit.h"
3-
#include "pack.h"
43
#include "walker.h"
54
#include "http.h"
65

@@ -590,19 +589,10 @@ static int fetch_indices(struct walker *walker, struct alt_base *repo)
590589

591590
static int fetch_pack(struct walker *walker, struct alt_base *repo, unsigned char *sha1)
592591
{
593-
char *url;
594592
struct packed_git *target;
595-
struct packed_git **lst;
596-
FILE *packfile;
597-
char *filename;
598-
char tmpfile[PATH_MAX];
599593
int ret;
600-
long prev_posn = 0;
601-
char range[RANGE_HEADER_SIZE];
602-
struct curl_slist *range_header = NULL;
603-
604-
struct active_request_slot *slot;
605594
struct slot_results results;
595+
struct http_pack_request *preq;
606596

607597
if (fetch_indices(walker, repo))
608598
return -1;
@@ -617,72 +607,33 @@ static int fetch_pack(struct walker *walker, struct alt_base *repo, unsigned cha
617607
sha1_to_hex(sha1));
618608
}
619609

620-
url = xmalloc(strlen(repo->base) + 65);
621-
sprintf(url, "%s/objects/pack/pack-%s.pack",
622-
repo->base, sha1_to_hex(target->sha1));
610+
preq = new_http_pack_request(target, repo->base);
611+
if (preq == NULL)
612+
goto abort;
613+
preq->lst = &repo->packs;
614+
preq->slot->results = &results;
623615

624-
filename = sha1_pack_name(target->sha1);
625-
snprintf(tmpfile, sizeof(tmpfile), "%s.temp", filename);
626-
packfile = fopen(tmpfile, "a");
627-
if (!packfile)
628-
return error("Unable to open local file %s for pack",
629-
tmpfile);
630-
631-
slot = get_active_slot();
632-
slot->results = &results;
633-
curl_easy_setopt(slot->curl, CURLOPT_FILE, packfile);
634-
curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite);
635-
curl_easy_setopt(slot->curl, CURLOPT_URL, url);
636-
curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, no_pragma_header);
637-
slot->local = packfile;
638-
639-
/*
640-
* If there is data present from a previous transfer attempt,
641-
* resume where it left off
642-
*/
643-
prev_posn = ftell(packfile);
644-
if (prev_posn>0) {
645-
if (walker->get_verbosely)
646-
fprintf(stderr,
647-
"Resuming fetch of pack %s at byte %ld\n",
648-
sha1_to_hex(target->sha1), prev_posn);
649-
sprintf(range, "Range: bytes=%ld-", prev_posn);
650-
range_header = curl_slist_append(range_header, range);
651-
curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, range_header);
652-
}
653-
654-
if (start_active_slot(slot)) {
655-
run_active_slot(slot);
616+
if (start_active_slot(preq->slot)) {
617+
run_active_slot(preq->slot);
656618
if (results.curl_result != CURLE_OK) {
657-
fclose(packfile);
658-
slot->local = NULL;
659-
return error("Unable to get pack file %s\n%s", url,
660-
curl_errorstr);
619+
error("Unable to get pack file %s\n%s", preq->url,
620+
curl_errorstr);
621+
goto abort;
661622
}
662623
} else {
663-
fclose(packfile);
664-
slot->local = NULL;
665-
return error("Unable to start request");
624+
error("Unable to start request");
625+
goto abort;
666626
}
667627

668-
target->pack_size = ftell(packfile);
669-
fclose(packfile);
670-
slot->local = NULL;
671-
672-
ret = move_temp_to_file(tmpfile, filename);
628+
ret = finish_http_pack_request(preq);
629+
release_http_pack_request(preq);
673630
if (ret)
674631
return ret;
675632

676-
lst = &repo->packs;
677-
while (*lst != target)
678-
lst = &((*lst)->next);
679-
*lst = (*lst)->next;
680-
681-
if (verify_pack(target))
682-
return -1;
683-
install_packed_git(target);
684-
685633
return 0;
634+
635+
abort:
636+
return -1;
686637
}
687638

688639
static void abort_object_request(struct object_request *obj_req)

0 commit comments

Comments
 (0)