diff options
author | Daniel Stenberg <daniel@haxx.se> | 2011-04-27 14:44:00 +0200 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2011-04-28 15:08:09 +0200 |
commit | 3b1b26578f7b21e2bfca1d1738aa77a44e11e111 (patch) | |
tree | 8401506df2650608c1de9c919e31f73f46ad498d | |
parent | 2cbe885c1a4d4f9b64fa0f41582e9d1b68affa25 (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.c | 18 | ||||
-rw-r--r-- | lib/socks.c | 2 | ||||
-rw-r--r-- | lib/url.c | 76 | ||||
-rw-r--r-- | tests/data/Makefile.am | 3 | ||||
-rw-r--r-- | tests/data/test708 | 60 |
5 files changed, 112 insertions, 47 deletions
@@ -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; @@ -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> |