From 21a584022f03d3853c028efc3cfddbd0136d3d1f Mon Sep 17 00:00:00 2001 From: mpl Date: Thu, 20 Aug 2015 00:33:49 +0200 Subject: [PATCH] pkg/client: be stricter when rewriting URLs url.Parse in Go 1.5 now fails with the scheme://IPv6:/foo form (trailing colon). But it still works when the hostname is an actual hostname, or an IPv4, which seems inconsistent. This CL therefore not only accepts this new failure (which comes with Go 1.5) but also considers any host with a trailing colon as an invalid URL and refuses to rewrite it. There probably are other places in Camlistore where we should the same. See https://github.com/golang/go/issues/12200 Change-Id: Ib9ea95a71013b5b53f2fd99415015ec916bb4d9d --- pkg/client/client.go | 15 +++++++++++---- pkg/client/client_test.go | 4 ++-- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/pkg/client/client.go b/pkg/client/client.go index 91117095b..6c6ea8e77 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -807,6 +807,8 @@ func (c *Client) Post(url string, bodyType string, body io.Reader) error { return res.Body.Close() } +// newRequests creates a request with the authentication header, and with the +// appropriate scheme and port in the case of self-signed TLS. func (c *Client) newRequest(method, url string, body ...io.Reader) *http.Request { var bodyR io.Reader if len(body) > 0 { @@ -866,14 +868,19 @@ func (c *Client) selfVerifiedSSL() bool { // and we do not want the http transport layer to redo it. func (c *Client) condRewriteURL(urlStr string) string { if c.selfVerifiedSSL() || c.insecureTLS() { - // url.Parse fails for mismached IPv6 brackets on Go 1.5, but - // not 1.4. See https://github.com/golang/go/issues/6530. - // SplitHostPort below always fails on mismatched IPv6 brackets, - // so overall we get the same behaviour on both 1.4 & 1.5. u, err := url.Parse(urlStr) if err != nil { return urlStr } + if strings.HasSuffix(u.Host, ":") { + // Here we compensate for the fact that, as of + // 2015-08-24, when the host part ends with a colon (empty + // port), url.Parse only fails when the hostname is an IPv6 + // address (https://github.com/golang/go/issues/12200). + // We instead choose to be consistent and we refuse to + // rewrite any URL that ends with a colon. + return urlStr + } if u.Scheme == "https" { // Keep the port 443 if no explicit port was specified. _, _, err := net.SplitHostPort(u.Host) diff --git a/pkg/client/client_test.go b/pkg/client/client_test.go index 1967f09f9..88679aa45 100644 --- a/pkg/client/client_test.go +++ b/pkg/client/client_test.go @@ -27,18 +27,18 @@ var rewritetests = []struct { {"https://foo.bar", "http://foo.bar:443"}, {"https://foo.bar/", "http://foo.bar:443/"}, {"https://foo.bar:443/", "http://foo.bar:443/"}, - {"https://foo.bar:/", "http://foo.bar:/"}, {"https://foo.bar:baz/", "http://foo.bar:baz/"}, {"https://[::0]/", "http://[::0]:443/"}, {"https://[::0]:82/", "http://[::0]:82/"}, {"https://[2001:DB8::1]:80/", "http://[2001:DB8::1]:80/"}, - {"https://[2001:DB8::1]:/", "http://[2001:DB8::1]:/"}, {"https://[2001:DB8:0:1]/", "http://[2001:DB8:0:1]:443/"}, {"https://192.0.2.3/", "http://192.0.2.3:443/"}, {"https://192.0.2.3:60/", "http://192.0.2.3:60/"}, // Invalid URLs stay exactly the same. {"https://[2001:DB8::1:/", "https://[2001:DB8::1:/"}, {"https://foo.bar:443:baz/", "https://foo.bar:443:baz/"}, + {"https://foo.bar:/", "https://foo.bar:/"}, + {"https://[2001:DB8::1]:/", "https://[2001:DB8::1]:/"}, } func TestCondRewriteURL(t *testing.T) {