Fix too many redirect

Signed-off-by: Emile Vauge <emile@vauge.com>
This commit is contained in:
Emile Vauge 2017-04-13 16:37:07 +02:00
parent ca9e36ebe3
commit e7a73d3fb3
No known key found for this signature in database
GPG key ID: D808B4C167352E59

View file

@ -549,12 +549,10 @@ func (server *Server) buildEntryPoints(globalConfiguration GlobalConfiguration)
func (server *Server) loadConfig(configurations configs, globalConfiguration GlobalConfiguration) (map[string]*serverEntryPoint, error) { func (server *Server) loadConfig(configurations configs, globalConfiguration GlobalConfiguration) (map[string]*serverEntryPoint, error) {
serverEntryPoints := server.buildEntryPoints(globalConfiguration) serverEntryPoints := server.buildEntryPoints(globalConfiguration)
redirectHandlers := make(map[string]negroni.Handler) redirectHandlers := make(map[string]negroni.Handler)
backends := map[string]http.Handler{} backends := map[string]http.Handler{}
backendsHealthcheck := map[string]*healthcheck.BackendHealthCheck{} backendsHealthcheck := map[string]*healthcheck.BackendHealthCheck{}
backend2FrontendMap := map[string]string{} backend2FrontendMap := map[string]string{}
for _, configuration := range configurations { for _, configuration := range configurations {
frontendNames := sortedFrontendNamesForConfig(configuration) frontendNames := sortedFrontendNamesForConfig(configuration)
frontend: frontend:
@ -609,7 +607,7 @@ func (server *Server) loadConfig(configurations configs, globalConfiguration Glo
redirectHandlers[entryPointName] = handler redirectHandlers[entryPointName] = handler
} }
} }
if backends[frontend.Backend] == nil { if backends[entryPointName+frontend.Backend] == nil {
log.Debugf("Creating backend %s", frontend.Backend) log.Debugf("Creating backend %s", frontend.Backend)
var lb http.Handler var lb http.Handler
rr, _ := roundrobin.New(saveBackend) rr, _ := roundrobin.New(saveBackend)
@ -634,131 +632,131 @@ func (server *Server) loadConfig(configurations configs, globalConfiguration Glo
sticky = roundrobin.NewStickySession(cookiename) sticky = roundrobin.NewStickySession(cookiename)
} }
switch lbMethod { switch lbMethod {
case types.Drr: case types.Drr:
log.Debugf("Creating load-balancer drr") log.Debugf("Creating load-balancer drr")
rebalancer, _ := roundrobin.NewRebalancer(rr, roundrobin.RebalancerLogger(oxyLogger)) rebalancer, _ := roundrobin.NewRebalancer(rr, roundrobin.RebalancerLogger(oxyLogger))
if stickysession { if stickysession {
log.Debugf("Sticky session with cookie %v", cookiename) log.Debugf("Sticky session with cookie %v", cookiename)
rebalancer, _ = roundrobin.NewRebalancer(rr, roundrobin.RebalancerLogger(oxyLogger), roundrobin.RebalancerStickySession(sticky)) rebalancer, _ = roundrobin.NewRebalancer(rr, roundrobin.RebalancerLogger(oxyLogger), roundrobin.RebalancerStickySession(sticky))
}
lb = rebalancer
for serverName, server := range configuration.Backends[frontend.Backend].Servers {
url, err := url.Parse(server.URL)
if err != nil {
log.Errorf("Error parsing server URL %s: %v", server.URL, err)
log.Errorf("Skipping frontend %s...", frontendName)
continue frontend
} }
lb = rebalancer backend2FrontendMap[url.String()] = frontendName
for serverName, server := range configuration.Backends[frontend.Backend].Servers { log.Debugf("Creating server %s at %s with weight %d", serverName, url.String(), server.Weight)
url, err := url.Parse(server.URL) if err := rebalancer.UpsertServer(url, roundrobin.Weight(server.Weight)); err != nil {
if err != nil { log.Errorf("Error adding server %s to load balancer: %v", server.URL, err)
log.Errorf("Error parsing server URL %s: %v", server.URL, err) log.Errorf("Skipping frontend %s...", frontendName)
log.Errorf("Skipping frontend %s...", frontendName) continue frontend
continue frontend
}
backend2FrontendMap[url.String()] = frontendName
log.Debugf("Creating server %s at %s with weight %d", serverName, url.String(), server.Weight)
if err := rebalancer.UpsertServer(url, roundrobin.Weight(server.Weight)); err != nil {
log.Errorf("Error adding server %s to load balancer: %v", server.URL, err)
log.Errorf("Skipping frontend %s...", frontendName)
continue frontend
}
hcOpts := parseHealthCheckOptions(rebalancer,frontend.Backend, configuration.Backends[frontend.Backend].HealthCheck, *globalConfiguration.HealthCheck)
if hcOpts != nil {
log.Debugf("Setting up backend health check %s", *hcOpts)
backendsHealthcheck[frontend.Backend] = healthcheck.NewBackendHealthCheck(*hcOpts)
}
} }
case types.Wrr: hcOpts := parseHealthCheckOptions(rebalancer, frontend.Backend, configuration.Backends[frontend.Backend].HealthCheck, *globalConfiguration.HealthCheck)
log.Debugf("Creating load-balancer wrr") if hcOpts != nil {
if stickysession { log.Debugf("Setting up backend health check %s", *hcOpts)
log.Debugf("Sticky session with cookie %v", cookiename)
rr, _ = roundrobin.New(saveBackend, roundrobin.EnableStickySession(sticky))
}
lb = rr
for serverName, server := range configuration.Backends[frontend.Backend].Servers {
url, err := url.Parse(server.URL)
if err != nil {
log.Errorf("Error parsing server URL %s: %v", server.URL, err)
log.Errorf("Skipping frontend %s...", frontendName)
continue frontend
}
backend2FrontendMap[url.String()] = frontendName
log.Debugf("Creating server %s at %s with weight %d", serverName, url.String(), server.Weight)
if err := rr.UpsertServer(url, roundrobin.Weight(server.Weight)); err != nil {
log.Errorf("Error adding server %s to load balancer: %v", server.URL, err)
log.Errorf("Skipping frontend %s...", frontendName)
continue frontend
}
}
hcOpts := parseHealthCheckOptions(rr,frontend.Backend, configuration.Backends[frontend.Backend].HealthCheck, *globalConfiguration.HealthCheck)
if hcOpts != nil {
log.Debugf("Setting up backend health check %s", *hcOpts)
backendsHealthcheck[frontend.Backend] = healthcheck.NewBackendHealthCheck(*hcOpts) backendsHealthcheck[frontend.Backend] = healthcheck.NewBackendHealthCheck(*hcOpts)
} }
} }
maxConns := configuration.Backends[frontend.Backend].MaxConn case types.Wrr:
if maxConns != nil && maxConns.Amount != 0 { log.Debugf("Creating load-balancer wrr")
extractFunc, err := utils.NewExtractor(maxConns.ExtractorFunc) if stickysession {
log.Debugf("Sticky session with cookie %v", cookiename)
rr, _ = roundrobin.New(saveBackend, roundrobin.EnableStickySession(sticky))
}
lb = rr
for serverName, server := range configuration.Backends[frontend.Backend].Servers {
url, err := url.Parse(server.URL)
if err != nil { if err != nil {
log.Errorf("Error creating connlimit: %v", err) log.Errorf("Error parsing server URL %s: %v", server.URL, err)
log.Errorf("Skipping frontend %s...", frontendName) log.Errorf("Skipping frontend %s...", frontendName)
continue frontend continue frontend
} }
log.Debugf("Creating load-balancer connlimit") backend2FrontendMap[url.String()] = frontendName
lb, err = connlimit.New(lb, extractFunc, maxConns.Amount, connlimit.Logger(oxyLogger)) log.Debugf("Creating server %s at %s with weight %d", serverName, url.String(), server.Weight)
if err != nil { if err := rr.UpsertServer(url, roundrobin.Weight(server.Weight)); err != nil {
log.Errorf("Error creating connlimit: %v", err) log.Errorf("Error adding server %s to load balancer: %v", server.URL, err)
log.Errorf("Skipping frontend %s...", frontendName) log.Errorf("Skipping frontend %s...", frontendName)
continue frontend continue frontend
} }
} }
// retry ? hcOpts := parseHealthCheckOptions(rr, frontend.Backend, configuration.Backends[frontend.Backend].HealthCheck, *globalConfiguration.HealthCheck)
if globalConfiguration.Retry != nil { if hcOpts != nil {
retries := len(configuration.Backends[frontend.Backend].Servers) log.Debugf("Setting up backend health check %s", *hcOpts)
if globalConfiguration.Retry.Attempts > 0 { backendsHealthcheck[frontend.Backend] = healthcheck.NewBackendHealthCheck(*hcOpts)
retries = globalConfiguration.Retry.Attempts }
} }
lb = middlewares.NewRetry(retries, lb) maxConns := configuration.Backends[frontend.Backend].MaxConn
log.Debugf("Creating retries max attempts %d", retries) if maxConns != nil && maxConns.Amount != 0 {
extractFunc, err := utils.NewExtractor(maxConns.ExtractorFunc)
if err != nil {
log.Errorf("Error creating connlimit: %v", err)
log.Errorf("Skipping frontend %s...", frontendName)
continue frontend
}
log.Debugf("Creating load-balancer connlimit")
lb, err = connlimit.New(lb, extractFunc, maxConns.Amount, connlimit.Logger(oxyLogger))
if err != nil {
log.Errorf("Error creating connlimit: %v", err)
log.Errorf("Skipping frontend %s...", frontendName)
continue frontend
}
}
// retry ?
if globalConfiguration.Retry != nil {
retries := len(configuration.Backends[frontend.Backend].Servers)
if globalConfiguration.Retry.Attempts > 0 {
retries = globalConfiguration.Retry.Attempts
}
lb = middlewares.NewRetry(retries, lb)
log.Debugf("Creating retries max attempts %d", retries)
}
if server.globalConfiguration.Web != nil && server.globalConfiguration.Web.Metrics != nil {
if server.globalConfiguration.Web.Metrics.Prometheus != nil {
metricsMiddlewareBackend := middlewares.NewMetricsWrapper(middlewares.NewPrometheus(frontend.Backend, server.globalConfiguration.Web.Metrics.Prometheus))
negroni.Use(metricsMiddlewareBackend)
}
}
if len(frontend.BasicAuth) > 0 {
users := types.Users{}
for _, user := range frontend.BasicAuth {
users = append(users, user)
} }
auth := &types.Auth{}
if server.globalConfiguration.Web != nil && server.globalConfiguration.Web.Metrics != nil { auth.Basic = &types.Basic{
if server.globalConfiguration.Web.Metrics.Prometheus != nil { Users: users,
metricsMiddlewareBackend := middlewares.NewMetricsWrapper(middlewares.NewPrometheus(frontend.Backend, server.globalConfiguration.Web.Metrics.Prometheus))
negroni.Use(metricsMiddlewareBackend)
}
} }
if len(frontend.BasicAuth) > 0 { authMiddleware, err := middlewares.NewAuthenticator(auth)
users := types.Users{} if err != nil {
for _, user := range frontend.BasicAuth { log.Fatal("Error creating Auth: ", err)
users = append(users, user)
}
auth := &types.Auth{}
auth.Basic = &types.Basic{
Users: users,
}
authMiddleware, err := middlewares.NewAuthenticator(auth)
if err != nil {
log.Fatal("Error creating Auth: ", err)
}
negroni.Use(authMiddleware)
} if configuration.Backends[frontend.Backend].CircuitBreaker != nil {
log.Debugf("Creating circuit breaker %s", configuration.Backends[frontend.Backend].CircuitBreaker.Expression)
cbreaker, err := middlewares.NewCircuitBreaker(lb, configuration.Backends[frontend.Backend].CircuitBreaker.Expression, cbreaker.Logger(oxyLogger))
if err != nil {
log.Errorf("Error creating circuit breaker: %v", err)
log.Errorf("Skipping frontend %s...", frontendName)
continue frontend
}
negroni.Use(cbreaker)
} else {
negroni.UseHandler(lb)
} }
backends[frontend.Backend] = negroni negroni.Use(authMiddleware)
}
if configuration.Backends[frontend.Backend].CircuitBreaker != nil {
log.Debugf("Creating circuit breaker %s", configuration.Backends[frontend.Backend].CircuitBreaker.Expression)
cbreaker, err := middlewares.NewCircuitBreaker(lb, configuration.Backends[frontend.Backend].CircuitBreaker.Expression, cbreaker.Logger(oxyLogger))
if err != nil {
log.Errorf("Error creating circuit breaker: %v", err)
log.Errorf("Skipping frontend %s...", frontendName)
continue frontend
}
negroni.Use(cbreaker)
} else { } else {
log.Debugf("Reusing backend %s", frontend.Backend) negroni.UseHandler(lb)
} }
if frontend.Priority > 0 { backends[entryPointName+frontend.Backend] = negroni
newServerRoute.route.Priority(frontend.Priority) } else {
} log.Debugf("Reusing backend %s", frontend.Backend)
server.wireFrontendBackend(newServerRoute, backends[frontend.Backend]) }
if frontend.Priority > 0 {
newServerRoute.route.Priority(frontend.Priority)
}
server.wireFrontendBackend(newServerRoute, backends[entryPointName+frontend.Backend])
err := newServerRoute.route.GetError() err := newServerRoute.route.GetError()
if err != nil { if err != nil {