http: add support selecting http version
authorForce Charlie <charlieio@outlook.com>
Fri, 9 Nov 2018 03:44:14 +0000 (19:44 -0800)
committerJunio C Hamano <gitster@pobox.com>
Fri, 9 Nov 2018 04:21:24 +0000 (13:21 +0900)
Usually we don't need to set libcurl to choose which version of the
HTTP protocol to use to communicate with a server.
But different versions of libcurl, the default value is not the same.

CURL >= 7.62.0: CURL_HTTP_VERSION_2TLS
CURL < 7.62: CURL_HTTP_VERSION_1_1

In order to give users the freedom to control the HTTP version,
we need to add a setting to choose which HTTP version to use.

Signed-off-by: Force Charlie <charlieio@outlook.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/config.txt
http.c
index 41a9ff2b6aa4ebcc87179ede7a70f680e2eba439..f397942128719130b849b4fc4622517f23547869 100644 (file)
@@ -1935,6 +1935,15 @@ http.saveCookies::
        If set, store cookies received during requests to the file specified by
        http.cookieFile. Has no effect if http.cookieFile is unset.
 
+http.version::
+       Use the specified HTTP protocol version when communicating with a server.
+       If you want to force the default. The available and default version depend
+       on libcurl. Actually the possible values of
+       this option are:
+
+       - HTTP/2
+       - HTTP/1.1
+
 http.sslVersion::
        The SSL version to use when negotiating an SSL connection, if you
        want to force the default.  The available and default version
diff --git a/http.c b/http.c
index 3dc8c560d65e7acebb22f63e797406e38afc6422..bc3274804eab106c7c607cf55c27c8699d464ce7 100644 (file)
--- a/http.c
+++ b/http.c
@@ -48,6 +48,7 @@ char curl_errorstr[CURL_ERROR_SIZE];
 
 static int curl_ssl_verify = -1;
 static int curl_ssl_try;
+static const char *curl_http_version = NULL;
 static const char *ssl_cert;
 static const char *ssl_cipherlist;
 static const char *ssl_version;
@@ -284,6 +285,9 @@ static void process_curl_messages(void)
 
 static int http_options(const char *var, const char *value, void *cb)
 {
+       if (!strcmp("http.version", var)) {
+               return git_config_string(&curl_http_version, var, value);
+       }
        if (!strcmp("http.sslverify", var)) {
                curl_ssl_verify = git_config_bool(var, value);
                return 0;
@@ -789,6 +793,31 @@ static long get_curl_allowed_protocols(int from_user)
 }
 #endif
 
+#if LIBCURL_VERSION_NUM >=0x072f00
+static int get_curl_http_version_opt(const char *version_string, long *opt)
+{
+       int i;
+       static struct {
+               const char *name;
+               long opt_token;
+       } choice[] = {
+               { "HTTP/1.1", CURL_HTTP_VERSION_1_1 },
+               { "HTTP/2", CURL_HTTP_VERSION_2 }
+       };
+
+       for (i = 0; i < ARRAY_SIZE(choice); i++) {
+               if (!strcmp(version_string, choice[i].name)) {
+                       *opt = choice[i].opt_token;
+                       return 0;
+               }
+       }
+
+       warning("unknown value given to http.version: '%s'", version_string);
+       return -1; /* not found */
+}
+
+#endif
+
 static CURL *get_curl_handle(void)
 {
        CURL *result = curl_easy_init();
@@ -806,6 +835,16 @@ static CURL *get_curl_handle(void)
                curl_easy_setopt(result, CURLOPT_SSL_VERIFYHOST, 2);
        }
 
+#if LIBCURL_VERSION_NUM >= 0x072f00 // 7.47.0
+    if (curl_http_version) {
+               long opt;
+               if (!get_curl_http_version_opt(curl_http_version, &opt)) {
+                       /* Set request use http version */
+                       curl_easy_setopt(result, CURLOPT_HTTP_VERSION, opt);
+               }
+    }
+#endif
+
 #if LIBCURL_VERSION_NUM >= 0x070907
        curl_easy_setopt(result, CURLOPT_NETRC, CURL_NETRC_OPTIONAL);
 #endif