proxy: allow socks:// prefix in proxy string
Inspired by a patch from OB.Conseil. Added test case 708 to verify.
This commit is contained in:
18
lib/ftp.c
18
lib/ftp.c
@@ -1554,10 +1554,10 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
|||||||
newport = (unsigned short)(num & 0xffff);
|
newport = (unsigned short)(num & 0xffff);
|
||||||
|
|
||||||
if(conn->bits.tunnel_proxy ||
|
if(conn->bits.tunnel_proxy ||
|
||||||
data->set.proxytype == CURLPROXY_SOCKS5 ||
|
conn->proxytype == CURLPROXY_SOCKS5 ||
|
||||||
data->set.proxytype == CURLPROXY_SOCKS5_HOSTNAME ||
|
conn->proxytype == CURLPROXY_SOCKS5_HOSTNAME ||
|
||||||
data->set.proxytype == CURLPROXY_SOCKS4 ||
|
conn->proxytype == CURLPROXY_SOCKS4 ||
|
||||||
data->set.proxytype == CURLPROXY_SOCKS4A)
|
conn->proxytype == CURLPROXY_SOCKS4A)
|
||||||
/* proxy tunnel -> use other host info because ip_addr_str is the
|
/* proxy tunnel -> use other host info because ip_addr_str is the
|
||||||
proxy address not the ftp host */
|
proxy address not the ftp host */
|
||||||
snprintf(newhost, sizeof(newhost), "%s", conn->host.name);
|
snprintf(newhost, sizeof(newhost), "%s", conn->host.name);
|
||||||
@@ -1610,10 +1610,10 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
|||||||
ip[0], ip[1], ip[2], ip[3],
|
ip[0], ip[1], ip[2], ip[3],
|
||||||
conn->ip_addr_str);
|
conn->ip_addr_str);
|
||||||
if(conn->bits.tunnel_proxy ||
|
if(conn->bits.tunnel_proxy ||
|
||||||
data->set.proxytype == CURLPROXY_SOCKS5 ||
|
conn->proxytype == CURLPROXY_SOCKS5 ||
|
||||||
data->set.proxytype == CURLPROXY_SOCKS5_HOSTNAME ||
|
conn->proxytype == CURLPROXY_SOCKS5_HOSTNAME ||
|
||||||
data->set.proxytype == CURLPROXY_SOCKS4 ||
|
conn->proxytype == CURLPROXY_SOCKS4 ||
|
||||||
data->set.proxytype == CURLPROXY_SOCKS4A)
|
conn->proxytype == CURLPROXY_SOCKS4A)
|
||||||
/* proxy tunnel -> use other host info because ip_addr_str is the
|
/* proxy tunnel -> use other host info because ip_addr_str is the
|
||||||
proxy address not the ftp host */
|
proxy address not the ftp host */
|
||||||
snprintf(newhost, sizeof(newhost), "%s", conn->host.name);
|
snprintf(newhost, sizeof(newhost), "%s", conn->host.name);
|
||||||
@@ -1715,7 +1715,7 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
|||||||
/* this just dumps information about this second connection */
|
/* this just dumps information about this second connection */
|
||||||
ftp_pasv_verbose(conn, conninfo, newhost, connectport);
|
ftp_pasv_verbose(conn, conninfo, newhost, connectport);
|
||||||
|
|
||||||
switch(data->set.proxytype) {
|
switch(conn->proxytype) {
|
||||||
/* FIX: this MUST wait for a proper connect first if 'connected' is
|
/* FIX: this MUST wait for a proper connect first if 'connected' is
|
||||||
* FALSE */
|
* FALSE */
|
||||||
case CURLPROXY_SOCKS5:
|
case CURLPROXY_SOCKS5:
|
||||||
|
@@ -385,7 +385,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
|
|||||||
curl_socket_t sock = conn->sock[sockindex];
|
curl_socket_t sock = conn->sock[sockindex];
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
long timeout;
|
long timeout;
|
||||||
bool socks5_resolve_local = (bool)(data->set.proxytype == CURLPROXY_SOCKS5);
|
bool socks5_resolve_local = (bool)(conn->proxytype == CURLPROXY_SOCKS5);
|
||||||
const size_t hostname_len = strlen(hostname);
|
const size_t hostname_len = strlen(hostname);
|
||||||
ssize_t packetsize = 0;
|
ssize_t packetsize = 0;
|
||||||
|
|
||||||
|
68
lib/url.c
68
lib/url.c
@@ -3132,25 +3132,22 @@ ConnectionStore(struct SessionHandle *data,
|
|||||||
*/
|
*/
|
||||||
CURLcode Curl_connected_proxy(struct connectdata *conn)
|
CURLcode Curl_connected_proxy(struct connectdata *conn)
|
||||||
{
|
{
|
||||||
CURLcode result = CURLE_OK;
|
switch(conn->proxytype) {
|
||||||
struct SessionHandle *data = conn->data;
|
|
||||||
|
|
||||||
switch(data->set.proxytype) {
|
|
||||||
#ifndef CURL_DISABLE_PROXY
|
#ifndef CURL_DISABLE_PROXY
|
||||||
case CURLPROXY_SOCKS5:
|
case CURLPROXY_SOCKS5:
|
||||||
case CURLPROXY_SOCKS5_HOSTNAME:
|
case CURLPROXY_SOCKS5_HOSTNAME:
|
||||||
result = Curl_SOCKS5(conn->proxyuser, conn->proxypasswd,
|
return Curl_SOCKS5(conn->proxyuser, conn->proxypasswd,
|
||||||
conn->host.name, conn->remote_port,
|
conn->host.name, conn->remote_port,
|
||||||
FIRSTSOCKET, conn);
|
FIRSTSOCKET, conn);
|
||||||
break;
|
|
||||||
case CURLPROXY_SOCKS4:
|
case CURLPROXY_SOCKS4:
|
||||||
result = Curl_SOCKS4(conn->proxyuser, conn->host.name,
|
return Curl_SOCKS4(conn->proxyuser, conn->host.name,
|
||||||
conn->remote_port, FIRSTSOCKET, conn, FALSE);
|
conn->remote_port, FIRSTSOCKET, conn, FALSE);
|
||||||
break;
|
|
||||||
case CURLPROXY_SOCKS4A:
|
case CURLPROXY_SOCKS4A:
|
||||||
result = Curl_SOCKS4(conn->proxyuser, conn->host.name,
|
return Curl_SOCKS4(conn->proxyuser, conn->host.name,
|
||||||
conn->remote_port, FIRSTSOCKET, conn, TRUE);
|
conn->remote_port, FIRSTSOCKET, conn, TRUE);
|
||||||
break;
|
|
||||||
#endif /* CURL_DISABLE_PROXY */
|
#endif /* CURL_DISABLE_PROXY */
|
||||||
case CURLPROXY_HTTP:
|
case CURLPROXY_HTTP:
|
||||||
case CURLPROXY_HTTP_1_0:
|
case CURLPROXY_HTTP_1_0:
|
||||||
@@ -3160,7 +3157,7 @@ CURLcode Curl_connected_proxy(struct connectdata *conn)
|
|||||||
break;
|
break;
|
||||||
} /* switch proxytype */
|
} /* switch proxytype */
|
||||||
|
|
||||||
return result;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CURLcode ConnectPlease(struct SessionHandle *data,
|
static CURLcode ConnectPlease(struct SessionHandle *data,
|
||||||
@@ -4066,16 +4063,23 @@ static CURLcode parse_proxy(struct SessionHandle *data,
|
|||||||
char *atsign;
|
char *atsign;
|
||||||
|
|
||||||
/* We do the proxy host string parsing here. We want the host name and the
|
/* We do the proxy host string parsing here. We want the host name and the
|
||||||
* port name. Accept a protocol:// prefix, even though it should just be
|
* port name. Accept a protocol:// prefix
|
||||||
* ignored.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Skip the protocol part if present */
|
/* Parse the protocol part if present */
|
||||||
endofprot = strstr(proxy, "://");
|
endofprot = strstr(proxy, "://");
|
||||||
if(endofprot)
|
if(endofprot) {
|
||||||
proxyptr = endofprot+3;
|
proxyptr = endofprot+3;
|
||||||
|
if(checkprefix("socks5", proxy))
|
||||||
|
conn->proxytype = CURLPROXY_SOCKS5;
|
||||||
|
else if(checkprefix("socks4a", proxy))
|
||||||
|
conn->proxytype = CURLPROXY_SOCKS4A;
|
||||||
|
else if(checkprefix("socks4", proxy))
|
||||||
|
conn->proxytype = CURLPROXY_SOCKS4;
|
||||||
|
/* Any other xxx:// : change to http proxy */
|
||||||
|
}
|
||||||
else
|
else
|
||||||
proxyptr = proxy;
|
proxyptr = proxy; /* No xxx:// head: It's a HTTP proxy */
|
||||||
|
|
||||||
/* Is there a username and password given in this proxy url? */
|
/* Is there a username and password given in this proxy url? */
|
||||||
atsign = strchr(proxyptr, '@');
|
atsign = strchr(proxyptr, '@');
|
||||||
@@ -4763,12 +4767,24 @@ static CURLcode create_conn(struct SessionHandle *data,
|
|||||||
else if(!proxy)
|
else if(!proxy)
|
||||||
proxy = detect_proxy(conn);
|
proxy = detect_proxy(conn);
|
||||||
|
|
||||||
if(proxy && !*proxy) {
|
if(proxy && (!*proxy || (conn->handler->flags & PROTOPT_BANPROXY))) {
|
||||||
free(proxy); /* Don't bother with an empty proxy string */
|
free(proxy); /* Don't bother with an empty proxy string or if the
|
||||||
|
protocol doesn't work with proxy */
|
||||||
proxy = NULL;
|
proxy = NULL;
|
||||||
}
|
}
|
||||||
/* proxy must be freed later unless NULL */
|
|
||||||
if(proxy && !(conn->handler->flags & PROTOPT_BANPROXY)) {
|
/***********************************************************************
|
||||||
|
* 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) {
|
||||||
|
result = parse_proxy(data, conn, proxy);
|
||||||
|
|
||||||
|
/* parse_proxy has freed the proxy string, so don't try to use it again */
|
||||||
|
if(result != CURLE_OK)
|
||||||
|
return result;
|
||||||
|
|
||||||
if((conn->proxytype == CURLPROXY_HTTP) ||
|
if((conn->proxytype == CURLPROXY_HTTP) ||
|
||||||
(conn->proxytype == CURLPROXY_HTTP_1_0)) {
|
(conn->proxytype == CURLPROXY_HTTP_1_0)) {
|
||||||
#ifdef CURL_DISABLE_HTTP
|
#ifdef CURL_DISABLE_HTTP
|
||||||
@@ -4790,18 +4806,6 @@ static CURLcode create_conn(struct SessionHandle *data,
|
|||||||
conn->bits.tunnel_proxy = FALSE;
|
conn->bits.tunnel_proxy = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* If this is supposed to use a proxy, we need to figure out the proxy
|
|
||||||
* host name, so that we can re-use an existing connection
|
|
||||||
* that may exist registered to the same proxy host.
|
|
||||||
***********************************************************************/
|
|
||||||
if(proxy) {
|
|
||||||
result = parse_proxy(data, conn, proxy);
|
|
||||||
/* parse_proxy has freed the proxy string, so don't try to use it again */
|
|
||||||
proxy = NULL;
|
|
||||||
if(result != CURLE_OK)
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
#endif /* CURL_DISABLE_PROXY */
|
#endif /* CURL_DISABLE_PROXY */
|
||||||
|
|
||||||
/*************************************************************
|
/*************************************************************
|
||||||
|
@@ -71,7 +71,8 @@ EXTRA_DIST = test1 test108 test117 test127 test20 test27 test34 test46 \
|
|||||||
test1203 test1117 test1118 test1119 test1120 test1300 test1301 test1302 \
|
test1203 test1117 test1118 test1119 test1120 test1300 test1301 test1302 \
|
||||||
test1303 test320 test321 test322 test323 test324 test1121 test581 test580 \
|
test1303 test320 test321 test322 test323 test324 test1121 test581 test580 \
|
||||||
test1304 test1305 test1306 test1307 test582 test583 test808 test809 \
|
test1304 test1305 test1306 test1307 test582 test583 test808 test809 \
|
||||||
test810 test811 test812 test813 test584 test1122 test1123 test1124 test1125
|
test810 test811 test812 test813 test584 test1122 test1123 test1124 test1125 \
|
||||||
|
test708
|
||||||
|
|
||||||
filecheck:
|
filecheck:
|
||||||
@mkdir test-place; \
|
@mkdir test-place; \
|
||||||
|
60
tests/data/test708
Normal file
60
tests/data/test708
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
<testcase>
|
||||||
|
<info>
|
||||||
|
<keywords>
|
||||||
|
HTTP
|
||||||
|
HTTP GET
|
||||||
|
SOCKS4
|
||||||
|
</keywords>
|
||||||
|
</info>
|
||||||
|
|
||||||
|
#
|
||||||
|
# Server-side
|
||||||
|
<reply name="1">
|
||||||
|
<data>
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||||
|
Server: test-server/fake
|
||||||
|
Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
|
||||||
|
ETag: "21025-dc7-39462498"
|
||||||
|
Accept-Ranges: bytes
|
||||||
|
Content-Length: 6
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
Funny-head: yesyes
|
||||||
|
|
||||||
|
-foo-
|
||||||
|
</data>
|
||||||
|
</reply>
|
||||||
|
|
||||||
|
#
|
||||||
|
# Client-side
|
||||||
|
<client>
|
||||||
|
<server>
|
||||||
|
http
|
||||||
|
socks4
|
||||||
|
</server>
|
||||||
|
<setenv>
|
||||||
|
all_proxy=socks4://%HOSTIP:%SOCKSPORT
|
||||||
|
</setenv>
|
||||||
|
<name>
|
||||||
|
HTTP GET via SOCKS4 proxy
|
||||||
|
</name>
|
||||||
|
<command>
|
||||||
|
http://%HOSTIP:%HTTPPORT/708
|
||||||
|
</command>
|
||||||
|
</client>
|
||||||
|
|
||||||
|
#
|
||||||
|
# Verify data after the test has been "shot"
|
||||||
|
<verify>
|
||||||
|
<strip>
|
||||||
|
^User-Agent:.*
|
||||||
|
</strip>
|
||||||
|
<protocol>
|
||||||
|
GET /708 HTTP/1.1
|
||||||
|
Host: %HOSTIP:%HTTPPORT
|
||||||
|
Accept: */*
|
||||||
|
|
||||||
|
</protocol>
|
||||||
|
</verify>
|
||||||
|
</testcase>
|
Reference in New Issue
Block a user