Merge branch 'sc/http-late-auth' into maint
authorJunio C Hamano <gitster@pobox.com>
Wed, 16 Jun 2010 23:32:15 +0000 (16:32 -0700)
committerJunio C Hamano <gitster@pobox.com>
Wed, 16 Jun 2010 23:32:15 +0000 (16:32 -0700)
* sc/http-late-auth:
Prompt for a username when an HTTP request 401s

http.c
http.h
remote-curl.c
diff --git a/http.c b/http.c
index 901e5972970e672f2524d70d11d4c3bb74ce98c5..1320c50e32eb7b8715b263bc2af089c3dbce39fa 100644 (file)
--- a/http.c
+++ b/http.c
@@ -816,7 +816,21 @@ 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 {
+                               /*
+                                * 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
                        ret = HTTP_ERROR;
        } else {
                error("Unable to start HTTP request for %s", url);
@@ -832,7 +846,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 b431b8bd5b6d694dd01fc92b2ffcca41655d82bf..a0b59015948c3b9736dd6c09fd9137f7ecd4f59a 100644 (file)
--- a/http.h
+++ b/http.h
@@ -127,6 +127,8 @@ extern void end_url_with_slash(struct strbuf *buf, const char *url);
 #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.
index 9c7fcf29566caa3813bd91a22fc78a00cec05335..24fbb9a9b972c1078b3688b2d0683c9704e09ee6 100644 (file)
@@ -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");