{"thread":{"id":"19594","subject":"[PATCH 14/17] http*: add http_get_info_packs","startedAt":"2009-05-29T17:59:37Z","lastAt":"2009-06-03T11:55:09Z","messageCount":3,"participants":["Tay Ray Chuan","Clemens Buchacher"],"isPatch":true,"patchVersion":1,"patchTotal":17},"messages":[{"id":"115036","messageId":"20090530015937.c402e5f2.rctay89@gmail.com","threadId":"19594","inReplyTo":null,"subject":"[PATCH 14/17] http*: add http_get_info_packs","fromName":"Tay Ray Chuan","fromEmail":"rctay89@gmail.com","sentAt":"2009-05-29T17:59:37Z","receivedAt":"2009-05-29T17:59:37Z","isPatch":true,"sender":{"key":"rctay89@gmail.com","avatar":"https://avatars.githubusercontent.com/u/61553?v=4"},"body":"http-push.c and http-walker.c no longer have to use fetch_index or\nsetup_index; they simply need to use http_get_info_packs, a new http\nmethod, in their fetch_indices implementations.\n\nMove fetch_index() and rename to fetch_pack_index() in http.c; this\nmethod is not meant to be used outside of http.c. It invokes\nend_url_with_slash with base_url; apart from that change, the code is\nidentical.\n\nMove setup_index() and rename to fetch_and_setup_pack_index() in\nhttp.c; this method is not meant to be used outside of http.c.\n\nSigned-off-by: Tay Ray Chuan <rctay89@gmail.com>\n---\n http-push.c   |  174 +-----------------------------------------------------\n http-walker.c |  180 ++------------------------------------------------------\n http.c        |  163 +++++++++++++++++++++++++++++++++++++++++++++++++++\n http.h        |    4 +\n 4 files changed, 178 insertions(+), 343 deletions(-)\n\ndiff --git a/http-push.c b/http-push.c\nindex 7aa4fc4..fb84e36 100644\n--- a/http-push.c\n+++ b/http-push.c\n@@ -950,182 +950,16 @@ static int add_send_request(struct object *obj, struct remote_lock *lock)\n \treturn 1;\n }\n\n-static int fetch_index(unsigned char *sha1)\n-{\n-\tint ret = 0;\n-\tchar *hex = xstrdup(sha1_to_hex(sha1));\n-\tchar *filename;\n-\tchar *url;\n-\tchar tmpfile[PATH_MAX];\n-\tlong prev_posn = 0;\n-\tchar range[RANGE_HEADER_SIZE];\n-\tstruct curl_slist *range_header = NULL;\n-\n-\tFILE *indexfile;\n-\tstruct active_request_slot *slot;\n-\tstruct slot_results results;\n-\n-\t/* Don't use the index if the pack isn't there */\n-\turl = xmalloc(strlen(repo->url) + 64);\n-\tsprintf(url, \"%sobjects/pack/pack-%s.pack\", repo->url, hex);\n-\tslot = get_active_slot();\n-\tslot->results = &results;\n-\tcurl_easy_setopt(slot->curl, CURLOPT_URL, url);\n-\tcurl_easy_setopt(slot->curl, CURLOPT_NOBODY, 1);\n-\tif (start_active_slot(slot)) {\n-\t\trun_active_slot(slot);\n-\t\tif (results.curl_result != CURLE_OK) {\n-\t\t\tret = error(\"Unable to verify pack %s is available\",\n-\t\t\t\t    hex);\n-\t\t\tgoto cleanup_pack;\n-\t\t}\n-\t} else {\n-\t\tret = error(\"Unable to start request\");\n-\t\tgoto cleanup_pack;\n-\t}\n-\n-\tif (has_pack_index(sha1)) {\n-\t\tret = 0;\n-\t\tgoto cleanup_pack;\n-\t}\n-\n-\tif (push_verbosely)\n-\t\tfprintf(stderr, \"Getting index for pack %s\\n\", hex);\n-\n-\tsprintf(url, \"%sobjects/pack/pack-%s.idx\", repo->url, hex);\n-\n-\tfilename = sha1_pack_index_name(sha1);\n-\tsnprintf(tmpfile, sizeof(tmpfile), \"%s.temp\", filename);\n-\tindexfile = fopen(tmpfile, \"a\");\n-\tif (!indexfile) {\n-\t\tret = error(\"Unable to open local file %s for pack index\",\n-\t\t\t    tmpfile);\n-\t\tgoto cleanup_pack;\n-\t}\n-\n-\tslot = get_active_slot();\n-\tslot->results = &results;\n-\tcurl_easy_setopt(slot->curl, CURLOPT_NOBODY, 0);\n-\tcurl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1);\n-\tcurl_easy_setopt(slot->curl, CURLOPT_FILE, indexfile);\n-\tcurl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite);\n-\tcurl_easy_setopt(slot->curl, CURLOPT_URL, url);\n-\tcurl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, no_pragma_header);\n-\tslot->local = indexfile;\n-\n-\t/*\n-\t * If there is data present from a previous transfer attempt,\n-\t * resume where it left off\n-\t */\n-\tprev_posn = ftell(indexfile);\n-\tif (prev_posn>0) {\n-\t\tif (push_verbosely)\n-\t\t\tfprintf(stderr,\n-\t\t\t\t\"Resuming fetch of index for pack %s at byte %ld\\n\",\n-\t\t\t\thex, prev_posn);\n-\t\tsprintf(range, \"Range: bytes=%ld-\", prev_posn);\n-\t\trange_header = curl_slist_append(range_header, range);\n-\t\tcurl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, range_header);\n-\t}\n-\n-\tif (start_active_slot(slot)) {\n-\t\trun_active_slot(slot);\n-\t\tif (results.curl_result != CURLE_OK) {\n-\t\t\tret = error(\"Unable to get pack index %s\\n%s\", url,\n-\t\t\t\t    curl_errorstr);\n-\t\t\tgoto cleanup_index;\n-\t\t}\n-\t} else {\n-\t\tret = error(\"Unable to start request\");\n-\t\tgoto cleanup_index;\n-\t}\n-\n-\tret = move_temp_to_file(tmpfile, filename);\n-\n-cleanup_index:\n-\tfclose(indexfile);\n-cleanup_pack:\n-\tfree(url);\n-\tfree(hex);\n-\treturn ret;\n-}\n-\n-static int setup_index(unsigned char *sha1)\n-{\n-\tstruct packed_git *new_pack;\n-\n-\tif (fetch_index(sha1))\n-\t\treturn -1;\n-\n-\tnew_pack = parse_pack_index(sha1);\n-\tif (!new_pack)\n-\t\treturn -1; /* parse_pack_index() already issued error message */\n-\tnew_pack->next = repo->packs;\n-\trepo->packs = new_pack;\n-\treturn 0;\n-}\n-\n static int fetch_indices(void)\n {\n-\tunsigned char sha1[20];\n-\tchar *url;\n-\tstruct strbuf buffer = STRBUF_INIT;\n-\tchar *data;\n-\tint i = 0;\n-\n-\tstruct active_request_slot *slot;\n-\tstruct slot_results results;\n-\n \tif (push_verbosely)\n \t\tfprintf(stderr, \"Getting pack list\\n\");\n\n-\turl = xmalloc(strlen(repo->url) + 20);\n-\tsprintf(url, \"%sobjects/info/packs\", repo->url);\n-\n-\tslot = get_active_slot();\n-\tslot->results = &results;\n-\tcurl_easy_setopt(slot->curl, CURLOPT_FILE, &buffer);\n-\tcurl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer);\n-\tcurl_easy_setopt(slot->curl, CURLOPT_URL, url);\n-\tcurl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, NULL);\n-\tif (start_active_slot(slot)) {\n-\t\trun_active_slot(slot);\n-\t\tif (results.curl_result != CURLE_OK) {\n-\t\t\tstrbuf_release(&buffer);\n-\t\t\tfree(url);\n-\t\t\tif (results.http_code == 404)\n-\t\t\t\treturn 0;\n-\t\t\telse\n-\t\t\t\treturn error(\"%s\", curl_errorstr);\n-\t\t}\n-\t} else {\n-\t\tstrbuf_release(&buffer);\n-\t\tfree(url);\n-\t\treturn error(\"Unable to start request\");\n-\t}\n-\tfree(url);\n-\n-\tdata = buffer.buf;\n-\twhile (i < buffer.len) {\n-\t\tswitch (data[i]) {\n-\t\tcase 'P':\n-\t\t\ti++;\n-\t\t\tif (i + 52 < buffer.len &&\n-\t\t\t    !prefixcmp(data + i, \" pack-\") &&\n-\t\t\t    !prefixcmp(data + i + 46, \".pack\\n\")) {\n-\t\t\t\tget_sha1_hex(data + i + 6, sha1);\n-\t\t\t\tsetup_index(sha1);\n-\t\t\t\ti += 51;\n-\t\t\t\tbreak;\n-\t\t\t}\n-\t\tdefault:\n-\t\t\twhile (data[i] != '\\n')\n-\t\t\t\ti++;\n-\t\t}\n-\t\ti++;\n-\t}\n+\tif (http_get_info_packs(repo->url, &repo->packs) == HTTP_OK)\n+\t\treturn 0;\n+\telse\n+\t\treturn -1;\n\n-\tstrbuf_release(&buffer);\n \treturn 0;\n }\n\ndiff --git a/http-walker.c b/http-walker.c\nindex 7d6795c..c550fd9 100644\n--- a/http-walker.c\n+++ b/http-walker.c\n@@ -368,123 +368,6 @@ static void prefetch(struct walker *walker, unsigned char *sha1)\n #endif\n }\n\n-static int fetch_index(struct walker *walker, struct alt_base *repo, unsigned char *sha1)\n-{\n-\tint ret = 0;\n-\tchar *hex = xstrdup(sha1_to_hex(sha1));\n-\tchar *filename;\n-\tchar *url;\n-\tchar tmpfile[PATH_MAX];\n-\tlong prev_posn = 0;\n-\tchar range[RANGE_HEADER_SIZE];\n-\tstruct curl_slist *range_header = NULL;\n-\n-\tFILE *indexfile;\n-\tstruct active_request_slot *slot;\n-\tstruct slot_results results;\n-\n-\t/* Don't use the index if the pack isn't there */\n-\turl = xmalloc(strlen(repo->base) + 64);\n-\tsprintf(url, \"%s/objects/pack/pack-%s.pack\", repo->base, hex);\n-\tslot = get_active_slot();\n-\tslot->results = &results;\n-\tcurl_easy_setopt(slot->curl, CURLOPT_URL, url);\n-\tcurl_easy_setopt(slot->curl, CURLOPT_NOBODY, 1);\n-\tif (start_active_slot(slot)) {\n-\t\trun_active_slot(slot);\n-\t\tif (results.curl_result != CURLE_OK) {\n-\t\t\tret = error(\"Unable to verify pack %s is available\",\n-\t\t\t\t     hex);\n-\t\t\tgoto cleanup_pack;\n-\t\t}\n-\t} else {\n-\t\tret = error(\"Unable to start request\");\n-\t\tgoto cleanup_pack;\n-\t}\n-\n-\tif (has_pack_index(sha1)) {\n-\t\tret = 0;\n-\t\tgoto cleanup_pack;\n-\t}\n-\n-\tif (walker->get_verbosely)\n-\t\tfprintf(stderr, \"Getting index for pack %s\\n\", hex);\n-\n-\tsprintf(url, \"%s/objects/pack/pack-%s.idx\", repo->base, hex);\n-\n-\tfilename = sha1_pack_index_name(sha1);\n-\tsnprintf(tmpfile, sizeof(tmpfile), \"%s.temp\", filename);\n-\tindexfile = fopen(tmpfile, \"a\");\n-\tif (!indexfile) {\n-\t\tret = error(\"Unable to open local file %s for pack index\",\n-\t\t\t    tmpfile);\n-\t\tgoto cleanup_pack;\n-\t}\n-\n-\tslot = get_active_slot();\n-\tslot->results = &results;\n-\tcurl_easy_setopt(slot->curl, CURLOPT_NOBODY, 0);\n-\tcurl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1);\n-\tcurl_easy_setopt(slot->curl, CURLOPT_FILE, indexfile);\n-\tcurl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite);\n-\tcurl_easy_setopt(slot->curl, CURLOPT_URL, url);\n-\tcurl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, no_pragma_header);\n-\tslot->local = indexfile;\n-\n-\t/*\n-\t * If there is data present from a previous transfer attempt,\n-\t * resume where it left off\n-\t */\n-\tprev_posn = ftell(indexfile);\n-\tif (prev_posn>0) {\n-\t\tif (walker->get_verbosely)\n-\t\t\tfprintf(stderr,\n-\t\t\t\t\"Resuming fetch of index for pack %s at byte %ld\\n\",\n-\t\t\t\thex, prev_posn);\n-\t\tsprintf(range, \"Range: bytes=%ld-\", prev_posn);\n-\t\trange_header = curl_slist_append(range_header, range);\n-\t\tcurl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, range_header);\n-\t}\n-\n-\tif (start_active_slot(slot)) {\n-\t\trun_active_slot(slot);\n-\t\tif (results.curl_result != CURLE_OK) {\n-\t\t\tret = error(\"Unable to get pack index %s\\n%s\", url,\n-\t\t\t\t    curl_errorstr);\n-\t\t\tgoto cleanup_index;\n-\t\t}\n-\t} else {\n-\t\tret = error(\"Unable to start request\");\n-\t\tgoto cleanup_index;\n-\t}\n-\n-\tret = move_temp_to_file(tmpfile, filename);\n-\n-cleanup_index:\n-\tfclose(indexfile);\n-cleanup_pack:\n-\tfree(url);\n-\tfree(hex);\n-\treturn ret;\n-}\n-\n-static int setup_index(struct walker *walker, struct alt_base *repo, unsigned char *sha1)\n-{\n-\tstruct packed_git *new_pack;\n-\tif (has_pack_file(sha1))\n-\t\treturn 0; /* don't list this as something we can get */\n-\n-\tif (fetch_index(walker, repo, sha1))\n-\t\treturn -1;\n-\n-\tnew_pack = parse_pack_index(sha1);\n-\tif (!new_pack)\n-\t\treturn -1; /* parse_pack_index() already issued error message */\n-\tnew_pack->next = repo->packs;\n-\trepo->packs = new_pack;\n-\treturn 0;\n-}\n-\n static void process_alternates_response(void *callback_data)\n {\n \tstruct alternates_request *alt_req =\n@@ -683,73 +566,24 @@ static void fetch_alternates(struct walker *walker, const char *base)\n\n static int fetch_indices(struct walker *walker, struct alt_base *repo)\n {\n-\tunsigned char sha1[20];\n-\tchar *url;\n-\tstruct strbuf buffer = STRBUF_INIT;\n-\tchar *data;\n-\tint i = 0;\n \tint ret = 0;\n\n-\tstruct active_request_slot *slot;\n-\tstruct slot_results results;\n-\n \tif (repo->got_indices)\n \t\treturn 0;\n\n \tif (walker->get_verbosely)\n \t\tfprintf(stderr, \"Getting pack list for %s\\n\", repo->base);\n\n-\turl = xmalloc(strlen(repo->base) + 21);\n-\tsprintf(url, \"%s/objects/info/packs\", repo->base);\n-\n-\tslot = get_active_slot();\n-\tslot->results = &results;\n-\tcurl_easy_setopt(slot->curl, CURLOPT_FILE, &buffer);\n-\tcurl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer);\n-\tcurl_easy_setopt(slot->curl, CURLOPT_URL, url);\n-\tcurl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, NULL);\n-\tif (start_active_slot(slot)) {\n-\t\trun_active_slot(slot);\n-\t\tif (results.curl_result != CURLE_OK) {\n-\t\t\tif (missing_target(&results)) {\n-\t\t\t\trepo->got_indices = 1;\n-\t\t\t\tgoto cleanup;\n-\t\t\t} else {\n-\t\t\t\trepo->got_indices = 0;\n-\t\t\t\tret = error(\"%s\", curl_errorstr);\n-\t\t\t\tgoto cleanup;\n-\t\t\t}\n-\t\t}\n-\t} else {\n+\tswitch (http_get_info_packs(repo->base, &repo->packs)) {\n+\tcase HTTP_OK:\n+\tcase HTTP_MISSING_TARGET:\n+\t\trepo->got_indices = 1;\n+\t\tbreak;\n+\tdefault:\n \t\trepo->got_indices = 0;\n-\t\tret = error(\"Unable to start request\");\n-\t\tgoto cleanup;\n+\t\tret = -1;\n \t}\n\n-\tdata = buffer.buf;\n-\twhile (i < buffer.len) {\n-\t\tswitch (data[i]) {\n-\t\tcase 'P':\n-\t\t\ti++;\n-\t\t\tif (i + 52 <= buffer.len &&\n-\t\t\t    !prefixcmp(data + i, \" pack-\") &&\n-\t\t\t    !prefixcmp(data + i + 46, \".pack\\n\")) {\n-\t\t\t\tget_sha1_hex(data + i + 6, sha1);\n-\t\t\t\tsetup_index(walker, repo, sha1);\n-\t\t\t\ti += 51;\n-\t\t\t\tbreak;\n-\t\t\t}\n-\t\tdefault:\n-\t\t\twhile (i < buffer.len && data[i] != '\\n')\n-\t\t\t\ti++;\n-\t\t}\n-\t\ti++;\n-\t}\n-\n-\trepo->got_indices = 1;\n-cleanup:\n-\tstrbuf_release(&buffer);\n-\tfree(url);\n \treturn ret;\n }\n\ndiff --git a/http.c b/http.c\nindex c640510..ba980c8 100644\n--- a/http.c\n+++ b/http.c\n@@ -789,3 +789,166 @@ int http_fetch_ref(const char *base, struct ref *ref)\n \tfree(url);\n \treturn ret;\n }\n+\n+/* Helpers for fetching packs */\n+static int fetch_pack_index(unsigned char *sha1, const char *base_url)\n+{\n+\tint ret = 0;\n+\tchar *hex = xstrdup(sha1_to_hex(sha1));\n+\tchar *filename;\n+\tchar *url;\n+\tchar tmpfile[PATH_MAX];\n+\tlong prev_posn = 0;\n+\tchar range[RANGE_HEADER_SIZE];\n+\tstruct strbuf buf = STRBUF_INIT;\n+\tstruct curl_slist *range_header = NULL;\n+\n+\tFILE *indexfile;\n+\tstruct active_request_slot *slot;\n+\tstruct slot_results results;\n+\n+\t/* Don't use the index if the pack isn't there */\n+\tend_url_with_slash(&buf, base_url);\n+\tstrbuf_addf(&buf, \"objects/pack/pack-%s.pack\", hex);\n+\turl = strbuf_detach(&buf, 0);\n+\n+\tslot = get_active_slot();\n+\tslot->results = &results;\n+\tcurl_easy_setopt(slot->curl, CURLOPT_URL, url);\n+\tcurl_easy_setopt(slot->curl, CURLOPT_NOBODY, 1);\n+\tif (start_active_slot(slot)) {\n+\t\trun_active_slot(slot);\n+\t\tif (results.curl_result != CURLE_OK) {\n+\t\t\tret = error(\"Unable to verify pack %s is available\",\n+\t\t\t\t    hex);\n+\t\t\tgoto cleanup_pack;\n+\t\t}\n+\t} else {\n+\t\tret = error(\"Unable to start request\");\n+\t\tgoto cleanup_pack;\n+\t}\n+\n+\tif (has_pack_index(sha1)) {\n+\t\tret = 0;\n+\t\tgoto cleanup_pack;\n+\t}\n+\n+\tif (http_is_verbose)\n+\t\tfprintf(stderr, \"Getting index for pack %s\\n\", hex);\n+\n+\tend_url_with_slash(&buf, base_url);\n+\tstrbuf_addf(&buf, \"objects/pack/pack-%s.idx\", hex);\n+\turl = strbuf_detach(&buf, NULL);\n+\n+\tfilename = sha1_pack_index_name(sha1);\n+\tsnprintf(tmpfile, sizeof(tmpfile), \"%s.temp\", filename);\n+\tindexfile = fopen(tmpfile, \"a\");\n+\tif (!indexfile) {\n+\t\tret = error(\"Unable to open local file %s for pack index\",\n+\t\t\t    tmpfile);\n+\t\tgoto cleanup_pack;\n+\t}\n+\n+\tslot = get_active_slot();\n+\tslot->results = &results;\n+\tcurl_easy_setopt(slot->curl, CURLOPT_NOBODY, 0);\n+\tcurl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1);\n+\tcurl_easy_setopt(slot->curl, CURLOPT_FILE, indexfile);\n+\tcurl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite);\n+\tcurl_easy_setopt(slot->curl, CURLOPT_URL, url);\n+\tcurl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, no_pragma_header);\n+\tslot->local = indexfile;\n+\n+\t/*\n+\t * If there is data present from a previous transfer attempt,\n+\t * resume where it left off\n+\t */\n+\tprev_posn = ftell(indexfile);\n+\tif (prev_posn>0) {\n+\t\tif (http_is_verbose)\n+\t\t\tfprintf(stderr,\n+\t\t\t\t\"Resuming fetch of index for pack %s at byte %ld\\n\",\n+\t\t\t\thex, prev_posn);\n+\t\tsprintf(range, \"Range: bytes=%ld-\", prev_posn);\n+\t\trange_header = curl_slist_append(range_header, range);\n+\t\tcurl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, range_header);\n+\t}\n+\n+\tif (start_active_slot(slot)) {\n+\t\trun_active_slot(slot);\n+\t\tif (results.curl_result != CURLE_OK) {\n+\t\t\tret = error(\"Unable to get pack index %s\\n%s\",\n+\t\t\t\t    url, curl_errorstr);\n+\t\t\tgoto cleanup_index;\n+\t\t}\n+\t} else {\n+\t\tret = error(\"Unable to start request\");\n+\t\tgoto cleanup_index;\n+\t}\n+\n+\tret = move_temp_to_file(tmpfile, filename);\n+\n+cleanup_index:\n+\tfclose(indexfile);\n+cleanup_pack:\n+\tfree(hex);\n+\tfree(url);\n+\treturn ret;\n+}\n+\n+static int fetch_and_setup_pack_index(struct packed_git **packs_head,\n+\tunsigned char *sha1, const char *base_url)\n+{\n+\tstruct packed_git *new_pack;\n+\n+\tif (fetch_pack_index(sha1, base_url))\n+\t\treturn -1;\n+\n+\tnew_pack = parse_pack_index(sha1);\n+\tif (!new_pack)\n+\t\treturn -1; /* parse_pack_index() already issued error message */\n+\tnew_pack->next = *packs_head;\n+\t*packs_head = new_pack;\n+\treturn 0;\n+}\n+\n+int http_get_info_packs(const char *base_url, struct packed_git **packs_head)\n+{\n+\tint ret = 0, i = 0;\n+\tchar *url, *data;\n+\tstruct strbuf buf = STRBUF_INIT;\n+\tunsigned char sha1[20];\n+\n+\tend_url_with_slash(&buf, base_url);\n+\tstrbuf_addstr(&buf, \"objects/info/packs\");\n+\turl = strbuf_detach(&buf, NULL);\n+\n+\tret = http_get_strbuf(url, &buf, HTTP_NO_CACHE);\n+\tif (ret != HTTP_OK)\n+\t\tgoto cleanup;\n+\n+\tdata = buf.buf;\n+\twhile (i < buf.len) {\n+\t\tswitch (data[i]) {\n+\t\tcase 'P':\n+\t\t\ti++;\n+\t\t\tif (i + 52 <= buf.len &&\n+\t\t\t    !prefixcmp(data + i, \" pack-\") &&\n+\t\t\t    !prefixcmp(data + i + 46, \".pack\\n\")) {\n+\t\t\t\tget_sha1_hex(data + i + 6, sha1);\n+\t\t\t\tfetch_and_setup_pack_index(packs_head, sha1,\n+\t\t\t\t\t\t      base_url);\n+\t\t\t\ti += 51;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\tdefault:\n+\t\t\twhile (i < buf.len && data[i] != '\\n')\n+\t\t\t\ti++;\n+\t\t}\n+\t\ti++;\n+\t}\n+\n+cleanup:\n+\tfree(url);\n+\treturn ret;\n+}\ndiff --git a/http.h b/http.h\nindex 3d878d5..180b1c2 100644\n--- a/http.h\n+++ b/http.h\n@@ -146,4 +146,8 @@ int http_error(const char *url, int ret);\n\n extern int http_fetch_ref(const char *base, struct ref *ref);\n\n+/* Helpers for fetching packs */\n+extern int http_get_info_packs(const char *base_url,\n+\tstruct packed_git **packs_head);\n+\n #endif /* HTTP_H */\n--\n1.6.3.1\n"},{"id":"115136","messageId":"20090531150256.GA27958@localhost","threadId":"19594","inReplyTo":"20090530015937.c402e5f2.rctay89@gmail.com","subject":"Re: [PATCH 14/17] http*: add http_get_info_packs","fromName":"Clemens Buchacher","fromEmail":"drizzd@aon.at","sentAt":"2009-05-31T15:02:56Z","receivedAt":"2009-05-31T15:02:56Z","isPatch":true,"sender":{"key":"drizzd@gmx.net","avatar":"https://avatars.githubusercontent.com/u/59082?v=4"},"body":"On Sat, May 30, 2009 at 01:59:37AM +0800, Tay Ray Chuan wrote:\n> --- a/http-push.c\n> +++ b/http-push.c\n> @@ -950,182 +950,16 @@ static int add_send_request(struct object *obj, struct remote_lock *lock)\n[...]\n>  static int fetch_indices(void)\n>  {\n[...]\n> -\t\tif (results.curl_result != CURLE_OK) {\n> -\t\t\tstrbuf_release(&buffer);\n> -\t\t\tfree(url);\n> -\t\t\tif (results.http_code == 404)\n> -\t\t\t\treturn 0;\n> -\t\t\telse\n> -\t\t\t\treturn error(\"%s\", curl_errorstr);\n> -\t\t}\n[...]\n> +\tif (http_get_info_packs(repo->url, &repo->packs) == HTTP_OK)\n> +\t\treturn 0;\n> +\telse\n> +\t\treturn -1;\n\nfetch_indices() used to return 0 if the pack info was missing. Now it\nreturns an error. I also think we could get rid of repo->has_info_packs.\nThis could easily be handled within fetch_indices().\n\nClemens\n"},{"id":"115337","messageId":"be6fef0d0906030455p7b3b4d20p609adbb68093e988@mail.gmail.com","threadId":"19594","inReplyTo":"20090531150256.GA27958@localhost","subject":"Re: [PATCH 14/17] http*: add http_get_info_packs","fromName":"Tay Ray Chuan","fromEmail":"rctay89@gmail.com","sentAt":"2009-06-03T11:55:09Z","receivedAt":"2009-06-03T11:55:09Z","isPatch":true,"sender":{"key":"rctay89@gmail.com","avatar":"https://avatars.githubusercontent.com/u/61553?v=4"},"body":"Hi,\n\nOn Sun, May 31, 2009 at 11:02 PM, Clemens Buchacher <drizzd@aon.at> wrote:\n> fetch_indices() used to return 0 if the pack info was missing. Now it\n> returns an error.\n\nThanks for noticing this.\n\n> I also think we could get rid of repo->has_info_packs.\n> This could easily be handled within fetch_indices().\n\nIndeed, sending out somewhat redundant HEAD requests is done pretty\noften; a separate patch/patch series should handle those.\n\n-- \nCheers,\nRay Chuan\n"}]}