{"thread":{"id":"20230","subject":"[PATCH 2/3] Use an external program to implement fetching with curl","startedAt":"2009-07-25T17:51:33Z","lastAt":"2009-07-25T17:51:33Z","messageCount":1,"participants":["Daniel Barkalow"],"isPatch":true,"patchVersion":1,"patchTotal":3},"messages":[{"id":"118739","messageId":"alpine.LNX.2.00.0907251333370.2147@iabervon.org","threadId":"20230","inReplyTo":null,"subject":"[PATCH 2/3] Use an external program to implement fetching with curl","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2009-07-25T17:51:33Z","receivedAt":"2009-07-25T17:51:33Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"Use the transport shim mechanism to fetch by http (and ftp, etc).\n\nSigned-off-by: Daniel Barkalow <barkalow@iabervon.org>\n---\n Makefile    |    5 ++\n shim-curl.c |  132 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n transport.c |  136 +----------------------------------------------------------\n 3 files changed, 138 insertions(+), 135 deletions(-)\n create mode 100644 shim-curl.c\n\ndiff --git a/Makefile b/Makefile\nindex 01efc73..d3dd2ed 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -980,6 +980,7 @@ else\n \t\tCURL_LIBCURL = -lcurl\n \tendif\n \tBUILTIN_OBJS += builtin-http-fetch.o\n+\tPROGRAMS += git-shim-curl$X\n \tEXTLIBS += $(CURL_LIBCURL)\n \tLIB_OBJS += http.o http-walker.o\n \tcurl_check := $(shell (echo 070908; curl-config --vernum) | sort -r | sed -ne 2p)\n@@ -1490,6 +1491,10 @@ git-http-push$X: revision.o http.o http-push.o $(GITLIBS)\n \t$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \\\n \t\t$(LIBS) $(CURL_LIBCURL) $(EXPAT_LIBEXPAT)\n \n+git-shim-curl$X: shim-curl.o http.o http-walker.o $(GITLIBS)\n+\t$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \\\n+\t\t$(LIBS) $(CURL_LIBCURL) $(EXPAT_LIBEXPAT)\n+\n $(LIB_OBJS) $(BUILTIN_OBJS): $(LIB_H)\n $(patsubst git-%$X,%.o,$(PROGRAMS)) git.o: $(LIB_H) $(wildcard */*.h)\n builtin-revert.o wt-status.o: wt-status.h\ndiff --git a/shim-curl.c b/shim-curl.c\nnew file mode 100644\nindex 0000000..8714667\n--- /dev/null\n+++ b/shim-curl.c\n@@ -0,0 +1,132 @@\n+#include \"cache.h\"\n+#include \"remote.h\"\n+#include \"strbuf.h\"\n+#include \"walker.h\"\n+#include \"http.h\"\n+\n+static struct ref *get_refs(struct walker *walker, const char *url)\n+{\n+\tint http_ret;\n+\tchar *refs_url;\n+\tstruct strbuf buffer = STRBUF_INIT;\n+\tchar *data, *start, *mid;\n+\tint i = 0;\n+\tchar *ref_name;\n+\tstruct ref *refs = NULL;\n+\tstruct ref *ref = NULL;\n+\tstruct ref *last_ref = NULL;\n+\n+\trefs_url = xmalloc(strlen(url) + 11);\n+\tsprintf(refs_url, \"%s/info/refs\", url);\n+\n+\thttp_ret = http_get_strbuf(refs_url, &buffer, HTTP_NO_CACHE);\n+\tswitch (http_ret) {\n+\tcase HTTP_OK:\n+\t\tbreak;\n+\tcase HTTP_MISSING_TARGET:\n+\t\tdie(\"%s not found: did you run git update-server-info on the\"\n+\t\t    \" server?\", refs_url);\n+\tdefault:\n+\t\thttp_error(refs_url, http_ret);\n+\t\tdie(\"HTTP request failed\");\n+\t}\n+\tfree(refs_url);\n+\n+\tdata = buffer.buf;\n+\tstart = NULL;\n+\tmid = data;\n+\twhile (i < buffer.len) {\n+\t\tif (!start) {\n+\t\t\tstart = &data[i];\n+\t\t}\n+\t\tif (data[i] == '\\t')\n+\t\t\tmid = &data[i];\n+\t\tif (data[i] == '\\n') {\n+\t\t\tdata[i] = 0;\n+\t\t\tref_name = mid + 1;\n+\t\t\tref = xmalloc(sizeof(struct ref) +\n+\t\t\t\t      strlen(ref_name) + 1);\n+\t\t\tmemset(ref, 0, sizeof(struct ref));\n+\t\t\tstrcpy(ref->name, ref_name);\n+\t\t\tget_sha1_hex(start, ref->old_sha1);\n+\t\t\tif (!refs)\n+\t\t\t\trefs = ref;\n+\t\t\tif (last_ref)\n+\t\t\t\tlast_ref->next = ref;\n+\t\t\tlast_ref = ref;\n+\t\t\tstart = NULL;\n+\t\t}\n+\t\ti++;\n+\t}\n+\tstrbuf_release(&buffer);\n+\n+\tref = alloc_ref(\"HEAD\");\n+\tif (!walker->fetch_ref(walker, ref) &&\n+\t    !resolve_remote_symref(ref, refs)) {\n+\t\tref->next = refs;\n+\t\trefs = ref;\n+\t} else {\n+\t\tfree(ref);\n+\t}\n+\n+\treturn refs;\n+}\n+\n+int main(int argc, const char **argv)\n+{\n+\tstruct remote *remote;\n+\tstruct strbuf buf = STRBUF_INIT;\n+\tconst char *url;\n+\tstruct walker *walker = NULL;\n+\n+\tsetup_git_directory();\n+\tif (argc < 2) {\n+\t\tfprintf(stderr, \"Remote needed\\n\");\n+\t\treturn 1;\n+\t}\n+\n+\tremote = remote_get(argv[1]);\n+\n+\tif (argc > 2) {\n+\t\turl = argv[2];\n+\t} else {\n+\t\turl = remote->url[0];\n+\t}\n+\n+\tdo {\n+\t\tif (strbuf_getline(&buf, stdin, '\\n') == EOF)\n+\t\t\tbreak;\n+\t\tif (!prefixcmp(buf.buf, \"fetch \")) {\n+\t\t\tchar *obj = buf.buf + strlen(\"fetch \");\n+\t\t\tif (!walker)\n+\t\t\t\twalker = get_http_walker(url, remote);\n+\t\t\twalker->get_all = 1;\n+\t\t\twalker->get_tree = 1;\n+\t\t\twalker->get_history = 1;\n+\t\t\twalker->get_verbosely = 0;\n+\t\t\twalker->get_recover = 0;\n+\t\t\tif (walker_fetch(walker, 1, &obj, NULL, NULL))\n+\t\t\t\tdie(\"Fetch failed.\");\n+\t\t\tprintf(\"\\n\");\n+\t\t\tfflush(stdout);\n+\t\t} else if (!strcmp(buf.buf, \"list\")) {\n+\t\t\tstruct ref *refs;\n+\t\t\tstruct ref *posn;\n+\t\t\tif (!walker)\n+\t\t\t\twalker = get_http_walker(url, remote);\n+\t\t\trefs = get_refs(walker, url);\n+\t\t\tfor (posn = refs; posn; posn = posn->next) {\n+\t\t\t\tif (posn->symref)\n+\t\t\t\t\tprintf(\"%s @%s\\n\", posn->name, posn->symref);\n+\t\t\t\telse\n+\t\t\t\t\tprintf(\"%s %s\\n\", posn->name, sha1_to_hex(posn->old_sha1));\n+\t\t\t}\n+\t\t\tprintf(\"\\n\");\n+\t\t\tfflush(stdout);\n+\t\t} else {\n+\t\t\treturn 1;\n+\t\t}\n+\t\tstrbuf_reset(&buf);\n+\t} while (1);\n+\treturn 0;\n+}\ndiff --git a/transport.c b/transport.c\nindex de0d587..6d13b0e 100644\n--- a/transport.c\n+++ b/transport.c\n@@ -1,9 +1,6 @@\n #include \"cache.h\"\n #include \"transport.h\"\n #include \"run-command.h\"\n-#ifndef NO_CURL\n-#include \"http.h\"\n-#endif\n #include \"pkt-line.h\"\n #include \"fetch-pack.h\"\n #include \"send-pack.h\"\n@@ -352,45 +349,6 @@ static int rsync_transport_push(struct transport *transport,\n \treturn result;\n }\n \n-/* Generic functions for using commit walkers */\n-\n-#ifndef NO_CURL /* http fetch is the only user */\n-static int fetch_objs_via_walker(struct transport *transport,\n-\t\t\t\t int nr_objs, const struct ref **to_fetch)\n-{\n-\tchar *dest = xstrdup(transport->url);\n-\tstruct walker *walker = transport->data;\n-\tchar **objs = xmalloc(nr_objs * sizeof(*objs));\n-\tint i;\n-\n-\twalker->get_all = 1;\n-\twalker->get_tree = 1;\n-\twalker->get_history = 1;\n-\twalker->get_verbosely = transport->verbose >= 0;\n-\twalker->get_recover = 0;\n-\n-\tfor (i = 0; i < nr_objs; i++)\n-\t\tobjs[i] = xstrdup(sha1_to_hex(to_fetch[i]->old_sha1));\n-\n-\tif (walker_fetch(walker, nr_objs, objs, NULL, NULL))\n-\t\tdie(\"Fetch failed.\");\n-\n-\tfor (i = 0; i < nr_objs; i++)\n-\t\tfree(objs[i]);\n-\tfree(objs);\n-\tfree(dest);\n-\treturn 0;\n-}\n-#endif /* NO_CURL */\n-\n-static int disconnect_walker(struct transport *transport)\n-{\n-\tstruct walker *walker = transport->data;\n-\tif (walker)\n-\t\twalker_free(walker);\n-\treturn 0;\n-}\n-\n #ifndef NO_CURL\n static int curl_transport_push(struct transport *transport, int refspec_nr, const char **refspec, int flags)\n {\n@@ -432,96 +390,6 @@ static int curl_transport_push(struct transport *transport, int refspec_nr, cons\n \treturn !!err;\n }\n \n-static struct ref *get_refs_via_curl(struct transport *transport, int for_push)\n-{\n-\tstruct strbuf buffer = STRBUF_INIT;\n-\tchar *data, *start, *mid;\n-\tchar *ref_name;\n-\tchar *refs_url;\n-\tint i = 0;\n-\tint http_ret;\n-\n-\tstruct ref *refs = NULL;\n-\tstruct ref *ref = NULL;\n-\tstruct ref *last_ref = NULL;\n-\n-\tstruct walker *walker;\n-\n-\tif (for_push)\n-\t\treturn NULL;\n-\n-\tif (!transport->data)\n-\t\ttransport->data = get_http_walker(transport->url,\n-\t\t\t\t\t\ttransport->remote);\n-\n-\twalker = transport->data;\n-\n-\trefs_url = xmalloc(strlen(transport->url) + 11);\n-\tsprintf(refs_url, \"%s/info/refs\", transport->url);\n-\n-\thttp_ret = http_get_strbuf(refs_url, &buffer, HTTP_NO_CACHE);\n-\tswitch (http_ret) {\n-\tcase HTTP_OK:\n-\t\tbreak;\n-\tcase HTTP_MISSING_TARGET:\n-\t\tdie(\"%s not found: did you run git update-server-info on the\"\n-\t\t    \" server?\", refs_url);\n-\tdefault:\n-\t\thttp_error(refs_url, http_ret);\n-\t\tdie(\"HTTP request failed\");\n-\t}\n-\n-\tdata = buffer.buf;\n-\tstart = NULL;\n-\tmid = data;\n-\twhile (i < buffer.len) {\n-\t\tif (!start)\n-\t\t\tstart = &data[i];\n-\t\tif (data[i] == '\\t')\n-\t\t\tmid = &data[i];\n-\t\tif (data[i] == '\\n') {\n-\t\t\tdata[i] = 0;\n-\t\t\tref_name = mid + 1;\n-\t\t\tref = xmalloc(sizeof(struct ref) +\n-\t\t\t\t      strlen(ref_name) + 1);\n-\t\t\tmemset(ref, 0, sizeof(struct ref));\n-\t\t\tstrcpy(ref->name, ref_name);\n-\t\t\tget_sha1_hex(start, ref->old_sha1);\n-\t\t\tif (!refs)\n-\t\t\t\trefs = ref;\n-\t\t\tif (last_ref)\n-\t\t\t\tlast_ref->next = ref;\n-\t\t\tlast_ref = ref;\n-\t\t\tstart = NULL;\n-\t\t}\n-\t\ti++;\n-\t}\n-\n-\tstrbuf_release(&buffer);\n-\n-\tref = alloc_ref(\"HEAD\");\n-\tif (!walker->fetch_ref(walker, ref) &&\n-\t    !resolve_remote_symref(ref, refs)) {\n-\t\tref->next = refs;\n-\t\trefs = ref;\n-\t} else {\n-\t\tfree(ref);\n-\t}\n-\n-\tstrbuf_release(&buffer);\n-\tfree(refs_url);\n-\treturn refs;\n-}\n-\n-static int fetch_objs_via_curl(struct transport *transport,\n-\t\t\t\t int nr_objs, const struct ref **to_fetch)\n-{\n-\tif (!transport->data)\n-\t\ttransport->data = get_http_walker(transport->url,\n-\t\t\t\t\t\ttransport->remote);\n-\treturn fetch_objs_via_walker(transport, nr_objs, to_fetch);\n-}\n-\n #endif\n \n struct bundle_transport_data {\n@@ -950,14 +818,12 @@ struct transport *transport_get(struct remote *remote, const char *url)\n \t} else if (!prefixcmp(url, \"http://\")\n \t        || !prefixcmp(url, \"https://\")\n \t        || !prefixcmp(url, \"ftp://\")) {\n+\t\ttransport_shim_init(ret, \"curl\");\n #ifdef NO_CURL\n \t\terror(\"git was compiled without libcurl support.\");\n #else\n-\t\tret->get_refs_list = get_refs_via_curl;\n-\t\tret->fetch = fetch_objs_via_curl;\n \t\tret->push = curl_transport_push;\n #endif\n-\t\tret->disconnect = disconnect_walker;\n \n \t} else if (is_local(url) && is_file(url)) {\n \t\tstruct bundle_transport_data *data = xcalloc(1, sizeof(*data));\n-- \n1.6.3.2.425.g3dedc\n"}]}