cURL / Mailing Lists / curl-library / Single Mail

curl-library

http proxy tunnel, connect-only and authentication

From: Giancarlo Formicuccia <giancarlo.formicuccia_at_gmail.com>
Date: Tue, 10 Jul 2007 16:20:42 +0000

Hi *,

I'm using libcurl to connect to an external server through a squid proxy. I
use libcurl only for opening the connection and performing the proxy
authentication; all the traffic is handled externally. My curl version is
7.16.2 from Debian unstable.

The connection setup is the following:

CURL *c = curl_easy_init();
curl_easy_setopt(c, CURLOPT_URL, url);
curl_easy_setopt(c, CURLOPT_PROXY, proxy);
curl_easy_setopt(c, CURLOPT_PROXYUSERPWD, userpass);
curl_easy_setopt(c, CURLOPT_HTTPPROXYTUNNEL, 1);
curl_easy_setopt(c, CURLOPT_CONNECT_ONLY, 1);
curl_easy_setopt(c, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
curl_easy_perform(c);
curl_easy_getinfo(c, CURLINFO_LASTSOCKET, &sock);

The connection works if the proxy does not require authentication; if I set up
a basic auth the connection fails. The log explains somehow what happens:

* About to connect() to proxy 192.168.1.202 port 3128 (#0)
* Trying 192.168.1.202... * connected
* Connected to 192.168.1.202 (192.168.1.202) port 3128 (#0)
* Establish HTTP proxy tunnel to 83.103.123.110:80
> CONNECT 83.103.123.110:80 HTTP/1.0
Host: 83.103.123.110:80
Proxy-Connection: Keep-Alive

< HTTP/1.0 407 Proxy Authentication Required
< Server: squid/2.6.STABLE5
< Date: Tue, 10 Jul 2007 13:28:44 GMT
< Content-Type: text/html
< Content-Length: 1269
< Expires: Tue, 10 Jul 2007 13:28:44 GMT
< X-Squid-Error: ERR_CACHE_ACCESS_DENIED 0
< Proxy-Authenticate: Basic realm="Squid proxy-caching web server"
< X-Cache: MISS from tmmc
< X-Cache-Lookup: NONE from tmmc:3128
< Via: 1.0 tmmc:3128 (squid/2.6.STABLE5)
< Proxy-Connection: close
<
* Ignore 1269 bytes of response-body
* Establish HTTP proxy tunnel to 83.103.123.110:80
* Proxy auth using Basic with user 'giancarlo'
> CONNECT 83.103.123.110:80 HTTP/1.0
Host: 83.103.123.110:80
Proxy-Authorization: Basic Z2lhbmNhcmxvOnRydXN0bm8x
Proxy-Connection: Keep-Alive

* Proxy CONNECT aborted
* Closing connection #0
* failure when receiving data from the peer

As you can see, squid replies with "Proxy-Connection: close". libcurl seems to
use the same socket again for the 2nd (authenticated) request, but it fails
(squid probably shut down the connection).
If I set explicitly
curl_easy_setopt(c, CURLOPT_PROXYAUTH, CURLAUTH_BASIC);
then the auth succeeds:

 About to connect() to proxy 192.168.1.202 port 3128 (#0)
* Trying 192.168.1.202... * connected
* Connected to 192.168.1.202 (192.168.1.202) port 3128 (#0)
* Establish HTTP proxy tunnel to 83.103.123.110:80
* Proxy auth using Basic with user 'giancarlo'
> CONNECT 83.103.123.110:80 HTTP/1.0
Host: 83.103.123.110:80
Proxy-Authorization: Basic Z2lhbmNhcmxvOnRydXN0bm8x
Proxy-Connection: Keep-Alive

< HTTP/1.0 200 Connection established
<
* Proxy replied OK to CONNECT request
* Connection #0 to host 192.168.1.202 left intact

In order to make CURLAUTH_ANY usable with my setup, I tried the following
patch to http.c:

--- curl-7.16.2.orig/lib/http.c 2007-04-11 13:10:22.000000000 +0000
+++ curl-7.16.2/lib/http.c 2007-07-10 15:08:08.000000000 +0000
@@ -1398,6 +1398,9 @@ CURLcode Curl_proxyCONNECT(struct connec
                   else if(Curl_compareheader(line_start,
                                              "Connection:", "close"))
                     closeConnection = TRUE;
+ else if(Curl_compareheader(line_start,
+ "Proxy-Connection:", "close"))
+ closeConnection = TRUE;
                   else if(2 == sscanf(line_start, "HTTP/1.%d %d",
                                       &subversion,
                                       &k->httpcode)) {

Now the behaviour seems correct:

* About to connect() to proxy 192.168.1.202 port 3128 (#0)
* Trying 192.168.1.202... * connected
* Connected to 192.168.1.202 (192.168.1.202) port 3128 (#0)
* Establish HTTP proxy tunnel to 83.103.123.110:80
> CONNECT 83.103.123.110:80 HTTP/1.0
Host: 83.103.123.110:80
Proxy-Connection: Keep-Alive

< HTTP/1.0 407 Proxy Authentication Required
[snip]
< Proxy-Connection: close
<
* Ignore 1269 bytes of response-body
* Received HTTP code 407 from proxy after CONNECT
* About to connect() to proxy 192.168.1.202 port 3128 (#0)
* Trying 192.168.1.202... * connected
* Connected to 192.168.1.202 (192.168.1.202) port 3128 (#0)
* Establish HTTP proxy tunnel to 83.103.123.110:80
* Proxy auth using Basic with user 'giancarlo'
> CONNECT 83.103.123.110:80 HTTP/1.0
Host: 83.103.123.110:80
Proxy-Authorization: Basic Z2lhbmNhcmxvOnRydXN0bm8x
Proxy-Connection: Keep-Alive

< HTTP/1.0 200 Connection established
<
* Proxy replied OK to CONNECT request
* Connection #0 to host 192.168.1.202 left intact

but I'm not expert about the proxy protocol, so don't know if this solution is
correct and without side effects.

Any ideas?

Thanks,
Giancarlo
Received on 2007-07-10