proxy: support socks5h scheme in proxy URL

Environment variable 'ALL_PROXY=socks5h://example.com' is commonly
used to specify a SOCKS5 proxy server.
In curl, 'socks5' means the host name will be resolved locally,
and 'socks5h' means the host name will be resolved by the server.

Go SOCKS5 client always uses the server to resolve host names.
So this change just added socks5h as a supported URL scheme.

Fixes golang/go#13454

Change-Id: I06d2b07f66cd0923c114dba4df0f884b39e58bc0
Reviewed-on: https://go-review.googlesource.com/c/156517
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
diff --git a/proxy/proxy.go b/proxy/proxy.go
index 553ead7..f6026b9 100644
--- a/proxy/proxy.go
+++ b/proxy/proxy.go
@@ -79,8 +79,13 @@
 	}
 
 	switch u.Scheme {
-	case "socks5":
-		return SOCKS5("tcp", u.Host, auth, forward)
+	case "socks5", "socks5h":
+		addr := u.Hostname()
+		port := u.Port()
+		if port == "" {
+			port = "1080"
+		}
+		return SOCKS5("tcp", net.JoinHostPort(addr, port), auth, forward)
 	}
 
 	// If the scheme doesn't match any of the built-in schemes, see if it
diff --git a/proxy/proxy_test.go b/proxy/proxy_test.go
index 0be1b42..d260d69 100644
--- a/proxy/proxy_test.go
+++ b/proxy/proxy_test.go
@@ -12,6 +12,7 @@
 	"strings"
 	"testing"
 
+	"golang.org/x/net/internal/socks"
 	"golang.org/x/net/internal/sockstest"
 )
 
@@ -53,6 +54,7 @@
 		{allProxyEnv: "127.0.0.1:8080", noProxyEnv: "localhost, 127.0.0.1", wantTypeOf: direct{}},
 		{allProxyEnv: "ftp://example.com:8000", noProxyEnv: "localhost, 127.0.0.1", wantTypeOf: direct{}},
 		{allProxyEnv: "socks5://example.com:8080", noProxyEnv: "localhost, 127.0.0.1", wantTypeOf: &PerHost{}},
+		{allProxyEnv: "socks5h://example.com", wantTypeOf: &socks.Dialer{}},
 		{allProxyEnv: "irc://example.com:8000", wantTypeOf: dummyDialer{}},
 		{noProxyEnv: "localhost, 127.0.0.1", wantTypeOf: direct{}},
 		{wantTypeOf: direct{}},