# [PATCH 3/6] http: fix http_proxy specified without protocol part

2 messages from 2012-05-03 to 2012-05-04. Participants: Nelson Benitez Leon, Jeff King.
Thread: https://gitlist.dev/t/30409

## Nelson Benitez Leon, 2012-05-03 16:40

Subject: [PATCH 3/6] http: fix http_proxy specified without protocol part
Message-ID: <4FA2B4E6.3080009@seap.minhap.es>
URL: https://gitlist.dev/e/4FA2B4E6.3080009%40seap.minhap.es

```
An earlier patch broke http_proxy specified as <host>:<port> by abusing
credential_from_url().  Teach the function to parse that format, but the
caller needs to be updated to handle the case where there is no protocol
in the parse result.

Also allow keyring implementations to differentiate authentication
material meant for http proxies and http destinations by using a
different token "http-proxy" to consult them for the former.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 credential.c |   12 ++++++++----
 http.c       |   13 ++++++++-----
 2 files changed, 16 insertions(+), 9 deletions(-)

diff --git a/credential.c b/credential.c
index 62d1c56..813e3cf 100644
--- a/credential.c
+++ b/credential.c
@@ -324,11 +324,15 @@ void credential_from_url(struct credential *c, const char *url)
 	 *   (1) proto://<host>/...
 	 *   (2) proto://<user>@<host>/...
 	 *   (3) proto://<user>:<pass>@<host>/...
+	 * or "proto://"-less variants of the above. They are not technically
+	 * URLs, but the caller may have some context-specific knowledge about
+	 * what protocol is in use.
 	 */
 	proto_end = strstr(url, "://");
-	if (!proto_end)
-		return;
-	cp = proto_end + 3;
+	if (proto_end)
+		cp = proto_end + 3;
+	else
+		cp = url;
 	at = strchr(cp, '@');
 	colon = strchr(cp, ':');
 	slash = strchrnul(cp, '/');
@@ -348,7 +352,7 @@ void credential_from_url(struct credential *c, const char *url)
 		host = at + 1;
 	}
 
-	if (proto_end - url > 0)
+	if (proto_end && proto_end != url)
 		c->protocol = xmemdupz(url, proto_end - url);
 	if (slash - host > 0)
 		c->host = url_decode_mem(host, slash - host);
diff --git a/http.c b/http.c
index 02f9fcd..22ffe0c 100644
--- a/http.c
+++ b/http.c
@@ -366,17 +366,20 @@ static CURL *get_curl_handle(const char *url)
 	}
 	
 	if (curl_http_proxy) {
-		struct strbuf proxyhost = STRBUF_INIT;
-
-		if (!proxy_auth.host) /* check to parse only once */
+		if (!proxy_auth.host) {
 			credential_from_url(&proxy_auth, curl_http_proxy);
+			if (!proxy_auth.protocol ||
+			    !strcmp(proxy_auth.protocol, "http")) {
+				free(proxy_auth.protocol);
+				proxy_auth.protocol = xstrdup("http-proxy");
+			}
+		}
 
 		if (http_proactive_auth && proxy_auth.username && !proxy_auth.password)
 			/* proxy string has username but no password, ask for password */
 			credential_fill(&proxy_auth);
 
-		strbuf_addf(&proxyhost, "%s://%s", proxy_auth.protocol, proxy_auth.host);
-		curl_easy_setopt(result, CURLOPT_PROXY, strbuf_detach(&proxyhost, NULL));
+		curl_easy_setopt(result, CURLOPT_PROXY, curl_http_proxy);
 		curl_easy_setopt(result, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
 		set_proxy_auth(result);
 	}
-- 
1.7.7.6

```

## Jeff King, 2012-05-04 07:22

Subject: Re: [PATCH 3/6] http: fix http_proxy specified without protocol part
Message-ID: <20120504072220.GC21895@sigill.intra.peff.net>
URL: https://gitlist.dev/e/20120504072220.GC21895%40sigill.intra.peff.net
In-Reply-To: <4FA2B4E6.3080009@seap.minhap.es>

```
On Thu, May 03, 2012 at 06:40:06PM +0200, Nelson Benitez Leon wrote:

> An earlier patch broke http_proxy specified as <host>:<port> by abusing
> credential_from_url().  Teach the function to parse that format, but the
> caller needs to be updated to handle the case where there is no protocol
> in the parse result.
> 
> Also allow keyring implementations to differentiate authentication
> material meant for http proxies and http destinations by using a
> different token "http-proxy" to consult them for the former.
> 
> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Should this be:

  From: Junio C Hamano <gitster@pobox.com>

?

Also, any time we read "an earlier patch broke..." and that earlier
patch is in this series, I have to wonder why the patches are not simply
reordered. Shouldn't the first half of this one come first, and just
explain the rationale as "teach credential_from_url to handle
protocol-less URLs, since those are used for proxy specifications, which
we will need to parse in a later patch".

> diff --git a/http.c b/http.c
> index 02f9fcd..22ffe0c 100644
> --- a/http.c
> +++ b/http.c
> @@ -366,17 +366,20 @@ static CURL *get_curl_handle(const char *url)
>  	}
>  	
>  	if (curl_http_proxy) {
> -		struct strbuf proxyhost = STRBUF_INIT;
> -
> -		if (!proxy_auth.host) /* check to parse only once */
> +		if (!proxy_auth.host) {
>  			credential_from_url(&proxy_auth, curl_http_proxy);
> +			if (!proxy_auth.protocol ||
> +			    !strcmp(proxy_auth.protocol, "http")) {
> +				free(proxy_auth.protocol);
> +				proxy_auth.protocol = xstrdup("http-proxy");
> +			}
> +		}

And then this hunk would just get squashed in in the first place.

>  		if (http_proactive_auth && proxy_auth.username && !proxy_auth.password)
>  			/* proxy string has username but no password, ask for password */
>  			credential_fill(&proxy_auth);
>  
> -		strbuf_addf(&proxyhost, "%s://%s", proxy_auth.protocol, proxy_auth.host);
> -		curl_easy_setopt(result, CURLOPT_PROXY, strbuf_detach(&proxyhost, NULL));
> +		curl_easy_setopt(result, CURLOPT_PROXY, curl_http_proxy);

And this too, which gets rid of my complaints about the previous patch.

-Peff

```
