1
0
Fork 0

Merge remote-tracking branch 'upstream/v2.2' into mrg-current-v2.2

This commit is contained in:
jb doumenjou 2020-07-10 10:46:11 +02:00
commit 73ca7ad0c1
156 changed files with 1768 additions and 892 deletions

View file

@ -9,9 +9,7 @@ import (
"github.com/containous/traefik/v2/pkg/middlewares"
)
var (
_ middlewares.Stateful = &captureResponseWriterWithCloseNotify{}
)
var _ middlewares.Stateful = &captureResponseWriterWithCloseNotify{}
type capturer interface {
http.ResponseWriter

View file

@ -19,7 +19,7 @@ type FieldHandler struct {
}
// NewFieldHandler creates a Field handler.
func NewFieldHandler(next http.Handler, name string, value string, applyFn FieldApply) http.Handler {
func NewFieldHandler(next http.Handler, name, value string, applyFn FieldApply) http.Handler {
return &FieldHandler{next: next, name: name, value: value, applyFn: applyFn}
}

View file

@ -131,11 +131,11 @@ func NewHandler(config *types.AccessLog) (*Handler, error) {
func openAccessLogFile(filePath string) (*os.File, error) {
dir := filepath.Dir(filePath)
if err := os.MkdirAll(dir, 0755); err != nil {
if err := os.MkdirAll(dir, 0o755); err != nil {
return nil, fmt.Errorf("failed to create log path %s: %w", dir, err)
}
file, err := os.OpenFile(filePath, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0664)
file, err := os.OpenFile(filePath, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0o664)
if err != nil {
return nil, fmt.Errorf("error opening file %s: %w", filePath, err)
}
@ -249,7 +249,7 @@ func (h *Handler) Rotate() error {
}
var err error
h.file, err = os.OpenFile(h.config.FilePath, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0664)
h.file, err = os.OpenFile(h.config.FilePath, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0o664)
if err != nil {
return err
}
@ -259,7 +259,7 @@ func (h *Handler) Rotate() error {
return nil
}
func silentSplitHostPort(value string) (host string, port string) {
func silentSplitHostPort(value string) (host, port string) {
host, port, err := net.SplitHostPort(value)
if err != nil {
return value, "-"

View file

@ -21,7 +21,7 @@ type CommonLogFormatter struct{}
func (f *CommonLogFormatter) Format(entry *logrus.Entry) ([]byte, error) {
b := &bytes.Buffer{}
var timestamp = defaultValue
timestamp := defaultValue
if v, ok := entry.Data[StartUTC]; ok {
timestamp = v.(time.Time).Format(commonLogTimeFormat)
} else if v, ok := entry.Data[StartLocal]; ok {
@ -52,7 +52,7 @@ func (f *CommonLogFormatter) Format(entry *logrus.Entry) ([]byte, error) {
return b.Bytes(), err
}
func toLog(fields logrus.Fields, key string, defaultValue string, quoted bool) interface{} {
func toLog(fields logrus.Fields, key, defaultValue string, quoted bool) interface{} {
if v, ok := fields[key]; ok {
if v == nil {
return defaultValue
@ -73,7 +73,7 @@ func toLog(fields logrus.Fields, key string, defaultValue string, quoted bool) i
return defaultValue
}
func toLogEntry(s string, defaultValue string, quote bool) string {
func toLogEntry(s, defaultValue string, quote bool) string {
if len(s) == 0 {
return defaultValue
}

View file

@ -62,29 +62,39 @@ func (b *basicAuth) GetTracingInformation() (string, ext.SpanKindEnum) {
func (b *basicAuth) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
logger := log.FromContext(middlewares.GetLoggerCtx(req.Context(), b.name, basicTypeName))
if username := b.auth.CheckAuth(req); username == "" {
user, password, ok := req.BasicAuth()
if ok {
secret := b.auth.Secrets(user, b.auth.Realm)
if secret == "" || !goauth.CheckSecret(password, secret) {
ok = false
}
}
logData := accesslog.GetLogData(req)
if logData != nil {
logData.Core[accesslog.ClientUsername] = user
}
if !ok {
logger.Debug("Authentication failed")
tracing.SetErrorWithEvent(req, "Authentication failed")
b.auth.RequireAuth(rw, req)
} else {
logger.Debug("Authentication succeeded")
req.URL.User = url.User(username)
logData := accesslog.GetLogData(req)
if logData != nil {
logData.Core[accesslog.ClientUsername] = username
}
if b.headerField != "" {
req.Header[b.headerField] = []string{username}
}
if b.removeHeader {
logger.Debug("Removing authorization header")
req.Header.Del(authorizationHeader)
}
b.next.ServeHTTP(rw, req)
return
}
logger.Debug("Authentication succeeded")
req.URL.User = url.User(user)
if b.headerField != "" {
req.Header[b.headerField] = []string{user}
}
if b.removeHeader {
logger.Debug("Removing authorization header")
req.Header.Del(authorizationHeader)
}
b.next.ServeHTTP(rw, req)
}
func (b *basicAuth) secretBasic(user, realm string) string {

View file

@ -63,6 +63,19 @@ func (d *digestAuth) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
username, authinfo := d.auth.CheckAuth(req)
if username == "" {
headerField := d.headerField
if d.headerField == "" {
headerField = "Authorization"
}
auth := goauth.DigestAuthParams(req.Header.Get(headerField))
if auth["username"] != "" {
logData := accesslog.GetLogData(req)
if logData != nil {
logData.Core[accesslog.ClientUsername] = auth["username"]
}
}
if authinfo != nil && *authinfo == "stale" {
logger.Debug("Digest authentication failed, possibly because out of order requests")
tracing.SetErrorWithEvent(req, "Digest authentication failed, possibly because out of order requests")

View file

@ -158,7 +158,7 @@ func (fa *forwardAuth) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
fa.next.ServeHTTP(rw, req)
}
func writeHeader(req *http.Request, forwardReq *http.Request, trustForwardHeader bool) {
func writeHeader(req, forwardReq *http.Request, trustForwardHeader bool) {
utils.CopyHeaders(forwardReq.Header, req.Header)
utils.RemoveHeaders(forwardReq.Header, forward.HopHeaders...)

View file

@ -325,7 +325,8 @@ func Test_writeHeader(t *testing.T) {
"X-Forwarded-Host": "foo.bar",
"X-Forwarded-Uri": "/path?q=1",
},
}, {
},
{
name: "trust Forward Header with forwarded request Method",
headers: map[string]string{
"X-Forwarded-Method": "OPTIONS",

View file

@ -246,7 +246,8 @@ func TestServeHTTP(t *testing.T) {
expectedHeaders: map[string]string{
xForwardedHost: "foo.com:8080",
},
}, {
},
{
desc: "xForwardedServer from req XForwarded",
host: "foo.com:8080",
expectedHeaders: map[string]string{

View file

@ -54,13 +54,13 @@ func New(ctx context.Context, next http.Handler, cfg dynamic.Headers, name strin
nextHandler := next
if hasSecureHeaders {
logger.Debug("Setting up secureHeaders from %v", cfg)
logger.Debugf("Setting up secureHeaders from %v", cfg)
handler = newSecure(next, cfg, name)
nextHandler = handler
}
if hasCustomHeaders || hasCorsHeaders {
logger.Debug("Setting up customHeaders/Cors from %v", cfg)
logger.Debugf("Setting up customHeaders/Cors from %v", cfg)
handler = NewHeader(nextHandler, cfg)
}

View file

@ -552,7 +552,8 @@ func TestCORSResponses(t *testing.T) {
expected: map[string][]string{
"Access-Control-Allow-Origin": {"*"},
},
}, {
},
{
desc: "Test Simple CustomRequestHeaders Not Hijacked by CORS",
header: NewHeader(emptyHandler, dynamic.Headers{
CustomRequestHeaders: map[string]string{"foo": "bar"},

View file

@ -7,6 +7,6 @@ import (
)
// GetLoggerCtx creates a logger context with the middleware fields.
func GetLoggerCtx(ctx context.Context, middleware string, middlewareType string) context.Context {
func GetLoggerCtx(ctx context.Context, middleware, middlewareType string) context.Context {
return log.With(ctx, log.Str(log.MiddlewareName, middleware), log.Str(log.MiddlewareType, middlewareType))
}

View file

@ -235,7 +235,7 @@ func writeParts(ctx context.Context, content io.StringWriter, entries []string,
}
}
func writePart(ctx context.Context, content io.StringWriter, entry string, prefix string) {
func writePart(ctx context.Context, content io.StringWriter, entry, prefix string) {
if len(entry) > 0 {
_, err := content.WriteString(fmt.Sprintf("%s=%s%s", prefix, entry, subFieldSeparator))
if err != nil {

View file

@ -24,7 +24,7 @@ type redirect struct {
}
// New creates a Redirect middleware.
func newRedirect(next http.Handler, regex string, replacement string, permanent bool, name string) (http.Handler, error) {
func newRedirect(next http.Handler, regex, replacement string, permanent bool, name string) (http.Handler, error) {
re, err := regexp.Compile(regex)
if err != nil {
return nil, err
@ -115,7 +115,7 @@ func rawURL(req *http.Request) string {
port := ""
uri := req.RequestURI
schemeRegex := `^(https?):\/\/([\w\._-]+)(:\d+)?(.*)$`
schemeRegex := `^(https?):\/\/(\[[\w:.]+\]|[\w\._-]+)?(:\d+)?(.*)$`
re, _ := regexp.Compile(schemeRegex)
if re.Match([]byte(req.RequestURI)) {
match := re.FindStringSubmatch(req.RequestURI)

View file

@ -12,7 +12,7 @@ import (
const (
typeSchemeName = "RedirectScheme"
schemeRedirectRegex = `^(https?:\/\/)?([\w\._-]+)(:\d+)?(.*)$`
schemeRedirectRegex = `^(https?:\/\/)?(\[[\w:.]+\]|[\w\._-]+)?(:\d+)?(.*)$`
)
// NewRedirectScheme creates a new RedirectScheme middleware.

View file

@ -186,6 +186,44 @@ func TestRedirectSchemeHandler(t *testing.T) {
expectedURL: "https://foo",
expectedStatus: http.StatusFound,
},
{
desc: "IPV6 HTTP to HTTPS redirection without port",
config: dynamic.RedirectScheme{
Scheme: "https",
},
url: "http://[::1]",
expectedURL: "https://[::1]",
expectedStatus: http.StatusFound,
},
{
desc: "IPV6 HTTP to HTTPS redirection with port",
config: dynamic.RedirectScheme{
Scheme: "https",
Port: "8443",
},
url: "http://[::1]",
expectedURL: "https://[::1]:8443",
expectedStatus: http.StatusFound,
},
{
desc: "IPV6 HTTP with port 80 to HTTPS redirection without port",
config: dynamic.RedirectScheme{
Scheme: "https",
},
url: "http://[::1]:80",
expectedURL: "https://[::1]",
expectedStatus: http.StatusFound,
},
{
desc: "IPV6 HTTP with port 80 to HTTPS redirection with port",
config: dynamic.RedirectScheme{
Scheme: "https",
Port: "8443",
},
url: "http://[::1]:80",
expectedURL: "https://[::1]:8443",
expectedStatus: http.StatusFound,
},
}
for _, test := range testCases {
@ -235,7 +273,7 @@ func TestRedirectSchemeHandler(t *testing.T) {
require.Errorf(t, err, "Location %v", location)
}
schemeRegex := `^(https?):\/\/([\w\._-]+)(:\d+)?(.*)$`
schemeRegex := `^(https?):\/\/(\[[\w:.]+\]|[\w\._-]+)?(:\d+)?(.*)$`
re, _ := regexp.Compile(schemeRegex)
if re.Match([]byte(test.url)) {

View file

@ -47,7 +47,7 @@ func (hr *Resolver) CNAMEFlatten(ctx context.Context, host string) string {
}
logger := log.FromContext(ctx)
var cacheDuration = 0 * time.Second
cacheDuration := 0 * time.Second
for depth := 0; depth < hr.ResolvDepth; depth++ {
resolv, err := cnameResolve(ctx, request, hr.ResolvConfig)
if err != nil {
@ -73,7 +73,7 @@ func (hr *Resolver) CNAMEFlatten(ctx context.Context, host string) string {
}
// cnameResolve resolves CNAME if exists, and return with the highest TTL.
func cnameResolve(ctx context.Context, host string, resolvPath string) (*cnameResolv, error) {
func cnameResolve(ctx context.Context, host, resolvPath string) (*cnameResolv, error) {
config, err := dns.ClientConfigFromFile(resolvPath)
if err != nil {
return nil, fmt.Errorf("invalid resolver configuration file: %s", resolvPath)
@ -102,7 +102,7 @@ func cnameResolve(ctx context.Context, host string, resolvPath string) (*cnameRe
return result[0], nil
}
func getRecord(client *dns.Client, msg *dns.Msg, server string, port string) (*cnameResolv, error) {
func getRecord(client *dns.Client, msg *dns.Msg, server, port string) (*cnameResolv, error) {
resp, _, err := client.Exchange(msg, net.JoinHostPort(server, port))
if err != nil {
return nil, fmt.Errorf("exchange error for server %s: %w", server, err)

View file

@ -45,7 +45,8 @@ func TestNewForwarder(t *testing.T) {
},
OperationName: "forward some-service.domain.tld/some-service.domain.tld",
},
}, {
},
{
desc: "Simple Forward Tracer with truncation and hashing",
spanNameLimit: 101,
tracing: &trackingBackenMock{

View file

@ -18,12 +18,12 @@ func (n MockTracer) StartSpan(operationName string, opts ...opentracing.StartSpa
}
// Inject belongs to the Tracer interface.
func (n MockTracer) Inject(sp opentracing.SpanContext, format interface{}, carrier interface{}) error {
func (n MockTracer) Inject(sp opentracing.SpanContext, format, carrier interface{}) error {
return nil
}
// Extract belongs to the Tracer interface.
func (n MockTracer) Extract(format interface{}, carrier interface{}) (opentracing.SpanContext, error) {
func (n MockTracer) Extract(format, carrier interface{}) (opentracing.SpanContext, error) {
return nil, opentracing.ErrSpanContextNotFound
}