Files
git/t/t5564-http-proxy.sh
Jeff King 1b5a6bfff3 curl: add support for curl_global_trace() components
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>
2025-08-27 09:49:43 -07:00

99 lines
2.9 KiB
Bash
Executable File

#!/bin/sh
test_description="test fetching through http proxy"
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-httpd.sh
LIB_HTTPD_PROXY=1
start_httpd
test_expect_success 'setup repository' '
test_commit foo &&
git init --bare "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
git push --mirror "$HTTPD_DOCUMENT_ROOT_PATH/repo.git"
'
setup_askpass_helper
# sanity check that our test setup is correctly using proxy
test_expect_success 'proxy requires password' '
test_config_global http.proxy $HTTPD_DEST &&
test_must_fail git clone $HTTPD_URL/smart/repo.git 2>err &&
grep "error.*407" err
'
test_expect_success 'clone through proxy with auth' '
test_when_finished "rm -rf clone" &&
test_config_global http.proxy http://proxuser:proxpass@$HTTPD_DEST &&
GIT_TRACE_CURL=$PWD/trace git clone $HTTPD_URL/smart/repo.git clone &&
grep -i "Proxy-Authorization: Basic <redacted>" trace
'
test_expect_success 'clone can prompt for proxy password' '
test_when_finished "rm -rf clone" &&
test_config_global http.proxy http://proxuser@$HTTPD_DEST &&
set_askpass nobody proxpass &&
GIT_TRACE_CURL=$PWD/trace git clone $HTTPD_URL/smart/repo.git clone &&
expect_askpass pass proxuser
'
start_socks() {
mkfifo socks_output &&
{
"$PERL_PATH" "$TEST_DIRECTORY/socks4-proxy.pl" "$1" >socks_output &
echo $! > "$TRASH_DIRECTORY/socks.pid"
} &&
read line <socks_output &&
test "$line" = ready
}
# The %30 tests that the correct amount of percent-encoding is applied to the
# proxy string passed to curl.
test_lazy_prereq SOCKS_PROXY '
test_have_prereq PERL &&
start_socks "$TRASH_DIRECTORY/%30.sock"
'
test_atexit '
test ! -e "$TRASH_DIRECTORY/socks.pid" ||
kill "$(cat "$TRASH_DIRECTORY/socks.pid")"
'
# The below tests morally ought to be gated on a prerequisite that Git is
# linked with a libcurl that supports Unix socket paths for proxies (7.84 or
# later), but this is not easy to test right now. Instead, we || the tests with
# this function.
old_libcurl_error() {
grep -Fx "fatal: libcurl 7.84 or later is required to support paths in proxy URLs" "$1"
}
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_TRACE_CURL_COMPONENTS=socks \
git clone "$HTTPD_URL/smart/repo.git" clone 2>err &&
grep -i "SOCKS4 request granted" trace
} ||
old_libcurl_error err
}
'
test_expect_success 'Unix socket requires socks*:' - <<\EOT
! git clone -c http.proxy=localhost/path https://example.com/repo.git 2>err && {
grep -Fx "fatal: Invalid proxy URL 'localhost/path': only SOCKS proxies support paths" err ||
old_libcurl_error err
}
EOT
test_expect_success 'Unix socket requires localhost' - <<\EOT
! git clone -c http.proxy=socks4://127.0.0.1/path https://example.com/repo.git 2>err && {
grep -Fx "fatal: Invalid proxy URL 'socks4://127.0.0.1/path': host must be localhost if a path is present" err ||
old_libcurl_error err
}
EOT
test_done