Merge 'v1.4.0' into master

This commit is contained in:
Fernandez Ludovic 2017-10-16 23:10:44 +02:00
commit 7192aa86b5
38 changed files with 1165 additions and 327 deletions

51
server/header_rewriter.go Normal file
View file

@ -0,0 +1,51 @@
package server
import (
"net"
"net/http"
"os"
"github.com/containous/traefik/whitelist"
"github.com/vulcand/oxy/forward"
)
// NewHeaderRewriter Create a header rewriter
func NewHeaderRewriter(trustedIPs []string, insecure bool) (forward.ReqRewriter, error) {
IPs, err := whitelist.NewIP(trustedIPs, insecure)
if err != nil {
return nil, err
}
h, err := os.Hostname()
if err != nil {
h = "localhost"
}
return &headerRewriter{
secureRewriter: &forward.HeaderRewriter{TrustForwardHeader: true, Hostname: h},
insecureRewriter: &forward.HeaderRewriter{TrustForwardHeader: false, Hostname: h},
ips: IPs,
insecure: insecure,
}, nil
}
type headerRewriter struct {
secureRewriter forward.ReqRewriter
insecureRewriter forward.ReqRewriter
insecure bool
ips *whitelist.IP
}
func (h *headerRewriter) Rewrite(req *http.Request) {
clientIP, _, err := net.SplitHostPort(req.RemoteAddr)
if err != nil {
h.secureRewriter.Rewrite(req)
}
authorized, _, err := h.ips.Contains(clientIP)
if h.insecure || authorized {
h.secureRewriter.Rewrite(req)
} else {
h.insecureRewriter.Rewrite(req)
}
}

View file

@ -656,7 +656,7 @@ func (server *Server) prepareServer(entryPointName string, entryPoint *configura
}
if entryPoint.ProxyProtocol != nil {
IPs, err := whitelist.NewIP(entryPoint.ProxyProtocol.TrustedIPs)
IPs, err := whitelist.NewIP(entryPoint.ProxyProtocol.TrustedIPs, entryPoint.ProxyProtocol.Insecure)
if err != nil {
return nil, nil, fmt.Errorf("Error creating whitelist: %s", err)
}
@ -807,11 +807,19 @@ func (server *Server) loadConfig(configurations types.Configurations, globalConf
continue frontend
}
rewriter, err := NewHeaderRewriter(entryPoint.ForwardedHeaders.TrustedIPs, entryPoint.ForwardedHeaders.Insecure)
if err != nil {
log.Errorf("Error creating rewriter for frontend %s: %v", frontendName, err)
log.Errorf("Skipping frontend %s...", frontendName)
continue frontend
}
fwd, err := forward.New(
forward.Logger(oxyLogger),
forward.PassHostHeader(frontend.PassHostHeader),
forward.RoundTripper(roundTripper),
forward.ErrorHandler(errorHandler),
forward.Rewriter(rewriter),
)
if err != nil {
@ -1174,27 +1182,32 @@ func (server *Server) configureFrontends(frontends map[string]*types.Frontend) {
}
func (*Server) configureBackends(backends map[string]*types.Backend) {
for backendName, backend := range backends {
for backendName := range backends {
backend := backends[backendName]
if backend.LoadBalancer != nil && backend.LoadBalancer.Sticky {
log.Warn("Deprecated configuration found: %s. Please use %s.", "backend.LoadBalancer.Sticky", "backend.LoadBalancer.Stickiness")
log.Warnf("Deprecated configuration found: %s. Please use %s.", "backend.LoadBalancer.Sticky", "backend.LoadBalancer.Stickiness")
}
_, err := types.NewLoadBalancerMethod(backend.LoadBalancer)
if err == nil {
if backend.LoadBalancer != nil && backend.LoadBalancer.Stickiness == nil && backend.LoadBalancer.Sticky {
backend.LoadBalancer.Stickiness = &types.Stickiness{}
backend.LoadBalancer.Stickiness = &types.Stickiness{
CookieName: "_TRAEFIK_BACKEND",
}
}
} else {
log.Debugf("Validation of load balancer method for backend %s failed: %s. Using default method wrr.", backendName, err)
var stickiness *types.Stickiness
if backend.LoadBalancer != nil {
if backend.LoadBalancer.Stickiness != nil {
stickiness = backend.LoadBalancer.Stickiness
} else if backend.LoadBalancer.Sticky {
if backend.LoadBalancer.Stickiness == nil {
stickiness = &types.Stickiness{}
if backend.LoadBalancer.Stickiness == nil {
if backend.LoadBalancer.Sticky {
stickiness = &types.Stickiness{
CookieName: "_TRAEFIK_BACKEND",
}
}
} else {
stickiness = backend.LoadBalancer.Stickiness
}
}
backend.LoadBalancer = &types.LoadBalancer{

View file

@ -96,7 +96,10 @@ func TestPrepareServerTimeouts(t *testing.T) {
t.Parallel()
entryPointName := "http"
entryPoint := &configuration.EntryPoint{Address: "localhost:0"}
entryPoint := &configuration.EntryPoint{
Address: "localhost:0",
ForwardedHeaders: &configuration.ForwardedHeaders{Insecure: true},
}
router := middlewares.NewHandlerSwitcher(mux.NewRouter())
srv := NewServer(test.globalConfig)
@ -210,7 +213,9 @@ func TestServerLoadConfigHealthCheckOptions(t *testing.T) {
t.Run(fmt.Sprintf("%s/hc=%t", lbMethod, healthCheck != nil), func(t *testing.T) {
globalConfig := configuration.GlobalConfiguration{
EntryPoints: configuration.EntryPoints{
"http": &configuration.EntryPoint{},
"http": &configuration.EntryPoint{
ForwardedHeaders: &configuration.ForwardedHeaders{Insecure: true},
},
},
HealthCheck: &configuration.HealthCheckConfig{Interval: flaeg.Duration(5 * time.Second)},
}
@ -383,7 +388,7 @@ func TestNewServerWithWhitelistSourceRange(t *testing.T) {
func TestServerLoadConfigEmptyBasicAuth(t *testing.T) {
globalConfig := configuration.GlobalConfiguration{
EntryPoints: configuration.EntryPoints{
"http": &configuration.EntryPoint{},
"http": &configuration.EntryPoint{ForwardedHeaders: &configuration.ForwardedHeaders{Insecure: true}},
},
}
@ -492,7 +497,7 @@ func TestConfigureBackends(t *testing.T) {
}
}
func TestServerEntrypointWhitelistConfig(t *testing.T) {
func TestServerEntryPointWhitelistConfig(t *testing.T) {
tests := []struct {
desc string
entrypoint *configuration.EntryPoint
@ -501,7 +506,8 @@ func TestServerEntrypointWhitelistConfig(t *testing.T) {
{
desc: "no whitelist middleware if no config on entrypoint",
entrypoint: &configuration.EntryPoint{
Address: ":0",
Address: ":0",
ForwardedHeaders: &configuration.ForwardedHeaders{Insecure: true},
},
wantMiddleware: false,
},
@ -512,6 +518,7 @@ func TestServerEntrypointWhitelistConfig(t *testing.T) {
WhitelistSourceRange: []string{
"127.0.0.1/32",
},
ForwardedHeaders: &configuration.ForwardedHeaders{Insecure: true},
},
wantMiddleware: true,
},
@ -633,7 +640,7 @@ func TestServerResponseEmptyBackend(t *testing.T) {
globalConfig := configuration.GlobalConfiguration{
EntryPoints: configuration.EntryPoints{
"http": &configuration.EntryPoint{},
"http": &configuration.EntryPoint{ForwardedHeaders: &configuration.ForwardedHeaders{Insecure: true}},
},
}
dynamicConfigs := types.Configurations{"config": test.dynamicConfig(testServer.URL)}