func new(c *C, p string) (*roundrobin.RoundRobin, *Streamer) { logger := utils.NewFileLogger(os.Stdout, utils.INFO) // forwarder will proxy the request to whatever destination fwd, err := forward.New(forward.Logger(logger)) c.Assert(err, IsNil) // load balancer will round robin request lb, err := roundrobin.New(fwd) c.Assert(err, IsNil) // stream handler will forward requests to redirect, make sure it uses files st, err := New(lb, Logger(logger), Retry(p), MemRequestBodyBytes(1)) c.Assert(err, IsNil) return lb, st }
func (f *frontend) rebuild() error { settings := f.frontend.HTTPSettings() // set up forwarder fwd, err := forward.New( forward.Logger(f.log), forward.RoundTripper(f.backend.transport), forward.Rewriter( &forward.HeaderRewriter{ Hostname: settings.Hostname, TrustForwardHeader: settings.TrustForwardHeader, }), forward.PassHostHeader(settings.PassHostHeader)) // rtwatcher will be observing and aggregating metrics watcher, err := NewWatcher(fwd) if err != nil { return err } // Create a load balancer rr, err := roundrobin.New(watcher) if err != nil { return err } // Rebalancer will readjust load balancer weights based on error ratios rb, err := roundrobin.NewRebalancer(rr, roundrobin.RebalancerLogger(f.log)) if err != nil { return err } // create middlewares sorted by priority and chain them middlewares := f.sortedMiddlewares() handlers := make([]http.Handler, len(middlewares)) for i, m := range middlewares { var prev http.Handler if i == 0 { prev = rb } else { prev = handlers[i-1] } h, err := m.Middleware.NewHandler(prev) if err != nil { return err } handlers[i] = h } var next http.Handler if len(handlers) != 0 { next = handlers[len(handlers)-1] } else { next = rb } // stream will retry and replay requests, fix encodings if settings.FailoverPredicate == "" { settings.FailoverPredicate = `IsNetworkError() && RequestMethod() == "GET" && Attempts() < 2` } str, err := stream.New(next, stream.Logger(f.log), stream.Retry(settings.FailoverPredicate), stream.MaxRequestBodyBytes(settings.Limits.MaxBodyBytes), stream.MemRequestBodyBytes(settings.Limits.MaxMemBodyBytes)) if err != nil { return err } if err := syncServers(f.mux, rb, f.backend, watcher); err != nil { return err } // Add the frontend to the router if err := f.mux.router.Handle(f.frontend.Route, str); err != nil { return err } f.lb = rb f.handler = str f.watcher = watcher return nil }