{"thread":{"id":"59107","subject":"[PATCH v6] curl: resolve deprecated curl declarations","startedAt":"2023-01-17T22:00:36Z","lastAt":"2023-01-18T07:57:57Z","messageCount":5,"participants":["Rose via GitGitGadget","Junio C Hamano"],"isPatch":true,"patchVersion":6,"patchTotal":null},"messages":[{"id":"470543","messageId":"pull.1435.v6.git.git.1673986937738.gitgitgadget@gmail.com","threadId":"59107","inReplyTo":"pull.1435.v5.git.git.1673986764553.gitgitgadget@gmail.com","subject":"[PATCH v6] curl: resolve deprecated curl declarations","fromName":"Rose via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2023-01-17T20:22:17Z","receivedAt":"2023-01-17T22:00:36Z","isPatch":true,"sender":{"key":"ckelsch@jgrcpa.com","avatar":null},"body":"From: Seija Kijin <doremylover123@gmail.com>\n\nFix CI-Alpine build by replacing deprecated\ndeclarations with their suggested replacements\n\nNote that this required changing the\ncallbacks of functions because the replacement\nfor these deprecations require a different function\nsignature for the callback and different parameters.\n\nEvery change done was made as to minimize\nchanged behavior as well as get the CI to pass again.\n\nSigned-off-by: Seija Kijin <doremylover123@gmail.com>\n---\n    curl: resolve deprecated curl declarations\n    \n    Fix CI-Alpine build by replacing deprecated declarations with their\n    suggested replacements\n    \n    Signed-off-by: Seija Kijin doremylover123@gmail.com\n\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-1435%2FAtariDreams%2Fcurl-v6\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-1435/AtariDreams/curl-v6\nPull-Request: https://github.com/git/git/pull/1435\n\nRange-diff vs v5:\n\n 1:  c8628c53d22 ! 1:  6b471a867d5 curl: resolve deprecated curl declarations\n     @@ http.c: void setup_curl_trace(CURL *handle)\n      +#ifdef GIT_CURL_HAVE_CURLOPT_PROTOCOLS_STR\n      +static void get_curl_allowed_protocols(struct strbuf *proto_buf, int from_user)\n      +{\n     -+\tunsigned int i = 0;\n     -+\n      +\tif (is_transport_allowed(\"http\", from_user)) {\n      +\t\tstrbuf_addstr(proto_buf, \"http\");\n      +\t}\n     -+\n     + \n      +\tif (is_transport_allowed(\"https\", from_user)) {\n      +\t\tif (proto_buf->len)\n      +\t\t\tstrbuf_addch(proto_buf, ',');\n      +\t\tstrbuf_addstr(proto_buf, \"https\");\n      +\t}\n     - \n     ++\n      +\tif (is_transport_allowed(\"ftp\", from_user)) {\n      +\t\tif (proto_buf->len)\n      +\t\t\tstrbuf_addch(proto_buf, ',');\n\n\n INSTALL           |  2 +-\n git-curl-compat.h |  8 ++++++\n http-push.c       |  6 ++---\n http.c            | 63 ++++++++++++++++++++++++++++++++++++++---------\n http.h            |  2 +-\n remote-curl.c     | 31 +++++++++++------------\n 6 files changed, 79 insertions(+), 33 deletions(-)\n\ndiff --git a/INSTALL b/INSTALL\nindex 33447883974..d5694f8c470 100644\n--- a/INSTALL\n+++ b/INSTALL\n@@ -139,7 +139,7 @@ Issues of note:\n \t  not need that functionality, use NO_CURL to build without\n \t  it.\n \n-\t  Git requires version \"7.19.4\" or later of \"libcurl\" to build\n+\t  Git requires version \"7.19.5\" or later of \"libcurl\" to build\n \t  without NO_CURL. This version requirement may be bumped in\n \t  the future.\n \ndiff --git a/git-curl-compat.h b/git-curl-compat.h\nindex 56a83b6bbd8..38a2237c8fe 100644\n--- a/git-curl-compat.h\n+++ b/git-curl-compat.h\n@@ -127,3 +127,11 @@\n #endif\n \n #endif\n+\n+/**\n+ * CURLOPT_PROTOCOLS_STR was added in 7.83.0, released in August\n+ * 2022.\n+ */\n+#if LIBCURL_VERSION_NUM >= 0x075500\n+#define GIT_CURL_HAVE_CURLOPT_PROTOCOLS_STR 1\n+#endif\ndiff --git a/http-push.c b/http-push.c\nindex 5f4340a36e6..7f71316456c 100644\n--- a/http-push.c\n+++ b/http-push.c\n@@ -198,13 +198,13 @@ static void curl_setup_http(CURL *curl, const char *url,\n \t\tconst char *custom_req, struct buffer *buffer,\n \t\tcurl_write_callback write_fn)\n {\n-\tcurl_easy_setopt(curl, CURLOPT_PUT, 1);\n+\tcurl_easy_setopt(curl, CURLOPT_UPLOAD, 1);\n \tcurl_easy_setopt(curl, CURLOPT_URL, url);\n \tcurl_easy_setopt(curl, CURLOPT_INFILE, buffer);\n \tcurl_easy_setopt(curl, CURLOPT_INFILESIZE, buffer->buf.len);\n \tcurl_easy_setopt(curl, CURLOPT_READFUNCTION, fread_buffer);\n-\tcurl_easy_setopt(curl, CURLOPT_IOCTLFUNCTION, ioctl_buffer);\n-\tcurl_easy_setopt(curl, CURLOPT_IOCTLDATA, buffer);\n+\tcurl_easy_setopt(curl, CURLOPT_SEEKFUNCTION, seek_buffer);\n+\tcurl_easy_setopt(curl, CURLOPT_SEEKDATA, buffer);\n \tcurl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_fn);\n \tcurl_easy_setopt(curl, CURLOPT_NOBODY, 0);\n \tcurl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, custom_req);\ndiff --git a/http.c b/http.c\nindex 8a5ba3f4776..74aa6edd1fd 100644\n--- a/http.c\n+++ b/http.c\n@@ -157,21 +157,19 @@ size_t fread_buffer(char *ptr, size_t eltsize, size_t nmemb, void *buffer_)\n \treturn size / eltsize;\n }\n \n-curlioerr ioctl_buffer(CURL *handle, int cmd, void *clientp)\n+int seek_buffer(void *userp, curl_off_t offset, int origin)\n {\n-\tstruct buffer *buffer = clientp;\n+\tstruct buffer *buffer = userp;\n \n-\tswitch (cmd) {\n-\tcase CURLIOCMD_NOP:\n-\t\treturn CURLIOE_OK;\n-\n-\tcase CURLIOCMD_RESTARTREAD:\n-\t\tbuffer->posn = 0;\n-\t\treturn CURLIOE_OK;\n-\n-\tdefault:\n-\t\treturn CURLIOE_UNKNOWNCMD;\n+\tif (origin != SEEK_SET)\n+\t\tBUG(\"seek_buffer only handles SEEK_SET\");\n+\tif (offset < 0 || offset >= buffer->buf.len) {\n+\t\terror(\"curl seek would be outside of buffer\");\n+\t\treturn CURL_SEEKFUNC_FAIL;\n \t}\n+\n+\tbuffer->posn = offset;\n+\treturn CURL_SEEKFUNC_OK;\n }\n \n size_t fwrite_buffer(char *ptr, size_t eltsize, size_t nmemb, void *buffer_)\n@@ -765,7 +763,32 @@ void setup_curl_trace(CURL *handle)\n \tcurl_easy_setopt(handle, CURLOPT_DEBUGFUNCTION, curl_trace);\n \tcurl_easy_setopt(handle, CURLOPT_DEBUGDATA, NULL);\n }\n+#ifdef GIT_CURL_HAVE_CURLOPT_PROTOCOLS_STR\n+static void get_curl_allowed_protocols(struct strbuf *proto_buf, int from_user)\n+{\n+\tif (is_transport_allowed(\"http\", from_user)) {\n+\t\tstrbuf_addstr(proto_buf, \"http\");\n+\t}\n \n+\tif (is_transport_allowed(\"https\", from_user)) {\n+\t\tif (proto_buf->len)\n+\t\t\tstrbuf_addch(proto_buf, ',');\n+\t\tstrbuf_addstr(proto_buf, \"https\");\n+\t}\n+\n+\tif (is_transport_allowed(\"ftp\", from_user)) {\n+\t\tif (proto_buf->len)\n+\t\t\tstrbuf_addch(proto_buf, ',');\n+\t\tstrbuf_addstr(proto_buf, \"ftp\");\n+\t}\n+\n+\tif (is_transport_allowed(\"ftps\", from_user)) {\n+\t\tif (proto_buf->len)\n+\t\t\tstrbuf_addch(proto_buf, ',');\n+\t\tstrbuf_addstr(proto_buf, \"ftps\");\n+\t}\n+}\n+#else\n static long get_curl_allowed_protocols(int from_user)\n {\n \tlong allowed_protocols = 0;\n@@ -781,6 +804,7 @@ static long get_curl_allowed_protocols(int from_user)\n \n \treturn allowed_protocols;\n }\n+#endif\n \n #ifdef GIT_CURL_HAVE_CURL_HTTP_VERSION_2\n static int get_curl_http_version_opt(const char *version_string, long *opt)\n@@ -923,10 +947,25 @@ static CURL *get_curl_handle(void)\n \n \tcurl_easy_setopt(result, CURLOPT_MAXREDIRS, 20);\n \tcurl_easy_setopt(result, CURLOPT_POSTREDIR, CURL_REDIR_POST_ALL);\n+#ifdef GIT_CURL_HAVE_CURLOPT_PROTOCOLS_STR\n+\t{\n+\t\tstruct strbuf buf = STRBUF_INIT;\n+\n+\t\tget_curl_allowed_protocols(&buf, 0);\n+\t\tcurl_easy_setopt(result, CURLOPT_REDIR_PROTOCOLS_STR, buf.buf);\n+\t\tstrbuf_reset(&buf);\n+\n+\t\tget_curl_allowed_protocols(&buf, -1);\n+\t\tcurl_easy_setopt(result, CURLOPT_PROTOCOLS_STR, buf.buf);\n+\t\tstrbuf_release(&buf);\n+\t}\n+#else\n \tcurl_easy_setopt(result, CURLOPT_REDIR_PROTOCOLS,\n \t\t\t get_curl_allowed_protocols(0));\n \tcurl_easy_setopt(result, CURLOPT_PROTOCOLS,\n \t\t\t get_curl_allowed_protocols(-1));\n+#endif\n+\n \tif (getenv(\"GIT_CURL_VERBOSE\"))\n \t\thttp_trace_curl_no_data();\n \tsetup_curl_trace(result);\ndiff --git a/http.h b/http.h\nindex 3c94c479100..0be9400ef53 100644\n--- a/http.h\n+++ b/http.h\n@@ -40,7 +40,7 @@ struct buffer {\n size_t fread_buffer(char *ptr, size_t eltsize, size_t nmemb, void *strbuf);\n size_t fwrite_buffer(char *ptr, size_t eltsize, size_t nmemb, void *strbuf);\n size_t fwrite_null(char *ptr, size_t eltsize, size_t nmemb, void *strbuf);\n-curlioerr ioctl_buffer(CURL *handle, int cmd, void *clientp);\n+int seek_buffer(void *userp, curl_off_t offset, int origin);\n \n /* Slot lifecycle functions */\n struct active_request_slot *get_active_slot(void);\ndiff --git a/remote-curl.c b/remote-curl.c\nindex 72dfb8fb86a..540da2b7989 100644\n--- a/remote-curl.c\n+++ b/remote-curl.c\n@@ -717,25 +717,24 @@ static size_t rpc_out(void *ptr, size_t eltsize,\n \treturn avail;\n }\n \n-static curlioerr rpc_ioctl(CURL *handle, int cmd, void *clientp)\n+static int rpc_seek(void *userp, curl_off_t offset, int origin)\n {\n-\tstruct rpc_state *rpc = clientp;\n+\tstruct rpc_state *rpc = userp;\n \n-\tswitch (cmd) {\n-\tcase CURLIOCMD_NOP:\n-\t\treturn CURLIOE_OK;\n+\tif (origin != SEEK_SET)\n+\t\tBUG(\"rpc_seek only handles SEEK_SET, not %d\", origin);\n \n-\tcase CURLIOCMD_RESTARTREAD:\n-\t\tif (rpc->initial_buffer) {\n-\t\t\trpc->pos = 0;\n-\t\t\treturn CURLIOE_OK;\n+\tif (rpc->initial_buffer) {\n+\t\tif (offset < 0 || offset > rpc->len) {\n+\t\t\terror(\"curl seek would be outside of rpc buffer\");\n+\t\t\treturn CURL_SEEKFUNC_FAIL;\n \t\t}\n-\t\terror(_(\"unable to rewind rpc post data - try increasing http.postBuffer\"));\n-\t\treturn CURLIOE_FAILRESTART;\n-\n-\tdefault:\n-\t\treturn CURLIOE_UNKNOWNCMD;\n+\t\trpc->pos = offset;\n+\t\treturn CURL_SEEKFUNC_OK;\n \t}\n+\n+\terror(_(\"unable to rewind rpc post data - try increasing http.postBuffer\"));\n+\treturn CURL_SEEKFUNC_FAIL;\n }\n \n struct check_pktline_state {\n@@ -959,8 +958,8 @@ retry:\n \t\trpc->initial_buffer = 1;\n \t\tcurl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, rpc_out);\n \t\tcurl_easy_setopt(slot->curl, CURLOPT_INFILE, rpc);\n-\t\tcurl_easy_setopt(slot->curl, CURLOPT_IOCTLFUNCTION, rpc_ioctl);\n-\t\tcurl_easy_setopt(slot->curl, CURLOPT_IOCTLDATA, rpc);\n+\t\tcurl_easy_setopt(slot->curl, CURLOPT_SEEKFUNCTION, rpc_seek);\n+\t\tcurl_easy_setopt(slot->curl, CURLOPT_SEEKDATA, rpc);\n \t\tif (options.verbosity > 1) {\n \t\t\tfprintf(stderr, \"POST %s (chunked)\\n\", rpc->service_name);\n \t\t\tfflush(stderr);\n\nbase-commit: a7caae2729742fc80147bca1c02ae848cb55921a\n-- \ngitgitgadget\n"},{"id":"470544","messageId":"pull.1435.v5.git.git.1673986764553.gitgitgadget@gmail.com","threadId":"59107","inReplyTo":"pull.1435.v4.git.git.1673986152672.gitgitgadget@gmail.com","subject":"[PATCH v5] curl: resolve deprecated curl declarations","fromName":"Rose via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2023-01-17T20:19:24Z","receivedAt":"2023-01-17T22:02:47Z","isPatch":true,"sender":{"key":"ckelsch@jgrcpa.com","avatar":null},"body":"From: Seija Kijin <doremylover123@gmail.com>\n\nFix CI-Alpine build by replacing deprecated\ndeclarations with their suggested replacements\n\nNote that this required changing the\ncallbacks of functions because the replacement\nfor these deprecations require a different function\nsignature for the callback and different parameters.\n\nEvery change done was made as to minimize\nchanged behavior as well as get the CI to pass again.\n\nSigned-off-by: Seija Kijin <doremylover123@gmail.com>\n---\n    curl: resolve deprecated curl declarations\n    \n    Fix CI-Alpine build by replacing deprecated declarations with their\n    suggested replacements\n    \n    Signed-off-by: Seija Kijin doremylover123@gmail.com\n\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-1435%2FAtariDreams%2Fcurl-v5\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-1435/AtariDreams/curl-v5\nPull-Request: https://github.com/git/git/pull/1435\n\nRange-diff vs v4:\n\n 1:  ebe36ad23fa ! 1:  c8628c53d22 curl: resolve deprecated curl declarations\n     @@ http.c: void setup_curl_trace(CURL *handle)\n       \tcurl_easy_setopt(handle, CURLOPT_DEBUGDATA, NULL);\n       }\n      +#ifdef GIT_CURL_HAVE_CURLOPT_PROTOCOLS_STR\n     -+static void get_curl_allowed_protocols(char* protocol_buff, int from_user)\n     ++static void get_curl_allowed_protocols(struct strbuf *proto_buf, int from_user)\n      +{\n      +\tunsigned int i = 0;\n      +\n      +\tif (is_transport_allowed(\"http\", from_user)) {\n     -+\t\tprotocol_buff[i++] = 'h';\n     -+\t\tprotocol_buff[i++] = 't';\n     -+\t\tprotocol_buff[i++] = 't';\n     -+\t\tprotocol_buff[i++] = 'p';\n     ++\t\tstrbuf_addstr(proto_buf, \"http\");\n      +\t}\n      +\n      +\tif (is_transport_allowed(\"https\", from_user)) {\n     -+\t\tif (i != 0) {\n     -+\t\t\tprotocol_buff[i++] = ',';\n     -+\t\t}\n     -+\n     -+\t\tprotocol_buff[i++] = 'h';\n     -+\t\tprotocol_buff[i++] = 't';\n     -+\t\tprotocol_buff[i++] = 't';\n     -+\t\tprotocol_buff[i++] = 'p';\n     -+\t\tprotocol_buff[i++] = 's';\n     ++\t\tif (proto_buf->len)\n     ++\t\t\tstrbuf_addch(proto_buf, ',');\n     ++\t\tstrbuf_addstr(proto_buf, \"https\");\n      +\t}\n     + \n      +\tif (is_transport_allowed(\"ftp\", from_user)) {\n     -+\t\tif (i != 0) {\n     -+\t\t\tprotocol_buff[i++] = ',';\n     -+\t\t}\n     -+\n     -+\t\tprotocol_buff[i++] = 'f';\n     -+\t\tprotocol_buff[i++] = 't';\n     -+\t\tprotocol_buff[i++] = 'p';\n     ++\t\tif (proto_buf->len)\n     ++\t\t\tstrbuf_addch(proto_buf, ',');\n     ++\t\tstrbuf_addstr(proto_buf, \"ftp\");\n      +\t}\n     -+\tif (is_transport_allowed(\"ftps\", from_user)) {\n     -+\t\tif (i != 0) {\n     -+\t\t\tprotocol_buff[i++] = ',';\n     -+\t\t}\n      +\n     -+\t\tprotocol_buff[i++] = 'f';\n     -+\t\tprotocol_buff[i++] = 't';\n     -+\t\tprotocol_buff[i++] = 'p';\n     -+\t\tprotocol_buff[i++] = 's';\n     ++\tif (is_transport_allowed(\"ftps\", from_user)) {\n     ++\t\tif (proto_buf->len)\n     ++\t\t\tstrbuf_addch(proto_buf, ',');\n     ++\t\tstrbuf_addstr(proto_buf, \"ftps\");\n      +\t}\n     - \n     -+\tprotocol_buff[i] = '\\0';\n      +}\n      +#else\n       static long get_curl_allowed_protocols(int from_user)\n     @@ http.c: static long get_curl_allowed_protocols(int from_user)\n       \n       #ifdef GIT_CURL_HAVE_CURL_HTTP_VERSION_2\n       static int get_curl_http_version_opt(const char *version_string, long *opt)\n     -@@ http.c: static int get_curl_http_version_opt(const char *version_string, long *opt)\n     - \n     - static CURL *get_curl_handle(void)\n     - {\n     -+\n     -+#ifdef GIT_CURL_HAVE_CURLOPT_PROTOCOLS_STR\n     -+char protocol_buff[20];\n     -+#endif\n     -+\n     - \tCURL *result = curl_easy_init();\n     - \n     - \tif (!result)\n      @@ http.c: static CURL *get_curl_handle(void)\n       \n       \tcurl_easy_setopt(result, CURLOPT_MAXREDIRS, 20);\n       \tcurl_easy_setopt(result, CURLOPT_POSTREDIR, CURL_REDIR_POST_ALL);\n      +#ifdef GIT_CURL_HAVE_CURLOPT_PROTOCOLS_STR\n     -+\tget_curl_allowed_protocols(protocol_buff, 0);\n     -+\tcurl_easy_setopt(result, CURLOPT_REDIR_PROTOCOLS_STR, protocol_buff);\n     -+\tget_curl_allowed_protocols(protocol_buff, -1);\n     -+\tcurl_easy_setopt(result, CURLOPT_PROTOCOLS_STR, protocol_buff);\n     ++\t{\n     ++\t\tstruct strbuf buf = STRBUF_INIT;\n     ++\n     ++\t\tget_curl_allowed_protocols(&buf, 0);\n     ++\t\tcurl_easy_setopt(result, CURLOPT_REDIR_PROTOCOLS_STR, buf.buf);\n     ++\t\tstrbuf_reset(&buf);\n     ++\n     ++\t\tget_curl_allowed_protocols(&buf, -1);\n     ++\t\tcurl_easy_setopt(result, CURLOPT_PROTOCOLS_STR, buf.buf);\n     ++\t\tstrbuf_release(&buf);\n     ++\t}\n      +#else\n       \tcurl_easy_setopt(result, CURLOPT_REDIR_PROTOCOLS,\n       \t\t\t get_curl_allowed_protocols(0));\n\n\n INSTALL           |  2 +-\n git-curl-compat.h |  8 ++++++\n http-push.c       |  6 ++---\n http.c            | 65 ++++++++++++++++++++++++++++++++++++++---------\n http.h            |  2 +-\n remote-curl.c     | 31 +++++++++++-----------\n 6 files changed, 81 insertions(+), 33 deletions(-)\n\ndiff --git a/INSTALL b/INSTALL\nindex 33447883974..d5694f8c470 100644\n--- a/INSTALL\n+++ b/INSTALL\n@@ -139,7 +139,7 @@ Issues of note:\n \t  not need that functionality, use NO_CURL to build without\n \t  it.\n \n-\t  Git requires version \"7.19.4\" or later of \"libcurl\" to build\n+\t  Git requires version \"7.19.5\" or later of \"libcurl\" to build\n \t  without NO_CURL. This version requirement may be bumped in\n \t  the future.\n \ndiff --git a/git-curl-compat.h b/git-curl-compat.h\nindex 56a83b6bbd8..38a2237c8fe 100644\n--- a/git-curl-compat.h\n+++ b/git-curl-compat.h\n@@ -127,3 +127,11 @@\n #endif\n \n #endif\n+\n+/**\n+ * CURLOPT_PROTOCOLS_STR was added in 7.83.0, released in August\n+ * 2022.\n+ */\n+#if LIBCURL_VERSION_NUM >= 0x075500\n+#define GIT_CURL_HAVE_CURLOPT_PROTOCOLS_STR 1\n+#endif\ndiff --git a/http-push.c b/http-push.c\nindex 5f4340a36e6..7f71316456c 100644\n--- a/http-push.c\n+++ b/http-push.c\n@@ -198,13 +198,13 @@ static void curl_setup_http(CURL *curl, const char *url,\n \t\tconst char *custom_req, struct buffer *buffer,\n \t\tcurl_write_callback write_fn)\n {\n-\tcurl_easy_setopt(curl, CURLOPT_PUT, 1);\n+\tcurl_easy_setopt(curl, CURLOPT_UPLOAD, 1);\n \tcurl_easy_setopt(curl, CURLOPT_URL, url);\n \tcurl_easy_setopt(curl, CURLOPT_INFILE, buffer);\n \tcurl_easy_setopt(curl, CURLOPT_INFILESIZE, buffer->buf.len);\n \tcurl_easy_setopt(curl, CURLOPT_READFUNCTION, fread_buffer);\n-\tcurl_easy_setopt(curl, CURLOPT_IOCTLFUNCTION, ioctl_buffer);\n-\tcurl_easy_setopt(curl, CURLOPT_IOCTLDATA, buffer);\n+\tcurl_easy_setopt(curl, CURLOPT_SEEKFUNCTION, seek_buffer);\n+\tcurl_easy_setopt(curl, CURLOPT_SEEKDATA, buffer);\n \tcurl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_fn);\n \tcurl_easy_setopt(curl, CURLOPT_NOBODY, 0);\n \tcurl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, custom_req);\ndiff --git a/http.c b/http.c\nindex 8a5ba3f4776..bc343656d5d 100644\n--- a/http.c\n+++ b/http.c\n@@ -157,21 +157,19 @@ size_t fread_buffer(char *ptr, size_t eltsize, size_t nmemb, void *buffer_)\n \treturn size / eltsize;\n }\n \n-curlioerr ioctl_buffer(CURL *handle, int cmd, void *clientp)\n+int seek_buffer(void *userp, curl_off_t offset, int origin)\n {\n-\tstruct buffer *buffer = clientp;\n+\tstruct buffer *buffer = userp;\n \n-\tswitch (cmd) {\n-\tcase CURLIOCMD_NOP:\n-\t\treturn CURLIOE_OK;\n-\n-\tcase CURLIOCMD_RESTARTREAD:\n-\t\tbuffer->posn = 0;\n-\t\treturn CURLIOE_OK;\n-\n-\tdefault:\n-\t\treturn CURLIOE_UNKNOWNCMD;\n+\tif (origin != SEEK_SET)\n+\t\tBUG(\"seek_buffer only handles SEEK_SET\");\n+\tif (offset < 0 || offset >= buffer->buf.len) {\n+\t\terror(\"curl seek would be outside of buffer\");\n+\t\treturn CURL_SEEKFUNC_FAIL;\n \t}\n+\n+\tbuffer->posn = offset;\n+\treturn CURL_SEEKFUNC_OK;\n }\n \n size_t fwrite_buffer(char *ptr, size_t eltsize, size_t nmemb, void *buffer_)\n@@ -765,7 +763,34 @@ void setup_curl_trace(CURL *handle)\n \tcurl_easy_setopt(handle, CURLOPT_DEBUGFUNCTION, curl_trace);\n \tcurl_easy_setopt(handle, CURLOPT_DEBUGDATA, NULL);\n }\n+#ifdef GIT_CURL_HAVE_CURLOPT_PROTOCOLS_STR\n+static void get_curl_allowed_protocols(struct strbuf *proto_buf, int from_user)\n+{\n+\tunsigned int i = 0;\n+\n+\tif (is_transport_allowed(\"http\", from_user)) {\n+\t\tstrbuf_addstr(proto_buf, \"http\");\n+\t}\n+\n+\tif (is_transport_allowed(\"https\", from_user)) {\n+\t\tif (proto_buf->len)\n+\t\t\tstrbuf_addch(proto_buf, ',');\n+\t\tstrbuf_addstr(proto_buf, \"https\");\n+\t}\n \n+\tif (is_transport_allowed(\"ftp\", from_user)) {\n+\t\tif (proto_buf->len)\n+\t\t\tstrbuf_addch(proto_buf, ',');\n+\t\tstrbuf_addstr(proto_buf, \"ftp\");\n+\t}\n+\n+\tif (is_transport_allowed(\"ftps\", from_user)) {\n+\t\tif (proto_buf->len)\n+\t\t\tstrbuf_addch(proto_buf, ',');\n+\t\tstrbuf_addstr(proto_buf, \"ftps\");\n+\t}\n+}\n+#else\n static long get_curl_allowed_protocols(int from_user)\n {\n \tlong allowed_protocols = 0;\n@@ -781,6 +806,7 @@ static long get_curl_allowed_protocols(int from_user)\n \n \treturn allowed_protocols;\n }\n+#endif\n \n #ifdef GIT_CURL_HAVE_CURL_HTTP_VERSION_2\n static int get_curl_http_version_opt(const char *version_string, long *opt)\n@@ -923,10 +949,25 @@ static CURL *get_curl_handle(void)\n \n \tcurl_easy_setopt(result, CURLOPT_MAXREDIRS, 20);\n \tcurl_easy_setopt(result, CURLOPT_POSTREDIR, CURL_REDIR_POST_ALL);\n+#ifdef GIT_CURL_HAVE_CURLOPT_PROTOCOLS_STR\n+\t{\n+\t\tstruct strbuf buf = STRBUF_INIT;\n+\n+\t\tget_curl_allowed_protocols(&buf, 0);\n+\t\tcurl_easy_setopt(result, CURLOPT_REDIR_PROTOCOLS_STR, buf.buf);\n+\t\tstrbuf_reset(&buf);\n+\n+\t\tget_curl_allowed_protocols(&buf, -1);\n+\t\tcurl_easy_setopt(result, CURLOPT_PROTOCOLS_STR, buf.buf);\n+\t\tstrbuf_release(&buf);\n+\t}\n+#else\n \tcurl_easy_setopt(result, CURLOPT_REDIR_PROTOCOLS,\n \t\t\t get_curl_allowed_protocols(0));\n \tcurl_easy_setopt(result, CURLOPT_PROTOCOLS,\n \t\t\t get_curl_allowed_protocols(-1));\n+#endif\n+\n \tif (getenv(\"GIT_CURL_VERBOSE\"))\n \t\thttp_trace_curl_no_data();\n \tsetup_curl_trace(result);\ndiff --git a/http.h b/http.h\nindex 3c94c479100..0be9400ef53 100644\n--- a/http.h\n+++ b/http.h\n@@ -40,7 +40,7 @@ struct buffer {\n size_t fread_buffer(char *ptr, size_t eltsize, size_t nmemb, void *strbuf);\n size_t fwrite_buffer(char *ptr, size_t eltsize, size_t nmemb, void *strbuf);\n size_t fwrite_null(char *ptr, size_t eltsize, size_t nmemb, void *strbuf);\n-curlioerr ioctl_buffer(CURL *handle, int cmd, void *clientp);\n+int seek_buffer(void *userp, curl_off_t offset, int origin);\n \n /* Slot lifecycle functions */\n struct active_request_slot *get_active_slot(void);\ndiff --git a/remote-curl.c b/remote-curl.c\nindex 72dfb8fb86a..540da2b7989 100644\n--- a/remote-curl.c\n+++ b/remote-curl.c\n@@ -717,25 +717,24 @@ static size_t rpc_out(void *ptr, size_t eltsize,\n \treturn avail;\n }\n \n-static curlioerr rpc_ioctl(CURL *handle, int cmd, void *clientp)\n+static int rpc_seek(void *userp, curl_off_t offset, int origin)\n {\n-\tstruct rpc_state *rpc = clientp;\n+\tstruct rpc_state *rpc = userp;\n \n-\tswitch (cmd) {\n-\tcase CURLIOCMD_NOP:\n-\t\treturn CURLIOE_OK;\n+\tif (origin != SEEK_SET)\n+\t\tBUG(\"rpc_seek only handles SEEK_SET, not %d\", origin);\n \n-\tcase CURLIOCMD_RESTARTREAD:\n-\t\tif (rpc->initial_buffer) {\n-\t\t\trpc->pos = 0;\n-\t\t\treturn CURLIOE_OK;\n+\tif (rpc->initial_buffer) {\n+\t\tif (offset < 0 || offset > rpc->len) {\n+\t\t\terror(\"curl seek would be outside of rpc buffer\");\n+\t\t\treturn CURL_SEEKFUNC_FAIL;\n \t\t}\n-\t\terror(_(\"unable to rewind rpc post data - try increasing http.postBuffer\"));\n-\t\treturn CURLIOE_FAILRESTART;\n-\n-\tdefault:\n-\t\treturn CURLIOE_UNKNOWNCMD;\n+\t\trpc->pos = offset;\n+\t\treturn CURL_SEEKFUNC_OK;\n \t}\n+\n+\terror(_(\"unable to rewind rpc post data - try increasing http.postBuffer\"));\n+\treturn CURL_SEEKFUNC_FAIL;\n }\n \n struct check_pktline_state {\n@@ -959,8 +958,8 @@ retry:\n \t\trpc->initial_buffer = 1;\n \t\tcurl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, rpc_out);\n \t\tcurl_easy_setopt(slot->curl, CURLOPT_INFILE, rpc);\n-\t\tcurl_easy_setopt(slot->curl, CURLOPT_IOCTLFUNCTION, rpc_ioctl);\n-\t\tcurl_easy_setopt(slot->curl, CURLOPT_IOCTLDATA, rpc);\n+\t\tcurl_easy_setopt(slot->curl, CURLOPT_SEEKFUNCTION, rpc_seek);\n+\t\tcurl_easy_setopt(slot->curl, CURLOPT_SEEKDATA, rpc);\n \t\tif (options.verbosity > 1) {\n \t\t\tfprintf(stderr, \"POST %s (chunked)\\n\", rpc->service_name);\n \t\t\tfflush(stderr);\n\nbase-commit: a7caae2729742fc80147bca1c02ae848cb55921a\n-- \ngitgitgadget\n"},{"id":"470545","messageId":"pull.1435.v7.git.git.1673987583356.gitgitgadget@gmail.com","threadId":"59107","inReplyTo":"pull.1435.v6.git.git.1673986937738.gitgitgadget@gmail.com","subject":"[PATCH v7] curl: resolve deprecated curl declarations","fromName":"Rose via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2023-01-17T20:33:03Z","receivedAt":"2023-01-17T22:06:35Z","isPatch":true,"sender":{"key":"ckelsch@jgrcpa.com","avatar":null},"body":"From: Seija Kijin <doremylover123@gmail.com>\n\nFix CI-Alpine build by replacing deprecated\ndeclarations with their suggested replacements\n\nNote that this required changing the\ncallbacks of functions because the replacement\nfor these deprecations require a different function\nsignature for the callback and different parameters.\n\nEvery change done was made as to minimize\nchanged behavior as well as get the CI to pass again.\n\nSigned-off-by: Seija Kijin <doremylover123@gmail.com>\n---\n    curl: resolve deprecated curl declarations\n    \n    Fix CI-Alpine build by replacing deprecated declarations with their\n    suggested replacements\n    \n    Signed-off-by: Seija Kijin doremylover123@gmail.com\n\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-1435%2FAtariDreams%2Fcurl-v7\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-1435/AtariDreams/curl-v7\nPull-Request: https://github.com/git/git/pull/1435\n\nRange-diff vs v6:\n\n 1:  6b471a867d5 ! 1:  23094afb2e6 curl: resolve deprecated curl declarations\n     @@ http.c: void setup_curl_trace(CURL *handle)\n      +\t}\n       \n      +\tif (is_transport_allowed(\"https\", from_user)) {\n     -+\t\tif (proto_buf->len)\n     -+\t\t\tstrbuf_addch(proto_buf, ',');\n     -+\t\tstrbuf_addstr(proto_buf, \"https\");\n     ++\t\tstrbuf_addstr(proto_buf, proto_buf->len ? \"https\" : \",https\");\n      +\t}\n      +\n      +\tif (is_transport_allowed(\"ftp\", from_user)) {\n     -+\t\tif (proto_buf->len)\n     -+\t\t\tstrbuf_addch(proto_buf, ',');\n     -+\t\tstrbuf_addstr(proto_buf, \"ftp\");\n     ++\t\tstrbuf_addstr(proto_buf, proto_buf->len ? \"ftp\" : \",ftp\");\n      +\t}\n      +\n      +\tif (is_transport_allowed(\"ftps\", from_user)) {\n     -+\t\tif (proto_buf->len)\n     -+\t\t\tstrbuf_addch(proto_buf, ',');\n     -+\t\tstrbuf_addstr(proto_buf, \"ftps\");\n     ++\t\tstrbuf_addstr(proto_buf, proto_buf->len ? \"ftps\" : \",ftps\");\n      +\t}\n      +}\n      +#else\n\n\n INSTALL           |  2 +-\n git-curl-compat.h |  8 +++++++\n http-push.c       |  6 ++---\n http.c            | 57 +++++++++++++++++++++++++++++++++++++----------\n http.h            |  2 +-\n remote-curl.c     | 31 +++++++++++++-------------\n 6 files changed, 73 insertions(+), 33 deletions(-)\n\ndiff --git a/INSTALL b/INSTALL\nindex 33447883974..d5694f8c470 100644\n--- a/INSTALL\n+++ b/INSTALL\n@@ -139,7 +139,7 @@ Issues of note:\n \t  not need that functionality, use NO_CURL to build without\n \t  it.\n \n-\t  Git requires version \"7.19.4\" or later of \"libcurl\" to build\n+\t  Git requires version \"7.19.5\" or later of \"libcurl\" to build\n \t  without NO_CURL. This version requirement may be bumped in\n \t  the future.\n \ndiff --git a/git-curl-compat.h b/git-curl-compat.h\nindex 56a83b6bbd8..38a2237c8fe 100644\n--- a/git-curl-compat.h\n+++ b/git-curl-compat.h\n@@ -127,3 +127,11 @@\n #endif\n \n #endif\n+\n+/**\n+ * CURLOPT_PROTOCOLS_STR was added in 7.83.0, released in August\n+ * 2022.\n+ */\n+#if LIBCURL_VERSION_NUM >= 0x075500\n+#define GIT_CURL_HAVE_CURLOPT_PROTOCOLS_STR 1\n+#endif\ndiff --git a/http-push.c b/http-push.c\nindex 5f4340a36e6..7f71316456c 100644\n--- a/http-push.c\n+++ b/http-push.c\n@@ -198,13 +198,13 @@ static void curl_setup_http(CURL *curl, const char *url,\n \t\tconst char *custom_req, struct buffer *buffer,\n \t\tcurl_write_callback write_fn)\n {\n-\tcurl_easy_setopt(curl, CURLOPT_PUT, 1);\n+\tcurl_easy_setopt(curl, CURLOPT_UPLOAD, 1);\n \tcurl_easy_setopt(curl, CURLOPT_URL, url);\n \tcurl_easy_setopt(curl, CURLOPT_INFILE, buffer);\n \tcurl_easy_setopt(curl, CURLOPT_INFILESIZE, buffer->buf.len);\n \tcurl_easy_setopt(curl, CURLOPT_READFUNCTION, fread_buffer);\n-\tcurl_easy_setopt(curl, CURLOPT_IOCTLFUNCTION, ioctl_buffer);\n-\tcurl_easy_setopt(curl, CURLOPT_IOCTLDATA, buffer);\n+\tcurl_easy_setopt(curl, CURLOPT_SEEKFUNCTION, seek_buffer);\n+\tcurl_easy_setopt(curl, CURLOPT_SEEKDATA, buffer);\n \tcurl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_fn);\n \tcurl_easy_setopt(curl, CURLOPT_NOBODY, 0);\n \tcurl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, custom_req);\ndiff --git a/http.c b/http.c\nindex 8a5ba3f4776..6dfbae96ac6 100644\n--- a/http.c\n+++ b/http.c\n@@ -157,21 +157,19 @@ size_t fread_buffer(char *ptr, size_t eltsize, size_t nmemb, void *buffer_)\n \treturn size / eltsize;\n }\n \n-curlioerr ioctl_buffer(CURL *handle, int cmd, void *clientp)\n+int seek_buffer(void *userp, curl_off_t offset, int origin)\n {\n-\tstruct buffer *buffer = clientp;\n+\tstruct buffer *buffer = userp;\n \n-\tswitch (cmd) {\n-\tcase CURLIOCMD_NOP:\n-\t\treturn CURLIOE_OK;\n-\n-\tcase CURLIOCMD_RESTARTREAD:\n-\t\tbuffer->posn = 0;\n-\t\treturn CURLIOE_OK;\n-\n-\tdefault:\n-\t\treturn CURLIOE_UNKNOWNCMD;\n+\tif (origin != SEEK_SET)\n+\t\tBUG(\"seek_buffer only handles SEEK_SET\");\n+\tif (offset < 0 || offset >= buffer->buf.len) {\n+\t\terror(\"curl seek would be outside of buffer\");\n+\t\treturn CURL_SEEKFUNC_FAIL;\n \t}\n+\n+\tbuffer->posn = offset;\n+\treturn CURL_SEEKFUNC_OK;\n }\n \n size_t fwrite_buffer(char *ptr, size_t eltsize, size_t nmemb, void *buffer_)\n@@ -765,7 +763,26 @@ void setup_curl_trace(CURL *handle)\n \tcurl_easy_setopt(handle, CURLOPT_DEBUGFUNCTION, curl_trace);\n \tcurl_easy_setopt(handle, CURLOPT_DEBUGDATA, NULL);\n }\n+#ifdef GIT_CURL_HAVE_CURLOPT_PROTOCOLS_STR\n+static void get_curl_allowed_protocols(struct strbuf *proto_buf, int from_user)\n+{\n+\tif (is_transport_allowed(\"http\", from_user)) {\n+\t\tstrbuf_addstr(proto_buf, \"http\");\n+\t}\n \n+\tif (is_transport_allowed(\"https\", from_user)) {\n+\t\tstrbuf_addstr(proto_buf, proto_buf->len ? \"https\" : \",https\");\n+\t}\n+\n+\tif (is_transport_allowed(\"ftp\", from_user)) {\n+\t\tstrbuf_addstr(proto_buf, proto_buf->len ? \"ftp\" : \",ftp\");\n+\t}\n+\n+\tif (is_transport_allowed(\"ftps\", from_user)) {\n+\t\tstrbuf_addstr(proto_buf, proto_buf->len ? \"ftps\" : \",ftps\");\n+\t}\n+}\n+#else\n static long get_curl_allowed_protocols(int from_user)\n {\n \tlong allowed_protocols = 0;\n@@ -781,6 +798,7 @@ static long get_curl_allowed_protocols(int from_user)\n \n \treturn allowed_protocols;\n }\n+#endif\n \n #ifdef GIT_CURL_HAVE_CURL_HTTP_VERSION_2\n static int get_curl_http_version_opt(const char *version_string, long *opt)\n@@ -923,10 +941,25 @@ static CURL *get_curl_handle(void)\n \n \tcurl_easy_setopt(result, CURLOPT_MAXREDIRS, 20);\n \tcurl_easy_setopt(result, CURLOPT_POSTREDIR, CURL_REDIR_POST_ALL);\n+#ifdef GIT_CURL_HAVE_CURLOPT_PROTOCOLS_STR\n+\t{\n+\t\tstruct strbuf buf = STRBUF_INIT;\n+\n+\t\tget_curl_allowed_protocols(&buf, 0);\n+\t\tcurl_easy_setopt(result, CURLOPT_REDIR_PROTOCOLS_STR, buf.buf);\n+\t\tstrbuf_reset(&buf);\n+\n+\t\tget_curl_allowed_protocols(&buf, -1);\n+\t\tcurl_easy_setopt(result, CURLOPT_PROTOCOLS_STR, buf.buf);\n+\t\tstrbuf_release(&buf);\n+\t}\n+#else\n \tcurl_easy_setopt(result, CURLOPT_REDIR_PROTOCOLS,\n \t\t\t get_curl_allowed_protocols(0));\n \tcurl_easy_setopt(result, CURLOPT_PROTOCOLS,\n \t\t\t get_curl_allowed_protocols(-1));\n+#endif\n+\n \tif (getenv(\"GIT_CURL_VERBOSE\"))\n \t\thttp_trace_curl_no_data();\n \tsetup_curl_trace(result);\ndiff --git a/http.h b/http.h\nindex 3c94c479100..0be9400ef53 100644\n--- a/http.h\n+++ b/http.h\n@@ -40,7 +40,7 @@ struct buffer {\n size_t fread_buffer(char *ptr, size_t eltsize, size_t nmemb, void *strbuf);\n size_t fwrite_buffer(char *ptr, size_t eltsize, size_t nmemb, void *strbuf);\n size_t fwrite_null(char *ptr, size_t eltsize, size_t nmemb, void *strbuf);\n-curlioerr ioctl_buffer(CURL *handle, int cmd, void *clientp);\n+int seek_buffer(void *userp, curl_off_t offset, int origin);\n \n /* Slot lifecycle functions */\n struct active_request_slot *get_active_slot(void);\ndiff --git a/remote-curl.c b/remote-curl.c\nindex 72dfb8fb86a..540da2b7989 100644\n--- a/remote-curl.c\n+++ b/remote-curl.c\n@@ -717,25 +717,24 @@ static size_t rpc_out(void *ptr, size_t eltsize,\n \treturn avail;\n }\n \n-static curlioerr rpc_ioctl(CURL *handle, int cmd, void *clientp)\n+static int rpc_seek(void *userp, curl_off_t offset, int origin)\n {\n-\tstruct rpc_state *rpc = clientp;\n+\tstruct rpc_state *rpc = userp;\n \n-\tswitch (cmd) {\n-\tcase CURLIOCMD_NOP:\n-\t\treturn CURLIOE_OK;\n+\tif (origin != SEEK_SET)\n+\t\tBUG(\"rpc_seek only handles SEEK_SET, not %d\", origin);\n \n-\tcase CURLIOCMD_RESTARTREAD:\n-\t\tif (rpc->initial_buffer) {\n-\t\t\trpc->pos = 0;\n-\t\t\treturn CURLIOE_OK;\n+\tif (rpc->initial_buffer) {\n+\t\tif (offset < 0 || offset > rpc->len) {\n+\t\t\terror(\"curl seek would be outside of rpc buffer\");\n+\t\t\treturn CURL_SEEKFUNC_FAIL;\n \t\t}\n-\t\terror(_(\"unable to rewind rpc post data - try increasing http.postBuffer\"));\n-\t\treturn CURLIOE_FAILRESTART;\n-\n-\tdefault:\n-\t\treturn CURLIOE_UNKNOWNCMD;\n+\t\trpc->pos = offset;\n+\t\treturn CURL_SEEKFUNC_OK;\n \t}\n+\n+\terror(_(\"unable to rewind rpc post data - try increasing http.postBuffer\"));\n+\treturn CURL_SEEKFUNC_FAIL;\n }\n \n struct check_pktline_state {\n@@ -959,8 +958,8 @@ retry:\n \t\trpc->initial_buffer = 1;\n \t\tcurl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, rpc_out);\n \t\tcurl_easy_setopt(slot->curl, CURLOPT_INFILE, rpc);\n-\t\tcurl_easy_setopt(slot->curl, CURLOPT_IOCTLFUNCTION, rpc_ioctl);\n-\t\tcurl_easy_setopt(slot->curl, CURLOPT_IOCTLDATA, rpc);\n+\t\tcurl_easy_setopt(slot->curl, CURLOPT_SEEKFUNCTION, rpc_seek);\n+\t\tcurl_easy_setopt(slot->curl, CURLOPT_SEEKDATA, rpc);\n \t\tif (options.verbosity > 1) {\n \t\t\tfprintf(stderr, \"POST %s (chunked)\\n\", rpc->service_name);\n \t\t\tfflush(stderr);\n\nbase-commit: a7caae2729742fc80147bca1c02ae848cb55921a\n-- \ngitgitgadget\n"},{"id":"470553","messageId":"pull.1435.v8.git.git.1673991669894.gitgitgadget@gmail.com","threadId":"59107","inReplyTo":"pull.1435.v7.git.git.1673987583356.gitgitgadget@gmail.com","subject":"[PATCH v8] curl: resolve deprecated curl declarations","fromName":"Rose via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2023-01-17T21:41:09Z","receivedAt":"2023-01-17T22:55:34Z","isPatch":true,"sender":{"key":"ckelsch@jgrcpa.com","avatar":null},"body":"From: Seija Kijin <doremylover123@gmail.com>\n\nFix CI-Alpine build by replacing deprecated\ndeclarations with their suggested replacements\n\nNote that this required changing the\ncallbacks of functions because the replacement\nfor these deprecations require a different function\nsignature for the callback and different parameters.\n\nEvery change done was made as to minimize\nchanged behavior as well as get the CI to pass again.\n\nSigned-off-by: Seija Kijin <doremylover123@gmail.com>\n---\n    curl: resolve deprecated curl declarations\n    \n    Fix CI-Alpine build by replacing deprecated declarations with their\n    suggested replacements\n    \n    Signed-off-by: Seija Kijin doremylover123@gmail.com\n\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-1435%2FAtariDreams%2Fcurl-v8\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-1435/AtariDreams/curl-v8\nPull-Request: https://github.com/git/git/pull/1435\n\nRange-diff vs v7:\n\n 1:  23094afb2e6 ! 1:  5e44592695e curl: resolve deprecated curl declarations\n     @@ http.c: void setup_curl_trace(CURL *handle)\n      +\t}\n       \n      +\tif (is_transport_allowed(\"https\", from_user)) {\n     -+\t\tstrbuf_addstr(proto_buf, proto_buf->len ? \"https\" : \",https\");\n     ++\t\tstrbuf_addstr(proto_buf, proto_buf->len ? \",https\" : \"https\");\n      +\t}\n      +\n      +\tif (is_transport_allowed(\"ftp\", from_user)) {\n     -+\t\tstrbuf_addstr(proto_buf, proto_buf->len ? \"ftp\" : \",ftp\");\n     ++\t\tstrbuf_addstr(proto_buf, proto_buf->len ? \",ftp\" : \"ftp\");\n      +\t}\n      +\n      +\tif (is_transport_allowed(\"ftps\", from_user)) {\n     -+\t\tstrbuf_addstr(proto_buf, proto_buf->len ? \"ftps\" : \",ftps\");\n     ++\t\tstrbuf_addstr(proto_buf, proto_buf->len ? \",ftps\" : \"ftps\");\n      +\t}\n      +}\n      +#else\n\n\n INSTALL           |  2 +-\n git-curl-compat.h |  8 +++++++\n http-push.c       |  6 ++---\n http.c            | 57 +++++++++++++++++++++++++++++++++++++----------\n http.h            |  2 +-\n remote-curl.c     | 31 +++++++++++++-------------\n 6 files changed, 73 insertions(+), 33 deletions(-)\n\ndiff --git a/INSTALL b/INSTALL\nindex 33447883974..d5694f8c470 100644\n--- a/INSTALL\n+++ b/INSTALL\n@@ -139,7 +139,7 @@ Issues of note:\n \t  not need that functionality, use NO_CURL to build without\n \t  it.\n \n-\t  Git requires version \"7.19.4\" or later of \"libcurl\" to build\n+\t  Git requires version \"7.19.5\" or later of \"libcurl\" to build\n \t  without NO_CURL. This version requirement may be bumped in\n \t  the future.\n \ndiff --git a/git-curl-compat.h b/git-curl-compat.h\nindex 56a83b6bbd8..38a2237c8fe 100644\n--- a/git-curl-compat.h\n+++ b/git-curl-compat.h\n@@ -127,3 +127,11 @@\n #endif\n \n #endif\n+\n+/**\n+ * CURLOPT_PROTOCOLS_STR was added in 7.83.0, released in August\n+ * 2022.\n+ */\n+#if LIBCURL_VERSION_NUM >= 0x075500\n+#define GIT_CURL_HAVE_CURLOPT_PROTOCOLS_STR 1\n+#endif\ndiff --git a/http-push.c b/http-push.c\nindex 5f4340a36e6..7f71316456c 100644\n--- a/http-push.c\n+++ b/http-push.c\n@@ -198,13 +198,13 @@ static void curl_setup_http(CURL *curl, const char *url,\n \t\tconst char *custom_req, struct buffer *buffer,\n \t\tcurl_write_callback write_fn)\n {\n-\tcurl_easy_setopt(curl, CURLOPT_PUT, 1);\n+\tcurl_easy_setopt(curl, CURLOPT_UPLOAD, 1);\n \tcurl_easy_setopt(curl, CURLOPT_URL, url);\n \tcurl_easy_setopt(curl, CURLOPT_INFILE, buffer);\n \tcurl_easy_setopt(curl, CURLOPT_INFILESIZE, buffer->buf.len);\n \tcurl_easy_setopt(curl, CURLOPT_READFUNCTION, fread_buffer);\n-\tcurl_easy_setopt(curl, CURLOPT_IOCTLFUNCTION, ioctl_buffer);\n-\tcurl_easy_setopt(curl, CURLOPT_IOCTLDATA, buffer);\n+\tcurl_easy_setopt(curl, CURLOPT_SEEKFUNCTION, seek_buffer);\n+\tcurl_easy_setopt(curl, CURLOPT_SEEKDATA, buffer);\n \tcurl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_fn);\n \tcurl_easy_setopt(curl, CURLOPT_NOBODY, 0);\n \tcurl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, custom_req);\ndiff --git a/http.c b/http.c\nindex 8a5ba3f4776..79ea98d7d54 100644\n--- a/http.c\n+++ b/http.c\n@@ -157,21 +157,19 @@ size_t fread_buffer(char *ptr, size_t eltsize, size_t nmemb, void *buffer_)\n \treturn size / eltsize;\n }\n \n-curlioerr ioctl_buffer(CURL *handle, int cmd, void *clientp)\n+int seek_buffer(void *userp, curl_off_t offset, int origin)\n {\n-\tstruct buffer *buffer = clientp;\n+\tstruct buffer *buffer = userp;\n \n-\tswitch (cmd) {\n-\tcase CURLIOCMD_NOP:\n-\t\treturn CURLIOE_OK;\n-\n-\tcase CURLIOCMD_RESTARTREAD:\n-\t\tbuffer->posn = 0;\n-\t\treturn CURLIOE_OK;\n-\n-\tdefault:\n-\t\treturn CURLIOE_UNKNOWNCMD;\n+\tif (origin != SEEK_SET)\n+\t\tBUG(\"seek_buffer only handles SEEK_SET\");\n+\tif (offset < 0 || offset >= buffer->buf.len) {\n+\t\terror(\"curl seek would be outside of buffer\");\n+\t\treturn CURL_SEEKFUNC_FAIL;\n \t}\n+\n+\tbuffer->posn = offset;\n+\treturn CURL_SEEKFUNC_OK;\n }\n \n size_t fwrite_buffer(char *ptr, size_t eltsize, size_t nmemb, void *buffer_)\n@@ -765,7 +763,26 @@ void setup_curl_trace(CURL *handle)\n \tcurl_easy_setopt(handle, CURLOPT_DEBUGFUNCTION, curl_trace);\n \tcurl_easy_setopt(handle, CURLOPT_DEBUGDATA, NULL);\n }\n+#ifdef GIT_CURL_HAVE_CURLOPT_PROTOCOLS_STR\n+static void get_curl_allowed_protocols(struct strbuf *proto_buf, int from_user)\n+{\n+\tif (is_transport_allowed(\"http\", from_user)) {\n+\t\tstrbuf_addstr(proto_buf, \"http\");\n+\t}\n \n+\tif (is_transport_allowed(\"https\", from_user)) {\n+\t\tstrbuf_addstr(proto_buf, proto_buf->len ? \",https\" : \"https\");\n+\t}\n+\n+\tif (is_transport_allowed(\"ftp\", from_user)) {\n+\t\tstrbuf_addstr(proto_buf, proto_buf->len ? \",ftp\" : \"ftp\");\n+\t}\n+\n+\tif (is_transport_allowed(\"ftps\", from_user)) {\n+\t\tstrbuf_addstr(proto_buf, proto_buf->len ? \",ftps\" : \"ftps\");\n+\t}\n+}\n+#else\n static long get_curl_allowed_protocols(int from_user)\n {\n \tlong allowed_protocols = 0;\n@@ -781,6 +798,7 @@ static long get_curl_allowed_protocols(int from_user)\n \n \treturn allowed_protocols;\n }\n+#endif\n \n #ifdef GIT_CURL_HAVE_CURL_HTTP_VERSION_2\n static int get_curl_http_version_opt(const char *version_string, long *opt)\n@@ -923,10 +941,25 @@ static CURL *get_curl_handle(void)\n \n \tcurl_easy_setopt(result, CURLOPT_MAXREDIRS, 20);\n \tcurl_easy_setopt(result, CURLOPT_POSTREDIR, CURL_REDIR_POST_ALL);\n+#ifdef GIT_CURL_HAVE_CURLOPT_PROTOCOLS_STR\n+\t{\n+\t\tstruct strbuf buf = STRBUF_INIT;\n+\n+\t\tget_curl_allowed_protocols(&buf, 0);\n+\t\tcurl_easy_setopt(result, CURLOPT_REDIR_PROTOCOLS_STR, buf.buf);\n+\t\tstrbuf_reset(&buf);\n+\n+\t\tget_curl_allowed_protocols(&buf, -1);\n+\t\tcurl_easy_setopt(result, CURLOPT_PROTOCOLS_STR, buf.buf);\n+\t\tstrbuf_release(&buf);\n+\t}\n+#else\n \tcurl_easy_setopt(result, CURLOPT_REDIR_PROTOCOLS,\n \t\t\t get_curl_allowed_protocols(0));\n \tcurl_easy_setopt(result, CURLOPT_PROTOCOLS,\n \t\t\t get_curl_allowed_protocols(-1));\n+#endif\n+\n \tif (getenv(\"GIT_CURL_VERBOSE\"))\n \t\thttp_trace_curl_no_data();\n \tsetup_curl_trace(result);\ndiff --git a/http.h b/http.h\nindex 3c94c479100..0be9400ef53 100644\n--- a/http.h\n+++ b/http.h\n@@ -40,7 +40,7 @@ struct buffer {\n size_t fread_buffer(char *ptr, size_t eltsize, size_t nmemb, void *strbuf);\n size_t fwrite_buffer(char *ptr, size_t eltsize, size_t nmemb, void *strbuf);\n size_t fwrite_null(char *ptr, size_t eltsize, size_t nmemb, void *strbuf);\n-curlioerr ioctl_buffer(CURL *handle, int cmd, void *clientp);\n+int seek_buffer(void *userp, curl_off_t offset, int origin);\n \n /* Slot lifecycle functions */\n struct active_request_slot *get_active_slot(void);\ndiff --git a/remote-curl.c b/remote-curl.c\nindex 72dfb8fb86a..540da2b7989 100644\n--- a/remote-curl.c\n+++ b/remote-curl.c\n@@ -717,25 +717,24 @@ static size_t rpc_out(void *ptr, size_t eltsize,\n \treturn avail;\n }\n \n-static curlioerr rpc_ioctl(CURL *handle, int cmd, void *clientp)\n+static int rpc_seek(void *userp, curl_off_t offset, int origin)\n {\n-\tstruct rpc_state *rpc = clientp;\n+\tstruct rpc_state *rpc = userp;\n \n-\tswitch (cmd) {\n-\tcase CURLIOCMD_NOP:\n-\t\treturn CURLIOE_OK;\n+\tif (origin != SEEK_SET)\n+\t\tBUG(\"rpc_seek only handles SEEK_SET, not %d\", origin);\n \n-\tcase CURLIOCMD_RESTARTREAD:\n-\t\tif (rpc->initial_buffer) {\n-\t\t\trpc->pos = 0;\n-\t\t\treturn CURLIOE_OK;\n+\tif (rpc->initial_buffer) {\n+\t\tif (offset < 0 || offset > rpc->len) {\n+\t\t\terror(\"curl seek would be outside of rpc buffer\");\n+\t\t\treturn CURL_SEEKFUNC_FAIL;\n \t\t}\n-\t\terror(_(\"unable to rewind rpc post data - try increasing http.postBuffer\"));\n-\t\treturn CURLIOE_FAILRESTART;\n-\n-\tdefault:\n-\t\treturn CURLIOE_UNKNOWNCMD;\n+\t\trpc->pos = offset;\n+\t\treturn CURL_SEEKFUNC_OK;\n \t}\n+\n+\terror(_(\"unable to rewind rpc post data - try increasing http.postBuffer\"));\n+\treturn CURL_SEEKFUNC_FAIL;\n }\n \n struct check_pktline_state {\n@@ -959,8 +958,8 @@ retry:\n \t\trpc->initial_buffer = 1;\n \t\tcurl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, rpc_out);\n \t\tcurl_easy_setopt(slot->curl, CURLOPT_INFILE, rpc);\n-\t\tcurl_easy_setopt(slot->curl, CURLOPT_IOCTLFUNCTION, rpc_ioctl);\n-\t\tcurl_easy_setopt(slot->curl, CURLOPT_IOCTLDATA, rpc);\n+\t\tcurl_easy_setopt(slot->curl, CURLOPT_SEEKFUNCTION, rpc_seek);\n+\t\tcurl_easy_setopt(slot->curl, CURLOPT_SEEKDATA, rpc);\n \t\tif (options.verbosity > 1) {\n \t\t\tfprintf(stderr, \"POST %s (chunked)\\n\", rpc->service_name);\n \t\t\tfflush(stderr);\n\nbase-commit: a7caae2729742fc80147bca1c02ae848cb55921a\n-- \ngitgitgadget\n"},{"id":"470586","messageId":"xmqqmt6g7109.fsf@gitster.g","threadId":"59107","inReplyTo":"pull.1435.v8.git.git.1673991669894.gitgitgadget@gmail.com","subject":"Re: [PATCH v8] curl: resolve deprecated curl declarations","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2023-01-18T07:30:46Z","receivedAt":"2023-01-18T07:57:57Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Rose via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-1435%2FAtariDreams%2Fcurl-v8\n> Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-1435/AtariDreams/curl-v8\n> Pull-Request: https://github.com/git/git/pull/1435\n>\n> Range-diff vs v7:\n>\n>  1:  23094afb2e6 ! 1:  5e44592695e curl: resolve deprecated curl declarations\n> ...\n\nPlease stop throwing in quick succession so many unsolicited\niterations of the same topic at the list, before waiting for reviews\nfrom others.\n\nI do not mean \"after you sent an initial revision out, even if you\nfind problems in it, do not send updates in for a while\".  I mean\n\"do not send out that initial revision out, before you spend enough\ntime reading it to find these problems in it you found in, like you\ndid in these previous topics.\"\n\nIn other words, reviewing your own patches to carefully find\nmistakes and correcting them is VERY GOOD, but rather than doing so\nin public, you can do so in private before sending the patches out\nto polish them sufficiently so that you won't find more trivial\nproblems [*].  Prepare patches in private and pretend to be a more\nperfect human with fewer trivial mistakes ;-).\n\n    Note. And you shouldn't be offended by me saying \"trivial\"; they\n    were found by yourself in a few minutes to a few hours after\n    you sent out the previous iteration.\n\nThat way, you'd save yourself from public embarrassment and also\nsave reviewer time.\n\nThanks.\n\nP.S. Doesn't Peff's 3-patch series already solve the same issue this\npatch is trying to address?\n"}]}