From e7a73d3fb32fb89b8b03bf805854641fd2c48ab1 Mon Sep 17 00:00:00 2001 From: Emile Vauge Date: Thu, 13 Apr 2017 16:37:07 +0200 Subject: [PATCH] Fix too many redirect Signed-off-by: Emile Vauge --- server/server.go | 218 +++++++++++++++++++++++------------------------ 1 file changed, 108 insertions(+), 110 deletions(-) diff --git a/server/server.go b/server/server.go index 51479cb36..da99e366d 100644 --- a/server/server.go +++ b/server/server.go @@ -549,12 +549,10 @@ func (server *Server) buildEntryPoints(globalConfiguration GlobalConfiguration) func (server *Server) loadConfig(configurations configs, globalConfiguration GlobalConfiguration) (map[string]*serverEntryPoint, error) { serverEntryPoints := server.buildEntryPoints(globalConfiguration) redirectHandlers := make(map[string]negroni.Handler) - backends := map[string]http.Handler{} - backendsHealthcheck := map[string]*healthcheck.BackendHealthCheck{} - backend2FrontendMap := map[string]string{} + for _, configuration := range configurations { frontendNames := sortedFrontendNamesForConfig(configuration) frontend: @@ -609,7 +607,7 @@ func (server *Server) loadConfig(configurations configs, globalConfiguration Glo redirectHandlers[entryPointName] = handler } } - if backends[frontend.Backend] == nil { + if backends[entryPointName+frontend.Backend] == nil { log.Debugf("Creating backend %s", frontend.Backend) var lb http.Handler rr, _ := roundrobin.New(saveBackend) @@ -634,131 +632,131 @@ func (server *Server) loadConfig(configurations configs, globalConfiguration Glo sticky = roundrobin.NewStickySession(cookiename) } - switch lbMethod { - case types.Drr: - log.Debugf("Creating load-balancer drr") - rebalancer, _ := roundrobin.NewRebalancer(rr, roundrobin.RebalancerLogger(oxyLogger)) - if stickysession { - log.Debugf("Sticky session with cookie %v", cookiename) - rebalancer, _ = roundrobin.NewRebalancer(rr, roundrobin.RebalancerLogger(oxyLogger), roundrobin.RebalancerStickySession(sticky)) + switch lbMethod { + case types.Drr: + log.Debugf("Creating load-balancer drr") + rebalancer, _ := roundrobin.NewRebalancer(rr, roundrobin.RebalancerLogger(oxyLogger)) + if stickysession { + log.Debugf("Sticky session with cookie %v", cookiename) + 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 - 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 := 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) - } + 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 } - case types.Wrr: - log.Debugf("Creating load-balancer wrr") - 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 { - 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) + 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) } } - maxConns := configuration.Backends[frontend.Backend].MaxConn - if maxConns != nil && maxConns.Amount != 0 { - extractFunc, err := utils.NewExtractor(maxConns.ExtractorFunc) + case types.Wrr: + log.Debugf("Creating load-balancer wrr") + 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 { - log.Errorf("Error creating connlimit: %v", err) + log.Errorf("Error parsing server URL %s: %v", server.URL, 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) + 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 } } - // 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) + 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) + } + } + maxConns := configuration.Backends[frontend.Backend].MaxConn + 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) } - - 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) - } + auth := &types.Auth{} + auth.Basic = &types.Basic{ + Users: users, } - if len(frontend.BasicAuth) > 0 { - users := types.Users{} - for _, user := range frontend.BasicAuth { - 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) + authMiddleware, err := middlewares.NewAuthenticator(auth) + if err != nil { + log.Fatal("Error creating Auth: ", err) } - 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 { - log.Debugf("Reusing backend %s", frontend.Backend) + negroni.UseHandler(lb) } - if frontend.Priority > 0 { - newServerRoute.route.Priority(frontend.Priority) - } - server.wireFrontendBackend(newServerRoute, backends[frontend.Backend]) + backends[entryPointName+frontend.Backend] = negroni + } else { + log.Debugf("Reusing backend %s", frontend.Backend) + } + if frontend.Priority > 0 { + newServerRoute.route.Priority(frontend.Priority) + } + server.wireFrontendBackend(newServerRoute, backends[entryPointName+frontend.Backend]) err := newServerRoute.route.GetError() if err != nil {