Merge branch v3.6 into v3.7

This commit is contained in:
romain
2026-06-03 14:44:43 +02:00
43 changed files with 730 additions and 692 deletions
@@ -8,6 +8,7 @@
[entryPoints.websecure]
address = ":4443"
[entryPoints.websecure.http3]
[api]
insecure = true
@@ -33,6 +34,35 @@
[http.routers.router3.tls]
options = "mytls"
[http.routers.router4]
rule = "Host(`site4.www.snitest.com`)"
service = "service4"
[http.routers.router4.tls]
[http.routers.router4path]
rule = "Host(`site4.www.snitest.com`) && PathPrefix(`/foo`)"
service = "service4"
[http.routers.router4path.tls]
options = "mytls"
[http.routers.router5]
rule = "Host(`site5.www.snitest.com`)"
service = "service5"
[http.routers.router5.tls]
options = "mytls"
[http.routers.router5path]
rule = "Host(`site5.www.snitest.com`) && PathPrefix(`/bar`)"
service = "service5"
[http.routers.router5path.tls]
options = "mytls"
[http.routers.router6]
rule = "Host(`site6.www.snitest.com.`)"
service = "service6"
[http.routers.router6.tls]
options = "mytls"
[http.services.service1]
[[http.services.service1.loadBalancer.servers]]
url = "http://127.0.0.1:9010"
@@ -45,10 +75,22 @@
[[http.services.service3.loadBalancer.servers]]
url = "http://127.0.0.1:9030"
[http.services.service4]
[[http.services.service4.loadBalancer.servers]]
url = "http://127.0.0.1:9040"
[http.services.service5]
[[http.services.service5.loadBalancer.servers]]
url = "http://127.0.0.1:9050"
[http.services.service6]
[[http.services.service6.loadBalancer.servers]]
url = "http://127.0.0.1:9060"
[[tls.certificates]]
certFile = "fixtures/https/wildcard.www.snitest.com.cert"
keyFile = "fixtures/https/wildcard.www.snitest.com.key"
[tls.options]
[tls.options.mytls]
maxVersion = "VersionTLS12"
maxVersion = "VersionTLS13"
+37 -24
View File
@@ -13,6 +13,7 @@ import (
"time"
"github.com/BurntSushi/toml"
"github.com/quic-go/quic-go/http3"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
@@ -352,7 +353,7 @@ func (s *HTTPSSuite) TestWithConflictingTLSOptions() {
assert.ErrorContains(s.T(), err, "tls: no supported versions satisfy MinVersion and MaxVersion")
// with unknown tls option
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains(fmt.Sprintf("found different TLS options for routers on the same host %v, so using the default TLS options instead", tr4.TLSClientConfig.ServerName)))
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains("found different TLS options for routers on the same host, so using the default TLS options instead"))
require.NoError(s.T(), err)
}
@@ -1083,19 +1084,20 @@ func (s *HTTPSSuite) TestWithDomainFronting() {
defer backend2.Close()
backend3 := startTestServer("9030", http.StatusOK, "server3")
defer backend3.Close()
backend5 := startTestServer("9050", http.StatusOK, "server5")
defer backend5.Close()
file := s.adaptFile("fixtures/https/https_domain_fronting.toml", struct{}{})
s.traefikCmd(withConfigFile(file))
// wait for Traefik
err := try.GetRequest("http://127.0.0.1:8080/api/rawdata", 500*time.Millisecond, try.BodyContains("Host(`site1.www.snitest.com`)"))
err := try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1000*time.Millisecond, try.BodyContains("Host(`site1.www.snitest.com`)"))
require.NoError(s.T(), err)
testCases := []struct {
desc string
hostHeader string
serverName string
expectedError bool
expectedContent string
expectedStatusCode int
}{
@@ -1113,14 +1115,6 @@ func (s *HTTPSSuite) TestWithDomainFronting() {
expectedContent: "server3",
expectedStatusCode: http.StatusOK,
},
{
desc: "Spaces after the host header",
hostHeader: "site3.www.snitest.com ",
serverName: "site3.www.snitest.com",
expectedError: true,
expectedContent: "server3",
expectedStatusCode: http.StatusOK,
},
{
desc: "Spaces after the servername",
hostHeader: "site3.www.snitest.com",
@@ -1128,14 +1122,6 @@ func (s *HTTPSSuite) TestWithDomainFronting() {
expectedContent: "server3",
expectedStatusCode: http.StatusOK,
},
{
desc: "Spaces after the servername and host header",
hostHeader: "site3.www.snitest.com ",
serverName: "site3.www.snitest.com ",
expectedError: true,
expectedContent: "server3",
expectedStatusCode: http.StatusOK,
},
{
desc: "Domain Fronting with same tlsOptions should follow header",
hostHeader: "site1.www.snitest.com",
@@ -1171,6 +1157,34 @@ func (s *HTTPSSuite) TestWithDomainFronting() {
expectedContent: "server1",
expectedStatusCode: http.StatusOK,
},
{
desc: "Domain Fronting with ambiguous TLS options should produce a 421",
hostHeader: "site4.www.snitest.com",
serverName: "site3.www.snitest.com",
expectedContent: "",
expectedStatusCode: http.StatusMisdirectedRequest,
},
{
desc: "Domain Fronting with same non-default TLS options should not produce a 421",
hostHeader: "site5.www.snitest.com",
serverName: "site3.www.snitest.com",
expectedContent: "server5",
expectedStatusCode: http.StatusOK,
},
{
desc: "FQDN host header with empty SNI to non-default TLS options route should produce a 421",
hostHeader: "site3.www.snitest.com.",
serverName: "",
expectedContent: "",
expectedStatusCode: http.StatusMisdirectedRequest,
},
{
desc: "Non-FQDN host header with empty SNI matching FQDN route rule should produce a 421",
hostHeader: "site6.www.snitest.com",
serverName: "",
expectedContent: "",
expectedStatusCode: http.StatusMisdirectedRequest,
},
}
for _, test := range testCases {
@@ -1179,11 +1193,10 @@ func (s *HTTPSSuite) TestWithDomainFronting() {
req.Host = test.hostHeader
err = try.RequestWithTransport(req, 500*time.Millisecond, &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true, ServerName: test.serverName}}, try.StatusCodeIs(test.expectedStatusCode), try.BodyContains(test.expectedContent))
if test.expectedError {
assert.Error(s.T(), err)
} else {
require.NoError(s.T(), err)
}
assert.NoError(s.T(), err, "test %s failed with: %v", test.desc, err)
err = try.RequestWithTransport(req, 500*time.Millisecond, &http3.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true, ServerName: test.serverName}}, try.StatusCodeIs(test.expectedStatusCode), try.BodyContains(test.expectedContent))
assert.NoError(s.T(), err, "test %s failed with: %v", test.desc, err)
}
}
+1 -1
View File
@@ -949,7 +949,7 @@ func (s *SimpleSuite) TestRouterConfigErrors() {
s.traefikCmd(withConfigFile(file))
// All errors
err := try.GetRequest("http://127.0.0.1:8080/api/http/routers", 1000*time.Millisecond, try.BodyContains(`["middleware \"unknown@file\" does not exist","found different TLS options for routers on the same host snitest.net, so using the default TLS options instead"]`))
err := try.GetRequest("http://127.0.0.1:8080/api/http/routers", 1000*time.Millisecond, try.BodyContains(`["middleware \"unknown@file\" does not exist","found different TLS options for routers on the same host, so using the default TLS options instead"]`))
require.NoError(s.T(), err)
// router3 has an error because it uses an unknown entrypoint
+3 -3
View File
@@ -76,7 +76,7 @@ func Request(req *http.Request, timeout time.Duration, conditions ...ResponseCon
// the condition on the response.
// ResponseCondition may be nil, in which case only the request against the URL must
// succeed.
func RequestWithTransport(req *http.Request, timeout time.Duration, transport *http.Transport, conditions ...ResponseCondition) error {
func RequestWithTransport(req *http.Request, timeout time.Duration, transport http.RoundTripper, conditions ...ResponseCondition) error {
resp, err := doTryRequest(req, timeout, transport, conditions...)
if resp != nil && resp.Body != nil {
@@ -140,12 +140,12 @@ func doTryRequest(request *http.Request, timeout time.Duration, transport http.R
func doRequest(action timedAction, timeout time.Duration, request *http.Request, transport http.RoundTripper, conditions ...ResponseCondition) (*http.Response, error) {
var resp *http.Response
return resp, action(timeout, func() error {
var err error
client := http.DefaultClient
var client http.Client
if transport != nil {
client.Transport = transport
}
var err error
resp, err = client.Do(request)
if err != nil {
return err