All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] http: honnor empty http.proxy option to bypass proxy
@ 2017-04-10 15:15 Sergey Ryazanov
  2017-04-10 16:33 ` Jeff King
  0 siblings, 1 reply; 3+ messages in thread
From: Sergey Ryazanov @ 2017-04-10 15:15 UTC (permalink / raw)
  To: git

Curl distinguish between empty proxy address and NULL proxy address. In
the first case it completly disable proxy usage, but if proxy address
option is NULL then curl attempt to determine proxy address from
http_proxy environment variable.

According to documentation, if http.proxy configured to empty string
then git should bypass proxy and connects to the server directly:

    export http_proxy=http://network-proxy/
    cd ~/foobar-project
    git config remote.origin.proxy ""
    git fetch

Previously, proxy host was configured by one line:

    curl_easy_setopt(result, CURLOPT_PROXY, curl_http_proxy);

Commit 372370f (http: use credential API to handle proxy auth...) parses
proxy option, extracts proxy host address and additionaly updates curl
configuration:

    credential_from_url(&proxy_auth, curl_http_proxy);
    curl_easy_setopt(result, CURLOPT_PROXY, proxy_auth.host);

But if proxy option is empty then proxy host field become NULL this
force curl to fallback to proxy configuration detection from
environment. This caused empty http.proxy option not working any more.

Avoid setting NULL CURLOPT_PROXY from proxy_auth.host to fix this issue.

Signed-off-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>
---
 http.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/http.c b/http.c
index 96d84bb..bf0e709 100644
--- a/http.c
+++ b/http.c
@@ -861,7 +861,12 @@ static CURL *get_curl_handle(void)
 			strbuf_release(&url);
 		}
 
-		curl_easy_setopt(result, CURLOPT_PROXY, proxy_auth.host);
+		/*
+		 * Avoid setting CURLOPT_PROXY to NULL if empty http.proxy
+		 * option configured.
+		 */
+		if (proxy_auth.host)
+			curl_easy_setopt(result, CURLOPT_PROXY, proxy_auth.host);
 #if LIBCURL_VERSION_NUM >= 0x071304
 		var_override(&curl_no_proxy, getenv("NO_PROXY"));
 		var_override(&curl_no_proxy, getenv("no_proxy"));
-- 
2.10.2


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] http: honnor empty http.proxy option to bypass proxy
  2017-04-10 15:15 [PATCH] http: honnor empty http.proxy option to bypass proxy Sergey Ryazanov
@ 2017-04-10 16:33 ` Jeff King
  2017-04-11  8:24   ` Sergey Ryazanov
  0 siblings, 1 reply; 3+ messages in thread
From: Jeff King @ 2017-04-10 16:33 UTC (permalink / raw)
  To: Sergey Ryazanov; +Cc: git

On Mon, Apr 10, 2017 at 06:15:56PM +0300, Sergey Ryazanov wrote:

> Curl distinguish between empty proxy address and NULL proxy address. In
> the first case it completly disable proxy usage, but if proxy address
> option is NULL then curl attempt to determine proxy address from
> http_proxy environment variable.
> 
> According to documentation, if http.proxy configured to empty string
> then git should bypass proxy and connects to the server directly:
> 
>     export http_proxy=http://network-proxy/
>     cd ~/foobar-project
>     git config remote.origin.proxy ""
>     git fetch
> 
> Previously, proxy host was configured by one line:
> 
>     curl_easy_setopt(result, CURLOPT_PROXY, curl_http_proxy);
> 
> Commit 372370f (http: use credential API to handle proxy auth...) parses
> proxy option, extracts proxy host address and additionaly updates curl
> configuration:
> 
>     credential_from_url(&proxy_auth, curl_http_proxy);
>     curl_easy_setopt(result, CURLOPT_PROXY, proxy_auth.host);
> 
> But if proxy option is empty then proxy host field become NULL this
> force curl to fallback to proxy configuration detection from
> environment. This caused empty http.proxy option not working any more.

That makes sense. And if I understand correctly, this was a regression
in 372370f; before that we fed curl_http_proxy directly, and it was
either NULL or not, depending on whether we had seen the config option.

It looks like we _still_ set CURLOPT_PROXY to curl_http_proxy, and then
immediately afterward set it to proxy_auth.host. That should make the
first one always a noop, I would think, and it should be removed.

But...

> diff --git a/http.c b/http.c
> index 96d84bb..bf0e709 100644
> --- a/http.c
> +++ b/http.c
> @@ -861,7 +861,12 @@ static CURL *get_curl_handle(void)
>  			strbuf_release(&url);
>  		}
>  
> -		curl_easy_setopt(result, CURLOPT_PROXY, proxy_auth.host);
> +		/*
> +		 * Avoid setting CURLOPT_PROXY to NULL if empty http.proxy
> +		 * option configured.
> +		 */
> +		if (proxy_auth.host)
> +			curl_easy_setopt(result, CURLOPT_PROXY, proxy_auth.host);

Here that second one becomes conditional, and we rely on the earlier
setting (but only sometimes). I would think this whole thing would be
more clear if we dropped the first CURLOPT_PROXY call entirely, and just
did:

  /*
   * If we parsed a null host from the URL, we must convert that
   * back into an empty string so that curl knows we want no proxy at
   * all (not to find the default).
   */
  curl_easy_setopt(result, CURLOPT_PROXY, proxy_auth.host ?
                                          proxy_auth.host : "");

-Peff

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] http: honnor empty http.proxy option to bypass proxy
  2017-04-10 16:33 ` Jeff King
@ 2017-04-11  8:24   ` Sergey Ryazanov
  0 siblings, 0 replies; 3+ messages in thread
From: Sergey Ryazanov @ 2017-04-11  8:24 UTC (permalink / raw)
  To: Jeff King; +Cc: git

On Mon, Apr 10, 2017 at 7:33 PM, Jeff King <peff@peff.net> wrote:
> On Mon, Apr 10, 2017 at 06:15:56PM +0300, Sergey Ryazanov wrote:
>> Curl distinguish between empty proxy address and NULL proxy address. In
>> the first case it completly disable proxy usage, but if proxy address
>> option is NULL then curl attempt to determine proxy address from
>> http_proxy environment variable.
>>
>> According to documentation, if http.proxy configured to empty string
>> then git should bypass proxy and connects to the server directly:
>>
>>     export http_proxy=http://network-proxy/
>>     cd ~/foobar-project
>>     git config remote.origin.proxy ""
>>     git fetch
>>
>> Previously, proxy host was configured by one line:
>>
>>     curl_easy_setopt(result, CURLOPT_PROXY, curl_http_proxy);
>>
>> Commit 372370f (http: use credential API to handle proxy auth...) parses
>> proxy option, extracts proxy host address and additionaly updates curl
>> configuration:
>>
>>     credential_from_url(&proxy_auth, curl_http_proxy);
>>     curl_easy_setopt(result, CURLOPT_PROXY, proxy_auth.host);
>>
>> But if proxy option is empty then proxy host field become NULL this
>> force curl to fallback to proxy configuration detection from
>> environment. This caused empty http.proxy option not working any more.
>
> That makes sense. And if I understand correctly, this was a regression
> in 372370f;

Yep this regression introduced in 372370f

> before that we fed curl_http_proxy directly, and it was
> either NULL or not, depending on whether we had seen the config option.

To be more precisely, before the mentioned changeset was committed we
either set CURLOPT_PROXY option to some not NULL value (including
empty string) or do not touch it at all. There are additional test few
lines above the discussed code.

> It looks like we _still_ set CURLOPT_PROXY to curl_http_proxy, and then
> immediately afterward set it to proxy_auth.host. That should make the
> first one always a noop, I would think,

Yep, exactly.

> and it should be removed.
>
>
> But...
>
>> diff --git a/http.c b/http.c
>> index 96d84bb..bf0e709 100644
>> --- a/http.c
>> +++ b/http.c
>> @@ -861,7 +861,12 @@ static CURL *get_curl_handle(void)
>>                       strbuf_release(&url);
>>               }
>>
>> -             curl_easy_setopt(result, CURLOPT_PROXY, proxy_auth.host);
>> +             /*
>> +              * Avoid setting CURLOPT_PROXY to NULL if empty http.proxy
>> +              * option configured.
>> +              */
>> +             if (proxy_auth.host)
>> +                     curl_easy_setopt(result, CURLOPT_PROXY, proxy_auth.host);
>
> Here that second one becomes conditional, and we rely on the earlier
> setting (but only sometimes). I would think this whole thing would be
> more clear if we dropped the first CURLOPT_PROXY call entirely, and just
> did:
>
>   /*
>    * If we parsed a null host from the URL, we must convert that
>    * back into an empty string so that curl knows we want no proxy at
>    * all (not to find the default).
>    */
>   curl_easy_setopt(result, CURLOPT_PROXY, proxy_auth.host ?
>                                           proxy_auth.host : "");
>

Empty http.proxy option value is an edge case. Until we started parse
proxy value itself, all the complexity was reside inside curl library.
Since 372370f commit we should take some care about this case in our
code too. This could be a tiny hack inside common code to make patch
less invasive. Or we could explicitly handle this case to make code
clear and avoid such regressions in the future.

I will make V2 with second approach to see which one is better.

-- 
Sergey

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2017-04-11  8:24 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-04-10 15:15 [PATCH] http: honnor empty http.proxy option to bypass proxy Sergey Ryazanov
2017-04-10 16:33 ` Jeff King
2017-04-11  8:24   ` Sergey Ryazanov

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.