diff --git a/integration/testdata/rawdata-consul.json b/integration/testdata/rawdata-consul.json index 8f70cc3b4..0bf110eac 100644 --- a/integration/testdata/rawdata-consul.json +++ b/integration/testdata/rawdata-consul.json @@ -86,7 +86,7 @@ }, "dashboard_redirect@internal": { "redirectRegex": { - "regex": "^(http:\\/\\/[^:\\/]+(:\\d+)?)\\/$", + "regex": "^(http:\\/\\/(\\[[\\w:.]+\\]|[\\w\\._-]+)(:\\d+)?)\\/$", "replacement": "${1}/dashboard/", "permanent": true }, diff --git a/integration/testdata/rawdata-etcd.json b/integration/testdata/rawdata-etcd.json index d8e844220..92b4aa2b5 100644 --- a/integration/testdata/rawdata-etcd.json +++ b/integration/testdata/rawdata-etcd.json @@ -86,7 +86,7 @@ }, "dashboard_redirect@internal": { "redirectRegex": { - "regex": "^(http:\\/\\/[^:\\/]+(:\\d+)?)\\/$", + "regex": "^(http:\\/\\/(\\[[\\w:.]+\\]|[\\w\\._-]+)(:\\d+)?)\\/$", "replacement": "${1}/dashboard/", "permanent": true }, diff --git a/integration/testdata/rawdata-ingress.json b/integration/testdata/rawdata-ingress.json index 6848403f4..dbbfc239e 100644 --- a/integration/testdata/rawdata-ingress.json +++ b/integration/testdata/rawdata-ingress.json @@ -54,7 +54,7 @@ "middlewares": { "dashboard_redirect@internal": { "redirectRegex": { - "regex": "^(http:\\/\\/[^:\\/]+(:\\d+)?)\\/$", + "regex": "^(http:\\/\\/(\\[[\\w:.]+\\]|[\\w\\._-]+)(:\\d+)?)\\/$", "replacement": "${1}/dashboard/", "permanent": true }, diff --git a/integration/testdata/rawdata-redis.json b/integration/testdata/rawdata-redis.json index 15a7a0396..1dda1cebe 100644 --- a/integration/testdata/rawdata-redis.json +++ b/integration/testdata/rawdata-redis.json @@ -86,7 +86,7 @@ }, "dashboard_redirect@internal": { "redirectRegex": { - "regex": "^(http:\\/\\/[^:\\/]+(:\\d+)?)\\/$", + "regex": "^(http:\\/\\/(\\[[\\w:.]+\\]|[\\w\\._-]+)(:\\d+)?)\\/$", "replacement": "${1}/dashboard/", "permanent": true }, diff --git a/integration/testdata/rawdata-zk.json b/integration/testdata/rawdata-zk.json index 494833760..67d5c47f9 100644 --- a/integration/testdata/rawdata-zk.json +++ b/integration/testdata/rawdata-zk.json @@ -86,7 +86,7 @@ }, "dashboard_redirect@internal": { "redirectRegex": { - "regex": "^(http:\\/\\/[^:\\/]+(:\\d+)?)\\/$", + "regex": "^(http:\\/\\/(\\[[\\w:.]+\\]|[\\w\\._-]+)(:\\d+)?)\\/$", "replacement": "${1}/dashboard/", "permanent": true }, diff --git a/pkg/middlewares/redirect/redirect.go b/pkg/middlewares/redirect/redirect.go index 9224a3252..0659a16a5 100644 --- a/pkg/middlewares/redirect/redirect.go +++ b/pkg/middlewares/redirect/redirect.go @@ -115,7 +115,7 @@ func rawURL(req *http.Request) string { port := "" uri := req.RequestURI - schemeRegex := `^(https?):\/\/([\w\._-]+)(:\d+)?(.*)$` + schemeRegex := `^(https?):\/\/(\[[\w:.]+\]|[\w\._-]+)?(:\d+)?(.*)$` re, _ := regexp.Compile(schemeRegex) if re.Match([]byte(req.RequestURI)) { match := re.FindStringSubmatch(req.RequestURI) diff --git a/pkg/middlewares/redirect/redirect_scheme.go b/pkg/middlewares/redirect/redirect_scheme.go index 92523c70e..749c3f594 100644 --- a/pkg/middlewares/redirect/redirect_scheme.go +++ b/pkg/middlewares/redirect/redirect_scheme.go @@ -12,7 +12,7 @@ import ( const ( typeSchemeName = "RedirectScheme" - schemeRedirectRegex = `^(https?:\/\/)?([\w\._-]+)(:\d+)?(.*)$` + schemeRedirectRegex = `^(https?:\/\/)?(\[[\w:.]+\]|[\w\._-]+)?(:\d+)?(.*)$` ) // NewRedirectScheme creates a new RedirectScheme middleware. diff --git a/pkg/middlewares/redirect/redirect_scheme_test.go b/pkg/middlewares/redirect/redirect_scheme_test.go index b0694cd57..e1e6fbacb 100644 --- a/pkg/middlewares/redirect/redirect_scheme_test.go +++ b/pkg/middlewares/redirect/redirect_scheme_test.go @@ -186,6 +186,44 @@ func TestRedirectSchemeHandler(t *testing.T) { expectedURL: "https://foo", expectedStatus: http.StatusFound, }, + { + desc: "IPV6 HTTP to HTTPS redirection without port", + config: dynamic.RedirectScheme{ + Scheme: "https", + }, + url: "http://[::1]", + expectedURL: "https://[::1]", + expectedStatus: http.StatusFound, + }, + { + desc: "IPV6 HTTP to HTTPS redirection with port", + config: dynamic.RedirectScheme{ + Scheme: "https", + Port: "8443", + }, + url: "http://[::1]", + expectedURL: "https://[::1]:8443", + expectedStatus: http.StatusFound, + }, + { + desc: "IPV6 HTTP with port 80 to HTTPS redirection without port", + config: dynamic.RedirectScheme{ + Scheme: "https", + }, + url: "http://[::1]:80", + expectedURL: "https://[::1]", + expectedStatus: http.StatusFound, + }, + { + desc: "IPV6 HTTP with port 80 to HTTPS redirection with port", + config: dynamic.RedirectScheme{ + Scheme: "https", + Port: "8443", + }, + url: "http://[::1]:80", + expectedURL: "https://[::1]:8443", + expectedStatus: http.StatusFound, + }, } for _, test := range testCases { @@ -235,7 +273,7 @@ func TestRedirectSchemeHandler(t *testing.T) { require.Errorf(t, err, "Location %v", location) } - schemeRegex := `^(https?):\/\/([\w\._-]+)(:\d+)?(.*)$` + schemeRegex := `^(https?):\/\/(\[[\w:.]+\]|[\w\._-]+)?(:\d+)?(.*)$` re, _ := regexp.Compile(schemeRegex) if re.Match([]byte(test.url)) { diff --git a/pkg/provider/traefik/fixtures/api_insecure_with_dashboard.json b/pkg/provider/traefik/fixtures/api_insecure_with_dashboard.json index c4a306889..992a447d1 100644 --- a/pkg/provider/traefik/fixtures/api_insecure_with_dashboard.json +++ b/pkg/provider/traefik/fixtures/api_insecure_with_dashboard.json @@ -25,7 +25,7 @@ "middlewares": { "dashboard_redirect": { "redirectRegex": { - "regex": "^(http:\\/\\/[^:\\/]+(:\\d+)?)\\/$", + "regex": "^(http:\\/\\/(\\[[\\w:.]+\\]|[\\w\\._-]+)(:\\d+)?)\\/$", "replacement": "${1}/dashboard/", "permanent": true } diff --git a/pkg/provider/traefik/fixtures/full_configuration.json b/pkg/provider/traefik/fixtures/full_configuration.json index bd08c9f0b..f09614e2e 100644 --- a/pkg/provider/traefik/fixtures/full_configuration.json +++ b/pkg/provider/traefik/fixtures/full_configuration.json @@ -57,7 +57,7 @@ "middlewares": { "dashboard_redirect": { "redirectRegex": { - "regex": "^(http:\\/\\/[^:\\/]+(:\\d+)?)\\/$", + "regex": "^(http:\\/\\/(\\[[\\w:.]+\\]|[\\w\\._-]+)(:\\d+)?)\\/$", "replacement": "${1}/dashboard/", "permanent": true } diff --git a/pkg/provider/traefik/internal.go b/pkg/provider/traefik/internal.go index 0c25420c5..a63a2f49b 100644 --- a/pkg/provider/traefik/internal.go +++ b/pkg/provider/traefik/internal.go @@ -197,7 +197,7 @@ func (i *Provider) apiConfiguration(cfg *dynamic.Configuration) { cfg.HTTP.Middlewares["dashboard_redirect"] = &dynamic.Middleware{ RedirectRegex: &dynamic.RedirectRegex{ - Regex: `^(http:\/\/[^:\/]+(:\d+)?)\/$`, + Regex: `^(http:\/\/(\[[\w:.]+\]|[\w\._-]+)(:\d+)?)\/$`, Replacement: "${1}/dashboard/", Permanent: true, },