1
0
Fork 0

redirect to another entryPoint per frontend

This commit is contained in:
Manuel Zapf 2017-11-18 13:50:03 +01:00 committed by Traefiker
parent 66e489addb
commit 5d6384e101
19 changed files with 251 additions and 14 deletions

View file

@ -1103,6 +1103,21 @@ func (server *Server) loadConfig(configurations types.Configurations, globalConf
log.Infof("Configured IP Whitelists: %s", frontend.WhitelistSourceRange)
}
if len(frontend.Redirect) > 0 {
proto := "http"
if server.globalConfiguration.EntryPoints[frontend.Redirect].TLS != nil {
proto = "https"
}
regex, replacement, err := server.buildRedirect(proto, entryPoint)
rewrite, err := middlewares.NewRewrite(regex, replacement, true)
if err != nil {
log.Fatalf("Error creating Frontend Redirect: %v", err)
}
n.Use(rewrite)
log.Debugf("Creating frontend %s redirect to %s", frontendName, proto)
}
if len(frontend.BasicAuth) > 0 {
users := types.Users{}
for _, user := range frontend.BasicAuth {
@ -1254,21 +1269,13 @@ func (server *Server) wireFrontendBackend(serverRoute *serverRoute, handler http
func (server *Server) loadEntryPointConfig(entryPointName string, entryPoint *configuration.EntryPoint) (negroni.Handler, error) {
regex := entryPoint.Redirect.Regex
replacement := entryPoint.Redirect.Replacement
var err error
if len(entryPoint.Redirect.EntryPoint) > 0 {
regex = `^(?:https?:\/\/)?([\w\._-]+)(?::\d+)?(.*)$`
if server.globalConfiguration.EntryPoints[entryPoint.Redirect.EntryPoint] == nil {
return nil, errors.New("Unknown entrypoint " + entryPoint.Redirect.EntryPoint)
}
protocol := "http"
var protocol = "http"
if server.globalConfiguration.EntryPoints[entryPoint.Redirect.EntryPoint].TLS != nil {
protocol = "https"
}
r, _ := regexp.Compile(`(:\d+)`)
match := r.FindStringSubmatch(server.globalConfiguration.EntryPoints[entryPoint.Redirect.EntryPoint].Address)
if len(match) == 0 {
return nil, errors.New("Bad Address format: " + server.globalConfiguration.EntryPoints[entryPoint.Redirect.EntryPoint].Address)
}
replacement = protocol + "://$1" + match[0] + "$2"
regex, replacement, err = server.buildRedirect(protocol, entryPoint)
}
rewrite, err := middlewares.NewRewrite(regex, replacement, true)
if err != nil {
@ -1279,6 +1286,20 @@ func (server *Server) loadEntryPointConfig(entryPointName string, entryPoint *co
return rewrite, nil
}
func (server *Server) buildRedirect(protocol string, entryPoint *configuration.EntryPoint) (string, string, error) {
regex := `^(?:https?:\/\/)?([\w\._-]+)(?::\d+)?(.*)$`
if server.globalConfiguration.EntryPoints[entryPoint.Redirect.EntryPoint] == nil {
return "", "", fmt.Errorf("unknown target entrypoint %q", entryPoint.Redirect.EntryPoint)
}
r, _ := regexp.Compile(`(:\d+)`)
match := r.FindStringSubmatch(server.globalConfiguration.EntryPoints[entryPoint.Redirect.EntryPoint].Address)
if len(match) == 0 {
return "", "", fmt.Errorf("bad Address format %q", server.globalConfiguration.EntryPoints[entryPoint.Redirect.EntryPoint].Address)
}
replacement := protocol + "://$1" + match[0] + "$2"
return regex, replacement, nil
}
func (server *Server) buildDefaultHTTPRouter() *mux.Router {
router := mux.NewRouter()
router.NotFoundHandler = http.HandlerFunc(notFoundHandler)

View file

@ -903,6 +903,72 @@ func TestServerResponseEmptyBackend(t *testing.T) {
}
}
func TestServerLoadConfigBuildRedirect(t *testing.T) {
testCases := []struct {
desc string
replacementProtocol string
globalConfiguration configuration.GlobalConfiguration
originEntryPointName string
expectedReplacement string
}{
{
desc: "Redirect endpoint http to https with HTTPS protocol",
replacementProtocol: "https",
originEntryPointName: "http",
globalConfiguration: configuration.GlobalConfiguration{
EntryPoints: configuration.EntryPoints{
"http": &configuration.EntryPoint{
Address: ":80",
Redirect: &configuration.Redirect{
EntryPoint: "https",
},
},
"https": &configuration.EntryPoint{
Address: ":443",
TLS: &tls.TLS{},
},
},
},
expectedReplacement: "https://$1:443$2",
},
{
desc: "Redirect endpoint http to http02 with HTTP protocol",
replacementProtocol: "http",
originEntryPointName: "http",
globalConfiguration: configuration.GlobalConfiguration{
EntryPoints: configuration.EntryPoints{
"http": &configuration.EntryPoint{
Address: ":80",
Redirect: &configuration.Redirect{
EntryPoint: "http02",
},
},
"http02": &configuration.EntryPoint{
Address: ":88",
},
},
},
expectedReplacement: "http://$1:88$2",
},
}
for _, test := range testCases {
test := test
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
srv := Server{globalConfiguration: test.globalConfiguration}
_, replacement, err := srv.buildRedirect(test.replacementProtocol, srv.globalConfiguration.EntryPoints[test.originEntryPointName])
require.NoError(t, err, "build redirect sent an unexpected error")
assert.Equal(t, test.expectedReplacement, replacement, "build redirect does not return the right replacement pattern")
})
}
}
func buildDynamicConfig(dynamicConfigBuilders ...func(*types.Configuration)) *types.Configuration {
config := &types.Configuration{
Frontends: make(map[string]*types.Frontend),