url: split off proxy init and parsing from create_conn
Move the proxy parse/init into helper create_conn_helper_init_proxy to mitigate the chances some non-proxy code will be mistakenly added to it. Ref: https://github.com/curl/curl/issues/1274#issuecomment-281556510 Ref: https://github.com/curl/curl/pull/1293 Closes https://github.com/curl/curl/pull/1298
This commit is contained in:
Родитель
cbff751e95
Коммит
9f20333443
319
lib/url.c
319
lib/url.c
|
@ -5187,6 +5187,168 @@ static CURLcode parse_proxy_auth(struct Curl_easy *data,
|
|||
NULL, FALSE);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* create_conn helper to parse and init proxy values. to be called after unix
|
||||
socket init but before any proxy vars are evaluated. */
|
||||
static CURLcode create_conn_helper_init_proxy(struct connectdata *conn)
|
||||
{
|
||||
char *proxy = NULL;
|
||||
char *socksproxy = NULL;
|
||||
char *no_proxy = NULL;
|
||||
CURLcode result = CURLE_OK;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
/*************************************************************
|
||||
* Extract the user and password from the authentication string
|
||||
*************************************************************/
|
||||
if(conn->bits.proxy_user_passwd) {
|
||||
result = parse_proxy_auth(data, conn);
|
||||
if(result)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* Detect what (if any) proxy to use
|
||||
*************************************************************/
|
||||
if(data->set.str[STRING_PROXY]) {
|
||||
proxy = strdup(data->set.str[STRING_PROXY]);
|
||||
/* if global proxy is set, this is it */
|
||||
if(NULL == proxy) {
|
||||
failf(data, "memory shortage");
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if(data->set.str[STRING_PRE_PROXY]) {
|
||||
socksproxy = strdup(data->set.str[STRING_PRE_PROXY]);
|
||||
/* if global socks proxy is set, this is it */
|
||||
if(NULL == socksproxy) {
|
||||
failf(data, "memory shortage");
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
no_proxy = curl_getenv("no_proxy");
|
||||
if(!no_proxy)
|
||||
no_proxy = curl_getenv("NO_PROXY");
|
||||
|
||||
if(check_noproxy(conn->host.name, data->set.str[STRING_NOPROXY]) ||
|
||||
(!data->set.str[STRING_NOPROXY] &&
|
||||
check_noproxy(conn->host.name, no_proxy))) {
|
||||
Curl_safefree(proxy);
|
||||
Curl_safefree(socksproxy);
|
||||
}
|
||||
else if(!proxy && !socksproxy)
|
||||
#ifndef CURL_DISABLE_HTTP
|
||||
/* if the host is not in the noproxy list, detect proxy. */
|
||||
proxy = detect_proxy(conn);
|
||||
#else /* !CURL_DISABLE_HTTP */
|
||||
proxy = NULL;
|
||||
#endif /* CURL_DISABLE_HTTP */
|
||||
|
||||
Curl_safefree(no_proxy);
|
||||
|
||||
#ifdef USE_UNIX_SOCKETS
|
||||
/* For the time being do not mix proxy and unix domain sockets. See #1274 */
|
||||
if(proxy && conn->unix_domain_socket) {
|
||||
free(proxy);
|
||||
proxy = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(proxy && (!*proxy || (conn->handler->flags & PROTOPT_NONETWORK))) {
|
||||
free(proxy); /* Don't bother with an empty proxy string or if the
|
||||
protocol doesn't work with network */
|
||||
proxy = NULL;
|
||||
}
|
||||
if(socksproxy && (!*socksproxy ||
|
||||
(conn->handler->flags & PROTOPT_NONETWORK))) {
|
||||
free(socksproxy); /* Don't bother with an empty socks proxy string or if
|
||||
the protocol doesn't work with network */
|
||||
socksproxy = NULL;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* If this is supposed to use a proxy, we need to figure out the proxy host
|
||||
* name, proxy type and port number, so that we can re-use an existing
|
||||
* connection that may exist registered to the same proxy host.
|
||||
***********************************************************************/
|
||||
if(proxy || socksproxy) {
|
||||
if(proxy) {
|
||||
result = parse_proxy(data, conn, proxy, conn->http_proxy.proxytype);
|
||||
Curl_safefree(proxy); /* parse_proxy copies the proxy string */
|
||||
if(result)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(socksproxy) {
|
||||
result = parse_proxy(data, conn, socksproxy,
|
||||
conn->socks_proxy.proxytype);
|
||||
/* parse_proxy copies the socks proxy string */
|
||||
Curl_safefree(socksproxy);
|
||||
if(result)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(conn->http_proxy.host.rawalloc) {
|
||||
#ifdef CURL_DISABLE_HTTP
|
||||
/* asking for a HTTP proxy is a bit funny when HTTP is disabled... */
|
||||
result = CURLE_UNSUPPORTED_PROTOCOL;
|
||||
goto out;
|
||||
#else
|
||||
/* force this connection's protocol to become HTTP if not already
|
||||
compatible - if it isn't tunneling through */
|
||||
if(!(conn->handler->protocol & PROTO_FAMILY_HTTP) &&
|
||||
!conn->bits.tunnel_proxy)
|
||||
conn->handler = &Curl_handler_http;
|
||||
|
||||
conn->bits.httpproxy = TRUE;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
conn->bits.httpproxy = FALSE; /* not a HTTP proxy */
|
||||
conn->bits.tunnel_proxy = FALSE; /* no tunneling if not HTTP */
|
||||
}
|
||||
|
||||
if(conn->socks_proxy.host.rawalloc) {
|
||||
if(!conn->http_proxy.host.rawalloc) {
|
||||
/* once a socks proxy */
|
||||
if(!conn->socks_proxy.user) {
|
||||
conn->socks_proxy.user = conn->http_proxy.user;
|
||||
conn->http_proxy.user = NULL;
|
||||
Curl_safefree(conn->socks_proxy.passwd);
|
||||
conn->socks_proxy.passwd = conn->http_proxy.passwd;
|
||||
conn->http_proxy.passwd = NULL;
|
||||
}
|
||||
}
|
||||
conn->bits.socksproxy = TRUE;
|
||||
}
|
||||
else
|
||||
conn->bits.socksproxy = FALSE; /* not a socks proxy */
|
||||
}
|
||||
else {
|
||||
conn->bits.socksproxy = FALSE;
|
||||
conn->bits.httpproxy = FALSE;
|
||||
}
|
||||
conn->bits.proxy = conn->bits.httpproxy || conn->bits.socksproxy;
|
||||
|
||||
if(!conn->bits.proxy) {
|
||||
/* we aren't using the proxy after all... */
|
||||
conn->bits.proxy = FALSE;
|
||||
conn->bits.httpproxy = FALSE;
|
||||
conn->bits.socksproxy = FALSE;
|
||||
conn->bits.proxy_user_passwd = FALSE;
|
||||
conn->bits.tunnel_proxy = FALSE;
|
||||
}
|
||||
|
||||
out:
|
||||
|
||||
free(socksproxy);
|
||||
free(proxy);
|
||||
return result;
|
||||
}
|
||||
#endif /* CURL_DISABLE_PROXY */
|
||||
|
||||
/*
|
||||
|
@ -6110,9 +6272,6 @@ static CURLcode create_conn(struct Curl_easy *data,
|
|||
char *passwd = NULL;
|
||||
char *options = NULL;
|
||||
bool reuse;
|
||||
char *proxy = NULL;
|
||||
char *socksproxy = NULL;
|
||||
char *no_proxy = NULL;
|
||||
bool prot_missing = FALSE;
|
||||
bool connections_available = TRUE;
|
||||
bool force_reuse = FALSE;
|
||||
|
@ -6267,154 +6426,14 @@ static CURLcode create_conn(struct Curl_easy *data,
|
|||
}
|
||||
#endif
|
||||
|
||||
/* After the unix socket init but before the proxy vars are used, parse and
|
||||
initialize the proxy vars */
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
/*************************************************************
|
||||
* Extract the user and password from the authentication string
|
||||
*************************************************************/
|
||||
if(conn->bits.proxy_user_passwd) {
|
||||
result = parse_proxy_auth(data, conn);
|
||||
if(result)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* Detect what (if any) proxy to use
|
||||
*************************************************************/
|
||||
if(data->set.str[STRING_PROXY]) {
|
||||
proxy = strdup(data->set.str[STRING_PROXY]);
|
||||
/* if global proxy is set, this is it */
|
||||
if(NULL == proxy) {
|
||||
failf(data, "memory shortage");
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if(data->set.str[STRING_PRE_PROXY]) {
|
||||
socksproxy = strdup(data->set.str[STRING_PRE_PROXY]);
|
||||
/* if global socks proxy is set, this is it */
|
||||
if(NULL == socksproxy) {
|
||||
failf(data, "memory shortage");
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
no_proxy = curl_getenv("no_proxy");
|
||||
if(!no_proxy)
|
||||
no_proxy = curl_getenv("NO_PROXY");
|
||||
|
||||
if(check_noproxy(conn->host.name, data->set.str[STRING_NOPROXY]) ||
|
||||
(!data->set.str[STRING_NOPROXY] &&
|
||||
check_noproxy(conn->host.name, no_proxy))) {
|
||||
Curl_safefree(proxy);
|
||||
Curl_safefree(socksproxy);
|
||||
}
|
||||
else if(!proxy && !socksproxy)
|
||||
#ifndef CURL_DISABLE_HTTP
|
||||
/* if the host is not in the noproxy list, detect proxy. */
|
||||
proxy = detect_proxy(conn);
|
||||
#else /* !CURL_DISABLE_HTTP */
|
||||
proxy = NULL;
|
||||
#endif /* CURL_DISABLE_HTTP */
|
||||
|
||||
Curl_safefree(no_proxy);
|
||||
|
||||
#ifdef USE_UNIX_SOCKETS
|
||||
/* For the time being do not mix proxy and unix domain sockets. See #1274 */
|
||||
if(proxy && conn->unix_domain_socket) {
|
||||
free(proxy);
|
||||
proxy = NULL;
|
||||
}
|
||||
result = create_conn_helper_init_proxy(conn);
|
||||
if(result)
|
||||
goto out;
|
||||
#endif
|
||||
|
||||
if(proxy && (!*proxy || (conn->handler->flags & PROTOPT_NONETWORK))) {
|
||||
free(proxy); /* Don't bother with an empty proxy string or if the
|
||||
protocol doesn't work with network */
|
||||
proxy = NULL;
|
||||
}
|
||||
if(socksproxy && (!*socksproxy ||
|
||||
(conn->handler->flags & PROTOPT_NONETWORK))) {
|
||||
free(socksproxy); /* Don't bother with an empty socks proxy string or if
|
||||
the protocol doesn't work with network */
|
||||
socksproxy = NULL;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* If this is supposed to use a proxy, we need to figure out the proxy host
|
||||
* name, proxy type and port number, so that we can re-use an existing
|
||||
* connection that may exist registered to the same proxy host.
|
||||
***********************************************************************/
|
||||
if(proxy || socksproxy) {
|
||||
if(proxy) {
|
||||
result = parse_proxy(data, conn, proxy, conn->http_proxy.proxytype);
|
||||
Curl_safefree(proxy); /* parse_proxy copies the proxy string */
|
||||
if(result)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(socksproxy) {
|
||||
result = parse_proxy(data, conn, socksproxy,
|
||||
conn->socks_proxy.proxytype);
|
||||
/* parse_proxy copies the socks proxy string */
|
||||
Curl_safefree(socksproxy);
|
||||
if(result)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(conn->http_proxy.host.rawalloc) {
|
||||
#ifdef CURL_DISABLE_HTTP
|
||||
/* asking for a HTTP proxy is a bit funny when HTTP is disabled... */
|
||||
result = CURLE_UNSUPPORTED_PROTOCOL;
|
||||
goto out;
|
||||
#else
|
||||
/* force this connection's protocol to become HTTP if not already
|
||||
compatible - if it isn't tunneling through */
|
||||
if(!(conn->handler->protocol & PROTO_FAMILY_HTTP) &&
|
||||
!conn->bits.tunnel_proxy)
|
||||
conn->handler = &Curl_handler_http;
|
||||
|
||||
conn->bits.httpproxy = TRUE;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
conn->bits.httpproxy = FALSE; /* not a HTTP proxy */
|
||||
conn->bits.tunnel_proxy = FALSE; /* no tunneling if not HTTP */
|
||||
}
|
||||
|
||||
if(conn->socks_proxy.host.rawalloc) {
|
||||
if(!conn->http_proxy.host.rawalloc) {
|
||||
/* once a socks proxy */
|
||||
if(!conn->socks_proxy.user) {
|
||||
conn->socks_proxy.user = conn->http_proxy.user;
|
||||
conn->http_proxy.user = NULL;
|
||||
Curl_safefree(conn->socks_proxy.passwd);
|
||||
conn->socks_proxy.passwd = conn->http_proxy.passwd;
|
||||
conn->http_proxy.passwd = NULL;
|
||||
}
|
||||
}
|
||||
conn->bits.socksproxy = TRUE;
|
||||
}
|
||||
else
|
||||
conn->bits.socksproxy = FALSE; /* not a socks proxy */
|
||||
}
|
||||
else {
|
||||
conn->bits.socksproxy = FALSE;
|
||||
conn->bits.httpproxy = FALSE;
|
||||
}
|
||||
conn->bits.proxy = conn->bits.httpproxy || conn->bits.socksproxy;
|
||||
|
||||
if(!conn->bits.proxy) {
|
||||
/* we aren't using the proxy after all... */
|
||||
conn->bits.proxy = FALSE;
|
||||
conn->bits.httpproxy = FALSE;
|
||||
conn->bits.socksproxy = FALSE;
|
||||
conn->bits.proxy_user_passwd = FALSE;
|
||||
conn->bits.tunnel_proxy = FALSE;
|
||||
}
|
||||
|
||||
#endif /* CURL_DISABLE_PROXY */
|
||||
|
||||
/*************************************************************
|
||||
* If the protocol is using SSL and HTTP proxy is used, we set
|
||||
* the tunnel_proxy bit.
|
||||
|
@ -6775,13 +6794,11 @@ static CURLcode create_conn(struct Curl_easy *data,
|
|||
*************************************************************/
|
||||
result = resolve_server(data, conn, async);
|
||||
|
||||
out:
|
||||
out:
|
||||
|
||||
free(options);
|
||||
free(passwd);
|
||||
free(user);
|
||||
free(socksproxy);
|
||||
free(proxy);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче