]> git.ipfire.org Git - thirdparty/git.git/commit
http: preserve wwwauth_headers across redirects
authorAaron Plattner <aplattner@nvidia.com>
Tue, 2 Jun 2026 16:11:48 +0000 (09:11 -0700)
committerJunio C Hamano <gitster@pobox.com>
Tue, 2 Jun 2026 22:38:45 +0000 (07:38 +0900)
commitbb88a926f48667eebc60573de1ffd98b156deec4
tree10f3a573bba894ec9d16836b6bafdaab7e4e2cff
parent94f057755b7941b321fd11fec1b2e3ca5313a4e0
http: preserve wwwauth_headers across redirects

When cURL follows a redirect, it calls the CURLOPT_HEADERFUNCTION for
each header received including ones from a redirect. http_request() sets
fwrite_wwwauth() as the header function, which will record the wwwauth[]
entries for the last step in the redirection chain.

However, when http_request_recoverable() sees that cURL followed a
redirect, it attempts to update the credentials for the request from the
new URL using credential_from_url(). The first thing that does is call
credential_clear(), which clears everything including wwwauth_headers.

If the new URL should use a credential helper rather than credentials
embedded in the URL, this loses the list of authentication methods that
the server provided in the redirect.

For example, I have a server that supports HTTP but always redirects to
HTTPS before handling requests. This redirect breaks OAuth
authentication:

  $ git ls-remote http://server/git
  => Send header: GET /git/info/refs?service=git-upload-pack HTTP/1.1
  <= Recv header: HTTP/1.1 302 Found
  <= Recv header: Location: https://server.nvidia.com/git/info/refs?service=git-upload-pack
  == Info: Issue another request to this URL: 'https://server.nvidia.com/git/info/refs?service=git-upload-pack'
  => Send header: GET /git/info/refs?service=git-upload-pack HTTP/1.1
  <= Recv header: HTTP/1.1 401 Unauthorized
  <= Recv header: WWW-Authenticate: Bearer error="invalid_request", error_description="No bearer token found in the request", msal-tenant-id="<tenant>", msal-client-id="<client>"
  trace: run_command: 'git credential-cache --timeout 7200 get'
  trace: start_command: /bin/sh -c 'git credential-cache --timeout 7200 get' 'git credential-cache --timeout 7200 get'
  trace: built-in: git credential-cache --timeout 7200 get
  trace: run_command: 'git credential-msal get'
  trace: start_command: /bin/sh -c 'git credential-msal get' 'git credential-msal get'
  trace: exec: git-credential-msal get
  trace: run_command: git-credential-msal get
  trace: start_command: /usr/bin/git-credential-msal get
  Username for 'https://server.nvidia.com': ^C

When git invokes the credential helper, it doesn't include the wwwauth[]
array, so git-credential-msal doesn't think that OAuth is supported [1].

Fix the problem by preserving the wwwauth_headers strvec across the call
to credential_from_url().

[1] https://github.com/Binary-Eater/git-credential-msal/blob/trunk/src/git_credential_msal/main.py#L69

Signed-off-by: Aaron Plattner <aplattner@nvidia.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
http.c
t/lib-httpd/apache.conf
t/t5563-simple-http-auth.sh