diff --git a/git-curl-compat.h b/git-curl-compat.h index 032aaf7126..25678b5dbd 100644 --- a/git-curl-compat.h +++ b/git-curl-compat.h @@ -28,6 +28,13 @@ * introduced, oldest first, in the official version of cURL library. */ +/** + * curl_url() interface added in 7.62.0 (October 2018) + */ +#if LIBCURL_VERSION_NUM >= 0x073e00 +#define GIT_CURL_HAVE_CURL_URL +#endif + /** * Versions before curl 7.66.0 (September 2019) required manually setting the * transfer-encoding for a streaming POST; after that this is handled diff --git a/http.c b/http.c index c8fcfd7693..4af3c29c76 100644 --- a/http.c +++ b/http.c @@ -2315,6 +2315,45 @@ static int http_request(const char *url, return ret; } +#ifndef GIT_CURL_HAVE_CURL_URL +#define strip_url_credential(in) NULL +#else +static char *strip_url_credential(const char *in) +{ + char *ret = NULL; + CURLU *url; + + url = curl_url(); + if (!url) + goto out; + + if (curl_url_set(url, CURLUPART_URL, in, 0)) + goto out; + + curl_url_set(url, CURLUPART_USER, NULL, 0); + curl_url_set(url, CURLUPART_PASSWORD, NULL, 0); + curl_url_get(url, CURLUPART_URL, &ret, 0); + +out: + curl_url_cleanup(url); + return ret; +} +#endif + +static int match_effective_url(const char *asked, const char *got) +{ + char *stripped; + int ret; + + if (!strcmp(asked, got)) + return 1; + + stripped = strip_url_credential(asked); + ret = stripped && !strcmp(stripped, got); + curl_free(stripped); + return ret; +} + /* * Update the "base" url to a more appropriate value, as deduced by * redirects seen when requesting a URL starting with "url". @@ -2347,7 +2386,7 @@ static int update_url_from_redirect(struct strbuf *base, const char *tail; size_t new_len; - if (!strcmp(asked, got->buf)) + if (match_effective_url(asked, got->buf)) return 0; if (!skip_prefix(asked, base->buf, &tail))