1
0
Fork 0

Add rate limiter, rename maxConn into inFlightReq

Co-authored-by: Julien Salleyron <julien.salleyron@gmail.com>
Co-authored-by: Jean-Baptiste Doumenjou <jb.doumenjou@gmail.com>
This commit is contained in:
mpl 2019-08-26 12:20:06 +02:00 committed by Traefiker Bot
parent a8c73f7baf
commit 4ec90c5c0d
30 changed files with 1419 additions and 651 deletions

View file

@ -295,9 +295,14 @@
key = "foobar"
insecureSkipVerify = true
[http.middlewares.Middleware16]
[http.middlewares.Middleware16.maxConn]
[http.middlewares.Middleware16.inFlightReq]
amount = 42
extractorFunc = "foobar"
[http.middlewares.Middleware16.inFlightReq.sourceCriterion]
requestHeaderName = "foobar"
requestHost = true
[http.middlewares.Middleware16.inFlightReq.sourceCriterion.ipStrategy]
depth = 42
excludedIPs = ["foobar", "foobar"]
[http.middlewares.Middleware17]
[http.middlewares.Middleware17.buffering]
maxRequestBodyBytes = 42

View file

@ -8,30 +8,28 @@ import (
"os"
"github.com/containous/traefik/v2/pkg/ip"
"github.com/containous/traefik/v2/pkg/types"
)
// +k8s:deepcopy-gen=true
// Middleware holds the Middleware configuration.
type Middleware struct {
AddPrefix *AddPrefix `json:"addPrefix,omitempty" toml:"addPrefix,omitempty" yaml:"addPrefix,omitempty"`
StripPrefix *StripPrefix `json:"stripPrefix,omitempty" toml:"stripPrefix,omitempty" yaml:"stripPrefix,omitempty"`
StripPrefixRegex *StripPrefixRegex `json:"stripPrefixRegex,omitempty" toml:"stripPrefixRegex,omitempty" yaml:"stripPrefixRegex,omitempty"`
ReplacePath *ReplacePath `json:"replacePath,omitempty" toml:"replacePath,omitempty" yaml:"replacePath,omitempty"`
ReplacePathRegex *ReplacePathRegex `json:"replacePathRegex,omitempty" toml:"replacePathRegex,omitempty" yaml:"replacePathRegex,omitempty"`
Chain *Chain `json:"chain,omitempty" toml:"chain,omitempty" yaml:"chain,omitempty"`
IPWhiteList *IPWhiteList `json:"ipWhiteList,omitempty" toml:"ipWhiteList,omitempty" yaml:"ipWhiteList,omitempty"`
Headers *Headers `json:"headers,omitempty" toml:"headers,omitempty" yaml:"headers,omitempty"`
Errors *ErrorPage `json:"errors,omitempty" toml:"errors,omitempty" yaml:"errors,omitempty"`
// TODO: disable temporarily
// RateLimit *RateLimit `json:"rateLimit,omitempty" toml:"rateLimit,omitempty" yaml:"rateLimit,omitempty"`
AddPrefix *AddPrefix `json:"addPrefix,omitempty" toml:"addPrefix,omitempty" yaml:"addPrefix,omitempty"`
StripPrefix *StripPrefix `json:"stripPrefix,omitempty" toml:"stripPrefix,omitempty" yaml:"stripPrefix,omitempty"`
StripPrefixRegex *StripPrefixRegex `json:"stripPrefixRegex,omitempty" toml:"stripPrefixRegex,omitempty" yaml:"stripPrefixRegex,omitempty"`
ReplacePath *ReplacePath `json:"replacePath,omitempty" toml:"replacePath,omitempty" yaml:"replacePath,omitempty"`
ReplacePathRegex *ReplacePathRegex `json:"replacePathRegex,omitempty" toml:"replacePathRegex,omitempty" yaml:"replacePathRegex,omitempty"`
Chain *Chain `json:"chain,omitempty" toml:"chain,omitempty" yaml:"chain,omitempty"`
IPWhiteList *IPWhiteList `json:"ipWhiteList,omitempty" toml:"ipWhiteList,omitempty" yaml:"ipWhiteList,omitempty"`
Headers *Headers `json:"headers,omitempty" toml:"headers,omitempty" yaml:"headers,omitempty"`
Errors *ErrorPage `json:"errors,omitempty" toml:"errors,omitempty" yaml:"errors,omitempty"`
RateLimit *RateLimit `json:"rateLimit,omitempty" toml:"rateLimit,omitempty" yaml:"rateLimit,omitempty"`
RedirectRegex *RedirectRegex `json:"redirectRegex,omitempty" toml:"redirectRegex,omitempty" yaml:"redirectRegex,omitempty"`
RedirectScheme *RedirectScheme `json:"redirectScheme,omitempty" toml:"redirectScheme,omitempty" yaml:"redirectScheme,omitempty"`
BasicAuth *BasicAuth `json:"basicAuth,omitempty" toml:"basicAuth,omitempty" yaml:"basicAuth,omitempty"`
DigestAuth *DigestAuth `json:"digestAuth,omitempty" toml:"digestAuth,omitempty" yaml:"digestAuth,omitempty"`
ForwardAuth *ForwardAuth `json:"forwardAuth,omitempty" toml:"forwardAuth,omitempty" yaml:"forwardAuth,omitempty"`
MaxConn *MaxConn `json:"maxConn,omitempty" toml:"maxConn,omitempty" yaml:"maxConn,omitempty"`
InFlightReq *InFlightReq `json:"inFlightReq,omitempty" toml:"inFlightReq,omitempty" yaml:"inFlightReq,omitempty"`
Buffering *Buffering `json:"buffering,omitempty" toml:"buffering,omitempty" yaml:"buffering,omitempty"`
CircuitBreaker *CircuitBreaker `json:"circuitBreaker,omitempty" toml:"circuitBreaker,omitempty" yaml:"circuitBreaker,omitempty"`
Compress *Compress `json:"compress,omitempty" toml:"compress,omitempty" yaml:"compress,omitempty" label:"allowEmpty"`
@ -219,10 +217,11 @@ func (h *Headers) HasSecureHeadersDefined() bool {
type IPStrategy struct {
Depth int `json:"depth,omitempty" toml:"depth,omitempty" yaml:"depth,omitempty" export:"true"`
ExcludedIPs []string `json:"excludedIPs,omitempty" toml:"excludedIPs,omitempty" yaml:"excludedIPs,omitempty"`
// TODO(mpl): I think we should make RemoteAddr an explicit field. For one thing, it would yield better documentation.
}
// Get an IP selection strategy
// if nil return the RemoteAddr strategy
// Get an IP selection strategy.
// If nil return the RemoteAddr strategy
// else return a strategy base on the configuration using the X-Forwarded-For Header.
// Depth override the ExcludedIPs
func (s *IPStrategy) Get() (ip.Strategy, error) {
@ -259,15 +258,17 @@ type IPWhiteList struct {
// +k8s:deepcopy-gen=true
// MaxConn holds maximum connection configuration.
type MaxConn struct {
Amount int64 `json:"amount,omitempty" toml:"amount,omitempty" yaml:"amount,omitempty"`
ExtractorFunc string `json:"extractorFunc,omitempty" toml:"extractorFunc,omitempty" yaml:"extractorFunc,omitempty"`
// InFlightReq limits the number of requests being processed and served concurrently.
type InFlightReq struct {
Amount int64 `json:"amount,omitempty" toml:"amount,omitempty" yaml:"amount,omitempty"`
SourceCriterion *SourceCriterion `json:"sourceCriterion,omitempty" toml:"sourceCriterion,omitempty" yaml:"sourceCriterion,omitempty"`
}
// SetDefaults Default values for a MaxConn.
func (m *MaxConn) SetDefaults() {
m.ExtractorFunc = "request.host"
// SetDefaults Default values for a InFlightReq.
func (i *InFlightReq) SetDefaults() {
i.SourceCriterion = &SourceCriterion{
RequestHost: true,
}
}
// +k8s:deepcopy-gen=true
@ -280,25 +281,34 @@ type PassTLSClientCert struct {
// +k8s:deepcopy-gen=true
// Rate holds the rate limiting configuration for a specific time period.
type Rate struct {
Period types.Duration `json:"period,omitempty" toml:"period,omitempty" yaml:"period,omitempty"`
Average int64 `json:"average,omitempty" toml:"average,omitempty" yaml:"average,omitempty"`
Burst int64 `json:"burst,omitempty" toml:"burst,omitempty" yaml:"burst,omitempty"`
// SourceCriterion defines what criterion is used to group requests as originating from a common source.
// The precedence order is IPStrategy, then RequestHeaderName.
// If none are set, the default is to use the request's remote address field.
type SourceCriterion struct {
IPStrategy *IPStrategy `json:"ipStrategy" toml:"ipStrategy, omitempty"`
RequestHeaderName string `json:"requestHeaderName,omitempty" toml:"requestHeaderName,omitempty" yaml:"requestHeaderName,omitempty"`
RequestHost bool `json:"requestHost,omitempty" toml:"requestHost,omitempty" yaml:"requestHost,omitempty"`
}
// +k8s:deepcopy-gen=true
// RateLimit holds the rate limiting configuration for a given frontend.
// RateLimit holds the rate limiting configuration for a given router.
type RateLimit struct {
RateSet map[string]*Rate `json:"rateSet,omitempty" toml:"rateSet,omitempty" yaml:"rateSet,omitempty"`
// FIXME replace by ipStrategy see oxy and replace
ExtractorFunc string `json:"extractorFunc,omitempty" toml:"extractorFunc,omitempty" yaml:"extractorFunc,omitempty"`
// Average is the maximum rate, in requests/s, allowed for the given source.
// It defaults to 0, which means no rate limiting.
Average int64 `json:"average,omitempty" toml:"average,omitempty" yaml:"average,omitempty"`
// Burst is the maximum number of requests allowed to arrive in the same arbitrarily small period of time.
// It defaults to 1.
Burst int64 `json:"burst,omitempty" toml:"burst,omitempty" yaml:"burst,omitempty"`
SourceCriterion *SourceCriterion `json:"sourceCriterion,omitempty" toml:"sourceCriterion,omitempty" yaml:"sourceCriterion,omitempty"`
}
// SetDefaults Default values for a MaxConn.
// SetDefaults sets the default values on a RateLimit.
func (r *RateLimit) SetDefaults() {
r.ExtractorFunc = "request.host"
r.Burst = 1
r.SourceCriterion = &SourceCriterion{
IPStrategy: &IPStrategy{},
}
}
// +k8s:deepcopy-gen=true
@ -398,30 +408,30 @@ type ClientTLS struct {
}
// CreateTLSConfig creates a TLS config from ClientTLS structures.
func (clientTLS *ClientTLS) CreateTLSConfig() (*tls.Config, error) {
if clientTLS == nil {
func (c *ClientTLS) CreateTLSConfig() (*tls.Config, error) {
if c == nil {
return nil, nil
}
var err error
caPool := x509.NewCertPool()
clientAuth := tls.NoClientCert
if clientTLS.CA != "" {
if c.CA != "" {
var ca []byte
if _, errCA := os.Stat(clientTLS.CA); errCA == nil {
ca, err = ioutil.ReadFile(clientTLS.CA)
if _, errCA := os.Stat(c.CA); errCA == nil {
ca, err = ioutil.ReadFile(c.CA)
if err != nil {
return nil, fmt.Errorf("failed to read CA. %s", err)
}
} else {
ca = []byte(clientTLS.CA)
ca = []byte(c.CA)
}
if !caPool.AppendCertsFromPEM(ca) {
return nil, fmt.Errorf("failed to parse CA")
}
if clientTLS.CAOptional {
if c.CAOptional {
clientAuth = tls.VerifyClientCertIfGiven
} else {
clientAuth = tls.RequireAndVerifyClientCert
@ -429,16 +439,16 @@ func (clientTLS *ClientTLS) CreateTLSConfig() (*tls.Config, error) {
}
cert := tls.Certificate{}
_, errKeyIsFile := os.Stat(clientTLS.Key)
_, errKeyIsFile := os.Stat(c.Key)
if !clientTLS.InsecureSkipVerify && (len(clientTLS.Cert) == 0 || len(clientTLS.Key) == 0) {
if !c.InsecureSkipVerify && (len(c.Cert) == 0 || len(c.Key) == 0) {
return nil, fmt.Errorf("TLS Certificate or Key file must be set when TLS configuration is created")
}
if len(clientTLS.Cert) > 0 && len(clientTLS.Key) > 0 {
if _, errCertIsFile := os.Stat(clientTLS.Cert); errCertIsFile == nil {
if len(c.Cert) > 0 && len(c.Key) > 0 {
if _, errCertIsFile := os.Stat(c.Cert); errCertIsFile == nil {
if errKeyIsFile == nil {
cert, err = tls.LoadX509KeyPair(clientTLS.Cert, clientTLS.Key)
cert, err = tls.LoadX509KeyPair(c.Cert, c.Key)
if err != nil {
return nil, fmt.Errorf("failed to load TLS keypair: %v", err)
}
@ -447,7 +457,7 @@ func (clientTLS *ClientTLS) CreateTLSConfig() (*tls.Config, error) {
}
} else {
if errKeyIsFile != nil {
cert, err = tls.X509KeyPair([]byte(clientTLS.Cert), []byte(clientTLS.Key))
cert, err = tls.X509KeyPair([]byte(c.Cert), []byte(c.Key))
if err != nil {
return nil, fmt.Errorf("failed to load TLS keypair: %v", err)
@ -461,7 +471,7 @@ func (clientTLS *ClientTLS) CreateTLSConfig() (*tls.Config, error) {
return &tls.Config{
Certificates: []tls.Certificate{cert},
RootCAs: caPool,
InsecureSkipVerify: clientTLS.InsecureSkipVerify,
InsecureSkipVerify: c.InsecureSkipVerify,
ClientAuth: clientAuth,
}, nil
}

View file

@ -525,17 +525,22 @@ func (in *IPWhiteList) DeepCopy() *IPWhiteList {
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *MaxConn) DeepCopyInto(out *MaxConn) {
func (in *InFlightReq) DeepCopyInto(out *InFlightReq) {
*out = *in
if in.SourceCriterion != nil {
in, out := &in.SourceCriterion, &out.SourceCriterion
*out = new(SourceCriterion)
(*in).DeepCopyInto(*out)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MaxConn.
func (in *MaxConn) DeepCopy() *MaxConn {
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InFlightReq.
func (in *InFlightReq) DeepCopy() *InFlightReq {
if in == nil {
return nil
}
out := new(MaxConn)
out := new(InFlightReq)
in.DeepCopyInto(out)
return out
}
@ -609,6 +614,11 @@ func (in *Middleware) DeepCopyInto(out *Middleware) {
*out = new(ErrorPage)
(*in).DeepCopyInto(*out)
}
if in.RateLimit != nil {
in, out := &in.RateLimit, &out.RateLimit
*out = new(RateLimit)
(*in).DeepCopyInto(*out)
}
if in.RedirectRegex != nil {
in, out := &in.RedirectRegex, &out.RedirectRegex
*out = new(RedirectRegex)
@ -634,10 +644,10 @@ func (in *Middleware) DeepCopyInto(out *Middleware) {
*out = new(ForwardAuth)
(*in).DeepCopyInto(*out)
}
if in.MaxConn != nil {
in, out := &in.MaxConn, &out.MaxConn
*out = new(MaxConn)
**out = **in
if in.InFlightReq != nil {
in, out := &in.InFlightReq, &out.InFlightReq
*out = new(InFlightReq)
(*in).DeepCopyInto(*out)
}
if in.Buffering != nil {
in, out := &in.Buffering, &out.Buffering
@ -698,39 +708,13 @@ func (in *PassTLSClientCert) DeepCopy() *PassTLSClientCert {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Rate) DeepCopyInto(out *Rate) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Rate.
func (in *Rate) DeepCopy() *Rate {
if in == nil {
return nil
}
out := new(Rate)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *RateLimit) DeepCopyInto(out *RateLimit) {
*out = *in
if in.RateSet != nil {
in, out := &in.RateSet, &out.RateSet
*out = make(map[string]*Rate, len(*in))
for key, val := range *in {
var outVal *Rate
if val == nil {
(*out)[key] = nil
} else {
in, out := &val, &outVal
*out = new(Rate)
**out = **in
}
(*out)[key] = outVal
}
if in.SourceCriterion != nil {
in, out := &in.SourceCriterion, &out.SourceCriterion
*out = new(SourceCriterion)
(*in).DeepCopyInto(*out)
}
return
}
@ -996,6 +980,27 @@ func (in *Service) DeepCopy() *Service {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *SourceCriterion) DeepCopyInto(out *SourceCriterion) {
*out = *in
if in.IPStrategy != nil {
in, out := &in.IPStrategy, &out.IPStrategy
*out = new(IPStrategy)
(*in).DeepCopyInto(*out)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SourceCriterion.
func (in *SourceCriterion) DeepCopy() *SourceCriterion {
if in == nil {
return nil
}
out := new(SourceCriterion)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Sticky) DeepCopyInto(out *Sticky) {
*out = *in
@ -1295,6 +1300,11 @@ func (in Users) DeepCopy() Users {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *WRRService) DeepCopyInto(out *WRRService) {
*out = *in
if in.Weight != nil {
in, out := &in.Weight, &out.Weight
*out = new(int)
**out = **in
}
return
}
@ -1314,7 +1324,9 @@ func (in *WeightedRoundRobin) DeepCopyInto(out *WeightedRoundRobin) {
if in.Services != nil {
in, out := &in.Services, &out.Services
*out = make([]WRRService, len(*in))
copy(*out, *in)
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.Sticky != nil {
in, out := &in.Sticky, &out.Sticky

View file

@ -287,9 +287,14 @@
key = "foobar"
insecureSkipVerify = true
[http.middlewares.Middleware16]
[http.middlewares.Middleware16.maxConn]
[http.middlewares.Middleware16.inFlightReq]
amount = 42
extractorFunc = "foobar"
[http.middlewares.Middleware16.inFlightReq.sourceCriterion]
requestHeaderName = "foobar"
requestHost = true
[http.middlewares.Middleware16.inFlightReq.sourceCriterion.ipStrategy]
depth = 42
excludedIPs = ["foobar", "foobar"]
[http.middlewares.Middleware17]
[http.middlewares.Middleware17.buffering]
maxRequestBodyBytes = 42

View file

@ -11,112 +11,113 @@ import (
func TestDecodeConfiguration(t *testing.T) {
labels := map[string]string{
"traefik.http.middlewares.Middleware0.addprefix.prefix": "foobar",
"traefik.http.middlewares.Middleware1.basicauth.headerfield": "foobar",
"traefik.http.middlewares.Middleware1.basicauth.realm": "foobar",
"traefik.http.middlewares.Middleware1.basicauth.removeheader": "true",
"traefik.http.middlewares.Middleware1.basicauth.users": "foobar, fiibar",
"traefik.http.middlewares.Middleware1.basicauth.usersfile": "foobar",
"traefik.http.middlewares.Middleware2.buffering.maxrequestbodybytes": "42",
"traefik.http.middlewares.Middleware2.buffering.maxresponsebodybytes": "42",
"traefik.http.middlewares.Middleware2.buffering.memrequestbodybytes": "42",
"traefik.http.middlewares.Middleware2.buffering.memresponsebodybytes": "42",
"traefik.http.middlewares.Middleware2.buffering.retryexpression": "foobar",
"traefik.http.middlewares.Middleware3.chain.middlewares": "foobar, fiibar",
"traefik.http.middlewares.Middleware4.circuitbreaker.expression": "foobar",
"traefik.http.middlewares.Middleware5.digestauth.headerfield": "foobar",
"traefik.http.middlewares.Middleware5.digestauth.realm": "foobar",
"traefik.http.middlewares.Middleware5.digestauth.removeheader": "true",
"traefik.http.middlewares.Middleware5.digestauth.users": "foobar, fiibar",
"traefik.http.middlewares.Middleware5.digestauth.usersfile": "foobar",
"traefik.http.middlewares.Middleware6.errors.query": "foobar",
"traefik.http.middlewares.Middleware6.errors.service": "foobar",
"traefik.http.middlewares.Middleware6.errors.status": "foobar, fiibar",
"traefik.http.middlewares.Middleware7.forwardauth.address": "foobar",
"traefik.http.middlewares.Middleware7.forwardauth.authresponseheaders": "foobar, fiibar",
"traefik.http.middlewares.Middleware7.forwardauth.tls.ca": "foobar",
"traefik.http.middlewares.Middleware7.forwardauth.tls.caoptional": "true",
"traefik.http.middlewares.Middleware7.forwardauth.tls.cert": "foobar",
"traefik.http.middlewares.Middleware7.forwardauth.tls.insecureskipverify": "true",
"traefik.http.middlewares.Middleware7.forwardauth.tls.key": "foobar",
"traefik.http.middlewares.Middleware7.forwardauth.trustforwardheader": "true",
"traefik.http.middlewares.Middleware8.headers.accesscontrolallowcredentials": "true",
"traefik.http.middlewares.Middleware8.headers.allowedhosts": "foobar, fiibar",
"traefik.http.middlewares.Middleware8.headers.accesscontrolallowheaders": "X-foobar, X-fiibar",
"traefik.http.middlewares.Middleware8.headers.accesscontrolallowmethods": "GET, PUT",
"traefik.http.middlewares.Middleware8.headers.accesscontrolalloworigin": "foobar",
"traefik.http.middlewares.Middleware8.headers.accesscontrolexposeheaders": "X-foobar, X-fiibar",
"traefik.http.middlewares.Middleware8.headers.accesscontrolmaxage": "200",
"traefik.http.middlewares.Middleware8.headers.addvaryheader": "true",
"traefik.http.middlewares.Middleware8.headers.browserxssfilter": "true",
"traefik.http.middlewares.Middleware8.headers.contentsecuritypolicy": "foobar",
"traefik.http.middlewares.Middleware8.headers.contenttypenosniff": "true",
"traefik.http.middlewares.Middleware8.headers.custombrowserxssvalue": "foobar",
"traefik.http.middlewares.Middleware8.headers.customframeoptionsvalue": "foobar",
"traefik.http.middlewares.Middleware8.headers.customrequestheaders.name0": "foobar",
"traefik.http.middlewares.Middleware8.headers.customrequestheaders.name1": "foobar",
"traefik.http.middlewares.Middleware8.headers.customresponseheaders.name0": "foobar",
"traefik.http.middlewares.Middleware8.headers.customresponseheaders.name1": "foobar",
"traefik.http.middlewares.Middleware8.headers.forcestsheader": "true",
"traefik.http.middlewares.Middleware8.headers.framedeny": "true",
"traefik.http.middlewares.Middleware8.headers.hostsproxyheaders": "foobar, fiibar",
"traefik.http.middlewares.Middleware8.headers.isdevelopment": "true",
"traefik.http.middlewares.Middleware8.headers.publickey": "foobar",
"traefik.http.middlewares.Middleware8.headers.referrerpolicy": "foobar",
"traefik.http.middlewares.Middleware8.headers.featurepolicy": "foobar",
"traefik.http.middlewares.Middleware8.headers.sslforcehost": "true",
"traefik.http.middlewares.Middleware8.headers.sslhost": "foobar",
"traefik.http.middlewares.Middleware8.headers.sslproxyheaders.name0": "foobar",
"traefik.http.middlewares.Middleware8.headers.sslproxyheaders.name1": "foobar",
"traefik.http.middlewares.Middleware8.headers.sslredirect": "true",
"traefik.http.middlewares.Middleware8.headers.ssltemporaryredirect": "true",
"traefik.http.middlewares.Middleware8.headers.stsincludesubdomains": "true",
"traefik.http.middlewares.Middleware8.headers.stspreload": "true",
"traefik.http.middlewares.Middleware8.headers.stsseconds": "42",
"traefik.http.middlewares.Middleware9.ipwhitelist.ipstrategy.depth": "42",
"traefik.http.middlewares.Middleware9.ipwhitelist.ipstrategy.excludedips": "foobar, fiibar",
"traefik.http.middlewares.Middleware9.ipwhitelist.sourcerange": "foobar, fiibar",
"traefik.http.middlewares.Middleware10.maxconn.amount": "42",
"traefik.http.middlewares.Middleware10.maxconn.extractorfunc": "foobar",
"traefik.http.middlewares.Middleware11.passtlsclientcert.info.notafter": "true",
"traefik.http.middlewares.Middleware11.passtlsclientcert.info.notbefore": "true",
"traefik.http.middlewares.Middleware11.passtlsclientcert.info.sans": "true",
"traefik.http.middlewares.Middleware11.passtlsclientcert.info.subject.commonname": "true",
"traefik.http.middlewares.Middleware11.passtlsclientcert.info.subject.country": "true",
"traefik.http.middlewares.Middleware11.passtlsclientcert.info.subject.domaincomponent": "true",
"traefik.http.middlewares.Middleware11.passtlsclientcert.info.subject.locality": "true",
"traefik.http.middlewares.Middleware11.passtlsclientcert.info.subject.organization": "true",
"traefik.http.middlewares.Middleware11.passtlsclientcert.info.subject.province": "true",
"traefik.http.middlewares.Middleware11.passtlsclientcert.info.subject.serialnumber": "true",
"traefik.http.middlewares.Middleware11.passtlsclientcert.info.issuer.commonname": "true",
"traefik.http.middlewares.Middleware11.passtlsclientcert.info.issuer.country": "true",
"traefik.http.middlewares.Middleware11.passtlsclientcert.info.issuer.domaincomponent": "true",
"traefik.http.middlewares.Middleware11.passtlsclientcert.info.issuer.locality": "true",
"traefik.http.middlewares.Middleware11.passtlsclientcert.info.issuer.organization": "true",
"traefik.http.middlewares.Middleware11.passtlsclientcert.info.issuer.province": "true",
"traefik.http.middlewares.Middleware11.passtlsclientcert.info.issuer.serialnumber": "true",
"traefik.http.middlewares.Middleware11.passtlsclientcert.pem": "true",
// TODO: disable temporarily (rateLimit)
// "traefik.http.middlewares.Middleware12.ratelimit.extractorfunc": "foobar",
// "traefik.http.middlewares.Middleware12.ratelimit.rateset.Rate0.average": "42",
// "traefik.http.middlewares.Middleware12.ratelimit.rateset.Rate0.burst": "42",
// "traefik.http.middlewares.Middleware12.ratelimit.rateset.Rate0.period": "42",
// "traefik.http.middlewares.Middleware12.ratelimit.rateset.Rate1.average": "42",
// "traefik.http.middlewares.Middleware12.ratelimit.rateset.Rate1.burst": "42",
// "traefik.http.middlewares.Middleware12.ratelimit.rateset.Rate1.period": "42",
"traefik.http.middlewares.Middleware13.redirectregex.permanent": "true",
"traefik.http.middlewares.Middleware13.redirectregex.regex": "foobar",
"traefik.http.middlewares.Middleware13.redirectregex.replacement": "foobar",
"traefik.http.middlewares.Middleware13b.redirectscheme.scheme": "https",
"traefik.http.middlewares.Middleware13b.redirectscheme.port": "80",
"traefik.http.middlewares.Middleware13b.redirectscheme.permanent": "true",
"traefik.http.middlewares.Middleware14.replacepath.path": "foobar",
"traefik.http.middlewares.Middleware15.replacepathregex.regex": "foobar",
"traefik.http.middlewares.Middleware15.replacepathregex.replacement": "foobar",
"traefik.http.middlewares.Middleware16.retry.attempts": "42",
"traefik.http.middlewares.Middleware17.stripprefix.prefixes": "foobar, fiibar",
"traefik.http.middlewares.Middleware18.stripprefixregex.regex": "foobar, fiibar",
"traefik.http.middlewares.Middleware19.compress": "true",
"traefik.http.middlewares.Middleware0.addprefix.prefix": "foobar",
"traefik.http.middlewares.Middleware1.basicauth.headerfield": "foobar",
"traefik.http.middlewares.Middleware1.basicauth.realm": "foobar",
"traefik.http.middlewares.Middleware1.basicauth.removeheader": "true",
"traefik.http.middlewares.Middleware1.basicauth.users": "foobar, fiibar",
"traefik.http.middlewares.Middleware1.basicauth.usersfile": "foobar",
"traefik.http.middlewares.Middleware2.buffering.maxrequestbodybytes": "42",
"traefik.http.middlewares.Middleware2.buffering.maxresponsebodybytes": "42",
"traefik.http.middlewares.Middleware2.buffering.memrequestbodybytes": "42",
"traefik.http.middlewares.Middleware2.buffering.memresponsebodybytes": "42",
"traefik.http.middlewares.Middleware2.buffering.retryexpression": "foobar",
"traefik.http.middlewares.Middleware3.chain.middlewares": "foobar, fiibar",
"traefik.http.middlewares.Middleware4.circuitbreaker.expression": "foobar",
"traefik.http.middlewares.Middleware5.digestauth.headerfield": "foobar",
"traefik.http.middlewares.Middleware5.digestauth.realm": "foobar",
"traefik.http.middlewares.Middleware5.digestauth.removeheader": "true",
"traefik.http.middlewares.Middleware5.digestauth.users": "foobar, fiibar",
"traefik.http.middlewares.Middleware5.digestauth.usersfile": "foobar",
"traefik.http.middlewares.Middleware6.errors.query": "foobar",
"traefik.http.middlewares.Middleware6.errors.service": "foobar",
"traefik.http.middlewares.Middleware6.errors.status": "foobar, fiibar",
"traefik.http.middlewares.Middleware7.forwardauth.address": "foobar",
"traefik.http.middlewares.Middleware7.forwardauth.authresponseheaders": "foobar, fiibar",
"traefik.http.middlewares.Middleware7.forwardauth.tls.ca": "foobar",
"traefik.http.middlewares.Middleware7.forwardauth.tls.caoptional": "true",
"traefik.http.middlewares.Middleware7.forwardauth.tls.cert": "foobar",
"traefik.http.middlewares.Middleware7.forwardauth.tls.insecureskipverify": "true",
"traefik.http.middlewares.Middleware7.forwardauth.tls.key": "foobar",
"traefik.http.middlewares.Middleware7.forwardauth.trustforwardheader": "true",
"traefik.http.middlewares.Middleware8.headers.accesscontrolallowcredentials": "true",
"traefik.http.middlewares.Middleware8.headers.allowedhosts": "foobar, fiibar",
"traefik.http.middlewares.Middleware8.headers.accesscontrolallowheaders": "X-foobar, X-fiibar",
"traefik.http.middlewares.Middleware8.headers.accesscontrolallowmethods": "GET, PUT",
"traefik.http.middlewares.Middleware8.headers.accesscontrolalloworigin": "foobar",
"traefik.http.middlewares.Middleware8.headers.accesscontrolexposeheaders": "X-foobar, X-fiibar",
"traefik.http.middlewares.Middleware8.headers.accesscontrolmaxage": "200",
"traefik.http.middlewares.Middleware8.headers.addvaryheader": "true",
"traefik.http.middlewares.Middleware8.headers.browserxssfilter": "true",
"traefik.http.middlewares.Middleware8.headers.contentsecuritypolicy": "foobar",
"traefik.http.middlewares.Middleware8.headers.contenttypenosniff": "true",
"traefik.http.middlewares.Middleware8.headers.custombrowserxssvalue": "foobar",
"traefik.http.middlewares.Middleware8.headers.customframeoptionsvalue": "foobar",
"traefik.http.middlewares.Middleware8.headers.customrequestheaders.name0": "foobar",
"traefik.http.middlewares.Middleware8.headers.customrequestheaders.name1": "foobar",
"traefik.http.middlewares.Middleware8.headers.customresponseheaders.name0": "foobar",
"traefik.http.middlewares.Middleware8.headers.customresponseheaders.name1": "foobar",
"traefik.http.middlewares.Middleware8.headers.forcestsheader": "true",
"traefik.http.middlewares.Middleware8.headers.framedeny": "true",
"traefik.http.middlewares.Middleware8.headers.hostsproxyheaders": "foobar, fiibar",
"traefik.http.middlewares.Middleware8.headers.isdevelopment": "true",
"traefik.http.middlewares.Middleware8.headers.publickey": "foobar",
"traefik.http.middlewares.Middleware8.headers.referrerpolicy": "foobar",
"traefik.http.middlewares.Middleware8.headers.featurepolicy": "foobar",
"traefik.http.middlewares.Middleware8.headers.sslforcehost": "true",
"traefik.http.middlewares.Middleware8.headers.sslhost": "foobar",
"traefik.http.middlewares.Middleware8.headers.sslproxyheaders.name0": "foobar",
"traefik.http.middlewares.Middleware8.headers.sslproxyheaders.name1": "foobar",
"traefik.http.middlewares.Middleware8.headers.sslredirect": "true",
"traefik.http.middlewares.Middleware8.headers.ssltemporaryredirect": "true",
"traefik.http.middlewares.Middleware8.headers.stsincludesubdomains": "true",
"traefik.http.middlewares.Middleware8.headers.stspreload": "true",
"traefik.http.middlewares.Middleware8.headers.stsseconds": "42",
"traefik.http.middlewares.Middleware9.ipwhitelist.ipstrategy.depth": "42",
"traefik.http.middlewares.Middleware9.ipwhitelist.ipstrategy.excludedips": "foobar, fiibar",
"traefik.http.middlewares.Middleware9.ipwhitelist.sourcerange": "foobar, fiibar",
"traefik.http.middlewares.Middleware10.inflightreq.amount": "42",
"traefik.http.middlewares.Middleware10.inflightreq.sourcecriterion.ipstrategy.depth": "42",
"traefik.http.middlewares.Middleware10.inflightreq.sourcecriterion.ipstrategy.excludedips": "foobar, fiibar",
"traefik.http.middlewares.Middleware10.inflightreq.sourcecriterion.requestheadername": "foobar",
"traefik.http.middlewares.Middleware10.inflightreq.sourcecriterion.requesthost": "true",
"traefik.http.middlewares.Middleware11.passtlsclientcert.info.notafter": "true",
"traefik.http.middlewares.Middleware11.passtlsclientcert.info.notbefore": "true",
"traefik.http.middlewares.Middleware11.passtlsclientcert.info.sans": "true",
"traefik.http.middlewares.Middleware11.passtlsclientcert.info.subject.commonname": "true",
"traefik.http.middlewares.Middleware11.passtlsclientcert.info.subject.country": "true",
"traefik.http.middlewares.Middleware11.passtlsclientcert.info.subject.domaincomponent": "true",
"traefik.http.middlewares.Middleware11.passtlsclientcert.info.subject.locality": "true",
"traefik.http.middlewares.Middleware11.passtlsclientcert.info.subject.organization": "true",
"traefik.http.middlewares.Middleware11.passtlsclientcert.info.subject.province": "true",
"traefik.http.middlewares.Middleware11.passtlsclientcert.info.subject.serialnumber": "true",
"traefik.http.middlewares.Middleware11.passtlsclientcert.info.issuer.commonname": "true",
"traefik.http.middlewares.Middleware11.passtlsclientcert.info.issuer.country": "true",
"traefik.http.middlewares.Middleware11.passtlsclientcert.info.issuer.domaincomponent": "true",
"traefik.http.middlewares.Middleware11.passtlsclientcert.info.issuer.locality": "true",
"traefik.http.middlewares.Middleware11.passtlsclientcert.info.issuer.organization": "true",
"traefik.http.middlewares.Middleware11.passtlsclientcert.info.issuer.province": "true",
"traefik.http.middlewares.Middleware11.passtlsclientcert.info.issuer.serialnumber": "true",
"traefik.http.middlewares.Middleware11.passtlsclientcert.pem": "true",
"traefik.http.middlewares.Middleware12.ratelimit.average": "42",
"traefik.http.middlewares.Middleware12.ratelimit.burst": "42",
"traefik.http.middlewares.Middleware12.ratelimit.sourcecriterion.requestheadername": "foobar",
"traefik.http.middlewares.Middleware12.ratelimit.sourcecriterion.requesthost": "true",
"traefik.http.middlewares.Middleware12.ratelimit.sourcecriterion.ipstrategy.depth": "42",
"traefik.http.middlewares.Middleware12.ratelimit.sourcecriterion.ipstrategy.excludedips": "foobar, foobar",
"traefik.http.middlewares.Middleware13.redirectregex.permanent": "true",
"traefik.http.middlewares.Middleware13.redirectregex.regex": "foobar",
"traefik.http.middlewares.Middleware13.redirectregex.replacement": "foobar",
"traefik.http.middlewares.Middleware13b.redirectscheme.scheme": "https",
"traefik.http.middlewares.Middleware13b.redirectscheme.port": "80",
"traefik.http.middlewares.Middleware13b.redirectscheme.permanent": "true",
"traefik.http.middlewares.Middleware14.replacepath.path": "foobar",
"traefik.http.middlewares.Middleware15.replacepathregex.regex": "foobar",
"traefik.http.middlewares.Middleware15.replacepathregex.replacement": "foobar",
"traefik.http.middlewares.Middleware16.retry.attempts": "42",
"traefik.http.middlewares.Middleware17.stripprefix.prefixes": "foobar, fiibar",
"traefik.http.middlewares.Middleware18.stripprefixregex.regex": "foobar, fiibar",
"traefik.http.middlewares.Middleware19.compress": "true",
"traefik.http.routers.Router0.entrypoints": "foobar, fiibar",
"traefik.http.routers.Router0.middlewares": "foobar, fiibar",
@ -273,9 +274,16 @@ func TestDecodeConfiguration(t *testing.T) {
},
},
"Middleware10": {
MaxConn: &dynamic.MaxConn{
Amount: 42,
ExtractorFunc: "foobar",
InFlightReq: &dynamic.InFlightReq{
Amount: 42,
SourceCriterion: &dynamic.SourceCriterion{
IPStrategy: &dynamic.IPStrategy{
Depth: 42,
ExcludedIPs: []string{"foobar", "fiibar"},
},
RequestHeaderName: "foobar",
RequestHost: true,
},
},
},
"Middleware11": {
@ -306,24 +314,20 @@ func TestDecodeConfiguration(t *testing.T) {
},
},
},
// TODO: disable temporarily (rateLimit)
// "Middleware12": {
// RateLimit: &dynamic.RateLimit{
// RateSet: map[string]*dynamic.Rate{
// "Rate0": {
// Period: types.Duration(42 * time.Second),
// Average: 42,
// Burst: 42,
// },
// "Rate1": {
// Period: types.Duration(42 * time.Second),
// Average: 42,
// Burst: 42,
// },
// },
// ExtractorFunc: "foobar",
// },
// },
"Middleware12": {
RateLimit: &dynamic.RateLimit{
Average: 42,
Burst: 42,
SourceCriterion: &dynamic.SourceCriterion{
IPStrategy: &dynamic.IPStrategy{
Depth: 42,
ExcludedIPs: []string{"foobar", "foobar"},
},
RequestHeaderName: "foobar",
RequestHost: true,
},
},
},
"Middleware13": {
RedirectRegex: &dynamic.RedirectRegex{
Regex: "foobar",
@ -674,9 +678,16 @@ func TestEncodeConfiguration(t *testing.T) {
},
},
"Middleware10": {
MaxConn: &dynamic.MaxConn{
Amount: 42,
ExtractorFunc: "foobar",
InFlightReq: &dynamic.InFlightReq{
Amount: 42,
SourceCriterion: &dynamic.SourceCriterion{
IPStrategy: &dynamic.IPStrategy{
Depth: 42,
ExcludedIPs: []string{"foobar", "fiibar"},
},
RequestHeaderName: "foobar",
RequestHost: true,
},
},
},
"Middleware11": {
@ -706,24 +717,20 @@ func TestEncodeConfiguration(t *testing.T) {
},
},
},
// TODO: disable temporarily (rateLimit)
// "Middleware12": {
// RateLimit: &dynamic.RateLimit{
// RateSet: map[string]*dynamic.Rate{
// "Rate0": {
// Period: types.Duration(42 * time.Nanosecond),
// Average: 42,
// Burst: 42,
// },
// "Rate1": {
// Period: types.Duration(42 * time.Nanosecond),
// Average: 42,
// Burst: 42,
// },
// },
// ExtractorFunc: "foobar",
// },
// },
"Middleware12": {
RateLimit: &dynamic.RateLimit{
Average: 42,
Burst: 42,
SourceCriterion: &dynamic.SourceCriterion{
IPStrategy: &dynamic.IPStrategy{
Depth: 42,
ExcludedIPs: []string{"foobar", "foobar"},
},
RequestHeaderName: "foobar",
RequestHost: true,
},
},
},
"Middleware13": {
RedirectRegex: &dynamic.RedirectRegex{
Regex: "foobar",
@ -975,112 +982,113 @@ func TestEncodeConfiguration(t *testing.T) {
require.NoError(t, err)
expected := map[string]string{
"traefik.HTTP.Middlewares.Middleware0.AddPrefix.Prefix": "foobar",
"traefik.HTTP.Middlewares.Middleware1.BasicAuth.HeaderField": "foobar",
"traefik.HTTP.Middlewares.Middleware1.BasicAuth.Realm": "foobar",
"traefik.HTTP.Middlewares.Middleware1.BasicAuth.RemoveHeader": "true",
"traefik.HTTP.Middlewares.Middleware1.BasicAuth.Users": "foobar, fiibar",
"traefik.HTTP.Middlewares.Middleware1.BasicAuth.UsersFile": "foobar",
"traefik.HTTP.Middlewares.Middleware2.Buffering.MaxRequestBodyBytes": "42",
"traefik.HTTP.Middlewares.Middleware2.Buffering.MaxResponseBodyBytes": "42",
"traefik.HTTP.Middlewares.Middleware2.Buffering.MemRequestBodyBytes": "42",
"traefik.HTTP.Middlewares.Middleware2.Buffering.MemResponseBodyBytes": "42",
"traefik.HTTP.Middlewares.Middleware2.Buffering.RetryExpression": "foobar",
"traefik.HTTP.Middlewares.Middleware3.Chain.Middlewares": "foobar, fiibar",
"traefik.HTTP.Middlewares.Middleware4.CircuitBreaker.Expression": "foobar",
"traefik.HTTP.Middlewares.Middleware5.DigestAuth.HeaderField": "foobar",
"traefik.HTTP.Middlewares.Middleware5.DigestAuth.Realm": "foobar",
"traefik.HTTP.Middlewares.Middleware5.DigestAuth.RemoveHeader": "true",
"traefik.HTTP.Middlewares.Middleware5.DigestAuth.Users": "foobar, fiibar",
"traefik.HTTP.Middlewares.Middleware5.DigestAuth.UsersFile": "foobar",
"traefik.HTTP.Middlewares.Middleware6.Errors.Query": "foobar",
"traefik.HTTP.Middlewares.Middleware6.Errors.Service": "foobar",
"traefik.HTTP.Middlewares.Middleware6.Errors.Status": "foobar, fiibar",
"traefik.HTTP.Middlewares.Middleware7.ForwardAuth.Address": "foobar",
"traefik.HTTP.Middlewares.Middleware7.ForwardAuth.AuthResponseHeaders": "foobar, fiibar",
"traefik.HTTP.Middlewares.Middleware7.ForwardAuth.TLS.CA": "foobar",
"traefik.HTTP.Middlewares.Middleware7.ForwardAuth.TLS.CAOptional": "true",
"traefik.HTTP.Middlewares.Middleware7.ForwardAuth.TLS.Cert": "foobar",
"traefik.HTTP.Middlewares.Middleware7.ForwardAuth.TLS.InsecureSkipVerify": "true",
"traefik.HTTP.Middlewares.Middleware7.ForwardAuth.TLS.Key": "foobar",
"traefik.HTTP.Middlewares.Middleware7.ForwardAuth.TrustForwardHeader": "true",
"traefik.HTTP.Middlewares.Middleware8.Headers.AccessControlAllowCredentials": "true",
"traefik.HTTP.Middlewares.Middleware8.Headers.AccessControlAllowHeaders": "X-foobar, X-fiibar",
"traefik.HTTP.Middlewares.Middleware8.Headers.AccessControlAllowMethods": "GET, PUT",
"traefik.HTTP.Middlewares.Middleware8.Headers.AccessControlAllowOrigin": "foobar",
"traefik.HTTP.Middlewares.Middleware8.Headers.AccessControlExposeHeaders": "X-foobar, X-fiibar",
"traefik.HTTP.Middlewares.Middleware8.Headers.AccessControlMaxAge": "200",
"traefik.HTTP.Middlewares.Middleware8.Headers.AddVaryHeader": "true",
"traefik.HTTP.Middlewares.Middleware8.Headers.AllowedHosts": "foobar, fiibar",
"traefik.HTTP.Middlewares.Middleware8.Headers.BrowserXSSFilter": "true",
"traefik.HTTP.Middlewares.Middleware8.Headers.ContentSecurityPolicy": "foobar",
"traefik.HTTP.Middlewares.Middleware8.Headers.ContentTypeNosniff": "true",
"traefik.HTTP.Middlewares.Middleware8.Headers.CustomBrowserXSSValue": "foobar",
"traefik.HTTP.Middlewares.Middleware8.Headers.CustomFrameOptionsValue": "foobar",
"traefik.HTTP.Middlewares.Middleware8.Headers.CustomRequestHeaders.name0": "foobar",
"traefik.HTTP.Middlewares.Middleware8.Headers.CustomRequestHeaders.name1": "foobar",
"traefik.HTTP.Middlewares.Middleware8.Headers.CustomResponseHeaders.name0": "foobar",
"traefik.HTTP.Middlewares.Middleware8.Headers.CustomResponseHeaders.name1": "foobar",
"traefik.HTTP.Middlewares.Middleware8.Headers.ForceSTSHeader": "true",
"traefik.HTTP.Middlewares.Middleware8.Headers.FrameDeny": "true",
"traefik.HTTP.Middlewares.Middleware8.Headers.HostsProxyHeaders": "foobar, fiibar",
"traefik.HTTP.Middlewares.Middleware8.Headers.IsDevelopment": "true",
"traefik.HTTP.Middlewares.Middleware8.Headers.PublicKey": "foobar",
"traefik.HTTP.Middlewares.Middleware8.Headers.ReferrerPolicy": "foobar",
"traefik.HTTP.Middlewares.Middleware8.Headers.FeaturePolicy": "foobar",
"traefik.HTTP.Middlewares.Middleware8.Headers.SSLForceHost": "true",
"traefik.HTTP.Middlewares.Middleware8.Headers.SSLHost": "foobar",
"traefik.HTTP.Middlewares.Middleware8.Headers.SSLProxyHeaders.name0": "foobar",
"traefik.HTTP.Middlewares.Middleware8.Headers.SSLProxyHeaders.name1": "foobar",
"traefik.HTTP.Middlewares.Middleware8.Headers.SSLRedirect": "true",
"traefik.HTTP.Middlewares.Middleware8.Headers.SSLTemporaryRedirect": "true",
"traefik.HTTP.Middlewares.Middleware8.Headers.STSIncludeSubdomains": "true",
"traefik.HTTP.Middlewares.Middleware8.Headers.STSPreload": "true",
"traefik.HTTP.Middlewares.Middleware8.Headers.STSSeconds": "42",
"traefik.HTTP.Middlewares.Middleware9.IPWhiteList.IPStrategy.Depth": "42",
"traefik.HTTP.Middlewares.Middleware9.IPWhiteList.IPStrategy.ExcludedIPs": "foobar, fiibar",
"traefik.HTTP.Middlewares.Middleware9.IPWhiteList.SourceRange": "foobar, fiibar",
"traefik.HTTP.Middlewares.Middleware10.MaxConn.Amount": "42",
"traefik.HTTP.Middlewares.Middleware10.MaxConn.ExtractorFunc": "foobar",
"traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.NotAfter": "true",
"traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.NotBefore": "true",
"traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.Sans": "true",
"traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.Subject.Country": "true",
"traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.Subject.Province": "true",
"traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.Subject.Locality": "true",
"traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.Subject.Organization": "true",
"traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.Subject.CommonName": "true",
"traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.Subject.SerialNumber": "true",
"traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.Subject.DomainComponent": "true",
"traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.Issuer.Country": "true",
"traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.Issuer.Province": "true",
"traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.Issuer.Locality": "true",
"traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.Issuer.Organization": "true",
"traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.Issuer.CommonName": "true",
"traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.Issuer.SerialNumber": "true",
"traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.Issuer.DomainComponent": "true",
"traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.PEM": "true",
// TODO: disable temporarily (rateLimit)
// "traefik.HTTP.Middlewares.Middleware12.RateLimit.ExtractorFunc": "foobar",
// "traefik.HTTP.Middlewares.Middleware12.RateLimit.RateSet.Rate0.Average": "42",
// "traefik.HTTP.Middlewares.Middleware12.RateLimit.RateSet.Rate0.Burst": "42",
// "traefik.HTTP.Middlewares.Middleware12.RateLimit.RateSet.Rate0.Period": "42",
// "traefik.HTTP.Middlewares.Middleware12.RateLimit.RateSet.Rate1.Average": "42",
// "traefik.HTTP.Middlewares.Middleware12.RateLimit.RateSet.Rate1.Burst": "42",
// "traefik.HTTP.Middlewares.Middleware12.RateLimit.RateSet.Rate1.Period": "42",
"traefik.HTTP.Middlewares.Middleware13.RedirectRegex.Regex": "foobar",
"traefik.HTTP.Middlewares.Middleware13.RedirectRegex.Replacement": "foobar",
"traefik.HTTP.Middlewares.Middleware13.RedirectRegex.Permanent": "true",
"traefik.HTTP.Middlewares.Middleware13b.RedirectScheme.Scheme": "https",
"traefik.HTTP.Middlewares.Middleware13b.RedirectScheme.Port": "80",
"traefik.HTTP.Middlewares.Middleware13b.RedirectScheme.Permanent": "true",
"traefik.HTTP.Middlewares.Middleware14.ReplacePath.Path": "foobar",
"traefik.HTTP.Middlewares.Middleware15.ReplacePathRegex.Regex": "foobar",
"traefik.HTTP.Middlewares.Middleware15.ReplacePathRegex.Replacement": "foobar",
"traefik.HTTP.Middlewares.Middleware16.Retry.Attempts": "42",
"traefik.HTTP.Middlewares.Middleware17.StripPrefix.Prefixes": "foobar, fiibar",
"traefik.HTTP.Middlewares.Middleware18.StripPrefixRegex.Regex": "foobar, fiibar",
"traefik.HTTP.Middlewares.Middleware19.Compress": "true",
"traefik.HTTP.Middlewares.Middleware0.AddPrefix.Prefix": "foobar",
"traefik.HTTP.Middlewares.Middleware1.BasicAuth.HeaderField": "foobar",
"traefik.HTTP.Middlewares.Middleware1.BasicAuth.Realm": "foobar",
"traefik.HTTP.Middlewares.Middleware1.BasicAuth.RemoveHeader": "true",
"traefik.HTTP.Middlewares.Middleware1.BasicAuth.Users": "foobar, fiibar",
"traefik.HTTP.Middlewares.Middleware1.BasicAuth.UsersFile": "foobar",
"traefik.HTTP.Middlewares.Middleware2.Buffering.MaxRequestBodyBytes": "42",
"traefik.HTTP.Middlewares.Middleware2.Buffering.MaxResponseBodyBytes": "42",
"traefik.HTTP.Middlewares.Middleware2.Buffering.MemRequestBodyBytes": "42",
"traefik.HTTP.Middlewares.Middleware2.Buffering.MemResponseBodyBytes": "42",
"traefik.HTTP.Middlewares.Middleware2.Buffering.RetryExpression": "foobar",
"traefik.HTTP.Middlewares.Middleware3.Chain.Middlewares": "foobar, fiibar",
"traefik.HTTP.Middlewares.Middleware4.CircuitBreaker.Expression": "foobar",
"traefik.HTTP.Middlewares.Middleware5.DigestAuth.HeaderField": "foobar",
"traefik.HTTP.Middlewares.Middleware5.DigestAuth.Realm": "foobar",
"traefik.HTTP.Middlewares.Middleware5.DigestAuth.RemoveHeader": "true",
"traefik.HTTP.Middlewares.Middleware5.DigestAuth.Users": "foobar, fiibar",
"traefik.HTTP.Middlewares.Middleware5.DigestAuth.UsersFile": "foobar",
"traefik.HTTP.Middlewares.Middleware6.Errors.Query": "foobar",
"traefik.HTTP.Middlewares.Middleware6.Errors.Service": "foobar",
"traefik.HTTP.Middlewares.Middleware6.Errors.Status": "foobar, fiibar",
"traefik.HTTP.Middlewares.Middleware7.ForwardAuth.Address": "foobar",
"traefik.HTTP.Middlewares.Middleware7.ForwardAuth.AuthResponseHeaders": "foobar, fiibar",
"traefik.HTTP.Middlewares.Middleware7.ForwardAuth.TLS.CA": "foobar",
"traefik.HTTP.Middlewares.Middleware7.ForwardAuth.TLS.CAOptional": "true",
"traefik.HTTP.Middlewares.Middleware7.ForwardAuth.TLS.Cert": "foobar",
"traefik.HTTP.Middlewares.Middleware7.ForwardAuth.TLS.InsecureSkipVerify": "true",
"traefik.HTTP.Middlewares.Middleware7.ForwardAuth.TLS.Key": "foobar",
"traefik.HTTP.Middlewares.Middleware7.ForwardAuth.TrustForwardHeader": "true",
"traefik.HTTP.Middlewares.Middleware8.Headers.AccessControlAllowCredentials": "true",
"traefik.HTTP.Middlewares.Middleware8.Headers.AccessControlAllowHeaders": "X-foobar, X-fiibar",
"traefik.HTTP.Middlewares.Middleware8.Headers.AccessControlAllowMethods": "GET, PUT",
"traefik.HTTP.Middlewares.Middleware8.Headers.AccessControlAllowOrigin": "foobar",
"traefik.HTTP.Middlewares.Middleware8.Headers.AccessControlExposeHeaders": "X-foobar, X-fiibar",
"traefik.HTTP.Middlewares.Middleware8.Headers.AccessControlMaxAge": "200",
"traefik.HTTP.Middlewares.Middleware8.Headers.AddVaryHeader": "true",
"traefik.HTTP.Middlewares.Middleware8.Headers.AllowedHosts": "foobar, fiibar",
"traefik.HTTP.Middlewares.Middleware8.Headers.BrowserXSSFilter": "true",
"traefik.HTTP.Middlewares.Middleware8.Headers.ContentSecurityPolicy": "foobar",
"traefik.HTTP.Middlewares.Middleware8.Headers.ContentTypeNosniff": "true",
"traefik.HTTP.Middlewares.Middleware8.Headers.CustomBrowserXSSValue": "foobar",
"traefik.HTTP.Middlewares.Middleware8.Headers.CustomFrameOptionsValue": "foobar",
"traefik.HTTP.Middlewares.Middleware8.Headers.CustomRequestHeaders.name0": "foobar",
"traefik.HTTP.Middlewares.Middleware8.Headers.CustomRequestHeaders.name1": "foobar",
"traefik.HTTP.Middlewares.Middleware8.Headers.CustomResponseHeaders.name0": "foobar",
"traefik.HTTP.Middlewares.Middleware8.Headers.CustomResponseHeaders.name1": "foobar",
"traefik.HTTP.Middlewares.Middleware8.Headers.ForceSTSHeader": "true",
"traefik.HTTP.Middlewares.Middleware8.Headers.FrameDeny": "true",
"traefik.HTTP.Middlewares.Middleware8.Headers.HostsProxyHeaders": "foobar, fiibar",
"traefik.HTTP.Middlewares.Middleware8.Headers.IsDevelopment": "true",
"traefik.HTTP.Middlewares.Middleware8.Headers.PublicKey": "foobar",
"traefik.HTTP.Middlewares.Middleware8.Headers.ReferrerPolicy": "foobar",
"traefik.HTTP.Middlewares.Middleware8.Headers.FeaturePolicy": "foobar",
"traefik.HTTP.Middlewares.Middleware8.Headers.SSLForceHost": "true",
"traefik.HTTP.Middlewares.Middleware8.Headers.SSLHost": "foobar",
"traefik.HTTP.Middlewares.Middleware8.Headers.SSLProxyHeaders.name0": "foobar",
"traefik.HTTP.Middlewares.Middleware8.Headers.SSLProxyHeaders.name1": "foobar",
"traefik.HTTP.Middlewares.Middleware8.Headers.SSLRedirect": "true",
"traefik.HTTP.Middlewares.Middleware8.Headers.SSLTemporaryRedirect": "true",
"traefik.HTTP.Middlewares.Middleware8.Headers.STSIncludeSubdomains": "true",
"traefik.HTTP.Middlewares.Middleware8.Headers.STSPreload": "true",
"traefik.HTTP.Middlewares.Middleware8.Headers.STSSeconds": "42",
"traefik.HTTP.Middlewares.Middleware9.IPWhiteList.IPStrategy.Depth": "42",
"traefik.HTTP.Middlewares.Middleware9.IPWhiteList.IPStrategy.ExcludedIPs": "foobar, fiibar",
"traefik.HTTP.Middlewares.Middleware9.IPWhiteList.SourceRange": "foobar, fiibar",
"traefik.HTTP.Middlewares.Middleware10.InFlightReq.Amount": "42",
"traefik.HTTP.Middlewares.Middleware10.InFlightReq.SourceCriterion.IPStrategy.Depth": "42",
"traefik.HTTP.Middlewares.Middleware10.InFlightReq.SourceCriterion.IPStrategy.ExcludedIPs": "foobar, fiibar",
"traefik.HTTP.Middlewares.Middleware10.InFlightReq.SourceCriterion.RequestHeaderName": "foobar",
"traefik.HTTP.Middlewares.Middleware10.InFlightReq.SourceCriterion.RequestHost": "true",
"traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.NotAfter": "true",
"traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.NotBefore": "true",
"traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.Sans": "true",
"traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.Subject.Country": "true",
"traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.Subject.Province": "true",
"traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.Subject.Locality": "true",
"traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.Subject.Organization": "true",
"traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.Subject.CommonName": "true",
"traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.Subject.SerialNumber": "true",
"traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.Subject.DomainComponent": "true",
"traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.Issuer.Country": "true",
"traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.Issuer.Province": "true",
"traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.Issuer.Locality": "true",
"traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.Issuer.Organization": "true",
"traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.Issuer.CommonName": "true",
"traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.Issuer.SerialNumber": "true",
"traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.Info.Issuer.DomainComponent": "true",
"traefik.HTTP.Middlewares.Middleware11.PassTLSClientCert.PEM": "true",
"traefik.HTTP.Middlewares.Middleware12.RateLimit.Average": "42",
"traefik.HTTP.Middlewares.Middleware12.RateLimit.Burst": "42",
"traefik.HTTP.Middlewares.Middleware12.RateLimit.SourceCriterion.RequestHeaderName": "foobar",
"traefik.HTTP.Middlewares.Middleware12.RateLimit.SourceCriterion.RequestHost": "true",
"traefik.HTTP.Middlewares.Middleware12.RateLimit.SourceCriterion.IPStrategy.Depth": "42",
"traefik.HTTP.Middlewares.Middleware12.RateLimit.SourceCriterion.IPStrategy.ExcludedIPs": "foobar, foobar",
"traefik.HTTP.Middlewares.Middleware13.RedirectRegex.Regex": "foobar",
"traefik.HTTP.Middlewares.Middleware13.RedirectRegex.Replacement": "foobar",
"traefik.HTTP.Middlewares.Middleware13.RedirectRegex.Permanent": "true",
"traefik.HTTP.Middlewares.Middleware13b.RedirectScheme.Scheme": "https",
"traefik.HTTP.Middlewares.Middleware13b.RedirectScheme.Port": "80",
"traefik.HTTP.Middlewares.Middleware13b.RedirectScheme.Permanent": "true",
"traefik.HTTP.Middlewares.Middleware14.ReplacePath.Path": "foobar",
"traefik.HTTP.Middlewares.Middleware15.ReplacePathRegex.Regex": "foobar",
"traefik.HTTP.Middlewares.Middleware15.ReplacePathRegex.Replacement": "foobar",
"traefik.HTTP.Middlewares.Middleware16.Retry.Attempts": "42",
"traefik.HTTP.Middlewares.Middleware17.StripPrefix.Prefixes": "foobar, fiibar",
"traefik.HTTP.Middlewares.Middleware18.StripPrefixRegex.Regex": "foobar, fiibar",
"traefik.HTTP.Middlewares.Middleware19.Compress": "true",
"traefik.HTTP.Routers.Router0.EntryPoints": "foobar, fiibar",
"traefik.HTTP.Routers.Router0.Middlewares": "foobar, fiibar",