diff --git a/CHANGELOG.md b/CHANGELOG.md index dd59fd431..de88943b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,14 @@ +## [v2.4.14](https://github.com/traefik/traefik/tree/v2.4.14) (2021-08-16) +[All Commits](https://github.com/traefik/traefik/compare/v2.4.13...v2.4.14) + +**Bug fixes:** +- **[k8s/crd,k8s]** Avoid unauthorized middleware cross namespace reference ([#8322](https://github.com/traefik/traefik/pull/8322) by [jbdoumenjou](https://github.com/jbdoumenjou)) +- **[kv]** Remove unwanted trailing slash in key ([#8335](https://github.com/traefik/traefik/pull/8335) by [jbdoumenjou](https://github.com/jbdoumenjou)) +- **[middleware]** Redirect: fix comparison when explicit port request and implicit redirect port ([#8348](https://github.com/traefik/traefik/pull/8348) by [tcolgate](https://github.com/tcolgate)) + +**Documentation:** +- **[kv]** Fix a router's entryPoint definition example for KV provider ([#8357](https://github.com/traefik/traefik/pull/8357) by [avtion](https://github.com/avtion)) + ## [v2.5.0-rc6](https://github.com/traefik/traefik/tree/v2.5.0-rc6) (2021-08-13) [All Commits](https://github.com/traefik/traefik/compare/v2.5.0-rc5...v2.5.0-rc6) diff --git a/docs/content/routing/providers/kv.md b/docs/content/routing/providers/kv.md index 2276f04df..34ca6d38f 100644 --- a/docs/content/routing/providers/kv.md +++ b/docs/content/routing/providers/kv.md @@ -28,8 +28,8 @@ A Story of key & values | Key (Path) | Value | |-----------------------------------------------|-------------| - | `traefik.http.routers.myrouter.entrypoints/0` | `web` | - | `traefik.http.routers.myrouter.entrypoints/1` | `websecure` | + | `traefik/http/routers/myrouter/entrypoints/0` | `web` | + | `traefik/http/routers/myrouter/entrypoints/1` | `websecure` | ??? info "`traefik/http/routers//middlewares`" diff --git a/docs/requirements.txt b/docs/requirements.txt index 1ea1cf557..c9c00839c 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,4 +1,4 @@ -mkdocs==1.1 +mkdocs==1.2.2 pymdown-extensions==7.0 mkdocs-bootswatch==1.0 mkdocs-traefiklabs>=100.0.7 diff --git a/pkg/middlewares/redirect/redirect.go b/pkg/middlewares/redirect/redirect.go index e58422315..d2783d1bc 100644 --- a/pkg/middlewares/redirect/redirect.go +++ b/pkg/middlewares/redirect/redirect.go @@ -4,13 +4,17 @@ import ( "net/http" "net/url" "regexp" - "strings" "github.com/opentracing/opentracing-go/ext" "github.com/traefik/traefik/v2/pkg/tracing" "github.com/vulcand/oxy/utils" ) +const ( + schemeHTTP = "http" + schemeHTTPS = "https" +) + type redirect struct { next http.Handler regex *regexp.Regexp @@ -18,10 +22,11 @@ type redirect struct { permanent bool errHandler utils.ErrorHandler name string + rawURL func(*http.Request) string } // New creates a Redirect middleware. -func newRedirect(next http.Handler, regex, replacement string, permanent bool, name string) (http.Handler, error) { +func newRedirect(next http.Handler, regex, replacement string, permanent bool, rawURL func(*http.Request) string, name string) (http.Handler, error) { re, err := regexp.Compile(regex) if err != nil { return nil, err @@ -34,6 +39,7 @@ func newRedirect(next http.Handler, regex, replacement string, permanent bool, n errHandler: utils.DefaultHandler, next: next, name: name, + rawURL: rawURL, }, nil } @@ -42,7 +48,7 @@ func (r *redirect) GetTracingInformation() (string, ext.SpanKindEnum) { } func (r *redirect) ServeHTTP(rw http.ResponseWriter, req *http.Request) { - oldURL := rawURL(req) + oldURL := r.rawURL(req) // If the Regexp doesn't match, skip to the next handler. if !r.regex.MatchString(oldURL) { @@ -98,33 +104,3 @@ func (m *moveHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) { http.Error(rw, err.Error(), http.StatusInternalServerError) } } - -func rawURL(req *http.Request) string { - scheme := "http" - host := req.Host - port := "" - uri := req.RequestURI - - schemeRegex := `^(https?):\/\/(\[[\w:.]+\]|[\w\._-]+)?(:\d+)?(.*)$` - re, _ := regexp.Compile(schemeRegex) - if re.Match([]byte(req.RequestURI)) { - match := re.FindStringSubmatch(req.RequestURI) - scheme = match[1] - - if len(match[2]) > 0 { - host = match[2] - } - - if len(match[3]) > 0 { - port = match[3] - } - - uri = match[4] - } - - if req.TLS != nil { - scheme = "https" - } - - return strings.Join([]string{scheme, "://", host, port, uri}, "") -} diff --git a/pkg/middlewares/redirect/redirect_regex.go b/pkg/middlewares/redirect/redirect_regex.go index c4a6918c9..f26b5e3d4 100644 --- a/pkg/middlewares/redirect/redirect_regex.go +++ b/pkg/middlewares/redirect/redirect_regex.go @@ -3,6 +3,8 @@ package redirect import ( "context" "net/http" + "regexp" + "strings" "github.com/traefik/traefik/v2/pkg/config/dynamic" "github.com/traefik/traefik/v2/pkg/log" @@ -19,5 +21,35 @@ func NewRedirectRegex(ctx context.Context, next http.Handler, conf dynamic.Redir logger.Debug("Creating middleware") logger.Debugf("Setting up redirection from %s to %s", conf.Regex, conf.Replacement) - return newRedirect(next, conf.Regex, conf.Replacement, conf.Permanent, name) + return newRedirect(next, conf.Regex, conf.Replacement, conf.Permanent, rawURL, name) +} + +func rawURL(req *http.Request) string { + scheme := schemeHTTP + host := req.Host + port := "" + uri := req.RequestURI + + schemeRegex := `^(https?):\/\/(\[[\w:.]+\]|[\w\._-]+)?(:\d+)?(.*)$` + re, _ := regexp.Compile(schemeRegex) + if re.Match([]byte(req.RequestURI)) { + match := re.FindStringSubmatch(req.RequestURI) + scheme = match[1] + + if len(match[2]) > 0 { + host = match[2] + } + + if len(match[3]) > 0 { + port = match[3] + } + + uri = match[4] + } + + if req.TLS != nil { + scheme = schemeHTTPS + } + + return strings.Join([]string{scheme, "://", host, port, uri}, "") } diff --git a/pkg/middlewares/redirect/redirect_scheme.go b/pkg/middlewares/redirect/redirect_scheme.go index e83b20136..36bcb25fd 100644 --- a/pkg/middlewares/redirect/redirect_scheme.go +++ b/pkg/middlewares/redirect/redirect_scheme.go @@ -3,7 +3,10 @@ package redirect import ( "context" "errors" + "net" "net/http" + "regexp" + "strings" "github.com/traefik/traefik/v2/pkg/config/dynamic" "github.com/traefik/traefik/v2/pkg/log" @@ -26,9 +29,47 @@ func NewRedirectScheme(ctx context.Context, next http.Handler, conf dynamic.Redi } port := "" - if len(conf.Port) > 0 && !(conf.Scheme == "http" && conf.Port == "80" || conf.Scheme == "https" && conf.Port == "443") { + if len(conf.Port) > 0 && !(conf.Scheme == schemeHTTP && conf.Port == "80" || conf.Scheme == schemeHTTPS && conf.Port == "443") { port = ":" + conf.Port } - return newRedirect(next, schemeRedirectRegex, conf.Scheme+"://${2}"+port+"${4}", conf.Permanent, name) + return newRedirect(next, schemeRedirectRegex, conf.Scheme+"://${2}"+port+"${4}", conf.Permanent, rawURLScheme, name) +} + +func rawURLScheme(req *http.Request) string { + scheme := schemeHTTP + host, port, err := net.SplitHostPort(req.Host) + if err != nil { + host = req.Host + } else { + port = ":" + port + } + uri := req.RequestURI + + schemeRegex := `^(https?):\/\/(\[[\w:.]+\]|[\w\._-]+)?(:\d+)?(.*)$` + re, _ := regexp.Compile(schemeRegex) + if re.Match([]byte(req.RequestURI)) { + match := re.FindStringSubmatch(req.RequestURI) + scheme = match[1] + + if len(match[2]) > 0 { + host = match[2] + } + + if len(match[3]) > 0 { + port = match[3] + } + + uri = match[4] + } + + if req.TLS != nil { + scheme = schemeHTTPS + } + + if scheme == schemeHTTP && port == ":80" || scheme == schemeHTTPS && port == ":443" || port == "" { + port = "" + } + + return strings.Join([]string{scheme, "://", host, port, uri}, "") } diff --git a/pkg/middlewares/redirect/redirect_scheme_test.go b/pkg/middlewares/redirect/redirect_scheme_test.go index 4b38ec8e9..710a681ee 100644 --- a/pkg/middlewares/redirect/redirect_scheme_test.go +++ b/pkg/middlewares/redirect/redirect_scheme_test.go @@ -127,8 +127,18 @@ func TestRedirectSchemeHandler(t *testing.T) { Port: "80", }, url: "http://foo:80", - expectedURL: "http://foo", - expectedStatus: http.StatusFound, + expectedURL: "http://foo:80", + expectedStatus: http.StatusOK, + }, + { + desc: "to HTTPS 443", + config: dynamic.RedirectScheme{ + Scheme: "https", + Port: "443", + }, + url: "https://foo:443", + expectedURL: "https://foo:443", + expectedStatus: http.StatusOK, }, { desc: "HTTP to wss", @@ -248,6 +258,7 @@ func TestRedirectSchemeHandler(t *testing.T) { if test.method != "" { method = test.method } + req := httptest.NewRequest(method, test.url, nil) for k, v := range test.headers { diff --git a/script/gcg/traefik-bugfix.toml b/script/gcg/traefik-bugfix.toml index 4021c6712..f954736d7 100644 --- a/script/gcg/traefik-bugfix.toml +++ b/script/gcg/traefik-bugfix.toml @@ -4,11 +4,11 @@ RepositoryName = "traefik" OutputType = "file" FileName = "traefik_changelog.md" -# example new bugfix v2.4.13 +# example new bugfix v2.4.14 CurrentRef = "v2.4" -PreviousRef = "v2.4.12" +PreviousRef = "v2.4.13" BaseBranch = "v2.4" -FutureCurrentRefName = "v2.4.13" +FutureCurrentRefName = "v2.4.14" ThresholdPreviousRef = 10 ThresholdCurrentRef = 10