commit 970595f9639dfdee707621932a09b86ed41af4fd Author: David Fifield david@bamsoftware.com Date: Fri Feb 1 20:19:18 2019 -0700
Make addrForDial's default ports numeric, also recognize http.
This is needed for an HTTP proxy. A CONNECT request is host:port but the port can only be numeric. --- meek-client/proxy_test.go | 54 +++++++++++++++++++++++++++++++++++++++++++++++ meek-client/utls.go | 11 ++++++---- 2 files changed, 61 insertions(+), 4 deletions(-)
diff --git a/meek-client/proxy_test.go b/meek-client/proxy_test.go new file mode 100644 index 0000000..5e87e56 --- /dev/null +++ b/meek-client/proxy_test.go @@ -0,0 +1,54 @@ +package main + +import ( + "net/url" + "testing" +) + +// Test that addrForDial returns a numeric port number. It needs to be numeric +// because we pass it as part of the authority-form URL in HTTP proxy requests. +// https://tools.ietf.org/html/rfc7230#section-5.3.3 authority-form +// https://tools.ietf.org/html/rfc3986#section-3.2.3 port +func TestAddrForDial(t *testing.T) { + // good tests + for _, test := range []struct { + URL string + Addr string + }{ + {"http://example.com", "example.com:80"}, + {"http://example.com/", "example.com:80"}, + {"https://example.com/", "example.com:443"}, + {"http://example.com:443/", "example.com:443"}, + {"ftp://example.com:21/", "example.com:21"}, + } { + u, err := url.Parse(test.URL) + if err != nil { + panic(err) + } + addr, err := addrForDial(u) + if err != nil { + t.Errorf("%q → error %v", test.URL, err) + continue + } + if addr != test.Addr { + t.Errorf("%q → %q, expected %q", test.URL, addr, test.Addr) + } + } + + // bad tests + for _, input := range []string{ + "example.com", + "example.com:80", + "ftp://example.com/", + } { + u, err := url.Parse(input) + if err != nil { + panic(err) + } + addr, err := addrForDial(u) + if err == nil { + t.Errorf("%q → %q, expected error", input, addr) + continue + } + } +} diff --git a/meek-client/utls.go b/meek-client/utls.go index 67cf104..1f9d32d 100644 --- a/meek-client/utls.go +++ b/meek-client/utls.go @@ -74,10 +74,13 @@ func addrForDial(url *url.URL) (string, error) { // internationalized domain name to ASCII. port := url.Port() if port == "" { - // No port? Use the default for the scheme. We only care about https. - if url.Scheme == "https" { - port = "https" - } else { + // No port? Use the default for the scheme. + switch url.Scheme { + case "http": + port = "80" + case "https": + port = "443" + default: return "", fmt.Errorf("unsupported URL scheme %q", url.Scheme) } }