{"thread":{"id":"11231","subject":"[PATCH 4/5] Correctly initialize buffer in start_put() in http-push.c","startedAt":"2007-12-10T21:36:07Z","lastAt":"2007-12-11T20:00:30Z","messageCount":11,"participants":["Mike Hommey","Junio C Hamano","Andreas Ericsson"],"isPatch":true,"patchVersion":1,"patchTotal":5},"messages":[{"id":"62619","messageId":"1197322571-25023-1-git-send-email-mh@glandium.org","threadId":"11231","inReplyTo":null,"subject":"[PATCH 1/5] Remove the default_headers variable from http-push.c","fromName":"Mike Hommey","fromEmail":"mh@glandium.org","sentAt":"2007-12-10T21:36:07Z","receivedAt":"2007-12-10T21:36:07Z","isPatch":true,"sender":{"key":"mh@glandium.org","avatar":"https://avatars.githubusercontent.com/u/1038527?v=4"},"body":"It appears that despite being initialized, it was never used.\n\nSigned-off-by: Mike Hommey <mh@glandium.org>\n---\n http-push.c |    7 -------\n 1 files changed, 0 insertions(+), 7 deletions(-)\n\ndiff --git a/http-push.c b/http-push.c\nindex a69d0e3..2ef764c 100644\n--- a/http-push.c\n+++ b/http-push.c\n@@ -75,7 +75,6 @@ static int aborted;\n static signed char remote_dir_exists[256];\n \n static struct curl_slist *no_pragma_header;\n-static struct curl_slist *default_headers;\n \n static int push_verbosely;\n static int push_all = MATCH_REFS_NONE;\n@@ -2286,11 +2285,6 @@ int main(int argc, char **argv)\n \thttp_init();\n \n \tno_pragma_header = curl_slist_append(no_pragma_header, \"Pragma:\");\n-\tdefault_headers = curl_slist_append(default_headers, \"Range:\");\n-\tdefault_headers = curl_slist_append(default_headers, \"Destination:\");\n-\tdefault_headers = curl_slist_append(default_headers, \"If:\");\n-\tdefault_headers = curl_slist_append(default_headers,\n-\t\t\t\t\t    \"Pragma: no-cache\");\n \n \t/* Verify DAV compliance/lock support */\n \tif (!locking_available()) {\n@@ -2470,7 +2464,6 @@ int main(int argc, char **argv)\n \tfree(remote);\n \n \tcurl_slist_free_all(no_pragma_header);\n-\tcurl_slist_free_all(default_headers);\n \n \thttp_cleanup();\n \n-- \n1.5.3.7.1159.gdd4a4\n"},{"id":"62621","messageId":"1197322571-25023-2-git-send-email-mh@glandium.org","threadId":"11231","inReplyTo":"1197322571-25023-1-git-send-email-mh@glandium.org","subject":"[PATCH 2/5] Remove a CURLOPT_HTTPHEADER (un)setting","fromName":"Mike Hommey","fromEmail":"mh@glandium.org","sentAt":"2007-12-10T21:36:08Z","receivedAt":"2007-12-10T21:36:08Z","isPatch":true,"sender":{"key":"mh@glandium.org","avatar":"https://avatars.githubusercontent.com/u/1038527?v=4"},"body":"Setting CURLOPT_HTTPHEADER doesn't add HTTP headers, but replaces whatever\nset of headers was configured before, so setting to NULL doesn't have any\nmagic meaning, and is pretty much useless when setting to another list\nright after.\n\nSigned-off-by: Mike Hommey <mh@glandium.org>\n---\n http.c |    1 -\n 1 files changed, 0 insertions(+), 1 deletions(-)\n\ndiff --git a/http.c b/http.c\nindex 2d0b46d..784b93e 100644\n--- a/http.c\n+++ b/http.c\n@@ -364,7 +364,6 @@ struct active_request_slot *get_active_slot(void)\n \tslot->finished = NULL;\n \tslot->callback_data = NULL;\n \tslot->callback_func = NULL;\n-\tcurl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, NULL);\n \tcurl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, pragma_header);\n \tcurl_easy_setopt(slot->curl, CURLOPT_ERRORBUFFER, curl_errorstr);\n \tcurl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, NULL);\n-- \n1.5.3.7.1159.gdd4a4\n"},{"id":"62620","messageId":"1197322571-25023-3-git-send-email-mh@glandium.org","threadId":"11231","inReplyTo":"1197322571-25023-2-git-send-email-mh@glandium.org","subject":"[PATCH 3/5] Avoid redundant declaration of missing_target()","fromName":"Mike Hommey","fromEmail":"mh@glandium.org","sentAt":"2007-12-10T21:36:09Z","receivedAt":"2007-12-10T21:36:09Z","isPatch":true,"sender":{"key":"mh@glandium.org","avatar":"https://avatars.githubusercontent.com/u/1038527?v=4"},"body":"Signed-off-by: Mike Hommey <mh@glandium.org>\n---\n\nI though it's also small enough to grant inlining.\n\n http-walker.c |   13 -------------\n http.h        |   13 +++++++++++++\n transport.c   |   13 -------------\n 3 files changed, 13 insertions(+), 26 deletions(-)\n\ndiff --git a/http-walker.c b/http-walker.c\nindex d9a5f1e..8dbf9cc 100644\n--- a/http-walker.c\n+++ b/http-walker.c\n@@ -90,19 +90,6 @@ static size_t fwrite_sha1_file(void *ptr, size_t eltsize, size_t nmemb,\n \treturn size;\n }\n \n-static int missing__target(int code, int result)\n-{\n-\treturn\t/* file:// URL -- do we ever use one??? */\n-\t\t(result == CURLE_FILE_COULDNT_READ_FILE) ||\n-\t\t/* http:// and https:// URL */\n-\t\t(code == 404 && result == CURLE_HTTP_RETURNED_ERROR) ||\n-\t\t/* ftp:// URL */\n-\t\t(code == 550 && result == CURLE_FTP_COULDNT_RETR_FILE)\n-\t\t;\n-}\n-\n-#define missing_target(a) missing__target((a)->http_code, (a)->curl_result)\n-\n static void fetch_alternates(struct walker *walker, const char *base);\n \n static void process_object_response(void *callback_data);\ndiff --git a/http.h b/http.h\nindex a0fb4cf..87d638b 100644\n--- a/http.h\n+++ b/http.h\n@@ -83,4 +83,17 @@ extern int active_requests;\n \n extern char curl_errorstr[CURL_ERROR_SIZE];\n \n+static inline int missing__target(int code, int result)\n+{\n+\treturn\t/* file:// URL -- do we ever use one??? */\n+\t\t(result == CURLE_FILE_COULDNT_READ_FILE) ||\n+\t\t/* http:// and https:// URL */\n+\t\t(code == 404 && result == CURLE_HTTP_RETURNED_ERROR) ||\n+\t\t/* ftp:// URL */\n+\t\t(code == 550 && result == CURLE_FTP_COULDNT_RETR_FILE)\n+\t\t;\n+}\n+\n+#define missing_target(a) missing__target((a)->http_code, (a)->curl_result)\n+\n #endif /* HTTP_H */\ndiff --git a/transport.c b/transport.c\nindex 22234e8..4e151a9 100644\n--- a/transport.c\n+++ b/transport.c\n@@ -426,19 +426,6 @@ static int curl_transport_push(struct transport *transport, int refspec_nr, cons\n \treturn !!err;\n }\n \n-static int missing__target(int code, int result)\n-{\n-\treturn\t/* file:// URL -- do we ever use one??? */\n-\t\t(result == CURLE_FILE_COULDNT_READ_FILE) ||\n-\t\t/* http:// and https:// URL */\n-\t\t(code == 404 && result == CURLE_HTTP_RETURNED_ERROR) ||\n-\t\t/* ftp:// URL */\n-\t\t(code == 550 && result == CURLE_FTP_COULDNT_RETR_FILE)\n-\t\t;\n-}\n-\n-#define missing_target(a) missing__target((a)->http_code, (a)->curl_result)\n-\n static struct ref *get_refs_via_curl(struct transport *transport)\n {\n \tstruct strbuf buffer = STRBUF_INIT;\n-- \n1.5.3.7.1159.gdd4a4\n"},{"id":"62618","messageId":"1197322571-25023-4-git-send-email-mh@glandium.org","threadId":"11231","inReplyTo":"1197322571-25023-3-git-send-email-mh@glandium.org","subject":"[PATCH 4/5] Correctly initialize buffer in start_put() in http-push.c","fromName":"Mike Hommey","fromEmail":"mh@glandium.org","sentAt":"2007-12-10T21:36:10Z","receivedAt":"2007-12-10T21:36:10Z","isPatch":true,"sender":{"key":"mh@glandium.org","avatar":"https://avatars.githubusercontent.com/u/1038527?v=4"},"body":"Brown paper bag fix to avoid random misbehaviour.\n\nSigned-off-by: Mike Hommey <mh@glandium.org>\n---\n\n This is a brown paper bag fix for my strbuf patch for the http code.\n\n http-push.c |    1 +\n 1 files changed, 1 insertions(+), 0 deletions(-)\n\ndiff --git a/http-push.c b/http-push.c\nindex 2ef764c..ad8167e 100644\n--- a/http-push.c\n+++ b/http-push.c\n@@ -495,6 +495,7 @@ static void start_put(struct transfer_request *request)\n \tdeflateInit(&stream, zlib_compression_level);\n \tsize = deflateBound(&stream, len + hdrlen);\n \tstrbuf_init(&request->buffer.buf, size);\n+\trequest->buffer.posn = 0;\n \n \t/* Compress it */\n \tstream.next_out = (unsigned char *)request->buffer.buf.buf;\n-- \n1.5.3.7.1159.gdd4a4\n"},{"id":"62622","messageId":"1197322571-25023-5-git-send-email-mh@glandium.org","threadId":"11231","inReplyTo":"1197322571-25023-4-git-send-email-mh@glandium.org","subject":"[PATCH 5/5] Fix various memory leaks in http-push.c and http-walker.c","fromName":"Mike Hommey","fromEmail":"mh@glandium.org","sentAt":"2007-12-10T21:36:11Z","receivedAt":"2007-12-10T21:36:11Z","isPatch":true,"sender":{"key":"mh@glandium.org","avatar":"https://avatars.githubusercontent.com/u/1038527?v=4"},"body":"\nSigned-off-by: Mike Hommey <mh@glandium.org>\n---\n\n This one, too, sits on top of my strbuf patch for the http code. Note that\n I only went for the obvious ones I saw in the code I touched. There is more\n in these files.\n\n http-push.c   |   32 +++++++++++++++++++++-----------\n http-walker.c |   40 +++++++++++++++++++++++++---------------\n 2 files changed, 46 insertions(+), 26 deletions(-)\n\ndiff --git a/http-push.c b/http-push.c\nindex ad8167e..610ed9c 100644\n--- a/http-push.c\n+++ b/http-push.c\n@@ -924,6 +924,7 @@ static int fetch_index(unsigned char *sha1)\n \t\t\t\t     hex);\n \t\t}\n \t} else {\n+\t\tfree(url);\n \t\treturn error(\"Unable to start request\");\n \t}\n \n@@ -1114,6 +1115,7 @@ int fetch_ref(char *ref, unsigned char *sha1)\n \tchar *base = remote->url;\n \tstruct active_request_slot *slot;\n \tstruct slot_results results;\n+\tint ret;\n \n \turl = quote_ref_url(base, ref);\n \tslot = get_active_slot();\n@@ -1124,17 +1126,23 @@ int fetch_ref(char *ref, unsigned char *sha1)\n \tcurl_easy_setopt(slot->curl, CURLOPT_URL, url);\n \tif (start_active_slot(slot)) {\n \t\trun_active_slot(slot);\n-\t\tif (results.curl_result != CURLE_OK)\n-\t\t\treturn error(\"Couldn't get %s for %s\\n%s\",\n-\t\t\t\t     url, ref, curl_errorstr);\n+\t\tif (results.curl_result == CURLE_OK) {\n+\t\t\tstrbuf_rtrim(&buffer);\n+\t\t\tif (buffer.len == 40)\n+\t\t\t\tret = get_sha1_hex(buffer.buf, sha1);\n+\t\t\telse\n+\t\t\t\tret = 1;\n+\t\t} else {\n+\t\t\tret = error(\"Couldn't get %s for %s\\n%s\",\n+\t\t\t\t    url, ref, curl_errorstr);\n+\t\t}\n \t} else {\n-\t\treturn error(\"Unable to start request\");\n+\t\tret = error(\"Unable to start request\");\n \t}\n \n-\tstrbuf_rtrim(&buffer);\n-\tif (buffer.len != 40)\n-\t\treturn 1;\n-\treturn get_sha1_hex(buffer.buf, sha1);\n+\tstrbuf_release(&buffer);\n+\tfree(url);\n+\treturn ret;\n }\n \n static void one_remote_object(const char *hex)\n@@ -2033,6 +2041,7 @@ static int remote_exists(const char *path)\n \tchar *url = xmalloc(strlen(remote->url) + strlen(path) + 1);\n \tstruct active_request_slot *slot;\n \tstruct slot_results results;\n+\tint ret = -1;\n \n \tsprintf(url, \"%s%s\", remote->url, path);\n \n@@ -2044,16 +2053,17 @@ static int remote_exists(const char *path)\n \tif (start_active_slot(slot)) {\n \t\trun_active_slot(slot);\n \t\tif (results.http_code == 404)\n-\t\t\treturn 0;\n+\t\t\tret = 0;\n \t\telse if (results.curl_result == CURLE_OK)\n-\t\t\treturn 1;\n+\t\t\tret = 1;\n \t\telse\n \t\t\tfprintf(stderr, \"HEAD HTTP error %ld\\n\", results.http_code);\n \t} else {\n \t\tfprintf(stderr, \"Unable to start HEAD request\\n\");\n \t}\n \n-\treturn -1;\n+\tfree(url);\n+\treturn ret;\n }\n \n static void fetch_symref(const char *path, char **symref, unsigned char *sha1)\ndiff --git a/http-walker.c b/http-walker.c\nindex 8dbf9cc..4e878b3 100644\n--- a/http-walker.c\n+++ b/http-walker.c\n@@ -644,6 +644,7 @@ static int fetch_indices(struct walker *walker, struct alt_base *repo)\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@@ -666,19 +667,19 @@ static int fetch_indices(struct walker *walker, struct alt_base *repo)\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\tif (missing_target(&results)) {\n \t\t\t\trepo->got_indices = 1;\n-\t\t\t\treturn 0;\n+\t\t\t\tgoto cleanup;\n \t\t\t} else {\n \t\t\t\trepo->got_indices = 0;\n-\t\t\t\treturn error(\"%s\", curl_errorstr);\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 \t\trepo->got_indices = 0;\n-\t\tstrbuf_release(&buffer);\n-\t\treturn error(\"Unable to start request\");\n+\t\tret = error(\"Unable to start request\");\n+\t\tgoto cleanup;\n \t}\n \n \tdata = buffer.buf;\n@@ -701,9 +702,11 @@ static int fetch_indices(struct walker *walker, struct alt_base *repo)\n \t\ti++;\n \t}\n \n-\tstrbuf_release(&buffer);\n \trepo->got_indices = 1;\n-\treturn 0;\n+cleanup:\n+\tstrbuf_release(&buffer);\n+\tfree(url);\n+\treturn ret;\n }\n \n static int fetch_pack(struct walker *walker, struct alt_base *repo, unsigned char *sha1)\n@@ -939,6 +942,7 @@ static int fetch_ref(struct walker *walker, char *ref, unsigned char *sha1)\n \tconst char *base = data->alt->base;\n \tstruct active_request_slot *slot;\n \tstruct slot_results results;\n+\tint ret;\n \n \turl = quote_ref_url(base, ref);\n \tslot = get_active_slot();\n@@ -949,17 +953,23 @@ static int fetch_ref(struct walker *walker, char *ref, unsigned char *sha1)\n \tcurl_easy_setopt(slot->curl, CURLOPT_URL, url);\n \tif (start_active_slot(slot)) {\n \t\trun_active_slot(slot);\n-\t\tif (results.curl_result != CURLE_OK)\n-\t\t\treturn error(\"Couldn't get %s for %s\\n%s\",\n-\t\t\t\t     url, ref, curl_errorstr);\n+\t\tif (results.curl_result == CURLE_OK) {\n+\t\t\tstrbuf_rtrim(&buffer);\n+\t\t\tif (buffer.len == 40)\n+\t\t\t\tret = get_sha1_hex(buffer.buf, sha1);\n+\t\t\telse\n+\t\t\t\tret = 1;\n+\t\t} else {\n+\t\t\tret = error(\"Couldn't get %s for %s\\n%s\",\n+\t\t\t\t    url, ref, curl_errorstr);\n+\t\t}\n \t} else {\n-\t\treturn error(\"Unable to start request\");\n+\t\tret = error(\"Unable to start request\");\n \t}\n \n-\tstrbuf_rtrim(&buffer);\n-\tif (buffer.len != 40)\n-\t\treturn 1;\n-\treturn get_sha1_hex(buffer.buf, sha1);\n+\tstrbuf_release(&buffer);\n+\tfree(url);\n+\treturn ret;\n }\n \n static void cleanup(struct walker *walker)\n-- \n1.5.3.7.1159.gdd4a4\n"},{"id":"62630","messageId":"1197328105-4843-1-git-send-email-mh@glandium.org","threadId":"11231","inReplyTo":"1197322571-25023-5-git-send-email-mh@glandium.org","subject":"[PATCH 6/5] Move fetch_ref from http-push.c and http-walker.c to http.c","fromName":"Mike Hommey","fromEmail":"mh@glandium.org","sentAt":"2007-12-10T23:08:25Z","receivedAt":"2007-12-10T23:08:25Z","isPatch":true,"sender":{"key":"mh@glandium.org","avatar":"https://avatars.githubusercontent.com/u/1038527?v=4"},"body":"Make the necessary changes to be ok with their difference, and rename the\nfunction http_fetch_ref.\n\nSigned-off-by: Mike Hommey <mh@glandium.org>\n---\n http-push.c   |   88 ++------------------------------------------------------\n http-walker.c |   80 +---------------------------------------------------\n http.c        |   82 +++++++++++++++++++++++++++++++++++++++++++++++++++++\n http.h        |    2 +\n 4 files changed, 89 insertions(+), 163 deletions(-)\n\ndiff --git a/http-push.c b/http-push.c\nindex 610ed9c..a4a9d1c 100644\n--- a/http-push.c\n+++ b/http-push.c\n@@ -1063,88 +1063,6 @@ static int fetch_indices(void)\n \treturn 0;\n }\n \n-static inline int needs_quote(int ch)\n-{\n-\tif (((ch >= 'A') && (ch <= 'Z'))\n-\t\t\t|| ((ch >= 'a') && (ch <= 'z'))\n-\t\t\t|| ((ch >= '0') && (ch <= '9'))\n-\t\t\t|| (ch == '/')\n-\t\t\t|| (ch == '-')\n-\t\t\t|| (ch == '.'))\n-\t\treturn 0;\n-\treturn 1;\n-}\n-\n-static inline int hex(int v)\n-{\n-\tif (v < 10) return '0' + v;\n-\telse return 'A' + v - 10;\n-}\n-\n-static char *quote_ref_url(const char *base, const char *ref)\n-{\n-\tconst char *cp;\n-\tchar *dp, *qref;\n-\tint len, baselen, ch;\n-\n-\tbaselen = strlen(base);\n-\tlen = baselen + 1;\n-\tfor (cp = ref; (ch = *cp) != 0; cp++, len++)\n-\t\tif (needs_quote(ch))\n-\t\t\tlen += 2; /* extra two hex plus replacement % */\n-\tqref = xmalloc(len);\n-\tmemcpy(qref, base, baselen);\n-\tfor (cp = ref, dp = qref + baselen; (ch = *cp) != 0; cp++) {\n-\t\tif (needs_quote(ch)) {\n-\t\t\t*dp++ = '%';\n-\t\t\t*dp++ = hex((ch >> 4) & 0xF);\n-\t\t\t*dp++ = hex(ch & 0xF);\n-\t\t}\n-\t\telse\n-\t\t\t*dp++ = ch;\n-\t}\n-\t*dp = 0;\n-\n-\treturn qref;\n-}\n-\n-int fetch_ref(char *ref, unsigned char *sha1)\n-{\n-\tchar *url;\n-\tstruct strbuf buffer = STRBUF_INIT;\n-\tchar *base = remote->url;\n-\tstruct active_request_slot *slot;\n-\tstruct slot_results results;\n-\tint ret;\n-\n-\turl = quote_ref_url(base, ref);\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_HTTPHEADER, NULL);\n-\tcurl_easy_setopt(slot->curl, CURLOPT_URL, url);\n-\tif (start_active_slot(slot)) {\n-\t\trun_active_slot(slot);\n-\t\tif (results.curl_result == CURLE_OK) {\n-\t\t\tstrbuf_rtrim(&buffer);\n-\t\t\tif (buffer.len == 40)\n-\t\t\t\tret = get_sha1_hex(buffer.buf, sha1);\n-\t\t\telse\n-\t\t\t\tret = 1;\n-\t\t} else {\n-\t\t\tret = error(\"Couldn't get %s for %s\\n%s\",\n-\t\t\t\t    url, ref, curl_errorstr);\n-\t\t}\n-\t} else {\n-\t\tret = error(\"Unable to start request\");\n-\t}\n-\n-\tstrbuf_release(&buffer);\n-\tfree(url);\n-\treturn ret;\n-}\n-\n static void one_remote_object(const char *hex)\n {\n \tunsigned char sha1[20];\n@@ -1827,7 +1745,8 @@ static void one_remote_ref(char *refname)\n \tstruct object *obj;\n \tint len = strlen(refname) + 1;\n \n-\tif (fetch_ref(refname, remote_sha1) != 0) {\n+\tif (http_fetch_ref(remote->url, refname + 5 /* \"refs/\" */,\n+\t\t\t   remote_sha1) != 0) {\n \t\tfprintf(stderr,\n \t\t\t\"Unable to fetch ref %s from %s\\n\",\n \t\t\trefname, remote->url);\n@@ -1959,7 +1878,8 @@ static void add_remote_info_ref(struct remote_ls_ctx *ls)\n \tint len;\n \tchar *ref_info;\n \n-\tif (fetch_ref(ls->dentry_name, remote_sha1) != 0) {\n+\tif (http_fetch_ref(remote->url, ls->dentry_name + 5 /* \"refs/\" */,\n+\t\t\t   remote_sha1) != 0) {\n \t\tfprintf(stderr,\n \t\t\t\"Unable to fetch ref %s from %s\\n\",\n \t\t\tls->dentry_name, remote->url);\ndiff --git a/http-walker.c b/http-walker.c\nindex 4e878b3..2c37868 100644\n--- a/http-walker.c\n+++ b/http-walker.c\n@@ -888,88 +888,10 @@ static int fetch(struct walker *walker, unsigned char *sha1)\n \t\t     data->alt->base);\n }\n \n-static inline int needs_quote(int ch)\n-{\n-\tif (((ch >= 'A') && (ch <= 'Z'))\n-\t\t\t|| ((ch >= 'a') && (ch <= 'z'))\n-\t\t\t|| ((ch >= '0') && (ch <= '9'))\n-\t\t\t|| (ch == '/')\n-\t\t\t|| (ch == '-')\n-\t\t\t|| (ch == '.'))\n-\t\treturn 0;\n-\treturn 1;\n-}\n-\n-static inline int hex(int v)\n-{\n-\tif (v < 10) return '0' + v;\n-\telse return 'A' + v - 10;\n-}\n-\n-static char *quote_ref_url(const char *base, const char *ref)\n-{\n-\tconst char *cp;\n-\tchar *dp, *qref;\n-\tint len, baselen, ch;\n-\n-\tbaselen = strlen(base);\n-\tlen = baselen + 7; /* \"/refs/\" + NUL */\n-\tfor (cp = ref; (ch = *cp) != 0; cp++, len++)\n-\t\tif (needs_quote(ch))\n-\t\t\tlen += 2; /* extra two hex plus replacement % */\n-\tqref = xmalloc(len);\n-\tmemcpy(qref, base, baselen);\n-\tmemcpy(qref + baselen, \"/refs/\", 6);\n-\tfor (cp = ref, dp = qref + baselen + 6; (ch = *cp) != 0; cp++) {\n-\t\tif (needs_quote(ch)) {\n-\t\t\t*dp++ = '%';\n-\t\t\t*dp++ = hex((ch >> 4) & 0xF);\n-\t\t\t*dp++ = hex(ch & 0xF);\n-\t\t}\n-\t\telse\n-\t\t\t*dp++ = ch;\n-\t}\n-\t*dp = 0;\n-\n-\treturn qref;\n-}\n-\n static int fetch_ref(struct walker *walker, char *ref, unsigned char *sha1)\n {\n-\tchar *url;\n-\tstruct strbuf buffer = STRBUF_INIT;\n \tstruct walker_data *data = walker->data;\n-\tconst char *base = data->alt->base;\n-\tstruct active_request_slot *slot;\n-\tstruct slot_results results;\n-\tint ret;\n-\n-\turl = quote_ref_url(base, ref);\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_HTTPHEADER, NULL);\n-\tcurl_easy_setopt(slot->curl, CURLOPT_URL, url);\n-\tif (start_active_slot(slot)) {\n-\t\trun_active_slot(slot);\n-\t\tif (results.curl_result == CURLE_OK) {\n-\t\t\tstrbuf_rtrim(&buffer);\n-\t\t\tif (buffer.len == 40)\n-\t\t\t\tret = get_sha1_hex(buffer.buf, sha1);\n-\t\t\telse\n-\t\t\t\tret = 1;\n-\t\t} else {\n-\t\t\tret = error(\"Couldn't get %s for %s\\n%s\",\n-\t\t\t\t    url, ref, curl_errorstr);\n-\t\t}\n-\t} else {\n-\t\tret = error(\"Unable to start request\");\n-\t}\n-\n-\tstrbuf_release(&buffer);\n-\tfree(url);\n-\treturn ret;\n+\treturn http_fetch_ref(data->alt->base, ref, sha1);\n }\n \n static void cleanup(struct walker *walker)\ndiff --git a/http.c b/http.c\nindex 784b93e..c6de964 100644\n--- a/http.c\n+++ b/http.c\n@@ -552,3 +552,85 @@ void finish_all_active_slots(void)\n \t\t\tslot = slot->next;\n \t\t}\n }\n+\n+static inline int needs_quote(int ch)\n+{\n+\tif (((ch >= 'A') && (ch <= 'Z'))\n+\t\t\t|| ((ch >= 'a') && (ch <= 'z'))\n+\t\t\t|| ((ch >= '0') && (ch <= '9'))\n+\t\t\t|| (ch == '/')\n+\t\t\t|| (ch == '-')\n+\t\t\t|| (ch == '.'))\n+\t\treturn 0;\n+\treturn 1;\n+}\n+\n+static inline int hex(int v)\n+{\n+\tif (v < 10) return '0' + v;\n+\telse return 'A' + v - 10;\n+}\n+\n+static char *quote_ref_url(const char *base, const char *ref)\n+{\n+\tconst char *cp;\n+\tchar *dp, *qref;\n+\tint len, baselen, ch;\n+\n+\tbaselen = strlen(base);\n+\tlen = baselen + 7; /* \"/refs/\" + NUL */\n+\tfor (cp = ref; (ch = *cp) != 0; cp++, len++)\n+\t\tif (needs_quote(ch))\n+\t\t\tlen += 2; /* extra two hex plus replacement % */\n+\tqref = xmalloc(len);\n+\tmemcpy(qref, base, baselen);\n+\tmemcpy(qref + baselen, \"/refs/\", 6);\n+\tfor (cp = ref, dp = qref + baselen + 6; (ch = *cp) != 0; cp++) {\n+\t\tif (needs_quote(ch)) {\n+\t\t\t*dp++ = '%';\n+\t\t\t*dp++ = hex((ch >> 4) & 0xF);\n+\t\t\t*dp++ = hex(ch & 0xF);\n+\t\t}\n+\t\telse\n+\t\t\t*dp++ = ch;\n+\t}\n+\t*dp = 0;\n+\n+\treturn qref;\n+}\n+\n+int http_fetch_ref(const char *base, const char *ref, unsigned char *sha1)\n+{\n+\tchar *url;\n+\tstruct strbuf buffer = STRBUF_INIT;\n+\tstruct active_request_slot *slot;\n+\tstruct slot_results results;\n+\tint ret;\n+\n+\turl = quote_ref_url(base, ref);\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_HTTPHEADER, NULL);\n+\tcurl_easy_setopt(slot->curl, CURLOPT_URL, url);\n+\tif (start_active_slot(slot)) {\n+\t\trun_active_slot(slot);\n+\t\tif (results.curl_result == CURLE_OK) {\n+\t\t\tstrbuf_rtrim(&buffer);\n+\t\t\tif (buffer.len == 40)\n+\t\t\t\tret = get_sha1_hex(buffer.buf, sha1);\n+\t\t\telse\n+\t\t\t\tret = 1;\n+\t\t} else {\n+\t\t\tret = error(\"Couldn't get %s for %s\\n%s\",\n+\t\t\t\t    url, ref, curl_errorstr);\n+\t\t}\n+\t} else {\n+\t\tret = error(\"Unable to start request\");\n+\t}\n+\n+\tstrbuf_release(&buffer);\n+\tfree(url);\n+\treturn ret;\n+}\ndiff --git a/http.h b/http.h\nindex 87d638b..b709222 100644\n--- a/http.h\n+++ b/http.h\n@@ -96,4 +96,6 @@ static inline int missing__target(int code, int result)\n \n #define missing_target(a) missing__target((a)->http_code, (a)->curl_result)\n \n+extern int http_fetch_ref(const char *base, const char *ref, unsigned char *sha1);\n+\n #endif /* HTTP_H */\n-- \n1.5.3.7.1160.g1e7a-dirty\n"},{"id":"62649","messageId":"7vve75hl72.fsf@gitster.siamese.dyndns.org","threadId":"11231","inReplyTo":"1197328105-4843-1-git-send-email-mh@glandium.org","subject":"Re: [PATCH 6/5] Move fetch_ref from http-push.c and http-walker.c to http.c","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-12-11T05:09:05Z","receivedAt":"2007-12-11T05:09:05Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Mike Hommey <mh@glandium.org> writes:\n\n> Make the necessary changes to be ok with their difference, and rename the\n> function http_fetch_ref.\n\nSorry, but I cannot parse \"ok with their difference\" part...\n"},{"id":"62661","messageId":"20071211062129.GA8372@glandium.org","threadId":"11231","inReplyTo":"7vve75hl72.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH 6/5] Move fetch_ref from http-push.c and http-walker.c to http.c","fromName":"Mike Hommey","fromEmail":"mh@glandium.org","sentAt":"2007-12-11T06:21:29Z","receivedAt":"2007-12-11T06:21:29Z","isPatch":true,"sender":{"key":"mh@glandium.org","avatar":"https://avatars.githubusercontent.com/u/1038527?v=4"},"body":"On Mon, Dec 10, 2007 at 09:09:05PM -0800, Junio C Hamano wrote:\n> Mike Hommey <mh@glandium.org> writes:\n> \n> > Make the necessary changes to be ok with their difference, and rename the\n> > function http_fetch_ref.\n> \n> Sorry, but I cannot parse \"ok with their difference\" part...\n\nWhat about \"to fit with their difference\" ?\n\nMike\n"},{"id":"62678","messageId":"475E3AA0.5010901@op5.se","threadId":"11231","inReplyTo":"20071211062129.GA8372@glandium.org","subject":"Re: [PATCH 6/5] Move fetch_ref from http-push.c and http-walker.c to http.c","fromName":"Andreas Ericsson","fromEmail":"ae@op5.se","sentAt":"2007-12-11T07:22:08Z","receivedAt":"2007-12-11T07:22:08Z","isPatch":true,"sender":{"key":"ae@op5.se","avatar":"https://gravatar.com/avatar/426e89595c75a8f5252dd0c989e5fabe5bcac616e68557427ad9aef6b0ca342a?d=mp&s=160"},"body":"Mike Hommey wrote:\n> On Mon, Dec 10, 2007 at 09:09:05PM -0800, Junio C Hamano wrote:\n>> Mike Hommey <mh@glandium.org> writes:\n>>\n>>> Make the necessary changes to be ok with their difference, and rename the\n>>> function http_fetch_ref.\n>> Sorry, but I cannot parse \"ok with their difference\" part...\n> \n> What about \"to fit with their difference\" ?\n> \n\nDefine \"their\" and \"difference\". Implicitly referring to another commit\nmessage won't help cursory glances much (and I have no idea what you're\ntalking about since I didn't read the rest of your series very carefully).\n\n-- \nAndreas Ericsson                   andreas.ericsson@op5.se\nOP5 AB                             www.op5.se\nTel: +46 8-230225                  Fax: +46 8-230231\n"},{"id":"62681","messageId":"20071211074931.GB12959@glandium.org","threadId":"11231","inReplyTo":"475E3AA0.5010901@op5.se","subject":"Re: [PATCH 6/5] Move fetch_ref from http-push.c and http-walker.c to http.c","fromName":"Mike Hommey","fromEmail":"mh@glandium.org","sentAt":"2007-12-11T07:49:31Z","receivedAt":"2007-12-11T07:49:31Z","isPatch":true,"sender":{"key":"mh@glandium.org","avatar":"https://avatars.githubusercontent.com/u/1038527?v=4"},"body":"On Tue, Dec 11, 2007 at 08:22:08AM +0100, Andreas Ericsson wrote:\n> Mike Hommey wrote:\n>> On Mon, Dec 10, 2007 at 09:09:05PM -0800, Junio C Hamano wrote:\n>>> Mike Hommey <mh@glandium.org> writes:\n>>>\n>>>> Make the necessary changes to be ok with their difference, and rename the\n>>>> function http_fetch_ref.\n>>> Sorry, but I cannot parse \"ok with their difference\" part...\n>>\n>> What about \"to fit with their difference\" ?\n>>\n>\n> Define \"their\" and \"difference\". Implicitly referring to another commit\n> message won't help cursory glances much (and I have no idea what you're\n> talking about since I didn't read the rest of your series very carefully).\n\nThe rest of the series doesn't have anything to do with this one, except\nthat fetch_ref had been modified to use strbuf in both.\n\nTheir difference is that one would take a ref with \"refs/\" at the\nbeginning and the other wouldn't. I'll try to write a better commit\nmessage later today.\n\nMike\n"},{"id":"62788","messageId":"1197403230-16863-1-git-send-email-mh@glandium.org","threadId":"11231","inReplyTo":"20071211074931.GB12959@glandium.org","subject":"[New PATCH] Move fetch_ref from http-push.c and http-walker.c to http.c","fromName":"Mike Hommey","fromEmail":"mh@glandium.org","sentAt":"2007-12-11T20:00:30Z","receivedAt":"2007-12-11T20:00:30Z","isPatch":true,"sender":{"key":"mh@glandium.org","avatar":"https://avatars.githubusercontent.com/u/1038527?v=4"},"body":"Call the moved function http_fetch_ref instead.\nAlso move needs_quote, hex and quote_ref_url altogether.\n\nBoth implementations had a slight difference, so it is not only code moving:\n\n- fetch_ref in http-push.c expects the ref to include \"refs/\" at the\n  beginning of its name, and gets the base url from a global variable.\n- fetch_ref in http-walker.c expects the ref to *not* include \"refs/\" at\n  the beginning (quote_ref_url would add it back), and gets the base url\n  from a struct walker * argument.\n\nSo we actually leave a fetch_ref wrapper function in http-walker.c that\ncalls the new http_fetch_ref with the proper arguments. In http-push.c,\nwe just change the only 2 callers to use the new function, with \"refs/\"\nremoved from the ref argument.\n\nSigned-off-by: Mike Hommey <mh@glandium.org>\n---\n\n  Only change is the commit message.\n\n http-push.c   |   88 ++------------------------------------------------------\n http-walker.c |   80 +---------------------------------------------------\n http.c        |   82 +++++++++++++++++++++++++++++++++++++++++++++++++++++\n http.h        |    2 +\n 4 files changed, 89 insertions(+), 163 deletions(-)\n\ndiff --git a/http-push.c b/http-push.c\nindex 610ed9c..a4a9d1c 100644\n--- a/http-push.c\n+++ b/http-push.c\n@@ -1063,88 +1063,6 @@ static int fetch_indices(void)\n \treturn 0;\n }\n \n-static inline int needs_quote(int ch)\n-{\n-\tif (((ch >= 'A') && (ch <= 'Z'))\n-\t\t\t|| ((ch >= 'a') && (ch <= 'z'))\n-\t\t\t|| ((ch >= '0') && (ch <= '9'))\n-\t\t\t|| (ch == '/')\n-\t\t\t|| (ch == '-')\n-\t\t\t|| (ch == '.'))\n-\t\treturn 0;\n-\treturn 1;\n-}\n-\n-static inline int hex(int v)\n-{\n-\tif (v < 10) return '0' + v;\n-\telse return 'A' + v - 10;\n-}\n-\n-static char *quote_ref_url(const char *base, const char *ref)\n-{\n-\tconst char *cp;\n-\tchar *dp, *qref;\n-\tint len, baselen, ch;\n-\n-\tbaselen = strlen(base);\n-\tlen = baselen + 1;\n-\tfor (cp = ref; (ch = *cp) != 0; cp++, len++)\n-\t\tif (needs_quote(ch))\n-\t\t\tlen += 2; /* extra two hex plus replacement % */\n-\tqref = xmalloc(len);\n-\tmemcpy(qref, base, baselen);\n-\tfor (cp = ref, dp = qref + baselen; (ch = *cp) != 0; cp++) {\n-\t\tif (needs_quote(ch)) {\n-\t\t\t*dp++ = '%';\n-\t\t\t*dp++ = hex((ch >> 4) & 0xF);\n-\t\t\t*dp++ = hex(ch & 0xF);\n-\t\t}\n-\t\telse\n-\t\t\t*dp++ = ch;\n-\t}\n-\t*dp = 0;\n-\n-\treturn qref;\n-}\n-\n-int fetch_ref(char *ref, unsigned char *sha1)\n-{\n-\tchar *url;\n-\tstruct strbuf buffer = STRBUF_INIT;\n-\tchar *base = remote->url;\n-\tstruct active_request_slot *slot;\n-\tstruct slot_results results;\n-\tint ret;\n-\n-\turl = quote_ref_url(base, ref);\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_HTTPHEADER, NULL);\n-\tcurl_easy_setopt(slot->curl, CURLOPT_URL, url);\n-\tif (start_active_slot(slot)) {\n-\t\trun_active_slot(slot);\n-\t\tif (results.curl_result == CURLE_OK) {\n-\t\t\tstrbuf_rtrim(&buffer);\n-\t\t\tif (buffer.len == 40)\n-\t\t\t\tret = get_sha1_hex(buffer.buf, sha1);\n-\t\t\telse\n-\t\t\t\tret = 1;\n-\t\t} else {\n-\t\t\tret = error(\"Couldn't get %s for %s\\n%s\",\n-\t\t\t\t    url, ref, curl_errorstr);\n-\t\t}\n-\t} else {\n-\t\tret = error(\"Unable to start request\");\n-\t}\n-\n-\tstrbuf_release(&buffer);\n-\tfree(url);\n-\treturn ret;\n-}\n-\n static void one_remote_object(const char *hex)\n {\n \tunsigned char sha1[20];\n@@ -1827,7 +1745,8 @@ static void one_remote_ref(char *refname)\n \tstruct object *obj;\n \tint len = strlen(refname) + 1;\n \n-\tif (fetch_ref(refname, remote_sha1) != 0) {\n+\tif (http_fetch_ref(remote->url, refname + 5 /* \"refs/\" */,\n+\t\t\t   remote_sha1) != 0) {\n \t\tfprintf(stderr,\n \t\t\t\"Unable to fetch ref %s from %s\\n\",\n \t\t\trefname, remote->url);\n@@ -1959,7 +1878,8 @@ static void add_remote_info_ref(struct remote_ls_ctx *ls)\n \tint len;\n \tchar *ref_info;\n \n-\tif (fetch_ref(ls->dentry_name, remote_sha1) != 0) {\n+\tif (http_fetch_ref(remote->url, ls->dentry_name + 5 /* \"refs/\" */,\n+\t\t\t   remote_sha1) != 0) {\n \t\tfprintf(stderr,\n \t\t\t\"Unable to fetch ref %s from %s\\n\",\n \t\t\tls->dentry_name, remote->url);\ndiff --git a/http-walker.c b/http-walker.c\nindex 4e878b3..2c37868 100644\n--- a/http-walker.c\n+++ b/http-walker.c\n@@ -888,88 +888,10 @@ static int fetch(struct walker *walker, unsigned char *sha1)\n \t\t     data->alt->base);\n }\n \n-static inline int needs_quote(int ch)\n-{\n-\tif (((ch >= 'A') && (ch <= 'Z'))\n-\t\t\t|| ((ch >= 'a') && (ch <= 'z'))\n-\t\t\t|| ((ch >= '0') && (ch <= '9'))\n-\t\t\t|| (ch == '/')\n-\t\t\t|| (ch == '-')\n-\t\t\t|| (ch == '.'))\n-\t\treturn 0;\n-\treturn 1;\n-}\n-\n-static inline int hex(int v)\n-{\n-\tif (v < 10) return '0' + v;\n-\telse return 'A' + v - 10;\n-}\n-\n-static char *quote_ref_url(const char *base, const char *ref)\n-{\n-\tconst char *cp;\n-\tchar *dp, *qref;\n-\tint len, baselen, ch;\n-\n-\tbaselen = strlen(base);\n-\tlen = baselen + 7; /* \"/refs/\" + NUL */\n-\tfor (cp = ref; (ch = *cp) != 0; cp++, len++)\n-\t\tif (needs_quote(ch))\n-\t\t\tlen += 2; /* extra two hex plus replacement % */\n-\tqref = xmalloc(len);\n-\tmemcpy(qref, base, baselen);\n-\tmemcpy(qref + baselen, \"/refs/\", 6);\n-\tfor (cp = ref, dp = qref + baselen + 6; (ch = *cp) != 0; cp++) {\n-\t\tif (needs_quote(ch)) {\n-\t\t\t*dp++ = '%';\n-\t\t\t*dp++ = hex((ch >> 4) & 0xF);\n-\t\t\t*dp++ = hex(ch & 0xF);\n-\t\t}\n-\t\telse\n-\t\t\t*dp++ = ch;\n-\t}\n-\t*dp = 0;\n-\n-\treturn qref;\n-}\n-\n static int fetch_ref(struct walker *walker, char *ref, unsigned char *sha1)\n {\n-\tchar *url;\n-\tstruct strbuf buffer = STRBUF_INIT;\n \tstruct walker_data *data = walker->data;\n-\tconst char *base = data->alt->base;\n-\tstruct active_request_slot *slot;\n-\tstruct slot_results results;\n-\tint ret;\n-\n-\turl = quote_ref_url(base, ref);\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_HTTPHEADER, NULL);\n-\tcurl_easy_setopt(slot->curl, CURLOPT_URL, url);\n-\tif (start_active_slot(slot)) {\n-\t\trun_active_slot(slot);\n-\t\tif (results.curl_result == CURLE_OK) {\n-\t\t\tstrbuf_rtrim(&buffer);\n-\t\t\tif (buffer.len == 40)\n-\t\t\t\tret = get_sha1_hex(buffer.buf, sha1);\n-\t\t\telse\n-\t\t\t\tret = 1;\n-\t\t} else {\n-\t\t\tret = error(\"Couldn't get %s for %s\\n%s\",\n-\t\t\t\t    url, ref, curl_errorstr);\n-\t\t}\n-\t} else {\n-\t\tret = error(\"Unable to start request\");\n-\t}\n-\n-\tstrbuf_release(&buffer);\n-\tfree(url);\n-\treturn ret;\n+\treturn http_fetch_ref(data->alt->base, ref, sha1);\n }\n \n static void cleanup(struct walker *walker)\ndiff --git a/http.c b/http.c\nindex 784b93e..c6de964 100644\n--- a/http.c\n+++ b/http.c\n@@ -552,3 +552,85 @@ void finish_all_active_slots(void)\n \t\t\tslot = slot->next;\n \t\t}\n }\n+\n+static inline int needs_quote(int ch)\n+{\n+\tif (((ch >= 'A') && (ch <= 'Z'))\n+\t\t\t|| ((ch >= 'a') && (ch <= 'z'))\n+\t\t\t|| ((ch >= '0') && (ch <= '9'))\n+\t\t\t|| (ch == '/')\n+\t\t\t|| (ch == '-')\n+\t\t\t|| (ch == '.'))\n+\t\treturn 0;\n+\treturn 1;\n+}\n+\n+static inline int hex(int v)\n+{\n+\tif (v < 10) return '0' + v;\n+\telse return 'A' + v - 10;\n+}\n+\n+static char *quote_ref_url(const char *base, const char *ref)\n+{\n+\tconst char *cp;\n+\tchar *dp, *qref;\n+\tint len, baselen, ch;\n+\n+\tbaselen = strlen(base);\n+\tlen = baselen + 7; /* \"/refs/\" + NUL */\n+\tfor (cp = ref; (ch = *cp) != 0; cp++, len++)\n+\t\tif (needs_quote(ch))\n+\t\t\tlen += 2; /* extra two hex plus replacement % */\n+\tqref = xmalloc(len);\n+\tmemcpy(qref, base, baselen);\n+\tmemcpy(qref + baselen, \"/refs/\", 6);\n+\tfor (cp = ref, dp = qref + baselen + 6; (ch = *cp) != 0; cp++) {\n+\t\tif (needs_quote(ch)) {\n+\t\t\t*dp++ = '%';\n+\t\t\t*dp++ = hex((ch >> 4) & 0xF);\n+\t\t\t*dp++ = hex(ch & 0xF);\n+\t\t}\n+\t\telse\n+\t\t\t*dp++ = ch;\n+\t}\n+\t*dp = 0;\n+\n+\treturn qref;\n+}\n+\n+int http_fetch_ref(const char *base, const char *ref, unsigned char *sha1)\n+{\n+\tchar *url;\n+\tstruct strbuf buffer = STRBUF_INIT;\n+\tstruct active_request_slot *slot;\n+\tstruct slot_results results;\n+\tint ret;\n+\n+\turl = quote_ref_url(base, ref);\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_HTTPHEADER, NULL);\n+\tcurl_easy_setopt(slot->curl, CURLOPT_URL, url);\n+\tif (start_active_slot(slot)) {\n+\t\trun_active_slot(slot);\n+\t\tif (results.curl_result == CURLE_OK) {\n+\t\t\tstrbuf_rtrim(&buffer);\n+\t\t\tif (buffer.len == 40)\n+\t\t\t\tret = get_sha1_hex(buffer.buf, sha1);\n+\t\t\telse\n+\t\t\t\tret = 1;\n+\t\t} else {\n+\t\t\tret = error(\"Couldn't get %s for %s\\n%s\",\n+\t\t\t\t    url, ref, curl_errorstr);\n+\t\t}\n+\t} else {\n+\t\tret = error(\"Unable to start request\");\n+\t}\n+\n+\tstrbuf_release(&buffer);\n+\tfree(url);\n+\treturn ret;\n+}\ndiff --git a/http.h b/http.h\nindex 87d638b..b709222 100644\n--- a/http.h\n+++ b/http.h\n@@ -96,4 +96,6 @@ static inline int missing__target(int code, int result)\n \n #define missing_target(a) missing__target((a)->http_code, (a)->curl_result)\n \n+extern int http_fetch_ref(const char *base, const char *ref, unsigned char *sha1);\n+\n #endif /* HTTP_H */\n-- \n1.5.3.7.1161.g4a58\n"}]}