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
This commit is contained in:
mpl 2015-08-20 00:33:49 +02:00
parent 9a42ac9b91
commit 21a584022f
2 changed files with 13 additions and 6 deletions

View File

@ -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)

View File

@ -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) {