@matheusbsbs / matheus-bagliano / commits / b8caac2b8a
Fork 0

http*: add http_get_info_packs

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>

Tay Ray Chuan committed Jun 6, 2009 at 16:43 UTC b8caac2b8ab6482e7ab59c8ec18f1c3d90e7387d
4 files changed +186 -345
http-push.c
+9 -170
@@ -953,184 +953,23 @@ static int add_send_request(struct object *obj, struct remote_lock *lock)
953 return 1;
954 }
955
956 -static int fetch_index(unsigned char *sha1)
957 -{
958 - int ret = 0;
959 - char *hex = xstrdup(sha1_to_hex(sha1));
960 - char *filename;
961 - char *url;
962 - char tmpfile[PATH_MAX];
963 - long prev_posn = 0;
964 - char range[RANGE_HEADER_SIZE];
965 - struct curl_slist *range_header = NULL;
966 -
967 - FILE *indexfile;
968 - struct active_request_slot *slot;
969 - struct slot_results results;
970 -
971 - /* Don't use the index if the pack isn't there */
972 - url = xmalloc(strlen(repo->url) + 64);
973 - sprintf(url, "%sobjects/pack/pack-%s.pack", repo->url, hex);
974 - slot = get_active_slot();
975 - slot->results = &results;
976 - curl_easy_setopt(slot->curl, CURLOPT_URL, url);
977 - curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 1);
978 - if (start_active_slot(slot)) {
979 - run_active_slot(slot);
980 - if (results.curl_result != CURLE_OK) {
981 - ret = error("Unable to verify pack %s is available",
982 - hex);
983 - goto cleanup_pack;
984 - }
985 - } else {
986 - ret = error("Unable to start request");
987 - goto cleanup_pack;
988 - }
989 -
990 - if (has_pack_index(sha1)) {
991 - ret = 0;
992 - goto cleanup_pack;
993 - }
994 -
995 - if (push_verbosely)
996 - fprintf(stderr, "Getting index for pack %s\n", hex);
997 -
998 - sprintf(url, "%sobjects/pack/pack-%s.idx", repo->url, hex);
999 -
1000 - filename = sha1_pack_index_name(sha1);
1001 - snprintf(tmpfile, sizeof(tmpfile), "%s.temp", filename);
1002 - indexfile = fopen(tmpfile, "a");
1003 - if (!indexfile) {
1004 - ret = error("Unable to open local file %s for pack index",
1005 - tmpfile);
1006 - goto cleanup_pack;
1007 - }
1008 -
1009 - slot = get_active_slot();
1010 - slot->results = &results;
1011 - curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 0);
1012 - curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1);
1013 - curl_easy_setopt(slot->curl, CURLOPT_FILE, indexfile);
1014 - curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite);
1015 - curl_easy_setopt(slot->curl, CURLOPT_URL, url);
1016 - curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, no_pragma_header);
1017 - slot->local = indexfile;
1018 -
1019 - /*
1020 - * If there is data present from a previous transfer attempt,
1021 - * resume where it left off
1022 - */
1023 - prev_posn = ftell(indexfile);
1024 - if (prev_posn>0) {
1025 - if (push_verbosely)
1026 - fprintf(stderr,
1027 - "Resuming fetch of index for pack %s at byte %ld\n",
1028 - hex, prev_posn);
1029 - sprintf(range, "Range: bytes=%ld-", prev_posn);
1030 - range_header = curl_slist_append(range_header, range);
1031 - curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, range_header);
1032 - }
1033 -
1034 - if (start_active_slot(slot)) {
1035 - run_active_slot(slot);
1036 - if (results.curl_result != CURLE_OK) {
1037 - ret = error("Unable to get pack index %s\n%s", url,
1038 - curl_errorstr);
1039 - goto cleanup_index;
1040 - }
1041 - } else {
1042 - ret = error("Unable to start request");
1043 - goto cleanup_index;
1044 - }
1045 -
1046 - ret = move_temp_to_file(tmpfile, filename);
1047 -
1048 -cleanup_index:
1049 - fclose(indexfile);
1050 - slot->local = NULL;
1051 -cleanup_pack:
1052 - free(url);
1053 - free(hex);
1054 - return ret;
1055 -}
1056 -
1057 -static int setup_index(unsigned char *sha1)
1058 -{
1059 - struct packed_git *new_pack;
1060 -
1061 - if (fetch_index(sha1))
1062 - return -1;
1063 -
1064 - new_pack = parse_pack_index(sha1);
1065 - if (!new_pack)
1066 - return -1; /* parse_pack_index() already issued error message */
1067 - new_pack->next = repo->packs;
1068 - repo->packs = new_pack;
1069 - return 0;
1070 -}
1071 -
956 static int fetch_indices(void)
957 {
1074 - unsigned char sha1[20];
1075 - char *url;
1076 - struct strbuf buffer = STRBUF_INIT;
1077 - char *data;
1078 - int i = 0;
1079 -
1080 - struct active_request_slot *slot;
1081 - struct slot_results results;
958 + int ret;
959
960 if (push_verbosely)
961 fprintf(stderr, "Getting pack list\n");
962
1086 - url = xmalloc(strlen(repo->url) + 20);
1087 - sprintf(url, "%sobjects/info/packs", repo->url);
1088 -
1089 - slot = get_active_slot();
1090 - slot->results = &results;
1091 - curl_easy_setopt(slot->curl, CURLOPT_FILE, &buffer);
1092 - curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer);
1093 - curl_easy_setopt(slot->curl, CURLOPT_URL, url);
1094 - curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, NULL);
1095 - if (start_active_slot(slot)) {
1096 - run_active_slot(slot);
1097 - if (results.curl_result != CURLE_OK) {
1098 - strbuf_release(&buffer);
1099 - free(url);
1100 - if (results.http_code == 404)
1101 - return 0;
1102 - else
1103 - return error("%s", curl_errorstr);
1104 - }
1105 - } else {
1106 - strbuf_release(&buffer);
1107 - free(url);
1108 - return error("Unable to start request");
1109 - }
1110 - free(url);
1111 -
1112 - data = buffer.buf;
1113 - while (i < buffer.len) {
1114 - switch (data[i]) {
1115 - case 'P':
1116 - i++;
1117 - if (i + 52 < buffer.len &&
1118 - !prefixcmp(data + i, " pack-") &&
1119 - !prefixcmp(data + i + 46, ".pack\n")) {
1120 - get_sha1_hex(data + i + 6, sha1);
1121 - setup_index(sha1);
1122 - i += 51;
1123 - break;
1124 - }
1125 - default:
1126 - while (data[i] != '\n')
1127 - i++;
1128 - }
1129 - i++;
963 + switch (http_get_info_packs(repo->url, &repo->packs)) {
964 + case HTTP_OK:
965 + case HTTP_MISSING_TARGET:
966 + ret = 0;
967 + break;
968 + default:
969 + ret = -1;
970 }
971
1132 - strbuf_release(&buffer);
1133 - return 0;
972 + return ret;
973 }
974
975 static void one_remote_object(const char *hex)
http-walker.c
+9 -175
@@ -368,124 +368,6 @@ static void prefetch(struct walker *walker, unsigned char *sha1)
368 #endif
369 }
370
371 -static int fetch_index(struct walker *walker, struct alt_base *repo, unsigned char *sha1)
372 -{
373 - int ret = 0;
374 - char *hex = xstrdup(sha1_to_hex(sha1));
375 - char *filename;
376 - char *url;
377 - char tmpfile[PATH_MAX];
378 - long prev_posn = 0;
379 - char range[RANGE_HEADER_SIZE];
380 - struct curl_slist *range_header = NULL;
381 -
382 - FILE *indexfile;
383 - struct active_request_slot *slot;
384 - struct slot_results results;
385 -
386 - /* Don't use the index if the pack isn't there */
387 - url = xmalloc(strlen(repo->base) + 64);
388 - sprintf(url, "%s/objects/pack/pack-%s.pack", repo->base, hex);
389 - slot = get_active_slot();
390 - slot->results = &results;
391 - curl_easy_setopt(slot->curl, CURLOPT_URL, url);
392 - curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 1);
393 - if (start_active_slot(slot)) {
394 - run_active_slot(slot);
395 - if (results.curl_result != CURLE_OK) {
396 - ret = error("Unable to verify pack %s is available",
397 - hex);
398 - goto cleanup_pack;
399 - }
400 - } else {
401 - ret = error("Unable to start request");
402 - goto cleanup_pack;
403 - }
404 -
405 - if (has_pack_index(sha1)) {
406 - ret = 0;
407 - goto cleanup_pack;
408 - }
409 -
410 - if (walker->get_verbosely)
411 - fprintf(stderr, "Getting index for pack %s\n", hex);
412 -
413 - sprintf(url, "%s/objects/pack/pack-%s.idx", repo->base, hex);
414 -
415 - filename = sha1_pack_index_name(sha1);
416 - snprintf(tmpfile, sizeof(tmpfile), "%s.temp", filename);
417 - indexfile = fopen(tmpfile, "a");
418 - if (!indexfile) {
419 - ret = error("Unable to open local file %s for pack index",
420 - tmpfile);
421 - goto cleanup_pack;
422 - }
423 -
424 - slot = get_active_slot();
425 - slot->results = &results;
426 - curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 0);
427 - curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1);
428 - curl_easy_setopt(slot->curl, CURLOPT_FILE, indexfile);
429 - curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite);
430 - curl_easy_setopt(slot->curl, CURLOPT_URL, url);
431 - curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, no_pragma_header);
432 - slot->local = indexfile;
433 -
434 - /*
435 - * If there is data present from a previous transfer attempt,
436 - * resume where it left off
437 - */
438 - prev_posn = ftell(indexfile);
439 - if (prev_posn>0) {
440 - if (walker->get_verbosely)
441 - fprintf(stderr,
442 - "Resuming fetch of index for pack %s at byte %ld\n",
443 - hex, prev_posn);
444 - sprintf(range, "Range: bytes=%ld-", prev_posn);
445 - range_header = curl_slist_append(range_header, range);
446 - curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, range_header);
447 - }
448 -
449 - if (start_active_slot(slot)) {
450 - run_active_slot(slot);
451 - if (results.curl_result != CURLE_OK) {
452 - ret = error("Unable to get pack index %s\n%s", url,
453 - curl_errorstr);
454 - goto cleanup_index;
455 - }
456 - } else {
457 - ret = error("Unable to start request");
458 - goto cleanup_index;
459 - }
460 -
461 - ret = move_temp_to_file(tmpfile, filename);
462 -
463 -cleanup_index:
464 - fclose(indexfile);
465 - slot->local = NULL;
466 -cleanup_pack:
467 - free(url);
468 - free(hex);
469 - return ret;
470 -}
471 -
472 -static int setup_index(struct walker *walker, struct alt_base *repo, unsigned char *sha1)
473 -{
474 - struct packed_git *new_pack;
475 - if (has_pack_file(sha1))
476 - return 0; /* don't list this as something we can get */
477 -
478 - if (fetch_index(walker, repo, sha1))
479 - return -1;
480 -
481 - new_pack = parse_pack_index(sha1);
482 - if (!new_pack)
483 - return -1; /* parse_pack_index() already issued error message */
484 - new_pack->next = repo->packs;
485 - repo->packs = new_pack;
486 - return 0;
487 -}
488 -
371 static void process_alternates_response(void *callback_data)
372 {
373 struct alternates_request *alt_req =
@@ -684,15 +566,7 @@ static void fetch_alternates(struct walker *walker, const char *base)
566
567 static int fetch_indices(struct walker *walker, struct alt_base *repo)
568 {
687 - unsigned char sha1[20];
688 - char *url;
689 - struct strbuf buffer = STRBUF_INIT;
690 - char *data;
691 - int i = 0;
692 - int ret = 0;
693 -
694 - struct active_request_slot *slot;
695 - struct slot_results results;
569 + int ret;
570
571 if (repo->got_indices)
572 return 0;
@@ -700,57 +574,17 @@ static int fetch_indices(struct walker *walker, struct alt_base *repo)
574 if (walker->get_verbosely)
575 fprintf(stderr, "Getting pack list for %s\n", repo->base);
576
703 - url = xmalloc(strlen(repo->base) + 21);
704 - sprintf(url, "%s/objects/info/packs", repo->base);
705 -
706 - slot = get_active_slot();
707 - slot->results = &results;
708 - curl_easy_setopt(slot->curl, CURLOPT_FILE, &buffer);
709 - curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer);
710 - curl_easy_setopt(slot->curl, CURLOPT_URL, url);
711 - curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, NULL);
712 - if (start_active_slot(slot)) {
713 - run_active_slot(slot);
714 - if (results.curl_result != CURLE_OK) {
715 - if (missing_target(&results)) {
716 - repo->got_indices = 1;
717 - goto cleanup;
718 - } else {
719 - repo->got_indices = 0;
720 - ret = error("%s", curl_errorstr);
721 - goto cleanup;
722 - }
723 - }
724 - } else {
577 + switch (http_get_info_packs(repo->base, &repo->packs)) {
578 + case HTTP_OK:
579 + case HTTP_MISSING_TARGET:
580 + repo->got_indices = 1;
581 + ret = 0;
582 + break;
583 + default:
584 repo->got_indices = 0;
726 - ret = error("Unable to start request");
727 - goto cleanup;
585 + ret = -1;
586 }
587
730 - data = buffer.buf;
731 - while (i < buffer.len) {
732 - switch (data[i]) {
733 - case 'P':
734 - i++;
735 - if (i + 52 <= buffer.len &&
736 - !prefixcmp(data + i, " pack-") &&
737 - !prefixcmp(data + i + 46, ".pack\n")) {
738 - get_sha1_hex(data + i + 6, sha1);
739 - setup_index(walker, repo, sha1);
740 - i += 51;
741 - break;
742 - }
743 - default:
744 - while (i < buffer.len && data[i] != '\n')
745 - i++;
746 - }
747 - i++;
748 - }
749 -
750 - repo->got_indices = 1;
751 -cleanup:
752 - strbuf_release(&buffer);
753 - free(url);
588 return ret;
589 }
590
http.c
+164
@@ -790,3 +790,167 @@ int http_fetch_ref(const char *base, struct ref *ref)
790 free(url);
791 return ret;
792 }
793 +
794 +/* Helpers for fetching packs */
795 +static int fetch_pack_index(unsigned char *sha1, const char *base_url)
796 +{
797 + int ret = 0;
798 + char *hex = xstrdup(sha1_to_hex(sha1));
799 + char *filename;
800 + char *url;
801 + char tmpfile[PATH_MAX];
802 + long prev_posn = 0;
803 + char range[RANGE_HEADER_SIZE];
804 + struct strbuf buf = STRBUF_INIT;
805 + struct curl_slist *range_header = NULL;
806 +
807 + FILE *indexfile;
808 + struct active_request_slot *slot;
809 + struct slot_results results;
810 +
811 + /* Don't use the index if the pack isn't there */
812 + end_url_with_slash(&buf, base_url);
813 + strbuf_addf(&buf, "objects/pack/pack-%s.pack", hex);
814 + url = strbuf_detach(&buf, 0);
815 +
816 + slot = get_active_slot();
817 + slot->results = &results;
818 + curl_easy_setopt(slot->curl, CURLOPT_URL, url);
819 + curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 1);
820 + if (start_active_slot(slot)) {
821 + run_active_slot(slot);
822 + if (results.curl_result != CURLE_OK) {
823 + ret = error("Unable to verify pack %s is available",
824 + hex);
825 + goto cleanup_pack;
826 + }
827 + } else {
828 + ret = error("Unable to start request");
829 + goto cleanup_pack;
830 + }
831 +
832 + if (has_pack_index(sha1)) {
833 + ret = 0;
834 + goto cleanup_pack;
835 + }
836 +
837 + if (http_is_verbose)
838 + fprintf(stderr, "Getting index for pack %s\n", hex);
839 +
840 + end_url_with_slash(&buf, base_url);
841 + strbuf_addf(&buf, "objects/pack/pack-%s.idx", hex);
842 + url = strbuf_detach(&buf, NULL);
843 +
844 + filename = sha1_pack_index_name(sha1);
845 + snprintf(tmpfile, sizeof(tmpfile), "%s.temp", filename);
846 + indexfile = fopen(tmpfile, "a");
847 + if (!indexfile) {
848 + ret = error("Unable to open local file %s for pack index",
849 + tmpfile);
850 + goto cleanup_pack;
851 + }
852 +
853 + slot = get_active_slot();
854 + slot->results = &results;
855 + curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 0);
856 + curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1);
857 + curl_easy_setopt(slot->curl, CURLOPT_FILE, indexfile);
858 + curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite);
859 + curl_easy_setopt(slot->curl, CURLOPT_URL, url);
860 + curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, no_pragma_header);
861 + slot->local = indexfile;
862 +
863 + /*
864 + * If there is data present from a previous transfer attempt,
865 + * resume where it left off
866 + */
867 + prev_posn = ftell(indexfile);
868 + if (prev_posn>0) {
869 + if (http_is_verbose)
870 + fprintf(stderr,
871 + "Resuming fetch of index for pack %s at byte %ld\n",
872 + hex, prev_posn);
873 + sprintf(range, "Range: bytes=%ld-", prev_posn);
874 + range_header = curl_slist_append(range_header, range);
875 + curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, range_header);
876 + }
877 +
878 + if (start_active_slot(slot)) {
879 + run_active_slot(slot);
880 + if (results.curl_result != CURLE_OK) {
881 + ret = error("Unable to get pack index %s\n%s",
882 + url, curl_errorstr);
883 + goto cleanup_index;
884 + }
885 + } else {
886 + ret = error("Unable to start request");
887 + goto cleanup_index;
888 + }
889 +
890 + ret = move_temp_to_file(tmpfile, filename);
891 +
892 +cleanup_index:
893 + fclose(indexfile);
894 + slot->local = NULL;
895 +cleanup_pack:
896 + free(hex);
897 + free(url);
898 + return ret;
899 +}
900 +
901 +static int fetch_and_setup_pack_index(struct packed_git **packs_head,
902 + unsigned char *sha1, const char *base_url)
903 +{
904 + struct packed_git *new_pack;
905 +
906 + if (fetch_pack_index(sha1, base_url))
907 + return -1;
908 +
909 + new_pack = parse_pack_index(sha1);
910 + if (!new_pack)
911 + return -1; /* parse_pack_index() already issued error message */
912 + new_pack->next = *packs_head;
913 + *packs_head = new_pack;
914 + return 0;
915 +}
916 +
917 +int http_get_info_packs(const char *base_url, struct packed_git **packs_head)
918 +{
919 + int ret = 0, i = 0;
920 + char *url, *data;
921 + struct strbuf buf = STRBUF_INIT;
922 + unsigned char sha1[20];
923 +
924 + end_url_with_slash(&buf, base_url);
925 + strbuf_addstr(&buf, "objects/info/packs");
926 + url = strbuf_detach(&buf, NULL);
927 +
928 + ret = http_get_strbuf(url, &buf, HTTP_NO_CACHE);
929 + if (ret != HTTP_OK)
930 + goto cleanup;
931 +
932 + data = buf.buf;
933 + while (i < buf.len) {
934 + switch (data[i]) {
935 + case 'P':
936 + i++;
937 + if (i + 52 <= buf.len &&
938 + !prefixcmp(data + i, " pack-") &&
939 + !prefixcmp(data + i + 46, ".pack\n")) {
940 + get_sha1_hex(data + i + 6, sha1);
941 + fetch_and_setup_pack_index(packs_head, sha1,
942 + base_url);
943 + i += 51;
944 + break;
945 + }
946 + default:
947 + while (i < buf.len && data[i] != '\n')
948 + i++;
949 + }
950 + i++;
951 + }
952 +
953 +cleanup:
954 + free(url);
955 + return ret;
956 +}
http.h
+4
@@ -146,4 +146,8 @@ int http_error(const char *url, int ret);
146
147 extern int http_fetch_ref(const char *base, struct ref *ref);
148
149 +/* Helpers for fetching packs */
150 +extern int http_get_info_packs(const char *base_url,
151 + struct packed_git **packs_head);
152 +
153 #endif /* HTTP_H */