Subject: Re: FYI: git issues with libcurl 8.0/1 HTTPS push

From: Junio C Hamano <[email-masked]>
Date: Tue, 22 Aug 2023 09:27:55 -0700

Daniel Stenberg <[email-masked]> writes:

> If you use git with libcurl 8.0.x or 8.1.x, there is a risk that you
> will experience a "curl 56 HTTP/2 stream N was reset" errors when
> pushing over HTTPS. (where N is an odd number, often 7)
>
> This is an unfortunate bug in libcurl that has subsequently already
> been fixed. We recommend using libcurl 8.2.1 (or later).
>
> You can work around this issue (that tends to be sticky) by forcing
> git to use HTTP/1.1 instead of HTTP/2 for the push and then restore
> back to the previous state again.

Thanks for a heads-up.

The following is admittedly a very blunt workaround to disable
HTTP/2 for the affected versions for any purpose, but I wonder if it
is an acceptable workaround.  The remote-curl transport helper is
used for both push and fetch and I didn't find a good place to
automatically force the protocol version only for pushes.

 git-curl-compat.h | 12 ++++++++++++
 http.c            |  2 +-
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git c/git-curl-compat.h w/git-curl-compat.h
index fd96b3cdff..f253408288 100644
--- c/git-curl-compat.h
+++ w/git-curl-compat.h
@@ -134,4 +134,16 @@
 #define GIT_CURL_HAVE_CURLOPT_PROTOCOLS_STR 1
 #endif
 
+/**
+ * If you use git with libcurl 8.0.x or 8.1.x, there is a risk that
+ * you will experience a "curl 56 HTTP/2 stream N was reset" errors
+ * when pushing over HTTPS. (where N is an odd number, often 7)
+ *
+ * This is an unfortunate bug in libcurl that has subsequently already
+ * been fixed. We recommend using libcurl 8.2.1 (or later).
+ */
+#if (LIBCURL_VERSION_NUM >= 0x080000) && (LIBCURL_VERSION_NUM < 0x080201)
+#define GIT_CURL_AVOID_HTTP2 1
+#endif
+
 #endif
diff --git c/http.c w/http.c
index e138b4b96f..156d6236da 100644
--- c/http.c
+++ w/http.c
@@ -962,7 +962,7 @@ static CURL *get_curl_handle(void)
 		curl_easy_setopt(result, CURLOPT_SSL_VERIFYHOST, 2);
 	}
 
-#ifdef GIT_CURL_HAVE_CURL_HTTP_VERSION_2
+#if defined(GIT_CURL_HAVE_CURL_HTTP_VERSION_2) && !defined(GIT_CURL_AVOID_HTTP2)
     if (curl_http_version) {
 		long opt;
 		if (!get_curl_http_version_opt(curl_http_version, &opt)) {