aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2011-04-27 14:44:00 +0200
committerDaniel Stenberg <daniel@haxx.se>2011-04-28 15:08:09 +0200
commit3b1b26578f7b21e2bfca1d1738aa77a44e11e111 (patch)
tree8401506df2650608c1de9c919e31f73f46ad498d
parent2cbe885c1a4d4f9b64fa0f41582e9d1b68affa25 (diff)
proxy: allow socks:// prefix in proxy string
Inspired by a patch from OB.Conseil. Added test case 708 to verify.
-rw-r--r--lib/ftp.c18
-rw-r--r--lib/socks.c2
-rw-r--r--lib/url.c76
-rw-r--r--tests/data/Makefile.am3
-rw-r--r--tests/data/test70860
5 files changed, 112 insertions, 47 deletions
diff --git a/lib/ftp.c b/lib/ftp.c
index 38ec8e9d0..203afe6ba 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -1554,10 +1554,10 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
newport = (unsigned short)(num & 0xffff);
if(conn->bits.tunnel_proxy ||
- data->set.proxytype == CURLPROXY_SOCKS5 ||
- data->set.proxytype == CURLPROXY_SOCKS5_HOSTNAME ||
- data->set.proxytype == CURLPROXY_SOCKS4 ||
- data->set.proxytype == CURLPROXY_SOCKS4A)
+ conn->proxytype == CURLPROXY_SOCKS5 ||
+ conn->proxytype == CURLPROXY_SOCKS5_HOSTNAME ||
+ conn->proxytype == CURLPROXY_SOCKS4 ||
+ conn->proxytype == CURLPROXY_SOCKS4A)
/* proxy tunnel -> use other host info because ip_addr_str is the
proxy address not the ftp host */
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],
conn->ip_addr_str);
if(conn->bits.tunnel_proxy ||
- data->set.proxytype == CURLPROXY_SOCKS5 ||
- data->set.proxytype == CURLPROXY_SOCKS5_HOSTNAME ||
- data->set.proxytype == CURLPROXY_SOCKS4 ||
- data->set.proxytype == CURLPROXY_SOCKS4A)
+ conn->proxytype == CURLPROXY_SOCKS5 ||
+ conn->proxytype == CURLPROXY_SOCKS5_HOSTNAME ||
+ conn->proxytype == CURLPROXY_SOCKS4 ||
+ conn->proxytype == CURLPROXY_SOCKS4A)
/* proxy tunnel -> use other host info because ip_addr_str is the
proxy address not the ftp host */
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 */
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
* FALSE */
case CURLPROXY_SOCKS5:
diff --git a/lib/socks.c b/lib/socks.c
index 14f8a2db2..d9ad9a7de 100644
--- a/lib/socks.c
+++ b/lib/socks.c
@@ -385,7 +385,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
curl_socket_t sock = conn->sock[sockindex];
struct SessionHandle *data = conn->data;
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);
ssize_t packetsize = 0;
diff --git a/lib/url.c b/lib/url.c
index 16c871df3..7c70be818 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -3132,25 +3132,22 @@ ConnectionStore(struct SessionHandle *data,
*/
CURLcode Curl_connected_proxy(struct connectdata *conn)
{
- CURLcode result = CURLE_OK;
- struct SessionHandle *data = conn->data;
-
- switch(data->set.proxytype) {
+ switch(conn->proxytype) {
#ifndef CURL_DISABLE_PROXY
case CURLPROXY_SOCKS5:
case CURLPROXY_SOCKS5_HOSTNAME:
- result = Curl_SOCKS5(conn->proxyuser, conn->proxypasswd,
- conn->host.name, conn->remote_port,
- FIRSTSOCKET, conn);
- break;
+ return Curl_SOCKS5(conn->proxyuser, conn->proxypasswd,
+ conn->host.name, conn->remote_port,
+ FIRSTSOCKET, conn);
+
case CURLPROXY_SOCKS4:
- result = Curl_SOCKS4(conn->proxyuser, conn->host.name,
- conn->remote_port, FIRSTSOCKET, conn, FALSE);
- break;
+ return Curl_SOCKS4(conn->proxyuser, conn->host.name,
+ conn->remote_port, FIRSTSOCKET, conn, FALSE);
+
case CURLPROXY_SOCKS4A:
- result = Curl_SOCKS4(conn->proxyuser, conn->host.name,
- conn->remote_port, FIRSTSOCKET, conn, TRUE);
- break;
+ return Curl_SOCKS4(conn->proxyuser, conn->host.name,
+ conn->remote_port, FIRSTSOCKET, conn, TRUE);
+
#endif /* CURL_DISABLE_PROXY */
case CURLPROXY_HTTP:
case CURLPROXY_HTTP_1_0:
@@ -3160,7 +3157,7 @@ CURLcode Curl_connected_proxy(struct connectdata *conn)
break;
} /* switch proxytype */
- return result;
+ return CURLE_OK;
}
static CURLcode ConnectPlease(struct SessionHandle *data,
@@ -4066,16 +4063,23 @@ static CURLcode parse_proxy(struct SessionHandle *data,
char *atsign;
/* 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
- * ignored.
+ * port name. Accept a protocol:// prefix
*/
- /* Skip the protocol part if present */
+ /* Parse the protocol part if present */
endofprot = strstr(proxy, "://");
- if(endofprot)
+ if(endofprot) {
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
- proxyptr = proxy;
+ proxyptr = proxy; /* No xxx:// head: It's a HTTP proxy */
/* Is there a username and password given in this proxy url? */
atsign = strchr(proxyptr, '@');
@@ -4763,12 +4767,24 @@ static CURLcode create_conn(struct SessionHandle *data,
else if(!proxy)
proxy = detect_proxy(conn);
- if(proxy && !*proxy) {
- free(proxy); /* Don't bother with an empty proxy string */
+ if(proxy && (!*proxy || (conn->handler->flags & PROTOPT_BANPROXY))) {
+ free(proxy); /* Don't bother with an empty proxy string or if the
+ protocol doesn't work with proxy */
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) ||
(conn->proxytype == CURLPROXY_HTTP_1_0)) {
#ifdef CURL_DISABLE_HTTP
@@ -4790,18 +4806,6 @@ static CURLcode create_conn(struct SessionHandle *data,
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 */
/*************************************************************
diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am
index b19de1266..8e0323717 100644
--- a/tests/data/Makefile.am
+++ b/tests/data/Makefile.am
@@ -71,7 +71,8 @@ EXTRA_DIST = test1 test108 test117 test127 test20 test27 test34 test46 \
test1203 test1117 test1118 test1119 test1120 test1300 test1301 test1302 \
test1303 test320 test321 test322 test323 test324 test1121 test581 test580 \
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:
@mkdir test-place; \
diff --git a/tests/data/test708 b/tests/data/test708
new file mode 100644
index 000000000..716d9aec0
--- /dev/null
+++ b/tests/data/test708
@@ -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>