Follow-up fix for the proxy fix I did for Jon Nelson's bug. It turned out I
was a bit too quick and broke test case 1101 with that change. The order of some of the setups is sensitive. I now changed it slightly again.
This commit is contained in:
Родитель
002ed5f298
Коммит
7603a29fc3
15
CHANGES
15
CHANGES
|
@ -6,6 +6,21 @@
|
||||||
|
|
||||||
Changelog
|
Changelog
|
||||||
|
|
||||||
|
Daniel Stenberg (17 Dec 2009)
|
||||||
|
- Follow-up fix for the proxy fix I did for Jon Nelson's bug. It turned out I
|
||||||
|
was a bit too quick and broke test case 1101 with that change. The order of
|
||||||
|
some of the setups is sensitive. I now changed it slightly again to make
|
||||||
|
sure we do them in this order:
|
||||||
|
|
||||||
|
1 - parse URL and figure out what protocol is used in the URL
|
||||||
|
2 - prepend protocol:// to URL if missing
|
||||||
|
3 - parse name+password off URL, which needs to know what protocol is used
|
||||||
|
(since only some allows for name+password in the URL)
|
||||||
|
4 - figure out if a proxy should be used set by an option
|
||||||
|
5 - if no proxy option, check proxy environment variables
|
||||||
|
6 - run the protocol-specific setup function, which needs to have the proxy
|
||||||
|
already set
|
||||||
|
|
||||||
Daniel Stenberg (15 Dec 2009)
|
Daniel Stenberg (15 Dec 2009)
|
||||||
- Jon Nelson found a regression that turned out to be a flaw in how libcurl
|
- Jon Nelson found a regression that turned out to be a flaw in how libcurl
|
||||||
detects and uses proxies based on the environment variables. If the proxy
|
detects and uses proxies based on the environment variables. If the proxy
|
||||||
|
|
139
lib/url.c
139
lib/url.c
|
@ -3255,11 +3255,53 @@ static struct connectdata *allocate_conn(void)
|
||||||
return conn;
|
return conn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static CURLcode findprotocol(struct SessionHandle *data,
|
||||||
|
struct connectdata *conn)
|
||||||
|
{
|
||||||
|
const struct Curl_handler * const *pp;
|
||||||
|
const struct Curl_handler *p;
|
||||||
|
|
||||||
|
/* Scan protocol handler table and match against 'protostr' to set a few
|
||||||
|
variables based on the URL. Now that the handler may be changed later
|
||||||
|
when the protocol specific setup function is called. */
|
||||||
|
for (pp = protocols; (p = *pp) != NULL; pp++) {
|
||||||
|
if(Curl_raw_equal(p->scheme, conn->protostr)) {
|
||||||
|
/* Protocol found in table. Check if allowed */
|
||||||
|
if(!(data->set.allowed_protocols & p->protocol))
|
||||||
|
/* nope, get out */
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* it is allowed for "normal" request, now do an extra check if this is
|
||||||
|
the result of a redirect */
|
||||||
|
if(data->state.this_is_a_follow &&
|
||||||
|
!(data->set.redir_protocols & p->protocol))
|
||||||
|
/* nope, get out */
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Perform setup complement if some. */
|
||||||
|
conn->handler = p;
|
||||||
|
conn->protocol |= p->protocol;
|
||||||
|
|
||||||
|
/* 'port' and 'remote_port' are set in setup_connection_internals() */
|
||||||
|
return CURLE_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* The protocol was not found in the table, but we don't have to assign it
|
||||||
|
to anything since it is already assigned to a dummy-struct in the
|
||||||
|
create_conn() function when the connectdata struct is allocated. */
|
||||||
|
failf(data, "Protocol %s not supported or disabled in " LIBCURL_NAME,
|
||||||
|
conn->protostr);
|
||||||
|
|
||||||
|
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse URL and fill in the relevant members of the connection struct.
|
* Parse URL and fill in the relevant members of the connection struct.
|
||||||
*/
|
*/
|
||||||
static CURLcode ParseURLAndFillConnection(struct SessionHandle *data,
|
static CURLcode parseurlandfillconn(struct SessionHandle *data,
|
||||||
struct connectdata *conn)
|
struct connectdata *conn)
|
||||||
{
|
{
|
||||||
char *at;
|
char *at;
|
||||||
char *tmp;
|
char *tmp;
|
||||||
|
@ -3455,8 +3497,8 @@ static CURLcode ParseURLAndFillConnection(struct SessionHandle *data,
|
||||||
* conn->host.name is B
|
* conn->host.name is B
|
||||||
* data->state.path is /C
|
* data->state.path is /C
|
||||||
*/
|
*/
|
||||||
(void)rc;
|
|
||||||
return CURLE_OK;
|
return findprotocol(data, conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void llist_dtor(void *user, void *element)
|
static void llist_dtor(void *user, void *element)
|
||||||
|
@ -3502,10 +3544,8 @@ static CURLcode setup_range(struct SessionHandle *data)
|
||||||
* Setup connection internals specific to the requested protocol.
|
* Setup connection internals specific to the requested protocol.
|
||||||
* This MUST get called after proxy magic has been figured out.
|
* This MUST get called after proxy magic has been figured out.
|
||||||
***************************************************************/
|
***************************************************************/
|
||||||
static CURLcode setup_connection_internals(struct SessionHandle *data,
|
static CURLcode setup_connection_internals(struct connectdata *conn)
|
||||||
struct connectdata *conn)
|
|
||||||
{
|
{
|
||||||
const struct Curl_handler * const * pp;
|
|
||||||
const struct Curl_handler * p;
|
const struct Curl_handler * p;
|
||||||
CURLcode result;
|
CURLcode result;
|
||||||
|
|
||||||
|
@ -3513,47 +3553,26 @@ static CURLcode setup_connection_internals(struct SessionHandle *data,
|
||||||
|
|
||||||
/* Scan protocol handler table. */
|
/* Scan protocol handler table. */
|
||||||
|
|
||||||
for (pp = protocols; (p = *pp) != NULL; pp++)
|
/* Perform setup complement if some. */
|
||||||
if(Curl_raw_equal(p->scheme, conn->protostr)) {
|
p = conn->handler;
|
||||||
/* Protocol found in table. Check if allowed */
|
|
||||||
if(!(data->set.allowed_protocols & p->protocol))
|
|
||||||
/* nope, get out */
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* it is allowed for "normal" request, now do an extra check if this is
|
if(p->setup_connection) {
|
||||||
the result of a redirect */
|
result = (*p->setup_connection)(conn);
|
||||||
if(data->state.this_is_a_follow &&
|
|
||||||
!(data->set.redir_protocols & p->protocol))
|
|
||||||
/* nope, get out */
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Perform setup complement if some. */
|
if(result != CURLE_OK)
|
||||||
conn->handler = p;
|
return result;
|
||||||
|
|
||||||
if(p->setup_connection) {
|
p = conn->handler; /* May have changed. */
|
||||||
result = (*p->setup_connection)(conn);
|
}
|
||||||
|
|
||||||
if(result != CURLE_OK)
|
if(conn->port < 0)
|
||||||
return result;
|
/* we check for -1 here since if proxy was detected already, this
|
||||||
|
was very likely already set to the proxy port */
|
||||||
|
conn->port = p->defport;
|
||||||
|
conn->remote_port = (unsigned short)p->defport;
|
||||||
|
conn->protocol |= p->protocol;
|
||||||
|
|
||||||
p = conn->handler; /* May have changed. */
|
return CURLE_OK;
|
||||||
}
|
|
||||||
|
|
||||||
if(conn->port < 0)
|
|
||||||
/* we check for -1 here since if proxy was detected already, this
|
|
||||||
was very likely already set to the proxy port */
|
|
||||||
conn->port = p->defport;
|
|
||||||
conn->remote_port = (unsigned short)p->defport;
|
|
||||||
conn->protocol |= p->protocol;
|
|
||||||
return CURLE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The protocol was not found in the table, but we don't have to assign it
|
|
||||||
to anything since it is already assigned to a dummy-struct in the
|
|
||||||
create_conn() function when the connectdata struct is allocated. */
|
|
||||||
failf(data, "Protocol %s not supported or disabled in " LIBCURL_NAME,
|
|
||||||
conn->protostr);
|
|
||||||
return CURLE_UNSUPPORTED_PROTOCOL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef CURL_DISABLE_PROXY
|
#ifndef CURL_DISABLE_PROXY
|
||||||
|
@ -3989,7 +4008,7 @@ static CURLcode parse_remote_port(struct SessionHandle *data,
|
||||||
char endbracket;
|
char endbracket;
|
||||||
|
|
||||||
/* Note that at this point, the IPv6 address cannot contain any scope
|
/* Note that at this point, the IPv6 address cannot contain any scope
|
||||||
suffix as that has already been removed in the ParseURLAndFillConnection()
|
suffix as that has already been removed in the parseurlandfillconn()
|
||||||
function */
|
function */
|
||||||
if((1 == sscanf(conn->host.name, "[%*45[0123456789abcdefABCDEF:.]%c",
|
if((1 == sscanf(conn->host.name, "[%*45[0123456789abcdefABCDEF:.]%c",
|
||||||
&endbracket)) &&
|
&endbracket)) &&
|
||||||
|
@ -4423,7 +4442,7 @@ static CURLcode create_conn(struct SessionHandle *data,
|
||||||
conn->host.name = conn->host.rawalloc;
|
conn->host.name = conn->host.rawalloc;
|
||||||
conn->host.name[0] = 0;
|
conn->host.name[0] = 0;
|
||||||
|
|
||||||
result = ParseURLAndFillConnection(data, conn);
|
result = parseurlandfillconn(data, conn);
|
||||||
if(result != CURLE_OK) {
|
if(result != CURLE_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -4449,6 +4468,14 @@ static CURLcode create_conn(struct SessionHandle *data,
|
||||||
conn->protocol &= ~PROT_MISSING; /* switch that one off again */
|
conn->protocol &= ~PROT_MISSING; /* switch that one off again */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*************************************************************
|
||||||
|
* Parse a user name and password in the URL and strip it out
|
||||||
|
* of the host name
|
||||||
|
*************************************************************/
|
||||||
|
result = parse_url_userpass(data, conn, user, passwd);
|
||||||
|
if(result != CURLE_OK)
|
||||||
|
return result;
|
||||||
|
|
||||||
#ifndef CURL_DISABLE_PROXY
|
#ifndef CURL_DISABLE_PROXY
|
||||||
/*************************************************************
|
/*************************************************************
|
||||||
* Extract the user and password from the authentication string
|
* Extract the user and password from the authentication string
|
||||||
|
@ -4523,20 +4550,12 @@ static CURLcode create_conn(struct SessionHandle *data,
|
||||||
* Setup internals depending on protocol. Needs to be done after
|
* Setup internals depending on protocol. Needs to be done after
|
||||||
* we figured out what/if proxy to use.
|
* we figured out what/if proxy to use.
|
||||||
*************************************************************/
|
*************************************************************/
|
||||||
result = setup_connection_internals(data, conn);
|
result = setup_connection_internals(conn);
|
||||||
if(result != CURLE_OK) {
|
if(result != CURLE_OK) {
|
||||||
Curl_safefree(proxy);
|
Curl_safefree(proxy);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************
|
|
||||||
* Parse a user name and password in the URL and strip it out
|
|
||||||
* of the host name
|
|
||||||
*************************************************************/
|
|
||||||
result = parse_url_userpass(data, conn, user, passwd);
|
|
||||||
if(result != CURLE_OK)
|
|
||||||
return result;
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* file: is a special case in that it doesn't need a network connection
|
* file: is a special case in that it doesn't need a network connection
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
@ -4598,12 +4617,6 @@ static CURLcode create_conn(struct SessionHandle *data,
|
||||||
if(result != CURLE_OK)
|
if(result != CURLE_OK)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
/*************************************************************
|
|
||||||
* Check the current list of connections to see if we can
|
|
||||||
* re-use an already existing one or if we have to create a
|
|
||||||
* new one.
|
|
||||||
*************************************************************/
|
|
||||||
|
|
||||||
/* Get a cloned copy of the SSL config situation stored in the
|
/* Get a cloned copy of the SSL config situation stored in the
|
||||||
connection struct. But to get this going nicely, we must first make
|
connection struct. But to get this going nicely, we must first make
|
||||||
sure that the strings in the master copy are pointing to the correct
|
sure that the strings in the master copy are pointing to the correct
|
||||||
|
@ -4624,6 +4637,12 @@ static CURLcode create_conn(struct SessionHandle *data,
|
||||||
if(!Curl_clone_ssl_config(&data->set.ssl, &conn->ssl_config))
|
if(!Curl_clone_ssl_config(&data->set.ssl, &conn->ssl_config))
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
|
/*************************************************************
|
||||||
|
* Check the current list of connections to see if we can
|
||||||
|
* re-use an already existing one or if we have to create a
|
||||||
|
* new one.
|
||||||
|
*************************************************************/
|
||||||
|
|
||||||
/* reuse_fresh is TRUE if we are told to use a new connection by force, but
|
/* reuse_fresh is TRUE if we are told to use a new connection by force, but
|
||||||
we only acknowledge this option if this is not a re-used connection
|
we only acknowledge this option if this is not a re-used connection
|
||||||
already (which happens due to follow-location or during a HTTP
|
already (which happens due to follow-location or during a HTTP
|
||||||
|
|
Загрузка…
Ссылка в новой задаче