Bump to go1.27

This commit is contained in:
Jenthe Noordsij authored and GitHub committed 2026-10-21 14:10:28 +02:00
1 parent ef51566a5f
commit 84d9df3ce1
30 files changed
+568 -601

No files matched your search

+1 -1
View File
@@ -6,7 +6,7 @@ on:
- '*'
env:
GOLANGCI_LINT_VERSION: v2.13.2
GOLANGCI_LINT_VERSION: v2.14.0
MISSPELL_VERSION: v0.7.0
jobs:
+1 -1
View File
@@ -1 +1 @@
1.26
1.27
+9 -11
View File
@@ -18,17 +18,15 @@ type TraefikCmdConfiguration struct {
// NewTraefikConfiguration creates a TraefikCmdConfiguration with default values.
func NewTraefikConfiguration() *TraefikCmdConfiguration {
return &TraefikCmdConfiguration{
Configuration: static.Configuration{
Global: &static.Global{
CheckNewVersion: true,
},
EntryPoints: make(static.EntryPoints),
Providers: &static.Providers{
ProvidersThrottleDuration: ptypes.Duration(2 * time.Second),
},
ServersTransport: &static.ServersTransport{
MaxIdleConnsPerHost: 200,
},
Global: &static.Global{
CheckNewVersion: true,
},
EntryPoints: make(static.EntryPoints),
Providers: &static.Providers{
ProvidersThrottleDuration: ptypes.Duration(2 * time.Second),
},
ServersTransport: &static.ServersTransport{
MaxIdleConnsPerHost: 200,
},
ConfigFile: "",
}
+31
View File
@@ -1196,3 +1196,34 @@ As the rejection happens before the routing, the rejected requests are not repor
They are only visible at the `DEBUG` log level.
To tunnel traffic through a forward proxy exposed by Traefik, route it with a [TCP router](../routing/routers/index.md#configuring-tcp-routers) instead.
## v2.11.61
Starting with `v2.11.61`, Traefik is built with Go 1.27.
### GODEBUG TLS Settings
Go 1.27 removed the `tlsrsakex`, `tls10server` and `tls3des` `GODEBUG` settings.
Setting them in the `GODEBUG` environment variable has no effect anymore.
For the incoming connections, the RSA key exchange and 3DES cipher suites, as well as TLS 1.0 and 1.1,
can still be enabled with the `cipherSuites` and `minVersion` fields of the [TLS options](../https/tls.md#tls-options),
referenced in the TLS configuration of a [router](../routing/routers/index.md#tls) or of an [entrypoint](../routing/entrypoints.md#tls).
For the connections to the backends, Traefik does not offer to configure the cipher suites,
so the RSA key exchange and 3DES cipher suites are not available anymore.
A backend supporting only these cipher suites cannot be reached.
Please check out the [go documentation](https://go.dev/doc/go1.27#cryptotlspkgcryptotls) for more details.
### Maximum Number of Request Header Values
Go 1.27 limits the number of header values a request can carry to 500.
A request exceeding this limit is rejected with a `431 Request Header Fields Too Large` response,
for HTTP/1 and HTTP/2.
This limit is not configurable.
As the rejection happens before the routing, the rejected requests are not reported in the access logs.
Please check out the [go documentation](https://go.dev/doc/go1.27#nethttppkgnethttp) for more details.
+4 -4
View File
@@ -1,6 +1,6 @@
module github.com/traefik/traefik/v2
go 1.26.0
go 1.27.0
require (
github.com/BurntSushi/toml v1.6.0
@@ -60,10 +60,12 @@ require (
github.com/prometheus/client_model v0.6.2
github.com/quic-go/quic-go v0.59.1
github.com/rancher/go-rancher-metadata v0.0.0-20200311180630-7f4c936a06ac // No tag on the repo.
github.com/samber/slog-logrus/v2 v2.5.4
github.com/sirupsen/logrus v1.10.2
github.com/stretchr/testify v1.12.1
github.com/stvp/go-udp-testing v0.0.0-20191102171040-06b61409b154 // No tag on the repo.
github.com/testcontainers/testcontainers-go v0.42.0
github.com/testcontainers/testcontainers-go/modules/k3s v0.42.0
github.com/traefik/paerser v0.2.2
github.com/traefik/yaegi v0.16.1
github.com/uber/jaeger-client-go v2.30.0+incompatible
@@ -89,6 +91,7 @@ require (
k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // No tag on the repo.
mvdan.cc/xurls/v2 v2.5.0
sigs.k8s.io/gateway-api v0.4.0
sigs.k8s.io/structured-merge-diff/v6 v6.3.0
)
require (
@@ -330,7 +333,6 @@ require (
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/samber/lo v1.53.0 // indirect
github.com/samber/slog-common v0.21.0 // indirect
github.com/samber/slog-logrus/v2 v2.5.4
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.36 // indirect
github.com/secure-systems-lab/go-securesystemslib v0.10.0 // indirect
github.com/segmentio/fasthash v1.0.3 // indirect
@@ -349,7 +351,6 @@ require (
github.com/stretchr/objx v0.5.3 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.106 // indirect
github.com/testcontainers/testcontainers-go/modules/k3s v0.42.0
github.com/tinylib/msgp v1.6.3 // indirect
github.com/tjfoc/gmsm v1.4.1 // indirect
github.com/tklauser/go-sysconf v0.3.16 // indirect
@@ -410,7 +411,6 @@ require (
k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 // indirect
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect
sigs.k8s.io/randfill v1.0.0 // indirect
sigs.k8s.io/structured-merge-diff/v6 v6.3.0
sigs.k8s.io/yaml v1.6.0 // indirect
software.sslmate.com/src/go-pkcs12 v0.7.3 // indirect
)
+2 -4
View File
@@ -1378,10 +1378,8 @@ func (s *HTTPSSuite) modifyCertificateConfFileContent(certFileName, confFileName
TLS: &dynamic.TLSConfiguration{
Certificates: []*traefiktls.CertAndStores{
{
Certificate: traefiktls.Certificate{
CertFile: traefiktls.FileOrContent("fixtures/https/" + certFileName + ".cert"),
KeyFile: traefiktls.FileOrContent("fixtures/https/" + certFileName + ".key"),
},
CertFile: traefiktls.FileOrContent("fixtures/https/" + certFileName + ".cert"),
KeyFile: traefiktls.FileOrContent("fixtures/https/" + certFileName + ".key"),
},
},
},
+17 -30
View File
@@ -12,17 +12,12 @@ import (
// Middleware tests based on https://github.com/unrolled/secure
func Test_newSecure_sslForceHost(t *testing.T) {
type expected struct {
statusCode int
location string
}
testCases := []struct {
expected
desc string
host string
cfg dynamic.Headers
desc string
host string
cfg dynamic.Headers
expectedStatusCode int
expectedLocation string
}{
{
desc: "http should return a 301",
@@ -32,10 +27,8 @@ func Test_newSecure_sslForceHost(t *testing.T) {
SSLForceHost: true,
SSLHost: "powpow.example.com",
},
expected: expected{
statusCode: http.StatusMovedPermanently,
location: "https://powpow.example.com",
},
expectedStatusCode: http.StatusMovedPermanently,
expectedLocation: "https://powpow.example.com",
},
{
desc: "http sub domain should return a 301",
@@ -45,10 +38,8 @@ func Test_newSecure_sslForceHost(t *testing.T) {
SSLForceHost: true,
SSLHost: "powpow.example.com",
},
expected: expected{
statusCode: http.StatusMovedPermanently,
location: "https://powpow.example.com",
},
expectedStatusCode: http.StatusMovedPermanently,
expectedLocation: "https://powpow.example.com",
},
{
desc: "https should return a 200",
@@ -58,7 +49,7 @@ func Test_newSecure_sslForceHost(t *testing.T) {
SSLForceHost: true,
SSLHost: "powpow.example.com",
},
expected: expected{statusCode: http.StatusOK},
expectedStatusCode: http.StatusOK,
},
{
desc: "https sub domain should return a 301",
@@ -68,10 +59,8 @@ func Test_newSecure_sslForceHost(t *testing.T) {
SSLForceHost: true,
SSLHost: "powpow.example.com",
},
expected: expected{
statusCode: http.StatusMovedPermanently,
location: "https://powpow.example.com",
},
expectedStatusCode: http.StatusMovedPermanently,
expectedLocation: "https://powpow.example.com",
},
{
desc: "http without force host and sub domain should return a 301",
@@ -81,10 +70,8 @@ func Test_newSecure_sslForceHost(t *testing.T) {
SSLForceHost: false,
SSLHost: "powpow.example.com",
},
expected: expected{
statusCode: http.StatusMovedPermanently,
location: "https://powpow.example.com",
},
expectedStatusCode: http.StatusMovedPermanently,
expectedLocation: "https://powpow.example.com",
},
{
desc: "https without force host and sub domain should return a 301",
@@ -94,7 +81,7 @@ func Test_newSecure_sslForceHost(t *testing.T) {
SSLForceHost: false,
SSLHost: "powpow.example.com",
},
expected: expected{statusCode: http.StatusOK},
expectedStatusCode: http.StatusOK,
},
}
@@ -112,8 +99,8 @@ func Test_newSecure_sslForceHost(t *testing.T) {
mid.ServeHTTP(rw, req)
assert.Equal(t, test.expected.statusCode, rw.Result().StatusCode)
assert.Equal(t, test.expected.location, rw.Header().Get("Location"))
assert.Equal(t, test.expectedStatusCode, rw.Result().StatusCode)
assert.Equal(t, test.expectedLocation, rw.Header().Get("Location"))
})
}
}
+3 -5
View File
@@ -152,11 +152,9 @@ func createMessage(certs map[string]*Certificate) dynamic.Message {
for _, cert := range certs {
certConf := &traefiktls.CertAndStores{
Certificate: traefiktls.Certificate{
CertFile: traefiktls.FileOrContent(cert.Certificate),
KeyFile: traefiktls.FileOrContent(cert.Key),
},
Stores: []string{tlsalpn01.ACMETLS1Protocol},
CertFile: traefiktls.FileOrContent(cert.Certificate),
KeyFile: traefiktls.FileOrContent(cert.Key),
Stores: []string{tlsalpn01.ACMETLS1Protocol},
}
conf.Configuration.TLS.Certificates = append(conf.Configuration.TLS.Certificates, certConf)
}
+3 -5
View File
@@ -775,11 +775,9 @@ func (p *Provider) buildMessage() dynamic.Message {
for _, cert := range p.certificates {
certConf := &traefiktls.CertAndStores{
Certificate: traefiktls.Certificate{
CertFile: traefiktls.FileOrContent(cert.Certificate.Certificate),
KeyFile: traefiktls.FileOrContent(cert.Key),
},
Stores: []string{cert.Store},
CertFile: traefiktls.FileOrContent(cert.Certificate.Certificate),
KeyFile: traefiktls.FileOrContent(cert.Key),
Stores: []string{cert.Store},
}
conf.Configuration.TLS.Certificates = append(conf.Configuration.TLS.Certificates, certConf)
}
+5 -15
View File
@@ -49,9 +49,7 @@ func TestGetUncheckedCertificates(t *testing.T) {
domains: []string{"*.traefik.wtf"},
acmeCertificates: []*CertAndStore{
{
Certificate: Certificate{
Domain: types.Domain{Main: "*.traefik.wtf"},
},
Domain: types.Domain{Main: "*.traefik.wtf"},
},
},
expectedDomains: nil,
@@ -72,9 +70,7 @@ func TestGetUncheckedCertificates(t *testing.T) {
domains: []string{"traefik.wtf", "foo.traefik.wtf"},
acmeCertificates: []*CertAndStore{
{
Certificate: Certificate{
Domain: types.Domain{Main: "traefik.wtf"},
},
Domain: types.Domain{Main: "traefik.wtf"},
},
},
expectedDomains: []string{"foo.traefik.wtf"},
@@ -90,9 +86,7 @@ func TestGetUncheckedCertificates(t *testing.T) {
domains: []string{"traefik.wtf"},
acmeCertificates: []*CertAndStore{
{
Certificate: Certificate{
Domain: types.Domain{Main: "traefik.wtf"},
},
Domain: types.Domain{Main: "traefik.wtf"},
},
},
expectedDomains: nil,
@@ -108,9 +102,7 @@ func TestGetUncheckedCertificates(t *testing.T) {
domains: []string{"who.traefik.wtf", "foo.traefik.wtf"},
acmeCertificates: []*CertAndStore{
{
Certificate: Certificate{
Domain: types.Domain{Main: "*.traefik.wtf"},
},
Domain: types.Domain{Main: "*.traefik.wtf"},
},
},
expectedDomains: nil,
@@ -120,9 +112,7 @@ func TestGetUncheckedCertificates(t *testing.T) {
domains: []string{"traefik.wtf", "foo.traefik.wtf"},
acmeCertificates: []*CertAndStore{
{
Certificate: Certificate{
Domain: types.Domain{Main: "*.traefik.wtf"},
},
Domain: types.Domain{Main: "*.traefik.wtf"},
},
},
expectedDomains: []string{"traefik.wtf"},
+6 -10
View File
@@ -276,10 +276,8 @@ func TestDefaultRule(t *testing.T) {
t.Parallel()
p := Provider{
Configuration: Configuration{
ExposedByDefault: true,
DefaultRule: test.defaultRule,
},
ExposedByDefault: true,
DefaultRule: test.defaultRule,
}
err := p.Init()
@@ -3160,12 +3158,10 @@ func Test_buildConfiguration(t *testing.T) {
t.Parallel()
p := Provider{
Configuration: Configuration{
ExposedByDefault: true,
DefaultRule: "Host(`{{ normalize .Name }}.traefik.wtf`)",
ConnectAware: test.ConnectAware,
Constraints: test.constraints,
},
ExposedByDefault: true,
DefaultRule: "Host(`{{ normalize .Name }}.traefik.wtf`)",
ConnectAware: test.ConnectAware,
Constraints: test.constraints,
}
err := p.Init()
+30 -34
View File
@@ -199,23 +199,21 @@ func TestListServices(t *testing.T) {
dockerVersion: "1.30",
networks: []networktypes.Summary{
{
Network: networktypes.Network{
Name: "network_name",
ID: "yk6l57rfwizjzxxzftn4amaot",
Created: time.Now(),
Scope: "swarm",
Driver: "overlay",
EnableIPv6: false,
Internal: true,
Ingress: false,
ConfigOnly: false,
Options: map[string]string{
"com.docker.networktypes.driver.overlay.vxlanid_list": "4098",
"com.docker.networktypes.enable_ipv6": "false",
},
Labels: map[string]string{
"com.docker.stack.namespace": "test",
},
Name: "network_name",
ID: "yk6l57rfwizjzxxzftn4amaot",
Created: time.Now(),
Scope: "swarm",
Driver: "overlay",
EnableIPv6: false,
Internal: true,
Ingress: false,
ConfigOnly: false,
Options: map[string]string{
"com.docker.networktypes.driver.overlay.vxlanid_list": "4098",
"com.docker.networktypes.enable_ipv6": "false",
},
Labels: map[string]string{
"com.docker.stack.namespace": "test",
},
},
},
@@ -256,23 +254,21 @@ func TestListServices(t *testing.T) {
dockerVersion: "1.30",
networks: []networktypes.Summary{
{
Network: networktypes.Network{
Name: "network_name",
ID: "yk6l57rfwizjzxxzftn4amaot",
Created: time.Now(),
Scope: "swarm",
Driver: "overlay",
EnableIPv6: false,
Internal: true,
Ingress: false,
ConfigOnly: false,
Options: map[string]string{
"com.docker.networktypes.driver.overlay.vxlanid_list": "4098",
"com.docker.networktypes.enable_ipv6": "false",
},
Labels: map[string]string{
"com.docker.stack.namespace": "test",
},
Name: "network_name",
ID: "yk6l57rfwizjzxxzftn4amaot",
Created: time.Now(),
Scope: "swarm",
Driver: "overlay",
EnableIPv6: false,
Internal: true,
Ingress: false,
ConfigOnly: false,
Options: map[string]string{
"com.docker.networktypes.driver.overlay.vxlanid_list": "4098",
"com.docker.networktypes.enable_ipv6": "false",
},
Labels: map[string]string{
"com.docker.stack.namespace": "test",
},
},
},
+6 -11
View File
@@ -8,24 +8,19 @@ import (
"github.com/stretchr/testify/require"
traefikcrdfake "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned/fake"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
kubefake "k8s.io/client-go/kubernetes/fake"
)
func TestClientIgnoresHelmOwnedSecrets(t *testing.T) {
secret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Namespace: "default",
Name: "secret",
},
Namespace: "default",
Name: "secret",
}
helmSecret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Namespace: "default",
Name: "helm-secret",
Labels: map[string]string{
"owner": "helm",
},
Namespace: "default",
Name: "helm-secret",
Labels: map[string]string{
"owner": "helm",
},
}
+2 -4
View File
@@ -1127,10 +1127,8 @@ func getTLS(k8sClient Client, secretName, namespace string) (*tls.CertAndStores,
}
return &tls.CertAndStores{
Certificate: tls.Certificate{
CertFile: tls.FileOrContent(cert),
KeyFile: tls.FileOrContent(key),
},
CertFile: tls.FileOrContent(cert),
KeyFile: tls.FileOrContent(key),
}, nil
}
+7 -13
View File
@@ -720,10 +720,8 @@ func TestLoadIngressRouteTCPs(t *testing.T) {
TLS: &dynamic.TLSConfiguration{
Certificates: []*tls.CertAndStores{
{
Certificate: tls.Certificate{
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
},
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
},
},
},
@@ -3647,10 +3645,8 @@ func TestLoadIngressRoutes(t *testing.T) {
TLS: &dynamic.TLSConfiguration{
Certificates: []*tls.CertAndStores{
{
Certificate: tls.Certificate{
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
},
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
},
},
},
@@ -5070,11 +5066,9 @@ func TestLoadIngressRoutes(t *testing.T) {
TLS: &dynamic.TLSConfiguration{
Certificates: []*tls.CertAndStores{
{
Certificate: tls.Certificate{
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
},
Stores: []string{"default"},
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
Stores: []string{"default"},
},
},
Stores: map[string]tls.Store{
@@ -1387,10 +1387,8 @@ func getTLS(k8sClient Client, secretName gatev1alpha2.ObjectName, namespace stri
}
return &tls.CertAndStores{
Certificate: tls.Certificate{
CertFile: tls.FileOrContent(cert),
KeyFile: tls.FileOrContent(key),
},
CertFile: tls.FileOrContent(cert),
KeyFile: tls.FileOrContent(key),
}, nil
}
@@ -8,7 +8,6 @@ import (
"github.com/traefik/traefik/v2/pkg/config/dynamic"
"github.com/traefik/traefik/v2/pkg/provider"
"github.com/traefik/traefik/v2/pkg/tls"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/utils/ptr"
gatev1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
)
@@ -470,10 +469,8 @@ func TestLoadHTTPRoutes(t *testing.T) {
TLS: &dynamic.TLSConfiguration{
Certificates: []*tls.CertAndStores{
{
Certificate: tls.Certificate{
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
},
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
},
},
},
@@ -705,10 +702,8 @@ func TestLoadHTTPRoutes(t *testing.T) {
TLS: &dynamic.TLSConfiguration{
Certificates: []*tls.CertAndStores{
{
Certificate: tls.Certificate{
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
},
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
},
},
},
@@ -1110,10 +1105,8 @@ func TestLoadHTTPRoutes(t *testing.T) {
TLS: &dynamic.TLSConfiguration{
Certificates: []*tls.CertAndStores{
{
Certificate: tls.Certificate{
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
},
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
},
},
},
@@ -1195,10 +1188,8 @@ func TestLoadHTTPRoutes(t *testing.T) {
TLS: &dynamic.TLSConfiguration{
Certificates: []*tls.CertAndStores{
{
Certificate: tls.Certificate{
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
},
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
},
},
},
@@ -2003,10 +1994,8 @@ func TestLoadTCPRoutes(t *testing.T) {
TLS: &dynamic.TLSConfiguration{
Certificates: []*tls.CertAndStores{
{
Certificate: tls.Certificate{
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
},
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
},
},
},
@@ -2485,10 +2474,8 @@ func TestLoadTLSRoutes(t *testing.T) {
TLS: &dynamic.TLSConfiguration{
Certificates: []*tls.CertAndStores{
{
Certificate: tls.Certificate{
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
},
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
},
},
},
@@ -2694,10 +2681,8 @@ func TestLoadTLSRoutes(t *testing.T) {
TLS: &dynamic.TLSConfiguration{
Certificates: []*tls.CertAndStores{
{
Certificate: tls.Certificate{
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
},
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
},
},
},
@@ -2762,10 +2747,8 @@ func TestLoadTLSRoutes(t *testing.T) {
TLS: &dynamic.TLSConfiguration{
Certificates: []*tls.CertAndStores{
{
Certificate: tls.Certificate{
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
},
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
},
},
},
@@ -3552,10 +3535,8 @@ func TestLoadMixedRoutes(t *testing.T) {
TLS: &dynamic.TLSConfiguration{
Certificates: []*tls.CertAndStores{
{
Certificate: tls.Certificate{
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
},
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
},
},
},
@@ -3726,10 +3707,8 @@ func TestLoadMixedRoutes(t *testing.T) {
TLS: &dynamic.TLSConfiguration{
Certificates: []*tls.CertAndStores{
{
Certificate: tls.Certificate{
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
},
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
},
},
},
@@ -3960,10 +3939,8 @@ func TestLoadMixedRoutes(t *testing.T) {
TLS: &dynamic.TLSConfiguration{
Certificates: []*tls.CertAndStores{
{
Certificate: tls.Certificate{
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
},
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
},
},
},
@@ -4107,10 +4084,8 @@ func TestLoadMixedRoutes(t *testing.T) {
TLS: &dynamic.TLSConfiguration{
Certificates: []*tls.CertAndStores{
{
Certificate: tls.Certificate{
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
},
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
},
},
},
@@ -4235,10 +4210,8 @@ func TestLoadMixedRoutes(t *testing.T) {
TLS: &dynamic.TLSConfiguration{
Certificates: []*tls.CertAndStores{
{
Certificate: tls.Certificate{
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
},
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
},
},
},
@@ -4708,10 +4681,8 @@ func Test_shouldAttach(t *testing.T) {
{
desc: "No ParentRefs",
gateway: &gatev1alpha2.Gateway{
ObjectMeta: metav1.ObjectMeta{
Name: "gateway",
Namespace: "default",
},
Name: "gateway",
Namespace: "default",
},
listener: gatev1alpha2.Listener{
Name: "foo",
@@ -4725,10 +4696,8 @@ func Test_shouldAttach(t *testing.T) {
{
desc: "Unsupported Kind",
gateway: &gatev1alpha2.Gateway{
ObjectMeta: metav1.ObjectMeta{
Name: "gateway",
Namespace: "default",
},
Name: "gateway",
Namespace: "default",
},
listener: gatev1alpha2.Listener{
Name: "foo",
@@ -4750,10 +4719,8 @@ func Test_shouldAttach(t *testing.T) {
{
desc: "Unsupported Group",
gateway: &gatev1alpha2.Gateway{
ObjectMeta: metav1.ObjectMeta{
Name: "gateway",
Namespace: "default",
},
Name: "gateway",
Namespace: "default",
},
listener: gatev1alpha2.Listener{
Name: "foo",
@@ -4775,10 +4742,8 @@ func Test_shouldAttach(t *testing.T) {
{
desc: "Kind is nil",
gateway: &gatev1alpha2.Gateway{
ObjectMeta: metav1.ObjectMeta{
Name: "gateway",
Namespace: "default",
},
Name: "gateway",
Namespace: "default",
},
listener: gatev1alpha2.Listener{
Name: "foo",
@@ -4799,10 +4764,8 @@ func Test_shouldAttach(t *testing.T) {
{
desc: "Group is nil",
gateway: &gatev1alpha2.Gateway{
ObjectMeta: metav1.ObjectMeta{
Name: "gateway",
Namespace: "default",
},
Name: "gateway",
Namespace: "default",
},
listener: gatev1alpha2.Listener{
Name: "foo",
@@ -4823,10 +4786,8 @@ func Test_shouldAttach(t *testing.T) {
{
desc: "SectionName does not match a listener desc",
gateway: &gatev1alpha2.Gateway{
ObjectMeta: metav1.ObjectMeta{
Name: "gateway",
Namespace: "default",
},
Name: "gateway",
Namespace: "default",
},
listener: gatev1alpha2.Listener{
Name: "foo",
@@ -4848,10 +4809,8 @@ func Test_shouldAttach(t *testing.T) {
{
desc: "Namespace does not match the Gateway namespace",
gateway: &gatev1alpha2.Gateway{
ObjectMeta: metav1.ObjectMeta{
Name: "gateway",
Namespace: "default",
},
Name: "gateway",
Namespace: "default",
},
listener: gatev1alpha2.Listener{
Name: "foo",
@@ -4873,10 +4832,8 @@ func Test_shouldAttach(t *testing.T) {
{
desc: "Route namespace does not match the Gateway namespace",
gateway: &gatev1alpha2.Gateway{
ObjectMeta: metav1.ObjectMeta{
Name: "gateway",
Namespace: "default",
},
Name: "gateway",
Namespace: "default",
},
listener: gatev1alpha2.Listener{
Name: "foo",
@@ -4897,10 +4854,8 @@ func Test_shouldAttach(t *testing.T) {
{
desc: "Unsupported Kind",
gateway: &gatev1alpha2.Gateway{
ObjectMeta: metav1.ObjectMeta{
Name: "gateway",
Namespace: "default",
},
Name: "gateway",
Namespace: "default",
},
listener: gatev1alpha2.Listener{
Name: "foo",
@@ -4922,10 +4877,8 @@ func Test_shouldAttach(t *testing.T) {
{
desc: "Route namespace matches the Gateway namespace",
gateway: &gatev1alpha2.Gateway{
ObjectMeta: metav1.ObjectMeta{
Name: "gateway",
Namespace: "default",
},
Name: "gateway",
Namespace: "default",
},
listener: gatev1alpha2.Listener{
Name: "foo",
@@ -4946,10 +4899,8 @@ func Test_shouldAttach(t *testing.T) {
{
desc: "Namespace matches the Gateway namespace",
gateway: &gatev1alpha2.Gateway{
ObjectMeta: metav1.ObjectMeta{
Name: "gateway",
Namespace: "default",
},
Name: "gateway",
Namespace: "default",
},
listener: gatev1alpha2.Listener{
Name: "foo",
@@ -4971,10 +4922,8 @@ func Test_shouldAttach(t *testing.T) {
{
desc: "Only one ParentRef matches the Gateway",
gateway: &gatev1alpha2.Gateway{
ObjectMeta: metav1.ObjectMeta{
Name: "gateway",
Namespace: "default",
},
Name: "gateway",
Namespace: "default",
},
listener: gatev1alpha2.Listener{
Name: "foo",
+18 -30
View File
@@ -134,18 +134,14 @@ func TestIsLoadBalancerIngressEquals(t *testing.T) {
func TestClientIgnoresHelmOwnedSecrets(t *testing.T) {
secret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Namespace: "default",
Name: "secret",
},
Namespace: "default",
Name: "secret",
}
helmSecret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Namespace: "default",
Name: "helm-secret",
Labels: map[string]string{
"owner": "helm",
},
Namespace: "default",
Name: "helm-secret",
Labels: map[string]string{
"owner": "helm",
},
}
@@ -190,22 +186,18 @@ func TestClientIgnoresHelmOwnedSecrets(t *testing.T) {
func TestClientIgnoresEmptyEndpointUpdates(t *testing.T) {
emptyEndpoint := &corev1.Endpoints{
ObjectMeta: metav1.ObjectMeta{
Name: "empty-endpoint",
Namespace: "test",
ResourceVersion: "1244",
Annotations: map[string]string{
"test-annotation": "_",
},
Name: "empty-endpoint",
Namespace: "test",
ResourceVersion: "1244",
Annotations: map[string]string{
"test-annotation": "_",
},
}
filledEndpoint := &corev1.Endpoints{
ObjectMeta: metav1.ObjectMeta{
Name: "filled-endpoint",
Namespace: "test",
ResourceVersion: "1234",
},
Name: "filled-endpoint",
Namespace: "test",
ResourceVersion: "1234",
Subsets: []corev1.EndpointSubset{{
Addresses: []corev1.EndpointAddress{{
IP: "10.13.37.1",
@@ -289,17 +281,13 @@ func TestClientIgnoresEmptyEndpointUpdates(t *testing.T) {
func TestClientUsesCorrectServerVersion(t *testing.T) {
ingressV1Beta := &netv1beta1.Ingress{
ObjectMeta: metav1.ObjectMeta{
Namespace: "default",
Name: "ingress-v1beta",
},
Namespace: "default",
Name: "ingress-v1beta",
}
ingressV1 := &netv1.Ingress{
ObjectMeta: metav1.ObjectMeta{
Namespace: "default",
Name: "ingress-v1",
},
Namespace: "default",
Name: "ingress-v1",
}
kubeClient := kubefake.NewClientset(ingressV1Beta, ingressV1)
@@ -483,10 +483,8 @@ func getCertificates(ctx context.Context, ingress *netv1.Ingress, k8sClient Clie
}
tlsConfigs[configKey] = &tls.CertAndStores{
Certificate: tls.Certificate{
CertFile: tls.FileOrContent(cert),
KeyFile: tls.FileOrContent(key),
},
CertFile: tls.FileOrContent(cert),
KeyFile: tls.FileOrContent(key),
}
}
}
@@ -15,7 +15,6 @@ import (
"github.com/traefik/traefik/v2/pkg/types"
corev1 "k8s.io/api/core/v1"
netv1 "k8s.io/api/networking/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
var _ provider.Provider = (*Provider)(nil)
@@ -824,10 +823,8 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
TLS: &dynamic.TLSConfiguration{
Certificates: []*tls.CertAndStores{
{
Certificate: tls.Certificate{
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
},
CertFile: tls.FileOrContent("-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"),
KeyFile: tls.FileOrContent("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----"),
},
},
},
@@ -2135,10 +2132,8 @@ func TestGetCertificates(t *testing.T) {
client: clientMock{
secrets: []*corev1.Secret{
{
ObjectMeta: metav1.ObjectMeta{
Name: "test-secret",
Namespace: "testing",
},
Name: "test-secret",
Namespace: "testing",
Data: map[string][]byte{
"tls.key": []byte("tls-key"),
},
@@ -2153,10 +2148,8 @@ func TestGetCertificates(t *testing.T) {
client: clientMock{
secrets: []*corev1.Secret{
{
ObjectMeta: metav1.ObjectMeta{
Name: "test-secret",
Namespace: "testing",
},
Name: "test-secret",
Namespace: "testing",
Data: map[string][]byte{
"tls.crt": []byte("tls-crt"),
},
@@ -2171,11 +2164,9 @@ func TestGetCertificates(t *testing.T) {
client: clientMock{
secrets: []*corev1.Secret{
{
ObjectMeta: metav1.ObjectMeta{
Name: "test-secret",
Namespace: "testing",
},
Data: map[string][]byte{},
Name: "test-secret",
Namespace: "testing",
Data: map[string][]byte{},
},
},
},
@@ -2198,20 +2189,16 @@ func TestGetCertificates(t *testing.T) {
client: clientMock{
secrets: []*corev1.Secret{
{
ObjectMeta: metav1.ObjectMeta{
Name: "test-secret2",
Namespace: "testing",
},
Name: "test-secret2",
Namespace: "testing",
Data: map[string][]byte{
"tls.crt": []byte("tls-crt"),
"tls.key": []byte("tls-key"),
},
},
{
ObjectMeta: metav1.ObjectMeta{
Name: "test-secret",
Namespace: "testing",
},
Name: "test-secret",
Namespace: "testing",
Data: map[string][]byte{
"tls.crt": []byte("tls-crt"),
"tls.key": []byte("tls-key"),
+58 -151
View File
@@ -6,7 +6,6 @@ import (
"github.com/stretchr/testify/assert"
corev1 "k8s.io/api/core/v1"
netv1 "k8s.io/api/networking/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
func Test_detectChanges(t *testing.T) {
@@ -38,139 +37,103 @@ func Test_detectChanges(t *testing.T) {
{
name: "With same version",
oldObj: &corev1.Endpoints{
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: "1",
},
ResourceVersion: "1",
},
newObj: &corev1.Endpoints{
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: "1",
},
ResourceVersion: "1",
},
},
{
name: "With different version",
oldObj: &corev1.Endpoints{
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: "1",
},
ResourceVersion: "1",
},
newObj: &corev1.Endpoints{
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: "2",
},
ResourceVersion: "2",
},
},
{
name: "Ingress With same version",
oldObj: &netv1.Ingress{
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: "1",
},
ResourceVersion: "1",
},
newObj: &netv1.Ingress{
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: "1",
},
ResourceVersion: "1",
},
},
{
name: "Ingress With different version",
oldObj: &netv1.Ingress{
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: "1",
},
ResourceVersion: "1",
},
newObj: &netv1.Ingress{
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: "2",
},
ResourceVersion: "2",
},
want: true,
},
{
name: "With same annotations",
oldObj: &corev1.Endpoints{
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: "1",
Annotations: map[string]string{
"test-annotation": "_",
},
ResourceVersion: "1",
Annotations: map[string]string{
"test-annotation": "_",
},
},
newObj: &corev1.Endpoints{
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: "2",
Annotations: map[string]string{
"test-annotation": "_",
},
ResourceVersion: "2",
Annotations: map[string]string{
"test-annotation": "_",
},
},
},
{
name: "With different annotations",
oldObj: &corev1.Endpoints{
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: "1",
Annotations: map[string]string{
"test-annotation": "V",
},
ResourceVersion: "1",
Annotations: map[string]string{
"test-annotation": "V",
},
},
newObj: &corev1.Endpoints{
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: "2",
Annotations: map[string]string{
"test-annotation": "X",
},
ResourceVersion: "2",
Annotations: map[string]string{
"test-annotation": "X",
},
},
},
{
name: "With same subsets",
oldObj: &corev1.Endpoints{
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: "1",
},
Subsets: []corev1.EndpointSubset{},
ResourceVersion: "1",
Subsets: []corev1.EndpointSubset{},
},
newObj: &corev1.Endpoints{
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: "1",
},
Subsets: []corev1.EndpointSubset{},
ResourceVersion: "1",
Subsets: []corev1.EndpointSubset{},
},
},
{
name: "With different len of subsets",
oldObj: &corev1.Endpoints{
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: "1",
},
Subsets: []corev1.EndpointSubset{},
ResourceVersion: "1",
Subsets: []corev1.EndpointSubset{},
},
newObj: &corev1.Endpoints{
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: "2",
},
Subsets: []corev1.EndpointSubset{{}},
ResourceVersion: "2",
Subsets: []corev1.EndpointSubset{{}},
},
want: true,
},
{
name: "With same subsets with same len of addresses",
oldObj: &corev1.Endpoints{
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: "1",
},
ResourceVersion: "1",
Subsets: []corev1.EndpointSubset{{
Addresses: []corev1.EndpointAddress{},
}},
},
newObj: &corev1.Endpoints{
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: "2",
},
ResourceVersion: "2",
Subsets: []corev1.EndpointSubset{{
Addresses: []corev1.EndpointAddress{},
}},
@@ -179,17 +142,13 @@ func Test_detectChanges(t *testing.T) {
{
name: "With same subsets with different len of addresses",
oldObj: &corev1.Endpoints{
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: "1",
},
ResourceVersion: "1",
Subsets: []corev1.EndpointSubset{{
Addresses: []corev1.EndpointAddress{},
}},
},
newObj: &corev1.Endpoints{
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: "2",
},
ResourceVersion: "2",
Subsets: []corev1.EndpointSubset{{
Addresses: []corev1.EndpointAddress{{}},
}},
@@ -199,17 +158,13 @@ func Test_detectChanges(t *testing.T) {
{
name: "With same subsets with same len of ports",
oldObj: &corev1.Endpoints{
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: "1",
},
ResourceVersion: "1",
Subsets: []corev1.EndpointSubset{{
Ports: []corev1.EndpointPort{},
}},
},
newObj: &corev1.Endpoints{
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: "2",
},
ResourceVersion: "2",
Subsets: []corev1.EndpointSubset{{
Ports: []corev1.EndpointPort{},
}},
@@ -218,17 +173,13 @@ func Test_detectChanges(t *testing.T) {
{
name: "With same subsets with different len of ports",
oldObj: &corev1.Endpoints{
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: "1",
},
ResourceVersion: "1",
Subsets: []corev1.EndpointSubset{{
Ports: []corev1.EndpointPort{},
}},
},
newObj: &corev1.Endpoints{
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: "2",
},
ResourceVersion: "2",
Subsets: []corev1.EndpointSubset{{
Ports: []corev1.EndpointPort{{}},
}},
@@ -238,9 +189,7 @@ func Test_detectChanges(t *testing.T) {
{
name: "With same subsets with same len of addresses with same ip",
oldObj: &corev1.Endpoints{
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: "1",
},
ResourceVersion: "1",
Subsets: []corev1.EndpointSubset{{
Addresses: []corev1.EndpointAddress{{
IP: "10.10.10.10",
@@ -248,9 +197,7 @@ func Test_detectChanges(t *testing.T) {
}},
},
newObj: &corev1.Endpoints{
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: "2",
},
ResourceVersion: "2",
Subsets: []corev1.EndpointSubset{{
Addresses: []corev1.EndpointAddress{{
IP: "10.10.10.10",
@@ -261,9 +208,7 @@ func Test_detectChanges(t *testing.T) {
{
name: "With same subsets with same len of addresses with different ip",
oldObj: &corev1.Endpoints{
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: "1",
},
ResourceVersion: "1",
Subsets: []corev1.EndpointSubset{{
Addresses: []corev1.EndpointAddress{{
IP: "10.10.10.10",
@@ -271,9 +216,7 @@ func Test_detectChanges(t *testing.T) {
}},
},
newObj: &corev1.Endpoints{
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: "2",
},
ResourceVersion: "2",
Subsets: []corev1.EndpointSubset{{
Addresses: []corev1.EndpointAddress{{
IP: "10.10.10.42",
@@ -285,9 +228,7 @@ func Test_detectChanges(t *testing.T) {
{
name: "With same subsets with same len of addresses with same hostname",
oldObj: &corev1.Endpoints{
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: "1",
},
ResourceVersion: "1",
Subsets: []corev1.EndpointSubset{{
Addresses: []corev1.EndpointAddress{{
Hostname: "foo",
@@ -295,9 +236,7 @@ func Test_detectChanges(t *testing.T) {
}},
},
newObj: &corev1.Endpoints{
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: "2",
},
ResourceVersion: "2",
Subsets: []corev1.EndpointSubset{{
Addresses: []corev1.EndpointAddress{{
Hostname: "foo",
@@ -308,9 +247,7 @@ func Test_detectChanges(t *testing.T) {
{
name: "With same subsets with same len of addresses with same hostname",
oldObj: &corev1.Endpoints{
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: "1",
},
ResourceVersion: "1",
Subsets: []corev1.EndpointSubset{{
Addresses: []corev1.EndpointAddress{{
Hostname: "foo",
@@ -318,9 +255,7 @@ func Test_detectChanges(t *testing.T) {
}},
},
newObj: &corev1.Endpoints{
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: "2",
},
ResourceVersion: "2",
Subsets: []corev1.EndpointSubset{{
Addresses: []corev1.EndpointAddress{{
Hostname: "bar",
@@ -332,9 +267,7 @@ func Test_detectChanges(t *testing.T) {
{
name: "With same subsets with same len of port with same name",
oldObj: &corev1.Endpoints{
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: "1",
},
ResourceVersion: "1",
Subsets: []corev1.EndpointSubset{{
Ports: []corev1.EndpointPort{{
Name: "foo",
@@ -342,9 +275,7 @@ func Test_detectChanges(t *testing.T) {
}},
},
newObj: &corev1.Endpoints{
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: "2",
},
ResourceVersion: "2",
Subsets: []corev1.EndpointSubset{{
Ports: []corev1.EndpointPort{{
Name: "foo",
@@ -355,9 +286,7 @@ func Test_detectChanges(t *testing.T) {
{
name: "With same subsets with same len of port with different name",
oldObj: &corev1.Endpoints{
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: "1",
},
ResourceVersion: "1",
Subsets: []corev1.EndpointSubset{{
Ports: []corev1.EndpointPort{{
Name: "foo",
@@ -365,9 +294,7 @@ func Test_detectChanges(t *testing.T) {
}},
},
newObj: &corev1.Endpoints{
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: "2",
},
ResourceVersion: "2",
Subsets: []corev1.EndpointSubset{{
Ports: []corev1.EndpointPort{{
Name: "bar",
@@ -379,9 +306,7 @@ func Test_detectChanges(t *testing.T) {
{
name: "With same subsets with same len of port with same port",
oldObj: &corev1.Endpoints{
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: "1",
},
ResourceVersion: "1",
Subsets: []corev1.EndpointSubset{{
Ports: []corev1.EndpointPort{{
Port: 4242,
@@ -389,9 +314,7 @@ func Test_detectChanges(t *testing.T) {
}},
},
newObj: &corev1.Endpoints{
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: "2",
},
ResourceVersion: "2",
Subsets: []corev1.EndpointSubset{{
Ports: []corev1.EndpointPort{{
Port: 4242,
@@ -402,9 +325,7 @@ func Test_detectChanges(t *testing.T) {
{
name: "With same subsets with same len of port with different port",
oldObj: &corev1.Endpoints{
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: "1",
},
ResourceVersion: "1",
Subsets: []corev1.EndpointSubset{{
Ports: []corev1.EndpointPort{{
Port: 4242,
@@ -412,9 +333,7 @@ func Test_detectChanges(t *testing.T) {
}},
},
newObj: &corev1.Endpoints{
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: "2",
},
ResourceVersion: "2",
Subsets: []corev1.EndpointSubset{{
Ports: []corev1.EndpointPort{{
Port: 6969,
@@ -426,9 +345,7 @@ func Test_detectChanges(t *testing.T) {
{
name: "With same subsets with same len of port with same protocol",
oldObj: &corev1.Endpoints{
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: "1",
},
ResourceVersion: "1",
Subsets: []corev1.EndpointSubset{{
Ports: []corev1.EndpointPort{{
Protocol: "HTTP",
@@ -436,9 +353,7 @@ func Test_detectChanges(t *testing.T) {
}},
},
newObj: &corev1.Endpoints{
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: "2",
},
ResourceVersion: "2",
Subsets: []corev1.EndpointSubset{{
Ports: []corev1.EndpointPort{{
Protocol: "HTTP",
@@ -449,9 +364,7 @@ func Test_detectChanges(t *testing.T) {
{
name: "With same subsets with same len of port with different protocol",
oldObj: &corev1.Endpoints{
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: "1",
},
ResourceVersion: "1",
Subsets: []corev1.EndpointSubset{{
Ports: []corev1.EndpointPort{{
Protocol: "HTTP",
@@ -459,9 +372,7 @@ func Test_detectChanges(t *testing.T) {
}},
},
newObj: &corev1.Endpoints{
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: "2",
},
ResourceVersion: "2",
Subsets: []corev1.EndpointSubset{{
Ports: []corev1.EndpointPort{{
Protocol: "TCP",
@@ -473,9 +384,7 @@ func Test_detectChanges(t *testing.T) {
{
name: "With same subsets with same subset",
oldObj: &corev1.Endpoints{
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: "1",
},
ResourceVersion: "1",
Subsets: []corev1.EndpointSubset{{
Addresses: []corev1.EndpointAddress{{
IP: "10.10.10.10",
@@ -489,9 +398,7 @@ func Test_detectChanges(t *testing.T) {
}},
},
newObj: &corev1.Endpoints{
ObjectMeta: metav1.ObjectMeta{
ResourceVersion: "2",
},
ResourceVersion: "2",
Subsets: []corev1.EndpointSubset{{
Addresses: []corev1.EndpointAddress{{
IP: "10.10.10.10",
+4 -8
View File
@@ -825,20 +825,16 @@ func Test_buildConfiguration(t *testing.T) {
TLS: &dynamic.TLSConfiguration{
Certificates: []*tls.CertAndStores{
{
Certificate: tls.Certificate{
CertFile: tls.FileOrContent("foobar"),
KeyFile: tls.FileOrContent("foobar"),
},
CertFile: tls.FileOrContent("foobar"),
KeyFile: tls.FileOrContent("foobar"),
Stores: []string{
"foobar",
"foobar",
},
},
{
Certificate: tls.Certificate{
CertFile: tls.FileOrContent("foobar"),
KeyFile: tls.FileOrContent("foobar"),
},
CertFile: tls.FileOrContent("foobar"),
KeyFile: tls.FileOrContent("foobar"),
Stores: []string{
"foobar",
"foobar",
+2 -4
View File
@@ -66,10 +66,8 @@ func Test_globalConfig(t *testing.T) {
for _, test := range cases {
t.Run(test.Name, func(t *testing.T) {
p := Provider{
Configuration: Configuration{
ExposedByDefault: test.ExposedByDefault,
Prefix: test.Prefix,
},
ExposedByDefault: test.ExposedByDefault,
Prefix: test.Prefix,
}
result := p.getExtraConf(test.Tags)
require.Equal(t, test.exp, result)
+44 -57
View File
@@ -23,7 +23,6 @@ import (
"github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd"
"github.com/traefik/traefik/v2/pkg/provider/kubernetes/gateway"
"github.com/traefik/traefik/v2/pkg/provider/kubernetes/ingress"
"github.com/traefik/traefik/v2/pkg/provider/kv"
"github.com/traefik/traefik/v2/pkg/provider/kv/consul"
"github.com/traefik/traefik/v2/pkg/provider/kv/etcd"
"github.com/traefik/traefik/v2/pkg/provider/kv/redis"
@@ -448,11 +447,9 @@ func init() {
},
Certificates: []*traefiktls.CertAndStores{
{
Certificate: traefiktls.Certificate{
CertFile: "cert.pem",
KeyFile: "key.pem",
},
Stores: []string{"foo"},
CertFile: "cert.pem",
KeyFile: "key.pem",
Stores: []string{"foo"},
},
},
Stores: map[string]traefiktls.Store{
@@ -683,36 +680,34 @@ func TestDo_staticConfiguration(t *testing.T) {
}
config.Providers.ConsulCatalog = &consulcatalog.ProviderBuilder{
Configuration: consulcatalog.Configuration{
Constraints: `Label("foo", "bar")`,
Endpoint: &consulcatalog.EndpointConfig{
Address: "MyAddress",
Scheme: "MyScheme",
DataCenter: "MyDatacenter",
Token: "MyToken",
TLS: &types.ClientTLS{
CA: "myCa",
CAOptional: true,
Cert: "mycert.pem",
Key: "mycert.key",
InsecureSkipVerify: true,
},
HTTPAuth: &consulcatalog.EndpointHTTPAuthConfig{
Username: "MyUsername",
Password: "MyPassword",
},
EndpointWaitTime: 42,
Constraints: `Label("foo", "bar")`,
Endpoint: &consulcatalog.EndpointConfig{
Address: "MyAddress",
Scheme: "MyScheme",
DataCenter: "MyDatacenter",
Token: "MyToken",
TLS: &types.ClientTLS{
CA: "myCa",
CAOptional: true,
Cert: "mycert.pem",
Key: "mycert.key",
InsecureSkipVerify: true,
},
Prefix: "MyPrefix",
RefreshInterval: 42,
RequireConsistent: true,
Stale: true,
Cache: true,
ExposedByDefault: true,
DefaultRule: "PathPrefix(`/`)",
HTTPAuth: &consulcatalog.EndpointHTTPAuthConfig{
Username: "MyUsername",
Password: "MyPassword",
},
EndpointWaitTime: 42,
},
Namespace: "ns",
Namespaces: []string{"ns1", "ns2"},
Prefix: "MyPrefix",
RefreshInterval: 42,
RequireConsistent: true,
Stale: true,
Cache: true,
ExposedByDefault: true,
DefaultRule: "PathPrefix(`/`)",
Namespace: "ns",
Namespaces: []string{"ns1", "ns2"},
}
config.Providers.Ecs = &ecs.Provider{
@@ -729,11 +724,9 @@ func TestDo_staticConfiguration(t *testing.T) {
}
config.Providers.Consul = &consul.ProviderBuilder{
Provider: kv.Provider{
RootKey: "RootKey",
Endpoints: nil,
},
Token: "secret",
RootKey: "RootKey",
Endpoints: nil,
Token: "secret",
TLS: &types.ClientTLS{
CA: "myCa",
CAOptional: true,
@@ -746,12 +739,10 @@ func TestDo_staticConfiguration(t *testing.T) {
}
config.Providers.Etcd = &etcd.Provider{
Provider: kv.Provider{
RootKey: "RootKey",
Endpoints: nil,
},
Username: "username",
Password: "password",
RootKey: "RootKey",
Endpoints: nil,
Username: "username",
Password: "password",
TLS: &types.ClientTLS{
CA: "myCa",
CAOptional: true,
@@ -762,21 +753,17 @@ func TestDo_staticConfiguration(t *testing.T) {
}
config.Providers.ZooKeeper = &zk.Provider{
Provider: kv.Provider{
RootKey: "RootKey",
Endpoints: nil,
},
Username: "username",
Password: "password",
RootKey: "RootKey",
Endpoints: nil,
Username: "username",
Password: "password",
}
config.Providers.Redis = &redis.Provider{
Provider: kv.Provider{
RootKey: "RootKey",
Endpoints: nil,
},
Username: "username",
Password: "password",
RootKey: "RootKey",
Endpoints: nil,
Username: "username",
Password: "password",
TLS: &types.ClientTLS{
CA: "myCa",
CAOptional: true,
+6 -4
View File
@@ -149,15 +149,17 @@ func Test_mergeConfiguration_tlsCertificates(t *testing.T) {
"tlsalpn.acme": &dynamic.Configuration{
TLS: &dynamic.TLSConfiguration{
Certificates: []*tls.CertAndStores{{
Certificate: tls.Certificate{CertFile: "foo", KeyFile: "bar"},
Stores: []string{tlsalpn01.ACMETLS1Protocol},
CertFile: "foo",
KeyFile: "bar",
Stores: []string{tlsalpn01.ACMETLS1Protocol},
}},
},
},
},
expected: []*tls.CertAndStores{{
Certificate: tls.Certificate{CertFile: "foo", KeyFile: "bar"},
Stores: []string{tlsalpn01.ACMETLS1Protocol},
CertFile: "foo",
KeyFile: "bar",
Stores: []string{tlsalpn01.ACMETLS1Protocol},
}},
},
}
+2 -2
View File
@@ -192,8 +192,8 @@ func Test_Routing(t *testing.T) {
},
},
[]*traefiktls.CertAndStores{{
Certificate: traefiktls.Certificate{CertFile: traefiktls.FileOrContent(certPEM), KeyFile: traefiktls.FileOrContent(keyPEM)},
Stores: []string{tlsalpn01.ACMETLS1Protocol},
CertFile: traefiktls.FileOrContent(certPEM), KeyFile: traefiktls.FileOrContent(keyPEM),
Stores: []string{tlsalpn01.ACMETLS1Protocol},
}})
middlewaresBuilder := tcpmiddleware.NewBuilder(conf.TCPMiddlewares)
+12 -14
View File
@@ -17,18 +17,8 @@ import (
"github.com/traefik/traefik/v2/pkg/config/dynamic"
"github.com/traefik/traefik/v2/pkg/log"
traefiktls "github.com/traefik/traefik/v2/pkg/tls"
"golang.org/x/net/http2"
)
type h2cTransportWrapper struct {
*http2.Transport
}
func (t *h2cTransportWrapper) RoundTrip(req *http.Request) (*http.Response, error) {
req.URL.Scheme = "http"
return t.Transport.RoundTrip(req)
}
// RoundTripperManager handles roundtripper for the reverse proxy.
type RoundTripperManager struct {
rtLock sync.RWMutex
@@ -133,6 +123,16 @@ func createRoundTripper(cfg *dynamic.ServersTransport) (http.RoundTripper, error
if cfg.ForwardingTimeouts != nil {
transport.ResponseHeaderTimeout = time.Duration(cfg.ForwardingTimeouts.ResponseHeaderTimeout)
transport.IdleConnTimeout = time.Duration(cfg.ForwardingTimeouts.IdleConnTimeout)
// The forwarding timeout names come from the x/net/http2.Transport fields (ReadIdleTimeout/PingTimeout),
// which were used to configure the HTTP/2 health checks before the net/http native support (Go 1.24).
// HTTP2Config.SendPingTimeout carries the same semantics as ReadIdleTimeout:
// the delay without any frame received on a connection after which a ping health check is sent.
// The field was renamed when the HTTP/2 configuration moved to net/http, see https://go.dev/issue/67813.
// The HTTP2 config does not enable HTTP2 protocol.
transport.HTTP2 = &http.HTTP2Config{
SendPingTimeout: time.Duration(cfg.ForwardingTimeouts.ReadIdleTimeout),
PingTimeout: time.Duration(cfg.ForwardingTimeouts.PingTimeout),
}
}
if cfg.InsecureSkipVerify || len(cfg.RootCAs) > 0 || len(cfg.ServerName) > 0 || len(cfg.Certificates) > 0 || cfg.PeerCertURI != "" {
@@ -160,10 +160,8 @@ func createRoundTripper(cfg *dynamic.ServersTransport) (http.RoundTripper, error
}, nil
}
rt, err := newSmartRoundTripper(transport, cfg.ForwardingTimeouts)
if err != nil {
return nil, err
}
rt := newSmartRoundTripper(transport)
return &KerberosRoundTripper{
OriginalRoundTripper: rt,
new: func() http.RoundTripper {
+190
View File
@@ -1,19 +1,26 @@
package service
import (
"bytes"
"crypto/tls"
"crypto/x509"
"io"
"net"
"net/http"
"net/http/httptest"
"net/url"
"sync"
"sync/atomic"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
ptypes "github.com/traefik/paerser/types"
"github.com/traefik/traefik/v2/pkg/config/dynamic"
traefiktls "github.com/traefik/traefik/v2/pkg/tls"
"golang.org/x/net/http2"
"golang.org/x/net/http2/hpack"
)
// LocalhostCert is a PEM-encoded TLS cert
@@ -261,6 +268,7 @@ func TestDisableHTTP2(t *testing.T) {
srv := httptest.NewUnstartedServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.WriteHeader(http.StatusOK)
}))
defer srv.Close()
srv.EnableHTTP2 = test.serverHTTP2
srv.StartTLS()
@@ -290,6 +298,188 @@ func TestDisableHTTP2(t *testing.T) {
}
}
func TestHTTP2HealthCheckTimeouts(t *testing.T) {
rt, err := createRoundTripper(&dynamic.ServersTransport{
ForwardingTimeouts: &dynamic.ForwardingTimeouts{
ReadIdleTimeout: ptypes.Duration(10 * time.Second),
PingTimeout: ptypes.Duration(15 * time.Second),
},
})
require.NoError(t, err)
krt, ok := rt.(*KerberosRoundTripper)
require.True(t, ok)
srt, ok := krt.OriginalRoundTripper.(*smartRoundTripper)
require.True(t, ok)
expected := &http.HTTP2Config{
SendPingTimeout: 10 * time.Second,
PingTimeout: 15 * time.Second,
}
assert.Equal(t, expected, srt.http.HTTP2)
assert.Equal(t, expected, srt.http2.HTTP2)
assert.Equal(t, expected, srt.h2c.HTTP2)
}
func TestProxyHTTP2BackendScheme(t *testing.T) {
testCases := []struct {
desc string
tls bool
expectedScheme string
}{
{
desc: "h2c backend",
expectedScheme: "http",
},
{
desc: "https backend",
tls: true,
expectedScheme: "https",
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
backendURL, schemes := startHTTP2FramerBackend(t, test.tls)
rtManager := NewRoundTripperManager()
rtManager.Update(map[string]*dynamic.ServersTransport{
"test": {
InsecureSkipVerify: true,
},
})
rt, err := rtManager.Get("test")
require.NoError(t, err)
proxy, err := buildProxy(new(true), nil, rt, newBufferPool())
require.NoError(t, err)
// The load balancer sets the backend server on the request URL before the proxy runs.
handler := http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
req.URL.Scheme = backendURL.Scheme
req.URL.Host = backendURL.Host
proxy.ServeHTTP(rw, req)
})
srv := httptest.NewServer(handler)
t.Cleanup(srv.Close)
req, err := http.NewRequestWithContext(t.Context(), http.MethodGet, srv.URL, nil)
require.NoError(t, err)
res, err := http.DefaultClient.Do(req)
require.NoError(t, err)
t.Cleanup(func() { _ = res.Body.Close() })
assert.Equal(t, http.StatusOK, res.StatusCode)
select {
case scheme := <-schemes:
assert.Equal(t, test.expectedScheme, scheme)
default:
t.Error("backend did not receive an HTTP/2 request")
}
})
}
}
// startHTTP2FramerBackend starts a backend speaking raw HTTP/2 frames,
// as the standard library server does not expose the :scheme pseudo-header.
func startHTTP2FramerBackend(t *testing.T, useTLS bool) (*url.URL, <-chan string) {
t.Helper()
ln, err := net.Listen("tcp", "127.0.0.1:0")
require.NoError(t, err)
scheme := "h2c"
if useTLS {
cert, err := tls.X509KeyPair(LocalhostCert, LocalhostKey)
require.NoError(t, err)
ln = tls.NewListener(ln, &tls.Config{
Certificates: []tls.Certificate{cert},
NextProtos: []string{"h2"},
})
scheme = "https"
}
t.Cleanup(func() { _ = ln.Close() })
schemes := make(chan string, 1)
go func() {
for {
conn, err := ln.Accept()
if err != nil {
return
}
go serveHTTP2Frames(conn, schemes)
}
}()
return &url.URL{Scheme: scheme, Host: ln.Addr().String()}, schemes
}
func serveHTTP2Frames(conn net.Conn, schemes chan<- string) {
defer func() { _ = conn.Close() }()
_ = conn.SetDeadline(time.Now().Add(5 * time.Second))
preface := make([]byte, len(http2.ClientPreface))
if _, err := io.ReadFull(conn, preface); err != nil || string(preface) != http2.ClientPreface {
return
}
framer := http2.NewFramer(conn, conn)
framer.ReadMetaHeaders = hpack.NewDecoder(4096, nil)
if err := framer.WriteSettings(); err != nil {
return
}
for {
frame, err := framer.ReadFrame()
if err != nil {
return
}
switch f := frame.(type) {
case *http2.SettingsFrame:
if f.IsAck() {
continue
}
if err := framer.WriteSettingsAck(); err != nil {
return
}
case *http2.MetaHeadersFrame:
select {
case schemes <- f.PseudoValue("scheme"):
default:
}
var headers bytes.Buffer
if err := hpack.NewEncoder(&headers).WriteField(hpack.HeaderField{Name: ":status", Value: "200"}); err != nil {
return
}
err := framer.WriteHeaders(http2.HeadersFrameParam{
StreamID: f.StreamID,
BlockFragment: headers.Bytes(),
EndHeaders: true,
EndStream: true,
})
if err != nil {
return
}
}
}
}
type roundTripperFn func(req *http.Request) (*http.Response, error)
func (r roundTripperFn) RoundTrip(request *http.Request) (*http.Response, error) {
+32 -36
View File
@@ -1,49 +1,33 @@
package service
import (
"crypto/tls"
"net"
"net/http"
"time"
"github.com/traefik/traefik/v2/pkg/config/dynamic"
"golang.org/x/net/http/httpguts"
"golang.org/x/net/http2"
)
func newSmartRoundTripper(transport *http.Transport, forwardingTimeouts *dynamic.ForwardingTimeouts) (*smartRoundTripper, error) {
func newSmartRoundTripper(transport *http.Transport) *smartRoundTripper {
// HTTP/1 only transport for requests with a Connection: Upgrade header.
transportHTTP1 := transport.Clone()
transportHTTP1.Protocols = new(http.Protocols)
transportHTTP1.Protocols.SetHTTP1(true)
transportHTTP2, err := http2.ConfigureTransports(transport)
if err != nil {
return nil, err
}
// Transport switching automatically to HTTP/2 with TLS ALPN.
transportHTTP2 := transport.Clone()
transportHTTP2.Protocols = new(http.Protocols)
transportHTTP2.Protocols.SetHTTP1(true)
transportHTTP2.Protocols.SetHTTP2(true)
if forwardingTimeouts != nil {
transportHTTP2.ReadIdleTimeout = time.Duration(forwardingTimeouts.ReadIdleTimeout)
transportHTTP2.PingTimeout = time.Duration(forwardingTimeouts.PingTimeout)
}
transportH2C := &h2cTransportWrapper{
Transport: &http2.Transport{
DialTLS: func(network, addr string, cfg *tls.Config) (net.Conn, error) {
return net.Dial(network, addr)
},
AllowHTTP: true,
},
}
if forwardingTimeouts != nil {
transportH2C.ReadIdleTimeout = time.Duration(forwardingTimeouts.ReadIdleTimeout)
transportH2C.PingTimeout = time.Duration(forwardingTimeouts.PingTimeout)
}
transport.RegisterProtocol("h2c", transportH2C)
// Transport speaking HTTP/2 with prior knowledge on unencrypted connections.
transportH2C := transport.Clone()
transportH2C.Protocols = new(http.Protocols)
transportH2C.Protocols.SetUnencryptedHTTP2(true)
return &smartRoundTripper{
http2: transport,
http2: transportHTTP2,
http: transportHTTP1,
}, nil
h2c: transportH2C,
}
}
// smartRoundTripper implements RoundTrip while making sure that HTTP/2 is not used
@@ -51,19 +35,31 @@ func newSmartRoundTripper(transport *http.Transport, forwardingTimeouts *dynamic
type smartRoundTripper struct {
http2 *http.Transport
http *http.Transport
h2c *http.Transport
}
func (m *smartRoundTripper) Clone() http.RoundTripper {
h := m.http.Clone()
h2 := m.http2.Clone()
return &smartRoundTripper{http: h, http2: h2}
return &smartRoundTripper{
http2: m.http2.Clone(),
http: m.http.Clone(),
h2c: m.h2c.Clone(),
}
}
func (m *smartRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
// If we have a connection upgrade, we don't use HTTP/2
h2c := req.URL.Scheme == "h2c"
if h2c {
req.URL.Scheme = "http"
}
// Connection upgrades cannot be carried over HTTP/2, they always use HTTP/1.
if httpguts.HeaderValuesContainsToken(req.Header["Connection"], "Upgrade") {
return m.http.RoundTrip(req)
}
if h2c {
return m.h2c.RoundTrip(req)
}
return m.http2.RoundTrip(req)
}
+6 -12
View File
@@ -69,10 +69,8 @@ ZboOWVe3icTy64BT3OQhmg==
func TestTLSInStore(t *testing.T) {
dynamicConfigs := []*CertAndStores{{
Certificate: Certificate{
CertFile: localhostCert,
KeyFile: localhostKey,
},
CertFile: localhostCert,
KeyFile: localhostKey,
}}
tlsManager := NewManager()
@@ -86,10 +84,8 @@ func TestTLSInStore(t *testing.T) {
func TestTLSInvalidStore(t *testing.T) {
dynamicConfigs := []*CertAndStores{{
Certificate: Certificate{
CertFile: localhostCert,
KeyFile: localhostKey,
},
CertFile: localhostCert,
KeyFile: localhostKey,
}}
tlsManager := NewManager()
@@ -111,10 +107,8 @@ func TestTLSInvalidStore(t *testing.T) {
func TestManager_Get(t *testing.T) {
dynamicConfigs := []*CertAndStores{{
Certificate: Certificate{
CertFile: localhostCert,
KeyFile: localhostKey,
},
CertFile: localhostCert,
KeyFile: localhostKey,
}}
tlsConfigs := map[string]Options{