path: root/http.c
diff options
authorScott Chacon <>2010-04-01 22:14:35 (GMT)
committerJunio C Hamano <>2010-04-02 06:24:59 (GMT)
commit42653c09c85015addc6fa8dd4d49cb250253412e (patch)
treecd33603246f89be8c771ff51284f9833bc565efa /http.c
parent890a13a45285ad44858add2ce2f74eb478f549c8 (diff)
Prompt for a username when an HTTP request 401s
When an HTTP request returns a 401, Git will currently fail with a confusing message saying that it got a 401, which is not very descriptive. Currently if a user wants to use Git over HTTP, they have to use one URL with the username in the URL (e.g. "") for write access and another without the username for unauthenticated read access (unless they want to be prompted for the password each time). However, since the HTTP servers will return a 401 if an action requires authentication, we can prompt for username and password if we see this, allowing us to use a single URL for both purposes. This patch changes http_request to prompt for the username and password, then return HTTP_REAUTH so http_get_strbuf can try again. If it gets a 401 even when a user/pass is supplied, http_request will now return HTTP_NOAUTH which remote_curl can then use to display a more intelligent error message that is less confusing. Signed-off-by: Scott Chacon <> Signed-off-by: Junio C Hamano <>
Diffstat (limited to 'http.c')
1 files changed, 20 insertions, 2 deletions
diff --git a/http.c b/http.c
index 4814217..51253e1 100644
--- a/http.c
+++ b/http.c
@@ -815,7 +815,21 @@ static int http_request(const char *url, void *result, int target, int options)
ret = HTTP_OK;
else if (missing_target(&results))
- else
+ else if (results.http_code == 401) {
+ if (user_name) {
+ ret = HTTP_NOAUTH;
+ } else {
+ /*
+ * git_getpass is needed here because its very likely stdin/stdout are
+ * pipes to our parent process. So we instead need to use /dev/tty,
+ * but that is non-portable. Using git_getpass() can at least be stubbed
+ * on other platforms with a different implementation if/when necessary.
+ */
+ user_name = xstrdup(git_getpass("Username: "));
+ init_curl_http_auth(slot->curl);
+ ret = HTTP_REAUTH;
+ }
+ } else
} else {
error("Unable to start HTTP request for %s", url);
@@ -831,7 +845,11 @@ static int http_request(const char *url, void *result, int target, int options)
int http_get_strbuf(const char *url, struct strbuf *result, int options)
- return http_request(url, result, HTTP_REQUEST_STRBUF, options);
+ int http_ret = http_request(url, result, HTTP_REQUEST_STRBUF, options);
+ if (http_ret == HTTP_REAUTH) {
+ http_ret = http_request(url, result, HTTP_REQUEST_STRBUF, options);
+ }
+ return http_ret;