Merge branch v3.2 into master
This commit is contained in:
commit
090db6d4b0
76 changed files with 1823 additions and 1016 deletions
|
@ -3,7 +3,7 @@ package dashboard
|
|||
import (
|
||||
"io/fs"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/traefik/traefik/v3/webui"
|
||||
|
@ -25,7 +25,8 @@ func Append(router *mux.Router, customAssets fs.FS) {
|
|||
router.Methods(http.MethodGet).
|
||||
Path("/").
|
||||
HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
|
||||
http.Redirect(resp, req, safePrefix(req)+"/dashboard/", http.StatusFound)
|
||||
prefix := strings.TrimSuffix(req.Header.Get("X-Forwarded-Prefix"), "/")
|
||||
http.Redirect(resp, req, prefix+"/dashboard/", http.StatusFound)
|
||||
})
|
||||
|
||||
router.Methods(http.MethodGet).
|
||||
|
@ -58,21 +59,3 @@ func (g Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
http.FileServerFS(assets).ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
func safePrefix(req *http.Request) string {
|
||||
prefix := req.Header.Get("X-Forwarded-Prefix")
|
||||
if prefix == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
parse, err := url.Parse(prefix)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
if parse.Host != "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
return parse.Path
|
||||
}
|
||||
|
|
|
@ -10,53 +10,8 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func Test_safePrefix(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
value string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
desc: "host",
|
||||
value: "https://example.com",
|
||||
expected: "",
|
||||
},
|
||||
{
|
||||
desc: "host with path",
|
||||
value: "https://example.com/foo/bar?test",
|
||||
expected: "",
|
||||
},
|
||||
{
|
||||
desc: "path",
|
||||
value: "/foo/bar",
|
||||
expected: "/foo/bar",
|
||||
},
|
||||
{
|
||||
desc: "path without leading slash",
|
||||
value: "foo/bar",
|
||||
expected: "foo/bar",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
req, err := http.NewRequest(http.MethodGet, "http://localhost", nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
req.Header.Set("X-Forwarded-Prefix", test.value)
|
||||
|
||||
prefix := safePrefix(req)
|
||||
|
||||
assert.Equal(t, test.expected, prefix)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_ContentSecurityPolicy(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
|
|
|
@ -19,7 +19,7 @@ import (
|
|||
"github.com/traefik/traefik/v3/pkg/config/static"
|
||||
)
|
||||
|
||||
func Bool(v bool) *bool { return &v }
|
||||
func pointer[T any](v T) *T { return &v }
|
||||
|
||||
func TestHandler_HTTP(t *testing.T) {
|
||||
type expected struct {
|
||||
|
@ -415,7 +415,7 @@ func TestHandler_HTTP(t *testing.T) {
|
|||
si := &runtime.ServiceInfo{
|
||||
Service: &dynamic.Service{
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1",
|
||||
|
@ -432,7 +432,7 @@ func TestHandler_HTTP(t *testing.T) {
|
|||
si := &runtime.ServiceInfo{
|
||||
Service: &dynamic.Service{
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.2",
|
||||
|
@ -501,7 +501,7 @@ func TestHandler_HTTP(t *testing.T) {
|
|||
si := &runtime.ServiceInfo{
|
||||
Service: &dynamic.Service{
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1",
|
||||
|
@ -518,7 +518,7 @@ func TestHandler_HTTP(t *testing.T) {
|
|||
si := &runtime.ServiceInfo{
|
||||
Service: &dynamic.Service{
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.2",
|
||||
|
@ -535,7 +535,7 @@ func TestHandler_HTTP(t *testing.T) {
|
|||
si := &runtime.ServiceInfo{
|
||||
Service: &dynamic.Service{
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.3",
|
||||
|
@ -565,7 +565,7 @@ func TestHandler_HTTP(t *testing.T) {
|
|||
si := &runtime.ServiceInfo{
|
||||
Service: &dynamic.Service{
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1",
|
||||
|
@ -583,7 +583,7 @@ func TestHandler_HTTP(t *testing.T) {
|
|||
si := &runtime.ServiceInfo{
|
||||
Service: &dynamic.Service{
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.2",
|
||||
|
@ -614,7 +614,7 @@ func TestHandler_HTTP(t *testing.T) {
|
|||
si := &runtime.ServiceInfo{
|
||||
Service: &dynamic.Service{
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1",
|
||||
|
@ -632,7 +632,7 @@ func TestHandler_HTTP(t *testing.T) {
|
|||
si := &runtime.ServiceInfo{
|
||||
Service: &dynamic.Service{
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.2",
|
||||
|
@ -663,7 +663,7 @@ func TestHandler_HTTP(t *testing.T) {
|
|||
si := &runtime.ServiceInfo{
|
||||
Service: &dynamic.Service{
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1",
|
||||
|
@ -692,7 +692,7 @@ func TestHandler_HTTP(t *testing.T) {
|
|||
si := &runtime.ServiceInfo{
|
||||
Service: &dynamic.Service{
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1",
|
||||
|
@ -721,7 +721,7 @@ func TestHandler_HTTP(t *testing.T) {
|
|||
si := &runtime.ServiceInfo{
|
||||
Service: &dynamic.Service{
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1",
|
||||
|
|
|
@ -38,7 +38,7 @@ func TestHandler_RawData(t *testing.T) {
|
|||
"foo-service@myprovider": {
|
||||
Service: &dynamic.Service{
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://127.0.0.1",
|
||||
|
|
|
@ -341,11 +341,7 @@ func (m tcpMiddlewareRepresentation) status() string {
|
|||
return m.Status
|
||||
}
|
||||
|
||||
type orderedByName interface {
|
||||
orderedWithName
|
||||
}
|
||||
|
||||
func sortByName[T orderedByName](direction string, results []T) {
|
||||
func sortByName[T orderedWithName](direction string, results []T) {
|
||||
// Ascending
|
||||
if direction == ascendantSorting {
|
||||
sort.Slice(results, func(i, j int) bool {
|
||||
|
|
|
@ -13,8 +13,7 @@ import (
|
|||
"github.com/traefik/traefik/v3/pkg/types"
|
||||
)
|
||||
|
||||
func Bool(v bool) *bool { return &v }
|
||||
func String(v string) *string { return &v }
|
||||
func pointer[T any](v T) *T { return &v }
|
||||
|
||||
func TestDecodeConfiguration(t *testing.T) {
|
||||
labels := map[string]string{
|
||||
|
@ -284,7 +283,7 @@ func TestDecodeConfiguration(t *testing.T) {
|
|||
Port: "42",
|
||||
},
|
||||
},
|
||||
TerminationDelay: func(i int) *int { return &i }(42),
|
||||
TerminationDelay: pointer(42),
|
||||
ProxyProtocol: &dynamic.ProxyProtocol{Version: 42},
|
||||
ServersTransport: "foo",
|
||||
},
|
||||
|
@ -296,7 +295,7 @@ func TestDecodeConfiguration(t *testing.T) {
|
|||
Port: "42",
|
||||
},
|
||||
},
|
||||
TerminationDelay: func(i int) *int { return &i }(42),
|
||||
TerminationDelay: pointer(42),
|
||||
ProxyProtocol: &dynamic.ProxyProtocol{Version: 2},
|
||||
ServersTransport: "foo",
|
||||
},
|
||||
|
@ -486,7 +485,7 @@ func TestDecodeConfiguration(t *testing.T) {
|
|||
"foobar",
|
||||
"fiibar",
|
||||
},
|
||||
ForceSlash: Bool(true),
|
||||
ForceSlash: pointer(true),
|
||||
},
|
||||
},
|
||||
"Middleware18": {
|
||||
|
@ -562,7 +561,7 @@ func TestDecodeConfiguration(t *testing.T) {
|
|||
Cert: "foobar",
|
||||
Key: "foobar",
|
||||
InsecureSkipVerify: true,
|
||||
CAOptional: Bool(true),
|
||||
CAOptional: pointer(true),
|
||||
},
|
||||
TrustForwardHeader: true,
|
||||
AuthResponseHeaders: []string{
|
||||
|
@ -616,14 +615,14 @@ func TestDecodeConfiguration(t *testing.T) {
|
|||
"foobar",
|
||||
"fiibar",
|
||||
},
|
||||
SSLRedirect: Bool(true),
|
||||
SSLTemporaryRedirect: Bool(true),
|
||||
SSLHost: String("foobar"),
|
||||
SSLRedirect: pointer(true),
|
||||
SSLTemporaryRedirect: pointer(true),
|
||||
SSLHost: pointer("foobar"),
|
||||
SSLProxyHeaders: map[string]string{
|
||||
"name0": "foobar",
|
||||
"name1": "foobar",
|
||||
},
|
||||
SSLForceHost: Bool(true),
|
||||
SSLForceHost: pointer(true),
|
||||
STSSeconds: 42,
|
||||
STSIncludeSubdomains: true,
|
||||
STSPreload: true,
|
||||
|
@ -637,7 +636,7 @@ func TestDecodeConfiguration(t *testing.T) {
|
|||
ContentSecurityPolicyReportOnly: "foobar",
|
||||
PublicKey: "foobar",
|
||||
ReferrerPolicy: "foobar",
|
||||
FeaturePolicy: String("foobar"),
|
||||
FeaturePolicy: pointer("foobar"),
|
||||
PermissionsPolicy: "foobar",
|
||||
IsDevelopment: true,
|
||||
},
|
||||
|
@ -698,9 +697,9 @@ func TestDecodeConfiguration(t *testing.T) {
|
|||
"name0": "foobar",
|
||||
"name1": "foobar",
|
||||
},
|
||||
FollowRedirects: func(v bool) *bool { return &v }(true),
|
||||
FollowRedirects: pointer(true),
|
||||
},
|
||||
PassHostHeader: func(v bool) *bool { return &v }(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(time.Second),
|
||||
},
|
||||
|
@ -729,9 +728,9 @@ func TestDecodeConfiguration(t *testing.T) {
|
|||
"name0": "foobar",
|
||||
"name1": "foobar",
|
||||
},
|
||||
FollowRedirects: func(v bool) *bool { return &v }(true),
|
||||
FollowRedirects: pointer(true),
|
||||
},
|
||||
PassHostHeader: func(v bool) *bool { return &v }(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(time.Second),
|
||||
},
|
||||
|
@ -812,7 +811,7 @@ func TestEncodeConfiguration(t *testing.T) {
|
|||
},
|
||||
},
|
||||
ServersTransport: "foo",
|
||||
TerminationDelay: func(i int) *int { return &i }(42),
|
||||
TerminationDelay: pointer(42),
|
||||
},
|
||||
},
|
||||
"Service1": {
|
||||
|
@ -823,7 +822,7 @@ func TestEncodeConfiguration(t *testing.T) {
|
|||
},
|
||||
},
|
||||
ServersTransport: "foo",
|
||||
TerminationDelay: func(i int) *int { return &i }(42),
|
||||
TerminationDelay: pointer(42),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -1010,7 +1009,7 @@ func TestEncodeConfiguration(t *testing.T) {
|
|||
"foobar",
|
||||
"fiibar",
|
||||
},
|
||||
ForceSlash: Bool(true),
|
||||
ForceSlash: pointer(true),
|
||||
},
|
||||
},
|
||||
"Middleware18": {
|
||||
|
@ -1094,7 +1093,7 @@ func TestEncodeConfiguration(t *testing.T) {
|
|||
Cert: "foobar",
|
||||
Key: "foobar",
|
||||
InsecureSkipVerify: true,
|
||||
CAOptional: Bool(true),
|
||||
CAOptional: pointer(true),
|
||||
},
|
||||
TrustForwardHeader: true,
|
||||
AuthResponseHeaders: []string{
|
||||
|
@ -1148,14 +1147,14 @@ func TestEncodeConfiguration(t *testing.T) {
|
|||
"foobar",
|
||||
"fiibar",
|
||||
},
|
||||
SSLRedirect: Bool(true),
|
||||
SSLTemporaryRedirect: Bool(true),
|
||||
SSLHost: String("foobar"),
|
||||
SSLRedirect: pointer(true),
|
||||
SSLTemporaryRedirect: pointer(true),
|
||||
SSLHost: pointer("foobar"),
|
||||
SSLProxyHeaders: map[string]string{
|
||||
"name0": "foobar",
|
||||
"name1": "foobar",
|
||||
},
|
||||
SSLForceHost: Bool(true),
|
||||
SSLForceHost: pointer(true),
|
||||
STSSeconds: 42,
|
||||
STSIncludeSubdomains: true,
|
||||
STSPreload: true,
|
||||
|
@ -1169,7 +1168,7 @@ func TestEncodeConfiguration(t *testing.T) {
|
|||
ContentSecurityPolicyReportOnly: "foobar",
|
||||
PublicKey: "foobar",
|
||||
ReferrerPolicy: "foobar",
|
||||
FeaturePolicy: String("foobar"),
|
||||
FeaturePolicy: pointer("foobar"),
|
||||
PermissionsPolicy: "foobar",
|
||||
IsDevelopment: true,
|
||||
},
|
||||
|
@ -1221,7 +1220,7 @@ func TestEncodeConfiguration(t *testing.T) {
|
|||
"name1": "foobar",
|
||||
},
|
||||
},
|
||||
PassHostHeader: func(v bool) *bool { return &v }(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(time.Second),
|
||||
},
|
||||
|
@ -1250,7 +1249,7 @@ func TestEncodeConfiguration(t *testing.T) {
|
|||
"name1": "foobar",
|
||||
},
|
||||
},
|
||||
PassHostHeader: func(v bool) *bool { return &v }(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(time.Second),
|
||||
},
|
||||
|
|
|
@ -27,14 +27,14 @@ type EntryPoint struct {
|
|||
|
||||
// GetAddress strips any potential protocol part of the address field of the
|
||||
// entry point, in order to return the actual address.
|
||||
func (ep EntryPoint) GetAddress() string {
|
||||
func (ep *EntryPoint) GetAddress() string {
|
||||
splitN := strings.SplitN(ep.Address, "/", 2)
|
||||
return splitN[0]
|
||||
}
|
||||
|
||||
// GetProtocol returns the protocol part of the address field of the entry point.
|
||||
// If none is specified, it defaults to "tcp".
|
||||
func (ep EntryPoint) GetProtocol() (string, error) {
|
||||
func (ep *EntryPoint) GetProtocol() (string, error) {
|
||||
splitN := strings.SplitN(ep.Address, "/", 2)
|
||||
if len(splitN) < 2 {
|
||||
return "tcp", nil
|
||||
|
|
|
@ -297,6 +297,12 @@ func (c *Configuration) SetEffectiveConfiguration() {
|
|||
c.Providers.KubernetesGateway.EntryPoints = entryPoints
|
||||
}
|
||||
|
||||
// Defines the default rule syntax for the Kubernetes Ingress Provider.
|
||||
// This allows the provider to adapt the matcher syntax to the desired rule syntax version.
|
||||
if c.Core != nil && c.Providers.KubernetesIngress != nil {
|
||||
c.Providers.KubernetesIngress.DefaultRuleSyntax = c.Core.DefaultRuleSyntax
|
||||
}
|
||||
|
||||
c.initACMEProvider()
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,8 @@ import (
|
|||
|
||||
const delta float64 = 1e-10
|
||||
|
||||
func pointer[T any](v T) *T { return &v }
|
||||
|
||||
func TestNewServiceHealthChecker_durations(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
|
@ -285,7 +287,7 @@ func TestServiceHealthChecker_checkHealthHTTP_NotFollowingRedirects(t *testing.T
|
|||
|
||||
config := &dynamic.ServerHealthCheck{
|
||||
Path: "/path",
|
||||
FollowRedirects: Bool(false),
|
||||
FollowRedirects: pointer(false),
|
||||
Interval: dynamic.DefaultHealthCheckInterval,
|
||||
Timeout: dynamic.DefaultHealthCheckTimeout,
|
||||
}
|
||||
|
@ -454,7 +456,3 @@ func TestServiceHealthChecker_Launch(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Bool(b bool) *bool {
|
||||
return &b
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ import (
|
|||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
|
@ -812,10 +811,10 @@ func assertValidLogData(t *testing.T, expected string, logData []byte) {
|
|||
assert.Equal(t, resultExpected[OriginContentSize], result[OriginContentSize], formatErrMessage)
|
||||
assert.Equal(t, resultExpected[RequestRefererHeader], result[RequestRefererHeader], formatErrMessage)
|
||||
assert.Equal(t, resultExpected[RequestUserAgentHeader], result[RequestUserAgentHeader], formatErrMessage)
|
||||
assert.Regexp(t, regexp.MustCompile(`\d*`), result[RequestCount], formatErrMessage)
|
||||
assert.Regexp(t, `\d*`, result[RequestCount], formatErrMessage)
|
||||
assert.Equal(t, resultExpected[RouterName], result[RouterName], formatErrMessage)
|
||||
assert.Equal(t, resultExpected[ServiceURL], result[ServiceURL], formatErrMessage)
|
||||
assert.Regexp(t, regexp.MustCompile(`\d*ms`), result[Duration], formatErrMessage)
|
||||
assert.Regexp(t, `\d*ms`, result[Duration], formatErrMessage)
|
||||
}
|
||||
|
||||
func captureStdout(t *testing.T) (out *os.File, restoreStdout func()) {
|
||||
|
|
|
@ -20,6 +20,7 @@ const (
|
|||
xForwardedServer = "X-Forwarded-Server"
|
||||
xForwardedURI = "X-Forwarded-Uri"
|
||||
xForwardedMethod = "X-Forwarded-Method"
|
||||
xForwardedPrefix = "X-Forwarded-Prefix"
|
||||
xForwardedTLSClientCert = "X-Forwarded-Tls-Client-Cert"
|
||||
xForwardedTLSClientCertInfo = "X-Forwarded-Tls-Client-Cert-Info"
|
||||
xRealIP = "X-Real-Ip"
|
||||
|
@ -35,6 +36,7 @@ var xHeaders = []string{
|
|||
xForwardedServer,
|
||||
xForwardedURI,
|
||||
xForwardedMethod,
|
||||
xForwardedPrefix,
|
||||
xForwardedTLSClientCert,
|
||||
xForwardedTLSClientCertInfo,
|
||||
xRealIP,
|
||||
|
|
|
@ -48,6 +48,7 @@ func TestServeHTTP(t *testing.T) {
|
|||
xForwardedMethod: {"GET"},
|
||||
xForwardedTLSClientCert: {"Cert"},
|
||||
xForwardedTLSClientCertInfo: {"CertInfo"},
|
||||
xForwardedPrefix: {"/prefix"},
|
||||
},
|
||||
expectedHeaders: map[string]string{
|
||||
xForwardedFor: "10.0.1.0, 10.0.1.12",
|
||||
|
@ -55,6 +56,7 @@ func TestServeHTTP(t *testing.T) {
|
|||
xForwardedMethod: "GET",
|
||||
xForwardedTLSClientCert: "Cert",
|
||||
xForwardedTLSClientCertInfo: "CertInfo",
|
||||
xForwardedPrefix: "/prefix",
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -68,6 +70,7 @@ func TestServeHTTP(t *testing.T) {
|
|||
xForwardedMethod: {"GET"},
|
||||
xForwardedTLSClientCert: {"Cert"},
|
||||
xForwardedTLSClientCertInfo: {"CertInfo"},
|
||||
xForwardedPrefix: {"/prefix"},
|
||||
},
|
||||
expectedHeaders: map[string]string{
|
||||
xForwardedFor: "",
|
||||
|
@ -75,6 +78,7 @@ func TestServeHTTP(t *testing.T) {
|
|||
xForwardedMethod: "",
|
||||
xForwardedTLSClientCert: "",
|
||||
xForwardedTLSClientCertInfo: "",
|
||||
xForwardedPrefix: "",
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -88,6 +92,7 @@ func TestServeHTTP(t *testing.T) {
|
|||
xForwardedMethod: {"GET"},
|
||||
xForwardedTLSClientCert: {"Cert"},
|
||||
xForwardedTLSClientCertInfo: {"CertInfo"},
|
||||
xForwardedPrefix: {"/prefix"},
|
||||
},
|
||||
expectedHeaders: map[string]string{
|
||||
xForwardedFor: "10.0.1.0, 10.0.1.12",
|
||||
|
@ -95,6 +100,7 @@ func TestServeHTTP(t *testing.T) {
|
|||
xForwardedMethod: "GET",
|
||||
xForwardedTLSClientCert: "Cert",
|
||||
xForwardedTLSClientCertInfo: "CertInfo",
|
||||
xForwardedPrefix: "/prefix",
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -108,6 +114,7 @@ func TestServeHTTP(t *testing.T) {
|
|||
xForwardedMethod: {"GET"},
|
||||
xForwardedTLSClientCert: {"Cert"},
|
||||
xForwardedTLSClientCertInfo: {"CertInfo"},
|
||||
xForwardedPrefix: {"/prefix"},
|
||||
},
|
||||
expectedHeaders: map[string]string{
|
||||
xForwardedFor: "",
|
||||
|
@ -115,6 +122,7 @@ func TestServeHTTP(t *testing.T) {
|
|||
xForwardedMethod: "",
|
||||
xForwardedTLSClientCert: "",
|
||||
xForwardedTLSClientCertInfo: "",
|
||||
xForwardedPrefix: "",
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -128,6 +136,7 @@ func TestServeHTTP(t *testing.T) {
|
|||
xForwardedMethod: {"GET"},
|
||||
xForwardedTLSClientCert: {"Cert"},
|
||||
xForwardedTLSClientCertInfo: {"CertInfo"},
|
||||
xForwardedPrefix: {"/prefix"},
|
||||
},
|
||||
expectedHeaders: map[string]string{
|
||||
xForwardedFor: "10.0.1.0, 10.0.1.12",
|
||||
|
@ -135,6 +144,7 @@ func TestServeHTTP(t *testing.T) {
|
|||
xForwardedMethod: "GET",
|
||||
xForwardedTLSClientCert: "Cert",
|
||||
xForwardedTLSClientCertInfo: "CertInfo",
|
||||
xForwardedPrefix: "/prefix",
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -148,6 +158,7 @@ func TestServeHTTP(t *testing.T) {
|
|||
xForwardedMethod: {"GET"},
|
||||
xForwardedTLSClientCert: {"Cert"},
|
||||
xForwardedTLSClientCertInfo: {"CertInfo"},
|
||||
xForwardedPrefix: {"/prefix"},
|
||||
},
|
||||
expectedHeaders: map[string]string{
|
||||
xForwardedFor: "",
|
||||
|
@ -155,6 +166,7 @@ func TestServeHTTP(t *testing.T) {
|
|||
xForwardedMethod: "",
|
||||
xForwardedTLSClientCert: "",
|
||||
xForwardedTLSClientCertInfo: "",
|
||||
xForwardedPrefix: "",
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -283,6 +295,7 @@ func TestServeHTTP(t *testing.T) {
|
|||
xForwardedPort,
|
||||
xForwardedTLSClientCert,
|
||||
xForwardedTLSClientCertInfo,
|
||||
xForwardedPrefix,
|
||||
xRealIP,
|
||||
},
|
||||
xForwardedProto: {"foo"},
|
||||
|
@ -293,6 +306,7 @@ func TestServeHTTP(t *testing.T) {
|
|||
xForwardedPort: {"foo"},
|
||||
xForwardedTLSClientCert: {"foo"},
|
||||
xForwardedTLSClientCertInfo: {"foo"},
|
||||
xForwardedPrefix: {"foo"},
|
||||
xRealIP: {"foo"},
|
||||
},
|
||||
expectedHeaders: map[string]string{
|
||||
|
@ -304,6 +318,7 @@ func TestServeHTTP(t *testing.T) {
|
|||
xForwardedPort: "80",
|
||||
xForwardedTLSClientCert: "",
|
||||
xForwardedTLSClientCertInfo: "",
|
||||
xForwardedPrefix: "",
|
||||
xRealIP: "",
|
||||
connection: "",
|
||||
},
|
||||
|
@ -321,6 +336,7 @@ func TestServeHTTP(t *testing.T) {
|
|||
xForwardedPort,
|
||||
xForwardedTLSClientCert,
|
||||
xForwardedTLSClientCertInfo,
|
||||
xForwardedPrefix,
|
||||
xRealIP,
|
||||
},
|
||||
xForwardedProto: {"foo"},
|
||||
|
@ -331,6 +347,7 @@ func TestServeHTTP(t *testing.T) {
|
|||
xForwardedPort: {"foo"},
|
||||
xForwardedTLSClientCert: {"foo"},
|
||||
xForwardedTLSClientCertInfo: {"foo"},
|
||||
xForwardedPrefix: {"foo"},
|
||||
xRealIP: {"foo"},
|
||||
},
|
||||
expectedHeaders: map[string]string{
|
||||
|
@ -342,6 +359,7 @@ func TestServeHTTP(t *testing.T) {
|
|||
xForwardedPort: "foo",
|
||||
xForwardedTLSClientCert: "foo",
|
||||
xForwardedTLSClientCertInfo: "foo",
|
||||
xForwardedPrefix: "foo",
|
||||
xRealIP: "foo",
|
||||
connection: "",
|
||||
},
|
||||
|
@ -358,6 +376,7 @@ func TestServeHTTP(t *testing.T) {
|
|||
xForwardedPort,
|
||||
xForwardedTLSClientCert,
|
||||
xForwardedTLSClientCertInfo,
|
||||
xForwardedPrefix,
|
||||
xRealIP,
|
||||
},
|
||||
incomingHeaders: map[string][]string{
|
||||
|
@ -370,6 +389,7 @@ func TestServeHTTP(t *testing.T) {
|
|||
xForwardedPort,
|
||||
xForwardedTLSClientCert,
|
||||
xForwardedTLSClientCertInfo,
|
||||
xForwardedPrefix,
|
||||
xRealIP,
|
||||
},
|
||||
xForwardedProto: {"foo"},
|
||||
|
@ -380,6 +400,7 @@ func TestServeHTTP(t *testing.T) {
|
|||
xForwardedPort: {"foo"},
|
||||
xForwardedTLSClientCert: {"foo"},
|
||||
xForwardedTLSClientCertInfo: {"foo"},
|
||||
xForwardedPrefix: {"foo"},
|
||||
xRealIP: {"foo"},
|
||||
},
|
||||
expectedHeaders: map[string]string{
|
||||
|
@ -391,6 +412,7 @@ func TestServeHTTP(t *testing.T) {
|
|||
xForwardedPort: "80",
|
||||
xForwardedTLSClientCert: "",
|
||||
xForwardedTLSClientCertInfo: "",
|
||||
xForwardedPrefix: "",
|
||||
xRealIP: "",
|
||||
connection: "",
|
||||
},
|
||||
|
@ -407,6 +429,7 @@ func TestServeHTTP(t *testing.T) {
|
|||
xForwardedPort,
|
||||
xForwardedTLSClientCert,
|
||||
xForwardedTLSClientCertInfo,
|
||||
xForwardedPrefix,
|
||||
xRealIP,
|
||||
},
|
||||
incomingHeaders: map[string][]string{
|
||||
|
@ -419,6 +442,7 @@ func TestServeHTTP(t *testing.T) {
|
|||
xForwardedPort,
|
||||
xForwardedTLSClientCert,
|
||||
xForwardedTLSClientCertInfo,
|
||||
xForwardedPrefix,
|
||||
xRealIP,
|
||||
},
|
||||
xForwardedProto: {"foo"},
|
||||
|
@ -429,6 +453,7 @@ func TestServeHTTP(t *testing.T) {
|
|||
xForwardedPort: {"foo"},
|
||||
xForwardedTLSClientCert: {"foo"},
|
||||
xForwardedTLSClientCertInfo: {"foo"},
|
||||
xForwardedPrefix: {"foo"},
|
||||
xRealIP: {"foo"},
|
||||
},
|
||||
expectedHeaders: map[string]string{
|
||||
|
@ -440,6 +465,7 @@ func TestServeHTTP(t *testing.T) {
|
|||
xForwardedPort: "foo",
|
||||
xForwardedTLSClientCert: "foo",
|
||||
xForwardedTLSClientCertInfo: "foo",
|
||||
xForwardedPrefix: "foo",
|
||||
xRealIP: "foo",
|
||||
connection: "",
|
||||
},
|
||||
|
|
|
@ -76,7 +76,7 @@ func NewMuxer() (*Muxer, error) {
|
|||
|
||||
// Match returns the handler of the first route matching the connection metadata,
|
||||
// and whether the match is exactly from the rule HostSNI(*).
|
||||
func (m Muxer) Match(meta ConnData) (tcp.Handler, bool) {
|
||||
func (m *Muxer) Match(meta ConnData) (tcp.Handler, bool) {
|
||||
for _, route := range m.routes {
|
||||
if route.matchers.match(meta) {
|
||||
return route.handler, route.catchAll
|
||||
|
|
|
@ -67,8 +67,8 @@ type ProviderAggregator struct {
|
|||
}
|
||||
|
||||
// NewProviderAggregator returns an aggregate of all the providers configured in the static configuration.
|
||||
func NewProviderAggregator(conf static.Providers) ProviderAggregator {
|
||||
p := ProviderAggregator{
|
||||
func NewProviderAggregator(conf static.Providers) *ProviderAggregator {
|
||||
p := &ProviderAggregator{
|
||||
providersThrottleDuration: time.Duration(conf.ProvidersThrottleDuration),
|
||||
}
|
||||
|
||||
|
@ -168,12 +168,12 @@ func (p *ProviderAggregator) AddProvider(provider provider.Provider) error {
|
|||
}
|
||||
|
||||
// Init the provider.
|
||||
func (p ProviderAggregator) Init() error {
|
||||
func (p *ProviderAggregator) Init() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Provide calls the provide method of every providers.
|
||||
func (p ProviderAggregator) Provide(configurationChan chan<- dynamic.Message, pool *safe.Pool) error {
|
||||
func (p *ProviderAggregator) Provide(configurationChan chan<- dynamic.Message, pool *safe.Pool) error {
|
||||
if p.fileProvider != nil {
|
||||
p.launchProvider(configurationChan, pool, p.fileProvider)
|
||||
}
|
||||
|
@ -193,7 +193,7 @@ func (p ProviderAggregator) Provide(configurationChan chan<- dynamic.Message, po
|
|||
return nil
|
||||
}
|
||||
|
||||
func (p ProviderAggregator) launchProvider(configurationChan chan<- dynamic.Message, pool *safe.Pool, prd provider.Provider) {
|
||||
func (p *ProviderAggregator) launchProvider(configurationChan chan<- dynamic.Message, pool *safe.Pool, prd provider.Provider) {
|
||||
jsonConf, err := redactor.RemoveCredentials(prd)
|
||||
if err != nil {
|
||||
log.Debug().Err(err).Msgf("Cannot marshal the provider configuration %T", prd)
|
||||
|
|
|
@ -15,8 +15,7 @@ import (
|
|||
"github.com/traefik/traefik/v3/pkg/types"
|
||||
)
|
||||
|
||||
func Int(v int) *int { return &v }
|
||||
func Bool(v bool) *bool { return &v }
|
||||
func pointer[T any](v T) *T { return &v }
|
||||
|
||||
func TestDefaultRule(t *testing.T) {
|
||||
testCases := []struct {
|
||||
|
@ -67,7 +66,7 @@ func TestDefaultRule(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -125,7 +124,7 @@ func TestDefaultRule(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -175,7 +174,7 @@ func TestDefaultRule(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -225,7 +224,7 @@ func TestDefaultRule(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -281,7 +280,7 @@ func TestDefaultRule(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -375,7 +374,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -436,7 +435,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "https://127.0.0.1:443",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -530,7 +529,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "https://127.0.0.2:444",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -615,7 +614,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -628,7 +627,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.2:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -695,7 +694,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.2:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -759,7 +758,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.2:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -826,7 +825,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.2:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -882,7 +881,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -939,7 +938,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -988,7 +987,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1050,7 +1049,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1102,7 +1101,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1115,7 +1114,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1297,7 +1296,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.2:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1352,7 +1351,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1433,7 +1432,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.2:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1501,7 +1500,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.2:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1585,7 +1584,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.3:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1649,7 +1648,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.2:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1727,7 +1726,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.3:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1797,7 +1796,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.2:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1853,7 +1852,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1910,7 +1909,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "h2c://127.0.0.1:8080",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1961,7 +1960,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1974,7 +1973,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.1:8080",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -2207,7 +2206,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -2274,7 +2273,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -2710,7 +2709,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.2:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -2801,7 +2800,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.2:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -3019,7 +3018,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "https://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -3033,7 +3032,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "https://127.0.0.2:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -3319,7 +3318,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -3495,7 +3494,7 @@ func TestFilterHealthStatuses(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -3508,7 +3507,7 @@ func TestFilterHealthStatuses(t *testing.T) {
|
|||
URL: "http://127.0.0.1:81",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -3611,7 +3610,7 @@ func TestFilterHealthStatuses(t *testing.T) {
|
|||
URL: "http://127.0.0.1:81",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -3691,7 +3690,7 @@ func TestFilterHealthStatuses(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -3704,7 +3703,7 @@ func TestFilterHealthStatuses(t *testing.T) {
|
|||
URL: "http://127.0.0.1:81",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -3803,7 +3802,7 @@ func TestFilterHealthStatuses(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -3816,7 +3815,7 @@ func TestFilterHealthStatuses(t *testing.T) {
|
|||
URL: "http://127.0.0.1:81",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -3829,7 +3828,7 @@ func TestFilterHealthStatuses(t *testing.T) {
|
|||
URL: "http://127.0.0.1:82",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -3842,7 +3841,7 @@ func TestFilterHealthStatuses(t *testing.T) {
|
|||
URL: "http://127.0.0.1:83",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
|
|
@ -74,7 +74,7 @@ func TestDynConfBuilder_DefaultRule(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -137,7 +137,7 @@ func TestDynConfBuilder_DefaultRule(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -202,7 +202,7 @@ func TestDynConfBuilder_DefaultRule(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -259,7 +259,7 @@ func TestDynConfBuilder_DefaultRule(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -316,7 +316,7 @@ func TestDynConfBuilder_DefaultRule(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -379,7 +379,7 @@ func TestDynConfBuilder_DefaultRule(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -613,7 +613,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -696,7 +696,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -709,7 +709,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
|||
URL: "http://127.0.0.2:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -792,7 +792,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
|||
URL: "http://127.0.0.2:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -856,7 +856,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -921,7 +921,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -978,7 +978,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1048,7 +1048,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1108,7 +1108,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1121,7 +1121,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1185,7 +1185,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1431,7 +1431,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
|||
URL: "http://127.0.0.2:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1494,7 +1494,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1594,7 +1594,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
|||
URL: "http://127.0.0.2:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1681,7 +1681,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
|||
URL: "http://127.0.0.2:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1790,7 +1790,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
|||
URL: "http://127.0.0.3:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1871,7 +1871,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
|||
URL: "http://127.0.0.2:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1974,7 +1974,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
|||
URL: "http://127.0.0.3:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -2060,7 +2060,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
|||
URL: "http://127.0.0.2:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -2136,7 +2136,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -2149,7 +2149,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
|||
URL: "http://127.0.0.2:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -2213,7 +2213,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -2278,7 +2278,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
|||
URL: "h2c://127.0.0.1:8080",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -2337,7 +2337,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -2350,7 +2350,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
|||
URL: "http://127.0.0.1:8080",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -2554,7 +2554,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
|||
Services: map[string]*dynamic.Service{
|
||||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -2819,7 +2819,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -2894,7 +2894,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -3368,7 +3368,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
|||
URL: "http://127.0.0.2:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -3549,7 +3549,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
|||
URL: "http://192.168.0.1:8081",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -3612,7 +3612,7 @@ func TestDynConfBuilder_build(t *testing.T) {
|
|||
URL: "http://127.0.0.1:79",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -4031,6 +4031,4 @@ func TestDynConfBuilder_getIPAddress_swarm(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func Int(v int) *int { return &v }
|
||||
|
||||
func Bool(v bool) *bool { return &v }
|
||||
func pointer[T any](v T) *T { return &v }
|
||||
|
|
|
@ -14,8 +14,7 @@ import (
|
|||
"github.com/traefik/traefik/v3/pkg/types"
|
||||
)
|
||||
|
||||
func Int(v int) *int { return &v }
|
||||
func Bool(v bool) *bool { return &v }
|
||||
func pointer[T any](v T) *T { return &v }
|
||||
|
||||
func TestDefaultRule(t *testing.T) {
|
||||
testCases := []struct {
|
||||
|
@ -69,7 +68,7 @@ func TestDefaultRule(t *testing.T) {
|
|||
URL: "http://10.0.0.1:1337",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -127,7 +126,7 @@ func TestDefaultRule(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -187,7 +186,7 @@ func TestDefaultRule(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -239,7 +238,7 @@ func TestDefaultRule(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -291,7 +290,7 @@ func TestDefaultRule(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -349,7 +348,7 @@ func TestDefaultRule(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -558,7 +557,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -631,7 +630,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -644,7 +643,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.2:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -717,7 +716,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.2:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -776,7 +775,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -836,7 +835,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -888,7 +887,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -953,7 +952,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1008,7 +1007,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1021,7 +1020,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1080,7 +1079,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1291,7 +1290,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.2:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1349,7 +1348,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1439,7 +1438,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.2:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1516,7 +1515,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.2:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1610,7 +1609,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.3:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1681,7 +1680,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.2:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1769,7 +1768,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.3:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1846,7 +1845,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.2:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1912,7 +1911,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1925,7 +1924,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.2:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1984,7 +1983,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -2044,7 +2043,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "h2c://127.0.0.1:8080",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -2104,7 +2103,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "h2c://127.0.0.1:8040",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -2172,7 +2171,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.1:32124",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -2185,7 +2184,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.1:32123",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -2239,7 +2238,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -2252,7 +2251,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.1:8080",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -2542,7 +2541,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -2612,7 +2611,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -3046,7 +3045,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.2:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -3206,7 +3205,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
|
|
@ -396,7 +396,7 @@ func (c configBuilder) buildServersLB(namespace string, svc traefikv1alpha1.Load
|
|||
return &dynamic.Service{LoadBalancer: lb}, nil
|
||||
}
|
||||
|
||||
func (c *configBuilder) makeServersTransportKey(parentNamespace string, serversTransportName string) (string, error) {
|
||||
func (c configBuilder) makeServersTransportKey(parentNamespace string, serversTransportName string) (string, error) {
|
||||
if serversTransportName == "" {
|
||||
return "", nil
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -128,8 +128,8 @@ func Test_parseServiceConfig(t *testing.T) {
|
|||
},
|
||||
ServersScheme: "protocol",
|
||||
ServersTransport: "foobar@file",
|
||||
PassHostHeader: Bool(true),
|
||||
NativeLB: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
NativeLB: pointer(true),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -145,7 +145,7 @@ func Test_parseServiceConfig(t *testing.T) {
|
|||
Path: String("/"),
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
kind: Ingress
|
||||
apiVersion: networking.k8s.io/v1
|
||||
metadata:
|
||||
name: ""
|
||||
namespace: testing
|
||||
|
||||
spec:
|
||||
rules:
|
||||
- host: "*.foobar.com"
|
||||
http:
|
||||
paths:
|
||||
- path: /bar
|
||||
backend:
|
||||
service:
|
||||
name: service1
|
||||
port:
|
||||
number: 80
|
||||
pathType: Prefix
|
||||
|
||||
---
|
||||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: service1
|
||||
namespace: testing
|
||||
|
||||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
clusterIP: 10.0.0.1
|
||||
|
||||
---
|
||||
kind: EndpointSlice
|
||||
apiVersion: discovery.k8s.io/v1
|
||||
metadata:
|
||||
name: service1-abc
|
||||
namespace: testing
|
||||
labels:
|
||||
kubernetes.io/service-name: service1
|
||||
|
||||
addressType: IPv4
|
||||
ports:
|
||||
- port: 8080
|
||||
name: ""
|
||||
endpoints:
|
||||
- addresses:
|
||||
- 10.10.0.1
|
||||
conditions:
|
||||
ready: true
|
|
@ -56,6 +56,9 @@ type Provider struct {
|
|||
DisableClusterScopeResources bool `description:"Disables the lookup of cluster scope resources (incompatible with IngressClasses and NodePortLB enabled services)." json:"disableClusterScopeResources,omitempty" toml:"disableClusterScopeResources,omitempty" yaml:"disableClusterScopeResources,omitempty" export:"true"`
|
||||
NativeLBByDefault bool `description:"Defines whether to use Native Kubernetes load-balancing mode by default." json:"nativeLBByDefault,omitempty" toml:"nativeLBByDefault,omitempty" yaml:"nativeLBByDefault,omitempty" export:"true"`
|
||||
|
||||
// The default rule syntax is initialized with the configuration defined by the user with the core.DefaultRuleSyntax option.
|
||||
DefaultRuleSyntax string `json:"-" toml:"-" yaml:"-" label:"-" file:"-"`
|
||||
|
||||
lastConfiguration safe.Safe
|
||||
|
||||
routerTransform k8s.RouterTransform
|
||||
|
@ -336,7 +339,7 @@ func (p *Provider) loadConfigurationFromIngresses(ctx context.Context, client Cl
|
|||
serviceName := provider.Normalize(ingress.Namespace + "-" + pa.Backend.Service.Name + "-" + portString)
|
||||
conf.HTTP.Services[serviceName] = service
|
||||
|
||||
rt := loadRouter(rule, pa, rtConfig, serviceName)
|
||||
rt := p.loadRouter(rule, pa, rtConfig, serviceName)
|
||||
|
||||
p.applyRouterTransform(ctxIngress, rt, ingress)
|
||||
|
||||
|
@ -432,100 +435,6 @@ func (p *Provider) shouldProcessIngress(ingress *netv1.Ingress, ingressClasses [
|
|||
len(p.IngressClass) == 0 && ingress.Annotations[annotationKubernetesIngressClass] == traefikDefaultIngressClass
|
||||
}
|
||||
|
||||
func buildHostRule(host string) string {
|
||||
if strings.HasPrefix(host, "*.") {
|
||||
host = strings.Replace(regexp.QuoteMeta(host), `\*\.`, `[a-zA-Z0-9-]+\.`, 1)
|
||||
return fmt.Sprintf("HostRegexp(`^%s$`)", host)
|
||||
}
|
||||
|
||||
return fmt.Sprintf("Host(`%s`)", host)
|
||||
}
|
||||
|
||||
func getCertificates(ctx context.Context, ingress *netv1.Ingress, k8sClient Client, tlsConfigs map[string]*tls.CertAndStores) error {
|
||||
for _, t := range ingress.Spec.TLS {
|
||||
if t.SecretName == "" {
|
||||
log.Ctx(ctx).Debug().Msg("Skipping TLS sub-section: No secret name provided")
|
||||
continue
|
||||
}
|
||||
|
||||
configKey := ingress.Namespace + "-" + t.SecretName
|
||||
if _, tlsExists := tlsConfigs[configKey]; !tlsExists {
|
||||
secret, exists, err := k8sClient.GetSecret(ingress.Namespace, t.SecretName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to fetch secret %s/%s: %w", ingress.Namespace, t.SecretName, err)
|
||||
}
|
||||
if !exists {
|
||||
return fmt.Errorf("secret %s/%s does not exist", ingress.Namespace, t.SecretName)
|
||||
}
|
||||
|
||||
cert, key, err := getCertificateBlocks(secret, ingress.Namespace, t.SecretName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tlsConfigs[configKey] = &tls.CertAndStores{
|
||||
Certificate: tls.Certificate{
|
||||
CertFile: types.FileOrContent(cert),
|
||||
KeyFile: types.FileOrContent(key),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getCertificateBlocks(secret *corev1.Secret, namespace, secretName string) (string, string, error) {
|
||||
var missingEntries []string
|
||||
|
||||
tlsCrtData, tlsCrtExists := secret.Data["tls.crt"]
|
||||
if !tlsCrtExists {
|
||||
missingEntries = append(missingEntries, "tls.crt")
|
||||
}
|
||||
|
||||
tlsKeyData, tlsKeyExists := secret.Data["tls.key"]
|
||||
if !tlsKeyExists {
|
||||
missingEntries = append(missingEntries, "tls.key")
|
||||
}
|
||||
|
||||
if len(missingEntries) > 0 {
|
||||
return "", "", fmt.Errorf("secret %s/%s is missing the following TLS data entries: %s",
|
||||
namespace, secretName, strings.Join(missingEntries, ", "))
|
||||
}
|
||||
|
||||
cert := string(tlsCrtData)
|
||||
if cert == "" {
|
||||
missingEntries = append(missingEntries, "tls.crt")
|
||||
}
|
||||
|
||||
key := string(tlsKeyData)
|
||||
if key == "" {
|
||||
missingEntries = append(missingEntries, "tls.key")
|
||||
}
|
||||
|
||||
if len(missingEntries) > 0 {
|
||||
return "", "", fmt.Errorf("secret %s/%s contains the following empty TLS data entries: %s",
|
||||
namespace, secretName, strings.Join(missingEntries, ", "))
|
||||
}
|
||||
|
||||
return cert, key, nil
|
||||
}
|
||||
|
||||
func getTLSConfig(tlsConfigs map[string]*tls.CertAndStores) []*tls.CertAndStores {
|
||||
var secretNames []string
|
||||
for secretName := range tlsConfigs {
|
||||
secretNames = append(secretNames, secretName)
|
||||
}
|
||||
sort.Strings(secretNames)
|
||||
|
||||
var configs []*tls.CertAndStores
|
||||
for _, secretName := range secretNames {
|
||||
configs = append(configs, tlsConfigs[secretName])
|
||||
}
|
||||
|
||||
return configs
|
||||
}
|
||||
|
||||
func (p *Provider) loadService(client Client, namespace string, backend netv1.IngressBackend) (*dynamic.Service, error) {
|
||||
if backend.Resource != nil {
|
||||
// https://kubernetes.io/docs/concepts/services-networking/ingress/#resource-backend
|
||||
|
@ -698,6 +607,152 @@ func (p *Provider) loadService(client Client, namespace string, backend netv1.In
|
|||
return svc, nil
|
||||
}
|
||||
|
||||
func (p *Provider) loadRouter(rule netv1.IngressRule, pa netv1.HTTPIngressPath, rtConfig *RouterConfig, serviceName string) *dynamic.Router {
|
||||
rt := &dynamic.Router{
|
||||
Service: serviceName,
|
||||
}
|
||||
|
||||
if rtConfig != nil && rtConfig.Router != nil {
|
||||
rt.RuleSyntax = rtConfig.Router.RuleSyntax
|
||||
rt.Priority = rtConfig.Router.Priority
|
||||
rt.EntryPoints = rtConfig.Router.EntryPoints
|
||||
rt.Middlewares = rtConfig.Router.Middlewares
|
||||
|
||||
if rtConfig.Router.TLS != nil {
|
||||
rt.TLS = rtConfig.Router.TLS
|
||||
}
|
||||
}
|
||||
|
||||
var rules []string
|
||||
if len(rule.Host) > 0 {
|
||||
if rt.RuleSyntax == "v2" || (rt.RuleSyntax == "" && p.DefaultRuleSyntax == "v2") {
|
||||
rules = append(rules, buildHostRuleV2(rule.Host))
|
||||
} else {
|
||||
rules = append(rules, buildHostRule(rule.Host))
|
||||
}
|
||||
}
|
||||
|
||||
if len(pa.Path) > 0 {
|
||||
matcher := defaultPathMatcher
|
||||
|
||||
if pa.PathType == nil || *pa.PathType == "" || *pa.PathType == netv1.PathTypeImplementationSpecific {
|
||||
if rtConfig != nil && rtConfig.Router != nil && rtConfig.Router.PathMatcher != "" {
|
||||
matcher = rtConfig.Router.PathMatcher
|
||||
}
|
||||
} else if *pa.PathType == netv1.PathTypeExact {
|
||||
matcher = "Path"
|
||||
}
|
||||
|
||||
rules = append(rules, fmt.Sprintf("%s(`%s`)", matcher, pa.Path))
|
||||
}
|
||||
|
||||
rt.Rule = strings.Join(rules, " && ")
|
||||
return rt
|
||||
}
|
||||
|
||||
func buildHostRuleV2(host string) string {
|
||||
if strings.HasPrefix(host, "*.") {
|
||||
host = strings.Replace(host, "*.", "{subdomain:[a-zA-Z0-9-]+}.", 1)
|
||||
return fmt.Sprintf("HostRegexp(`%s`)", host)
|
||||
}
|
||||
|
||||
return fmt.Sprintf("Host(`%s`)", host)
|
||||
}
|
||||
|
||||
func buildHostRule(host string) string {
|
||||
if strings.HasPrefix(host, "*.") {
|
||||
host = strings.Replace(regexp.QuoteMeta(host), `\*\.`, `[a-zA-Z0-9-]+\.`, 1)
|
||||
return fmt.Sprintf("HostRegexp(`^%s$`)", host)
|
||||
}
|
||||
|
||||
return fmt.Sprintf("Host(`%s`)", host)
|
||||
}
|
||||
|
||||
func getCertificates(ctx context.Context, ingress *netv1.Ingress, k8sClient Client, tlsConfigs map[string]*tls.CertAndStores) error {
|
||||
for _, t := range ingress.Spec.TLS {
|
||||
if t.SecretName == "" {
|
||||
log.Ctx(ctx).Debug().Msg("Skipping TLS sub-section: No secret name provided")
|
||||
continue
|
||||
}
|
||||
|
||||
configKey := ingress.Namespace + "-" + t.SecretName
|
||||
if _, tlsExists := tlsConfigs[configKey]; !tlsExists {
|
||||
secret, exists, err := k8sClient.GetSecret(ingress.Namespace, t.SecretName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to fetch secret %s/%s: %w", ingress.Namespace, t.SecretName, err)
|
||||
}
|
||||
if !exists {
|
||||
return fmt.Errorf("secret %s/%s does not exist", ingress.Namespace, t.SecretName)
|
||||
}
|
||||
|
||||
cert, key, err := getCertificateBlocks(secret, ingress.Namespace, t.SecretName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tlsConfigs[configKey] = &tls.CertAndStores{
|
||||
Certificate: tls.Certificate{
|
||||
CertFile: types.FileOrContent(cert),
|
||||
KeyFile: types.FileOrContent(key),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getCertificateBlocks(secret *corev1.Secret, namespace, secretName string) (string, string, error) {
|
||||
var missingEntries []string
|
||||
|
||||
tlsCrtData, tlsCrtExists := secret.Data["tls.crt"]
|
||||
if !tlsCrtExists {
|
||||
missingEntries = append(missingEntries, "tls.crt")
|
||||
}
|
||||
|
||||
tlsKeyData, tlsKeyExists := secret.Data["tls.key"]
|
||||
if !tlsKeyExists {
|
||||
missingEntries = append(missingEntries, "tls.key")
|
||||
}
|
||||
|
||||
if len(missingEntries) > 0 {
|
||||
return "", "", fmt.Errorf("secret %s/%s is missing the following TLS data entries: %s",
|
||||
namespace, secretName, strings.Join(missingEntries, ", "))
|
||||
}
|
||||
|
||||
cert := string(tlsCrtData)
|
||||
if cert == "" {
|
||||
missingEntries = append(missingEntries, "tls.crt")
|
||||
}
|
||||
|
||||
key := string(tlsKeyData)
|
||||
if key == "" {
|
||||
missingEntries = append(missingEntries, "tls.key")
|
||||
}
|
||||
|
||||
if len(missingEntries) > 0 {
|
||||
return "", "", fmt.Errorf("secret %s/%s contains the following empty TLS data entries: %s",
|
||||
namespace, secretName, strings.Join(missingEntries, ", "))
|
||||
}
|
||||
|
||||
return cert, key, nil
|
||||
}
|
||||
|
||||
func getTLSConfig(tlsConfigs map[string]*tls.CertAndStores) []*tls.CertAndStores {
|
||||
var secretNames []string
|
||||
for secretName := range tlsConfigs {
|
||||
secretNames = append(secretNames, secretName)
|
||||
}
|
||||
sort.Strings(secretNames)
|
||||
|
||||
var configs []*tls.CertAndStores
|
||||
for _, secretName := range secretNames {
|
||||
configs = append(configs, tlsConfigs[secretName])
|
||||
}
|
||||
|
||||
return configs
|
||||
}
|
||||
|
||||
func getNativeServiceAddress(service corev1.Service, svcPort corev1.ServicePort) (string, error) {
|
||||
if service.Spec.ClusterIP == "None" {
|
||||
return "", fmt.Errorf("no clusterIP on headless service: %s/%s", service.Namespace, service.Name)
|
||||
|
@ -734,45 +789,6 @@ func makeRouterKeyWithHash(key, rule string) (string, error) {
|
|||
return dupKey, nil
|
||||
}
|
||||
|
||||
func loadRouter(rule netv1.IngressRule, pa netv1.HTTPIngressPath, rtConfig *RouterConfig, serviceName string) *dynamic.Router {
|
||||
var rules []string
|
||||
if len(rule.Host) > 0 {
|
||||
rules = []string{buildHostRule(rule.Host)}
|
||||
}
|
||||
|
||||
if len(pa.Path) > 0 {
|
||||
matcher := defaultPathMatcher
|
||||
|
||||
if pa.PathType == nil || *pa.PathType == "" || *pa.PathType == netv1.PathTypeImplementationSpecific {
|
||||
if rtConfig != nil && rtConfig.Router != nil && rtConfig.Router.PathMatcher != "" {
|
||||
matcher = rtConfig.Router.PathMatcher
|
||||
}
|
||||
} else if *pa.PathType == netv1.PathTypeExact {
|
||||
matcher = "Path"
|
||||
}
|
||||
|
||||
rules = append(rules, fmt.Sprintf("%s(`%s`)", matcher, pa.Path))
|
||||
}
|
||||
|
||||
rt := &dynamic.Router{
|
||||
Rule: strings.Join(rules, " && "),
|
||||
Service: serviceName,
|
||||
}
|
||||
|
||||
if rtConfig != nil && rtConfig.Router != nil {
|
||||
rt.RuleSyntax = rtConfig.Router.RuleSyntax
|
||||
rt.Priority = rtConfig.Router.Priority
|
||||
rt.EntryPoints = rtConfig.Router.EntryPoints
|
||||
rt.Middlewares = rtConfig.Router.Middlewares
|
||||
|
||||
if rtConfig.Router.TLS != nil {
|
||||
rt.TLS = rtConfig.Router.TLS
|
||||
}
|
||||
}
|
||||
|
||||
return rt
|
||||
}
|
||||
|
||||
func throttleEvents(ctx context.Context, throttleDuration time.Duration, pool *safe.Pool, eventsChan <-chan interface{}) chan interface{} {
|
||||
if throttleDuration == 0 {
|
||||
return nil
|
||||
|
|
|
@ -22,7 +22,7 @@ import (
|
|||
|
||||
var _ provider.Provider = (*Provider)(nil)
|
||||
|
||||
func Bool(v bool) *bool { return &v }
|
||||
func pointer[T any](v T) *T { return &v }
|
||||
|
||||
func String(v string) *string { return &v }
|
||||
|
||||
|
@ -34,6 +34,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
allowEmptyServices bool
|
||||
disableIngressClassLookup bool
|
||||
disableClusterScopeResources bool
|
||||
defaultRuleSyntax string
|
||||
}{
|
||||
{
|
||||
desc: "Empty ingresses",
|
||||
|
@ -69,7 +70,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -119,7 +120,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -164,7 +165,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -200,7 +201,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -236,7 +237,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -272,7 +273,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -304,7 +305,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -336,7 +337,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
Services: map[string]*dynamic.Service{
|
||||
"testing-example-com-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -369,7 +370,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -405,7 +406,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -441,7 +442,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -457,7 +458,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
},
|
||||
"testing-service2-8082": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -490,7 +491,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -526,7 +527,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
Services: map[string]*dynamic.Service{
|
||||
"default-backend": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -558,7 +559,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -590,7 +591,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-tchouk": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -622,7 +623,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-tchouk": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -658,7 +659,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-tchouk": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -674,7 +675,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
},
|
||||
"testing-service1-carotte": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -706,7 +707,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-tchouk": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -742,7 +743,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-tchouk": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -758,7 +759,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
},
|
||||
"toto-service1-tchouk": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -810,7 +811,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-8080": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -840,7 +841,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
Services: map[string]*dynamic.Service{
|
||||
"testing-example-com-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -879,7 +880,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-443": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -911,7 +912,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-8443": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -944,7 +945,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-8443": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -978,7 +979,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
Services: map[string]*dynamic.Service{
|
||||
"default-backend": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1010,7 +1011,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1082,7 +1083,39 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:8080",
|
||||
Scheme: "",
|
||||
Port: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "Ingress with wildcard host syntax v2",
|
||||
defaultRuleSyntax: "v2",
|
||||
expected: &dynamic.Configuration{
|
||||
HTTP: &dynamic.HTTPConfiguration{
|
||||
Middlewares: map[string]*dynamic.Middleware{},
|
||||
Routers: map[string]*dynamic.Router{
|
||||
"testing-foobar-com-bar": {
|
||||
Rule: "HostRegexp(`{subdomain:[a-zA-Z0-9-]+}.foobar.com`) && PathPrefix(`/bar`)",
|
||||
Service: "testing-service1-80",
|
||||
},
|
||||
},
|
||||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1117,7 +1150,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1147,7 +1180,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1176,7 +1209,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1205,7 +1238,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1234,7 +1267,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1263,7 +1296,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1292,7 +1325,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1324,7 +1357,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1356,7 +1389,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1385,7 +1418,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1440,7 +1473,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-foobar": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1481,7 +1514,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
Services: map[string]*dynamic.Service{
|
||||
"default-backend": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1508,6 +1541,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
AllowEmptyServices: test.allowEmptyServices,
|
||||
DisableIngressClassLookup: test.disableIngressClassLookup,
|
||||
DisableClusterScopeResources: test.disableClusterScopeResources,
|
||||
DefaultRuleSyntax: test.defaultRuleSyntax,
|
||||
}
|
||||
conf := p.loadConfigurationFromIngresses(context.Background(), clientMock)
|
||||
|
||||
|
@ -1548,7 +1582,7 @@ func TestLoadConfigurationFromIngressesWithExternalNameServices(t *testing.T) {
|
|||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-8080": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1582,7 +1616,7 @@ func TestLoadConfigurationFromIngressesWithExternalNameServices(t *testing.T) {
|
|||
URL: "http://[2001:0db8:3c4d:0015:0000:0000:1a2f:1a2b]:8080",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1612,7 +1646,7 @@ func TestLoadConfigurationFromIngressesWithExternalNameServices(t *testing.T) {
|
|||
URL: "http://[2001:0db8:3c4d:0015:0000:0000:1a2f:2a3b]:8080",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1660,7 +1694,7 @@ func TestLoadConfigurationFromIngressesWithNativeLB(t *testing.T) {
|
|||
"testing-service1-8080": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{FlushInterval: dynamic.DefaultFlushInterval},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.0.0.1:8080",
|
||||
|
@ -1709,7 +1743,7 @@ func TestLoadConfigurationFromIngressesWithNodePortLB(t *testing.T) {
|
|||
"testing-service1-8080": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{FlushInterval: dynamic.DefaultFlushInterval},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://172.16.4.4:32456",
|
||||
|
@ -1946,7 +1980,7 @@ func TestLoadConfigurationFromIngressesWithNativeLBByDefault(t *testing.T) {
|
|||
"testing-service1-8080": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{FlushInterval: dynamic.DefaultFlushInterval},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.0.0.1:8080",
|
||||
|
@ -1973,7 +2007,7 @@ func TestLoadConfigurationFromIngressesWithNativeLBByDefault(t *testing.T) {
|
|||
"default-service1-8080": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{FlushInterval: dynamic.DefaultFlushInterval},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.0.0.1:8080",
|
||||
|
|
|
@ -15,8 +15,7 @@ import (
|
|||
"github.com/traefik/traefik/v3/pkg/types"
|
||||
)
|
||||
|
||||
func Bool(v bool) *bool { return &v }
|
||||
func String(v string) *string { return &v }
|
||||
func pointer[T any](v T) *T { return &v }
|
||||
|
||||
func Test_buildConfiguration(t *testing.T) {
|
||||
provider := newProviderMock(mapToPairs(map[string]string{
|
||||
|
@ -387,7 +386,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
"foobar",
|
||||
"foobar",
|
||||
},
|
||||
ForceSlash: Bool(true),
|
||||
ForceSlash: pointer(true),
|
||||
},
|
||||
},
|
||||
"Middleware00": {
|
||||
|
@ -430,7 +429,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
Cert: "foobar",
|
||||
Key: "foobar",
|
||||
InsecureSkipVerify: true,
|
||||
CAOptional: Bool(true),
|
||||
CAOptional: pointer(true),
|
||||
},
|
||||
TrustForwardHeader: true,
|
||||
AuthResponseHeaders: []string{
|
||||
|
@ -603,14 +602,14 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
"foobar",
|
||||
"foobar",
|
||||
},
|
||||
SSLRedirect: Bool(true),
|
||||
SSLTemporaryRedirect: Bool(true),
|
||||
SSLHost: String("foobar"),
|
||||
SSLRedirect: pointer(true),
|
||||
SSLTemporaryRedirect: pointer(true),
|
||||
SSLHost: pointer("foobar"),
|
||||
SSLProxyHeaders: map[string]string{
|
||||
"name1": "foobar",
|
||||
"name0": "foobar",
|
||||
},
|
||||
SSLForceHost: Bool(true),
|
||||
SSLForceHost: pointer(true),
|
||||
STSSeconds: 42,
|
||||
STSIncludeSubdomains: true,
|
||||
STSPreload: true,
|
||||
|
@ -624,7 +623,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
ContentSecurityPolicyReportOnly: "foobar",
|
||||
PublicKey: "foobar",
|
||||
ReferrerPolicy: "foobar",
|
||||
FeaturePolicy: String("foobar"),
|
||||
FeaturePolicy: pointer("foobar"),
|
||||
PermissionsPolicy: "foobar",
|
||||
IsDevelopment: true,
|
||||
},
|
||||
|
@ -665,13 +664,13 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
Interval: ptypes.Duration(time.Second),
|
||||
Timeout: ptypes.Duration(time.Second),
|
||||
Hostname: "foobar",
|
||||
FollowRedirects: func(v bool) *bool { return &v }(true),
|
||||
FollowRedirects: pointer(true),
|
||||
Headers: map[string]string{
|
||||
"name0": "foobar",
|
||||
"name1": "foobar",
|
||||
},
|
||||
},
|
||||
PassHostHeader: func(v bool) *bool { return &v }(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(time.Second),
|
||||
},
|
||||
|
@ -680,8 +679,8 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
"Service02": {
|
||||
Mirroring: &dynamic.Mirroring{
|
||||
Service: "foobar",
|
||||
MirrorBody: func(v bool) *bool { return &v }(true),
|
||||
MaxBodySize: func(v int64) *int64 { return &v }(42),
|
||||
MirrorBody: pointer(true),
|
||||
MaxBodySize: pointer[int64](42),
|
||||
Mirrors: []dynamic.MirrorService{
|
||||
{
|
||||
Name: "foobar",
|
||||
|
@ -699,11 +698,11 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
Services: []dynamic.WRRService{
|
||||
{
|
||||
Name: "foobar",
|
||||
Weight: func(v int) *int { return &v }(42),
|
||||
Weight: pointer(42),
|
||||
},
|
||||
{
|
||||
Name: "foobar",
|
||||
Weight: func(v int) *int { return &v }(42),
|
||||
Weight: pointer(42),
|
||||
},
|
||||
},
|
||||
Sticky: &dynamic.Sticky{
|
||||
|
@ -788,7 +787,7 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
Services: map[string]*dynamic.TCPService{
|
||||
"TCPService01": {
|
||||
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
||||
TerminationDelay: func(v int) *int { return &v }(42),
|
||||
TerminationDelay: pointer(42),
|
||||
Servers: []dynamic.TCPServer{
|
||||
{Address: "foobar"},
|
||||
{Address: "foobar"},
|
||||
|
@ -800,11 +799,11 @@ func Test_buildConfiguration(t *testing.T) {
|
|||
Services: []dynamic.TCPWRRService{
|
||||
{
|
||||
Name: "foobar",
|
||||
Weight: func(v int) *int { return &v }(42),
|
||||
Weight: pointer(42),
|
||||
},
|
||||
{
|
||||
Name: "foobar",
|
||||
Weight: func(v int) *int { return &v }(43),
|
||||
Weight: pointer(43),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -61,7 +61,7 @@ func Test_defaultRule(t *testing.T) {
|
|||
URL: "http://127.0.0.1:9999",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -119,7 +119,7 @@ func Test_defaultRule(t *testing.T) {
|
|||
URL: "http://127.0.0.1:9999",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -168,7 +168,7 @@ func Test_defaultRule(t *testing.T) {
|
|||
URL: "http://127.0.0.1:9999",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -223,7 +223,7 @@ func Test_defaultRule(t *testing.T) {
|
|||
URL: "http://127.0.0.1:9999",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -301,7 +301,7 @@ func Test_buildConfig(t *testing.T) {
|
|||
URL: "http://127.0.0.1:9999",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -368,7 +368,7 @@ func Test_buildConfig(t *testing.T) {
|
|||
URL: "http://192.168.1.101:9999",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -381,7 +381,7 @@ func Test_buildConfig(t *testing.T) {
|
|||
URL: "http://192.168.1.102:9999",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -448,7 +448,7 @@ func Test_buildConfig(t *testing.T) {
|
|||
URL: "http://127.0.0.2:9999",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -512,7 +512,7 @@ func Test_buildConfig(t *testing.T) {
|
|||
URL: "http://127.0.0.2:9999",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -579,7 +579,7 @@ func Test_buildConfig(t *testing.T) {
|
|||
URL: "http://127.0.0.2:9999",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -635,7 +635,7 @@ func Test_buildConfig(t *testing.T) {
|
|||
URL: "http://127.0.0.1:9999",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -692,7 +692,7 @@ func Test_buildConfig(t *testing.T) {
|
|||
URL: "http://127.0.0.1:9999",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -777,7 +777,7 @@ func Test_buildConfig(t *testing.T) {
|
|||
URL: "http://127.0.0.1:9999",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -839,7 +839,7 @@ func Test_buildConfig(t *testing.T) {
|
|||
URL: "http://127.0.0.1:9999",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -891,7 +891,7 @@ func Test_buildConfig(t *testing.T) {
|
|||
URL: "http://127.0.0.1:9999",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -904,7 +904,7 @@ func Test_buildConfig(t *testing.T) {
|
|||
URL: "http://127.0.0.1:9999",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1087,7 +1087,7 @@ func Test_buildConfig(t *testing.T) {
|
|||
URL: "http://127.0.0.2:9999",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1142,7 +1142,7 @@ func Test_buildConfig(t *testing.T) {
|
|||
URL: "http://127.0.0.1:9999",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1224,7 +1224,7 @@ func Test_buildConfig(t *testing.T) {
|
|||
URL: "http://127.0.0.2:9999",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1293,7 +1293,7 @@ func Test_buildConfig(t *testing.T) {
|
|||
URL: "http://127.0.0.2:9999",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1356,7 +1356,7 @@ func Test_buildConfig(t *testing.T) {
|
|||
URL: "http://127.0.0.2:9999",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1424,7 +1424,7 @@ func Test_buildConfig(t *testing.T) {
|
|||
URL: "http://127.0.0.2:9999",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1480,7 +1480,7 @@ func Test_buildConfig(t *testing.T) {
|
|||
URL: "http://127.0.0.1:9999",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1537,7 +1537,7 @@ func Test_buildConfig(t *testing.T) {
|
|||
URL: "h2c://127.0.0.1:8080",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1588,7 +1588,7 @@ func Test_buildConfig(t *testing.T) {
|
|||
URL: "http://127.0.0.1:9999",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1601,7 +1601,7 @@ func Test_buildConfig(t *testing.T) {
|
|||
URL: "http://127.0.0.1:8080",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1800,7 +1800,7 @@ func Test_buildConfig(t *testing.T) {
|
|||
URL: "http://127.0.0.1:9999",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -1867,7 +1867,7 @@ func Test_buildConfig(t *testing.T) {
|
|||
URL: "http://127.0.0.1:9999",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -2279,7 +2279,7 @@ func Test_buildConfig(t *testing.T) {
|
|||
URL: "http://127.0.0.2:9999",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -2370,7 +2370,7 @@ func Test_buildConfig(t *testing.T) {
|
|||
URL: "http://127.0.0.2:9999",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -2587,7 +2587,7 @@ func Test_buildConfig(t *testing.T) {
|
|||
URL: "http://127.0.0.1:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -2600,7 +2600,7 @@ func Test_buildConfig(t *testing.T) {
|
|||
URL: "http://127.0.0.2:80",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -2819,7 +2819,7 @@ func Test_buildConfig(t *testing.T) {
|
|||
URL: "http://127.0.0.1:9999",
|
||||
},
|
||||
},
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -2906,7 +2906,7 @@ func Test_buildConfigAllowEmptyServicesTrue(t *testing.T) {
|
|||
"Test": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Servers: nil,
|
||||
PassHostHeader: Bool(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
|
@ -3254,5 +3254,4 @@ func extractNamespacesFromProvider(providers []*Provider) []string {
|
|||
return res
|
||||
}
|
||||
|
||||
func Int(v int) *int { return &v }
|
||||
func Bool(v bool) *bool { return &v }
|
||||
func pointer[T any](v T) *T { return &v }
|
||||
|
|
|
@ -32,7 +32,7 @@ func New(staticCfg static.Configuration) *Provider {
|
|||
}
|
||||
|
||||
// ThrottleDuration returns the throttle duration.
|
||||
func (i Provider) ThrottleDuration() time.Duration {
|
||||
func (i *Provider) ThrottleDuration() time.Duration {
|
||||
return 0
|
||||
}
|
||||
|
||||
|
|
|
@ -171,7 +171,7 @@ func (p *ReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
|||
if reqUpType != "" {
|
||||
outReq.Header.Set("Connection", "Upgrade")
|
||||
outReq.Header.Set("Upgrade", reqUpType)
|
||||
if reqUpType == "websocket" {
|
||||
if strings.EqualFold(reqUpType, "websocket") {
|
||||
cleanWebSocketHeaders(&outReq.Header)
|
||||
}
|
||||
}
|
||||
|
@ -353,6 +353,7 @@ type fasthttpHeader interface {
|
|||
SetBytesV(key string, value []byte)
|
||||
DelBytes(key []byte)
|
||||
Del(key string)
|
||||
ConnectionUpgrade() bool
|
||||
}
|
||||
|
||||
// removeConnectionHeaders removes hop-by-hop headers listed in the "Connection" header of h.
|
||||
|
|
|
@ -2,7 +2,9 @@ package fast
|
|||
|
||||
import (
|
||||
"bufio"
|
||||
"crypto/sha1"
|
||||
"crypto/tls"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
|
@ -19,6 +21,34 @@ import (
|
|||
"golang.org/x/net/websocket"
|
||||
)
|
||||
|
||||
func TestWebSocketUpgradeCase(t *testing.T) {
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
challengeKey := r.Header.Get("Sec-Websocket-Key")
|
||||
|
||||
hijacker, ok := w.(http.Hijacker)
|
||||
require.True(t, ok)
|
||||
|
||||
c, _, err := hijacker.Hijack()
|
||||
require.NoError(t, err)
|
||||
|
||||
// Force answer with "Connection: upgrade" in lowercase.
|
||||
_, err = c.Write([]byte("HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: upgrade\r\nSec-WebSocket-Accept: " + computeAcceptKey(challengeKey) + "\r\n\n"))
|
||||
require.NoError(t, err)
|
||||
}))
|
||||
defer srv.Close()
|
||||
|
||||
proxy := createProxyWithForwarder(t, srv.URL, createConnectionPool(srv.URL, nil))
|
||||
|
||||
proxyAddr := proxy.Listener.Addr().String()
|
||||
_, conn, err := newWebsocketRequest(
|
||||
withServer(proxyAddr),
|
||||
withPath("/ws"),
|
||||
).open()
|
||||
require.NoError(t, err)
|
||||
|
||||
conn.Close()
|
||||
}
|
||||
|
||||
func TestWebSocketTCPClose(t *testing.T) {
|
||||
errChan := make(chan error, 1)
|
||||
upgrader := gorillawebsocket.Upgrader{}
|
||||
|
@ -691,3 +721,10 @@ func createProxyWithForwarder(t *testing.T, uri string, pool *connPool) *httptes
|
|||
|
||||
return srv
|
||||
}
|
||||
|
||||
func computeAcceptKey(challengeKey string) string {
|
||||
h := sha1.New() // #nosec G401 -- (CWE-326) https://datatracker.ietf.org/doc/html/rfc6455#page-54
|
||||
h.Write([]byte(challengeKey))
|
||||
h.Write([]byte("258EAFA5-E914-47DA-95CA-C5AB0DC85B11"))
|
||||
return base64.StdEncoding.EncodeToString(h.Sum(nil))
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package fast
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
|
@ -100,7 +99,7 @@ func upgradeType(h http.Header) string {
|
|||
}
|
||||
|
||||
func upgradeTypeFastHTTP(h fasthttpHeader) string {
|
||||
if !bytes.Contains(h.Peek("Connection"), []byte("Upgrade")) {
|
||||
if !h.ConnectionUpgrade() {
|
||||
return ""
|
||||
}
|
||||
|
||||
|
|
|
@ -78,12 +78,12 @@ func init() {
|
|||
Interval: ptypes.Duration(111 * time.Second),
|
||||
Timeout: ptypes.Duration(111 * time.Second),
|
||||
Hostname: "foo",
|
||||
FollowRedirects: boolPtr(true),
|
||||
FollowRedirects: pointer(true),
|
||||
Headers: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
},
|
||||
PassHostHeader: boolPtr(true),
|
||||
PassHostHeader: pointer(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(111 * time.Second),
|
||||
},
|
||||
|
@ -100,7 +100,7 @@ func init() {
|
|||
Services: []dynamic.WRRService{
|
||||
{
|
||||
Name: "foo",
|
||||
Weight: intPtr(42),
|
||||
Weight: pointer(42),
|
||||
},
|
||||
},
|
||||
Sticky: &dynamic.Sticky{
|
||||
|
@ -116,7 +116,7 @@ func init() {
|
|||
"baz": {
|
||||
Mirroring: &dynamic.Mirroring{
|
||||
Service: "foo",
|
||||
MaxBodySize: int64Ptr(42),
|
||||
MaxBodySize: pointer[int64](42),
|
||||
Mirrors: []dynamic.MirrorService{
|
||||
{
|
||||
Name: "foo",
|
||||
|
@ -380,7 +380,7 @@ func init() {
|
|||
Services: []dynamic.TCPWRRService{
|
||||
{
|
||||
Name: "foo",
|
||||
Weight: intPtr(42),
|
||||
Weight: pointer(42),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -427,7 +427,7 @@ func init() {
|
|||
Services: []dynamic.UDPWRRService{
|
||||
{
|
||||
Name: "foo",
|
||||
Weight: intPtr(42),
|
||||
Weight: pointer(42),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -484,7 +484,7 @@ func TestAnonymize_dynamicConfiguration(t *testing.T) {
|
|||
}
|
||||
|
||||
expected := strings.TrimSuffix(string(expectedConfiguration), "\n")
|
||||
assert.Equal(t, expected, cleanJSON)
|
||||
assert.JSONEq(t, expected, cleanJSON)
|
||||
}
|
||||
|
||||
func TestSecure_dynamicConfiguration(t *testing.T) {
|
||||
|
@ -501,7 +501,7 @@ func TestSecure_dynamicConfiguration(t *testing.T) {
|
|||
}
|
||||
|
||||
expected := strings.TrimSuffix(string(expectedConfiguration), "\n")
|
||||
assert.Equal(t, expected, cleanJSON)
|
||||
assert.JSONEq(t, expected, cleanJSON)
|
||||
}
|
||||
|
||||
func TestDo_staticConfiguration(t *testing.T) {
|
||||
|
@ -950,17 +950,7 @@ func TestDo_staticConfiguration(t *testing.T) {
|
|||
}
|
||||
|
||||
expected := strings.TrimSuffix(string(expectedConfiguration), "\n")
|
||||
assert.Equal(t, expected, cleanJSON)
|
||||
assert.JSONEq(t, expected, cleanJSON)
|
||||
}
|
||||
|
||||
func boolPtr(value bool) *bool {
|
||||
return &value
|
||||
}
|
||||
|
||||
func intPtr(value int) *int {
|
||||
return &value
|
||||
}
|
||||
|
||||
func int64Ptr(value int64) *int64 {
|
||||
return &value
|
||||
}
|
||||
func pointer[T any](v T) *T { return &v }
|
||||
|
|
|
@ -323,7 +323,7 @@ func TestListenProvidersThrottleProviderConfigReload(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
providerAggregator := aggregator.ProviderAggregator{}
|
||||
providerAggregator := &aggregator.ProviderAggregator{}
|
||||
err := providerAggregator.AddProvider(pvd)
|
||||
assert.NoError(t, err)
|
||||
|
||||
|
@ -507,7 +507,7 @@ func TestListenProvidersIgnoreSameConfig(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
providerAggregator := aggregator.ProviderAggregator{}
|
||||
providerAggregator := &aggregator.ProviderAggregator{}
|
||||
err := providerAggregator.AddProvider(pvd)
|
||||
assert.NoError(t, err)
|
||||
|
||||
|
@ -651,7 +651,7 @@ func TestListenProvidersIgnoreIntermediateConfigs(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
providerAggregator := aggregator.ProviderAggregator{}
|
||||
providerAggregator := &aggregator.ProviderAggregator{}
|
||||
err := providerAggregator.AddProvider(pvd)
|
||||
assert.NoError(t, err)
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ func isPostgres(br *bufio.Reader) (bool, error) {
|
|||
if err != nil {
|
||||
var opErr *net.OpError
|
||||
if !errors.Is(err, io.EOF) && (!errors.As(err, &opErr) || !opErr.Timeout()) {
|
||||
log.Error().Err(err).Msg("Error while Peeking first byte")
|
||||
log.Debug().Err(err).Msg("Error while peeking first bytes")
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
|
|
|
@ -364,7 +364,7 @@ func clientHelloInfo(br *bufio.Reader) (*clientHello, error) {
|
|||
if err != nil {
|
||||
var opErr *net.OpError
|
||||
if !errors.Is(err, io.EOF) && (!errors.As(err, &opErr) || !opErr.Timeout()) {
|
||||
log.Error().Err(err).Msg("Error while Peeking first byte")
|
||||
log.Debug().Err(err).Msg("Error while peeking first byte")
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
@ -390,7 +390,7 @@ func clientHelloInfo(br *bufio.Reader) (*clientHello, error) {
|
|||
const recordHeaderLen = 5
|
||||
hdr, err = br.Peek(recordHeaderLen)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Error while Peeking hello")
|
||||
log.Error().Err(err).Msg("Error while peeking client hello header")
|
||||
return &clientHello{
|
||||
peeked: getPeeked(br),
|
||||
}, nil
|
||||
|
@ -404,7 +404,7 @@ func clientHelloInfo(br *bufio.Reader) (*clientHello, error) {
|
|||
|
||||
helloBytes, err := br.Peek(recordHeaderLen + recLen)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Error while Hello")
|
||||
log.Error().Err(err).Msg("Error while peeking client hello bytes")
|
||||
return &clientHello{
|
||||
isTLS: true,
|
||||
peeked: getPeeked(br),
|
||||
|
@ -433,7 +433,7 @@ func clientHelloInfo(br *bufio.Reader) (*clientHello, error) {
|
|||
func getPeeked(br *bufio.Reader) string {
|
||||
peeked, err := br.Peek(br.Buffered())
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Could not get anything")
|
||||
log.Error().Err(err).Msg("Error while peeking bytes")
|
||||
return ""
|
||||
}
|
||||
return string(peeked)
|
||||
|
|
|
@ -625,17 +625,17 @@ func createHTTPServer(ctx context.Context, ln net.Listener, configuration *stati
|
|||
|
||||
handler = contenttype.DisableAutoDetection(handler)
|
||||
|
||||
debugConnection := os.Getenv(debugConnectionEnv) != ""
|
||||
if debugConnection || (configuration.Transport != nil && (configuration.Transport.KeepAliveMaxTime > 0 || configuration.Transport.KeepAliveMaxRequests > 0)) {
|
||||
handler = newKeepAliveMiddleware(handler, configuration.Transport.KeepAliveMaxRequests, configuration.Transport.KeepAliveMaxTime)
|
||||
}
|
||||
|
||||
if withH2c {
|
||||
handler = h2c.NewHandler(handler, &http2.Server{
|
||||
MaxConcurrentStreams: uint32(configuration.HTTP2.MaxConcurrentStreams),
|
||||
})
|
||||
}
|
||||
|
||||
debugConnection := os.Getenv(debugConnectionEnv) != ""
|
||||
if debugConnection || (configuration.Transport != nil && (configuration.Transport.KeepAliveMaxTime > 0 || configuration.Transport.KeepAliveMaxRequests > 0)) {
|
||||
handler = newKeepAliveMiddleware(handler, configuration.Transport.KeepAliveMaxRequests, configuration.Transport.KeepAliveMaxTime)
|
||||
}
|
||||
|
||||
serverHTTP := &http.Server{
|
||||
Handler: handler,
|
||||
ErrorLog: stdlog.New(logs.NoLevel(log.Logger, zerolog.DebugLevel), "", 0),
|
||||
|
|
|
@ -3,6 +3,7 @@ package server
|
|||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"io"
|
||||
"net"
|
||||
|
@ -17,6 +18,7 @@ import (
|
|||
"github.com/traefik/traefik/v3/pkg/config/static"
|
||||
tcprouter "github.com/traefik/traefik/v3/pkg/server/router/tcp"
|
||||
"github.com/traefik/traefik/v3/pkg/tcp"
|
||||
"golang.org/x/net/http2"
|
||||
)
|
||||
|
||||
func TestShutdownHijacked(t *testing.T) {
|
||||
|
@ -330,3 +332,53 @@ func TestKeepAliveMaxTime(t *testing.T) {
|
|||
err = resp.Body.Close()
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestKeepAliveH2c(t *testing.T) {
|
||||
epConfig := &static.EntryPointsTransport{}
|
||||
epConfig.SetDefaults()
|
||||
epConfig.KeepAliveMaxRequests = 1
|
||||
|
||||
entryPoint, err := NewTCPEntryPoint(context.Background(), "", &static.EntryPoint{
|
||||
Address: ":0",
|
||||
Transport: epConfig,
|
||||
ForwardedHeaders: &static.ForwardedHeaders{},
|
||||
HTTP2: &static.HTTP2Config{},
|
||||
}, nil, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
router, err := tcprouter.NewRouter()
|
||||
require.NoError(t, err)
|
||||
|
||||
router.SetHTTPHandler(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
rw.WriteHeader(http.StatusOK)
|
||||
}))
|
||||
|
||||
conn, err := startEntrypoint(entryPoint, router)
|
||||
require.NoError(t, err)
|
||||
|
||||
http2Transport := &http2.Transport{
|
||||
AllowHTTP: true,
|
||||
DialTLSContext: func(ctx context.Context, network, addr string, cfg *tls.Config) (net.Conn, error) {
|
||||
return conn, nil
|
||||
},
|
||||
}
|
||||
|
||||
client := &http.Client{Transport: http2Transport}
|
||||
|
||||
resp, err := client.Get("http://" + entryPoint.listener.Addr().String())
|
||||
require.NoError(t, err)
|
||||
require.False(t, resp.Close)
|
||||
err = resp.Body.Close()
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = client.Get("http://" + entryPoint.listener.Addr().String())
|
||||
require.Error(t, err)
|
||||
// Unlike HTTP/1, where we can directly check `resp.Close`, HTTP/2 uses a different
|
||||
// mechanism: it sends a GOAWAY frame when the connection is closing.
|
||||
// We can only check the error type. The error received should be poll.ErrClosed from
|
||||
// the `internal/poll` package, but we cannot directly reference the error type due to
|
||||
// package restrictions. Since this error message ("use of closed network connection")
|
||||
// is distinct and specific, we rely on its consistency, assuming it is stable and unlikely
|
||||
// to change.
|
||||
require.Contains(t, err.Error(), "use of closed network connection")
|
||||
}
|
||||
|
|
|
@ -8,11 +8,6 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
type serviceManager interface {
|
||||
BuildHTTP(rootCtx context.Context, serviceName string) (http.Handler, error)
|
||||
LaunchHealthCheck(ctx context.Context)
|
||||
}
|
||||
|
||||
// InternalHandlers is the internal HTTP handlers builder.
|
||||
type InternalHandlers struct {
|
||||
api http.Handler
|
||||
|
@ -21,26 +16,24 @@ type InternalHandlers struct {
|
|||
prometheus http.Handler
|
||||
ping http.Handler
|
||||
acmeHTTP http.Handler
|
||||
serviceManager
|
||||
}
|
||||
|
||||
// NewInternalHandlers creates a new InternalHandlers.
|
||||
func NewInternalHandlers(next serviceManager, apiHandler, rest, metricsHandler, pingHandler, dashboard, acmeHTTP http.Handler) *InternalHandlers {
|
||||
func NewInternalHandlers(apiHandler, rest, metricsHandler, pingHandler, dashboard, acmeHTTP http.Handler) *InternalHandlers {
|
||||
return &InternalHandlers{
|
||||
api: apiHandler,
|
||||
dashboard: dashboard,
|
||||
rest: rest,
|
||||
prometheus: metricsHandler,
|
||||
ping: pingHandler,
|
||||
acmeHTTP: acmeHTTP,
|
||||
serviceManager: next,
|
||||
api: apiHandler,
|
||||
dashboard: dashboard,
|
||||
rest: rest,
|
||||
prometheus: metricsHandler,
|
||||
ping: pingHandler,
|
||||
acmeHTTP: acmeHTTP,
|
||||
}
|
||||
}
|
||||
|
||||
// BuildHTTP builds an HTTP handler.
|
||||
func (m *InternalHandlers) BuildHTTP(rootCtx context.Context, serviceName string) (http.Handler, error) {
|
||||
if !strings.HasSuffix(serviceName, "@internal") {
|
||||
return m.serviceManager.BuildHTTP(rootCtx, serviceName)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
internalHandler, err := m.get(serviceName)
|
||||
|
|
|
@ -10,18 +10,20 @@ import (
|
|||
"github.com/traefik/traefik/v3/pkg/config/dynamic"
|
||||
)
|
||||
|
||||
func pointer[T any](v T) *T { return &v }
|
||||
|
||||
func TestBalancer(t *testing.T) {
|
||||
balancer := New(nil, false)
|
||||
|
||||
balancer.Add("first", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
rw.Header().Set("server", "first")
|
||||
rw.WriteHeader(http.StatusOK)
|
||||
}), Int(3))
|
||||
}), pointer(3))
|
||||
|
||||
balancer.Add("second", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
rw.Header().Set("server", "second")
|
||||
rw.WriteHeader(http.StatusOK)
|
||||
}), Int(1))
|
||||
}), pointer(1))
|
||||
|
||||
recorder := &responseRecorder{ResponseRecorder: httptest.NewRecorder(), save: map[string]int{}}
|
||||
for range 4 {
|
||||
|
@ -47,9 +49,9 @@ func TestBalancerOneServerZeroWeight(t *testing.T) {
|
|||
balancer.Add("first", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
rw.Header().Set("server", "first")
|
||||
rw.WriteHeader(http.StatusOK)
|
||||
}), Int(1))
|
||||
}), pointer(1))
|
||||
|
||||
balancer.Add("second", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {}), Int(0))
|
||||
balancer.Add("second", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {}), pointer(0))
|
||||
|
||||
recorder := &responseRecorder{ResponseRecorder: httptest.NewRecorder(), save: map[string]int{}}
|
||||
for range 3 {
|
||||
|
@ -68,11 +70,11 @@ func TestBalancerNoServiceUp(t *testing.T) {
|
|||
|
||||
balancer.Add("first", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
rw.WriteHeader(http.StatusInternalServerError)
|
||||
}), Int(1))
|
||||
}), pointer(1))
|
||||
|
||||
balancer.Add("second", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
rw.WriteHeader(http.StatusInternalServerError)
|
||||
}), Int(1))
|
||||
}), pointer(1))
|
||||
|
||||
balancer.SetStatus(context.WithValue(context.Background(), serviceName, "parent"), "first", false)
|
||||
balancer.SetStatus(context.WithValue(context.Background(), serviceName, "parent"), "second", false)
|
||||
|
@ -89,11 +91,11 @@ func TestBalancerOneServerDown(t *testing.T) {
|
|||
balancer.Add("first", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
rw.Header().Set("server", "first")
|
||||
rw.WriteHeader(http.StatusOK)
|
||||
}), Int(1))
|
||||
}), pointer(1))
|
||||
|
||||
balancer.Add("second", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
rw.WriteHeader(http.StatusInternalServerError)
|
||||
}), Int(1))
|
||||
}), pointer(1))
|
||||
balancer.SetStatus(context.WithValue(context.Background(), serviceName, "parent"), "second", false)
|
||||
|
||||
recorder := &responseRecorder{ResponseRecorder: httptest.NewRecorder(), save: map[string]int{}}
|
||||
|
@ -110,12 +112,12 @@ func TestBalancerDownThenUp(t *testing.T) {
|
|||
balancer.Add("first", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
rw.Header().Set("server", "first")
|
||||
rw.WriteHeader(http.StatusOK)
|
||||
}), Int(1))
|
||||
}), pointer(1))
|
||||
|
||||
balancer.Add("second", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
rw.Header().Set("server", "second")
|
||||
rw.WriteHeader(http.StatusOK)
|
||||
}), Int(1))
|
||||
}), pointer(1))
|
||||
balancer.SetStatus(context.WithValue(context.Background(), serviceName, "parent"), "second", false)
|
||||
|
||||
recorder := &responseRecorder{ResponseRecorder: httptest.NewRecorder(), save: map[string]int{}}
|
||||
|
@ -139,30 +141,30 @@ func TestBalancerPropagate(t *testing.T) {
|
|||
balancer1.Add("first", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
rw.Header().Set("server", "first")
|
||||
rw.WriteHeader(http.StatusOK)
|
||||
}), Int(1))
|
||||
}), pointer(1))
|
||||
balancer1.Add("second", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
rw.Header().Set("server", "second")
|
||||
rw.WriteHeader(http.StatusOK)
|
||||
}), Int(1))
|
||||
}), pointer(1))
|
||||
|
||||
balancer2 := New(nil, true)
|
||||
balancer2.Add("third", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
rw.Header().Set("server", "third")
|
||||
rw.WriteHeader(http.StatusOK)
|
||||
}), Int(1))
|
||||
}), pointer(1))
|
||||
balancer2.Add("fourth", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
rw.Header().Set("server", "fourth")
|
||||
rw.WriteHeader(http.StatusOK)
|
||||
}), Int(1))
|
||||
}), pointer(1))
|
||||
|
||||
topBalancer := New(nil, true)
|
||||
topBalancer.Add("balancer1", balancer1, Int(1))
|
||||
topBalancer.Add("balancer1", balancer1, pointer(1))
|
||||
_ = balancer1.RegisterStatusUpdater(func(up bool) {
|
||||
topBalancer.SetStatus(context.WithValue(context.Background(), serviceName, "top"), "balancer1", up)
|
||||
// TODO(mpl): if test gets flaky, add channel or something here to signal that
|
||||
// propagation is done, and wait on it before sending request.
|
||||
})
|
||||
topBalancer.Add("balancer2", balancer2, Int(1))
|
||||
topBalancer.Add("balancer2", balancer2, pointer(1))
|
||||
_ = balancer2.RegisterStatusUpdater(func(up bool) {
|
||||
topBalancer.SetStatus(context.WithValue(context.Background(), serviceName, "top"), "balancer2", up)
|
||||
})
|
||||
|
@ -209,8 +211,8 @@ func TestBalancerPropagate(t *testing.T) {
|
|||
func TestBalancerAllServersZeroWeight(t *testing.T) {
|
||||
balancer := New(nil, false)
|
||||
|
||||
balancer.Add("test", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {}), Int(0))
|
||||
balancer.Add("test2", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {}), Int(0))
|
||||
balancer.Add("test", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {}), pointer(0))
|
||||
balancer.Add("test2", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {}), pointer(0))
|
||||
|
||||
recorder := httptest.NewRecorder()
|
||||
balancer.ServeHTTP(recorder, httptest.NewRequest(http.MethodGet, "/", nil))
|
||||
|
@ -233,12 +235,12 @@ func TestSticky(t *testing.T) {
|
|||
balancer.Add("first", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
rw.Header().Set("server", "first")
|
||||
rw.WriteHeader(http.StatusOK)
|
||||
}), Int(1))
|
||||
}), pointer(1))
|
||||
|
||||
balancer.Add("second", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
rw.Header().Set("server", "second")
|
||||
rw.WriteHeader(http.StatusOK)
|
||||
}), Int(2))
|
||||
}), pointer(2))
|
||||
|
||||
recorder := &responseRecorder{
|
||||
ResponseRecorder: httptest.NewRecorder(),
|
||||
|
@ -275,12 +277,12 @@ func TestSticky_FallBack(t *testing.T) {
|
|||
balancer.Add("first", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
rw.Header().Set("server", "first")
|
||||
rw.WriteHeader(http.StatusOK)
|
||||
}), Int(1))
|
||||
}), pointer(1))
|
||||
|
||||
balancer.Add("second", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
rw.Header().Set("server", "second")
|
||||
rw.WriteHeader(http.StatusOK)
|
||||
}), Int(2))
|
||||
}), pointer(2))
|
||||
|
||||
recorder := &responseRecorder{ResponseRecorder: httptest.NewRecorder(), save: map[string]int{}}
|
||||
|
||||
|
@ -304,12 +306,12 @@ func TestBalancerBias(t *testing.T) {
|
|||
balancer.Add("first", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
rw.Header().Set("server", "A")
|
||||
rw.WriteHeader(http.StatusOK)
|
||||
}), Int(11))
|
||||
}), pointer(11))
|
||||
|
||||
balancer.Add("second", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
rw.Header().Set("server", "B")
|
||||
rw.WriteHeader(http.StatusOK)
|
||||
}), Int(3))
|
||||
}), pointer(3))
|
||||
|
||||
recorder := &responseRecorder{ResponseRecorder: httptest.NewRecorder(), save: map[string]int{}}
|
||||
|
||||
|
@ -322,8 +324,6 @@ func TestBalancerBias(t *testing.T) {
|
|||
assert.Equal(t, wantSequence, recorder.sequence)
|
||||
}
|
||||
|
||||
func Int(v int) *int { return &v }
|
||||
|
||||
type responseRecorder struct {
|
||||
*httptest.ResponseRecorder
|
||||
save map[string]int
|
||||
|
|
|
@ -74,13 +74,12 @@ func NewManagerFactory(staticConfiguration static.Configuration, routinesPool *s
|
|||
}
|
||||
|
||||
// Build creates a service manager.
|
||||
func (f *ManagerFactory) Build(configuration *runtime.Configuration) *InternalHandlers {
|
||||
svcManager := NewManager(configuration.Services, f.observabilityMgr, f.routinesPool, f.transportManager, f.proxyBuilder)
|
||||
|
||||
func (f *ManagerFactory) Build(configuration *runtime.Configuration) *Manager {
|
||||
var apiHandler http.Handler
|
||||
if f.api != nil {
|
||||
apiHandler = f.api(configuration)
|
||||
}
|
||||
|
||||
return NewInternalHandlers(svcManager, apiHandler, f.restHandler, f.metricsHandler, f.pingHandler, f.dashboardHandler, f.acmeHTTPHandler)
|
||||
internalHandlers := NewInternalHandlers(apiHandler, f.restHandler, f.metricsHandler, f.pingHandler, f.dashboardHandler, f.acmeHTTPHandler)
|
||||
return NewManager(configuration.Services, f.observabilityMgr, f.routinesPool, f.transportManager, f.proxyBuilder, internalHandlers)
|
||||
}
|
||||
|
|
|
@ -46,12 +46,18 @@ type ProxyBuilder interface {
|
|||
Update(configs map[string]*dynamic.ServersTransport)
|
||||
}
|
||||
|
||||
// ServiceBuilder is a Service builder.
|
||||
type ServiceBuilder interface {
|
||||
BuildHTTP(rootCtx context.Context, serviceName string) (http.Handler, error)
|
||||
}
|
||||
|
||||
// Manager The service manager.
|
||||
type Manager struct {
|
||||
routinePool *safe.Pool
|
||||
observabilityMgr *middleware.ObservabilityMgr
|
||||
transportManager httputil.TransportManager
|
||||
proxyBuilder ProxyBuilder
|
||||
serviceBuilders []ServiceBuilder
|
||||
|
||||
services map[string]http.Handler
|
||||
configs map[string]*runtime.ServiceInfo
|
||||
|
@ -60,12 +66,13 @@ type Manager struct {
|
|||
}
|
||||
|
||||
// NewManager creates a new Manager.
|
||||
func NewManager(configs map[string]*runtime.ServiceInfo, observabilityMgr *middleware.ObservabilityMgr, routinePool *safe.Pool, transportManager httputil.TransportManager, proxyBuilder ProxyBuilder) *Manager {
|
||||
func NewManager(configs map[string]*runtime.ServiceInfo, observabilityMgr *middleware.ObservabilityMgr, routinePool *safe.Pool, transportManager httputil.TransportManager, proxyBuilder ProxyBuilder, serviceBuilders ...ServiceBuilder) *Manager {
|
||||
return &Manager{
|
||||
routinePool: routinePool,
|
||||
observabilityMgr: observabilityMgr,
|
||||
transportManager: transportManager,
|
||||
proxyBuilder: proxyBuilder,
|
||||
serviceBuilders: serviceBuilders,
|
||||
services: make(map[string]http.Handler),
|
||||
configs: configs,
|
||||
healthCheckers: make(map[string]*healthcheck.ServiceHealthChecker),
|
||||
|
@ -85,6 +92,18 @@ func (m *Manager) BuildHTTP(rootCtx context.Context, serviceName string) (http.H
|
|||
return handler, nil
|
||||
}
|
||||
|
||||
// Must be before we get configs to handle services without config.
|
||||
for _, builder := range m.serviceBuilders {
|
||||
handler, err := builder.BuildHTTP(rootCtx, serviceName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if handler != nil {
|
||||
m.services[serviceName] = handler
|
||||
return handler, nil
|
||||
}
|
||||
}
|
||||
|
||||
conf, ok := m.configs[serviceName]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("the service %q does not exist", serviceName)
|
||||
|
|
|
@ -20,6 +20,8 @@ import (
|
|||
"github.com/traefik/traefik/v3/pkg/testhelpers"
|
||||
)
|
||||
|
||||
func pointer[T any](v T) *T { return &v }
|
||||
|
||||
func TestGetLoadBalancer(t *testing.T) {
|
||||
sm := Manager{
|
||||
transportManager: &transportManagerMock{},
|
||||
|
@ -235,7 +237,7 @@ func TestGetLoadBalancerServiceHandler(t *testing.T) {
|
|||
serviceName: "test",
|
||||
service: &dynamic.ServersLoadBalancer{
|
||||
Sticky: &dynamic.Sticky{Cookie: &dynamic.Cookie{}},
|
||||
PassHostHeader: func(v bool) *bool { return &v }(true),
|
||||
PassHostHeader: pointer(true),
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: serverPassHost.URL,
|
||||
|
@ -253,7 +255,7 @@ func TestGetLoadBalancerServiceHandler(t *testing.T) {
|
|||
desc: "PassHost doesn't pass the host instead of the IP",
|
||||
serviceName: "test",
|
||||
service: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: boolPtr(false),
|
||||
PassHostHeader: pointer(false),
|
||||
Sticky: &dynamic.Sticky{Cookie: &dynamic.Cookie{}},
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
|
@ -448,6 +450,48 @@ func Test1xxResponses(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
type serviceBuilderFunc func(ctx context.Context, serviceName string) (http.Handler, error)
|
||||
|
||||
func (s serviceBuilderFunc) BuildHTTP(ctx context.Context, serviceName string) (http.Handler, error) {
|
||||
return s(ctx, serviceName)
|
||||
}
|
||||
|
||||
type internalHandler struct{}
|
||||
|
||||
func (internalHandler) ServeHTTP(_ http.ResponseWriter, _ *http.Request) {}
|
||||
|
||||
func TestManager_ServiceBuilders(t *testing.T) {
|
||||
var internalHandler internalHandler
|
||||
|
||||
manager := NewManager(map[string]*runtime.ServiceInfo{
|
||||
"test@test": {
|
||||
Service: &dynamic.Service{
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{},
|
||||
},
|
||||
},
|
||||
}, nil, nil, &TransportManager{
|
||||
roundTrippers: map[string]http.RoundTripper{
|
||||
"default@internal": http.DefaultTransport,
|
||||
},
|
||||
}, nil, serviceBuilderFunc(func(rootCtx context.Context, serviceName string) (http.Handler, error) {
|
||||
if strings.HasSuffix(serviceName, "@internal") {
|
||||
return internalHandler, nil
|
||||
}
|
||||
return nil, nil
|
||||
}))
|
||||
|
||||
h, err := manager.BuildHTTP(context.Background(), "test@internal")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, internalHandler, h)
|
||||
|
||||
h, err = manager.BuildHTTP(context.Background(), "test@test")
|
||||
require.NoError(t, err)
|
||||
assert.NotNil(t, h)
|
||||
|
||||
_, err = manager.BuildHTTP(context.Background(), "wrong@test")
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestManager_Build(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
|
|
|
@ -27,10 +27,6 @@ import (
|
|||
"github.com/traefik/traefik/v3/pkg/types"
|
||||
)
|
||||
|
||||
func Int32(i int32) *int32 {
|
||||
return &i
|
||||
}
|
||||
|
||||
// LocalhostCert is a PEM-encoded TLS cert
|
||||
// for host example.com, www.example.com
|
||||
// expiring at Jan 29 16:00:00 2084 GMT.
|
||||
|
@ -128,7 +124,7 @@ func TestKeepConnectionWhenSameConfiguration(t *testing.T) {
|
|||
rw.WriteHeader(http.StatusOK)
|
||||
}))
|
||||
|
||||
connCount := Int32(0)
|
||||
connCount := pointer[int32](0)
|
||||
srv.Config.ConnState = func(conn net.Conn, state http.ConnState) {
|
||||
if state == http.StateNew {
|
||||
atomic.AddInt32(connCount, 1)
|
||||
|
|
|
@ -79,7 +79,7 @@ func (p *Proxy) ServeTCP(conn WriteCloser) {
|
|||
<-errChan
|
||||
}
|
||||
|
||||
func (p Proxy) dialBackend() (WriteCloser, error) {
|
||||
func (p *Proxy) dialBackend() (WriteCloser, error) {
|
||||
conn, err := p.dialer.Dial("tcp", p.address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -88,7 +88,7 @@ func (p Proxy) dialBackend() (WriteCloser, error) {
|
|||
return conn.(WriteCloser), nil
|
||||
}
|
||||
|
||||
func (p Proxy) connCopy(dst, src WriteCloser, errCh chan error) {
|
||||
func (p *Proxy) connCopy(dst, src WriteCloser, errCh chan error) {
|
||||
_, err := io.Copy(dst, src)
|
||||
errCh <- err
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
|
@ -45,13 +46,6 @@ var (
|
|||
}
|
||||
)
|
||||
|
||||
// Certificate holds a SSL cert/key pair
|
||||
// Certs and Key could be either a file path, or the file content itself.
|
||||
type Certificate struct {
|
||||
CertFile types.FileOrContent `json:"certFile,omitempty" toml:"certFile,omitempty" yaml:"certFile,omitempty"`
|
||||
KeyFile types.FileOrContent `json:"keyFile,omitempty" toml:"keyFile,omitempty" yaml:"keyFile,omitempty" loggable:"false"`
|
||||
}
|
||||
|
||||
// Certificates defines traefik certificates type
|
||||
// Certs and Keys could be either a file path, or the file content itself.
|
||||
type Certificates []Certificate
|
||||
|
@ -73,6 +67,13 @@ func (c Certificates) GetCertificates() []tls.Certificate {
|
|||
return certs
|
||||
}
|
||||
|
||||
// Certificate holds a SSL cert/key pair
|
||||
// Certs and Key could be either a file path, or the file content itself.
|
||||
type Certificate struct {
|
||||
CertFile types.FileOrContent `json:"certFile,omitempty" toml:"certFile,omitempty" yaml:"certFile,omitempty"`
|
||||
KeyFile types.FileOrContent `json:"keyFile,omitempty" toml:"keyFile,omitempty" yaml:"keyFile,omitempty" loggable:"false"`
|
||||
}
|
||||
|
||||
// AppendCertificate appends a Certificate to a certificates map keyed by store name.
|
||||
func (c *Certificate) AppendCertificate(certs map[string]map[string]*tls.Certificate, storeName string) error {
|
||||
certContent, err := c.CertFile.Read()
|
||||
|
@ -166,31 +167,6 @@ func (c *Certificate) GetCertificateFromBytes() (tls.Certificate, error) {
|
|||
return cert, nil
|
||||
}
|
||||
|
||||
// GetTruncatedCertificateName truncates the certificate name.
|
||||
func (c *Certificate) GetTruncatedCertificateName() string {
|
||||
certName := c.CertFile.String()
|
||||
|
||||
// Truncate certificate information only if it's a well formed certificate content with more than 50 characters
|
||||
if !c.CertFile.IsPath() && strings.HasPrefix(certName, certificateHeader) && len(certName) > len(certificateHeader)+50 {
|
||||
certName = strings.TrimPrefix(c.CertFile.String(), certificateHeader)[:50]
|
||||
}
|
||||
|
||||
return certName
|
||||
}
|
||||
|
||||
// String is the method to format the flag's value, part of the flag.Value interface.
|
||||
// The String method's output will be used in diagnostics.
|
||||
func (c *Certificates) String() string {
|
||||
if len(*c) == 0 {
|
||||
return ""
|
||||
}
|
||||
var result []string
|
||||
for _, certificate := range *c {
|
||||
result = append(result, certificate.CertFile.String()+","+certificate.KeyFile.String())
|
||||
}
|
||||
return strings.Join(result, ";")
|
||||
}
|
||||
|
||||
// Set is the method to set the flag value, part of the flag.Value interface.
|
||||
// Set's argument is a string to be parsed to set the flag.
|
||||
// It's a comma-separated list, so we split it.
|
||||
|
@ -209,9 +185,43 @@ func (c *Certificates) Set(value string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Type is type of the struct.
|
||||
func (c *Certificates) Type() string {
|
||||
return "certificates"
|
||||
// GetTruncatedCertificateName truncates the certificate name.
|
||||
func (c *Certificate) GetTruncatedCertificateName() string {
|
||||
certName := c.CertFile.String()
|
||||
|
||||
// Truncate certificate information only if it's a well formed certificate content with more than 50 characters
|
||||
if !c.CertFile.IsPath() && strings.HasPrefix(certName, certificateHeader) && len(certName) > len(certificateHeader)+50 {
|
||||
certName = strings.TrimPrefix(c.CertFile.String(), certificateHeader)[:50]
|
||||
}
|
||||
|
||||
return certName
|
||||
}
|
||||
|
||||
// FileOrContent hold a file path or content.
|
||||
type FileOrContent string
|
||||
|
||||
func (f FileOrContent) String() string {
|
||||
return string(f)
|
||||
}
|
||||
|
||||
// IsPath returns true if the FileOrContent is a file path, otherwise returns false.
|
||||
func (f FileOrContent) IsPath() bool {
|
||||
_, err := os.Stat(f.String())
|
||||
return err == nil
|
||||
}
|
||||
|
||||
func (f FileOrContent) Read() ([]byte, error) {
|
||||
var content []byte
|
||||
if f.IsPath() {
|
||||
var err error
|
||||
content, err = os.ReadFile(f.String())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
content = []byte(f)
|
||||
}
|
||||
return content, nil
|
||||
}
|
||||
|
||||
// VerifyPeerCertificate verifies the chain certificates and their URI.
|
||||
|
|
|
@ -31,7 +31,7 @@ func NewCertificateStore() *CertificateStore {
|
|||
}
|
||||
}
|
||||
|
||||
func (c CertificateStore) getDefaultCertificateDomains() []string {
|
||||
func (c *CertificateStore) getDefaultCertificateDomains() []string {
|
||||
var allCerts []string
|
||||
|
||||
if c.DefaultCertificate == nil {
|
||||
|
@ -58,7 +58,7 @@ func (c CertificateStore) getDefaultCertificateDomains() []string {
|
|||
}
|
||||
|
||||
// GetAllDomains return a slice with all the certificate domain.
|
||||
func (c CertificateStore) GetAllDomains() []string {
|
||||
func (c *CertificateStore) GetAllDomains() []string {
|
||||
allDomains := c.getDefaultCertificateDomains()
|
||||
|
||||
// Get dynamic certificates
|
||||
|
@ -157,7 +157,7 @@ func (c *CertificateStore) GetCertificate(domains []string) *tls.Certificate {
|
|||
}
|
||||
|
||||
// ResetCache clears the cache in the store.
|
||||
func (c CertificateStore) ResetCache() {
|
||||
func (c *CertificateStore) ResetCache() {
|
||||
if c.CertCache != nil {
|
||||
c.CertCache.Flush()
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue