Merge current v2.4 into v2.5
This commit is contained in:
commit
2bd60f9e60
8 changed files with 115 additions and 44 deletions
11
CHANGELOG.md
11
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)
|
## [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)
|
[All Commits](https://github.com/traefik/traefik/compare/v2.5.0-rc5...v2.5.0-rc6)
|
||||||
|
|
||||||
|
|
|
@ -28,8 +28,8 @@ A Story of key & values
|
||||||
|
|
||||||
| Key (Path) | Value |
|
| Key (Path) | Value |
|
||||||
|-----------------------------------------------|-------------|
|
|-----------------------------------------------|-------------|
|
||||||
| `traefik.http.routers.myrouter.entrypoints/0` | `web` |
|
| `traefik/http/routers/myrouter/entrypoints/0` | `web` |
|
||||||
| `traefik.http.routers.myrouter.entrypoints/1` | `websecure` |
|
| `traefik/http/routers/myrouter/entrypoints/1` | `websecure` |
|
||||||
|
|
||||||
??? info "`traefik/http/routers/<router_name>/middlewares`"
|
??? info "`traefik/http/routers/<router_name>/middlewares`"
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
mkdocs==1.1
|
mkdocs==1.2.2
|
||||||
pymdown-extensions==7.0
|
pymdown-extensions==7.0
|
||||||
mkdocs-bootswatch==1.0
|
mkdocs-bootswatch==1.0
|
||||||
mkdocs-traefiklabs>=100.0.7
|
mkdocs-traefiklabs>=100.0.7
|
||||||
|
|
|
@ -4,13 +4,17 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/opentracing/opentracing-go/ext"
|
"github.com/opentracing/opentracing-go/ext"
|
||||||
"github.com/traefik/traefik/v2/pkg/tracing"
|
"github.com/traefik/traefik/v2/pkg/tracing"
|
||||||
"github.com/vulcand/oxy/utils"
|
"github.com/vulcand/oxy/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
schemeHTTP = "http"
|
||||||
|
schemeHTTPS = "https"
|
||||||
|
)
|
||||||
|
|
||||||
type redirect struct {
|
type redirect struct {
|
||||||
next http.Handler
|
next http.Handler
|
||||||
regex *regexp.Regexp
|
regex *regexp.Regexp
|
||||||
|
@ -18,10 +22,11 @@ type redirect struct {
|
||||||
permanent bool
|
permanent bool
|
||||||
errHandler utils.ErrorHandler
|
errHandler utils.ErrorHandler
|
||||||
name string
|
name string
|
||||||
|
rawURL func(*http.Request) string
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a Redirect middleware.
|
// 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)
|
re, err := regexp.Compile(regex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -34,6 +39,7 @@ func newRedirect(next http.Handler, regex, replacement string, permanent bool, n
|
||||||
errHandler: utils.DefaultHandler,
|
errHandler: utils.DefaultHandler,
|
||||||
next: next,
|
next: next,
|
||||||
name: name,
|
name: name,
|
||||||
|
rawURL: rawURL,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +48,7 @@ func (r *redirect) GetTracingInformation() (string, ext.SpanKindEnum) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *redirect) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
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 the Regexp doesn't match, skip to the next handler.
|
||||||
if !r.regex.MatchString(oldURL) {
|
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)
|
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}, "")
|
|
||||||
}
|
|
||||||
|
|
|
@ -3,6 +3,8 @@ package redirect
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/traefik/traefik/v2/pkg/config/dynamic"
|
"github.com/traefik/traefik/v2/pkg/config/dynamic"
|
||||||
"github.com/traefik/traefik/v2/pkg/log"
|
"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.Debug("Creating middleware")
|
||||||
logger.Debugf("Setting up redirection from %s to %s", conf.Regex, conf.Replacement)
|
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}, "")
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,10 @@ package redirect
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/traefik/traefik/v2/pkg/config/dynamic"
|
"github.com/traefik/traefik/v2/pkg/config/dynamic"
|
||||||
"github.com/traefik/traefik/v2/pkg/log"
|
"github.com/traefik/traefik/v2/pkg/log"
|
||||||
|
@ -26,9 +29,47 @@ func NewRedirectScheme(ctx context.Context, next http.Handler, conf dynamic.Redi
|
||||||
}
|
}
|
||||||
|
|
||||||
port := ""
|
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
|
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}, "")
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,8 +127,18 @@ func TestRedirectSchemeHandler(t *testing.T) {
|
||||||
Port: "80",
|
Port: "80",
|
||||||
},
|
},
|
||||||
url: "http://foo:80",
|
url: "http://foo:80",
|
||||||
expectedURL: "http://foo",
|
expectedURL: "http://foo:80",
|
||||||
expectedStatus: http.StatusFound,
|
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",
|
desc: "HTTP to wss",
|
||||||
|
@ -248,6 +258,7 @@ func TestRedirectSchemeHandler(t *testing.T) {
|
||||||
if test.method != "" {
|
if test.method != "" {
|
||||||
method = test.method
|
method = test.method
|
||||||
}
|
}
|
||||||
|
|
||||||
req := httptest.NewRequest(method, test.url, nil)
|
req := httptest.NewRequest(method, test.url, nil)
|
||||||
|
|
||||||
for k, v := range test.headers {
|
for k, v := range test.headers {
|
||||||
|
|
|
@ -4,11 +4,11 @@ RepositoryName = "traefik"
|
||||||
OutputType = "file"
|
OutputType = "file"
|
||||||
FileName = "traefik_changelog.md"
|
FileName = "traefik_changelog.md"
|
||||||
|
|
||||||
# example new bugfix v2.4.13
|
# example new bugfix v2.4.14
|
||||||
CurrentRef = "v2.4"
|
CurrentRef = "v2.4"
|
||||||
PreviousRef = "v2.4.12"
|
PreviousRef = "v2.4.13"
|
||||||
BaseBranch = "v2.4"
|
BaseBranch = "v2.4"
|
||||||
FutureCurrentRefName = "v2.4.13"
|
FutureCurrentRefName = "v2.4.14"
|
||||||
|
|
||||||
ThresholdPreviousRef = 10
|
ThresholdPreviousRef = 10
|
||||||
ThresholdCurrentRef = 10
|
ThresholdCurrentRef = 10
|
||||||
|
|
Loading…
Reference in a new issue