- Robert Foreman provided a prime example snippet showing how libcurl would

get confused and not acknowledge the 'no_proxy' variable properly once it
  had used the proxy and you re-used the same easy handle. I made sure the
  proxy name is properly stored in the connect struct rather than the
  sessionhandle/easy struct.
This commit is contained in:
Daniel Stenberg 2006-12-22 15:04:59 +00:00
parent 61a6992559
commit bedc61ac45
6 changed files with 31 additions and 48 deletions

View File

@ -7,6 +7,12 @@
Changelog Changelog
Daniel (22 December 2006) Daniel (22 December 2006)
- Robert Foreman provided a prime example snippet showing how libcurl would
get confused and not acknowledge the 'no_proxy' variable properly once it
had used the proxy and you re-used the same easy handle. I made sure the
proxy name is properly stored in the connect struct rather than the
sessionhandle/easy struct.
- David McCreedy fixed a bad call to getsockname() that wrongly used a size_t - David McCreedy fixed a bad call to getsockname() that wrongly used a size_t
variable to point to when it should be a socklen_t. variable to point to when it should be a socklen_t.

View File

@ -57,6 +57,6 @@ advice from friends like these:
Ciprian Badescu, Dmitriy Sergeyev, Nir Soffer, Venkat Akella, Toon Verwaest, Ciprian Badescu, Dmitriy Sergeyev, Nir Soffer, Venkat Akella, Toon Verwaest,
Matt Witherspoon, Alexey Simak, Martin Skinner, Sh Diao, Jared Lundell, Matt Witherspoon, Alexey Simak, Martin Skinner, Sh Diao, Jared Lundell,
Stefan Krause, Sebastien Willemijns, Alexey Simak, Brendan Jurd, Stefan Krause, Sebastien Willemijns, Alexey Simak, Brendan Jurd,
Robson Braga Araujo Robson Braga Araujo, David McCreedy, Robert Foreman
Thanks! (and sorry if I forgot to mention someone) Thanks! (and sorry if I forgot to mention someone)

View File

@ -593,12 +593,7 @@ CURL *curl_easy_duphandle(CURL *incurl)
break; break;
outcurl->change.url_alloc = TRUE; outcurl->change.url_alloc = TRUE;
} }
if(data->change.proxy) {
outcurl->change.proxy = strdup(data->change.proxy);
if(!outcurl->change.proxy)
break;
outcurl->change.proxy_alloc = TRUE;
}
if(data->change.referer) { if(data->change.referer) {
outcurl->change.referer = strdup(data->change.referer); outcurl->change.referer = strdup(data->change.referer);
if(!outcurl->change.referer) if(!outcurl->change.referer)
@ -633,8 +628,6 @@ CURL *curl_easy_duphandle(CURL *incurl)
Curl_rm_connc(outcurl->state.connc); Curl_rm_connc(outcurl->state.connc);
if(outcurl->state.headerbuff) if(outcurl->state.headerbuff)
free(outcurl->state.headerbuff); free(outcurl->state.headerbuff);
if(outcurl->change.proxy)
free(outcurl->change.proxy);
if(outcurl->change.url) if(outcurl->change.url)
free(outcurl->change.url); free(outcurl->change.url);
if(outcurl->change.referer) if(outcurl->change.referer)

View File

@ -1668,7 +1668,7 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
return CURLE_FTP_WEIRD_PASV_REPLY; return CURLE_FTP_WEIRD_PASV_REPLY;
} }
if(data->change.proxy && *data->change.proxy) { if(data->set.proxy && *data->set.proxy) {
/* /*
* This is a tunnel through a http proxy and we need to connect to the * This is a tunnel through a http proxy and we need to connect to the
* proxy again here. * proxy again here.

View File

@ -310,9 +310,6 @@ CURLcode Curl_close(struct SessionHandle *data)
Curl_safefree(data->state.first_host); Curl_safefree(data->state.first_host);
Curl_safefree(data->state.scratch); Curl_safefree(data->state.scratch);
if(data->change.proxy_alloc)
free(data->change.proxy);
if(data->change.referer_alloc) if(data->change.referer_alloc)
free(data->change.referer); free(data->change.referer);
@ -1105,15 +1102,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
* Setting it to NULL, means no proxy but allows the environment variables * Setting it to NULL, means no proxy but allows the environment variables
* to decide for us. * to decide for us.
*/ */
if(data->change.proxy_alloc) { data->set.proxy = va_arg(param, char *);
/*
* The already set string is allocated, free that first
*/
data->change.proxy_alloc = FALSE;
free(data->change.proxy);
}
data->set.set_proxy = va_arg(param, char *);
data->change.proxy = data->set.set_proxy;
break; break;
case CURLOPT_WRITEHEADER: case CURLOPT_WRITEHEADER:
@ -1915,7 +1904,7 @@ int Curl_removeHandleFromPipeline(struct SessionHandle *handle,
return 0; return 0;
} }
#if 0 #if 0 /* this code is saved here as it is useful for debugging purposes */
static void Curl_printPipeline(struct curl_llist *pipe) static void Curl_printPipeline(struct curl_llist *pipe)
{ {
struct curl_llist_element *curr; struct curl_llist_element *curr;
@ -2082,7 +2071,6 @@ ConnectionExists(struct SessionHandle *data,
} }
if(match) { if(match) {
#if 1
if (!IsPipeliningEnabled(data)) { if (!IsPipeliningEnabled(data)) {
/* The check for a dead socket makes sense only in the /* The check for a dead socket makes sense only in the
non-pipelining case */ non-pipelining case */
@ -2097,7 +2085,6 @@ ConnectionExists(struct SessionHandle *data,
return FALSE; return FALSE;
} }
} }
#endif
check->inuse = TRUE; /* mark this as being in use so that no other check->inuse = TRUE; /* mark this as being in use so that no other
handle in a multi stack may nick it */ handle in a multi stack may nick it */
@ -2230,10 +2217,10 @@ static CURLcode ConnectPlease(struct SessionHandle *data,
{ {
CURLcode result; CURLcode result;
Curl_addrinfo *addr; Curl_addrinfo *addr;
char *hostname = data->change.proxy?conn->proxy.name:conn->host.name; char *hostname = conn->bits.httpproxy?conn->proxy.name:conn->host.name;
infof(data, "About to connect() to %s%s port %d (#%d)\n", infof(data, "About to connect() to %s%s port %d (#%d)\n",
data->change.proxy?"proxy ":"", conn->bits.httpproxy?"proxy ":"",
hostname, conn->port, conn->connectindex); hostname, conn->port, conn->connectindex);
/************************************************************* /*************************************************************
@ -2706,6 +2693,8 @@ static CURLcode CreateConnection(struct SessionHandle *data,
char passwd[MAX_CURL_PASSWORD_LENGTH]; char passwd[MAX_CURL_PASSWORD_LENGTH];
int rc; int rc;
bool reuse; bool reuse;
char *proxy;
bool proxy_alloc = FALSE;
#ifndef USE_ARES #ifndef USE_ARES
#ifdef SIGALRM #ifdef SIGALRM
@ -2754,9 +2743,10 @@ static CURLcode CreateConnection(struct SessionHandle *data,
conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */ conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */
conn->connectindex = -1; /* no index */ conn->connectindex = -1; /* no index */
conn->bits.httpproxy = (bool)(data->change.proxy /* http proxy or not */ conn->bits.httpproxy = (bool)(data->set.proxy /* http proxy or not */
&& *data->change.proxy && *data->set.proxy
&& (data->set.proxytype == CURLPROXY_HTTP)); && (data->set.proxytype == CURLPROXY_HTTP));
proxy = data->set.proxy; /* if global proxy is set, this is it */
/* Default protocol-independent behavior doesn't support persistent /* Default protocol-independent behavior doesn't support persistent
connections, so we set this to force-close. Protocols that support connections, so we set this to force-close. Protocols that support
@ -2856,7 +2846,7 @@ static CURLcode CreateConnection(struct SessionHandle *data,
/************************************************************* /*************************************************************
* Detect what (if any) proxy to use * Detect what (if any) proxy to use
*************************************************************/ *************************************************************/
if(!data->change.proxy) { if(!conn->bits.httpproxy) {
/* If proxy was not specified, we check for default proxy environment /* If proxy was not specified, we check for default proxy environment
* variables, to enable i.e Lynx compliance: * variables, to enable i.e Lynx compliance:
* *
@ -2876,7 +2866,6 @@ static CURLcode CreateConnection(struct SessionHandle *data,
*/ */
char *no_proxy=NULL; char *no_proxy=NULL;
char *no_proxy_tok_buf; char *no_proxy_tok_buf;
char *proxy=NULL;
char proxy_env[128]; char proxy_env[128];
no_proxy=curl_getenv("no_proxy"); no_proxy=curl_getenv("no_proxy");
@ -2952,12 +2941,11 @@ static CURLcode CreateConnection(struct SessionHandle *data,
if(proxy && *proxy) { if(proxy && *proxy) {
long bits = conn->protocol & (PROT_HTTPS|PROT_SSL|PROT_MISSING); long bits = conn->protocol & (PROT_HTTPS|PROT_SSL|PROT_MISSING);
data->change.proxy = proxy;
data->change.proxy_alloc=TRUE; /* this needs to be freed later */
conn->bits.httpproxy = TRUE;
/* force this to become HTTP */ /* force this to become HTTP */
conn->protocol = PROT_HTTP | bits; conn->protocol = PROT_HTTP | bits;
proxy_alloc=TRUE; /* this needs to be freed later */
conn->bits.httpproxy = TRUE;
} }
} /* if (!nope) - it wasn't specified non-proxy */ } /* if (!nope) - it wasn't specified non-proxy */
} /* NO_PROXY wasn't specified or '*' */ } /* NO_PROXY wasn't specified or '*' */
@ -3070,9 +3058,7 @@ static CURLcode CreateConnection(struct SessionHandle *data,
conn->remote_port = (unsigned short)port; conn->remote_port = (unsigned short)port;
conn->protocol |= PROT_FTP; conn->protocol |= PROT_FTP;
if(data->change.proxy && if(proxy && *proxy && !data->set.tunnel_thru_httpproxy) {
*data->change.proxy &&
!data->set.tunnel_thru_httpproxy) {
/* Unless we have asked to tunnel ftp operations through the proxy, we /* Unless we have asked to tunnel ftp operations through the proxy, we
switch and use HTTP operations only */ switch and use HTTP operations only */
#ifndef CURL_DISABLE_HTTP #ifndef CURL_DISABLE_HTTP
@ -3270,7 +3256,7 @@ else {
return CURLE_UNSUPPORTED_PROTOCOL; return CURLE_UNSUPPORTED_PROTOCOL;
} }
if(data->change.proxy && *data->change.proxy) { if(proxy && *proxy) {
/* If this is supposed to use a proxy, we need to figure out the proxy /* If this is supposed to use a proxy, we need to figure out the proxy
host name name, so that we can re-use an existing connection host name name, so that we can re-use an existing connection
that may exist registered to the same proxy host. */ that may exist registered to the same proxy host. */
@ -3279,8 +3265,9 @@ else {
char *endofprot; char *endofprot;
/* We need to make a duplicate of the proxy so that we can modify the /* We need to make a duplicate of the proxy so that we can modify the
string safely. */ string safely. If 'proxy_alloc' is TRUE, the string is already
char *proxydup=strdup(data->change.proxy); allocated and we can treat it as duplicated. */
char *proxydup=proxy_alloc?proxy:strdup(proxy);
/* We use 'proxyptr' to point to the proxy name from now on... */ /* We use 'proxyptr' to point to the proxy name from now on... */
char *proxyptr=proxydup; char *proxyptr=proxydup;
@ -3840,7 +3827,7 @@ else {
/* set a pointer to the hostname we display */ /* set a pointer to the hostname we display */
fix_hostname(data, conn, &conn->host); fix_hostname(data, conn, &conn->host);
if(!data->change.proxy || !*data->change.proxy) { if(!proxy || !*proxy) {
/* If not connecting via a proxy, extract the port from the URL, if it is /* If not connecting via a proxy, extract the port from the URL, if it is
* there, thus overriding any defaults that might have been set above. */ * there, thus overriding any defaults that might have been set above. */
conn->port = conn->remote_port; /* it is the same port */ conn->port = conn->remote_port; /* it is the same port */
@ -3953,8 +3940,7 @@ static CURLcode SetupConnection(struct connectdata *conn,
* Send user-agent to HTTP proxies even if the target protocol * Send user-agent to HTTP proxies even if the target protocol
* isn't HTTP. * isn't HTTP.
*************************************************************/ *************************************************************/
if((conn->protocol&PROT_HTTP) || if((conn->protocol&PROT_HTTP) || conn->bits.httpproxy) {
(data->change.proxy && *data->change.proxy)) {
if(data->set.useragent) { if(data->set.useragent) {
Curl_safefree(conn->allocptr.uagent); Curl_safefree(conn->allocptr.uagent);
conn->allocptr.uagent = conn->allocptr.uagent =

View File

@ -1102,8 +1102,6 @@ struct DynamicStatic {
changed after the connect phase, as we allow callback changed after the connect phase, as we allow callback
to change it and if so, we reconnect to use the new to change it and if so, we reconnect to use the new
URL instead */ URL instead */
char *proxy; /* work proxy, copied from UserDefined */
bool proxy_alloc; /* http proxy string is malloc()'ed */
char *referer; /* referer string */ char *referer; /* referer string */
bool referer_alloc; /* referer sting is malloc()ed */ bool referer_alloc; /* referer sting is malloc()ed */
struct curl_slist *cookielist; /* list of cookie files set by struct curl_slist *cookielist; /* list of cookie files set by
@ -1132,7 +1130,7 @@ struct UserDefined {
void *in; /* the uploaded file is read from here */ void *in; /* the uploaded file is read from here */
void *writeheader; /* write the header to this if non-NULL */ void *writeheader; /* write the header to this if non-NULL */
char *set_url; /* what original URL to work on */ char *set_url; /* what original URL to work on */
char *set_proxy; /* proxy to use */ char *proxy; /* proxy to use */
long use_port; /* which port to use (when not using default) */ long use_port; /* which port to use (when not using default) */
char *userpwd; /* <user:password>, if used */ char *userpwd; /* <user:password>, if used */
long httpauth; /* what kind of HTTP authentication to use (bitmask) */ long httpauth; /* what kind of HTTP authentication to use (bitmask) */