1
#include "cache.h"
2
#include "commit.h"
3
-#include "pack.h"
3
#include "tag.h"
4
#include "blob.h"
5
#include "http.h"
118
char filename[PATH_MAX];
119
char tmpfile[PATH_MAX];
120
int local_fileno;
122
- FILE *local_stream;
121
enum transfer_state state;
122
CURLcode curl_result;
123
char errorstr[CURL_ERROR_SIZE];
450
451
static void start_fetch_packed(struct transfer_request *request)
452
{
455
- char *url;
453
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;
454
455
struct transfer_request *check_request = request_queue_head;
464
- struct active_request_slot *slot;
456
+ struct http_pack_request *preq;
457
458
target = find_sha1_pack(request->obj->sha1, repo->packs);
459
if (!target) {
466
fprintf(stderr, "Fetching pack %s\n", sha1_to_hex(target->sha1));
467
fprintf(stderr, " which contains %s\n", sha1_to_hex(request->obj->sha1));
468
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;
476
477
/* Make sure there isn't another open request for this pack */
478
while (check_request) {
479
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);
482
release_request(request);
483
return;
484
}
485
check_request = check_request->next;
486
}
487
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;
492
493
/* Try to get the request started, abort the request on error */
494
request->state = RUN_FETCH_PACKED;
537
- if (!start_active_slot(slot)) {
495
+ if (!start_active_slot(preq->slot)) {
496
fprintf(stderr, "Unable to start GET request\n");
497
+ release_http_pack_request(preq);
498
repo->can_update_info_refs = 0;
499
release_request(request);
500
}
677
678
if (request->local_fileno != -1)
679
close(request->local_fileno);
721
- if (request->local_stream)
722
- fclose(request->local_stream);
680
free(request->url);
681
free(request);
682
}
684
static void finish_request(struct transfer_request *request)
685
{
686
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;
688
689
request->curl_result = request->slot->curl_result;
690
request->http_code = request->slot->http_code;
736
- slot = request->slot;
691
request->slot = NULL;
692
693
/* Keep locks active */
775
start_fetch_packed(request);
776
777
} else if (request->state == RUN_FETCH_PACKED) {
778
+ int fail = 1;
779
if (request->curl_result != CURLE_OK) {
780
fprintf(stderr, "Unable to get pack file %s\n%s",
781
request->url, curl_errorstr);
827
- repo->can_update_info_refs = 0;
782
} 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);
789
}
790
}
791
+ if (fail)
792
+ repo->can_update_info_refs = 0;
793
release_request(request);
794
}
795
}
844
request->lock = NULL;
845
request->headers = NULL;
846
request->local_fileno = -1;
903
- request->local_stream = NULL;
847
request->state = NEED_FETCH;
848
request->next = request_queue_head;
849
request_queue_head = request;
883
request->lock = lock;
884
request->headers = NULL;
885
request->local_fileno = -1;
943
- request->local_stream = NULL;
886
request->state = NEED_PUSH;
887
request->next = request_queue_head;
888
request_queue_head = request;