Support regex redirect by frontend

This commit is contained in:
Ludovic Fernandez 2017-12-15 11:48:03 +01:00 committed by Traefiker
parent bddad57a7b
commit 7ecd6d20ba
22 changed files with 405 additions and 195 deletions

View file

@ -944,7 +944,7 @@ func (s *Server) loadConfig(configurations types.Configurations, globalConfigura
if entryPoint.Redirect != nil {
if redirectHandlers[entryPointName] != nil {
n.Use(redirectHandlers[entryPointName])
} else if handler, err := s.buildEntryPointRedirect(entryPointName, entryPoint); err != nil {
} else if handler, err := s.buildRedirectHandler(entryPointName, entryPoint.Redirect); err != nil {
log.Errorf("Error loading entrypoint configuration for frontend %s: %v", frontendName, err)
log.Errorf("Skipping frontend %s...", frontendName)
continue frontend
@ -1131,8 +1131,8 @@ func (s *Server) loadConfig(configurations types.Configurations, globalConfigura
log.Infof("Configured IP Whitelists: %s", frontend.WhitelistSourceRange)
}
if len(frontend.Redirect) > 0 {
rewrite, err := s.buildRedirectRewrite(entryPointName, frontend.Redirect)
if frontend.Redirect != nil {
rewrite, err := s.buildRedirectHandler(entryPointName, frontend.Redirect)
if err != nil {
log.Errorf("Error creating Frontend Redirect: %v", err)
}
@ -1287,23 +1287,23 @@ func (s *Server) wireFrontendBackend(serverRoute *serverRoute, handler http.Hand
serverRoute.route.Handler(handler)
}
func (s *Server) buildEntryPointRedirect(srcEntryPointName string, entryPoint *configuration.EntryPoint) (*middlewares.Rewrite, error) {
if len(entryPoint.Redirect.EntryPoint) > 0 {
return s.buildRedirectRewrite(srcEntryPointName, entryPoint.Redirect.EntryPoint)
func (s *Server) buildRedirectHandler(srcEntryPointName string, redirect *types.Redirect) (*middlewares.Rewrite, error) {
// entry point redirect
if len(redirect.EntryPoint) > 0 {
return s.buildEntryPointRedirect(srcEntryPointName, redirect.EntryPoint)
}
regex := entryPoint.Redirect.Regex
replacement := entryPoint.Redirect.Replacement
rewrite, err := middlewares.NewRewrite(regex, replacement, true)
// regex redirect
rewrite, err := middlewares.NewRewrite(redirect.Regex, redirect.Replacement, true)
if err != nil {
return nil, err
}
log.Debugf("Creating entryPoint redirect %s -> %s : %s -> %s", srcEntryPointName, entryPoint.Redirect.EntryPoint, regex, replacement)
log.Debugf("Creating entryPoint redirect %s -> %s -> %s", srcEntryPointName, redirect.Regex, redirect.Replacement)
return rewrite, nil
}
func (s *Server) buildRedirectRewrite(srcEntryPointName string, redirectEntryPoint string) (*middlewares.Rewrite, error) {
func (s *Server) buildEntryPointRedirect(srcEntryPointName string, redirectEntryPoint string) (*middlewares.Rewrite, error) {
regex, replacement, err := s.buildRedirect(redirectEntryPoint)
if err != nil {
return nil, err

View file

@ -918,15 +918,20 @@ func TestBuildEntryPointRedirect(t *testing.T) {
srcEntryPointName string
url string
entryPoint *configuration.EntryPoint
redirect *types.Redirect
expectedURL string
}{
{
desc: "redirect regex",
srcEntryPointName: "http",
url: "http://foo.com",
redirect: &types.Redirect{
Regex: `^(?:http?:\/\/)(foo)(\.com)$`,
Replacement: "https://$1{{\"bar\"}}$2",
},
entryPoint: &configuration.EntryPoint{
Address: ":80",
Redirect: &configuration.Redirect{
Redirect: &types.Redirect{
Regex: `^(?:http?:\/\/)(foo)(\.com)$`,
Replacement: "https://$1{{\"bar\"}}$2",
},
@ -937,9 +942,12 @@ func TestBuildEntryPointRedirect(t *testing.T) {
desc: "redirect entry point",
srcEntryPointName: "http",
url: "http://foo:80",
redirect: &types.Redirect{
EntryPoint: "https",
},
entryPoint: &configuration.EntryPoint{
Address: ":80",
Redirect: &configuration.Redirect{
Redirect: &types.Redirect{
EntryPoint: "https",
},
},
@ -949,9 +957,14 @@ func TestBuildEntryPointRedirect(t *testing.T) {
desc: "redirect entry point with regex (ignored)",
srcEntryPointName: "http",
url: "http://foo.com:80",
redirect: &types.Redirect{
EntryPoint: "https",
Regex: `^(?:http?:\/\/)(foo)(\.com)$`,
Replacement: "https://$1{{\"bar\"}}$2",
},
entryPoint: &configuration.EntryPoint{
Address: ":80",
Redirect: &configuration.Redirect{
Redirect: &types.Redirect{
EntryPoint: "https",
Regex: `^(?:http?:\/\/)(foo)(\.com)$`,
Replacement: "https://$1{{\"bar\"}}$2",
@ -966,7 +979,7 @@ func TestBuildEntryPointRedirect(t *testing.T) {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
rewrite, err := srv.buildEntryPointRedirect(test.srcEntryPointName, test.entryPoint)
rewrite, err := srv.buildRedirectHandler(test.srcEntryPointName, test.redirect)
require.NoError(t, err)
req := testhelpers.MustNewRequest(http.MethodGet, test.url, nil)
@ -983,7 +996,7 @@ func TestBuildEntryPointRedirect(t *testing.T) {
}
}
func TestServerBuildRedirectRewrite(t *testing.T) {
func TestServerBuildEntryPointRedirect(t *testing.T) {
srv := Server{
globalConfiguration: configuration.GlobalConfiguration{
EntryPoints: configuration.EntryPoints{
@ -1022,7 +1035,7 @@ func TestServerBuildRedirectRewrite(t *testing.T) {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
rewrite, err := srv.buildRedirectRewrite(test.srcEntryPointName, test.redirectEntryPoint)
rewrite, err := srv.buildEntryPointRedirect(test.srcEntryPointName, test.redirectEntryPoint)
if test.errorExpected {
require.Error(t, err)
} else {