git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH] Prompt for a username when an HTTP request 401s

From
Scott Chacon <schacon@gmail.com>
Date
Mar 18, 2010, 18:57 UTC
Message-ID
<d411cc4a1003181157o79f1a1e1qcdea05322d76b812@mail.gmail.com>

When an HTTP request returns a 401, Git will currently fail with a confusing message saying that it got a 401. This 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 <schacon@gmail.com>
---
 http.c        |   21 +++++++++++++++++++--
 http.h        |    2 ++
 remote-curl.c |    2 ++
 3 files changed, 23 insertions(+), 2 deletions(-)
diff --git a/http.c b/http.c
index deab595..731783e 100644
--- a/http.c
+++ b/http.c
@@ -199,6 +199,11 @@ static int http_options(const char *var, const
char *value, void *cb)
 	return git_default_config(var, value, cb);
 }

+static void get_http_user_name()
+{
+	user_name = xstrdup(getpass("Username: "));
+}
+
 static void init_curl_http_auth(CURL *result)
 {
 	if (user_name) {
@@ -815,7 +820,15 @@ static int http_request(const char *url, void
*result, int target, int options)
 			ret = HTTP_OK;
 		else if (missing_target(&results))
 			ret = HTTP_MISSING_TARGET;
-		else
+		else if (results.http_code == 401) {
+			if (user_name) {
+				ret = HTTP_NOAUTH;
+			} else {
+				get_http_user_name();
+				init_curl_http_auth(slot->curl);
+				ret = HTTP_REAUTH;
+			}
+		} else
 			ret = HTTP_ERROR;
 	} else {
 		error("Unable to start HTTP request for %s", url);
@@ -831,7 +844,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;
 }

 /*
diff --git a/http.h b/http.h
index 5c9441c..2dd03e8 100644
--- a/http.h
+++ b/http.h
@@ -126,6 +126,8 @@ extern char *get_remote_object_url(const char
*url, const char *hex,
 #define HTTP_MISSING_TARGET	1
 #define HTTP_ERROR		2
 #define HTTP_START_FAILED	3
+#define HTTP_REAUTH	4
+#define HTTP_NOAUTH	5

 /*
  * Requests an url and stores the result in a strbuf.
diff --git a/remote-curl.c b/remote-curl.c
index b76bfcb..0782756 100644
--- a/remote-curl.c
+++ b/remote-curl.c
@@ -132,6 +132,8 @@ static struct discovery* discover_refs(const char *service)
 	case HTTP_MISSING_TARGET:
 		die("%s not found: did you run git update-server-info on the"
 		    " server?", refs_url);
+	case HTTP_NOAUTH:
+		die("Authentication failed");
 	default:
 		http_error(refs_url, http_ret);
 		die("HTTP request failed");
-- 
1.7.0.1
Next: Shawn O. Pearce
Message 1 of 3 in “Prompt for a username when an HTTP request 401s”
  1. Prompt for a username when an HTTP request 401sScott Chacon, Mar 18, 2010
  2. Shawn O. PearceMar 18, 2010
  3. René ScharfeMar 18, 2010

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.