diff --git a/anonymize/anonymize_doOnJSON_test.go b/anonymize/anonymize_doOnJSON_test.go index 1585bd47c..99a607c21 100644 --- a/anonymize/anonymize_doOnJSON_test.go +++ b/anonymize/anonymize_doOnJSON_test.go @@ -20,11 +20,6 @@ func Test_doOnJSON(t *testing.T) { "Network": "", "Address": ":80", "TLS": null, - "Redirect": { - "EntryPoint": "https", - "Regex": "", - "Replacement": "" - }, "Auth": null, "Compress": false }, @@ -36,7 +31,6 @@ func Test_doOnJSON(t *testing.T) { "Certificates": null, "ClientCAFiles": null }, - "Redirect": null, "Auth": null, "Compress": false } @@ -109,11 +103,6 @@ func Test_doOnJSON(t *testing.T) { "Network": "", "Address": ":80", "TLS": null, - "Redirect": { - "EntryPoint": "https", - "Regex": "", - "Replacement": "" - }, "Auth": null, "Compress": false }, @@ -125,7 +114,6 @@ func Test_doOnJSON(t *testing.T) { "Certificates": null, "ClientCAFiles": null }, - "Redirect": null, "Auth": null, "Compress": false } diff --git a/config/middlewares.go b/config/middlewares.go index ff588225a..95800566a 100644 --- a/config/middlewares.go +++ b/config/middlewares.go @@ -17,7 +17,8 @@ type Middleware struct { Headers *Headers `json:"headers,omitempty"` Errors *ErrorPage `json:"errors,omitempty"` RateLimit *RateLimit `json:"rateLimit,omitempty"` - Redirect *Redirect `json:"redirect,omitempty"` + RedirectRegex *RedirectRegex `json:"redirectregex,omitempty"` + RedirectScheme *RedirectScheme `json:"redirectscheme,omitempty"` BasicAuth *BasicAuth `json:"basicAuth,omitempty"` DigestAuth *DigestAuth `json:"digestAuth,omitempty"` ForwardAuth *ForwardAuth `json:"forwardAuth,omitempty"` @@ -229,13 +230,20 @@ func (r *RateLimit) SetDefaults() { r.ExtractorFunc = "request.host" } -// Redirect holds the redirection configuration of an entry point to another, or to an URL. -type Redirect struct { +// RedirectRegex holds the redirection configuration. +type RedirectRegex struct { Regex string `json:"regex,omitempty"` Replacement string `json:"replacement,omitempty"` Permanent bool `json:"permanent,omitempty"` } +// RedirectScheme holds the scheme redirection configuration. +type RedirectScheme struct { + Scheme string `json:"scheme,omitempty"` + Port string `json:"port,omitempty"` + Permanent bool `json:"permanent,omitempty"` +} + // ReplacePath holds the ReplacePath configuration. type ReplacePath struct { Path string `json:"path,omitempty"` @@ -247,7 +255,7 @@ type ReplacePathRegex struct { Replacement string `json:"replacement,omitempty"` } -// Retry contains request retry config +// Retry holds the retry configuration. type Retry struct { Attempts int `description:"Number of attempts" export:"true"` } diff --git a/integration/fixtures/https/https_redirect.toml b/integration/fixtures/https/https_redirect.toml index 491d0d916..9e68b1b4b 100644 --- a/integration/fixtures/https/https_redirect.toml +++ b/integration/fixtures/https/https_redirect.toml @@ -6,9 +6,6 @@ logLevel = "DEBUG" [entryPoints.http] address = ":8888" - [entryPoints.http.redirect] - entryPoint = "https" - [entryPoints.https] address = ":8443" [entryPoints.https.tls] @@ -92,9 +89,9 @@ logLevel = "DEBUG" path = "/api" [Middlewares.api-slash-replace-path.ReplacePath] path = "/api/" - [Middlewares.redirect-https.redirect] - regex = "^(?:https?://)?([\\w\\._-]+)(?::\\d+)?(.*)$" - replacement = "https://${1}:8443${2}" + [Middlewares.redirect-https.redirectScheme] + scheme = "https" + port = "8443" [Services] [Services.service1] diff --git a/integration/resources/compose/access_log.yml b/integration/resources/compose/access_log.yml index 36ea8b785..238b1514a 100644 --- a/integration/resources/compose/access_log.yml +++ b/integration/resources/compose/access_log.yml @@ -53,8 +53,8 @@ frontendRedirect: - traefik.routers.rt-frontendRedirect.entryPoints=frontendRedirect - traefik.routers.rt-frontendRedirect.rule=Path:/test - traefik.routers.rt-frontendRedirect.middlewares=redirecthttp - - traefik.middlewares.redirecthttp.redirect.regex=^(?:https?://)?([\w\._-]+)(?::\d+)?(.*)$$ - - traefik.middlewares.redirecthttp.redirect.replacement=http://$${1}:8000$${2} + - traefik.middlewares.redirecthttp.redirectScheme.scheme=http + - traefik.middlewares.redirecthttp.redirectScheme.port=8000 - traefik.services.service3.loadbalancer.server.port=80 rateLimit: image: containous/whoami diff --git a/middlewares/redirect/redirect.go b/middlewares/redirect/redirect.go index d9fdb584b..260157212 100644 --- a/middlewares/redirect/redirect.go +++ b/middlewares/redirect/redirect.go @@ -10,17 +10,11 @@ import ( "regexp" "strings" - "github.com/containous/traefik/config" - "github.com/containous/traefik/middlewares" "github.com/containous/traefik/tracing" "github.com/opentracing/opentracing-go/ext" "github.com/vulcand/oxy/utils" ) -const ( - typeName = "Redirect" -) - type redirect struct { next http.Handler regex *regexp.Regexp @@ -30,21 +24,17 @@ type redirect struct { name string } -// New creates a redirect middleware. -func New(ctx context.Context, next http.Handler, config config.Redirect, name string) (http.Handler, error) { - logger := middlewares.GetLogger(ctx, name, typeName) - logger.Debug("Creating middleware") - logger.Debugf("Setting up redirect %s -> %s", config.Regex, config.Replacement) - - re, err := regexp.Compile(config.Regex) +// New creates a Redirect middleware. +func newRedirect(ctx context.Context, next http.Handler, regex string, replacement string, permanent bool, name string) (http.Handler, error) { + re, err := regexp.Compile(regex) if err != nil { return nil, err } return &redirect{ regex: re, - replacement: config.Replacement, - permanent: config.Permanent, + replacement: replacement, + permanent: permanent, errHandler: utils.DefaultHandler, next: next, name: name, @@ -122,11 +112,32 @@ func (m *moveHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) { func rawURL(req *http.Request) string { scheme := "http" + host := req.Host + port := "" + uri := req.RequestURI + + schemeRegex := `^(https?):\/\/([\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 || isXForwardedHTTPS(req) { scheme = "https" } - return strings.Join([]string{scheme, "://", req.Host, req.RequestURI}, "") + return strings.Join([]string{scheme, "://", host, port, uri}, "") } func isXForwardedHTTPS(request *http.Request) bool { diff --git a/middlewares/redirect/redirect_regex.go b/middlewares/redirect/redirect_regex.go new file mode 100644 index 000000000..b57383b71 --- /dev/null +++ b/middlewares/redirect/redirect_regex.go @@ -0,0 +1,22 @@ +package redirect + +import ( + "context" + "net/http" + + "github.com/containous/traefik/config" + "github.com/containous/traefik/middlewares" +) + +const ( + typeRegexName = "RedirectRegex" +) + +// NewRedirectRegex creates a redirect middleware. +func NewRedirectRegex(ctx context.Context, next http.Handler, conf config.RedirectRegex, name string) (http.Handler, error) { + logger := middlewares.GetLogger(ctx, name, typeRegexName) + logger.Debug("Creating middleware") + logger.Debugf("Setting up redirection from %s to %s", conf.Regex, conf.Replacement) + + return newRedirect(ctx, next, conf.Regex, conf.Replacement, conf.Permanent, name) +} diff --git a/middlewares/redirect/redirect_test.go b/middlewares/redirect/redirect_regex_test.go similarity index 88% rename from middlewares/redirect/redirect_test.go rename to middlewares/redirect/redirect_regex_test.go index 592c64488..139d770f7 100644 --- a/middlewares/redirect/redirect_test.go +++ b/middlewares/redirect/redirect_regex_test.go @@ -13,10 +13,10 @@ import ( "github.com/stretchr/testify/require" ) -func TestNewRegexHandler(t *testing.T) { +func TestRedirectRegexHandler(t *testing.T) { testCases := []struct { desc string - config config.Redirect + config config.RedirectRegex method string url string secured bool @@ -26,7 +26,7 @@ func TestNewRegexHandler(t *testing.T) { }{ { desc: "simple redirection", - config: config.Redirect{ + config: config.RedirectRegex{ Regex: `^(?:http?:\/\/)(foo)(\.com)(:\d+)(.*)$`, Replacement: "https://${1}bar$2:443$4", }, @@ -36,7 +36,7 @@ func TestNewRegexHandler(t *testing.T) { }, { desc: "use request header", - config: config.Redirect{ + config: config.RedirectRegex{ Regex: `^(?:http?:\/\/)(foo)(\.com)(:\d+)(.*)$`, Replacement: `https://${1}{{ .Request.Header.Get "X-Foo" }}$2:443$4`, }, @@ -46,7 +46,7 @@ func TestNewRegexHandler(t *testing.T) { }, { desc: "URL doesn't match regex", - config: config.Redirect{ + config: config.RedirectRegex{ Regex: `^(?:http?:\/\/)(foo)(\.com)(:\d+)(.*)$`, Replacement: "https://${1}bar$2:443$4", }, @@ -55,7 +55,7 @@ func TestNewRegexHandler(t *testing.T) { }, { desc: "invalid rewritten URL", - config: config.Redirect{ + config: config.RedirectRegex{ Regex: `^(.*)$`, Replacement: "http://192.168.0.%31/", }, @@ -64,7 +64,7 @@ func TestNewRegexHandler(t *testing.T) { }, { desc: "invalid regex", - config: config.Redirect{ + config: config.RedirectRegex{ Regex: `^(.*`, Replacement: "$1", }, @@ -73,7 +73,7 @@ func TestNewRegexHandler(t *testing.T) { }, { desc: "HTTP to HTTPS permanent", - config: config.Redirect{ + config: config.RedirectRegex{ Regex: `^http://`, Replacement: "https://$1", Permanent: true, @@ -84,7 +84,7 @@ func TestNewRegexHandler(t *testing.T) { }, { desc: "HTTPS to HTTP permanent", - config: config.Redirect{ + config: config.RedirectRegex{ Regex: `https://foo`, Replacement: "http://foo", Permanent: true, @@ -96,7 +96,7 @@ func TestNewRegexHandler(t *testing.T) { }, { desc: "HTTP to HTTPS", - config: config.Redirect{ + config: config.RedirectRegex{ Regex: `http://foo:80`, Replacement: "https://foo:443", }, @@ -106,7 +106,7 @@ func TestNewRegexHandler(t *testing.T) { }, { desc: "HTTPS to HTTP", - config: config.Redirect{ + config: config.RedirectRegex{ Regex: `https://foo:443`, Replacement: "http://foo:80", }, @@ -117,7 +117,7 @@ func TestNewRegexHandler(t *testing.T) { }, { desc: "HTTP to HTTP", - config: config.Redirect{ + config: config.RedirectRegex{ Regex: `http://foo:80`, Replacement: "http://foo:88", }, @@ -127,7 +127,7 @@ func TestNewRegexHandler(t *testing.T) { }, { desc: "HTTP to HTTP POST", - config: config.Redirect{ + config: config.RedirectRegex{ Regex: `^http://`, Replacement: "https://$1", }, @@ -138,7 +138,7 @@ func TestNewRegexHandler(t *testing.T) { }, { desc: "HTTP to HTTP POST permanent", - config: config.Redirect{ + config: config.RedirectRegex{ Regex: `^http://`, Replacement: "https://$1", Permanent: true, @@ -156,7 +156,7 @@ func TestNewRegexHandler(t *testing.T) { t.Parallel() next := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}) - handler, err := New(context.Background(), next, test.config, "traefikTest") + handler, err := NewRedirectRegex(context.Background(), next, test.config, "traefikTest") if test.errorExpected { require.Error(t, err) diff --git a/middlewares/redirect/redirect_scheme.go b/middlewares/redirect/redirect_scheme.go new file mode 100644 index 000000000..2142c09b1 --- /dev/null +++ b/middlewares/redirect/redirect_scheme.go @@ -0,0 +1,34 @@ +package redirect + +import ( + "context" + "net/http" + + "github.com/containous/traefik/middlewares" + "github.com/pkg/errors" + + "github.com/containous/traefik/config" +) + +const ( + typeSchemeName = "RedirectScheme" + schemeRedirectRegex = `^(https?:\/\/)?([\w\._-]+)(:\d+)?(.*)$` +) + +// NewRedirectScheme creates a new RedirectScheme middleware. +func NewRedirectScheme(ctx context.Context, next http.Handler, conf config.RedirectScheme, name string) (http.Handler, error) { + logger := middlewares.GetLogger(ctx, name, typeSchemeName) + logger.Debug("Creating middleware") + logger.Debugf("Setting up redirection to %s %s", conf.Scheme, conf.Port) + + if len(conf.Scheme) == 0 { + return nil, errors.New("you must provide a target scheme") + } + + port := "" + if len(conf.Port) > 0 && !(conf.Scheme == "http" && conf.Port == "80" || conf.Scheme == "https" && conf.Port == "443") { + port = ":" + conf.Port + } + + return newRedirect(ctx, next, schemeRedirectRegex, conf.Scheme+"://${2}"+port+"${4}", conf.Permanent, name) +} diff --git a/middlewares/redirect/redirect_scheme_test.go b/middlewares/redirect/redirect_scheme_test.go new file mode 100644 index 000000000..b7dc6507f --- /dev/null +++ b/middlewares/redirect/redirect_scheme_test.go @@ -0,0 +1,250 @@ +package redirect + +import ( + "context" + "crypto/tls" + "net/http" + "net/http/httptest" + "regexp" + "testing" + + "github.com/containous/traefik/config" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestRedirectSchemeHandler(t *testing.T) { + testCases := []struct { + desc string + config config.RedirectScheme + method string + url string + secured bool + expectedURL string + expectedStatus int + errorExpected bool + }{ + { + desc: "Without scheme", + config: config.RedirectScheme{}, + url: "http://foo", + errorExpected: true, + }, + { + desc: "HTTP to HTTPS", + config: config.RedirectScheme{ + Scheme: "https", + }, + url: "http://foo", + expectedURL: "https://foo", + expectedStatus: http.StatusFound, + }, + { + desc: "HTTP with port to HTTPS without port", + config: config.RedirectScheme{ + Scheme: "https", + }, + url: "http://foo:8080", + expectedURL: "https://foo", + expectedStatus: http.StatusFound, + }, + { + desc: "HTTP without port to HTTPS with port", + config: config.RedirectScheme{ + Scheme: "https", + Port: "8443", + }, + url: "http://foo", + expectedURL: "https://foo:8443", + expectedStatus: http.StatusFound, + }, + { + desc: "HTTP with port to HTTPS with port", + config: config.RedirectScheme{ + Scheme: "https", + Port: "8443", + }, + url: "http://foo:8000", + expectedURL: "https://foo:8443", + expectedStatus: http.StatusFound, + }, + { + desc: "HTTPS with port to HTTPS with port", + config: config.RedirectScheme{ + Scheme: "https", + Port: "8443", + }, + url: "https://foo:8000", + expectedURL: "https://foo:8443", + expectedStatus: http.StatusFound, + }, + { + desc: "HTTPS with port to HTTPS without port", + config: config.RedirectScheme{ + Scheme: "https", + }, + url: "https://foo:8000", + expectedURL: "https://foo", + expectedStatus: http.StatusFound, + }, + { + desc: "redirection to HTTPS without port from an URL already in https", + config: config.RedirectScheme{ + Scheme: "https", + }, + url: "https://foo:8000/theother", + expectedURL: "https://foo/theother", + expectedStatus: http.StatusFound, + }, + { + desc: "HTTP to HTTPS permanent", + config: config.RedirectScheme{ + Scheme: "https", + Port: "8443", + Permanent: true, + }, + url: "http://foo", + expectedURL: "https://foo:8443", + expectedStatus: http.StatusMovedPermanently, + }, + { + desc: "to HTTP 80", + config: config.RedirectScheme{ + Scheme: "http", + Port: "80", + }, + url: "http://foo:80", + expectedURL: "http://foo", + expectedStatus: http.StatusFound, + }, + { + desc: "HTTP to wss", + config: config.RedirectScheme{ + Scheme: "wss", + Port: "9443", + }, + url: "http://foo", + expectedURL: "wss://foo:9443", + expectedStatus: http.StatusFound, + }, + { + desc: "HTTP to wss without port", + config: config.RedirectScheme{ + Scheme: "wss", + }, + url: "http://foo", + expectedURL: "wss://foo", + expectedStatus: http.StatusFound, + }, + { + desc: "HTTP with port to wss without port", + config: config.RedirectScheme{ + Scheme: "wss", + }, + url: "http://foo:5678", + expectedURL: "wss://foo", + expectedStatus: http.StatusFound, + }, + { + desc: "HTTP to HTTPS without port", + config: config.RedirectScheme{ + Scheme: "https", + }, + url: "http://foo:443", + expectedURL: "https://foo", + expectedStatus: http.StatusFound, + }, + { + desc: "HTTP port redirection", + config: config.RedirectScheme{ + Scheme: "http", + Port: "8181", + }, + url: "http://foo:8080", + expectedURL: "http://foo:8181", + expectedStatus: http.StatusFound, + }, + { + desc: "HTTPS with port 80 to HTTPS without port", + config: config.RedirectScheme{ + Scheme: "https", + }, + url: "https://foo:80", + expectedURL: "https://foo", + expectedStatus: http.StatusFound, + }, + } + + for _, test := range testCases { + test := test + + t.Run(test.desc, func(t *testing.T) { + t.Parallel() + + next := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}) + handler, err := NewRedirectScheme(context.Background(), next, test.config, "traefikTest") + + if test.errorExpected { + require.Error(t, err) + require.Nil(t, handler) + } else { + require.NoError(t, err) + require.NotNil(t, handler) + + recorder := httptest.NewRecorder() + + method := http.MethodGet + if test.method != "" { + method = test.method + } + r := httptest.NewRequest(method, test.url, nil) + + if test.secured { + r.TLS = &tls.ConnectionState{} + } + r.Header.Set("X-Foo", "bar") + handler.ServeHTTP(recorder, r) + + assert.Equal(t, test.expectedStatus, recorder.Code) + if test.expectedStatus == http.StatusMovedPermanently || + test.expectedStatus == http.StatusFound || + test.expectedStatus == http.StatusTemporaryRedirect || + test.expectedStatus == http.StatusPermanentRedirect { + + location, err := recorder.Result().Location() + require.NoError(t, err) + + assert.Equal(t, test.expectedURL, location.String()) + } else { + location, err := recorder.Result().Location() + require.Errorf(t, err, "Location %v", location) + } + + schemeRegex := `^(https?):\/\/([\w\._-]+)(:\d+)?(.*)$` + re, _ := regexp.Compile(schemeRegex) + + if re.Match([]byte(test.url)) { + match := re.FindStringSubmatch(test.url) + r.RequestURI = match[4] + + handler.ServeHTTP(recorder, r) + + assert.Equal(t, test.expectedStatus, recorder.Code) + if test.expectedStatus == http.StatusMovedPermanently || + test.expectedStatus == http.StatusFound || + test.expectedStatus == http.StatusTemporaryRedirect || + test.expectedStatus == http.StatusPermanentRedirect { + + location, err := recorder.Result().Location() + require.NoError(t, err) + + assert.Equal(t, test.expectedURL, location.String()) + } else { + location, err := recorder.Result().Location() + require.Errorf(t, err, "Location %v", location) + } + } + } + }) + } +} diff --git a/provider/label/parser_test.go b/provider/label/parser_test.go index 71ec148da..bf441a1e8 100644 --- a/provider/label/parser_test.go +++ b/provider/label/parser_test.go @@ -90,9 +90,12 @@ func TestDecodeConfiguration(t *testing.T) { "traefik.middlewares.Middleware12.ratelimit.rateset.Rate1.average": "42", "traefik.middlewares.Middleware12.ratelimit.rateset.Rate1.burst": "42", "traefik.middlewares.Middleware12.ratelimit.rateset.Rate1.period": "42", - "traefik.middlewares.Middleware13.redirect.permanent": "true", - "traefik.middlewares.Middleware13.redirect.regex": "foobar", - "traefik.middlewares.Middleware13.redirect.replacement": "foobar", + "traefik.middlewares.Middleware13.redirectregex.permanent": "true", + "traefik.middlewares.Middleware13.redirectregex.regex": "foobar", + "traefik.middlewares.Middleware13.redirectregex.replacement": "foobar", + "traefik.middlewares.Middleware13b.redirectscheme.scheme": "https", + "traefik.middlewares.Middleware13b.redirectscheme.port": "80", + "traefik.middlewares.Middleware13b.redirectscheme.permanent": "true", "traefik.middlewares.Middleware14.replacepath.path": "foobar", "traefik.middlewares.Middleware15.replacepathregex.regex": "foobar", "traefik.middlewares.Middleware15.replacepathregex.replacement": "foobar", @@ -237,12 +240,19 @@ func TestDecodeConfiguration(t *testing.T) { }, }, "Middleware13": { - Redirect: &config.Redirect{ + RedirectRegex: &config.RedirectRegex{ Regex: "foobar", Replacement: "foobar", Permanent: true, }, }, + "Middleware13b": { + RedirectScheme: &config.RedirectScheme{ + Scheme: "https", + Port: "80", + Permanent: true, + }, + }, "Middleware14": { ReplacePath: &config.ReplacePath{ Path: "foobar", @@ -553,12 +563,19 @@ func TestEncodeConfiguration(t *testing.T) { }, }, "Middleware13": { - Redirect: &config.Redirect{ + RedirectRegex: &config.RedirectRegex{ Regex: "foobar", Replacement: "foobar", Permanent: true, }, }, + "Middleware13b": { + RedirectScheme: &config.RedirectScheme{ + Scheme: "https", + Port: "80", + Permanent: true, + }, + }, "Middleware14": { ReplacePath: &config.ReplacePath{ Path: "foobar", @@ -856,9 +873,12 @@ func TestEncodeConfiguration(t *testing.T) { "traefik.Middlewares.Middleware12.RateLimit.RateSet.Rate1.Average": "42", "traefik.Middlewares.Middleware12.RateLimit.RateSet.Rate1.Burst": "42", "traefik.Middlewares.Middleware12.RateLimit.RateSet.Rate1.Period": "42", - "traefik.Middlewares.Middleware13.Redirect.Permanent": "true", - "traefik.Middlewares.Middleware13.Redirect.Regex": "foobar", - "traefik.Middlewares.Middleware13.Redirect.Replacement": "foobar", + "traefik.Middlewares.Middleware13.RedirectRegex.Regex": "foobar", + "traefik.Middlewares.Middleware13.RedirectRegex.Replacement": "foobar", + "traefik.Middlewares.Middleware13.RedirectRegex.Permanent": "true", + "traefik.Middlewares.Middleware13b.RedirectScheme.Scheme": "https", + "traefik.Middlewares.Middleware13b.RedirectScheme.Port": "80", + "traefik.Middlewares.Middleware13b.RedirectScheme.Permanent": "true", "traefik.Middlewares.Middleware14.ReplacePath.Path": "foobar", "traefik.Middlewares.Middleware15.ReplacePathRegex.Regex": "foobar", "traefik.Middlewares.Middleware15.ReplacePathRegex.Replacement": "foobar", diff --git a/server/middleware/middlewares.go b/server/middleware/middlewares.go index d9ecc89c0..8d3fba945 100644 --- a/server/middleware/middlewares.go +++ b/server/middleware/middlewares.go @@ -248,11 +248,22 @@ func (b *Builder) buildConstructor(ctx context.Context, middlewareName string, c } } - // Redirect - if config.Redirect != nil { + // RedirectRegex + if config.RedirectRegex != nil { if middleware == nil { middleware = func(next http.Handler) (http.Handler, error) { - return redirect.New(ctx, next, *config.Redirect, middlewareName) + return redirect.NewRedirectRegex(ctx, next, *config.RedirectRegex, middlewareName) + } + } else { + return nil, badConf + } + } + + // RedirectScheme + if config.RedirectScheme != nil { + if middleware == nil { + middleware = func(next http.Handler) (http.Handler, error) { + return redirect.NewRedirectScheme(ctx, next, *config.RedirectScheme, middlewareName) } } else { return nil, badConf