Skip to content

Commit 986bbc0

Browse files
snaewegitster
authored andcommitted
http: don't always prompt for password
When a username is already specified at the beginning of any HTTP transaction (e.g. "git push https://[email protected]/project.git" or "git ls-remote https://[email protected]/project.git"), the code interactively asks for a password before calling into the libcurl library. It is very likely that the reason why user included the username in the URL is because the user knows that it would require authentication to access the resource. Asking for the password upfront would save one roundtrip to get a 401 response, getting the password and then retrying the request. This is a reasonable optimization. HOWEVER. This is done even when $HOME/.netrc might have a corresponding entry to access the site, or the site does not require authentication to access the resource after all. But neither condition can be determined until we call into libcurl library (we do not read and parse $HOME/.netrc ourselves). In these cases, the user is forced to respond to the password prompt, only to give a password that is not used in the HTTP transaction. If the password is in $HOME/.netrc, an empty input would later let the libcurl layer to pick up the password from there, and if the resource does not require authentication, any input would be taken and then discarded without getting used. It is wasteful to ask this unused information to the end user. Reduce the confusion by not trying to optimize for this case and always incur roundtrip penalty. An alternative might be to document this and keep this round-trip optimization as-is. Signed-off-by: Stefan Naewe <[email protected]> Helped-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 9638384 commit 986bbc0

File tree

1 file changed

+3
-4
lines changed

1 file changed

+3
-4
lines changed

http.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -279,8 +279,6 @@ static CURL *get_curl_handle(void)
279279
curl_easy_setopt(result, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
280280
#endif
281281

282-
init_curl_http_auth(result);
283-
284282
if (ssl_cert != NULL)
285283
curl_easy_setopt(result, CURLOPT_SSLCERT, ssl_cert);
286284
if (has_cert_password())
@@ -846,7 +844,7 @@ static int http_request(const char *url, void *result, int target, int options)
846844
else if (missing_target(&results))
847845
ret = HTTP_MISSING_TARGET;
848846
else if (results.http_code == 401) {
849-
if (user_name) {
847+
if (user_name && user_pass) {
850848
ret = HTTP_NOAUTH;
851849
} else {
852850
/*
@@ -855,7 +853,8 @@ static int http_request(const char *url, void *result, int target, int options)
855853
* but that is non-portable. Using git_getpass() can at least be stubbed
856854
* on other platforms with a different implementation if/when necessary.
857855
*/
858-
user_name = xstrdup(git_getpass_with_description("Username", description));
856+
if (!user_name)
857+
user_name = xstrdup(git_getpass_with_description("Username", description));
859858
init_curl_http_auth(slot->curl);
860859
ret = HTTP_REAUTH;
861860
}

0 commit comments

Comments
 (0)