git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v2 3/3] http: support CURLOPT_PROTOCOLS_STR

From
Jeff King <peff@peff.net>
Date
Jan 17, 2023, 03:04 UTC
Message-ID
<Y8YQUD8bMHc4Lmph@coredump.intra.peff.net>
In-Reply-To
<Y8YP+R/hyNr6sEFA@coredump.intra.peff.net>

The CURLOPT_PROTOCOLS (and matching CURLOPT_REDIR_PROTOCOLS) flag was deprecated in curl 7.85.0, and using it generate compiler warnings as of curl 7.87.0. The path forward is to use CURLOPT_PROTOCOLS_STR, but we can't just do so unilaterally, as it was only introduced less than a year ago in 7.85.0.

Until that version becomes ubiquitous, we have to either disable the deprecation warning or conditionally use the "STR" variant on newer versions of libcurl. This patch switches to the new variant, which is nice for two reasons:

  - we don't have to worry that silencing curl's deprecation warnings
    might cause us to miss other more useful ones
  - we'd eventually want to move to the new variant anyway, so this gets
    us set up (albeit with some extra ugly boilerplate for the
    conditional)

There are a lot of ways to split up the two cases. One way would be to abstract the storage type (strbuf versus a long), how to append (strbuf_addstr vs bitwise OR), how to initialize, which CURLOPT to use, and so on. But the resulting code looks pretty magical:

  GIT_CURL_PROTOCOL_TYPE allowed = GIT_CURL_PROTOCOL_TYPE_INIT;
  if (...http is allowed...)
	GIT_CURL_PROTOCOL_APPEND(&allowed, "http", CURLOPT_HTTP);

and you end up with more "#define GIT_CURL_PROTOCOL_TYPE" macros than actual code.

On the other end of the spectrum, we could just implement two separate functions, one that handles a string list and one that handles bits. But then we end up repeating our list of protocols (http, https, ftp, ftp).

This patch takes the middle ground. The run-time code is always there to handle both types, and we just choose which one to feed to curl.

Signed-off-by: Jeff King <peff@peff.net>
---
 git-curl-compat.h |  8 +++++++
 http.c            | 59 ++++++++++++++++++++++++++++++++++++-----------
 2 files changed, 54 insertions(+), 13 deletions(-)
diff --git a/git-curl-compat.h b/git-curl-compat.h
index 56a83b6bbd..fd96b3cdff 100644
--- a/git-curl-compat.h
+++ b/git-curl-compat.h
@@ -126,4 +126,12 @@
 #define GIT_CURL_HAVE_CURLSSLSET_NO_BACKENDS
 #endif
 
+/**
+ * CURLOPT_PROTOCOLS_STR and CURLOPT_REDIR_PROTOCOLS_STR were added in 7.85.0,
+ * released in August 2022.
+ */
+#if LIBCURL_VERSION_NUM >= 0x075500
+#define GIT_CURL_HAVE_CURLOPT_PROTOCOLS_STR 1
+#endif
+
 #endif
diff --git a/http.c b/http.c
index ca0fe80ddb..c4b6ddef28 100644
--- a/http.c
+++ b/http.c
@@ -764,20 +764,37 @@ void setup_curl_trace(CURL *handle)
 	curl_easy_setopt(handle, CURLOPT_DEBUGDATA, NULL);
 }
 
-static long get_curl_allowed_protocols(int from_user)
+static void proto_list_append(struct strbuf *list, const char *proto)
 {
-	long allowed_protocols = 0;
+	if (!list)
+		return;
+	if (list->len)
+		strbuf_addch(list, ',');
+	strbuf_addstr(list, proto);
+}
 
-	if (is_transport_allowed("http", from_user))
-		allowed_protocols |= CURLPROTO_HTTP;
-	if (is_transport_allowed("https", from_user))
-		allowed_protocols |= CURLPROTO_HTTPS;
-	if (is_transport_allowed("ftp", from_user))
-		allowed_protocols |= CURLPROTO_FTP;
-	if (is_transport_allowed("ftps", from_user))
-		allowed_protocols |= CURLPROTO_FTPS;
+static long get_curl_allowed_protocols(int from_user, struct strbuf *list)
+{
+	long bits = 0;
 
-	return allowed_protocols;
+	if (is_transport_allowed("http", from_user)) {
+		bits |= CURLPROTO_HTTP;
+		proto_list_append(list, "http");
+	}
+	if (is_transport_allowed("https", from_user)) {
+		bits |= CURLPROTO_HTTPS;
+		proto_list_append(list, "https");
+	}
+	if (is_transport_allowed("ftp", from_user)) {
+		bits |= CURLPROTO_FTP;
+		proto_list_append(list, "ftp");
+	}
+	if (is_transport_allowed("ftps", from_user)) {
+		bits |= CURLPROTO_FTPS;
+		proto_list_append(list, "ftps");
+	}
+
+	return bits;
 }
 
 #ifdef GIT_CURL_HAVE_CURL_HTTP_VERSION_2
@@ -921,10 +938,26 @@ static CURL *get_curl_handle(void)
 
 	curl_easy_setopt(result, CURLOPT_MAXREDIRS, 20);
 	curl_easy_setopt(result, CURLOPT_POSTREDIR, CURL_REDIR_POST_ALL);
+
+#ifdef GIT_CURL_HAVE_CURLOPT_PROTOCOLS_STR
+	{
+		struct strbuf buf = STRBUF_INIT;
+
+		get_curl_allowed_protocols(0, &buf);
+		curl_easy_setopt(result, CURLOPT_REDIR_PROTOCOLS_STR, buf.buf);
+		strbuf_reset(&buf);
+
+		get_curl_allowed_protocols(-1, &buf);
+		curl_easy_setopt(result, CURLOPT_PROTOCOLS_STR, buf.buf);
+		strbuf_release(&buf);
+	}
+#else
 	curl_easy_setopt(result, CURLOPT_REDIR_PROTOCOLS,
-			 get_curl_allowed_protocols(0));
+			 get_curl_allowed_protocols(0, NULL));
 	curl_easy_setopt(result, CURLOPT_PROTOCOLS,
-			 get_curl_allowed_protocols(-1));
+			 get_curl_allowed_protocols(-1, NULL));
+#endif
+
 	if (getenv("GIT_CURL_VERBOSE"))
 		http_trace_curl_no_data();
 	setup_curl_trace(result);
-- 
2.39.0.513.g00e40dbe01
Previous: Jeff KingNext: Ramsay Jones
Message 34 of 42 in “ci: do not die on deprecated-declarations warning”
  1. ci: do not die on deprecated-declarations warningJunio C Hamano, Jan 14, 2023
  2. Ramsay JonesJan 14, 2023
  3. Ramsay JonesJan 14, 2023
  4. Junio C HamanoJan 14, 2023
  5. Jeff KingJan 14, 2023
  6. Jeff KingJan 14, 2023
  7. Junio C HamanoJan 14, 2023
  8. Jeff KingJan 14, 2023
  9. Junio C HamanoJan 15, 2023
  10. Jeff KingJan 15, 2023
  11. Junio C HamanoJan 15, 2023
  12. Junio C HamanoJan 14, 2023
  13. Junio C HamanoJan 15, 2023
  14. Jeff KingJan 15, 2023
  15. 1/3 http-push: prefer CURLOPT_UPLOAD to CURLOPT_PUTJeff King, Jan 15, 2023
  16. Ramsay JonesJan 15, 2023
  17. Jeff KingJan 15, 2023
  18. Jeff KingJan 15, 2023
  19. 2/3 http: prefer CURLOPT_SEEKFUNCTION to CURLOPT_IOCTLFUNCTIONJeff King, Jan 15, 2023
  20. Ramsay JonesJan 15, 2023
  21. Junio C HamanoJan 15, 2023
  22. Jeff KingJan 15, 2023
  23. 3/3 http: support CURLOPT_PROTOCOLS_STRJeff King, Jan 15, 2023
  24. Ramsay JonesJan 15, 2023
  25. Jeff KingJan 15, 2023
  26. Ævar Arnfjörð BjarmasonJan 16, 2023
  27. Junio C HamanoJan 16, 2023
  28. Junio C HamanoJan 16, 2023
  29. Jeff KingJan 16, 2023
  30. Jeff KingJan 16, 2023
  31. avoiding deprecated curl optionsJeff King, Jan 17, 2023
  32. 1/3 http-push: prefer CURLOPT_UPLOAD to CURLOPT_PUTJeff King, Jan 17, 2023
  33. 2/3 http: prefer CURLOPT_SEEKFUNCTION to CURLOPT_IOCTLFUNCTIONJeff King, Jan 17, 2023
  34. 3/3 http: support CURLOPT_PROTOCOLS_STRJeff King, Jan 17, 2023
  35. Ramsay JonesJan 18, 2023
  36. Jeff KingJan 14, 2023
  37. Ramsay JonesJan 16, 2023
  38. Jeff KingJan 16, 2023
  39. ci: do not die on deprecated-declarations warningJunio C Hamano, Jan 14, 2023
  40. Jeff KingJan 14, 2023
  41. 1/3 http-push: prefer CURLOPT_UPLOAD to CURLOPT_PUTJeff King, Jan 17, 2023
  42. Jeff KingJan 17, 2023

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.