Merge v2.10 into v3.0

This commit is contained in:
romain 2023-11-29 12:20:57 +01:00
commit e29a142f6a
118 changed files with 1324 additions and 1290 deletions

View file

@ -267,7 +267,7 @@ func TestListenProvidersThrottleProviderConfigReload(t *testing.T) {
providerAggregator := aggregator.ProviderAggregator{}
err := providerAggregator.AddProvider(pvd)
assert.Nil(t, err)
assert.NoError(t, err)
watcher := NewConfigurationWatcher(routinesPool, providerAggregator, []string{}, "")
@ -342,7 +342,7 @@ func TestListenProvidersSkipsSameConfigurationForProvider(t *testing.T) {
// give some time so that the configuration can be processed
time.Sleep(100 * time.Millisecond)
assert.Equal(t, configurationReloads, 1, "Same configuration should not be published multiple times")
assert.Equal(t, 1, configurationReloads, "Same configuration should not be published multiple times")
}
func TestListenProvidersDoesNotSkipFlappingConfiguration(t *testing.T) {
@ -450,7 +450,7 @@ func TestListenProvidersIgnoreSameConfig(t *testing.T) {
providerAggregator := aggregator.ProviderAggregator{}
err := providerAggregator.AddProvider(pvd)
assert.Nil(t, err)
assert.NoError(t, err)
watcher := NewConfigurationWatcher(routinesPool, providerAggregator, []string{"defaultEP"}, "")
@ -593,7 +593,7 @@ func TestListenProvidersIgnoreIntermediateConfigs(t *testing.T) {
providerAggregator := aggregator.ProviderAggregator{}
err := providerAggregator.AddProvider(pvd)
assert.Nil(t, err)
assert.NoError(t, err)
watcher := NewConfigurationWatcher(routinesPool, providerAggregator, []string{"defaultEP"}, "")

View file

@ -12,6 +12,7 @@ import (
"github.com/traefik/traefik/v3/pkg/logs"
"github.com/traefik/traefik/v3/pkg/metrics"
"github.com/traefik/traefik/v3/pkg/middlewares/accesslog"
"github.com/traefik/traefik/v3/pkg/middlewares/denyrouterrecursion"
metricsMiddle "github.com/traefik/traefik/v3/pkg/middlewares/metrics"
"github.com/traefik/traefik/v3/pkg/middlewares/recovery"
"github.com/traefik/traefik/v3/pkg/middlewares/tracing"
@ -207,6 +208,10 @@ func (m *Manager) buildHTTPHandler(ctx context.Context, router *runtime.RouterIn
chain = chain.Append(metricsMiddle.WrapRouterHandler(ctx, m.metricsRegistry, routerName, provider.GetQualifiedName(ctx, router.Service)))
}
if router.DefaultRule {
chain = chain.Append(denyrouterrecursion.WrapHandler(routerName))
}
return chain.Extend(*mHandler).Append(tHandler).Then(sHandler)
}

View file

@ -620,12 +620,12 @@ func Test_Routing(t *testing.T) {
err := check.checkRouter(epListener.Addr().String(), timeout)
if check.expectedError != "" {
require.NotNil(t, err, check.desc)
require.Error(t, err, check.desc)
assert.Contains(t, err.Error(), check.expectedError, check.desc)
continue
}
assert.Nil(t, err, check.desc)
assert.NoError(t, err, check.desc)
}
epListener.Close()

View file

@ -517,7 +517,7 @@ func (c *connectionTracker) Close() {
}
type stoppable interface {
Shutdown(context.Context) error
Shutdown(ctx context.Context) error
Close() error
}
@ -553,6 +553,7 @@ func createHTTPServer(ctx context.Context, ln net.Listener, configuration *stati
return nil, err
}
handler = denyFragment(handler)
if configuration.HTTP.EncodeQuerySemicolons {
handler = encodeQuerySemicolons(handler)
} else {
@ -640,3 +641,20 @@ func encodeQuerySemicolons(h http.Handler) http.Handler {
}
})
}
// When go receives an HTTP request, it assumes the absence of fragment URL.
// However, it is still possible to send a fragment in the request.
// In this case, Traefik will encode the '#' character, altering the request's intended meaning.
// To avoid this behavior, the following function rejects requests that include a fragment in the URL.
func denyFragment(h http.Handler) http.Handler {
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
if strings.Contains(req.URL.RawPath, "#") {
log.Debug().Msgf("Rejecting request because it contains a fragment in the URL path: %s", req.URL.RawPath)
rw.WriteHeader(http.StatusBadRequest)
return
}
h.ServeHTTP(rw, req)
})
}

View file

@ -98,7 +98,7 @@ func TestHijack(t *testing.T) {
var mirrorRequest bool
err := mirror.AddMirror(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
hijacker, ok := rw.(http.Hijacker)
assert.Equal(t, true, ok)
assert.True(t, ok)
_, _, err := hijacker.Hijack()
assert.Error(t, err)
@ -109,7 +109,7 @@ func TestHijack(t *testing.T) {
mirror.ServeHTTP(httptest.NewRecorder(), httptest.NewRequest(http.MethodGet, "/", nil))
pool.Stop()
assert.Equal(t, true, mirrorRequest)
assert.True(t, mirrorRequest)
}
func TestFlush(t *testing.T) {
@ -122,7 +122,7 @@ func TestFlush(t *testing.T) {
var mirrorRequest bool
err := mirror.AddMirror(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
hijacker, ok := rw.(http.Flusher)
assert.Equal(t, true, ok)
assert.True(t, ok)
hijacker.Flush()
@ -133,7 +133,7 @@ func TestFlush(t *testing.T) {
mirror.ServeHTTP(httptest.NewRecorder(), httptest.NewRequest(http.MethodGet, "/", nil))
pool.Stop()
assert.Equal(t, true, mirrorRequest)
assert.True(t, mirrorRequest)
}
func TestMirroringWithBody(t *testing.T) {
@ -233,7 +233,7 @@ func TestCloneRequest(t *testing.T) {
_, expectedBytes, err := newReusableRequest(req, 2)
assert.Error(t, err)
assert.Equal(t, bb[:3], expectedBytes)
assert.Equal(t, expectedBytes, bb[:3])
})
t.Run("valid case with maxBodySize", func(t *testing.T) {
@ -258,7 +258,7 @@ func TestCloneRequest(t *testing.T) {
rr, expectedBytes, err := newReusableRequest(req, 20)
assert.NoError(t, err)
assert.Nil(t, expectedBytes)
assert.Len(t, rr.body, 0)
assert.Empty(t, rr.body)
})
t.Run("no request given", func(t *testing.T) {

View file

@ -256,8 +256,8 @@ func TestSticky(t *testing.T) {
assert.Equal(t, 0, recorder.save["first"])
assert.Equal(t, 3, recorder.save["second"])
assert.Equal(t, true, recorder.cookies["test"].HttpOnly)
assert.Equal(t, true, recorder.cookies["test"].Secure)
assert.True(t, recorder.cookies["test"].HttpOnly)
assert.True(t, recorder.cookies["test"].Secure)
assert.Equal(t, http.SameSiteNoneMode, recorder.cookies["test"].SameSite)
}

View file

@ -51,7 +51,7 @@ func TestWebSocketTCPClose(t *testing.T) {
serverErr := <-errChan
var wsErr *gorillawebsocket.CloseError
require.True(t, errors.As(serverErr, &wsErr))
require.ErrorAs(t, serverErr, &wsErr)
assert.Equal(t, 1006, wsErr.Code)
}

View file

@ -2,6 +2,7 @@ package service
import (
"context"
"encoding/hex"
"errors"
"fmt"
"hash/fnv"
@ -287,7 +288,7 @@ func (m *Manager) getLoadBalancerServiceHandler(ctx context.Context, serviceName
hasher := fnv.New64a()
_, _ = hasher.Write([]byte(server.URL)) // this will never return an error.
proxyName := fmt.Sprintf("%x", hasher.Sum(nil))
proxyName := hex.EncodeToString(hasher.Sum(nil))
target, err := url.Parse(server.URL)
if err != nil {

View file

@ -393,7 +393,7 @@ func Test1xxResponses(t *testing.T) {
}
handler, err := sm.getLoadBalancerServiceHandler(context.Background(), "foobar", info)
assert.Nil(t, err)
assert.NoError(t, err)
frontend := httptest.NewServer(handler)
t.Cleanup(frontend.Close)
@ -439,7 +439,7 @@ func Test1xxResponses(t *testing.T) {
req, _ := http.NewRequestWithContext(httptrace.WithClientTrace(context.Background(), trace), http.MethodGet, frontend.URL, nil)
res, err := frontendClient.Do(req)
assert.Nil(t, err)
assert.NoError(t, err)
defer res.Body.Close()