{"thread":{"id":"11214","subject":"[PATCH 1/4] Cleanup variables in http.[ch]","startedAt":"2007-12-09T17:04:57Z","lastAt":"2007-12-11T06:25:38Z","messageCount":23,"participants":["Mike Hommey","Junio C Hamano","David Kastrup","Randal L. Schwartz"],"isPatch":true,"patchVersion":1,"patchTotal":4},"messages":[{"id":"62491","messageId":"1197219900-19334-1-git-send-email-mh@glandium.org","threadId":"11214","inReplyTo":null,"subject":"[PATCH 1/4] Cleanup variables in http.[ch]","fromName":"Mike Hommey","fromEmail":"mh@glandium.org","sentAt":"2007-12-09T17:04:57Z","receivedAt":"2007-12-09T17:04:57Z","isPatch":true,"sender":{"key":"mh@glandium.org","avatar":"https://avatars.githubusercontent.com/u/1038527?v=4"},"body":"Quite some variables defined as extern in http.h are only used in http.c,\nand some others, only defined in http.c, were not static. Cleanup that.\n\nSigned-off-by: Mike Hommey <mh@glandium.org>\n---\n http.c |   28 ++++++++++++++--------------\n http.h |   18 ------------------\n 2 files changed, 14 insertions(+), 32 deletions(-)\n\ndiff --git a/http.c b/http.c\nindex e4aa9c1..146f626 100644\n--- a/http.c\n+++ b/http.c\n@@ -4,31 +4,31 @@ int data_received;\n int active_requests = 0;\n \n #ifdef USE_CURL_MULTI\n-int max_requests = -1;\n-CURLM *curlm;\n+static int max_requests = -1;\n+static CURLM *curlm;\n #endif\n #ifndef NO_CURL_EASY_DUPHANDLE\n-CURL *curl_default;\n+static CURL *curl_default;\n #endif\n char curl_errorstr[CURL_ERROR_SIZE];\n \n-int curl_ssl_verify = -1;\n-char *ssl_cert = NULL;\n+static int curl_ssl_verify = -1;\n+static char *ssl_cert = NULL;\n #if LIBCURL_VERSION_NUM >= 0x070902\n-char *ssl_key = NULL;\n+static char *ssl_key = NULL;\n #endif\n #if LIBCURL_VERSION_NUM >= 0x070908\n-char *ssl_capath = NULL;\n+static char *ssl_capath = NULL;\n #endif\n-char *ssl_cainfo = NULL;\n-long curl_low_speed_limit = -1;\n-long curl_low_speed_time = -1;\n-int curl_ftp_no_epsv = 0;\n-char *curl_http_proxy = NULL;\n+static char *ssl_cainfo = NULL;\n+static long curl_low_speed_limit = -1;\n+static long curl_low_speed_time = -1;\n+static int curl_ftp_no_epsv = 0;\n+static char *curl_http_proxy = NULL;\n \n-struct curl_slist *pragma_header;\n+static struct curl_slist *pragma_header;\n \n-struct active_request_slot *active_queue_head = NULL;\n+static struct active_request_slot *active_queue_head = NULL;\n \n size_t fread_buffer(void *ptr, size_t eltsize, size_t nmemb,\n \t\t\t   struct buffer *buffer)\ndiff --git a/http.h b/http.h\nindex 72abac2..fe1b0d1 100644\n--- a/http.h\n+++ b/http.h\n@@ -80,24 +80,6 @@ extern void http_cleanup(void);\n extern int data_received;\n extern int active_requests;\n \n-#ifndef NO_CURL_EASY_DUPHANDLE\n-extern CURL *curl_default;\n-#endif\n extern char curl_errorstr[CURL_ERROR_SIZE];\n \n-extern int curl_ssl_verify;\n-extern char *ssl_cert;\n-#if LIBCURL_VERSION_NUM >= 0x070902\n-extern char *ssl_key;\n-#endif\n-#if LIBCURL_VERSION_NUM >= 0x070908\n-extern char *ssl_capath;\n-#endif\n-extern char *ssl_cainfo;\n-extern long curl_low_speed_limit;\n-extern long curl_low_speed_time;\n-\n-extern struct curl_slist *pragma_header;\n-extern struct curl_slist *no_range_header;\n-\n #endif /* HTTP_H */\n-- \n1.5.3.7\n"},{"id":"62492","messageId":"1197219900-19334-2-git-send-email-mh@glandium.org","threadId":"11214","inReplyTo":"1197219900-19334-1-git-send-email-mh@glandium.org","subject":"[PATCH 2/4] Use strbuf in http code","fromName":"Mike Hommey","fromEmail":"mh@glandium.org","sentAt":"2007-12-09T17:04:58Z","receivedAt":"2007-12-09T17:04:58Z","isPatch":true,"sender":{"key":"mh@glandium.org","avatar":"https://avatars.githubusercontent.com/u/1038527?v=4"},"body":"Also, replace whitespaces with tabs in some places\n\nSigned-off-by: Mike Hommey <mh@glandium.org>\n---\n\n While testing this, I noticed 3 things:\n - CURL_MULTI makes the code very racy\n - a lot of the code doesn't do anything useful without CURL_MULTI\n - the code is redundant\n\n So, if I have some time soon, I'll try to refactor all that.\n\n http-push.c   |  186 ++++++++++++++++++--------------------------------------\n http-walker.c |   59 +++++++------------\n http.c        |   34 ++++------\n http.h        |   11 ++--\n transport.c   |   18 ++----\n 5 files changed, 107 insertions(+), 201 deletions(-)\n\ndiff --git a/http-push.c b/http-push.c\nindex 78283b4..e01b3a9 100644\n--- a/http-push.c\n+++ b/http-push.c\n@@ -495,10 +495,10 @@ static void start_put(struct transfer_request *request)\n \tmemset(&stream, 0, sizeof(stream));\n \tdeflateInit(&stream, zlib_compression_level);\n \tsize = deflateBound(&stream, len + hdrlen);\n-\trequest->buffer.buffer = xmalloc(size);\n+\tstrbuf_init(&request->buffer.buf, size);\n \n \t/* Compress it */\n-\tstream.next_out = request->buffer.buffer;\n+\tstream.next_out = (unsigned char *)request->buffer.buf.buf;\n \tstream.avail_out = size;\n \n \t/* First header.. */\n@@ -515,8 +515,7 @@ static void start_put(struct transfer_request *request)\n \tdeflateEnd(&stream);\n \tfree(unpacked);\n \n-\trequest->buffer.size = stream.total_out;\n-\trequest->buffer.posn = 0;\n+\trequest->buffer.buf.len = stream.total_out;\n \n \trequest->url = xmalloc(strlen(remote->url) +\n \t\t\t       strlen(request->lock->token) + 51);\n@@ -538,7 +537,7 @@ static void start_put(struct transfer_request *request)\n \tslot->callback_func = process_response;\n \tslot->callback_data = request;\n \tcurl_easy_setopt(slot->curl, CURLOPT_INFILE, &request->buffer);\n-\tcurl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, request->buffer.size);\n+\tcurl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, request->buffer.buf.len);\n \tcurl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, fread_buffer);\n \tcurl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_null);\n \tcurl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_PUT);\n@@ -1003,18 +1002,13 @@ static int fetch_indices(void)\n {\n \tunsigned char sha1[20];\n \tchar *url;\n-\tstruct buffer buffer;\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-\tdata = xcalloc(1, 4096);\n-\tbuffer.size = 4096;\n-\tbuffer.posn = 0;\n-\tbuffer.buffer = data;\n-\n \tif (push_verbosely)\n \t\tfprintf(stderr, \"Getting pack list\\n\");\n \n@@ -1030,7 +1024,7 @@ static int fetch_indices(void)\n \tif (start_active_slot(slot)) {\n \t\trun_active_slot(slot);\n \t\tif (results.curl_result != CURLE_OK) {\n-\t\t\tfree(buffer.buffer);\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@@ -1038,18 +1032,18 @@ static int fetch_indices(void)\n \t\t\t\treturn error(\"%s\", curl_errorstr);\n \t\t}\n \t} else {\n-\t\tfree(buffer.buffer);\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.buffer;\n-\twhile (i < buffer.posn) {\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.posn &&\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@@ -1064,7 +1058,7 @@ static int fetch_indices(void)\n \t\ti++;\n \t}\n \n-\tfree(buffer.buffer);\n+\tstrbuf_release(&buffer);\n \treturn 0;\n }\n \n@@ -1115,16 +1109,11 @@ static char *quote_ref_url(const char *base, const char *ref)\n \n int fetch_ref(char *ref, unsigned char *sha1)\n {\n-        char *url;\n-        char hex[42];\n-        struct buffer buffer;\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-        buffer.size = 41;\n-        buffer.posn = 0;\n-        buffer.buffer = hex;\n-        hex[41] = '\\0';\n \n \turl = quote_ref_url(base, ref);\n \tslot = get_active_slot();\n@@ -1142,9 +1131,9 @@ int fetch_ref(char *ref, unsigned char *sha1)\n \t\treturn error(\"Unable to start request\");\n \t}\n \n-        hex[40] = '\\0';\n-        get_sha1_hex(hex, sha1);\n-        return 0;\n+\tbuffer.buf[40] = '\\0';\n+\tget_sha1_hex(buffer.buf, sha1);\n+\treturn 0;\n }\n \n static void one_remote_object(const char *hex)\n@@ -1267,10 +1256,8 @@ static struct remote_lock *lock_remote(const char *path, long timeout)\n {\n \tstruct active_request_slot *slot;\n \tstruct slot_results results;\n-\tstruct buffer out_buffer;\n-\tstruct buffer in_buffer;\n-\tchar *out_data;\n-\tchar *in_data;\n+\tstruct buffer out_buffer = { 0, STRBUF_INIT };\n+\tstruct strbuf in_buffer = STRBUF_INIT;\n \tchar *url;\n \tchar *ep;\n \tchar timeout_header[25];\n@@ -1312,16 +1299,7 @@ static struct remote_lock *lock_remote(const char *path, long timeout)\n \t\tep = strchr(ep + 1, '/');\n \t}\n \n-\tout_buffer.size = strlen(LOCK_REQUEST) + strlen(git_default_email) - 2;\n-\tout_data = xmalloc(out_buffer.size + 1);\n-\tsnprintf(out_data, out_buffer.size + 1, LOCK_REQUEST, git_default_email);\n-\tout_buffer.posn = 0;\n-\tout_buffer.buffer = out_data;\n-\n-\tin_buffer.size = 4096;\n-\tin_data = xmalloc(in_buffer.size);\n-\tin_buffer.posn = 0;\n-\tin_buffer.buffer = in_data;\n+\tstrbuf_addf(&out_buffer.buf, LOCK_REQUEST, git_default_email);\n \n \tsprintf(timeout_header, \"Timeout: Second-%ld\", timeout);\n \tdav_headers = curl_slist_append(dav_headers, timeout_header);\n@@ -1330,7 +1308,7 @@ static struct remote_lock *lock_remote(const char *path, long timeout)\n \tslot = get_active_slot();\n \tslot->results = &results;\n \tcurl_easy_setopt(slot->curl, CURLOPT_INFILE, &out_buffer);\n-\tcurl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, out_buffer.size);\n+\tcurl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, out_buffer.buf.len);\n \tcurl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, fread_buffer);\n \tcurl_easy_setopt(slot->curl, CURLOPT_FILE, &in_buffer);\n \tcurl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer);\n@@ -1354,8 +1332,8 @@ static struct remote_lock *lock_remote(const char *path, long timeout)\n \t\t\tXML_SetElementHandler(parser, xml_start_tag,\n \t\t\t\t\t      xml_end_tag);\n \t\t\tXML_SetCharacterDataHandler(parser, xml_cdata);\n-\t\t\tresult = XML_Parse(parser, in_buffer.buffer,\n-\t\t\t\t\t   in_buffer.posn, 1);\n+\t\t\tresult = XML_Parse(parser, in_buffer.buf,\n+\t\t\t\t\t   in_buffer.len, 1);\n \t\t\tfree(ctx.name);\n \t\t\tif (result != XML_STATUS_OK) {\n \t\t\t\tfprintf(stderr, \"XML error: %s\\n\",\n@@ -1369,8 +1347,8 @@ static struct remote_lock *lock_remote(const char *path, long timeout)\n \t}\n \n \tcurl_slist_free_all(dav_headers);\n-\tfree(out_data);\n-\tfree(in_data);\n+\tstrbuf_release(&out_buffer.buf);\n+\tstrbuf_release(&in_buffer);\n \n \tif (lock->token == NULL || lock->timeout <= 0) {\n \t\tif (lock->token != NULL)\n@@ -1521,10 +1499,8 @@ static void remote_ls(const char *path, int flags,\n \tchar *url = xmalloc(strlen(remote->url) + strlen(path) + 1);\n \tstruct active_request_slot *slot;\n \tstruct slot_results results;\n-\tstruct buffer in_buffer;\n-\tstruct buffer out_buffer;\n-\tchar *in_data;\n-\tchar *out_data;\n+\tstruct strbuf in_buffer = STRBUF_INIT;\n+\tstruct buffer out_buffer = { 0, STRBUF_INIT };\n \tXML_Parser parser = XML_ParserCreate(NULL);\n \tenum XML_Status result;\n \tstruct curl_slist *dav_headers = NULL;\n@@ -1540,16 +1516,7 @@ static void remote_ls(const char *path, int flags,\n \n \tsprintf(url, \"%s%s\", remote->url, path);\n \n-\tout_buffer.size = strlen(PROPFIND_ALL_REQUEST);\n-\tout_data = xmalloc(out_buffer.size + 1);\n-\tsnprintf(out_data, out_buffer.size + 1, PROPFIND_ALL_REQUEST);\n-\tout_buffer.posn = 0;\n-\tout_buffer.buffer = out_data;\n-\n-\tin_buffer.size = 4096;\n-\tin_data = xmalloc(in_buffer.size);\n-\tin_buffer.posn = 0;\n-\tin_buffer.buffer = in_data;\n+\tstrbuf_addf(&out_buffer.buf, PROPFIND_ALL_REQUEST);\n \n \tdav_headers = curl_slist_append(dav_headers, \"Depth: 1\");\n \tdav_headers = curl_slist_append(dav_headers, \"Content-Type: text/xml\");\n@@ -1557,7 +1524,7 @@ static void remote_ls(const char *path, int flags,\n \tslot = get_active_slot();\n \tslot->results = &results;\n \tcurl_easy_setopt(slot->curl, CURLOPT_INFILE, &out_buffer);\n-\tcurl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, out_buffer.size);\n+\tcurl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, out_buffer.buf.len);\n \tcurl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, fread_buffer);\n \tcurl_easy_setopt(slot->curl, CURLOPT_FILE, &in_buffer);\n \tcurl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer);\n@@ -1578,8 +1545,8 @@ static void remote_ls(const char *path, int flags,\n \t\t\tXML_SetElementHandler(parser, xml_start_tag,\n \t\t\t\t\t      xml_end_tag);\n \t\t\tXML_SetCharacterDataHandler(parser, xml_cdata);\n-\t\t\tresult = XML_Parse(parser, in_buffer.buffer,\n-\t\t\t\t\t   in_buffer.posn, 1);\n+\t\t\tresult = XML_Parse(parser, in_buffer.buf,\n+\t\t\t\t\t   in_buffer.len, 1);\n \t\t\tfree(ctx.name);\n \n \t\t\tif (result != XML_STATUS_OK) {\n@@ -1594,8 +1561,8 @@ static void remote_ls(const char *path, int flags,\n \n \tfree(ls.path);\n \tfree(url);\n-\tfree(out_data);\n-\tfree(in_buffer.buffer);\n+\tstrbuf_release(&out_buffer.buf);\n+\tstrbuf_release(&in_buffer);\n \tcurl_slist_free_all(dav_headers);\n }\n \n@@ -1616,29 +1583,15 @@ static int locking_available(void)\n {\n \tstruct active_request_slot *slot;\n \tstruct slot_results results;\n-\tstruct buffer in_buffer;\n-\tstruct buffer out_buffer;\n-\tchar *in_data;\n-\tchar *out_data;\n+\tstruct strbuf in_buffer = STRBUF_INIT;\n+\tstruct buffer out_buffer = { 0, STRBUF_INIT };\n \tXML_Parser parser = XML_ParserCreate(NULL);\n \tenum XML_Status result;\n \tstruct curl_slist *dav_headers = NULL;\n \tstruct xml_ctx ctx;\n \tint lock_flags = 0;\n \n-\tout_buffer.size =\n-\t\tstrlen(PROPFIND_SUPPORTEDLOCK_REQUEST) +\n-\t\tstrlen(remote->url) - 2;\n-\tout_data = xmalloc(out_buffer.size + 1);\n-\tsnprintf(out_data, out_buffer.size + 1,\n-\t\t PROPFIND_SUPPORTEDLOCK_REQUEST, remote->url);\n-\tout_buffer.posn = 0;\n-\tout_buffer.buffer = out_data;\n-\n-\tin_buffer.size = 4096;\n-\tin_data = xmalloc(in_buffer.size);\n-\tin_buffer.posn = 0;\n-\tin_buffer.buffer = in_data;\n+\tstrbuf_addf(&out_buffer.buf, PROPFIND_SUPPORTEDLOCK_REQUEST, remote->url);\n \n \tdav_headers = curl_slist_append(dav_headers, \"Depth: 0\");\n \tdav_headers = curl_slist_append(dav_headers, \"Content-Type: text/xml\");\n@@ -1646,7 +1599,7 @@ static int locking_available(void)\n \tslot = get_active_slot();\n \tslot->results = &results;\n \tcurl_easy_setopt(slot->curl, CURLOPT_INFILE, &out_buffer);\n-\tcurl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, out_buffer.size);\n+\tcurl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, out_buffer.buf.len);\n \tcurl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, fread_buffer);\n \tcurl_easy_setopt(slot->curl, CURLOPT_FILE, &in_buffer);\n \tcurl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer);\n@@ -1666,8 +1619,8 @@ static int locking_available(void)\n \t\t\tXML_SetUserData(parser, &ctx);\n \t\t\tXML_SetElementHandler(parser, xml_start_tag,\n \t\t\t\t\t      xml_end_tag);\n-\t\t\tresult = XML_Parse(parser, in_buffer.buffer,\n-\t\t\t\t\t   in_buffer.posn, 1);\n+\t\t\tresult = XML_Parse(parser, in_buffer.buf,\n+\t\t\t\t\t   in_buffer.len, 1);\n \t\t\tfree(ctx.name);\n \n \t\t\tif (result != XML_STATUS_OK) {\n@@ -1681,8 +1634,8 @@ static int locking_available(void)\n \t\tfprintf(stderr, \"Unable to start PROPFIND request\\n\");\n \t}\n \n-\tfree(out_data);\n-\tfree(in_buffer.buffer);\n+\tstrbuf_release(&out_buffer.buf);\n+\tstrbuf_release(&in_buffer);\n \tcurl_slist_free_all(dav_headers);\n \n \treturn lock_flags;\n@@ -1800,30 +1753,20 @@ static int update_remote(unsigned char *sha1, struct remote_lock *lock)\n {\n \tstruct active_request_slot *slot;\n \tstruct slot_results results;\n-\tchar *out_data;\n \tchar *if_header;\n-\tstruct buffer out_buffer;\n+\tstruct buffer out_buffer = { 0, STRBUF_INIT };\n \tstruct curl_slist *dav_headers = NULL;\n-\tint i;\n \n \tif_header = xmalloc(strlen(lock->token) + 25);\n \tsprintf(if_header, \"If: (<opaquelocktoken:%s>)\", lock->token);\n \tdav_headers = curl_slist_append(dav_headers, if_header);\n \n-\tout_buffer.size = 41;\n-\tout_data = xmalloc(out_buffer.size + 1);\n-\ti = snprintf(out_data, out_buffer.size + 1, \"%s\\n\", sha1_to_hex(sha1));\n-\tif (i != out_buffer.size) {\n-\t\tfprintf(stderr, \"Unable to initialize PUT request body\\n\");\n-\t\treturn 0;\n-\t}\n-\tout_buffer.posn = 0;\n-\tout_buffer.buffer = out_data;\n+\tstrbuf_addf(&out_buffer.buf, \"%s\\n\", sha1_to_hex(sha1));\n \n \tslot = get_active_slot();\n \tslot->results = &results;\n \tcurl_easy_setopt(slot->curl, CURLOPT_INFILE, &out_buffer);\n-\tcurl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, out_buffer.size);\n+\tcurl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, out_buffer.buf.len);\n \tcurl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, fread_buffer);\n \tcurl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_null);\n \tcurl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_PUT);\n@@ -1834,7 +1777,7 @@ static int update_remote(unsigned char *sha1, struct remote_lock *lock)\n \n \tif (start_active_slot(slot)) {\n \t\trun_active_slot(slot);\n-\t\tfree(out_data);\n+\t\tstrbuf_release(&out_buffer.buf);\n \t\tfree(if_header);\n \t\tif (results.curl_result != CURLE_OK) {\n \t\t\tfprintf(stderr,\n@@ -1844,7 +1787,7 @@ static int update_remote(unsigned char *sha1, struct remote_lock *lock)\n \t\t\treturn 0;\n \t\t}\n \t} else {\n-\t\tfree(out_data);\n+\t\tstrbuf_release(&out_buffer.buf);\n \t\tfree(if_header);\n \t\tfprintf(stderr, \"Unable to start PUT request\\n\");\n \t\treturn 0;\n@@ -2001,7 +1944,7 @@ static void mark_edges_uninteresting(struct commit_list *list)\n \n static void add_remote_info_ref(struct remote_ls_ctx *ls)\n {\n-\tstruct buffer *buf = (struct buffer *)ls->userData;\n+\tstruct strbuf *buf = (struct strbuf *)ls->userData;\n \tunsigned char remote_sha1[20];\n \tstruct object *o;\n \tint len;\n@@ -2046,17 +1989,14 @@ static void add_remote_info_ref(struct remote_ls_ctx *ls)\n \n static void update_remote_info_refs(struct remote_lock *lock)\n {\n-\tstruct buffer buffer;\n+\tstruct buffer buffer = { 0, STRBUF_INIT };\n \tstruct active_request_slot *slot;\n \tstruct slot_results results;\n \tchar *if_header;\n \tstruct curl_slist *dav_headers = NULL;\n \n-\tbuffer.buffer = xcalloc(1, 4096);\n-\tbuffer.size = 4096;\n-\tbuffer.posn = 0;\n \tremote_ls(\"refs/\", (PROCESS_FILES | RECURSIVE),\n-\t\t  add_remote_info_ref, &buffer);\n+\t\t  add_remote_info_ref, &buffer.buf);\n \tif (!aborted) {\n \t\tif_header = xmalloc(strlen(lock->token) + 25);\n \t\tsprintf(if_header, \"If: (<opaquelocktoken:%s>)\", lock->token);\n@@ -2065,7 +2005,7 @@ static void update_remote_info_refs(struct remote_lock *lock)\n \t\tslot = get_active_slot();\n \t\tslot->results = &results;\n \t\tcurl_easy_setopt(slot->curl, CURLOPT_INFILE, &buffer);\n-\t\tcurl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, buffer.posn);\n+\t\tcurl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, buffer.buf.len);\n \t\tcurl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, fread_buffer);\n \t\tcurl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_null);\n \t\tcurl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_PUT);\n@@ -2074,8 +2014,6 @@ static void update_remote_info_refs(struct remote_lock *lock)\n \t\tcurl_easy_setopt(slot->curl, CURLOPT_PUT, 1);\n \t\tcurl_easy_setopt(slot->curl, CURLOPT_URL, lock->url);\n \n-\t\tbuffer.posn = 0;\n-\n \t\tif (start_active_slot(slot)) {\n \t\t\trun_active_slot(slot);\n \t\t\tif (results.curl_result != CURLE_OK) {\n@@ -2086,7 +2024,7 @@ static void update_remote_info_refs(struct remote_lock *lock)\n \t\t}\n \t\tfree(if_header);\n \t}\n-\tfree(buffer.buffer);\n+\tstrbuf_release(&buffer.buf);\n }\n \n static int remote_exists(const char *path)\n@@ -2097,12 +2035,12 @@ static int remote_exists(const char *path)\n \n \tsprintf(url, \"%s%s\", remote->url, path);\n \n-        slot = get_active_slot();\n+\tslot = get_active_slot();\n \tslot->results = &results;\n-        curl_easy_setopt(slot->curl, CURLOPT_URL, url);\n-        curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 1);\n+\tcurl_easy_setopt(slot->curl, CURLOPT_URL, url);\n+\tcurl_easy_setopt(slot->curl, CURLOPT_NOBODY, 1);\n \n-        if (start_active_slot(slot)) {\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@@ -2120,17 +2058,13 @@ static int remote_exists(const char *path)\n static void fetch_symref(const char *path, char **symref, unsigned char *sha1)\n {\n \tchar *url;\n-\tstruct buffer buffer;\n+\tstruct strbuf buffer = STRBUF_INIT;\n \tstruct active_request_slot *slot;\n \tstruct slot_results results;\n \n \turl = xmalloc(strlen(remote->url) + strlen(path) + 1);\n \tsprintf(url, \"%s%s\", remote->url, path);\n \n-\tbuffer.size = 4096;\n-\tbuffer.posn = 0;\n-\tbuffer.buffer = xmalloc(buffer.size);\n-\n \tslot = get_active_slot();\n \tslot->results = &results;\n \tcurl_easy_setopt(slot->curl, CURLOPT_FILE, &buffer);\n@@ -2153,17 +2087,17 @@ static void fetch_symref(const char *path, char **symref, unsigned char *sha1)\n \t*symref = NULL;\n \thashclr(sha1);\n \n-\tif (buffer.posn == 0)\n+\tif (buffer.len == 0)\n \t\treturn;\n \n \t/* If it's a symref, set the refname; otherwise try for a sha1 */\n-\tif (!prefixcmp((char *)buffer.buffer, \"ref: \")) {\n-\t\t*symref = xmemdupz((char *)buffer.buffer + 5, buffer.posn - 6);\n+\tif (!prefixcmp((char *)buffer.buf, \"ref: \")) {\n+\t\t*symref = xmemdupz((char *)buffer.buf + 5, buffer.len - 6);\n \t} else {\n-\t\tget_sha1_hex(buffer.buffer, sha1);\n+\t\tget_sha1_hex(buffer.buf, sha1);\n \t}\n \n-\tfree(buffer.buffer);\n+\tstrbuf_release(&buffer);\n }\n \n static int verify_merge_base(unsigned char *head_sha1, unsigned char *branch_sha1)\ndiff --git a/http-walker.c b/http-walker.c\nindex a3fb596..d925005 100644\n--- a/http-walker.c\n+++ b/http-walker.c\n@@ -48,7 +48,7 @@ struct alternates_request {\n \tstruct walker *walker;\n \tconst char *base;\n \tchar *url;\n-\tstruct buffer *buffer;\n+\tstruct strbuf *buffer;\n \tstruct active_request_slot *slot;\n \tint http_specific;\n };\n@@ -475,7 +475,7 @@ static void process_alternates_response(void *callback_data)\n \n \tif (alt_req->http_specific) {\n \t\tif (slot->curl_result != CURLE_OK ||\n-\t\t    !alt_req->buffer->posn) {\n+\t\t    !alt_req->buffer->len) {\n \n \t\t\t/* Try reusing the slot to get non-http alternates */\n \t\t\talt_req->http_specific = 0;\n@@ -503,12 +503,12 @@ static void process_alternates_response(void *callback_data)\n \t}\n \n \tfwrite_buffer(&null_byte, 1, 1, alt_req->buffer);\n-\talt_req->buffer->posn--;\n-\tdata = alt_req->buffer->buffer;\n+\talt_req->buffer->len--;\n+\tdata = alt_req->buffer->buf;\n \n-\twhile (i < alt_req->buffer->posn) {\n+\twhile (i < alt_req->buffer->len) {\n \t\tint posn = i;\n-\t\twhile (posn < alt_req->buffer->posn && data[posn] != '\\n')\n+\t\twhile (posn < alt_req->buffer->len && data[posn] != '\\n')\n \t\t\tposn++;\n \t\tif (data[posn] == '\\n') {\n \t\t\tint okay = 0;\n@@ -596,9 +596,8 @@ static void process_alternates_response(void *callback_data)\n \n static void fetch_alternates(struct walker *walker, const char *base)\n {\n-\tstruct buffer buffer;\n+\tstruct strbuf buffer = STRBUF_INIT;\n \tchar *url;\n-\tchar *data;\n \tstruct active_request_slot *slot;\n \tstruct alternates_request alt_req;\n \tstruct walker_data *cdata = walker->data;\n@@ -619,11 +618,6 @@ static void fetch_alternates(struct walker *walker, const char *base)\n \t/* Start the fetch */\n \tcdata->got_alternates = 0;\n \n-\tdata = xmalloc(4096);\n-\tbuffer.size = 4096;\n-\tbuffer.posn = 0;\n-\tbuffer.buffer = data;\n-\n \tif (walker->get_verbosely)\n \t\tfprintf(stderr, \"Getting alternates list for %s\\n\", base);\n \n@@ -652,7 +646,7 @@ static void fetch_alternates(struct walker *walker, const char *base)\n \telse\n \t\tcdata->got_alternates = -1;\n \n-\tfree(data);\n+\tstrbuf_release(&buffer);\n \tfree(url);\n }\n \n@@ -660,7 +654,7 @@ static int fetch_indices(struct walker *walker, struct alt_base *repo)\n {\n \tunsigned char sha1[20];\n \tchar *url;\n-\tstruct buffer buffer;\n+\tstruct strbuf buffer = STRBUF_INIT;\n \tchar *data;\n \tint i = 0;\n \n@@ -670,11 +664,6 @@ static int fetch_indices(struct walker *walker, struct alt_base *repo)\n \tif (repo->got_indices)\n \t\treturn 0;\n \n-\tdata = xmalloc(4096);\n-\tbuffer.size = 4096;\n-\tbuffer.posn = 0;\n-\tbuffer.buffer = data;\n-\n \tif (walker->get_verbosely)\n \t\tfprintf(stderr, \"Getting pack list for %s\\n\", repo->base);\n \n@@ -690,28 +679,27 @@ 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\tfree(buffer.buffer);\n \t\t\t\treturn 0;\n \t\t\t} else {\n \t\t\t\trepo->got_indices = 0;\n-\t\t\t\tfree(buffer.buffer);\n \t\t\t\treturn error(\"%s\", curl_errorstr);\n \t\t\t}\n \t\t}\n \t} else {\n \t\trepo->got_indices = 0;\n-\t\tfree(buffer.buffer);\n+\t\tstrbuf_release(&buffer);\n \t\treturn error(\"Unable to start request\");\n \t}\n \n-\tdata = buffer.buffer;\n-\twhile (i < buffer.posn) {\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.posn &&\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@@ -720,13 +708,13 @@ static int fetch_indices(struct walker *walker, struct alt_base *repo)\n \t\t\t\tbreak;\n \t\t\t}\n \t\tdefault:\n-\t\t\twhile (i < buffer.posn && data[i] != '\\n')\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-\tfree(buffer.buffer);\n+\tstrbuf_release(&buffer);\n \trepo->got_indices = 1;\n \treturn 0;\n }\n@@ -958,17 +946,12 @@ static char *quote_ref_url(const char *base, const char *ref)\n \n static int fetch_ref(struct walker *walker, char *ref, unsigned char *sha1)\n {\n-        char *url;\n-        char hex[42];\n-        struct buffer buffer;\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-        buffer.size = 41;\n-        buffer.posn = 0;\n-        buffer.buffer = hex;\n-        hex[41] = '\\0';\n \n \turl = quote_ref_url(base, ref);\n \tslot = get_active_slot();\n@@ -986,9 +969,9 @@ static int fetch_ref(struct walker *walker, char *ref, unsigned char *sha1)\n \t\treturn error(\"Unable to start request\");\n \t}\n \n-        hex[40] = '\\0';\n-        get_sha1_hex(hex, sha1);\n-        return 0;\n+\tbuffer.buf[40] = '\\0';\n+\tget_sha1_hex(buffer.buf, sha1);\n+\treturn 0;\n }\n \n static void cleanup(struct walker *walker)\ndiff --git a/http.c b/http.c\nindex 146f626..2d0b46d 100644\n--- a/http.c\n+++ b/http.c\n@@ -34,31 +34,25 @@ size_t fread_buffer(void *ptr, size_t eltsize, size_t nmemb,\n \t\t\t   struct buffer *buffer)\n {\n \tsize_t size = eltsize * nmemb;\n-\tif (size > buffer->size - buffer->posn)\n-\t\tsize = buffer->size - buffer->posn;\n-\tmemcpy(ptr, (char *) buffer->buffer + buffer->posn, size);\n+\tif (size > buffer->buf.len - buffer->posn)\n+\t\tsize = buffer->buf.len - buffer->posn;\n+\tmemcpy(ptr, (char *) buffer->buf.buf + buffer->posn, size);\n \tbuffer->posn += size;\n+\n \treturn size;\n }\n \n size_t fwrite_buffer(const void *ptr, size_t eltsize,\n-\t\t\t    size_t nmemb, struct buffer *buffer)\n+\t\t\t    size_t nmemb, struct strbuf *buffer)\n {\n \tsize_t size = eltsize * nmemb;\n-\tif (size > buffer->size - buffer->posn) {\n-\t\tbuffer->size = buffer->size * 3 / 2;\n-\t\tif (buffer->size < buffer->posn + size)\n-\t\t\tbuffer->size = buffer->posn + size;\n-\t\tbuffer->buffer = xrealloc(buffer->buffer, buffer->size);\n-\t}\n-\tmemcpy((char *) buffer->buffer + buffer->posn, ptr, size);\n-\tbuffer->posn += size;\n+\tstrbuf_add(buffer, ptr, size);\n \tdata_received++;\n \treturn size;\n }\n \n size_t fwrite_null(const void *ptr, size_t eltsize,\n-\t\t\t  size_t nmemb, struct buffer *buffer)\n+\t\t\t  size_t nmemb, struct strbuf *buffer)\n {\n \tdata_received++;\n \treturn eltsize * nmemb;\n@@ -508,8 +502,8 @@ void run_active_slot(struct active_request_slot *slot)\n \n static void closedown_active_slot(struct active_request_slot *slot)\n {\n-        active_requests--;\n-        slot->in_use = 0;\n+\tactive_requests--;\n+\tslot->in_use = 0;\n }\n \n void release_active_slot(struct active_request_slot *slot)\n@@ -530,7 +524,7 @@ void release_active_slot(struct active_request_slot *slot)\n static void finish_active_slot(struct active_request_slot *slot)\n {\n \tclosedown_active_slot(slot);\n-        curl_easy_getinfo(slot->curl, CURLINFO_HTTP_CODE, &slot->http_code);\n+\tcurl_easy_getinfo(slot->curl, CURLINFO_HTTP_CODE, &slot->http_code);\n \n \tif (slot->finished != NULL)\n \t\t(*slot->finished) = 1;\n@@ -541,10 +535,10 @@ static void finish_active_slot(struct active_request_slot *slot)\n \t\tslot->results->http_code = slot->http_code;\n \t}\n \n-        /* Run callback if appropriate */\n-        if (slot->callback_func != NULL) {\n-                slot->callback_func(slot->callback_data);\n-        }\n+\t/* Run callback if appropriate */\n+\tif (slot->callback_func != NULL) {\n+\t\tslot->callback_func(slot->callback_data);\n+\t}\n }\n \n void finish_all_active_slots(void)\ndiff --git a/http.h b/http.h\nindex fe1b0d1..bf3f12c 100644\n--- a/http.h\n+++ b/http.h\n@@ -6,6 +6,8 @@\n #include <curl/curl.h>\n #include <curl/easy.h>\n \n+#include \"strbuf.h\"\n+\n #if LIBCURL_VERSION_NUM >= 0x071000\n #define USE_CURL_MULTI\n #define DEFAULT_MAX_REQUESTS 5\n@@ -48,18 +50,17 @@ struct active_request_slot\n \n struct buffer\n {\n-        size_t posn;\n-        size_t size;\n-        void *buffer;\n+\tstruct strbuf buf;\n+\tsize_t posn;\n };\n \n /* Curl request read/write callbacks */\n extern size_t fread_buffer(void *ptr, size_t eltsize, size_t nmemb,\n \t\t\t   struct buffer *buffer);\n extern size_t fwrite_buffer(const void *ptr, size_t eltsize,\n-\t\t\t    size_t nmemb, struct buffer *buffer);\n+\t\t\t    size_t nmemb, struct strbuf *buffer);\n extern size_t fwrite_null(const void *ptr, size_t eltsize,\n-\t\t\t  size_t nmemb, struct buffer *buffer);\n+\t\t\t  size_t nmemb, struct strbuf *buffer);\n \n /* Slot lifecycle functions */\n extern struct active_request_slot *get_active_slot(void);\ndiff --git a/transport.c b/transport.c\nindex 58e66f6..22234e8 100644\n--- a/transport.c\n+++ b/transport.c\n@@ -441,7 +441,7 @@ static int missing__target(int code, int result)\n \n static struct ref *get_refs_via_curl(struct transport *transport)\n {\n-\tstruct buffer buffer;\n+\tstruct strbuf buffer = STRBUF_INIT;\n \tchar *data, *start, *mid;\n \tchar *ref_name;\n \tchar *refs_url;\n@@ -454,11 +454,6 @@ static struct ref *get_refs_via_curl(struct transport *transport)\n \tstruct ref *ref = NULL;\n \tstruct ref *last_ref = NULL;\n \n-\tdata = xmalloc(4096);\n-\tbuffer.size = 4096;\n-\tbuffer.posn = 0;\n-\tbuffer.buffer = data;\n-\n \trefs_url = xmalloc(strlen(transport->url) + 11);\n \tsprintf(refs_url, \"%s/info/refs\", transport->url);\n \n@@ -477,27 +472,26 @@ static struct ref *get_refs_via_curl(struct transport *transport)\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\tfree(buffer.buffer);\n \t\t\t\treturn NULL;\n \t\t\t} else {\n-\t\t\t\tfree(buffer.buffer);\n \t\t\t\terror(\"%s\", curl_errorstr);\n \t\t\t\treturn NULL;\n \t\t\t}\n \t\t}\n \t} else {\n-\t\tfree(buffer.buffer);\n+\t\tstrbuf_release(&buffer);\n \t\terror(\"Unable to start request\");\n \t\treturn NULL;\n \t}\n \n \thttp_cleanup();\n \n-\tdata = buffer.buffer;\n+\tdata = buffer.buf;\n \tstart = NULL;\n \tmid = data;\n-\twhile (i < buffer.posn) {\n+\twhile (i < buffer.len) {\n \t\tif (!start)\n \t\t\tstart = &data[i];\n \t\tif (data[i] == '\\t')\n@@ -520,7 +514,7 @@ static struct ref *get_refs_via_curl(struct transport *transport)\n \t\ti++;\n \t}\n \n-\tfree(buffer.buffer);\n+\tstrbuf_release(&buffer);\n \n \treturn refs;\n }\n-- \n1.5.3.7\n"},{"id":"62493","messageId":"1197219900-19334-3-git-send-email-mh@glandium.org","threadId":"11214","inReplyTo":"1197219900-19334-2-git-send-email-mh@glandium.org","subject":"[PATCH 3/4] Move the file read logic to read_patch_file() in builtin-apply.c","fromName":"Mike Hommey","fromEmail":"mh@glandium.org","sentAt":"2007-12-09T17:04:59Z","receivedAt":"2007-12-09T17:04:59Z","isPatch":true,"sender":{"key":"mh@glandium.org","avatar":"https://avatars.githubusercontent.com/u/1038527?v=4"},"body":"This will allow to extend the read logic further. We also return a better\nerror message than usage() when the given filename can't be opened, and\navoid whitespace options not being set when reading from stdin with the\n\"-\" argument as a side effect.\n\nSigned-off-by: Mike Hommey <mh@glandium.org>\n---\n builtin-apply.c |   32 +++++++++++++++++---------------\n 1 files changed, 17 insertions(+), 15 deletions(-)\n\ndiff --git a/builtin-apply.c b/builtin-apply.c\nindex f2e9a33..8c8162a 100644\n--- a/builtin-apply.c\n+++ b/builtin-apply.c\n@@ -182,11 +182,23 @@ static void say_patch_name(FILE *output, const char *pre,\n #define CHUNKSIZE (8192)\n #define SLOP (16)\n \n-static void read_patch_file(struct strbuf *sb, int fd)\n+static void read_patch_file(struct strbuf *sb, const char *filename)\n {\n+\tint fd;\n+\n+\tif (!strcmp(filename, \"-\")) {\n+\t\tfd = 0;\n+\t} else {\n+\t\tfd = open(filename, O_RDONLY);\n+\t\tif (fd < 0)\n+\t\t\tdie(\"git-apply: could not open %s: %s\", filename,\n+\t\t\t    strerror(errno));\n+\t}\n+\n \tif (strbuf_read(sb, fd, 0) < 0)\n \t\tdie(\"git-apply: read returned %s\", strerror(errno));\n \n+\tclose(fd);\n \t/*\n \t * Make sure that we have some slop in the buffer\n \t * so that we can do speculative \"memcmp\" etc, and\n@@ -2705,7 +2717,7 @@ static void prefix_patches(struct patch *p)\n \t}\n }\n \n-static int apply_patch(int fd, const char *filename, int inaccurate_eof)\n+static int apply_patch(const char *filename, int inaccurate_eof)\n {\n \tsize_t offset;\n \tstruct strbuf buf;\n@@ -2714,7 +2726,7 @@ static int apply_patch(int fd, const char *filename, int inaccurate_eof)\n \n \tstrbuf_init(&buf, 0);\n \tpatch_input_file = filename;\n-\tread_patch_file(&buf, fd);\n+\tread_patch_file(&buf, filename);\n \toffset = 0;\n \twhile (offset < buf.len) {\n \t\tstruct patch *patch;\n@@ -2807,13 +2819,7 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix)\n \tfor (i = 1; i < argc; i++) {\n \t\tconst char *arg = argv[i];\n \t\tchar *end;\n-\t\tint fd;\n \n-\t\tif (!strcmp(arg, \"-\")) {\n-\t\t\terrs |= apply_patch(0, \"<stdin>\", inaccurate_eof);\n-\t\t\tread_stdin = 0;\n-\t\t\tcontinue;\n-\t\t}\n \t\tif (!prefixcmp(arg, \"--exclude=\")) {\n \t\t\tstruct excludes *x = xmalloc(sizeof(*x));\n \t\t\tx->path = arg + 10;\n@@ -2916,17 +2922,13 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix)\n \t\tif (0 < prefix_length)\n \t\t\targ = prefix_filename(prefix, prefix_length, arg);\n \n-\t\tfd = open(arg, O_RDONLY);\n-\t\tif (fd < 0)\n-\t\t\tusage(apply_usage);\n \t\tread_stdin = 0;\n \t\tset_default_whitespace_mode(whitespace_option);\n-\t\terrs |= apply_patch(fd, arg, inaccurate_eof);\n-\t\tclose(fd);\n+\t\terrs |= apply_patch(arg, inaccurate_eof);\n \t}\n \tset_default_whitespace_mode(whitespace_option);\n \tif (read_stdin)\n-\t\terrs |= apply_patch(0, \"<stdin>\", inaccurate_eof);\n+\t\terrs |= apply_patch(\"-\", inaccurate_eof);\n \tif (whitespace_error) {\n \t\tif (squelch_whitespace_errors &&\n \t\t    squelch_whitespace_errors < whitespace_error) {\n-- \n1.5.3.7\n"},{"id":"62494","messageId":"1197219900-19334-4-git-send-email-mh@glandium.org","threadId":"11214","inReplyTo":"1197219900-19334-3-git-send-email-mh@glandium.org","subject":"[PATCH 4/4] Add support for URLs to git-apply","fromName":"Mike Hommey","fromEmail":"mh@glandium.org","sentAt":"2007-12-09T17:05:00Z","receivedAt":"2007-12-09T17:05:00Z","isPatch":true,"sender":{"key":"mh@glandium.org","avatar":"https://avatars.githubusercontent.com/u/1038527?v=4"},"body":"Instead of doing several \"wget -O - url | git-apply -\" in a raw, you now\ncan just git-apply url1 url2 ...\n\nSigned-off-by: Mike Hommey <mh@glandium.org>\n---\n Documentation/git-apply.txt |    3 +-\n builtin-apply.c             |   58 ++++++++++++++++++++++++++++++++++++------\n 2 files changed, 51 insertions(+), 10 deletions(-)\n\ndiff --git a/Documentation/git-apply.txt b/Documentation/git-apply.txt\nindex bae3e7b..2d5d725 100644\n--- a/Documentation/git-apply.txt\n+++ b/Documentation/git-apply.txt\n@@ -25,7 +25,8 @@ OPTIONS\n -------\n <patch>...::\n \tThe files to read patch from.  '-' can be used to read\n-\tfrom the standard input.\n+\tfrom the standard input. They can also be http, https or\n+\tftp URLs.\n \n --stat::\n \tInstead of applying the patch, output diffstat for the\ndiff --git a/builtin-apply.c b/builtin-apply.c\nindex 8c8162a..59834f0 100644\n--- a/builtin-apply.c\n+++ b/builtin-apply.c\n@@ -12,6 +12,9 @@\n #include \"blob.h\"\n #include \"delta.h\"\n #include \"builtin.h\"\n+#ifndef NO_CURL\n+#include \"http.h\"\n+#endif\n \n /*\n  *  --check turns on checking that the working tree matches the\n@@ -182,12 +185,47 @@ static void say_patch_name(FILE *output, const char *pre,\n #define CHUNKSIZE (8192)\n #define SLOP (16)\n \n-static void read_patch_file(struct strbuf *sb, const char *filename)\n+#ifndef NO_CURL\n+static int used_http;\n+\n+static void read_patch_url(struct strbuf *sb, const char *url)\n+{\n+\tstruct active_request_slot *slot;\n+\tstruct slot_results results;\n+\n+\tif (! used_http) {\n+\t\thttp_init();\n+\t\tused_http = 1;\n+\t}\n+\n+\tslot = get_active_slot();\n+\tslot->results = &results;\n+\tcurl_easy_setopt(slot->curl, CURLOPT_FILE, sb);\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+\n+\tif (start_active_slot(slot)) {\n+\t\trun_active_slot(slot);\n+\t\tif (results.curl_result != CURLE_OK)\n+\t\t\tdie(\"git-apply: could not open %s\", url);\n+\t}\n+}\n+#endif\n+\n+static void read_patch(struct strbuf *sb, const char *filename)\n {\n \tint fd;\n \n \tif (!strcmp(filename, \"-\")) {\n \t\tfd = 0;\n+#ifndef NO_CURL\n+\t} else if (!strncmp(filename, \"http://\", 7) ||\n+\t\t   !strncmp(filename, \"https://\", 8) ||\n+\t\t   !strncmp(filename, \"ftp://\", 6)) {\n+\t\tread_patch_url(sb, filename);\n+\t\treturn;\n+#endif\n \t} else {\n \t\tfd = open(filename, O_RDONLY);\n \t\tif (fd < 0)\n@@ -199,13 +237,6 @@ static void read_patch_file(struct strbuf *sb, const char *filename)\n \t\tdie(\"git-apply: read returned %s\", strerror(errno));\n \n \tclose(fd);\n-\t/*\n-\t * Make sure that we have some slop in the buffer\n-\t * so that we can do speculative \"memcmp\" etc, and\n-\t * see to it that it is NUL-filled.\n-\t */\n-\tstrbuf_grow(sb, SLOP);\n-\tmemset(sb->buf + sb->len, 0, SLOP);\n }\n \n static unsigned long linelen(const char *buffer, unsigned long size)\n@@ -2726,7 +2757,14 @@ static int apply_patch(const char *filename, int inaccurate_eof)\n \n \tstrbuf_init(&buf, 0);\n \tpatch_input_file = filename;\n-\tread_patch_file(&buf, filename);\n+\tread_patch(&buf, filename);\n+\t/*\n+\t * Make sure that we have some slop in the buffer\n+\t * so that we can do speculative \"memcmp\" etc, and\n+\t * see to it that it is NUL-filled.\n+\t */\n+\tstrbuf_grow(&buf, SLOP);\n+\tmemset(buf.buf + buf.len, 0, SLOP);\n \toffset = 0;\n \twhile (offset < buf.len) {\n \t\tstruct patch *patch;\n@@ -2926,6 +2964,8 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix)\n \t\tset_default_whitespace_mode(whitespace_option);\n \t\terrs |= apply_patch(arg, inaccurate_eof);\n \t}\n+\tif (used_http)\n+\t\thttp_cleanup();\n \tset_default_whitespace_mode(whitespace_option);\n \tif (read_stdin)\n \t\terrs |= apply_patch(\"-\", inaccurate_eof);\n-- \n1.5.3.7\n"},{"id":"62495","messageId":"1197220648-20433-1-git-send-email-mh@glandium.org","threadId":"11214","inReplyTo":"1197219900-19334-1-git-send-email-mh@glandium.org","subject":"[PATCH] git-send-email.perl: Really add angle brackets to In-Reply-To if necessary","fromName":"Mike Hommey","fromEmail":"mh@glandium.org","sentAt":"2007-12-09T17:17:28Z","receivedAt":"2007-12-09T17:17:28Z","isPatch":true,"sender":{"key":"mh@glandium.org","avatar":"https://avatars.githubusercontent.com/u/1038527?v=4"},"body":"3803bcea tried to fix this, but it only adds the branckes when the given\nIn-Reply-To begins and ends with whitespaces. It also didn't do anything\nto the --in-reply-to argument.\n\nSigned-off-by: Mike Hommey <mh@glandium.org>\n---\n\nI just got bitten by this...\n\n git-send-email.perl |    5 +++--\n 1 files changed, 3 insertions(+), 2 deletions(-)\n\ndiff --git a/git-send-email.perl b/git-send-email.perl\nindex 76baa8e..1434eb2 100755\n--- a/git-send-email.perl\n+++ b/git-send-email.perl\n@@ -367,10 +367,11 @@ if ($thread && !defined $initial_reply_to && $prompting) {\n \t} while (!defined $_);\n \n \t$initial_reply_to = $_;\n-\t$initial_reply_to =~ s/^\\s+<?/</;\n-\t$initial_reply_to =~ s/>?\\s+$/>/;\n }\n \n+$initial_reply_to =~ s/^\\s*\\<?/\\</;\n+$initial_reply_to =~ s/>?\\s*$/>/;\n+\n if (!defined $smtp_server) {\n \tforeach (qw( /usr/sbin/sendmail /usr/lib/sendmail )) {\n \t\tif (-x $_) {\n-- \n1.5.3.7\n"},{"id":"62496","messageId":"20071209173835.GA4965@glandium.org","threadId":"11214","inReplyTo":"1197220648-20433-1-git-send-email-mh@glandium.org","subject":"Re: [PATCH] git-send-email.perl: Really add angle brackets to In-Reply-To if necessary","fromName":"Mike Hommey","fromEmail":"mh@glandium.org","sentAt":"2007-12-09T17:38:35Z","receivedAt":"2007-12-09T17:38:35Z","isPatch":true,"sender":{"key":"mh@glandium.org","avatar":"https://avatars.githubusercontent.com/u/1038527?v=4"},"body":"On Sun, Dec 09, 2007 at 06:17:28PM +0100, Mike Hommey wrote:\n> 3803bcea tried to fix this, but it only adds the branckes when the given\n\ns/branckes/brackets/\n\nMike\n"},{"id":"62498","messageId":"7v63z7rb87.fsf@gitster.siamese.dyndns.org","threadId":"11214","inReplyTo":"1197220648-20433-1-git-send-email-mh@glandium.org","subject":"Re: [PATCH] git-send-email.perl: Really add angle brackets to In-Reply-To if necessary","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-12-09T18:09:44Z","receivedAt":"2007-12-09T18:09:44Z","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> 3803bcea tried to fix this, but it only adds the branckes when the given\n> In-Reply-To begins and ends with whitespaces. It also didn't do anything\n> to the --in-reply-to argument.\n>\n> Signed-off-by: Mike Hommey <mh@glandium.org>\n> ---\n>\n> I just got bitten by this...\n\nInteresting.\n\n>\n>  git-send-email.perl |    5 +++--\n>  1 files changed, 3 insertions(+), 2 deletions(-)\n>\n> diff --git a/git-send-email.perl b/git-send-email.perl\n> index 76baa8e..1434eb2 100755\n> --- a/git-send-email.perl\n> +++ b/git-send-email.perl\n> @@ -367,10 +367,11 @@ if ($thread && !defined $initial_reply_to && $prompting) {\n>  \t} while (!defined $_);\n>  \n>  \t$initial_reply_to = $_;\n> -\t$initial_reply_to =~ s/^\\s+<?/</;\n> -\t$initial_reply_to =~ s/>?\\s+$/>/;\n>  }\n\nI wonder what the original rationale for these \\s+ was.\nWill apply, anyway.  Thanks.\n\n>  \n> +$initial_reply_to =~ s/^\\s*\\<?/\\</;\n> +$initial_reply_to =~ s/>?\\s*$/>/;\n> +\n>  if (!defined $smtp_server) {\n>  \tforeach (qw( /usr/sbin/sendmail /usr/lib/sendmail )) {\n>  \t\tif (-x $_) {\n> -- \n> 1.5.3.7\n"},{"id":"62499","messageId":"20071209181437.GA9211@glandium.org","threadId":"11214","inReplyTo":"7v63z7rb87.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH] git-send-email.perl: Really add angle brackets to In-Reply-To if necessary","fromName":"Mike Hommey","fromEmail":"mh@glandium.org","sentAt":"2007-12-09T18:14:37Z","receivedAt":"2007-12-09T18:14:37Z","isPatch":true,"sender":{"key":"mh@glandium.org","avatar":"https://avatars.githubusercontent.com/u/1038527?v=4"},"body":"On Sun, Dec 09, 2007 at 10:09:44AM -0800, Junio C Hamano wrote:\n> Mike Hommey <mh@glandium.org> writes:\n> >  git-send-email.perl |    5 +++--\n> >  1 files changed, 3 insertions(+), 2 deletions(-)\n> >\n> > diff --git a/git-send-email.perl b/git-send-email.perl\n> > index 76baa8e..1434eb2 100755\n> > --- a/git-send-email.perl\n> > +++ b/git-send-email.perl\n> > @@ -367,10 +367,11 @@ if ($thread && !defined $initial_reply_to && $prompting) {\n> >  \t} while (!defined $_);\n> >  \n> >  \t$initial_reply_to = $_;\n> > -\t$initial_reply_to =~ s/^\\s+<?/</;\n> > -\t$initial_reply_to =~ s/>?\\s+$/>/;\n> >  }\n> \n> I wonder what the original rationale for these \\s+ was.\n\nI'd say copy/paste:\n-       $initial_reply_to =~ s/(^\\s+|\\s+$)//g;\n+       $initial_reply_to =~ s/^\\s+<?/</;\n+       $initial_reply_to =~ s/>?\\s+$/>/;\n\nMike\n"},{"id":"62500","messageId":"7vy7c3pwek.fsf@gitster.siamese.dyndns.org","threadId":"11214","inReplyTo":"1197219900-19334-2-git-send-email-mh@glandium.org","subject":"Re: [PATCH 2/4] Use strbuf in http code","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-12-09T18:15:15Z","receivedAt":"2007-12-09T18:15:15Z","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> Also, replace whitespaces with tabs in some places\n>\n> Signed-off-by: Mike Hommey <mh@glandium.org>\n> ---\n>\n>  While testing this, I noticed 3 things:\n>  - CURL_MULTI makes the code very racy\n>  - a lot of the code doesn't do anything useful without CURL_MULTI\n>  - the code is redundant\n\nYeah, there does seem to be a lot of duplicated code that does common\nsetup with slightly different request string.\n\n> @@ -1115,16 +1109,11 @@ static char *quote_ref_url(const char *base, const char *ref)\n>  \n>  int fetch_ref(char *ref, unsigned char *sha1)\n>  {\n> -        char *url;\n> -        char hex[42];\n> -        struct buffer buffer;\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> -        buffer.size = 41;\n> -        buffer.posn = 0;\n> -        buffer.buffer = hex;\n> -        hex[41] = '\\0';\n>  \n>  \turl = quote_ref_url(base, ref);\n>  \tslot = get_active_slot();\n> @@ -1142,9 +1131,9 @@ int fetch_ref(char *ref, unsigned char *sha1)\n>  \t\treturn error(\"Unable to start request\");\n>  \t}\n>  \n> -        hex[40] = '\\0';\n> -        get_sha1_hex(hex, sha1);\n> -        return 0;\n> +\tbuffer.buf[40] = '\\0';\n> +\tget_sha1_hex(buffer.buf, sha1);\n> +\treturn 0;\n>  }\n\nA conversion like this is worrysome and needs to be rethought I think.\n\nAt least with the old code, we knew hex[40] was a safe location to make\nassignment to, even though we did not check if what it contained made\nsense --- the other end might have had a garbage in that URL (but the\ncaller hopefully would be responsible for noticing that).  But with your\nchange, I do not think you have that guarantee.  fwrite_buffer() may\nhave extended the buffer using strbuf API, but it may have received less\nthan what you are expecting, in which case you may not have buf[40]\ntouchable for you, no?\n\nI at the same time think the original code is buggy.  It initializes\nbuffer.buffer to the on-stack storage hex[], but lets fwrite_buffer() to\ncall xrealloc() on it.\n"},{"id":"62504","messageId":"7vbq8zpw4r.fsf@gitster.siamese.dyndns.org","threadId":"11214","inReplyTo":"1197219900-19334-1-git-send-email-mh@glandium.org","subject":"Re: [PATCH 1/4] Cleanup variables in http.[ch]","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-12-09T18:21:08Z","receivedAt":"2007-12-09T18:21:08Z","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> Quite some variables defined as extern in http.h are only used in http.c,\n> and some others, only defined in http.c, were not static.\n\nGood riddance of many globals.\n"},{"id":"62505","messageId":"851w9vsp8o.fsf@lola.goethe.zz","threadId":"11214","inReplyTo":"7v63z7rb87.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH] git-send-email.perl: Really add angle brackets to In-Reply-To if necessary","fromName":"David Kastrup","fromEmail":"dak@gnu.org","sentAt":"2007-12-09T18:21:43Z","receivedAt":"2007-12-09T18:21:43Z","isPatch":true,"sender":{"key":"dak@gnu.org","avatar":"https://avatars.githubusercontent.com/u/52141349?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Mike Hommey <mh@glandium.org> writes:\n>\n>> 3803bcea tried to fix this, but it only adds the branckes when the given\n>> In-Reply-To begins and ends with whitespaces. It also didn't do anything\n>> to the --in-reply-to argument.\n>>\n>> Signed-off-by: Mike Hommey <mh@glandium.org>\n>> ---\n>>\n>> I just got bitten by this...\n>\n> Interesting.\n\nOuch.\n\n>>  git-send-email.perl |    5 +++--\n>>  1 files changed, 3 insertions(+), 2 deletions(-)\n>>\n>> diff --git a/git-send-email.perl b/git-send-email.perl\n>> index 76baa8e..1434eb2 100755\n>> --- a/git-send-email.perl\n>> +++ b/git-send-email.perl\n>> @@ -367,10 +367,11 @@ if ($thread && !defined $initial_reply_to && $prompting) {\n>>  \t} while (!defined $_);\n>>  \n>>  \t$initial_reply_to = $_;\n>> -\t$initial_reply_to =~ s/^\\s+<?/</;\n>> -\t$initial_reply_to =~ s/>?\\s+$/>/;\n>>  }\n>\n> I wonder what the original rationale for these \\s+ was.\n> Will apply, anyway.  Thanks.\n\nThe original line read\n\n\t$initial_reply_to =~ s/(^\\s+|\\s+$)//g;\n\nand was used just for stripping spaces (no stripping necessary when\nthere is no space, so \\s+ was ok).  The change was supposed to work\non the brackets, too.\n\nThat Mike got bitten here is proof that the original idea had merit.\nToo bad the implementation did not actually work.\n\n-- \nDavid Kastrup, Kriemhildstr. 15, 44793 Bochum\n"},{"id":"62506","messageId":"20071209182408.GA9427@glandium.org","threadId":"11214","inReplyTo":"7vy7c3pwek.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH 2/4] Use strbuf in http code","fromName":"Mike Hommey","fromEmail":"mh@glandium.org","sentAt":"2007-12-09T18:24:08Z","receivedAt":"2007-12-09T18:24:08Z","isPatch":true,"sender":{"key":"mh@glandium.org","avatar":"https://avatars.githubusercontent.com/u/1038527?v=4"},"body":"On Sun, Dec 09, 2007 at 10:15:15AM -0800, Junio C Hamano wrote:\n> Mike Hommey <mh@glandium.org> writes:\n> \n> > Also, replace whitespaces with tabs in some places\n> >\n> > Signed-off-by: Mike Hommey <mh@glandium.org>\n> > ---\n> >\n> >  While testing this, I noticed 3 things:\n> >  - CURL_MULTI makes the code very racy\n> >  - a lot of the code doesn't do anything useful without CURL_MULTI\n> >  - the code is redundant\n> \n> Yeah, there does seem to be a lot of duplicated code that does common\n> setup with slightly different request string.\n> \n> > @@ -1115,16 +1109,11 @@ static char *quote_ref_url(const char *base, const char *ref)\n> >  \n> >  int fetch_ref(char *ref, unsigned char *sha1)\n> >  {\n> > -        char *url;\n> > -        char hex[42];\n> > -        struct buffer buffer;\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> > -        buffer.size = 41;\n> > -        buffer.posn = 0;\n> > -        buffer.buffer = hex;\n> > -        hex[41] = '\\0';\n> >  \n> >  \turl = quote_ref_url(base, ref);\n> >  \tslot = get_active_slot();\n> > @@ -1142,9 +1131,9 @@ int fetch_ref(char *ref, unsigned char *sha1)\n> >  \t\treturn error(\"Unable to start request\");\n> >  \t}\n> >  \n> > -        hex[40] = '\\0';\n> > -        get_sha1_hex(hex, sha1);\n> > -        return 0;\n> > +\tbuffer.buf[40] = '\\0';\n> > +\tget_sha1_hex(buffer.buf, sha1);\n> > +\treturn 0;\n> >  }\n> \n> A conversion like this is worrysome and needs to be rethought I think.\n> \n> At least with the old code, we knew hex[40] was a safe location to make\n> assignment to, even though we did not check if what it contained made\n> sense --- the other end might have had a garbage in that URL (but the\n> caller hopefully would be responsible for noticing that).  But with your\n> change, I do not think you have that guarantee.  fwrite_buffer() may\n> have extended the buffer using strbuf API, but it may have received less\n> than what you are expecting, in which case you may not have buf[40]\n> touchable for you, no?\n> \n> I at the same time think the original code is buggy.  It initializes\n> buffer.buffer to the on-stack storage hex[], but lets fwrite_buffer() to\n> call xrealloc() on it.\n\nBoth codes are also buggy in case the ref is a symbolic ref, and that\nhappens. I got bitten by this while testing.\n\nConsidering the assumption being made that refs are all properly filled\nwith sha1s, both codes are mostly equally bad.\n\nFixing the issue would obviously be the subject for another patch.\n\nMike\n"},{"id":"62508","messageId":"7v7ijnpvuy.fsf@gitster.siamese.dyndns.org","threadId":"11214","inReplyTo":"1197219900-19334-3-git-send-email-mh@glandium.org","subject":"Re: [PATCH 3/4] Move the file read logic to read_patch_file() in builtin-apply.c","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-12-09T18:27:01Z","receivedAt":"2007-12-09T18:27:01Z","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> This will allow to extend the read logic further. We also return a better\n> error message than usage() when the given filename can't be opened, and\n> avoid whitespace options not being set when reading from stdin with the\n> \"-\" argument as a side effect.\n\nI think this is a good clean-up, but I suspect that apply_patch() should\nbe further refactored to take strbuf, instead of <fd, filename>\n(original) or <filename> (yours).\n"},{"id":"62510","messageId":"7vy7c3ogu2.fsf@gitster.siamese.dyndns.org","threadId":"11214","inReplyTo":"20071209182408.GA9427@glandium.org","subject":"Re: [PATCH 2/4] Use strbuf in http code","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-12-09T18:36:53Z","receivedAt":"2007-12-09T18:36:53Z","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> Both codes are also buggy in case the ref is a symbolic ref, and that\n> happens. I got bitten by this while testing.\n>\n> Considering the assumption being made that refs are all properly filled\n> with sha1s, both codes are mostly equally bad.\n>\n> Fixing the issue would obviously be the subject for another patch.\n\nOk, I'll reject [2/4] and expect a reroll.\n"},{"id":"62511","messageId":"86aboju2bp.fsf@blue.stonehenge.com","threadId":"11214","inReplyTo":"851w9vsp8o.fsf@lola.goethe.zz","subject":"Re: [PATCH] git-send-email.perl: Really add angle brackets to In-Reply-To if necessary","fromName":"Randal L. Schwartz","fromEmail":"merlyn@stonehenge.com","sentAt":"2007-12-09T18:53:46Z","receivedAt":"2007-12-09T18:53:46Z","isPatch":true,"sender":{"key":"merlyn@stonehenge.com","avatar":"https://gravatar.com/avatar/dc528d210743ff0333e6213f9ee7b33b23f1b7bc1f3c5a8c2d819074ecd7ab19?d=mp&s=160"},"body":">>>>> \"David\" == David Kastrup <dak@gnu.org> writes:\n\n>>> $initial_reply_to = $_;\n>>> -\t$initial_reply_to =~ s/^\\s+<?/</;\n>>> -\t$initial_reply_to =~ s/>?\\s+$/>/;\n>>> }\n>> \n>> I wonder what the original rationale for these \\s+ was.\n>> Will apply, anyway.  Thanks.\n\nDavid> The original line read\n\nDavid> \t$initial_reply_to =~ s/(^\\s+|\\s+$)//g;\n\nDavid> and was used just for stripping spaces (no stripping necessary when\nDavid> there is no space, so \\s+ was ok).  The change was supposed to work\nDavid> on the brackets, too.\n\nDavid> That Mike got bitten here is proof that the original idea had merit.\nDavid> Too bad the implementation did not actually work.\n\nI think what you were trying to do would work with:\n\n  for ($initial_reply_to) {\n      s/^\\s*<?/</;\n      s/>?\\s*$/>/;\n  }\n\nUntested, but I get this stuff right most of the time. :)\n\n-- \nRandal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095\n<merlyn@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>\nPerl/Unix/security consulting, Technical writing, Comedy, etc. etc.\nSee PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!\n"},{"id":"62514","messageId":"1197228659-19459-1-git-send-email-mh@glandium.org","threadId":"11214","inReplyTo":"7vy7c3ogu2.fsf@gitster.siamese.dyndns.org","subject":"[Resend PATCH 2/4] Use strbuf in http code","fromName":"Mike Hommey","fromEmail":"mh@glandium.org","sentAt":"2007-12-09T19:30:59Z","receivedAt":"2007-12-09T19:30:59Z","isPatch":true,"sender":{"key":"mh@glandium.org","avatar":"https://avatars.githubusercontent.com/u/1038527?v=4"},"body":"Also, replace whitespaces with tabs in some places\n\nSigned-off-by: Mike Hommey <mh@glandium.org>\n---\n\n While this doesn't fix the problem with symbolic refs, it does fail more\n cleanly.\n\n http-push.c   |  187 +++++++++++++++++++--------------------------------------\n http-walker.c |   60 +++++++------------\n http.c        |   34 ++++------\n http.h        |   11 ++--\n transport.c   |   18 ++----\n 5 files changed, 109 insertions(+), 201 deletions(-)\n\ndiff --git a/http-push.c b/http-push.c\nindex 78283b4..a69d0e3 100644\n--- a/http-push.c\n+++ b/http-push.c\n@@ -495,10 +495,10 @@ static void start_put(struct transfer_request *request)\n \tmemset(&stream, 0, sizeof(stream));\n \tdeflateInit(&stream, zlib_compression_level);\n \tsize = deflateBound(&stream, len + hdrlen);\n-\trequest->buffer.buffer = xmalloc(size);\n+\tstrbuf_init(&request->buffer.buf, size);\n \n \t/* Compress it */\n-\tstream.next_out = request->buffer.buffer;\n+\tstream.next_out = (unsigned char *)request->buffer.buf.buf;\n \tstream.avail_out = size;\n \n \t/* First header.. */\n@@ -515,8 +515,7 @@ static void start_put(struct transfer_request *request)\n \tdeflateEnd(&stream);\n \tfree(unpacked);\n \n-\trequest->buffer.size = stream.total_out;\n-\trequest->buffer.posn = 0;\n+\trequest->buffer.buf.len = stream.total_out;\n \n \trequest->url = xmalloc(strlen(remote->url) +\n \t\t\t       strlen(request->lock->token) + 51);\n@@ -538,7 +537,7 @@ static void start_put(struct transfer_request *request)\n \tslot->callback_func = process_response;\n \tslot->callback_data = request;\n \tcurl_easy_setopt(slot->curl, CURLOPT_INFILE, &request->buffer);\n-\tcurl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, request->buffer.size);\n+\tcurl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, request->buffer.buf.len);\n \tcurl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, fread_buffer);\n \tcurl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_null);\n \tcurl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_PUT);\n@@ -1003,18 +1002,13 @@ static int fetch_indices(void)\n {\n \tunsigned char sha1[20];\n \tchar *url;\n-\tstruct buffer buffer;\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-\tdata = xcalloc(1, 4096);\n-\tbuffer.size = 4096;\n-\tbuffer.posn = 0;\n-\tbuffer.buffer = data;\n-\n \tif (push_verbosely)\n \t\tfprintf(stderr, \"Getting pack list\\n\");\n \n@@ -1030,7 +1024,7 @@ static int fetch_indices(void)\n \tif (start_active_slot(slot)) {\n \t\trun_active_slot(slot);\n \t\tif (results.curl_result != CURLE_OK) {\n-\t\t\tfree(buffer.buffer);\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@@ -1038,18 +1032,18 @@ static int fetch_indices(void)\n \t\t\t\treturn error(\"%s\", curl_errorstr);\n \t\t}\n \t} else {\n-\t\tfree(buffer.buffer);\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.buffer;\n-\twhile (i < buffer.posn) {\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.posn &&\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@@ -1064,7 +1058,7 @@ static int fetch_indices(void)\n \t\ti++;\n \t}\n \n-\tfree(buffer.buffer);\n+\tstrbuf_release(&buffer);\n \treturn 0;\n }\n \n@@ -1115,16 +1109,11 @@ static char *quote_ref_url(const char *base, const char *ref)\n \n int fetch_ref(char *ref, unsigned char *sha1)\n {\n-        char *url;\n-        char hex[42];\n-        struct buffer buffer;\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-        buffer.size = 41;\n-        buffer.posn = 0;\n-        buffer.buffer = hex;\n-        hex[41] = '\\0';\n \n \turl = quote_ref_url(base, ref);\n \tslot = get_active_slot();\n@@ -1142,9 +1131,10 @@ int fetch_ref(char *ref, unsigned char *sha1)\n \t\treturn error(\"Unable to start request\");\n \t}\n \n-        hex[40] = '\\0';\n-        get_sha1_hex(hex, sha1);\n-        return 0;\n+\tstrbuf_rtrim(&buffer);\n+\tif (buffer.len != 40)\n+\t\treturn 1;\n+\treturn get_sha1_hex(buffer.buf, sha1);\n }\n \n static void one_remote_object(const char *hex)\n@@ -1267,10 +1257,8 @@ static struct remote_lock *lock_remote(const char *path, long timeout)\n {\n \tstruct active_request_slot *slot;\n \tstruct slot_results results;\n-\tstruct buffer out_buffer;\n-\tstruct buffer in_buffer;\n-\tchar *out_data;\n-\tchar *in_data;\n+\tstruct buffer out_buffer = { 0, STRBUF_INIT };\n+\tstruct strbuf in_buffer = STRBUF_INIT;\n \tchar *url;\n \tchar *ep;\n \tchar timeout_header[25];\n@@ -1312,16 +1300,7 @@ static struct remote_lock *lock_remote(const char *path, long timeout)\n \t\tep = strchr(ep + 1, '/');\n \t}\n \n-\tout_buffer.size = strlen(LOCK_REQUEST) + strlen(git_default_email) - 2;\n-\tout_data = xmalloc(out_buffer.size + 1);\n-\tsnprintf(out_data, out_buffer.size + 1, LOCK_REQUEST, git_default_email);\n-\tout_buffer.posn = 0;\n-\tout_buffer.buffer = out_data;\n-\n-\tin_buffer.size = 4096;\n-\tin_data = xmalloc(in_buffer.size);\n-\tin_buffer.posn = 0;\n-\tin_buffer.buffer = in_data;\n+\tstrbuf_addf(&out_buffer.buf, LOCK_REQUEST, git_default_email);\n \n \tsprintf(timeout_header, \"Timeout: Second-%ld\", timeout);\n \tdav_headers = curl_slist_append(dav_headers, timeout_header);\n@@ -1330,7 +1309,7 @@ static struct remote_lock *lock_remote(const char *path, long timeout)\n \tslot = get_active_slot();\n \tslot->results = &results;\n \tcurl_easy_setopt(slot->curl, CURLOPT_INFILE, &out_buffer);\n-\tcurl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, out_buffer.size);\n+\tcurl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, out_buffer.buf.len);\n \tcurl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, fread_buffer);\n \tcurl_easy_setopt(slot->curl, CURLOPT_FILE, &in_buffer);\n \tcurl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer);\n@@ -1354,8 +1333,8 @@ static struct remote_lock *lock_remote(const char *path, long timeout)\n \t\t\tXML_SetElementHandler(parser, xml_start_tag,\n \t\t\t\t\t      xml_end_tag);\n \t\t\tXML_SetCharacterDataHandler(parser, xml_cdata);\n-\t\t\tresult = XML_Parse(parser, in_buffer.buffer,\n-\t\t\t\t\t   in_buffer.posn, 1);\n+\t\t\tresult = XML_Parse(parser, in_buffer.buf,\n+\t\t\t\t\t   in_buffer.len, 1);\n \t\t\tfree(ctx.name);\n \t\t\tif (result != XML_STATUS_OK) {\n \t\t\t\tfprintf(stderr, \"XML error: %s\\n\",\n@@ -1369,8 +1348,8 @@ static struct remote_lock *lock_remote(const char *path, long timeout)\n \t}\n \n \tcurl_slist_free_all(dav_headers);\n-\tfree(out_data);\n-\tfree(in_data);\n+\tstrbuf_release(&out_buffer.buf);\n+\tstrbuf_release(&in_buffer);\n \n \tif (lock->token == NULL || lock->timeout <= 0) {\n \t\tif (lock->token != NULL)\n@@ -1521,10 +1500,8 @@ static void remote_ls(const char *path, int flags,\n \tchar *url = xmalloc(strlen(remote->url) + strlen(path) + 1);\n \tstruct active_request_slot *slot;\n \tstruct slot_results results;\n-\tstruct buffer in_buffer;\n-\tstruct buffer out_buffer;\n-\tchar *in_data;\n-\tchar *out_data;\n+\tstruct strbuf in_buffer = STRBUF_INIT;\n+\tstruct buffer out_buffer = { 0, STRBUF_INIT };\n \tXML_Parser parser = XML_ParserCreate(NULL);\n \tenum XML_Status result;\n \tstruct curl_slist *dav_headers = NULL;\n@@ -1540,16 +1517,7 @@ static void remote_ls(const char *path, int flags,\n \n \tsprintf(url, \"%s%s\", remote->url, path);\n \n-\tout_buffer.size = strlen(PROPFIND_ALL_REQUEST);\n-\tout_data = xmalloc(out_buffer.size + 1);\n-\tsnprintf(out_data, out_buffer.size + 1, PROPFIND_ALL_REQUEST);\n-\tout_buffer.posn = 0;\n-\tout_buffer.buffer = out_data;\n-\n-\tin_buffer.size = 4096;\n-\tin_data = xmalloc(in_buffer.size);\n-\tin_buffer.posn = 0;\n-\tin_buffer.buffer = in_data;\n+\tstrbuf_addf(&out_buffer.buf, PROPFIND_ALL_REQUEST);\n \n \tdav_headers = curl_slist_append(dav_headers, \"Depth: 1\");\n \tdav_headers = curl_slist_append(dav_headers, \"Content-Type: text/xml\");\n@@ -1557,7 +1525,7 @@ static void remote_ls(const char *path, int flags,\n \tslot = get_active_slot();\n \tslot->results = &results;\n \tcurl_easy_setopt(slot->curl, CURLOPT_INFILE, &out_buffer);\n-\tcurl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, out_buffer.size);\n+\tcurl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, out_buffer.buf.len);\n \tcurl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, fread_buffer);\n \tcurl_easy_setopt(slot->curl, CURLOPT_FILE, &in_buffer);\n \tcurl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer);\n@@ -1578,8 +1546,8 @@ static void remote_ls(const char *path, int flags,\n \t\t\tXML_SetElementHandler(parser, xml_start_tag,\n \t\t\t\t\t      xml_end_tag);\n \t\t\tXML_SetCharacterDataHandler(parser, xml_cdata);\n-\t\t\tresult = XML_Parse(parser, in_buffer.buffer,\n-\t\t\t\t\t   in_buffer.posn, 1);\n+\t\t\tresult = XML_Parse(parser, in_buffer.buf,\n+\t\t\t\t\t   in_buffer.len, 1);\n \t\t\tfree(ctx.name);\n \n \t\t\tif (result != XML_STATUS_OK) {\n@@ -1594,8 +1562,8 @@ static void remote_ls(const char *path, int flags,\n \n \tfree(ls.path);\n \tfree(url);\n-\tfree(out_data);\n-\tfree(in_buffer.buffer);\n+\tstrbuf_release(&out_buffer.buf);\n+\tstrbuf_release(&in_buffer);\n \tcurl_slist_free_all(dav_headers);\n }\n \n@@ -1616,29 +1584,15 @@ static int locking_available(void)\n {\n \tstruct active_request_slot *slot;\n \tstruct slot_results results;\n-\tstruct buffer in_buffer;\n-\tstruct buffer out_buffer;\n-\tchar *in_data;\n-\tchar *out_data;\n+\tstruct strbuf in_buffer = STRBUF_INIT;\n+\tstruct buffer out_buffer = { 0, STRBUF_INIT };\n \tXML_Parser parser = XML_ParserCreate(NULL);\n \tenum XML_Status result;\n \tstruct curl_slist *dav_headers = NULL;\n \tstruct xml_ctx ctx;\n \tint lock_flags = 0;\n \n-\tout_buffer.size =\n-\t\tstrlen(PROPFIND_SUPPORTEDLOCK_REQUEST) +\n-\t\tstrlen(remote->url) - 2;\n-\tout_data = xmalloc(out_buffer.size + 1);\n-\tsnprintf(out_data, out_buffer.size + 1,\n-\t\t PROPFIND_SUPPORTEDLOCK_REQUEST, remote->url);\n-\tout_buffer.posn = 0;\n-\tout_buffer.buffer = out_data;\n-\n-\tin_buffer.size = 4096;\n-\tin_data = xmalloc(in_buffer.size);\n-\tin_buffer.posn = 0;\n-\tin_buffer.buffer = in_data;\n+\tstrbuf_addf(&out_buffer.buf, PROPFIND_SUPPORTEDLOCK_REQUEST, remote->url);\n \n \tdav_headers = curl_slist_append(dav_headers, \"Depth: 0\");\n \tdav_headers = curl_slist_append(dav_headers, \"Content-Type: text/xml\");\n@@ -1646,7 +1600,7 @@ static int locking_available(void)\n \tslot = get_active_slot();\n \tslot->results = &results;\n \tcurl_easy_setopt(slot->curl, CURLOPT_INFILE, &out_buffer);\n-\tcurl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, out_buffer.size);\n+\tcurl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, out_buffer.buf.len);\n \tcurl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, fread_buffer);\n \tcurl_easy_setopt(slot->curl, CURLOPT_FILE, &in_buffer);\n \tcurl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer);\n@@ -1666,8 +1620,8 @@ static int locking_available(void)\n \t\t\tXML_SetUserData(parser, &ctx);\n \t\t\tXML_SetElementHandler(parser, xml_start_tag,\n \t\t\t\t\t      xml_end_tag);\n-\t\t\tresult = XML_Parse(parser, in_buffer.buffer,\n-\t\t\t\t\t   in_buffer.posn, 1);\n+\t\t\tresult = XML_Parse(parser, in_buffer.buf,\n+\t\t\t\t\t   in_buffer.len, 1);\n \t\t\tfree(ctx.name);\n \n \t\t\tif (result != XML_STATUS_OK) {\n@@ -1681,8 +1635,8 @@ static int locking_available(void)\n \t\tfprintf(stderr, \"Unable to start PROPFIND request\\n\");\n \t}\n \n-\tfree(out_data);\n-\tfree(in_buffer.buffer);\n+\tstrbuf_release(&out_buffer.buf);\n+\tstrbuf_release(&in_buffer);\n \tcurl_slist_free_all(dav_headers);\n \n \treturn lock_flags;\n@@ -1800,30 +1754,20 @@ static int update_remote(unsigned char *sha1, struct remote_lock *lock)\n {\n \tstruct active_request_slot *slot;\n \tstruct slot_results results;\n-\tchar *out_data;\n \tchar *if_header;\n-\tstruct buffer out_buffer;\n+\tstruct buffer out_buffer = { 0, STRBUF_INIT };\n \tstruct curl_slist *dav_headers = NULL;\n-\tint i;\n \n \tif_header = xmalloc(strlen(lock->token) + 25);\n \tsprintf(if_header, \"If: (<opaquelocktoken:%s>)\", lock->token);\n \tdav_headers = curl_slist_append(dav_headers, if_header);\n \n-\tout_buffer.size = 41;\n-\tout_data = xmalloc(out_buffer.size + 1);\n-\ti = snprintf(out_data, out_buffer.size + 1, \"%s\\n\", sha1_to_hex(sha1));\n-\tif (i != out_buffer.size) {\n-\t\tfprintf(stderr, \"Unable to initialize PUT request body\\n\");\n-\t\treturn 0;\n-\t}\n-\tout_buffer.posn = 0;\n-\tout_buffer.buffer = out_data;\n+\tstrbuf_addf(&out_buffer.buf, \"%s\\n\", sha1_to_hex(sha1));\n \n \tslot = get_active_slot();\n \tslot->results = &results;\n \tcurl_easy_setopt(slot->curl, CURLOPT_INFILE, &out_buffer);\n-\tcurl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, out_buffer.size);\n+\tcurl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, out_buffer.buf.len);\n \tcurl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, fread_buffer);\n \tcurl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_null);\n \tcurl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_PUT);\n@@ -1834,7 +1778,7 @@ static int update_remote(unsigned char *sha1, struct remote_lock *lock)\n \n \tif (start_active_slot(slot)) {\n \t\trun_active_slot(slot);\n-\t\tfree(out_data);\n+\t\tstrbuf_release(&out_buffer.buf);\n \t\tfree(if_header);\n \t\tif (results.curl_result != CURLE_OK) {\n \t\t\tfprintf(stderr,\n@@ -1844,7 +1788,7 @@ static int update_remote(unsigned char *sha1, struct remote_lock *lock)\n \t\t\treturn 0;\n \t\t}\n \t} else {\n-\t\tfree(out_data);\n+\t\tstrbuf_release(&out_buffer.buf);\n \t\tfree(if_header);\n \t\tfprintf(stderr, \"Unable to start PUT request\\n\");\n \t\treturn 0;\n@@ -2001,7 +1945,7 @@ static void mark_edges_uninteresting(struct commit_list *list)\n \n static void add_remote_info_ref(struct remote_ls_ctx *ls)\n {\n-\tstruct buffer *buf = (struct buffer *)ls->userData;\n+\tstruct strbuf *buf = (struct strbuf *)ls->userData;\n \tunsigned char remote_sha1[20];\n \tstruct object *o;\n \tint len;\n@@ -2046,17 +1990,14 @@ static void add_remote_info_ref(struct remote_ls_ctx *ls)\n \n static void update_remote_info_refs(struct remote_lock *lock)\n {\n-\tstruct buffer buffer;\n+\tstruct buffer buffer = { 0, STRBUF_INIT };\n \tstruct active_request_slot *slot;\n \tstruct slot_results results;\n \tchar *if_header;\n \tstruct curl_slist *dav_headers = NULL;\n \n-\tbuffer.buffer = xcalloc(1, 4096);\n-\tbuffer.size = 4096;\n-\tbuffer.posn = 0;\n \tremote_ls(\"refs/\", (PROCESS_FILES | RECURSIVE),\n-\t\t  add_remote_info_ref, &buffer);\n+\t\t  add_remote_info_ref, &buffer.buf);\n \tif (!aborted) {\n \t\tif_header = xmalloc(strlen(lock->token) + 25);\n \t\tsprintf(if_header, \"If: (<opaquelocktoken:%s>)\", lock->token);\n@@ -2065,7 +2006,7 @@ static void update_remote_info_refs(struct remote_lock *lock)\n \t\tslot = get_active_slot();\n \t\tslot->results = &results;\n \t\tcurl_easy_setopt(slot->curl, CURLOPT_INFILE, &buffer);\n-\t\tcurl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, buffer.posn);\n+\t\tcurl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, buffer.buf.len);\n \t\tcurl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, fread_buffer);\n \t\tcurl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_null);\n \t\tcurl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_PUT);\n@@ -2074,8 +2015,6 @@ static void update_remote_info_refs(struct remote_lock *lock)\n \t\tcurl_easy_setopt(slot->curl, CURLOPT_PUT, 1);\n \t\tcurl_easy_setopt(slot->curl, CURLOPT_URL, lock->url);\n \n-\t\tbuffer.posn = 0;\n-\n \t\tif (start_active_slot(slot)) {\n \t\t\trun_active_slot(slot);\n \t\t\tif (results.curl_result != CURLE_OK) {\n@@ -2086,7 +2025,7 @@ static void update_remote_info_refs(struct remote_lock *lock)\n \t\t}\n \t\tfree(if_header);\n \t}\n-\tfree(buffer.buffer);\n+\tstrbuf_release(&buffer.buf);\n }\n \n static int remote_exists(const char *path)\n@@ -2097,12 +2036,12 @@ static int remote_exists(const char *path)\n \n \tsprintf(url, \"%s%s\", remote->url, path);\n \n-        slot = get_active_slot();\n+\tslot = get_active_slot();\n \tslot->results = &results;\n-        curl_easy_setopt(slot->curl, CURLOPT_URL, url);\n-        curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 1);\n+\tcurl_easy_setopt(slot->curl, CURLOPT_URL, url);\n+\tcurl_easy_setopt(slot->curl, CURLOPT_NOBODY, 1);\n \n-        if (start_active_slot(slot)) {\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@@ -2120,17 +2059,13 @@ static int remote_exists(const char *path)\n static void fetch_symref(const char *path, char **symref, unsigned char *sha1)\n {\n \tchar *url;\n-\tstruct buffer buffer;\n+\tstruct strbuf buffer = STRBUF_INIT;\n \tstruct active_request_slot *slot;\n \tstruct slot_results results;\n \n \turl = xmalloc(strlen(remote->url) + strlen(path) + 1);\n \tsprintf(url, \"%s%s\", remote->url, path);\n \n-\tbuffer.size = 4096;\n-\tbuffer.posn = 0;\n-\tbuffer.buffer = xmalloc(buffer.size);\n-\n \tslot = get_active_slot();\n \tslot->results = &results;\n \tcurl_easy_setopt(slot->curl, CURLOPT_FILE, &buffer);\n@@ -2153,17 +2088,17 @@ static void fetch_symref(const char *path, char **symref, unsigned char *sha1)\n \t*symref = NULL;\n \thashclr(sha1);\n \n-\tif (buffer.posn == 0)\n+\tif (buffer.len == 0)\n \t\treturn;\n \n \t/* If it's a symref, set the refname; otherwise try for a sha1 */\n-\tif (!prefixcmp((char *)buffer.buffer, \"ref: \")) {\n-\t\t*symref = xmemdupz((char *)buffer.buffer + 5, buffer.posn - 6);\n+\tif (!prefixcmp((char *)buffer.buf, \"ref: \")) {\n+\t\t*symref = xmemdupz((char *)buffer.buf + 5, buffer.len - 6);\n \t} else {\n-\t\tget_sha1_hex(buffer.buffer, sha1);\n+\t\tget_sha1_hex(buffer.buf, sha1);\n \t}\n \n-\tfree(buffer.buffer);\n+\tstrbuf_release(&buffer);\n }\n \n static int verify_merge_base(unsigned char *head_sha1, unsigned char *branch_sha1)\ndiff --git a/http-walker.c b/http-walker.c\nindex a3fb596..d9a5f1e 100644\n--- a/http-walker.c\n+++ b/http-walker.c\n@@ -48,7 +48,7 @@ struct alternates_request {\n \tstruct walker *walker;\n \tconst char *base;\n \tchar *url;\n-\tstruct buffer *buffer;\n+\tstruct strbuf *buffer;\n \tstruct active_request_slot *slot;\n \tint http_specific;\n };\n@@ -475,7 +475,7 @@ static void process_alternates_response(void *callback_data)\n \n \tif (alt_req->http_specific) {\n \t\tif (slot->curl_result != CURLE_OK ||\n-\t\t    !alt_req->buffer->posn) {\n+\t\t    !alt_req->buffer->len) {\n \n \t\t\t/* Try reusing the slot to get non-http alternates */\n \t\t\talt_req->http_specific = 0;\n@@ -503,12 +503,12 @@ static void process_alternates_response(void *callback_data)\n \t}\n \n \tfwrite_buffer(&null_byte, 1, 1, alt_req->buffer);\n-\talt_req->buffer->posn--;\n-\tdata = alt_req->buffer->buffer;\n+\talt_req->buffer->len--;\n+\tdata = alt_req->buffer->buf;\n \n-\twhile (i < alt_req->buffer->posn) {\n+\twhile (i < alt_req->buffer->len) {\n \t\tint posn = i;\n-\t\twhile (posn < alt_req->buffer->posn && data[posn] != '\\n')\n+\t\twhile (posn < alt_req->buffer->len && data[posn] != '\\n')\n \t\t\tposn++;\n \t\tif (data[posn] == '\\n') {\n \t\t\tint okay = 0;\n@@ -596,9 +596,8 @@ static void process_alternates_response(void *callback_data)\n \n static void fetch_alternates(struct walker *walker, const char *base)\n {\n-\tstruct buffer buffer;\n+\tstruct strbuf buffer = STRBUF_INIT;\n \tchar *url;\n-\tchar *data;\n \tstruct active_request_slot *slot;\n \tstruct alternates_request alt_req;\n \tstruct walker_data *cdata = walker->data;\n@@ -619,11 +618,6 @@ static void fetch_alternates(struct walker *walker, const char *base)\n \t/* Start the fetch */\n \tcdata->got_alternates = 0;\n \n-\tdata = xmalloc(4096);\n-\tbuffer.size = 4096;\n-\tbuffer.posn = 0;\n-\tbuffer.buffer = data;\n-\n \tif (walker->get_verbosely)\n \t\tfprintf(stderr, \"Getting alternates list for %s\\n\", base);\n \n@@ -652,7 +646,7 @@ static void fetch_alternates(struct walker *walker, const char *base)\n \telse\n \t\tcdata->got_alternates = -1;\n \n-\tfree(data);\n+\tstrbuf_release(&buffer);\n \tfree(url);\n }\n \n@@ -660,7 +654,7 @@ static int fetch_indices(struct walker *walker, struct alt_base *repo)\n {\n \tunsigned char sha1[20];\n \tchar *url;\n-\tstruct buffer buffer;\n+\tstruct strbuf buffer = STRBUF_INIT;\n \tchar *data;\n \tint i = 0;\n \n@@ -670,11 +664,6 @@ static int fetch_indices(struct walker *walker, struct alt_base *repo)\n \tif (repo->got_indices)\n \t\treturn 0;\n \n-\tdata = xmalloc(4096);\n-\tbuffer.size = 4096;\n-\tbuffer.posn = 0;\n-\tbuffer.buffer = data;\n-\n \tif (walker->get_verbosely)\n \t\tfprintf(stderr, \"Getting pack list for %s\\n\", repo->base);\n \n@@ -690,28 +679,27 @@ 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\tfree(buffer.buffer);\n \t\t\t\treturn 0;\n \t\t\t} else {\n \t\t\t\trepo->got_indices = 0;\n-\t\t\t\tfree(buffer.buffer);\n \t\t\t\treturn error(\"%s\", curl_errorstr);\n \t\t\t}\n \t\t}\n \t} else {\n \t\trepo->got_indices = 0;\n-\t\tfree(buffer.buffer);\n+\t\tstrbuf_release(&buffer);\n \t\treturn error(\"Unable to start request\");\n \t}\n \n-\tdata = buffer.buffer;\n-\twhile (i < buffer.posn) {\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.posn &&\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@@ -720,13 +708,13 @@ static int fetch_indices(struct walker *walker, struct alt_base *repo)\n \t\t\t\tbreak;\n \t\t\t}\n \t\tdefault:\n-\t\t\twhile (i < buffer.posn && data[i] != '\\n')\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-\tfree(buffer.buffer);\n+\tstrbuf_release(&buffer);\n \trepo->got_indices = 1;\n \treturn 0;\n }\n@@ -958,17 +946,12 @@ static char *quote_ref_url(const char *base, const char *ref)\n \n static int fetch_ref(struct walker *walker, char *ref, unsigned char *sha1)\n {\n-        char *url;\n-        char hex[42];\n-        struct buffer buffer;\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-        buffer.size = 41;\n-        buffer.posn = 0;\n-        buffer.buffer = hex;\n-        hex[41] = '\\0';\n \n \turl = quote_ref_url(base, ref);\n \tslot = get_active_slot();\n@@ -986,9 +969,10 @@ static int fetch_ref(struct walker *walker, char *ref, unsigned char *sha1)\n \t\treturn error(\"Unable to start request\");\n \t}\n \n-        hex[40] = '\\0';\n-        get_sha1_hex(hex, sha1);\n-        return 0;\n+\tstrbuf_rtrim(&buffer);\n+\tif (buffer.len != 40)\n+\t\treturn 1;\n+\treturn get_sha1_hex(buffer.buf, sha1);\n }\n \n static void cleanup(struct walker *walker)\ndiff --git a/http.c b/http.c\nindex 146f626..2d0b46d 100644\n--- a/http.c\n+++ b/http.c\n@@ -34,31 +34,25 @@ size_t fread_buffer(void *ptr, size_t eltsize, size_t nmemb,\n \t\t\t   struct buffer *buffer)\n {\n \tsize_t size = eltsize * nmemb;\n-\tif (size > buffer->size - buffer->posn)\n-\t\tsize = buffer->size - buffer->posn;\n-\tmemcpy(ptr, (char *) buffer->buffer + buffer->posn, size);\n+\tif (size > buffer->buf.len - buffer->posn)\n+\t\tsize = buffer->buf.len - buffer->posn;\n+\tmemcpy(ptr, (char *) buffer->buf.buf + buffer->posn, size);\n \tbuffer->posn += size;\n+\n \treturn size;\n }\n \n size_t fwrite_buffer(const void *ptr, size_t eltsize,\n-\t\t\t    size_t nmemb, struct buffer *buffer)\n+\t\t\t    size_t nmemb, struct strbuf *buffer)\n {\n \tsize_t size = eltsize * nmemb;\n-\tif (size > buffer->size - buffer->posn) {\n-\t\tbuffer->size = buffer->size * 3 / 2;\n-\t\tif (buffer->size < buffer->posn + size)\n-\t\t\tbuffer->size = buffer->posn + size;\n-\t\tbuffer->buffer = xrealloc(buffer->buffer, buffer->size);\n-\t}\n-\tmemcpy((char *) buffer->buffer + buffer->posn, ptr, size);\n-\tbuffer->posn += size;\n+\tstrbuf_add(buffer, ptr, size);\n \tdata_received++;\n \treturn size;\n }\n \n size_t fwrite_null(const void *ptr, size_t eltsize,\n-\t\t\t  size_t nmemb, struct buffer *buffer)\n+\t\t\t  size_t nmemb, struct strbuf *buffer)\n {\n \tdata_received++;\n \treturn eltsize * nmemb;\n@@ -508,8 +502,8 @@ void run_active_slot(struct active_request_slot *slot)\n \n static void closedown_active_slot(struct active_request_slot *slot)\n {\n-        active_requests--;\n-        slot->in_use = 0;\n+\tactive_requests--;\n+\tslot->in_use = 0;\n }\n \n void release_active_slot(struct active_request_slot *slot)\n@@ -530,7 +524,7 @@ void release_active_slot(struct active_request_slot *slot)\n static void finish_active_slot(struct active_request_slot *slot)\n {\n \tclosedown_active_slot(slot);\n-        curl_easy_getinfo(slot->curl, CURLINFO_HTTP_CODE, &slot->http_code);\n+\tcurl_easy_getinfo(slot->curl, CURLINFO_HTTP_CODE, &slot->http_code);\n \n \tif (slot->finished != NULL)\n \t\t(*slot->finished) = 1;\n@@ -541,10 +535,10 @@ static void finish_active_slot(struct active_request_slot *slot)\n \t\tslot->results->http_code = slot->http_code;\n \t}\n \n-        /* Run callback if appropriate */\n-        if (slot->callback_func != NULL) {\n-                slot->callback_func(slot->callback_data);\n-        }\n+\t/* Run callback if appropriate */\n+\tif (slot->callback_func != NULL) {\n+\t\tslot->callback_func(slot->callback_data);\n+\t}\n }\n \n void finish_all_active_slots(void)\ndiff --git a/http.h b/http.h\nindex fe1b0d1..bf3f12c 100644\n--- a/http.h\n+++ b/http.h\n@@ -6,6 +6,8 @@\n #include <curl/curl.h>\n #include <curl/easy.h>\n \n+#include \"strbuf.h\"\n+\n #if LIBCURL_VERSION_NUM >= 0x071000\n #define USE_CURL_MULTI\n #define DEFAULT_MAX_REQUESTS 5\n@@ -48,18 +50,17 @@ struct active_request_slot\n \n struct buffer\n {\n-        size_t posn;\n-        size_t size;\n-        void *buffer;\n+\tstruct strbuf buf;\n+\tsize_t posn;\n };\n \n /* Curl request read/write callbacks */\n extern size_t fread_buffer(void *ptr, size_t eltsize, size_t nmemb,\n \t\t\t   struct buffer *buffer);\n extern size_t fwrite_buffer(const void *ptr, size_t eltsize,\n-\t\t\t    size_t nmemb, struct buffer *buffer);\n+\t\t\t    size_t nmemb, struct strbuf *buffer);\n extern size_t fwrite_null(const void *ptr, size_t eltsize,\n-\t\t\t  size_t nmemb, struct buffer *buffer);\n+\t\t\t  size_t nmemb, struct strbuf *buffer);\n \n /* Slot lifecycle functions */\n extern struct active_request_slot *get_active_slot(void);\ndiff --git a/transport.c b/transport.c\nindex 58e66f6..22234e8 100644\n--- a/transport.c\n+++ b/transport.c\n@@ -441,7 +441,7 @@ static int missing__target(int code, int result)\n \n static struct ref *get_refs_via_curl(struct transport *transport)\n {\n-\tstruct buffer buffer;\n+\tstruct strbuf buffer = STRBUF_INIT;\n \tchar *data, *start, *mid;\n \tchar *ref_name;\n \tchar *refs_url;\n@@ -454,11 +454,6 @@ static struct ref *get_refs_via_curl(struct transport *transport)\n \tstruct ref *ref = NULL;\n \tstruct ref *last_ref = NULL;\n \n-\tdata = xmalloc(4096);\n-\tbuffer.size = 4096;\n-\tbuffer.posn = 0;\n-\tbuffer.buffer = data;\n-\n \trefs_url = xmalloc(strlen(transport->url) + 11);\n \tsprintf(refs_url, \"%s/info/refs\", transport->url);\n \n@@ -477,27 +472,26 @@ static struct ref *get_refs_via_curl(struct transport *transport)\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\tfree(buffer.buffer);\n \t\t\t\treturn NULL;\n \t\t\t} else {\n-\t\t\t\tfree(buffer.buffer);\n \t\t\t\terror(\"%s\", curl_errorstr);\n \t\t\t\treturn NULL;\n \t\t\t}\n \t\t}\n \t} else {\n-\t\tfree(buffer.buffer);\n+\t\tstrbuf_release(&buffer);\n \t\terror(\"Unable to start request\");\n \t\treturn NULL;\n \t}\n \n \thttp_cleanup();\n \n-\tdata = buffer.buffer;\n+\tdata = buffer.buf;\n \tstart = NULL;\n \tmid = data;\n-\twhile (i < buffer.posn) {\n+\twhile (i < buffer.len) {\n \t\tif (!start)\n \t\t\tstart = &data[i];\n \t\tif (data[i] == '\\t')\n@@ -520,7 +514,7 @@ static struct ref *get_refs_via_curl(struct transport *transport)\n \t\ti++;\n \t}\n \n-\tfree(buffer.buffer);\n+\tstrbuf_release(&buffer);\n \n \treturn refs;\n }\n-- \n1.5.3.7\n"},{"id":"62516","messageId":"85lk83r6qq.fsf@lola.goethe.zz","threadId":"11214","inReplyTo":"86aboju2bp.fsf@blue.stonehenge.com","subject":"Re: [PATCH] git-send-email.perl: Really add angle brackets to In-Reply-To if necessary","fromName":"David Kastrup","fromEmail":"dak@gnu.org","sentAt":"2007-12-09T19:46:37Z","receivedAt":"2007-12-09T19:46:37Z","isPatch":true,"sender":{"key":"dak@gnu.org","avatar":"https://avatars.githubusercontent.com/u/52141349?v=4"},"body":"merlyn@stonehenge.com (Randal L. Schwartz) writes:\n\n> I think what you were trying to do would work with:\n>\n>   for ($initial_reply_to) {\n>       s/^\\s*<?/</;\n>       s/>?\\s*$/>/;\n>   }\n>\n> Untested, but I get this stuff right most of the time. :)\n\nHow is that supposed to differ from Mike's patch?\n\n-- \nDavid Kastrup, Kriemhildstr. 15, 44793 Bochum\n"},{"id":"62517","messageId":"8663z7tznv.fsf@blue.stonehenge.com","threadId":"11214","inReplyTo":"85lk83r6qq.fsf@lola.goethe.zz","subject":"Re: [PATCH] git-send-email.perl: Really add angle brackets to In-Reply-To if necessary","fromName":"Randal L. Schwartz","fromEmail":"merlyn@stonehenge.com","sentAt":"2007-12-09T19:51:16Z","receivedAt":"2007-12-09T19:51:16Z","isPatch":true,"sender":{"key":"merlyn@stonehenge.com","avatar":"https://gravatar.com/avatar/dc528d210743ff0333e6213f9ee7b33b23f1b7bc1f3c5a8c2d819074ecd7ab19?d=mp&s=160"},"body":">>>>> \"David\" == David Kastrup <dak@gnu.org> writes:\n\nDavid> How is that supposed to differ from Mike's patch?\n\nNow that I've seen it, not a bit.  Sorry, was solving the problem that had\nalready been solved, in a slightly different way.\n\nOh, you don't need to \\ the < and > though.  Cleans it up a bit\nif you get rid of those.\n\n-- \nRandal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095\n<merlyn@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>\nPerl/Unix/security consulting, Technical writing, Comedy, etc. etc.\nSee PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!\n"},{"id":"62519","messageId":"1197230339-22756-1-git-send-email-mh@glandium.org","threadId":"11214","inReplyTo":"8663z7tznv.fsf@blue.stonehenge.com","subject":"[Resend PATCH] git-send-email.perl: Really add angle brackets to In-Reply-To if necessary","fromName":"Mike Hommey","fromEmail":"mh@glandium.org","sentAt":"2007-12-09T19:58:59Z","receivedAt":"2007-12-09T19:58:59Z","isPatch":true,"sender":{"key":"mh@glandium.org","avatar":"https://avatars.githubusercontent.com/u/1038527?v=4"},"body":"3803bcea tried to fix this, but it only adds the branckes when the given\nIn-Reply-To begins and ends with whitespaces. It also didn't do anything\nto the --in-reply-to argument.\n\nSigned-off-by: Mike Hommey <mh@glandium.org>\n---\n\nRandal L. Schwartz wrote:\n> Oh, you don't need to \\ the < and > though.  Cleans it up a bit\n> if you get rid of those.\n\nDoh', I forgot to remove them. Here is a cleaned out patch.\n\n git-send-email.perl |    5 +++--\n 1 files changed, 3 insertions(+), 2 deletions(-)\n\ndiff --git a/git-send-email.perl b/git-send-email.perl\nindex 76baa8e..c0e1dd3 100755\n--- a/git-send-email.perl\n+++ b/git-send-email.perl\n@@ -367,10 +367,11 @@ if ($thread && !defined $initial_reply_to && $prompting) {\n \t} while (!defined $_);\n \n \t$initial_reply_to = $_;\n-\t$initial_reply_to =~ s/^\\s+<?/</;\n-\t$initial_reply_to =~ s/>?\\s+$/>/;\n }\n \n+$initial_reply_to =~ s/^\\s*<?/</;\n+$initial_reply_to =~ s/>?\\s*$/>/;\n+\n if (!defined $smtp_server) {\n \tforeach (qw( /usr/sbin/sendmail /usr/lib/sendmail )) {\n \t\tif (-x $_) {\n-- \n1.5.3.7\n"},{"id":"62553","messageId":"1197277618-13727-1-git-send-email-mh@glandium.org","threadId":"11214","inReplyTo":"1197219900-19334-4-git-send-email-mh@glandium.org","subject":"[Replacement PATCH 4/4] Add support for URLs to git-apply","fromName":"Mike Hommey","fromEmail":"mh@glandium.org","sentAt":"2007-12-10T09:06:58Z","receivedAt":"2007-12-10T09:06:58Z","isPatch":true,"sender":{"key":"mh@glandium.org","avatar":"https://avatars.githubusercontent.com/u/1038527?v=4"},"body":"Instead of doing several \"wget -O - url | git-apply -\" in a raw, you now\ncan just git-apply url1 url2 ...\n\nSigned-off-by: Mike Hommey <mh@glandium.org>\n---\n\n A #ifndef NO_CURL was missing in the previous patch.\n\n Documentation/git-apply.txt |    3 +-\n builtin-apply.c             |   60 ++++++++++++++++++++++++++++++++++++------\n 2 files changed, 53 insertions(+), 10 deletions(-)\n\ndiff --git a/Documentation/git-apply.txt b/Documentation/git-apply.txt\nindex bae3e7b..2d5d725 100644\n--- a/Documentation/git-apply.txt\n+++ b/Documentation/git-apply.txt\n@@ -25,7 +25,8 @@ OPTIONS\n -------\n <patch>...::\n \tThe files to read patch from.  '-' can be used to read\n-\tfrom the standard input.\n+\tfrom the standard input. They can also be http, https or\n+\tftp URLs.\n \n --stat::\n \tInstead of applying the patch, output diffstat for the\ndiff --git a/builtin-apply.c b/builtin-apply.c\nindex 8c8162a..28645c7 100644\n--- a/builtin-apply.c\n+++ b/builtin-apply.c\n@@ -12,6 +12,9 @@\n #include \"blob.h\"\n #include \"delta.h\"\n #include \"builtin.h\"\n+#ifndef NO_CURL\n+#include \"http.h\"\n+#endif\n \n /*\n  *  --check turns on checking that the working tree matches the\n@@ -182,12 +185,47 @@ static void say_patch_name(FILE *output, const char *pre,\n #define CHUNKSIZE (8192)\n #define SLOP (16)\n \n-static void read_patch_file(struct strbuf *sb, const char *filename)\n+#ifndef NO_CURL\n+static int used_http;\n+\n+static void read_patch_url(struct strbuf *sb, const char *url)\n+{\n+\tstruct active_request_slot *slot;\n+\tstruct slot_results results;\n+\n+\tif (! used_http) {\n+\t\thttp_init();\n+\t\tused_http = 1;\n+\t}\n+\n+\tslot = get_active_slot();\n+\tslot->results = &results;\n+\tcurl_easy_setopt(slot->curl, CURLOPT_FILE, sb);\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+\n+\tif (start_active_slot(slot)) {\n+\t\trun_active_slot(slot);\n+\t\tif (results.curl_result != CURLE_OK)\n+\t\t\tdie(\"git-apply: could not open %s\", url);\n+\t}\n+}\n+#endif\n+\n+static void read_patch(struct strbuf *sb, const char *filename)\n {\n \tint fd;\n \n \tif (!strcmp(filename, \"-\")) {\n \t\tfd = 0;\n+#ifndef NO_CURL\n+\t} else if (!strncmp(filename, \"http://\", 7) ||\n+\t\t   !strncmp(filename, \"https://\", 8) ||\n+\t\t   !strncmp(filename, \"ftp://\", 6)) {\n+\t\tread_patch_url(sb, filename);\n+\t\treturn;\n+#endif\n \t} else {\n \t\tfd = open(filename, O_RDONLY);\n \t\tif (fd < 0)\n@@ -199,13 +237,6 @@ static void read_patch_file(struct strbuf *sb, const char *filename)\n \t\tdie(\"git-apply: read returned %s\", strerror(errno));\n \n \tclose(fd);\n-\t/*\n-\t * Make sure that we have some slop in the buffer\n-\t * so that we can do speculative \"memcmp\" etc, and\n-\t * see to it that it is NUL-filled.\n-\t */\n-\tstrbuf_grow(sb, SLOP);\n-\tmemset(sb->buf + sb->len, 0, SLOP);\n }\n \n static unsigned long linelen(const char *buffer, unsigned long size)\n@@ -2726,7 +2757,14 @@ static int apply_patch(const char *filename, int inaccurate_eof)\n \n \tstrbuf_init(&buf, 0);\n \tpatch_input_file = filename;\n-\tread_patch_file(&buf, filename);\n+\tread_patch(&buf, filename);\n+\t/*\n+\t * Make sure that we have some slop in the buffer\n+\t * so that we can do speculative \"memcmp\" etc, and\n+\t * see to it that it is NUL-filled.\n+\t */\n+\tstrbuf_grow(&buf, SLOP);\n+\tmemset(buf.buf + buf.len, 0, SLOP);\n \toffset = 0;\n \twhile (offset < buf.len) {\n \t\tstruct patch *patch;\n@@ -2926,6 +2964,10 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix)\n \t\tset_default_whitespace_mode(whitespace_option);\n \t\terrs |= apply_patch(arg, inaccurate_eof);\n \t}\n+#ifndef NO_CURL\n+\tif (used_http)\n+\t\thttp_cleanup();\n+#endif\n \tset_default_whitespace_mode(whitespace_option);\n \tif (read_stdin)\n \t\terrs |= apply_patch(\"-\", inaccurate_eof);\n-- \n1.5.3.7.1148.gcfe7\n"},{"id":"62657","messageId":"7vlk81him3.fsf@gitster.siamese.dyndns.org","threadId":"11214","inReplyTo":"1197228659-19459-1-git-send-email-mh@glandium.org","subject":"Re: [Resend PATCH 2/4] Use strbuf in http code","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-12-11T06:04:52Z","receivedAt":"2007-12-11T06:04:52Z","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> Also, replace whitespaces with tabs in some places\n>\n> Signed-off-by: Mike Hommey <mh@glandium.org>\n> ---\n>\n>  While this doesn't fix the problem with symbolic refs, it does fail more\n>  cleanly.\n>\n>  http-push.c   |  187 +++++++++++++++++++--------------------------------------\n>  http-walker.c |   60 +++++++------------\n>  http.c        |   34 ++++------\n>  http.h        |   11 ++--\n>  transport.c   |   18 ++----\n>  5 files changed, 109 insertions(+), 201 deletions(-)\n\nI like this code reduction, but\n\n> diff --git a/http.h b/http.h\n> index fe1b0d1..bf3f12c 100644\n> --- a/http.h\n> +++ b/http.h\n> @@ -6,6 +6,8 @@\n>  #include <curl/curl.h>\n>  #include <curl/easy.h>\n>  \n> +#include \"strbuf.h\"\n> +\n>  #if LIBCURL_VERSION_NUM >= 0x071000\n>  #define USE_CURL_MULTI\n>  #define DEFAULT_MAX_REQUESTS 5\n> @@ -48,18 +50,17 @@ struct active_request_slot\n>  \n>  struct buffer\n>  {\n> -        size_t posn;\n> -        size_t size;\n> -        void *buffer;\n> +\tstruct strbuf buf;\n> +\tsize_t posn;\n>  };\n\nWith this definition of \"struct buffer\", I do not think this can be correct.\n\n> @@ -1267,10 +1257,8 @@ static struct remote_lock *lock_remote(const char *path, long timeout)\n>  {\n>  \tstruct active_request_slot *slot;\n>  \tstruct slot_results results;\n> -\tstruct buffer out_buffer;\n> -\tstruct buffer in_buffer;\n> -\tchar *out_data;\n> -\tchar *in_data;\n> +\tstruct buffer out_buffer = { 0, STRBUF_INIT };\n\nHow seriously have you proofread and tested this series before sending\nit out?\n"},{"id":"62658","messageId":"20071211061620.GA8047@glandium.org","threadId":"11214","inReplyTo":"7vlk81him3.fsf@gitster.siamese.dyndns.org","subject":"Re: [Resend PATCH 2/4] Use strbuf in http code","fromName":"Mike Hommey","fromEmail":"mh@glandium.org","sentAt":"2007-12-11T06:16:20Z","receivedAt":"2007-12-11T06:16:20Z","isPatch":true,"sender":{"key":"mh@glandium.org","avatar":"https://avatars.githubusercontent.com/u/1038527?v=4"},"body":"On Mon, Dec 10, 2007 at 10:04:52PM -0800, Junio C Hamano wrote:\n> Mike Hommey <mh@glandium.org> writes:\n> >  struct buffer\n> >  {\n> > -        size_t posn;\n> > -        size_t size;\n> > -        void *buffer;\n> > +\tstruct strbuf buf;\n> > +\tsize_t posn;\n> >  };\n> \n> With this definition of \"struct buffer\", I do not think this can be correct.\n> \n> > @@ -1267,10 +1257,8 @@ static struct remote_lock *lock_remote(const char *path, long timeout)\n> >  {\n> >  \tstruct active_request_slot *slot;\n> >  \tstruct slot_results results;\n> > -\tstruct buffer out_buffer;\n> > -\tstruct buffer in_buffer;\n> > -\tchar *out_data;\n> > -\tchar *in_data;\n> > +\tstruct buffer out_buffer = { 0, STRBUF_INIT };\n> \n> How seriously have you proofread and tested this series before sending\n> it out?\n\nDamn ! I did fix this on sunday and was pretty sure to have sent it :-/\n\nMike\n"},{"id":"62662","messageId":"1197354338-9473-1-git-send-email-mh@glandium.org","threadId":"11214","inReplyTo":"20071211061620.GA8047@glandium.org","subject":"[Replacement PATCH 2/4] Use strbuf in http code","fromName":"Mike Hommey","fromEmail":"mh@glandium.org","sentAt":"2007-12-11T06:25:38Z","receivedAt":"2007-12-11T06:25:38Z","isPatch":true,"sender":{"key":"mh@glandium.org","avatar":"https://avatars.githubusercontent.com/u/1038527?v=4"},"body":"Also, replace whitespaces with tabs in some places\n\nSigned-off-by: Mike Hommey <mh@glandium.org>\n---\n http-push.c   |  187 +++++++++++++++++++--------------------------------------\n http-walker.c |   60 +++++++------------\n http.c        |   34 ++++------\n http.h        |   11 ++--\n transport.c   |   18 ++----\n 5 files changed, 109 insertions(+), 201 deletions(-)\n\ndiff --git a/http-push.c b/http-push.c\nindex 78283b4..a69d0e3 100644\n--- a/http-push.c\n+++ b/http-push.c\n@@ -495,10 +495,10 @@ static void start_put(struct transfer_request *request)\n \tmemset(&stream, 0, sizeof(stream));\n \tdeflateInit(&stream, zlib_compression_level);\n \tsize = deflateBound(&stream, len + hdrlen);\n-\trequest->buffer.buffer = xmalloc(size);\n+\tstrbuf_init(&request->buffer.buf, size);\n \n \t/* Compress it */\n-\tstream.next_out = request->buffer.buffer;\n+\tstream.next_out = (unsigned char *)request->buffer.buf.buf;\n \tstream.avail_out = size;\n \n \t/* First header.. */\n@@ -515,8 +515,7 @@ static void start_put(struct transfer_request *request)\n \tdeflateEnd(&stream);\n \tfree(unpacked);\n \n-\trequest->buffer.size = stream.total_out;\n-\trequest->buffer.posn = 0;\n+\trequest->buffer.buf.len = stream.total_out;\n \n \trequest->url = xmalloc(strlen(remote->url) +\n \t\t\t       strlen(request->lock->token) + 51);\n@@ -538,7 +537,7 @@ static void start_put(struct transfer_request *request)\n \tslot->callback_func = process_response;\n \tslot->callback_data = request;\n \tcurl_easy_setopt(slot->curl, CURLOPT_INFILE, &request->buffer);\n-\tcurl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, request->buffer.size);\n+\tcurl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, request->buffer.buf.len);\n \tcurl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, fread_buffer);\n \tcurl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_null);\n \tcurl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_PUT);\n@@ -1003,18 +1002,13 @@ static int fetch_indices(void)\n {\n \tunsigned char sha1[20];\n \tchar *url;\n-\tstruct buffer buffer;\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-\tdata = xcalloc(1, 4096);\n-\tbuffer.size = 4096;\n-\tbuffer.posn = 0;\n-\tbuffer.buffer = data;\n-\n \tif (push_verbosely)\n \t\tfprintf(stderr, \"Getting pack list\\n\");\n \n@@ -1030,7 +1024,7 @@ static int fetch_indices(void)\n \tif (start_active_slot(slot)) {\n \t\trun_active_slot(slot);\n \t\tif (results.curl_result != CURLE_OK) {\n-\t\t\tfree(buffer.buffer);\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@@ -1038,18 +1032,18 @@ static int fetch_indices(void)\n \t\t\t\treturn error(\"%s\", curl_errorstr);\n \t\t}\n \t} else {\n-\t\tfree(buffer.buffer);\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.buffer;\n-\twhile (i < buffer.posn) {\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.posn &&\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@@ -1064,7 +1058,7 @@ static int fetch_indices(void)\n \t\ti++;\n \t}\n \n-\tfree(buffer.buffer);\n+\tstrbuf_release(&buffer);\n \treturn 0;\n }\n \n@@ -1115,16 +1109,11 @@ static char *quote_ref_url(const char *base, const char *ref)\n \n int fetch_ref(char *ref, unsigned char *sha1)\n {\n-        char *url;\n-        char hex[42];\n-        struct buffer buffer;\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-        buffer.size = 41;\n-        buffer.posn = 0;\n-        buffer.buffer = hex;\n-        hex[41] = '\\0';\n \n \turl = quote_ref_url(base, ref);\n \tslot = get_active_slot();\n@@ -1142,9 +1131,10 @@ int fetch_ref(char *ref, unsigned char *sha1)\n \t\treturn error(\"Unable to start request\");\n \t}\n \n-        hex[40] = '\\0';\n-        get_sha1_hex(hex, sha1);\n-        return 0;\n+\tstrbuf_rtrim(&buffer);\n+\tif (buffer.len != 40)\n+\t\treturn 1;\n+\treturn get_sha1_hex(buffer.buf, sha1);\n }\n \n static void one_remote_object(const char *hex)\n@@ -1267,10 +1257,8 @@ static struct remote_lock *lock_remote(const char *path, long timeout)\n {\n \tstruct active_request_slot *slot;\n \tstruct slot_results results;\n-\tstruct buffer out_buffer;\n-\tstruct buffer in_buffer;\n-\tchar *out_data;\n-\tchar *in_data;\n+\tstruct buffer out_buffer = { 0, STRBUF_INIT };\n+\tstruct strbuf in_buffer = STRBUF_INIT;\n \tchar *url;\n \tchar *ep;\n \tchar timeout_header[25];\n@@ -1312,16 +1300,7 @@ static struct remote_lock *lock_remote(const char *path, long timeout)\n \t\tep = strchr(ep + 1, '/');\n \t}\n \n-\tout_buffer.size = strlen(LOCK_REQUEST) + strlen(git_default_email) - 2;\n-\tout_data = xmalloc(out_buffer.size + 1);\n-\tsnprintf(out_data, out_buffer.size + 1, LOCK_REQUEST, git_default_email);\n-\tout_buffer.posn = 0;\n-\tout_buffer.buffer = out_data;\n-\n-\tin_buffer.size = 4096;\n-\tin_data = xmalloc(in_buffer.size);\n-\tin_buffer.posn = 0;\n-\tin_buffer.buffer = in_data;\n+\tstrbuf_addf(&out_buffer.buf, LOCK_REQUEST, git_default_email);\n \n \tsprintf(timeout_header, \"Timeout: Second-%ld\", timeout);\n \tdav_headers = curl_slist_append(dav_headers, timeout_header);\n@@ -1330,7 +1309,7 @@ static struct remote_lock *lock_remote(const char *path, long timeout)\n \tslot = get_active_slot();\n \tslot->results = &results;\n \tcurl_easy_setopt(slot->curl, CURLOPT_INFILE, &out_buffer);\n-\tcurl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, out_buffer.size);\n+\tcurl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, out_buffer.buf.len);\n \tcurl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, fread_buffer);\n \tcurl_easy_setopt(slot->curl, CURLOPT_FILE, &in_buffer);\n \tcurl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer);\n@@ -1354,8 +1333,8 @@ static struct remote_lock *lock_remote(const char *path, long timeout)\n \t\t\tXML_SetElementHandler(parser, xml_start_tag,\n \t\t\t\t\t      xml_end_tag);\n \t\t\tXML_SetCharacterDataHandler(parser, xml_cdata);\n-\t\t\tresult = XML_Parse(parser, in_buffer.buffer,\n-\t\t\t\t\t   in_buffer.posn, 1);\n+\t\t\tresult = XML_Parse(parser, in_buffer.buf,\n+\t\t\t\t\t   in_buffer.len, 1);\n \t\t\tfree(ctx.name);\n \t\t\tif (result != XML_STATUS_OK) {\n \t\t\t\tfprintf(stderr, \"XML error: %s\\n\",\n@@ -1369,8 +1348,8 @@ static struct remote_lock *lock_remote(const char *path, long timeout)\n \t}\n \n \tcurl_slist_free_all(dav_headers);\n-\tfree(out_data);\n-\tfree(in_data);\n+\tstrbuf_release(&out_buffer.buf);\n+\tstrbuf_release(&in_buffer);\n \n \tif (lock->token == NULL || lock->timeout <= 0) {\n \t\tif (lock->token != NULL)\n@@ -1521,10 +1500,8 @@ static void remote_ls(const char *path, int flags,\n \tchar *url = xmalloc(strlen(remote->url) + strlen(path) + 1);\n \tstruct active_request_slot *slot;\n \tstruct slot_results results;\n-\tstruct buffer in_buffer;\n-\tstruct buffer out_buffer;\n-\tchar *in_data;\n-\tchar *out_data;\n+\tstruct strbuf in_buffer = STRBUF_INIT;\n+\tstruct buffer out_buffer = { 0, STRBUF_INIT };\n \tXML_Parser parser = XML_ParserCreate(NULL);\n \tenum XML_Status result;\n \tstruct curl_slist *dav_headers = NULL;\n@@ -1540,16 +1517,7 @@ static void remote_ls(const char *path, int flags,\n \n \tsprintf(url, \"%s%s\", remote->url, path);\n \n-\tout_buffer.size = strlen(PROPFIND_ALL_REQUEST);\n-\tout_data = xmalloc(out_buffer.size + 1);\n-\tsnprintf(out_data, out_buffer.size + 1, PROPFIND_ALL_REQUEST);\n-\tout_buffer.posn = 0;\n-\tout_buffer.buffer = out_data;\n-\n-\tin_buffer.size = 4096;\n-\tin_data = xmalloc(in_buffer.size);\n-\tin_buffer.posn = 0;\n-\tin_buffer.buffer = in_data;\n+\tstrbuf_addf(&out_buffer.buf, PROPFIND_ALL_REQUEST);\n \n \tdav_headers = curl_slist_append(dav_headers, \"Depth: 1\");\n \tdav_headers = curl_slist_append(dav_headers, \"Content-Type: text/xml\");\n@@ -1557,7 +1525,7 @@ static void remote_ls(const char *path, int flags,\n \tslot = get_active_slot();\n \tslot->results = &results;\n \tcurl_easy_setopt(slot->curl, CURLOPT_INFILE, &out_buffer);\n-\tcurl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, out_buffer.size);\n+\tcurl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, out_buffer.buf.len);\n \tcurl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, fread_buffer);\n \tcurl_easy_setopt(slot->curl, CURLOPT_FILE, &in_buffer);\n \tcurl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer);\n@@ -1578,8 +1546,8 @@ static void remote_ls(const char *path, int flags,\n \t\t\tXML_SetElementHandler(parser, xml_start_tag,\n \t\t\t\t\t      xml_end_tag);\n \t\t\tXML_SetCharacterDataHandler(parser, xml_cdata);\n-\t\t\tresult = XML_Parse(parser, in_buffer.buffer,\n-\t\t\t\t\t   in_buffer.posn, 1);\n+\t\t\tresult = XML_Parse(parser, in_buffer.buf,\n+\t\t\t\t\t   in_buffer.len, 1);\n \t\t\tfree(ctx.name);\n \n \t\t\tif (result != XML_STATUS_OK) {\n@@ -1594,8 +1562,8 @@ static void remote_ls(const char *path, int flags,\n \n \tfree(ls.path);\n \tfree(url);\n-\tfree(out_data);\n-\tfree(in_buffer.buffer);\n+\tstrbuf_release(&out_buffer.buf);\n+\tstrbuf_release(&in_buffer);\n \tcurl_slist_free_all(dav_headers);\n }\n \n@@ -1616,29 +1584,15 @@ static int locking_available(void)\n {\n \tstruct active_request_slot *slot;\n \tstruct slot_results results;\n-\tstruct buffer in_buffer;\n-\tstruct buffer out_buffer;\n-\tchar *in_data;\n-\tchar *out_data;\n+\tstruct strbuf in_buffer = STRBUF_INIT;\n+\tstruct buffer out_buffer = { 0, STRBUF_INIT };\n \tXML_Parser parser = XML_ParserCreate(NULL);\n \tenum XML_Status result;\n \tstruct curl_slist *dav_headers = NULL;\n \tstruct xml_ctx ctx;\n \tint lock_flags = 0;\n \n-\tout_buffer.size =\n-\t\tstrlen(PROPFIND_SUPPORTEDLOCK_REQUEST) +\n-\t\tstrlen(remote->url) - 2;\n-\tout_data = xmalloc(out_buffer.size + 1);\n-\tsnprintf(out_data, out_buffer.size + 1,\n-\t\t PROPFIND_SUPPORTEDLOCK_REQUEST, remote->url);\n-\tout_buffer.posn = 0;\n-\tout_buffer.buffer = out_data;\n-\n-\tin_buffer.size = 4096;\n-\tin_data = xmalloc(in_buffer.size);\n-\tin_buffer.posn = 0;\n-\tin_buffer.buffer = in_data;\n+\tstrbuf_addf(&out_buffer.buf, PROPFIND_SUPPORTEDLOCK_REQUEST, remote->url);\n \n \tdav_headers = curl_slist_append(dav_headers, \"Depth: 0\");\n \tdav_headers = curl_slist_append(dav_headers, \"Content-Type: text/xml\");\n@@ -1646,7 +1600,7 @@ static int locking_available(void)\n \tslot = get_active_slot();\n \tslot->results = &results;\n \tcurl_easy_setopt(slot->curl, CURLOPT_INFILE, &out_buffer);\n-\tcurl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, out_buffer.size);\n+\tcurl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, out_buffer.buf.len);\n \tcurl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, fread_buffer);\n \tcurl_easy_setopt(slot->curl, CURLOPT_FILE, &in_buffer);\n \tcurl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer);\n@@ -1666,8 +1620,8 @@ static int locking_available(void)\n \t\t\tXML_SetUserData(parser, &ctx);\n \t\t\tXML_SetElementHandler(parser, xml_start_tag,\n \t\t\t\t\t      xml_end_tag);\n-\t\t\tresult = XML_Parse(parser, in_buffer.buffer,\n-\t\t\t\t\t   in_buffer.posn, 1);\n+\t\t\tresult = XML_Parse(parser, in_buffer.buf,\n+\t\t\t\t\t   in_buffer.len, 1);\n \t\t\tfree(ctx.name);\n \n \t\t\tif (result != XML_STATUS_OK) {\n@@ -1681,8 +1635,8 @@ static int locking_available(void)\n \t\tfprintf(stderr, \"Unable to start PROPFIND request\\n\");\n \t}\n \n-\tfree(out_data);\n-\tfree(in_buffer.buffer);\n+\tstrbuf_release(&out_buffer.buf);\n+\tstrbuf_release(&in_buffer);\n \tcurl_slist_free_all(dav_headers);\n \n \treturn lock_flags;\n@@ -1800,30 +1754,20 @@ static int update_remote(unsigned char *sha1, struct remote_lock *lock)\n {\n \tstruct active_request_slot *slot;\n \tstruct slot_results results;\n-\tchar *out_data;\n \tchar *if_header;\n-\tstruct buffer out_buffer;\n+\tstruct buffer out_buffer = { 0, STRBUF_INIT };\n \tstruct curl_slist *dav_headers = NULL;\n-\tint i;\n \n \tif_header = xmalloc(strlen(lock->token) + 25);\n \tsprintf(if_header, \"If: (<opaquelocktoken:%s>)\", lock->token);\n \tdav_headers = curl_slist_append(dav_headers, if_header);\n \n-\tout_buffer.size = 41;\n-\tout_data = xmalloc(out_buffer.size + 1);\n-\ti = snprintf(out_data, out_buffer.size + 1, \"%s\\n\", sha1_to_hex(sha1));\n-\tif (i != out_buffer.size) {\n-\t\tfprintf(stderr, \"Unable to initialize PUT request body\\n\");\n-\t\treturn 0;\n-\t}\n-\tout_buffer.posn = 0;\n-\tout_buffer.buffer = out_data;\n+\tstrbuf_addf(&out_buffer.buf, \"%s\\n\", sha1_to_hex(sha1));\n \n \tslot = get_active_slot();\n \tslot->results = &results;\n \tcurl_easy_setopt(slot->curl, CURLOPT_INFILE, &out_buffer);\n-\tcurl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, out_buffer.size);\n+\tcurl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, out_buffer.buf.len);\n \tcurl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, fread_buffer);\n \tcurl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_null);\n \tcurl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_PUT);\n@@ -1834,7 +1778,7 @@ static int update_remote(unsigned char *sha1, struct remote_lock *lock)\n \n \tif (start_active_slot(slot)) {\n \t\trun_active_slot(slot);\n-\t\tfree(out_data);\n+\t\tstrbuf_release(&out_buffer.buf);\n \t\tfree(if_header);\n \t\tif (results.curl_result != CURLE_OK) {\n \t\t\tfprintf(stderr,\n@@ -1844,7 +1788,7 @@ static int update_remote(unsigned char *sha1, struct remote_lock *lock)\n \t\t\treturn 0;\n \t\t}\n \t} else {\n-\t\tfree(out_data);\n+\t\tstrbuf_release(&out_buffer.buf);\n \t\tfree(if_header);\n \t\tfprintf(stderr, \"Unable to start PUT request\\n\");\n \t\treturn 0;\n@@ -2001,7 +1945,7 @@ static void mark_edges_uninteresting(struct commit_list *list)\n \n static void add_remote_info_ref(struct remote_ls_ctx *ls)\n {\n-\tstruct buffer *buf = (struct buffer *)ls->userData;\n+\tstruct strbuf *buf = (struct strbuf *)ls->userData;\n \tunsigned char remote_sha1[20];\n \tstruct object *o;\n \tint len;\n@@ -2046,17 +1990,14 @@ static void add_remote_info_ref(struct remote_ls_ctx *ls)\n \n static void update_remote_info_refs(struct remote_lock *lock)\n {\n-\tstruct buffer buffer;\n+\tstruct buffer buffer = { 0, STRBUF_INIT };\n \tstruct active_request_slot *slot;\n \tstruct slot_results results;\n \tchar *if_header;\n \tstruct curl_slist *dav_headers = NULL;\n \n-\tbuffer.buffer = xcalloc(1, 4096);\n-\tbuffer.size = 4096;\n-\tbuffer.posn = 0;\n \tremote_ls(\"refs/\", (PROCESS_FILES | RECURSIVE),\n-\t\t  add_remote_info_ref, &buffer);\n+\t\t  add_remote_info_ref, &buffer.buf);\n \tif (!aborted) {\n \t\tif_header = xmalloc(strlen(lock->token) + 25);\n \t\tsprintf(if_header, \"If: (<opaquelocktoken:%s>)\", lock->token);\n@@ -2065,7 +2006,7 @@ static void update_remote_info_refs(struct remote_lock *lock)\n \t\tslot = get_active_slot();\n \t\tslot->results = &results;\n \t\tcurl_easy_setopt(slot->curl, CURLOPT_INFILE, &buffer);\n-\t\tcurl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, buffer.posn);\n+\t\tcurl_easy_setopt(slot->curl, CURLOPT_INFILESIZE, buffer.buf.len);\n \t\tcurl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, fread_buffer);\n \t\tcurl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_null);\n \t\tcurl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_PUT);\n@@ -2074,8 +2015,6 @@ static void update_remote_info_refs(struct remote_lock *lock)\n \t\tcurl_easy_setopt(slot->curl, CURLOPT_PUT, 1);\n \t\tcurl_easy_setopt(slot->curl, CURLOPT_URL, lock->url);\n \n-\t\tbuffer.posn = 0;\n-\n \t\tif (start_active_slot(slot)) {\n \t\t\trun_active_slot(slot);\n \t\t\tif (results.curl_result != CURLE_OK) {\n@@ -2086,7 +2025,7 @@ static void update_remote_info_refs(struct remote_lock *lock)\n \t\t}\n \t\tfree(if_header);\n \t}\n-\tfree(buffer.buffer);\n+\tstrbuf_release(&buffer.buf);\n }\n \n static int remote_exists(const char *path)\n@@ -2097,12 +2036,12 @@ static int remote_exists(const char *path)\n \n \tsprintf(url, \"%s%s\", remote->url, path);\n \n-        slot = get_active_slot();\n+\tslot = get_active_slot();\n \tslot->results = &results;\n-        curl_easy_setopt(slot->curl, CURLOPT_URL, url);\n-        curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 1);\n+\tcurl_easy_setopt(slot->curl, CURLOPT_URL, url);\n+\tcurl_easy_setopt(slot->curl, CURLOPT_NOBODY, 1);\n \n-        if (start_active_slot(slot)) {\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@@ -2120,17 +2059,13 @@ static int remote_exists(const char *path)\n static void fetch_symref(const char *path, char **symref, unsigned char *sha1)\n {\n \tchar *url;\n-\tstruct buffer buffer;\n+\tstruct strbuf buffer = STRBUF_INIT;\n \tstruct active_request_slot *slot;\n \tstruct slot_results results;\n \n \turl = xmalloc(strlen(remote->url) + strlen(path) + 1);\n \tsprintf(url, \"%s%s\", remote->url, path);\n \n-\tbuffer.size = 4096;\n-\tbuffer.posn = 0;\n-\tbuffer.buffer = xmalloc(buffer.size);\n-\n \tslot = get_active_slot();\n \tslot->results = &results;\n \tcurl_easy_setopt(slot->curl, CURLOPT_FILE, &buffer);\n@@ -2153,17 +2088,17 @@ static void fetch_symref(const char *path, char **symref, unsigned char *sha1)\n \t*symref = NULL;\n \thashclr(sha1);\n \n-\tif (buffer.posn == 0)\n+\tif (buffer.len == 0)\n \t\treturn;\n \n \t/* If it's a symref, set the refname; otherwise try for a sha1 */\n-\tif (!prefixcmp((char *)buffer.buffer, \"ref: \")) {\n-\t\t*symref = xmemdupz((char *)buffer.buffer + 5, buffer.posn - 6);\n+\tif (!prefixcmp((char *)buffer.buf, \"ref: \")) {\n+\t\t*symref = xmemdupz((char *)buffer.buf + 5, buffer.len - 6);\n \t} else {\n-\t\tget_sha1_hex(buffer.buffer, sha1);\n+\t\tget_sha1_hex(buffer.buf, sha1);\n \t}\n \n-\tfree(buffer.buffer);\n+\tstrbuf_release(&buffer);\n }\n \n static int verify_merge_base(unsigned char *head_sha1, unsigned char *branch_sha1)\ndiff --git a/http-walker.c b/http-walker.c\nindex a3fb596..d9a5f1e 100644\n--- a/http-walker.c\n+++ b/http-walker.c\n@@ -48,7 +48,7 @@ struct alternates_request {\n \tstruct walker *walker;\n \tconst char *base;\n \tchar *url;\n-\tstruct buffer *buffer;\n+\tstruct strbuf *buffer;\n \tstruct active_request_slot *slot;\n \tint http_specific;\n };\n@@ -475,7 +475,7 @@ static void process_alternates_response(void *callback_data)\n \n \tif (alt_req->http_specific) {\n \t\tif (slot->curl_result != CURLE_OK ||\n-\t\t    !alt_req->buffer->posn) {\n+\t\t    !alt_req->buffer->len) {\n \n \t\t\t/* Try reusing the slot to get non-http alternates */\n \t\t\talt_req->http_specific = 0;\n@@ -503,12 +503,12 @@ static void process_alternates_response(void *callback_data)\n \t}\n \n \tfwrite_buffer(&null_byte, 1, 1, alt_req->buffer);\n-\talt_req->buffer->posn--;\n-\tdata = alt_req->buffer->buffer;\n+\talt_req->buffer->len--;\n+\tdata = alt_req->buffer->buf;\n \n-\twhile (i < alt_req->buffer->posn) {\n+\twhile (i < alt_req->buffer->len) {\n \t\tint posn = i;\n-\t\twhile (posn < alt_req->buffer->posn && data[posn] != '\\n')\n+\t\twhile (posn < alt_req->buffer->len && data[posn] != '\\n')\n \t\t\tposn++;\n \t\tif (data[posn] == '\\n') {\n \t\t\tint okay = 0;\n@@ -596,9 +596,8 @@ static void process_alternates_response(void *callback_data)\n \n static void fetch_alternates(struct walker *walker, const char *base)\n {\n-\tstruct buffer buffer;\n+\tstruct strbuf buffer = STRBUF_INIT;\n \tchar *url;\n-\tchar *data;\n \tstruct active_request_slot *slot;\n \tstruct alternates_request alt_req;\n \tstruct walker_data *cdata = walker->data;\n@@ -619,11 +618,6 @@ static void fetch_alternates(struct walker *walker, const char *base)\n \t/* Start the fetch */\n \tcdata->got_alternates = 0;\n \n-\tdata = xmalloc(4096);\n-\tbuffer.size = 4096;\n-\tbuffer.posn = 0;\n-\tbuffer.buffer = data;\n-\n \tif (walker->get_verbosely)\n \t\tfprintf(stderr, \"Getting alternates list for %s\\n\", base);\n \n@@ -652,7 +646,7 @@ static void fetch_alternates(struct walker *walker, const char *base)\n \telse\n \t\tcdata->got_alternates = -1;\n \n-\tfree(data);\n+\tstrbuf_release(&buffer);\n \tfree(url);\n }\n \n@@ -660,7 +654,7 @@ static int fetch_indices(struct walker *walker, struct alt_base *repo)\n {\n \tunsigned char sha1[20];\n \tchar *url;\n-\tstruct buffer buffer;\n+\tstruct strbuf buffer = STRBUF_INIT;\n \tchar *data;\n \tint i = 0;\n \n@@ -670,11 +664,6 @@ static int fetch_indices(struct walker *walker, struct alt_base *repo)\n \tif (repo->got_indices)\n \t\treturn 0;\n \n-\tdata = xmalloc(4096);\n-\tbuffer.size = 4096;\n-\tbuffer.posn = 0;\n-\tbuffer.buffer = data;\n-\n \tif (walker->get_verbosely)\n \t\tfprintf(stderr, \"Getting pack list for %s\\n\", repo->base);\n \n@@ -690,28 +679,27 @@ 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\tfree(buffer.buffer);\n \t\t\t\treturn 0;\n \t\t\t} else {\n \t\t\t\trepo->got_indices = 0;\n-\t\t\t\tfree(buffer.buffer);\n \t\t\t\treturn error(\"%s\", curl_errorstr);\n \t\t\t}\n \t\t}\n \t} else {\n \t\trepo->got_indices = 0;\n-\t\tfree(buffer.buffer);\n+\t\tstrbuf_release(&buffer);\n \t\treturn error(\"Unable to start request\");\n \t}\n \n-\tdata = buffer.buffer;\n-\twhile (i < buffer.posn) {\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.posn &&\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@@ -720,13 +708,13 @@ static int fetch_indices(struct walker *walker, struct alt_base *repo)\n \t\t\t\tbreak;\n \t\t\t}\n \t\tdefault:\n-\t\t\twhile (i < buffer.posn && data[i] != '\\n')\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-\tfree(buffer.buffer);\n+\tstrbuf_release(&buffer);\n \trepo->got_indices = 1;\n \treturn 0;\n }\n@@ -958,17 +946,12 @@ static char *quote_ref_url(const char *base, const char *ref)\n \n static int fetch_ref(struct walker *walker, char *ref, unsigned char *sha1)\n {\n-        char *url;\n-        char hex[42];\n-        struct buffer buffer;\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-        buffer.size = 41;\n-        buffer.posn = 0;\n-        buffer.buffer = hex;\n-        hex[41] = '\\0';\n \n \turl = quote_ref_url(base, ref);\n \tslot = get_active_slot();\n@@ -986,9 +969,10 @@ static int fetch_ref(struct walker *walker, char *ref, unsigned char *sha1)\n \t\treturn error(\"Unable to start request\");\n \t}\n \n-        hex[40] = '\\0';\n-        get_sha1_hex(hex, sha1);\n-        return 0;\n+\tstrbuf_rtrim(&buffer);\n+\tif (buffer.len != 40)\n+\t\treturn 1;\n+\treturn get_sha1_hex(buffer.buf, sha1);\n }\n \n static void cleanup(struct walker *walker)\ndiff --git a/http.c b/http.c\nindex 146f626..2d0b46d 100644\n--- a/http.c\n+++ b/http.c\n@@ -34,31 +34,25 @@ size_t fread_buffer(void *ptr, size_t eltsize, size_t nmemb,\n \t\t\t   struct buffer *buffer)\n {\n \tsize_t size = eltsize * nmemb;\n-\tif (size > buffer->size - buffer->posn)\n-\t\tsize = buffer->size - buffer->posn;\n-\tmemcpy(ptr, (char *) buffer->buffer + buffer->posn, size);\n+\tif (size > buffer->buf.len - buffer->posn)\n+\t\tsize = buffer->buf.len - buffer->posn;\n+\tmemcpy(ptr, (char *) buffer->buf.buf + buffer->posn, size);\n \tbuffer->posn += size;\n+\n \treturn size;\n }\n \n size_t fwrite_buffer(const void *ptr, size_t eltsize,\n-\t\t\t    size_t nmemb, struct buffer *buffer)\n+\t\t\t    size_t nmemb, struct strbuf *buffer)\n {\n \tsize_t size = eltsize * nmemb;\n-\tif (size > buffer->size - buffer->posn) {\n-\t\tbuffer->size = buffer->size * 3 / 2;\n-\t\tif (buffer->size < buffer->posn + size)\n-\t\t\tbuffer->size = buffer->posn + size;\n-\t\tbuffer->buffer = xrealloc(buffer->buffer, buffer->size);\n-\t}\n-\tmemcpy((char *) buffer->buffer + buffer->posn, ptr, size);\n-\tbuffer->posn += size;\n+\tstrbuf_add(buffer, ptr, size);\n \tdata_received++;\n \treturn size;\n }\n \n size_t fwrite_null(const void *ptr, size_t eltsize,\n-\t\t\t  size_t nmemb, struct buffer *buffer)\n+\t\t\t  size_t nmemb, struct strbuf *buffer)\n {\n \tdata_received++;\n \treturn eltsize * nmemb;\n@@ -508,8 +502,8 @@ void run_active_slot(struct active_request_slot *slot)\n \n static void closedown_active_slot(struct active_request_slot *slot)\n {\n-        active_requests--;\n-        slot->in_use = 0;\n+\tactive_requests--;\n+\tslot->in_use = 0;\n }\n \n void release_active_slot(struct active_request_slot *slot)\n@@ -530,7 +524,7 @@ void release_active_slot(struct active_request_slot *slot)\n static void finish_active_slot(struct active_request_slot *slot)\n {\n \tclosedown_active_slot(slot);\n-        curl_easy_getinfo(slot->curl, CURLINFO_HTTP_CODE, &slot->http_code);\n+\tcurl_easy_getinfo(slot->curl, CURLINFO_HTTP_CODE, &slot->http_code);\n \n \tif (slot->finished != NULL)\n \t\t(*slot->finished) = 1;\n@@ -541,10 +535,10 @@ static void finish_active_slot(struct active_request_slot *slot)\n \t\tslot->results->http_code = slot->http_code;\n \t}\n \n-        /* Run callback if appropriate */\n-        if (slot->callback_func != NULL) {\n-                slot->callback_func(slot->callback_data);\n-        }\n+\t/* Run callback if appropriate */\n+\tif (slot->callback_func != NULL) {\n+\t\tslot->callback_func(slot->callback_data);\n+\t}\n }\n \n void finish_all_active_slots(void)\ndiff --git a/http.h b/http.h\nindex fe1b0d1..a0fb4cf 100644\n--- a/http.h\n+++ b/http.h\n@@ -6,6 +6,8 @@\n #include <curl/curl.h>\n #include <curl/easy.h>\n \n+#include \"strbuf.h\"\n+\n #if LIBCURL_VERSION_NUM >= 0x071000\n #define USE_CURL_MULTI\n #define DEFAULT_MAX_REQUESTS 5\n@@ -48,18 +50,17 @@ struct active_request_slot\n \n struct buffer\n {\n-        size_t posn;\n-        size_t size;\n-        void *buffer;\n+\tsize_t posn;\n+\tstruct strbuf buf;\n };\n \n /* Curl request read/write callbacks */\n extern size_t fread_buffer(void *ptr, size_t eltsize, size_t nmemb,\n \t\t\t   struct buffer *buffer);\n extern size_t fwrite_buffer(const void *ptr, size_t eltsize,\n-\t\t\t    size_t nmemb, struct buffer *buffer);\n+\t\t\t    size_t nmemb, struct strbuf *buffer);\n extern size_t fwrite_null(const void *ptr, size_t eltsize,\n-\t\t\t  size_t nmemb, struct buffer *buffer);\n+\t\t\t  size_t nmemb, struct strbuf *buffer);\n \n /* Slot lifecycle functions */\n extern struct active_request_slot *get_active_slot(void);\ndiff --git a/transport.c b/transport.c\nindex 58e66f6..22234e8 100644\n--- a/transport.c\n+++ b/transport.c\n@@ -441,7 +441,7 @@ static int missing__target(int code, int result)\n \n static struct ref *get_refs_via_curl(struct transport *transport)\n {\n-\tstruct buffer buffer;\n+\tstruct strbuf buffer = STRBUF_INIT;\n \tchar *data, *start, *mid;\n \tchar *ref_name;\n \tchar *refs_url;\n@@ -454,11 +454,6 @@ static struct ref *get_refs_via_curl(struct transport *transport)\n \tstruct ref *ref = NULL;\n \tstruct ref *last_ref = NULL;\n \n-\tdata = xmalloc(4096);\n-\tbuffer.size = 4096;\n-\tbuffer.posn = 0;\n-\tbuffer.buffer = data;\n-\n \trefs_url = xmalloc(strlen(transport->url) + 11);\n \tsprintf(refs_url, \"%s/info/refs\", transport->url);\n \n@@ -477,27 +472,26 @@ static struct ref *get_refs_via_curl(struct transport *transport)\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\tfree(buffer.buffer);\n \t\t\t\treturn NULL;\n \t\t\t} else {\n-\t\t\t\tfree(buffer.buffer);\n \t\t\t\terror(\"%s\", curl_errorstr);\n \t\t\t\treturn NULL;\n \t\t\t}\n \t\t}\n \t} else {\n-\t\tfree(buffer.buffer);\n+\t\tstrbuf_release(&buffer);\n \t\terror(\"Unable to start request\");\n \t\treturn NULL;\n \t}\n \n \thttp_cleanup();\n \n-\tdata = buffer.buffer;\n+\tdata = buffer.buf;\n \tstart = NULL;\n \tmid = data;\n-\twhile (i < buffer.posn) {\n+\twhile (i < buffer.len) {\n \t\tif (!start)\n \t\t\tstart = &data[i];\n \t\tif (data[i] == '\\t')\n@@ -520,7 +514,7 @@ static struct ref *get_refs_via_curl(struct transport *transport)\n \t\ti++;\n \t}\n \n-\tfree(buffer.buffer);\n+\tstrbuf_release(&buffer);\n \n \treturn refs;\n }\n-- \n1.5.3.7.1161.g14b8\n"}]}