{"thread":{"id":"30504","subject":"[PATCH 1/3] http: handle proxy authentication failure (error 407)","startedAt":"2012-05-11T13:13:40Z","lastAt":"2012-05-11T17:15:51Z","messageCount":2,"participants":["Nelson Benitez Leon","Jeff King"],"isPatch":true,"patchVersion":1,"patchTotal":3},"messages":[{"id":"191387","messageId":"4FAD1084.4000605@seap.minhap.es","threadId":"30504","inReplyTo":null,"subject":"[PATCH 1/3] http: handle proxy authentication failure (error 407)","fromName":"Nelson Benitez Leon","fromEmail":"nelsonjesus.benitez@seap.minhap.es","sentAt":"2012-05-11T13:13:40Z","receivedAt":"2012-05-11T13:13:40Z","isPatch":true,"sender":{"key":"nelsonjesus.benitez@seap.minhap.es","avatar":null},"body":"Handle http 407 error code by asking for credentials and\nretrying request in case credentials were not present, or\nmarking credentials as rejected if they were already provided.\n\nSigned-off-by: Nelson Benitez Leon <nbenitezl@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n http.c |   24 ++++++++++++++++++++++++\n 1 files changed, 24 insertions(+), 0 deletions(-)\n\ndiff --git a/http.c b/http.c\nindex 5cb87f1..624d1a0 100644\n--- a/http.c\n+++ b/http.c\n@@ -43,6 +43,7 @@ static int curl_ftp_no_epsv;\n static const char *curl_http_proxy;\n static const char *curl_cookie_file;\n static struct credential http_auth = CREDENTIAL_INIT;\n+static struct credential proxy_auth = CREDENTIAL_INIT;\n static int http_proactive_auth;\n static const char *user_agent;\n \n@@ -241,6 +242,20 @@ static int has_cert_password(void)\n \treturn 1;\n }\n \n+static void set_proxy_auth(CURL *result)\n+{\n+\tif (proxy_auth.username && proxy_auth.password) {\n+#if LIBCURL_VERSION_NUM >= 0x071301\n+\t\tcurl_easy_setopt(result, CURLOPT_PROXYUSERNAME, proxy_auth.username);\n+\t\tcurl_easy_setopt(result, CURLOPT_PROXYPASSWORD, proxy_auth.password);\n+#else\n+\t\tstruct strbuf userpwd = STRBUF_INIT;\n+\t\tstrbuf_addf(&userpwd, \"%s:%s\", proxy_auth.username, proxy_auth.password);\n+\t\tcurl_easy_setopt(result, CURLOPT_PROXYUSERPWD, strbuf_detach(&userpwd, NULL));\n+#endif\n+\t}\n+}\n+\n static CURL *get_curl_handle(void)\n {\n \tCURL *result = curl_easy_init();\n@@ -804,6 +819,15 @@ static int http_request(const char *url, void *result, int target, int options)\n \t\t\t\tinit_curl_http_auth(slot->curl);\n \t\t\t\tret = HTTP_REAUTH;\n \t\t\t}\n+\t\t} else if (results.http_code == 407) { /* Proxy authentication failure */\n+\t\t\tif (proxy_auth.username && proxy_auth.password) {\n+\t\t\t\tcredential_reject(&proxy_auth);\n+\t\t\t\tret = HTTP_NOAUTH;\n+\t\t\t} else {\n+\t\t\t\tcredential_fill(&proxy_auth);\n+\t\t\t\tset_proxy_auth(slot->curl);\n+\t\t\t\tret = HTTP_REAUTH;\n+\t\t\t}\n \t\t} else {\n \t\t\tif (!curl_errorstr[0])\n \t\t\t\tstrlcpy(curl_errorstr,\n-- \n1.7.7.6\n"},{"id":"191402","messageId":"20120511171550.GB26916@sigill.intra.peff.net","threadId":"30504","inReplyTo":"4FAD1084.4000605@seap.minhap.es","subject":"Re: [PATCH 1/3] http: handle proxy authentication failure (error 407)","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2012-05-11T17:15:51Z","receivedAt":"2012-05-11T17:15:51Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, May 11, 2012 at 03:13:40PM +0200, Nelson Benitez Leon wrote:\n\n> @@ -804,6 +819,15 @@ static int http_request(const char *url, void *result, int target, int options)\n>  \t\t\t\tinit_curl_http_auth(slot->curl);\n>  \t\t\t\tret = HTTP_REAUTH;\n>  \t\t\t}\n> +\t\t} else if (results.http_code == 407) { /* Proxy authentication failure */\n> +\t\t\tif (proxy_auth.username && proxy_auth.password) {\n> +\t\t\t\tcredential_reject(&proxy_auth);\n> +\t\t\t\tret = HTTP_NOAUTH;\n> +\t\t\t} else {\n> +\t\t\t\tcredential_fill(&proxy_auth);\n> +\t\t\t\tset_proxy_auth(slot->curl);\n> +\t\t\t\tret = HTTP_REAUTH;\n> +\t\t\t}\n\nThis part will fill in the username/password based on the proxy URL. But\nwe never set the proxy URL ahead of time, so there is no chance for\ncredential helpers to act, and the prompts will be confusing (they will\njust say \"Password\" instead of \"Password for ...\", which will make it\nunclear that we want the proxy password, not the remote server's\npassword).\n\nSo it's OK to drop the environment-parsing bits, but:\n\n  1. When we _do_ get the proxy via config, should we still parse it? I\n     could go either way. It's a nice feature, and I think we don't have\n     to care about how the environment parsing or NO_PROXY works. On the\n     other hand, we could just wait for the callback-based\n     authentication that will come in newer versions of curl, and code\n     to that, which will be even simpler. In the meantime, people can\n     just accept it.\n\n  2. When we don't know the proxy name beforehand, we should probably\n     say something to stderr to indicate that it was a proxy\n     authentication failure.\n\nAlso, what about the dumb http-push code-paths? They would need us to\nhandle http_proactive_auth in the same way. Which obviously won't work\nfor environment-based proxies, but could work for config-based proxies.\nI'm not sure if it's worth caring about. In the long run, the\ncallback-based authentication is the way forward (though of course it\nwill take time for that feature to get released in curl, and then for\npeople to start having a curl that uses it, and so on).\n\nIf we just punt on (1) and the proactive auth thing, then I think as a\nminimum we can get away with squashing this into your patch:\n\ndiff --git a/http.c b/http.c\nindex 0023119..86e68ee 100644\n--- a/http.c\n+++ b/http.c\n@@ -824,6 +824,7 @@ static int http_request(const char *url, void *result, int target, int options)\n \t\t\t\tcredential_reject(&proxy_auth);\n \t\t\t\tret = HTTP_NOAUTH;\n \t\t\t} else {\n+\t\t\t\twarning(_(\"http proxy did not accept our credentials, retrying\"))\n \t\t\t\tcredential_fill(&proxy_auth);\n \t\t\t\tset_proxy_auth(slot->curl);\n \t\t\t\tret = HTTP_AUTH_RETRY;\n\n-Peff\n"}]}