{"thread":{"id":"19397","subject":"[PATCH 2/3] http*: add helper methods for fetching objects/info/packs","startedAt":"2009-05-18T08:14:22Z","lastAt":"2009-05-18T08:14:22Z","messageCount":1,"participants":["Tay Ray Chuan"],"isPatch":true,"patchVersion":1,"patchTotal":3},"messages":[{"id":"114165","messageId":"20090518161422.f42bc0e6.rctay89@gmail.com","threadId":"19397","inReplyTo":null,"subject":"[PATCH 2/3] http*: add helper methods for fetching objects/info/packs","fromName":"Tay Ray Chuan","fromEmail":"rctay89@gmail.com","sentAt":"2009-05-18T08:14:22Z","receivedAt":"2009-05-18T08:14:22Z","isPatch":true,"sender":{"key":"rctay89@gmail.com","avatar":"https://avatars.githubusercontent.com/u/61553?v=4"},"body":"The code handling the fetching of objects/info/packs in http-push.c and\nhttp-walker.c have been refactored into new methods and a new struct\nin http.c. They are not meant to be invoked elsewhere.\n\nThe new methods in http.c are\n *new_http_info_packs_request\n *finish_http_info_packs_request\n *release_http_info_packs_request\n\nand the new struct is http_info_packs_request.\n\nA callback function wraps the invocation of fetch_http_pack_index,\ninvoked in finish_http_info_packs_request when parsing info/packs.\n\nThe fetching code lives in three methods to accomodate http-walker.c's\nimplementation, which involves the variable repo->got_indices.\n\nSigned-off-by: Tay Ray Chuan <rctay89@gmail.com>\n---\n http-push.c   |   59 +++++++++++++++----------------------------------------\n http-walker.c |   59 ++++++++++++++++++------------------------------------\n http.c        |   61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n http.h        |   18 ++++++++++++++++\n 4 files changed, 115 insertions(+), 82 deletions(-)\n\ndiff --git a/http-push.c b/http-push.c\nindex 2694d16..3ded6ec 100644\n--- a/http-push.c\n+++ b/http-push.c\n@@ -895,67 +895,40 @@ static int add_send_request(struct object *obj, struct remote_lock *lock)\n \treturn 1;\n }\n \n-static int fetch_indices(void)\n+static void fetch_indices_request_callback(unsigned char *sha1,\n+\tvoid *callback_data)\n {\n-\tunsigned char sha1[20];\n-\tchar *url;\n-\tstruct strbuf buffer = STRBUF_INIT;\n-\tchar *data;\n-\tint i = 0;\n+\tfetch_http_pack_index(&repo->packs, sha1, repo->url);\n+}\n \n-\tstruct active_request_slot *slot;\n+static int fetch_indices(void)\n+{\n \tstruct slot_results results;\n+\tstruct http_info_packs_request *req;\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+\treq = new_http_info_packs_request(repo->url);\n+\treq->slot->results = &results;\n+\treq->callback_func = fetch_indices_request_callback;\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+\tif (start_active_slot(req->slot)) {\n+\t\trun_active_slot(req->slot);\n \t\tif (results.curl_result != CURLE_OK) {\n-\t\t\tstrbuf_release(&buffer);\n-\t\t\tfree(url);\n+\t\t\trelease_http_info_packs_request(req);\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\trelease_http_info_packs_request(req);\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\tfetch_http_pack_index(&repo->packs, sha1, repo->url);\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+\tfinish_http_info_packs_request(req);\n \n-\tstrbuf_release(&buffer);\n \treturn 0;\n }\n \ndiff --git a/http-walker.c b/http-walker.c\nindex 2b8097c..20be607 100644\n--- a/http-walker.c\n+++ b/http-walker.c\n@@ -563,17 +563,19 @@ static void fetch_alternates(struct walker *walker, const char *base)\n \tfree(url);\n }\n \n+static void fetch_indices_request_callback(unsigned char *sha1,\n+\tvoid *callback_data)\n+{\n+\tstruct alt_base *repo =\n+\t\t(struct alt_base *)callback_data;\n+\tfetch_http_pack_index(&repo->packs, sha1, repo->base);\n+}\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+\tstruct http_info_packs_request *req;\n \n \tif (repo->got_indices)\n \t\treturn 0;\n@@ -581,17 +583,14 @@ static int fetch_indices(struct walker *walker, struct alt_base *repo)\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+\treq = new_http_info_packs_request(repo->base);\n+\treq->slot->results = &results;\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+\treq->callback_data = (void *)repo;\n+\treq->callback_func = fetch_indices_request_callback;\n+\n+\tif (start_active_slot(req->slot)) {\n+\t\trun_active_slot(req->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@@ -608,30 +607,12 @@ static int fetch_indices(struct walker *walker, struct alt_base *repo)\n \t\tgoto cleanup;\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\tfetch_http_pack_index(&repo->packs, sha1, repo->base);\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+\tfinish_http_info_packs_request(req);\n \trepo->got_indices = 1;\n+\treturn 0;\n+\n cleanup:\n-\tstrbuf_release(&buffer);\n-\tfree(url);\n+\trelease_http_info_packs_request(req);\n \treturn ret;\n }\n \ndiff --git a/http.c b/http.c\nindex b11c082..37d72f8 100644\n--- a/http.c\n+++ b/http.c\n@@ -929,3 +929,64 @@ abort:\n \tfree(filename);\n \treturn NULL;\n }\n+\n+/* Helpers for fetching objects/info/packs */\n+void release_http_info_packs_request(struct http_info_packs_request *req)\n+{\n+\tstrbuf_release(req->buffer);\n+\tfree(req->url);\n+}\n+\n+void finish_http_info_packs_request(struct http_info_packs_request *req)\n+{\n+\tchar *data;\n+\tint i = 0;\n+\tunsigned char sha1[20];\n+\n+\tdata = req->buffer->buf;\n+\twhile (i < req->buffer->len) {\n+\t\tswitch (data[i]) {\n+\t\tcase 'P':\n+\t\t\ti++;\n+\t\t\tif (i + 52 <= req->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\treq->callback_func(sha1, req->callback_data);\n+\t\t\t\ti += 51;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\tdefault:\n+\t\t\twhile (i < req->buffer->len && data[i] != '\\n')\n+\t\t\t\ti++;\n+\t\t}\n+\t\ti++;\n+\t}\n+\n+\trelease_http_info_packs_request(req);\n+}\n+\n+struct http_info_packs_request *new_http_info_packs_request(const char *base_url)\n+{\n+\tchar *url;\n+\tstruct strbuf buf = STRBUF_INIT;\n+\tstruct http_info_packs_request *req;\n+\n+\treq = xmalloc(sizeof(*req));\n+\n+\treq->buffer = xmalloc(sizeof(*req->buffer));\n+\tstrbuf_init(req->buffer, 0);\n+\n+\tend_url_with_slash(&buf, base_url);\n+\tstrbuf_addstr(&buf, \"objects/info/packs\");\n+\turl = strbuf_detach(&buf, NULL);\n+\treq->url = xstrdup(url);\n+\n+\treq->slot = get_active_slot();\n+\tcurl_easy_setopt(req->slot->curl, CURLOPT_FILE, req->buffer);\n+\tcurl_easy_setopt(req->slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer);\n+\tcurl_easy_setopt(req->slot->curl, CURLOPT_URL, url);\n+\tcurl_easy_setopt(req->slot->curl, CURLOPT_HTTPHEADER, NULL);\n+\n+\treturn req;\n+}\ndiff --git a/http.h b/http.h\nindex c72bcc1..c4b1204 100644\n--- a/http.h\n+++ b/http.h\n@@ -137,4 +137,22 @@ extern struct http_pack_request *new_http_pack_request(\n extern int finish_http_pack_request(struct http_pack_request *preq);\n extern void release_http_pack_request(struct http_pack_request *preq);\n \n+/* Helpers for fetching objects/info/packs */\n+struct http_info_packs_request\n+{\n+\tchar *url;\n+\tstruct strbuf *buffer;\n+\tstruct active_request_slot *slot;\n+\n+\tvoid *callback_data;\n+\tvoid (*callback_func)(unsigned char *sha1, void *callback_data);\n+};\n+\n+extern struct http_info_packs_request *new_http_info_packs_request(\n+\tconst char *base_url);\n+extern void finish_http_info_packs_request(\n+\tstruct http_info_packs_request *req);\n+extern void release_http_info_packs_request(\n+\tstruct http_info_packs_request *req);\n+\n #endif /* HTTP_H */\n-- \n1.6.3.rc0\n"}]}