Skip to content

Commit e4ff3b6

Browse files
avargitster
authored andcommitted
http: centralize the accounting of libcurl dependencies
As discussed in 644de29 (http: drop support for curl < 7.19.4, 2021-07-30) checking against LIBCURL_VERSION_NUM isn't as reliable as checking specific symbols present in curl, as some distros have been known to backport features. However, while some of the curl_easy_setopt() arguments we rely on are macros, others are enum, and we can't assume that those that are macros won't change into enums in the future. So we're still going to have to check LIBCURL_VERSION_NUM, but by doing that in one central place and using a macro definition of our own, anyone who's backporting features can define it themselves, and thus have access to more modern curl features that they backported, even if they didn't bump the LIBCURL_VERSION_NUM. More importantly, as shown in a preceding commit doing these version checks makes for hard to read and possibly buggy code, as shown by the bug fixed there where we were conflating base 10 for base 16 when comparing the version. By doing them all in one place we'll hopefully reduce the chances of such future mistakes, furthermore it now becomes easier to see at a glance what the oldest supported version is, which makes it easier to reason about any future deprecation similar to the recent e48a623 (Merge branch 'ab/http-drop-old-curl', 2021-08-24). Signed-off-by: Ævar Arnfjörð Bjarmason <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 905a028 commit e4ff3b6

File tree

3 files changed

+133
-15
lines changed

3 files changed

+133
-15
lines changed

git-curl-compat.h

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
#ifndef GIT_CURL_COMPAT_H
2+
#define GIT_CURL_COMPAT_H
3+
#include <curl/curl.h>
4+
5+
/**
6+
* This header centralizes the declaration of our libcurl dependencies
7+
* to make it easy to discover the oldest versions we support, and to
8+
* inform decisions about removing support for older libcurl in the
9+
* future.
10+
*
11+
* The oldest supported version of curl is documented in the "INSTALL"
12+
* document.
13+
*
14+
* The source of truth for what versions have which symbols is
15+
* https://github.com/curl/curl/blob/master/docs/libcurl/symbols-in-versions;
16+
* the release dates are taken from curl.git (at
17+
* https://github.com/curl/curl/).
18+
*
19+
* For each X symbol we need from curl we define our own
20+
* GIT_CURL_HAVE_X. If multiple similar symbols with the same prefix
21+
* were defined in the same version we pick one and check for that name.
22+
*
23+
* Keep any symbols in date order of when their support was
24+
* introduced, oldest first, in the official version of cURL library.
25+
*/
26+
27+
/**
28+
* CURLOPT_TCP_KEEPALIVE was added in 7.25.0, released in March 2012.
29+
*/
30+
#if LIBCURL_VERSION_NUM >= 0x071900
31+
#define GITCURL_HAVE_CURLOPT_TCP_KEEPALIVE 1
32+
#endif
33+
34+
35+
/**
36+
* CURLOPT_LOGIN_OPTIONS was added in 7.34.0, released in December
37+
* 2013.
38+
*
39+
* If we start requiring 7.34.0 we might also be able to remove the
40+
* code conditional on USE_CURL_FOR_IMAP_SEND in imap-send.c, see
41+
* 1e16b255b95 (git-imap-send: use libcurl for implementation,
42+
* 2014-11-09) and the check it added for "072200" in the Makefile.
43+
44+
*/
45+
#if LIBCURL_VERSION_NUM >= 0x072200
46+
#define GIT_CURL_HAVE_CURLOPT_LOGIN_OPTIONS 1
47+
#endif
48+
49+
/**
50+
* CURL_SSLVERSION_TLSv1_[012] was added in 7.34.0, released in
51+
* December 2013.
52+
*/
53+
#if LIBCURL_VERSION_NUM >= 0x072200
54+
#define GIT_CURL_HAVE_CURL_SSLVERSION_TLSv1_0
55+
#endif
56+
57+
/**
58+
* CURLOPT_PINNEDPUBLICKEY was added in 7.39.0, released in November
59+
* 2014.
60+
*/
61+
#if LIBCURL_VERSION_NUM >= 0x072c00
62+
#define GIT_CURL_HAVE_CURLOPT_PINNEDPUBLICKEY 1
63+
#endif
64+
65+
/**
66+
* CURL_HTTP_VERSION_2 was added in 7.43.0, released in June 2015.
67+
*
68+
* The CURL_HTTP_VERSION_2 alias (but not CURL_HTTP_VERSION_2_0) has
69+
* always been a macro, not an enum field (checked on curl version
70+
* 7.78.0)
71+
*/
72+
#if LIBCURL_VERSION_NUM >= 0x072b00
73+
#define GIT_CURL_HAVE_CURL_HTTP_VERSION_2 1
74+
#endif
75+
76+
/**
77+
* CURLSSLOPT_NO_REVOKE was added in 7.44.0, released in August 2015.
78+
*
79+
* The CURLSSLOPT_NO_REVOKE is, has always been a macro, not an enum
80+
* field (checked on curl version 7.78.0)
81+
*/
82+
#if LIBCURL_VERSION_NUM >= 0x072c00
83+
#define GIT_CURL_HAVE_CURLSSLOPT_NO_REVOKE 1
84+
#endif
85+
86+
/**
87+
* CURLOPT_PROXY_CAINFO was added in 7.52.0, released in August 2017.
88+
*/
89+
#if LIBCURL_VERSION_NUM >= 0x073400
90+
#define GIT_CURL_HAVE_CURLOPT_PROXY_CAINFO 1
91+
#endif
92+
93+
/**
94+
* CURLOPT_PROXY_{KEYPASSWD,SSLCERT,SSLKEY} was added in 7.52.0,
95+
* released in August 2017.
96+
*/
97+
#if LIBCURL_VERSION_NUM >= 0x073400
98+
#define GIT_CURL_HAVE_CURLOPT_PROXY_KEYPASSWD 1
99+
#endif
100+
101+
/**
102+
* CURL_SSLVERSION_TLSv1_3 was added in 7.53.0, released in February
103+
* 2017.
104+
*/
105+
#if LIBCURL_VERSION_NUM >= 0x073400
106+
#define GIT_CURL_HAVE_CURL_SSLVERSION_TLSv1_3 1
107+
#endif
108+
109+
/**
110+
* CURLSSLSET_{NO_BACKENDS,OK,TOO_LATE,UNKNOWN_BACKEND} were added in
111+
* 7.56.0, released in September 2017.
112+
*/
113+
#if LIBCURL_VERSION_NUM >= 0x073800
114+
#define GIT_CURL_HAVE_CURLSSLSET_NO_BACKENDS
115+
#endif
116+
117+
#endif

http.c

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "git-compat-util.h"
2+
#include "git-curl-compat.h"
23
#include "http.h"
34
#include "config.h"
45
#include "pack.h"
@@ -47,19 +48,19 @@ static struct {
4748
{ "sslv2", CURL_SSLVERSION_SSLv2 },
4849
{ "sslv3", CURL_SSLVERSION_SSLv3 },
4950
{ "tlsv1", CURL_SSLVERSION_TLSv1 },
50-
#if LIBCURL_VERSION_NUM >= 0x072200
51+
#ifdef GIT_CURL_HAVE_CURL_SSLVERSION_TLSv1_0
5152
{ "tlsv1.0", CURL_SSLVERSION_TLSv1_0 },
5253
{ "tlsv1.1", CURL_SSLVERSION_TLSv1_1 },
5354
{ "tlsv1.2", CURL_SSLVERSION_TLSv1_2 },
5455
#endif
55-
#if LIBCURL_VERSION_NUM >= 0x073400
56+
#ifdef GIT_CURL_HAVE_CURL_SSLVERSION_TLSv1_3
5657
{ "tlsv1.3", CURL_SSLVERSION_TLSv1_3 },
5758
#endif
5859
};
5960
static const char *ssl_key;
6061
static const char *ssl_capath;
6162
static const char *curl_no_proxy;
62-
#if LIBCURL_VERSION_NUM >= 0x072700
63+
#ifdef GIT_CURL_HAVE_CURLOPT_PINNEDPUBLICKEY
6364
static const char *ssl_pinnedkey;
6465
#endif
6566
static const char *ssl_cainfo;
@@ -373,7 +374,7 @@ static int http_options(const char *var, const char *value, void *cb)
373374
}
374375

375376
if (!strcmp("http.pinnedpubkey", var)) {
376-
#if LIBCURL_VERSION_NUM >= 0x072700
377+
#ifdef GIT_CURL_HAVE_CURLOPT_PINNEDPUBLICKEY
377378
return git_config_pathname(&ssl_pinnedkey, var, value);
378379
#else
379380
warning(_("Public key pinning not supported with cURL < 7.39.0"));
@@ -500,7 +501,7 @@ static int has_cert_password(void)
500501
return 1;
501502
}
502503

503-
#if LIBCURL_VERSION_NUM >= 0x073400
504+
#ifdef GIT_CURL_HAVE_CURLOPT_PROXY_KEYPASSWD
504505
static int has_proxy_cert_password(void)
505506
{
506507
if (http_proxy_ssl_cert == NULL || proxy_ssl_cert_password_required != 1)
@@ -516,7 +517,7 @@ static int has_proxy_cert_password(void)
516517
}
517518
#endif
518519

519-
#if LIBCURL_VERSION_NUM >= 0x071900
520+
#ifdef GITCURL_HAVE_CURLOPT_TCP_KEEPALIVE
520521
static void set_curl_keepalive(CURL *c)
521522
{
522523
curl_easy_setopt(c, CURLOPT_TCP_KEEPALIVE, 1);
@@ -732,7 +733,7 @@ static long get_curl_allowed_protocols(int from_user)
732733
return allowed_protocols;
733734
}
734735

735-
#if LIBCURL_VERSION_NUM >=0x072b00
736+
#ifdef GIT_CURL_HAVE_CURL_HTTP_VERSION_2
736737
static int get_curl_http_version_opt(const char *version_string, long *opt)
737738
{
738739
int i;
@@ -774,7 +775,7 @@ static CURL *get_curl_handle(void)
774775
curl_easy_setopt(result, CURLOPT_SSL_VERIFYHOST, 2);
775776
}
776777

777-
#if LIBCURL_VERSION_NUM >= 0x072b00
778+
#ifdef GIT_CURL_HAVE_CURL_HTTP_VERSION_2
778779
if (curl_http_version) {
779780
long opt;
780781
if (!get_curl_http_version_opt(curl_http_version, &opt)) {
@@ -805,7 +806,7 @@ static CURL *get_curl_handle(void)
805806

806807
if (http_ssl_backend && !strcmp("schannel", http_ssl_backend) &&
807808
!http_schannel_check_revoke) {
808-
#if LIBCURL_VERSION_NUM >= 0x072c00
809+
#ifdef GIT_CURL_HAVE_CURLSSLOPT_NO_REVOKE
809810
curl_easy_setopt(result, CURLOPT_SSL_OPTIONS, CURLSSLOPT_NO_REVOKE);
810811
#else
811812
warning(_("CURLSSLOPT_NO_REVOKE not supported with cURL < 7.44.0"));
@@ -845,20 +846,20 @@ static CURL *get_curl_handle(void)
845846
curl_easy_setopt(result, CURLOPT_SSLKEY, ssl_key);
846847
if (ssl_capath != NULL)
847848
curl_easy_setopt(result, CURLOPT_CAPATH, ssl_capath);
848-
#if LIBCURL_VERSION_NUM >= 0x072700
849+
#ifdef GIT_CURL_HAVE_CURLOPT_PINNEDPUBLICKEY
849850
if (ssl_pinnedkey != NULL)
850851
curl_easy_setopt(result, CURLOPT_PINNEDPUBLICKEY, ssl_pinnedkey);
851852
#endif
852853
if (http_ssl_backend && !strcmp("schannel", http_ssl_backend) &&
853854
!http_schannel_use_ssl_cainfo) {
854855
curl_easy_setopt(result, CURLOPT_CAINFO, NULL);
855-
#if LIBCURL_VERSION_NUM >= 0x073400
856+
#ifdef GIT_CURL_HAVE_CURLOPT_PROXY_CAINFO
856857
curl_easy_setopt(result, CURLOPT_PROXY_CAINFO, NULL);
857858
#endif
858859
} else if (ssl_cainfo != NULL || http_proxy_ssl_ca_info != NULL) {
859860
if (ssl_cainfo != NULL)
860861
curl_easy_setopt(result, CURLOPT_CAINFO, ssl_cainfo);
861-
#if LIBCURL_VERSION_NUM >= 0x073400
862+
#ifdef GIT_CURL_HAVE_CURLOPT_PROXY_CAINFO
862863
if (http_proxy_ssl_ca_info != NULL)
863864
curl_easy_setopt(result, CURLOPT_PROXY_CAINFO, http_proxy_ssl_ca_info);
864865
#endif
@@ -939,7 +940,7 @@ static CURL *get_curl_handle(void)
939940
else if (starts_with(curl_http_proxy, "socks"))
940941
curl_easy_setopt(result,
941942
CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4);
942-
#if LIBCURL_VERSION_NUM >= 0x073400
943+
#ifdef GIT_CURL_HAVE_CURLOPT_PROXY_KEYPASSWD
943944
else if (starts_with(curl_http_proxy, "https")) {
944945
curl_easy_setopt(result, CURLOPT_PROXYTYPE, CURLPROXY_HTTPS);
945946

@@ -1004,7 +1005,7 @@ void http_init(struct remote *remote, const char *url, int proactive_auth)
10041005
free(normalized_url);
10051006
string_list_clear(&config.vars, 1);
10061007

1007-
#if LIBCURL_VERSION_NUM >= 0x073800
1008+
#ifdef GIT_CURL_HAVE_CURLSSLSET_NO_BACKENDS
10081009
if (http_ssl_backend) {
10091010
const curl_ssl_backend **backends;
10101011
struct strbuf buf = STRBUF_INIT;

imap-send.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1441,7 +1441,7 @@ static CURL *setup_curl(struct imap_server_conf *srvc, struct credential *cred)
14411441
curl_easy_setopt(curl, CURLOPT_PORT, server.port);
14421442

14431443
if (server.auth_method) {
1444-
#if LIBCURL_VERSION_NUM < 0x072200
1444+
#ifndef GIT_CURL_HAVE_CURLOPT_LOGIN_OPTIONS
14451445
warning("No LOGIN_OPTIONS support in this cURL version");
14461446
#else
14471447
struct strbuf auth = STRBUF_INIT;

0 commit comments

Comments
 (0)