]> git.ipfire.org Git - thirdparty/git.git/commitdiff
curl: add support for curl_global_trace() components
authorJeff King <peff@peff.net>
Wed, 27 Aug 2025 08:07:02 +0000 (04:07 -0400)
committerJunio C Hamano <gitster@pobox.com>
Wed, 27 Aug 2025 16:49:43 +0000 (09:49 -0700)
In addition to the regular trace information produced by
CURLOPT_VERBOSE, recent curl versions can enable or disable tracing of
specific subsystems using a call to curl_global_trace().

This level of detail may or may not be useful for us in Git as mere
users of libcurl, but there's one case where we need it for a test. In
t5564, we set up a socks proxy, access it with GIT_TRACE_CURL set, and
expect to find socks-related messages in the output. This test is broken
in the release candidates for libcurl 8.16, as those socks messages are
no longer produced in the trace.

The problem bisects to curl's commit ab5e0bfddc (pytest: add SOCKS tests
and scoring, 2025-07-21). There the socks messages were moved from
generic infof() messages to the component-specific CURL_TRC_CF() system.
And so we do not see them by default, but only if "socks" is enabled as
a logging component.

Teach Git's http code to accept a component list from the
environment and pass it into curl_global_trace(). We can then use
that in the test to enable the correct component.

It should be safe to do so unconditionally. In older versions of curl
which don't support this call, setting the environment variable is a
noop. Likewise, any versions of curl which don't recognize the "socks"
component should silently ignore it. The manpage for curl_global_trace()
says this:

  The config string is a list of comma-separated component names. Names
  are case-insensitive and unknown names are ignored. The special name
  "all" applies to all components. Names may be prefixed with '+' or '-'
  to enable or disable detailed logging for a component.

  The list of component names is not part of curl's public API. Names may
  be added or disappear in future versions of libcurl. Since unknown
  names are silently ignored, outdated log configurations does not cause
  errors when upgrading libcurl. Given that, some names can be expected
  to be fairly stable and are listed below for easy reference.

So this should let us make the test work on all versions without
worrying about confusing older (or newer) versions. For the same reason,
I've opted not to document this interface. This is deep internal voodoo
for which we can make no promises to users. In fact, I was tempted to
simply hard-code "socks" to let our test pass and not expose anything.
But I suspect a little run-time flexibility may come in handy in the
future when debugging or dealing with similar logging issues.

I also considered just putting "all" into such a hard-coded default. But
if you try it, you will see that many of the components are quite
verbose and likely not interesting. They would clutter up our trace
output if we enabled them by default.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
git-curl-compat.h
http.c
t/t5564-http-proxy.sh

index aa8eed7ed2b5e3bd7cd861681c84b511871941c0..659e5a3875e3d66820ba05936f3f79d934fa5c02 100644 (file)
 #define GIT_CURL_HAVE_CURLOPT_PROTOCOLS_STR 1
 #endif
 
+/**
+ * curl_global_trace() was added in 8.3.0, released September 2023.
+ */
+#if LIBCURL_VERSION_NUM >= 0x080300
+#define GIT_CURL_HAVE_GLOBAL_TRACE 1
+#endif
+
 /**
  * CURLOPT_TCP_KEEPCNT was added in 8.9.0, released in July, 2024.
  */
diff --git a/http.c b/http.c
index d88e79fbde9c4c707c6f14aeffe6e0ac312224bf..86254a3ebab23fea36f1c57e5be47474e4088621 100644 (file)
--- a/http.c
+++ b/http.c
@@ -1347,6 +1347,14 @@ void http_init(struct remote *remote, const char *url, int proactive_auth)
        if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK)
                die("curl_global_init failed");
 
+#ifdef GIT_CURL_HAVE_GLOBAL_TRACE
+       {
+               const char *comp = getenv("GIT_TRACE_CURL_COMPONENTS");
+               if (comp)
+                       curl_global_trace(comp);
+       }
+#endif
+
        if (proactive_auth && http_proactive_auth == PROACTIVE_AUTH_NONE)
                http_proactive_auth = PROACTIVE_AUTH_IF_CREDENTIALS;
 
index b27e481f95bc4d8948dd2f404f0972106c53a295..c3903faf2d3e6fde2a36a9a19a325d52e44fc4b1 100755 (executable)
@@ -72,7 +72,9 @@ test_expect_success SOCKS_PROXY 'clone via Unix socket' '
        test_when_finished "rm -rf clone" &&
        test_config_global http.proxy "socks4://localhost$PWD/%2530.sock" && {
                {
-                       GIT_TRACE_CURL=$PWD/trace git clone "$HTTPD_URL/smart/repo.git" clone 2>err &&
+                       GIT_TRACE_CURL=$PWD/trace \
+                       GIT_TRACE_CURL_COMPONENTS=socks \
+                       git clone "$HTTPD_URL/smart/repo.git" clone 2>err &&
                        grep -i "SOCKS4 request granted" trace
                } ||
                old_libcurl_error err