cURL / Mailing Lists / curl-library / Single Mail

curl-library

re: http proxy tunnel ... through a proxy

From: Prashant Ramanathan <prashant_at_netenrich.com>
Date: Wed, 21 Jun 2006 18:06:29 -0700

Hi Daniel, Yes, we go through two proxies and do two CONNECTs. The first
proxy is a normal proxy connection; the second is a proxy tunnel
connection. There are two new options that can be set by
curl_easy_setopt(): 1. CURLOPT_CONNECTTUNNEL (used to specify a proxy
tunnel connection, but can also be used in conjunction with
CURLOPT_PROXY, in case we need to go through another proxy server) 2.
CURLOPT_FORCE_REUSE (used so that the connection made to the proxy
tunnel stays open) There is one new option that is set by
curl_easy_getinfo(): 1. CURLINFO_CONNECTINDEX (used to reference the new
connection, so that we can directly access the socket connection) Below
are the diffs made on curl-7.15.4. prashant.

========================================================================
========================================================================

Index: getinfo.c
=================================================================== RCS
file: /cvs/netenrich/ra/curl-7.15.4/lib/getinfo.c,v retrieving revision
1.2 retrieving revision 1.1 diff -u -r1.2 -r1.1 --- getinfo.c 13 Jun
2006 21:28:03 -0000 1.2 +++ getinfo.c 13 Jun 2006 18:53:49 -0000 1.1 @@
-18,7 +18,7 @@ * This software is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY * KIND, either express or implied. * - * $Id:
getinfo.c,v 1.2 2006/06/13 21:28:03 ratna Exp $ + * $Id: getinfo.c,v 1.1
2006/06/13 18:53:49 ratna Exp $
***************************************************************************/
#include "setup.h" @@ -197,10 +197,6 @@ Callers must never free it
themselves. */ *param_charp = data->state.most_recent_ftp_entrypath;
break; - /* HTTP Tunneling - */ - case CURLINFO_CONNECTINDEX: -
*param_longp = data->info.connectindex; - break; case
CURLINFO_LASTSOCKET: if((data->state.lastconnect != -1) &&
(data->state.connects[data->state.lastconnect] != NULL)) {

========================================================================
========================================================================

Index: http.c
=================================================================== RCS
file: /cvs/netenrich/ra/curl-7.15.4/lib/http.c,v retrieving revision 1.2
retrieving revision 1.1 diff -u -r1.2 -r1.1 --- http.c 13 Jun 2006
21:28:03 -0000 1.2 +++ http.c 13 Jun 2006 18:53:49 -0000 1.1 @@ -18,7
+18,7 @@ * This software is distributed on an "AS IS" basis, WITHOUT
WARRANTY OF ANY * KIND, either express or implied. * - * $Id: http.c,v
1.2 2006/06/13 21:28:03 ratna Exp $ + * $Id: http.c,v 1.1 2006/06/13
18:53:49 ratna Exp $
***************************************************************************/
#include "setup.h" @@ -1616,9 +1616,6 @@ /* Now set the 'request'
pointer to the proper request string */ if(data->set.customrequest)
request = data->set.customrequest; - /* HTTP Tunneling - */ - else
if(data->set.tunneldest) - request = (char *)"CONNECT"; else {
if(conn->bits.no_body) request = (char *)"HEAD"; @@ -1941,46 +1938,6 @@
return CURLE_OUT_OF_MEMORY; /* add the main request stuff */ - /* HTTP
Tunneling - */ - if (data->set.tunneldest) { - result = -
add_bufferf(req_buffer, - "%s " /* CONNECT */ - "%s HTTP/%s\r\n" /*
tunnel destination + HTTP version */ - "%s" /* proxyuserpwd */ - "%s" /*
userpwd */ - "%s" /* range */ - "%s" /* user agent */ - "%s" /* host */
- "%s" /* pragma */ - "%s" /* accept */ - "%s" /* accept-encoding */ -
"%s" /* referer */ - "%s" /* Proxy-Connection */ - "%s",/*
transfer-encoding */ - - request, - data->set.tunneldest, - httpstring,
- conn->allocptr.proxyuserpwd? - conn->allocptr.proxyuserpwd:"", -
conn->allocptr.userpwd?conn->allocptr.userpwd:"", -
(conn->bits.use_range && conn->allocptr.rangeline)? -
conn->allocptr.rangeline:"", - (data->set.useragent &&
*data->set.useragent && conn->allocptr.uagent)? -
conn->allocptr.uagent:"", -
(conn->allocptr.host?conn->allocptr.host:""), /* Host: host */ -
http->p_pragma?http->p_pragma:"", - http->p_accept?http->p_accept:"", -
(data->set.encoding && *data->set.encoding &&
conn->allocptr.accept_encoding)? - conn->allocptr.accept_encoding:"", -
(data->change.referer && conn->allocptr.ref)?conn->allocptr.ref:"" /*
Referer: <data> */, - (conn->bits.httpproxy &&
!conn->bits.tunnel_proxy)? - "Proxy-Connection: Keep-Alive\r\n":"", - te
- ); - } - else { result = add_bufferf(req_buffer, "%s " /*
GET/HEAD/POST/PUT */ @@ -2017,7 +1974,7 @@ "Proxy-Connection:
Keep-Alive\r\n":"", te ); - } + if(result) return result;

========================================================================
========================================================================

Index: transfer.c
=================================================================== RCS
file: /cvs/netenrich/ra/curl-7.15.4/lib/transfer.c,v retrieving revision
1.2 retrieving revision 1.1 diff -u -r1.2 -r1.1 --- transfer.c 13 Jun
2006 21:28:03 -0000 1.2 +++ transfer.c 13 Jun 2006 18:53:49 -0000 1.1 @@
-18,7 +18,7 @@ * This software is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY * KIND, either express or implied. * - * $Id:
transfer.c,v 1.2 2006/06/13 21:28:03 ratna Exp $ + * $Id: transfer.c,v
1.1 2006/06/13 18:53:49 ratna Exp $
***************************************************************************/
#include "setup.h" @@ -2196,9 +2196,7 @@ do { res =
Curl_connect_host(data, &conn); /* primary connection */ - /* HTTP
Tunneling - Remember the current connectindex */ - if(res == CURLE_OK) -
data->info.connectindex = conn->connectindex; + if(res == CURLE_OK) { if
(data->set.source_url) /* 3rd party transfer */ res =
Curl_second_connect(conn);

========================================================================
========================================================================

Index: url.c
=================================================================== RCS
file: /cvs/netenrich/ra/curl-7.15.4/lib/url.c,v retrieving revision 1.2
retrieving revision 1.1 diff -u -r1.2 -r1.1 --- url.c 13 Jun 2006
21:28:03 -0000 1.2 +++ url.c 13 Jun 2006 18:53:49 -0000 1.1 @@ -18,7
+18,7 @@ * This software is distributed on an "AS IS" basis, WITHOUT
WARRANTY OF ANY * KIND, either express or implied. * - * $Id: url.c,v
1.2 2006/06/13 21:28:03 ratna Exp $ + * $Id: url.c,v 1.1 2006/06/13
18:53:49 ratna Exp $
***************************************************************************/
/* -- WIN32 approved -- */ @@ -498,14 +498,6 @@ */
data->set.reuse_forbid = va_arg(param, long)?TRUE:FALSE; break; - /*
HTTP Tunneling - */ - case CURLOPT_FORCE_REUSE: - /* - * When this
transfer is done, the connection is forced to remain open - *
(especially useful for HTTP CONNECT proxy tunnels) - */ -
data->set.reuse_force = va_arg(param, long)?TRUE:FALSE; - break; case
CURLOPT_FRESH_CONNECT: /* * This transfer shall not use a previously
cached connection but @@ -906,18 +898,6 @@ here, we continue as if we
were using the already set type and this just changes the actual request
keyword */ break; - /* HTTP Tunneling - */ - case CURLOPT_CONNECTTUNNEL:
- /* - * Specifies a tcp tunnel using the CONNECT command. Sets the - *
ipaddr:portnumber to tunnel to. - */ - data->set.tunneldest =
va_arg(param, char *); - /* we don't set - data->set.httpreq =
HTTPREQ_CONNECTTUNNEL; - here, we continue as if we were using the
already set type - and this just changes the actual request keyword */ -
break; case CURLOPT_PROXYPORT: /* @@ -4088,8 +4068,7 @@ if
conn->bits.close is TRUE, it means that the connection should be closed
in spite of all our efforts to be nice, due to protocol restrictions in
our or the server's end */ - /* HTTP Tunneling - */ - if((
data->set.reuse_forbid || conn->bits.close ) &&
(!(data->set.reuse_force))) { + if(data->set.reuse_forbid ||
conn->bits.close) { CURLcode res2; res2 = Curl_disconnect(conn); /*
close the connection */

========================================================================
========================================================================

Index: urldata.h
=================================================================== RCS
file: /cvs/netenrich/ra/curl-7.15.4/lib/urldata.h,v retrieving revision
1.2 retrieving revision 1.1 diff -u -r1.2 -r1.1 --- urldata.h 13 Jun
2006 21:28:03 -0000 1.2 +++ urldata.h 13 Jun 2006 18:53:49 -0000 1.1 @@
-20,7 +20,7 @@ * This software is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY * KIND, either express or implied. * - * $Id:
urldata.h,v 1.2 2006/06/13 21:28:03 ratna Exp $ + * $Id: urldata.h,v 1.1
2006/06/13 18:53:49 ratna Exp $
***************************************************************************/
/* This file is for lib internal stuff */ @@ -793,8 +793,6 @@ long
numconnects; /* how many new connection did libcurl created */ char
*contenttype; /* the content type of the object */ - /* HTTP Tunneling -
*/ - long connectindex; /* the connectindex of the most recent
connection */ }; @@ -1068,8 +1066,6 @@ curl_closepolicy closepolicy; /*
connection cache close concept */ Curl_HttpReq httpreq; /* what kind of
HTTP request (if any) is this */ char *customrequest; /* HTTP/FTP
request to use */ - /* HTTP Tunneling - */ - char *tunneldest; /*
destination ipaddr:port for tunnel, if using HTTP CONNECT tunneling */
long httpversion; /* when non-zero, a specific HTTP version requested to
be used in the library's request(s) */ char *auth_host; /* if set, this
is the allocated string to the host name @@ -1132,8 +1128,6 @@ bool
verbose; bool krb4; /* kerberos4 connection requested */ bool
reuse_forbid; /* forbidden to be reused, close after use */ - /* HTTP
Tunneling - */ - bool reuse_force; /* force to keep connection alive */
bool reuse_fresh; /* do not re-use an existing connection */ bool
expect100header; /* TRUE if we added Expect: 100-continue */ bool
ftp_use_epsv; /* if EPSV is to be attempted or not */

========================================================================
========================================================================

Index: curl.h
=================================================================== RCS
file: /cvs/netenrich/ra/curl-7.15.4/include/curl/curl.h,v retrieving
revision 1.2 retrieving revision 1.1 diff -u -r1.2 -r1.1 --- curl.h 13
Jun 2006 21:28:03 -0000 1.2 +++ curl.h 13 Jun 2006 18:53:48 -0000 1.1 @@
-20,7 +20,7 @@ * This software is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY * KIND, either express or implied. * - * $Id:
curl.h,v 1.2 2006/06/13 21:28:03 ratna Exp $ + * $Id: curl.h,v 1.1
2006/06/13 18:53:48 ratna Exp $
***************************************************************************/
/* If you have problems, all libcurl docs and details are found here: @@
-963,18 +963,6 @@ Note that this is used only for SSL certificate
processing */ CINIT(CONV_FROM_UTF8_FUNCTION, FUNCTIONPOINT, 144), - /*
Set to explicitly force the upcoming transfer's connection to be kept
open - when done. Useful for HTTP CONNECT proxy tunnel connections - */
- CINIT(FORCE_REUSE, LONG, 142), - - /* Set to specify an http tunnel
connection. The specified string contains the - ip address and port (ie.
"127.0.0.1:9900"). If NULL, then this method is not - used. The result
http message, for example, contains the header - "CONNECT 127.0.0.1:9900
HTTP/1.1" - */ - CINIT(CONNECTTUNNEL, OBJECTPOINT, 143), -
CURLOPT_LASTENTRY /* the last unused */ } CURLoption; @@ -1347,11
+1335,9 @@ CURLINFO_COOKIELIST = CURLINFO_SLIST + 28,
CURLINFO_LASTSOCKET = CURLINFO_LONG + 29, CURLINFO_FTP_ENTRY_PATH =
CURLINFO_STRING + 30, - CURLINFO_CONNECTINDEX = CURLINFO_LONG + 31, - /*
Fill in new entries below here! */ - CURLINFO_LASTONE = 31 +
CURLINFO_LASTONE = 30 } CURLINFO; /* CURLINFO_RESPONSE_CODE is the new
name for the option previously known as

========================================================================
========================================================================

========

>> We use libcurl for (among other things) making http proxy tunnel
>> connections. However, currently with libcurl, we can't do this if there is
>> another proxy server that you first have to go through (something that we
>> needed to do). We've implemented some functionality that allows a proxy
>> tunnel connection, first going through another proxy server. We would like
>> to contribute this code to the libcurl project. If this is something that
>> is useful to the community at large, please let me know, as well as how I
>> can go about uploading my changes.
>
>

Wow, this sounds like fun. So you're going through *two* proxies on your way
to the target server?! And is this then doing two CONNECT requests?

Please make a diff -u output of your changes (preferably against a very recent
curl version) and post to the list!
Received on 2006-06-22