From 914f39d78461c410730920fed749d8ad09cdb6ea Mon Sep 17 00:00:00 2001 From: Matthew Holt Date: Tue, 13 Aug 2019 14:37:45 -0600 Subject: [PATCH] Adjust address parsing for Go 1.12.8's breaking changes See https://github.com/golang/go/commit/3226f2d492963d361af9dfc6714ef141ba606713 and https://github.com/golang/go/issues/29098 --- caddyhttp/httpserver/plugin.go | 23 +++++++++++++---------- caddyhttp/httpserver/plugin_test.go | 14 +++++++------- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/caddyhttp/httpserver/plugin.go b/caddyhttp/httpserver/plugin.go index ecd92298..19e814d7 100644 --- a/caddyhttp/httpserver/plugin.go +++ b/caddyhttp/httpserver/plugin.go @@ -510,6 +510,15 @@ func standardizeAddress(str string) (Address, error) { httpPort := strconv.Itoa(certmagic.HTTPPort) httpsPort := strconv.Itoa(certmagic.HTTPSPort) + // As of Go 1.12.8 (Aug 2019), ports that are service names such + // as ":http" and ":https" are no longer parsed as they were + // before, which is a breaking change for us. Attempt to smooth + // this over for now by replacing those strings with their port + // equivalents. See + // https://github.com/golang/go/commit/3226f2d492963d361af9dfc6714ef141ba606713 + str = strings.Replace(str, ":https", ":"+httpsPort, 1) + str = strings.Replace(str, ":http", ":"+httpPort, 1) + // Split input into components (prepend with // to assert host by default) if !strings.Contains(str, "//") && !strings.HasPrefix(str, "/") { str = "//" + str @@ -537,26 +546,20 @@ func standardizeAddress(str string) (Address, error) { } } - // repeated or conflicting scheme is confusing, so error - if u.Scheme != "" && (port == "http" || port == "https") { - return Address{}, fmt.Errorf("[%s] scheme specified twice in address", input) - } - // error if scheme and port combination violate convention if (u.Scheme == "http" && port == httpsPort) || (u.Scheme == "https" && port == httpPort) { return Address{}, fmt.Errorf("[%s] scheme and port violate convention", input) } // standardize http and https ports to their respective port numbers - if port == "http" { + // (this behavior changed in Go 1.12.8) + if port == httpPort { u.Scheme = "http" - port = httpPort - } else if port == "https" { + } else if port == httpsPort { u.Scheme = "https" - port = httpsPort } - return Address{Original: input, Scheme: u.Scheme, Host: host, Port: port, Path: u.Path}, err + return Address{Original: input, Scheme: u.Scheme, Host: host, Port: port, Path: u.Path}, nil } // RegisterDevDirective splices name into the list of directives diff --git a/caddyhttp/httpserver/plugin_test.go b/caddyhttp/httpserver/plugin_test.go index 702ef00f..6e20a858 100644 --- a/caddyhttp/httpserver/plugin_test.go +++ b/caddyhttp/httpserver/plugin_test.go @@ -45,10 +45,10 @@ func TestStandardizeAddress(t *testing.T) { {`localhost:https`, "https", "localhost", "443", "", false}, {`:http`, "http", "", "80", "", false}, {`:https`, "https", "", "443", "", false}, - {`http://localhost:https`, "", "", "", "", true}, // conflict - {`http://localhost:http`, "", "", "", "", true}, // repeated scheme - {`http://localhost:443`, "", "", "", "", true}, // not conventional - {`https://localhost:80`, "", "", "", "", true}, // not conventional + {`http://localhost:https`, "", "", "", "", true}, // conflict + {`http://localhost:http`, "http", "localhost", "80", "", false}, // repeated scheme -- test adjusted for Go 1.12.8 (expect no error) + {`http://localhost:443`, "", "", "", "", true}, // not conventional + {`https://localhost:80`, "", "", "", "", true}, // not conventional {`http://localhost`, "http", "localhost", "80", "", false}, {`https://localhost`, "https", "localhost", "443", "", false}, {`http://127.0.0.1`, "http", "127.0.0.1", "80", "", false}, @@ -58,8 +58,8 @@ func TestStandardizeAddress(t *testing.T) { {`https://127.0.0.1:1234`, "https", "127.0.0.1", "1234", "", false}, {`http://[::1]:1234`, "http", "::1", "1234", "", false}, {``, "", "", "", "", false}, - {`::1`, "", "::1", "", "", true}, - {`localhost::`, "", "localhost::", "", "", true}, + {`::1`, "", "::1", "", "", false}, // test adjusted for Go 1.12.8 (expect no error) + {`localhost::`, "", "localhost::", "", "", false}, // test adjusted for Go 1.12.8 (expect no error) {`#$%@`, "", "", "", "", true}, {`host/path`, "", "host", "", "/path", false}, {`http://host/`, "http", "host", "80", "/", false}, @@ -67,7 +67,7 @@ func TestStandardizeAddress(t *testing.T) { {`:1234/asdf`, "", "", "1234", "/asdf", false}, {`http://host/path`, "http", "host", "80", "/path", false}, {`https://host:443/path/foo`, "https", "host", "443", "/path/foo", false}, - {`host:80/path`, "", "host", "80", "/path", false}, + {`host:80/path`, "http", "host", "80", "/path", false}, // test adjusted for Go 1.12.8 (expect "http" scheme) {`host:https/path`, "https", "host", "443", "/path", false}, {`/path`, "", "", "", "/path", false}, } {