Merge branch v3.1 into master
This commit is contained in:
commit
54c3afd760
23 changed files with 134 additions and 142 deletions
|
@ -13,22 +13,21 @@ const (
|
|||
upgradeHeader = "Upgrade"
|
||||
)
|
||||
|
||||
// Remover removes hop-by-hop headers listed in the "Connection" header.
|
||||
// RemoveConnectionHeaders removes hop-by-hop headers listed in the "Connection" header.
|
||||
// See RFC 7230, section 6.1.
|
||||
func Remover(next http.Handler) http.HandlerFunc {
|
||||
return func(rw http.ResponseWriter, req *http.Request) {
|
||||
next.ServeHTTP(rw, Remove(req))
|
||||
}
|
||||
}
|
||||
|
||||
// Remove removes hop-by-hop header on the request.
|
||||
func Remove(req *http.Request) *http.Request {
|
||||
func RemoveConnectionHeaders(req *http.Request) {
|
||||
var reqUpType string
|
||||
if httpguts.HeaderValuesContainsToken(req.Header[connectionHeader], upgradeHeader) {
|
||||
reqUpType = req.Header.Get(upgradeHeader)
|
||||
}
|
||||
|
||||
removeConnectionHeaders(req.Header)
|
||||
for _, f := range req.Header[connectionHeader] {
|
||||
for _, sf := range strings.Split(f, ",") {
|
||||
if sf = textproto.TrimString(sf); sf != "" {
|
||||
req.Header.Del(sf)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if reqUpType != "" {
|
||||
req.Header.Set(connectionHeader, upgradeHeader)
|
||||
|
@ -36,16 +35,4 @@ func Remove(req *http.Request) *http.Request {
|
|||
} else {
|
||||
req.Header.Del(connectionHeader)
|
||||
}
|
||||
|
||||
return req
|
||||
}
|
||||
|
||||
func removeConnectionHeaders(h http.Header) {
|
||||
for _, f := range h[connectionHeader] {
|
||||
for _, sf := range strings.Split(f, ",") {
|
||||
if sf = textproto.TrimString(sf); sf != "" {
|
||||
h.Del(sf)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,19 +50,13 @@ func TestRemover(t *testing.T) {
|
|||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
next := http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {})
|
||||
|
||||
h := Remover(next)
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "https://localhost", nil)
|
||||
|
||||
for k, v := range test.reqHeaders {
|
||||
req.Header.Set(k, v)
|
||||
}
|
||||
|
||||
rw := httptest.NewRecorder()
|
||||
|
||||
h.ServeHTTP(rw, req)
|
||||
RemoveConnectionHeaders(req)
|
||||
|
||||
assert.Equal(t, test.expected, req.Header)
|
||||
})
|
||||
|
|
|
@ -123,8 +123,6 @@ func (fa *forwardAuth) GetTracingInformation() (string, string, trace.SpanKind)
|
|||
func (fa *forwardAuth) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||
logger := middlewares.GetLogger(req.Context(), fa.name, typeNameForward)
|
||||
|
||||
req = Remove(req)
|
||||
|
||||
forwardReq, err := http.NewRequestWithContext(req.Context(), http.MethodGet, fa.address, nil)
|
||||
if err != nil {
|
||||
logger.Debug().Msgf("Error calling %s. Cause %s", fa.address, err)
|
||||
|
@ -274,6 +272,8 @@ func (fa *forwardAuth) buildModifier(authCookies []*http.Cookie) func(res *http.
|
|||
|
||||
func writeHeader(req, forwardReq *http.Request, trustForwardHeader bool, allowedHeaders []string) {
|
||||
utils.CopyHeaders(forwardReq.Header, req.Header)
|
||||
|
||||
RemoveConnectionHeaders(forwardReq)
|
||||
utils.RemoveHeaders(forwardReq.Header, hopHeaders...)
|
||||
|
||||
forwardReq.Header = filterForwardRequestHeaders(forwardReq.Header, allowedHeaders)
|
||||
|
|
|
@ -623,8 +623,11 @@ func (p *Provider) resolveDefaultCertificate(ctx context.Context, domains []stri
|
|||
|
||||
p.resolvingDomainsMutex.Lock()
|
||||
|
||||
sort.Strings(domains)
|
||||
domainKey := strings.Join(domains, ",")
|
||||
sortedDomains := make([]string, len(domains))
|
||||
copy(sortedDomains, domains)
|
||||
sort.Strings(sortedDomains)
|
||||
|
||||
domainKey := strings.Join(sortedDomains, ",")
|
||||
|
||||
if _, ok := p.resolvingDomains[domainKey]; ok {
|
||||
p.resolvingDomainsMutex.Unlock()
|
||||
|
@ -1026,12 +1029,14 @@ func (p *Provider) certExists(validDomains []string) bool {
|
|||
p.certificatesMu.RLock()
|
||||
defer p.certificatesMu.RUnlock()
|
||||
|
||||
sort.Strings(validDomains)
|
||||
sortedDomains := make([]string, len(validDomains))
|
||||
copy(sortedDomains, validDomains)
|
||||
sort.Strings(sortedDomains)
|
||||
|
||||
for _, cert := range p.certificates {
|
||||
domains := cert.Certificate.Domain.ToStrArray()
|
||||
sort.Strings(domains)
|
||||
if reflect.DeepEqual(domains, validDomains) {
|
||||
if reflect.DeepEqual(domains, sortedDomains) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -219,7 +219,7 @@ func (p *Provider) loadConfigurationFromIngresses(ctx context.Context, client Cl
|
|||
|
||||
var ingressClasses []*netv1.IngressClass
|
||||
|
||||
if !p.DisableIngressClassLookup {
|
||||
if !p.DisableIngressClassLookup && !p.DisableClusterScopeResources {
|
||||
ics, err := client.GetIngressClasses()
|
||||
if err != nil {
|
||||
log.Ctx(ctx).Warn().Err(err).Msg("Failed to list ingress classes")
|
||||
|
|
|
@ -26,11 +26,12 @@ func Bool(v bool) *bool { return &v }
|
|||
|
||||
func TestLoadConfigurationFromIngresses(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
ingressClass string
|
||||
expected *dynamic.Configuration
|
||||
allowEmptyServices bool
|
||||
disableIngressClassLookup bool
|
||||
desc string
|
||||
ingressClass string
|
||||
expected *dynamic.Configuration
|
||||
allowEmptyServices bool
|
||||
disableIngressClassLookup bool
|
||||
disableClusterScopeResources bool
|
||||
}{
|
||||
{
|
||||
desc: "Empty ingresses",
|
||||
|
@ -1335,6 +1336,38 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
// Duplicate test case with the same fixture as the one above, but with the disableClusterScopeResources option to true.
|
||||
// Showing that disabling the ingressClass discovery still allow the discovery of ingresses with ingress annotation.
|
||||
desc: "Ingress with ingress annotation",
|
||||
disableClusterScopeResources: true,
|
||||
expected: &dynamic.Configuration{
|
||||
HTTP: &dynamic.HTTPConfiguration{
|
||||
Middlewares: map[string]*dynamic.Middleware{},
|
||||
Routers: map[string]*dynamic.Router{
|
||||
"testing-bar": {
|
||||
Rule: "PathPrefix(`/bar`)",
|
||||
Service: "testing-service1-80",
|
||||
},
|
||||
},
|
||||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-80": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
ResponseForwarding: &dynamic.ResponseForwarding{
|
||||
FlushInterval: ptypes.Duration(100 * time.Millisecond),
|
||||
},
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:8080",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "Ingress with ingressClass",
|
||||
expected: &dynamic.Configuration{
|
||||
|
@ -1377,6 +1410,19 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
// Duplicate test case with the same fixture as the one above, but with the disableClusterScopeResources option to true.
|
||||
// Showing that disabling the ingressClass discovery avoid discovering Ingresses with an IngressClass.
|
||||
desc: "Ingress with ingressClass",
|
||||
disableClusterScopeResources: true,
|
||||
expected: &dynamic.Configuration{
|
||||
HTTP: &dynamic.HTTPConfiguration{
|
||||
Middlewares: map[string]*dynamic.Middleware{},
|
||||
Routers: map[string]*dynamic.Router{},
|
||||
Services: map[string]*dynamic.Service{},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "Ingress with named port",
|
||||
expected: &dynamic.Configuration{
|
||||
|
@ -1455,9 +1501,10 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
|
||||
clientMock := newClientMock(generateTestFilename(test.desc))
|
||||
p := Provider{
|
||||
IngressClass: test.ingressClass,
|
||||
AllowEmptyServices: test.allowEmptyServices,
|
||||
DisableIngressClassLookup: test.disableIngressClassLookup,
|
||||
IngressClass: test.ingressClass,
|
||||
AllowEmptyServices: test.allowEmptyServices,
|
||||
DisableIngressClassLookup: test.disableIngressClassLookup,
|
||||
DisableClusterScopeResources: test.disableClusterScopeResources,
|
||||
}
|
||||
conf := p.loadConfigurationFromIngresses(context.Background(), clientMock)
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ func isPostgres(br *bufio.Reader) (bool, error) {
|
|||
peeked, err := br.Peek(i)
|
||||
if err != nil {
|
||||
var opErr *net.OpError
|
||||
if !errors.Is(err, io.EOF) && (!errors.As(err, &opErr) || opErr.Timeout()) {
|
||||
if !errors.Is(err, io.EOF) && (!errors.As(err, &opErr) || !opErr.Timeout()) {
|
||||
log.Error().Err(err).Msg("Error while Peeking first byte")
|
||||
}
|
||||
return false, err
|
||||
|
|
|
@ -363,7 +363,7 @@ func clientHelloInfo(br *bufio.Reader) (*clientHello, error) {
|
|||
hdr, err := br.Peek(1)
|
||||
if err != nil {
|
||||
var opErr *net.OpError
|
||||
if !errors.Is(err, io.EOF) && (!errors.As(err, &opErr) || opErr.Timeout()) {
|
||||
if !errors.Is(err, io.EOF) && (!errors.As(err, &opErr) || !opErr.Timeout()) {
|
||||
log.Error().Err(err).Msg("Error while Peeking first byte")
|
||||
}
|
||||
return nil, err
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue