diff --git a/.golangci.toml b/.golangci.toml index 30fb95f58..70bc7866d 100644 --- a/.golangci.toml +++ b/.golangci.toml @@ -93,6 +93,9 @@ [[issues.exclude-rules]] path = "cmd/configuration.go" text = "string `traefik` has (\\d) occurrences, make it a constant" + [[issues.exclude-rules]] + path = "pkg/server/middleware/middlewares.go" + text = "Function 'buildConstructor' is too long \\(\\d+ > 230\\)" [[issues.exclude-rules]] # FIXME must be fixed path = "cmd/context.go" text = "S1000: should use a simple channel send/receive instead of `select` with a single case" diff --git a/docs/content/middlewares/contenttype.md b/docs/content/middlewares/contenttype.md new file mode 100644 index 000000000..b92c272be --- /dev/null +++ b/docs/content/middlewares/contenttype.md @@ -0,0 +1,83 @@ + +# ContentType + +Handling ContentType auto-detection +{: .subtitle } + +The Content-Type middleware - or rather its unique `autoDetect` option - +specifies whether to let the `Content-Type` header, +if it has not been set by the backend, +be automatically set to a value derived from the contents of the response. + +As a proxy, the default behavior should be to leave the header alone, +regardless of what the backend did with it. +However, the historic default was to always auto-detect and set the header if it was nil, +and it is going to be kept that way in order to support users currently relying on it. +This middleware exists to enable the correct behavior until at least the default one can be changed in a future version. + +!!! info + + As explained above, for compatibility reasons the default behavior on a router (without this middleware), + is still to automatically set the `Content-Type` header. + Therefore, given the default value of the `autoDetect` option (false), + simply enabling this middleware for a router switches the router's behavior. + +## Configuration Examples + +```yaml tab="Docker" +# Disable auto-detection +labels: + - "traefik.http.middlewares.autodetect.contenttype.autodetect=false" +``` + +```yaml tab="Kubernetes" +# Disable auto-detection +apiVersion: traefik.containo.us/v1alpha1 +kind: Middleware +metadata: + name: autodetect +spec: + contentType: + autoDetect: false +``` + +```yaml tab="Consul Catalog" +# Disable auto-detection +- "traefik.http.middlewares.autodetect.contenttype.autodetect=false" +``` + +```json tab="Marathon" +"labels": { + "traefik.http.middlewares.autodetect.contenttype.autodetect": "false" +} +``` + +```yaml tab="Rancher" +# Disable auto-detection +labels: + - "traefik.http.middlewares.autodetect.contenttype.autodetect=false" +``` + +```toml tab="File (TOML)" +# Disable auto-detection +[http.middlewares] + [http.middlewares.autodetect.contentType] + autoDetect=false +``` + +```yaml tab="File (YAML)" +# Disable auto-detection +http: + middlewares: + autodetect: + contentType: + autoDetect: false +``` + +## Configuration Options + +### `autoDetect` + +`autoDetect` specifies whether to let the `Content-Type` header, +if it has not been set by the backend, +be automatically set to a value derived from the contents of the response. diff --git a/docs/content/reference/dynamic-configuration/docker-labels.yml b/docs/content/reference/dynamic-configuration/docker-labels.yml index 19ce7cef5..8e2097ce0 100644 --- a/docs/content/reference/dynamic-configuration/docker-labels.yml +++ b/docs/content/reference/dynamic-configuration/docker-labels.yml @@ -12,100 +12,102 @@ - "traefik.http.middlewares.middleware03.chain.middlewares=foobar, foobar" - "traefik.http.middlewares.middleware04.circuitbreaker.expression=foobar" - "traefik.http.middlewares.middleware05.compress=true" -- "traefik.http.middlewares.middleware06.digestauth.headerfield=foobar" -- "traefik.http.middlewares.middleware06.digestauth.realm=foobar" -- "traefik.http.middlewares.middleware06.digestauth.removeheader=true" -- "traefik.http.middlewares.middleware06.digestauth.users=foobar, foobar" -- "traefik.http.middlewares.middleware06.digestauth.usersfile=foobar" -- "traefik.http.middlewares.middleware07.errors.query=foobar" -- "traefik.http.middlewares.middleware07.errors.service=foobar" -- "traefik.http.middlewares.middleware07.errors.status=foobar, foobar" -- "traefik.http.middlewares.middleware08.forwardauth.address=foobar" -- "traefik.http.middlewares.middleware08.forwardauth.authresponseheaders=foobar, foobar" -- "traefik.http.middlewares.middleware08.forwardauth.tls.ca=foobar" -- "traefik.http.middlewares.middleware08.forwardauth.tls.caoptional=true" -- "traefik.http.middlewares.middleware08.forwardauth.tls.cert=foobar" -- "traefik.http.middlewares.middleware08.forwardauth.tls.insecureskipverify=true" -- "traefik.http.middlewares.middleware08.forwardauth.tls.key=foobar" -- "traefik.http.middlewares.middleware08.forwardauth.trustforwardheader=true" -- "traefik.http.middlewares.middleware09.headers.accesscontrolallowcredentials=true" -- "traefik.http.middlewares.middleware09.headers.accesscontrolallowheaders=foobar, foobar" -- "traefik.http.middlewares.middleware09.headers.accesscontrolallowmethods=foobar, foobar" -- "traefik.http.middlewares.middleware09.headers.accesscontrolalloworigin=foobar" -- "traefik.http.middlewares.middleware09.headers.accesscontrolexposeheaders=foobar, foobar" -- "traefik.http.middlewares.middleware09.headers.accesscontrolmaxage=42" -- "traefik.http.middlewares.middleware09.headers.addvaryheader=true" -- "traefik.http.middlewares.middleware09.headers.allowedhosts=foobar, foobar" -- "traefik.http.middlewares.middleware09.headers.browserxssfilter=true" -- "traefik.http.middlewares.middleware09.headers.contentsecuritypolicy=foobar" -- "traefik.http.middlewares.middleware09.headers.contenttypenosniff=true" -- "traefik.http.middlewares.middleware09.headers.custombrowserxssvalue=foobar" -- "traefik.http.middlewares.middleware09.headers.customframeoptionsvalue=foobar" -- "traefik.http.middlewares.middleware09.headers.customrequestheaders.name0=foobar" -- "traefik.http.middlewares.middleware09.headers.customrequestheaders.name1=foobar" -- "traefik.http.middlewares.middleware09.headers.customresponseheaders.name0=foobar" -- "traefik.http.middlewares.middleware09.headers.customresponseheaders.name1=foobar" -- "traefik.http.middlewares.middleware09.headers.featurepolicy=foobar" -- "traefik.http.middlewares.middleware09.headers.forcestsheader=true" -- "traefik.http.middlewares.middleware09.headers.framedeny=true" -- "traefik.http.middlewares.middleware09.headers.hostsproxyheaders=foobar, foobar" -- "traefik.http.middlewares.middleware09.headers.isdevelopment=true" -- "traefik.http.middlewares.middleware09.headers.publickey=foobar" -- "traefik.http.middlewares.middleware09.headers.referrerpolicy=foobar" -- "traefik.http.middlewares.middleware09.headers.sslforcehost=true" -- "traefik.http.middlewares.middleware09.headers.sslhost=foobar" -- "traefik.http.middlewares.middleware09.headers.sslproxyheaders.name0=foobar" -- "traefik.http.middlewares.middleware09.headers.sslproxyheaders.name1=foobar" -- "traefik.http.middlewares.middleware09.headers.sslredirect=true" -- "traefik.http.middlewares.middleware09.headers.ssltemporaryredirect=true" -- "traefik.http.middlewares.middleware09.headers.stsincludesubdomains=true" -- "traefik.http.middlewares.middleware09.headers.stspreload=true" -- "traefik.http.middlewares.middleware09.headers.stsseconds=42" -- "traefik.http.middlewares.middleware10.ipwhitelist.ipstrategy.depth=42" -- "traefik.http.middlewares.middleware10.ipwhitelist.ipstrategy.excludedips=foobar, foobar" -- "traefik.http.middlewares.middleware10.ipwhitelist.sourcerange=foobar, foobar" -- "traefik.http.middlewares.middleware11.inflightreq.amount=42" -- "traefik.http.middlewares.middleware11.inflightreq.sourcecriterion.ipstrategy.depth=42" -- "traefik.http.middlewares.middleware11.inflightreq.sourcecriterion.ipstrategy.excludedips=foobar, foobar" -- "traefik.http.middlewares.middleware11.inflightreq.sourcecriterion.requestheadername=foobar" -- "traefik.http.middlewares.middleware11.inflightreq.sourcecriterion.requesthost=true" -- "traefik.http.middlewares.middleware12.passtlsclientcert.info.issuer.commonname=true" -- "traefik.http.middlewares.middleware12.passtlsclientcert.info.issuer.country=true" -- "traefik.http.middlewares.middleware12.passtlsclientcert.info.issuer.domaincomponent=true" -- "traefik.http.middlewares.middleware12.passtlsclientcert.info.issuer.locality=true" -- "traefik.http.middlewares.middleware12.passtlsclientcert.info.issuer.organization=true" -- "traefik.http.middlewares.middleware12.passtlsclientcert.info.issuer.province=true" -- "traefik.http.middlewares.middleware12.passtlsclientcert.info.issuer.serialnumber=true" -- "traefik.http.middlewares.middleware12.passtlsclientcert.info.notafter=true" -- "traefik.http.middlewares.middleware12.passtlsclientcert.info.notbefore=true" -- "traefik.http.middlewares.middleware12.passtlsclientcert.info.sans=true" -- "traefik.http.middlewares.middleware12.passtlsclientcert.info.subject.commonname=true" -- "traefik.http.middlewares.middleware12.passtlsclientcert.info.subject.country=true" -- "traefik.http.middlewares.middleware12.passtlsclientcert.info.subject.domaincomponent=true" -- "traefik.http.middlewares.middleware12.passtlsclientcert.info.subject.locality=true" -- "traefik.http.middlewares.middleware12.passtlsclientcert.info.subject.organization=true" -- "traefik.http.middlewares.middleware12.passtlsclientcert.info.subject.province=true" -- "traefik.http.middlewares.middleware12.passtlsclientcert.info.subject.serialnumber=true" -- "traefik.http.middlewares.middleware12.passtlsclientcert.pem=true" -- "traefik.http.middlewares.middleware13.ratelimit.average=42" -- "traefik.http.middlewares.middleware13.ratelimit.burst=42" -- "traefik.http.middlewares.middleware13.ratelimit.sourcecriterion.ipstrategy.depth=42" -- "traefik.http.middlewares.middleware13.ratelimit.sourcecriterion.ipstrategy.excludedips=foobar, foobar" -- "traefik.http.middlewares.middleware13.ratelimit.sourcecriterion.requestheadername=foobar" -- "traefik.http.middlewares.middleware13.ratelimit.sourcecriterion.requesthost=true" -- "traefik.http.middlewares.middleware14.redirectregex.permanent=true" -- "traefik.http.middlewares.middleware14.redirectregex.regex=foobar" -- "traefik.http.middlewares.middleware14.redirectregex.replacement=foobar" -- "traefik.http.middlewares.middleware15.redirectscheme.permanent=true" -- "traefik.http.middlewares.middleware15.redirectscheme.port=foobar" -- "traefik.http.middlewares.middleware15.redirectscheme.scheme=foobar" -- "traefik.http.middlewares.middleware16.replacepath.path=foobar" -- "traefik.http.middlewares.middleware17.replacepathregex.regex=foobar" -- "traefik.http.middlewares.middleware17.replacepathregex.replacement=foobar" -- "traefik.http.middlewares.middleware18.retry.attempts=42" -- "traefik.http.middlewares.middleware19.stripprefix.forceslash=true" -- "traefik.http.middlewares.middleware19.stripprefix.prefixes=foobar, foobar" -- "traefik.http.middlewares.middleware20.stripprefixregex.regex=foobar, foobar" +- "traefik.http.middlewares.middleware05.compress.excludedcontenttypes=foobar, foobar" +- "traefik.http.middlewares.middleware06.contenttype.autodetect=true" +- "traefik.http.middlewares.middleware07.digestauth.headerfield=foobar" +- "traefik.http.middlewares.middleware07.digestauth.realm=foobar" +- "traefik.http.middlewares.middleware07.digestauth.removeheader=true" +- "traefik.http.middlewares.middleware07.digestauth.users=foobar, foobar" +- "traefik.http.middlewares.middleware07.digestauth.usersfile=foobar" +- "traefik.http.middlewares.middleware08.errors.query=foobar" +- "traefik.http.middlewares.middleware08.errors.service=foobar" +- "traefik.http.middlewares.middleware08.errors.status=foobar, foobar" +- "traefik.http.middlewares.middleware09.forwardauth.address=foobar" +- "traefik.http.middlewares.middleware09.forwardauth.authresponseheaders=foobar, foobar" +- "traefik.http.middlewares.middleware09.forwardauth.tls.ca=foobar" +- "traefik.http.middlewares.middleware09.forwardauth.tls.caoptional=true" +- "traefik.http.middlewares.middleware09.forwardauth.tls.cert=foobar" +- "traefik.http.middlewares.middleware09.forwardauth.tls.insecureskipverify=true" +- "traefik.http.middlewares.middleware09.forwardauth.tls.key=foobar" +- "traefik.http.middlewares.middleware09.forwardauth.trustforwardheader=true" +- "traefik.http.middlewares.middleware10.headers.accesscontrolallowcredentials=true" +- "traefik.http.middlewares.middleware10.headers.accesscontrolallowheaders=foobar, foobar" +- "traefik.http.middlewares.middleware10.headers.accesscontrolallowmethods=foobar, foobar" +- "traefik.http.middlewares.middleware10.headers.accesscontrolalloworigin=foobar" +- "traefik.http.middlewares.middleware10.headers.accesscontrolexposeheaders=foobar, foobar" +- "traefik.http.middlewares.middleware10.headers.accesscontrolmaxage=42" +- "traefik.http.middlewares.middleware10.headers.addvaryheader=true" +- "traefik.http.middlewares.middleware10.headers.allowedhosts=foobar, foobar" +- "traefik.http.middlewares.middleware10.headers.browserxssfilter=true" +- "traefik.http.middlewares.middleware10.headers.contentsecuritypolicy=foobar" +- "traefik.http.middlewares.middleware10.headers.contenttypenosniff=true" +- "traefik.http.middlewares.middleware10.headers.custombrowserxssvalue=foobar" +- "traefik.http.middlewares.middleware10.headers.customframeoptionsvalue=foobar" +- "traefik.http.middlewares.middleware10.headers.customrequestheaders.name0=foobar" +- "traefik.http.middlewares.middleware10.headers.customrequestheaders.name1=foobar" +- "traefik.http.middlewares.middleware10.headers.customresponseheaders.name0=foobar" +- "traefik.http.middlewares.middleware10.headers.customresponseheaders.name1=foobar" +- "traefik.http.middlewares.middleware10.headers.featurepolicy=foobar" +- "traefik.http.middlewares.middleware10.headers.forcestsheader=true" +- "traefik.http.middlewares.middleware10.headers.framedeny=true" +- "traefik.http.middlewares.middleware10.headers.hostsproxyheaders=foobar, foobar" +- "traefik.http.middlewares.middleware10.headers.isdevelopment=true" +- "traefik.http.middlewares.middleware10.headers.publickey=foobar" +- "traefik.http.middlewares.middleware10.headers.referrerpolicy=foobar" +- "traefik.http.middlewares.middleware10.headers.sslforcehost=true" +- "traefik.http.middlewares.middleware10.headers.sslhost=foobar" +- "traefik.http.middlewares.middleware10.headers.sslproxyheaders.name0=foobar" +- "traefik.http.middlewares.middleware10.headers.sslproxyheaders.name1=foobar" +- "traefik.http.middlewares.middleware10.headers.sslredirect=true" +- "traefik.http.middlewares.middleware10.headers.ssltemporaryredirect=true" +- "traefik.http.middlewares.middleware10.headers.stsincludesubdomains=true" +- "traefik.http.middlewares.middleware10.headers.stspreload=true" +- "traefik.http.middlewares.middleware10.headers.stsseconds=42" +- "traefik.http.middlewares.middleware11.ipwhitelist.ipstrategy.depth=42" +- "traefik.http.middlewares.middleware11.ipwhitelist.ipstrategy.excludedips=foobar, foobar" +- "traefik.http.middlewares.middleware11.ipwhitelist.sourcerange=foobar, foobar" +- "traefik.http.middlewares.middleware12.inflightreq.amount=42" +- "traefik.http.middlewares.middleware12.inflightreq.sourcecriterion.ipstrategy.depth=42" +- "traefik.http.middlewares.middleware12.inflightreq.sourcecriterion.ipstrategy.excludedips=foobar, foobar" +- "traefik.http.middlewares.middleware12.inflightreq.sourcecriterion.requestheadername=foobar" +- "traefik.http.middlewares.middleware12.inflightreq.sourcecriterion.requesthost=true" +- "traefik.http.middlewares.middleware13.passtlsclientcert.info.issuer.commonname=true" +- "traefik.http.middlewares.middleware13.passtlsclientcert.info.issuer.country=true" +- "traefik.http.middlewares.middleware13.passtlsclientcert.info.issuer.domaincomponent=true" +- "traefik.http.middlewares.middleware13.passtlsclientcert.info.issuer.locality=true" +- "traefik.http.middlewares.middleware13.passtlsclientcert.info.issuer.organization=true" +- "traefik.http.middlewares.middleware13.passtlsclientcert.info.issuer.province=true" +- "traefik.http.middlewares.middleware13.passtlsclientcert.info.issuer.serialnumber=true" +- "traefik.http.middlewares.middleware13.passtlsclientcert.info.notafter=true" +- "traefik.http.middlewares.middleware13.passtlsclientcert.info.notbefore=true" +- "traefik.http.middlewares.middleware13.passtlsclientcert.info.sans=true" +- "traefik.http.middlewares.middleware13.passtlsclientcert.info.subject.commonname=true" +- "traefik.http.middlewares.middleware13.passtlsclientcert.info.subject.country=true" +- "traefik.http.middlewares.middleware13.passtlsclientcert.info.subject.domaincomponent=true" +- "traefik.http.middlewares.middleware13.passtlsclientcert.info.subject.locality=true" +- "traefik.http.middlewares.middleware13.passtlsclientcert.info.subject.organization=true" +- "traefik.http.middlewares.middleware13.passtlsclientcert.info.subject.province=true" +- "traefik.http.middlewares.middleware13.passtlsclientcert.info.subject.serialnumber=true" +- "traefik.http.middlewares.middleware13.passtlsclientcert.pem=true" +- "traefik.http.middlewares.middleware14.ratelimit.average=42" +- "traefik.http.middlewares.middleware14.ratelimit.burst=42" +- "traefik.http.middlewares.middleware14.ratelimit.sourcecriterion.ipstrategy.depth=42" +- "traefik.http.middlewares.middleware14.ratelimit.sourcecriterion.ipstrategy.excludedips=foobar, foobar" +- "traefik.http.middlewares.middleware14.ratelimit.sourcecriterion.requestheadername=foobar" +- "traefik.http.middlewares.middleware14.ratelimit.sourcecriterion.requesthost=true" +- "traefik.http.middlewares.middleware15.redirectregex.permanent=true" +- "traefik.http.middlewares.middleware15.redirectregex.regex=foobar" +- "traefik.http.middlewares.middleware15.redirectregex.replacement=foobar" +- "traefik.http.middlewares.middleware16.redirectscheme.permanent=true" +- "traefik.http.middlewares.middleware16.redirectscheme.port=foobar" +- "traefik.http.middlewares.middleware16.redirectscheme.scheme=foobar" +- "traefik.http.middlewares.middleware17.replacepath.path=foobar" +- "traefik.http.middlewares.middleware18.replacepathregex.regex=foobar" +- "traefik.http.middlewares.middleware18.replacepathregex.replacement=foobar" +- "traefik.http.middlewares.middleware19.retry.attempts=42" +- "traefik.http.middlewares.middleware20.stripprefix.forceslash=true" +- "traefik.http.middlewares.middleware20.stripprefix.prefixes=foobar, foobar" +- "traefik.http.middlewares.middleware21.stripprefixregex.regex=foobar, foobar" - "traefik.http.routers.router0.entrypoints=foobar, foobar" - "traefik.http.routers.router0.middlewares=foobar, foobar" - "traefik.http.routers.router0.priority=42" diff --git a/docs/content/reference/dynamic-configuration/file.toml b/docs/content/reference/dynamic-configuration/file.toml index 5b6889254..c61ca3743 100644 --- a/docs/content/reference/dynamic-configuration/file.toml +++ b/docs/content/reference/dynamic-configuration/file.toml @@ -113,31 +113,35 @@ expression = "foobar" [http.middlewares.Middleware05] [http.middlewares.Middleware05.compress] + excludedContentTypes = ["foobar", "foobar"] [http.middlewares.Middleware06] - [http.middlewares.Middleware06.digestAuth] + [http.middlewares.Middleware06.contentType] + autoDetect = true + [http.middlewares.Middleware07] + [http.middlewares.Middleware07.digestAuth] users = ["foobar", "foobar"] usersFile = "foobar" removeHeader = true realm = "foobar" headerField = "foobar" - [http.middlewares.Middleware07] - [http.middlewares.Middleware07.errors] + [http.middlewares.Middleware08] + [http.middlewares.Middleware08.errors] status = ["foobar", "foobar"] service = "foobar" query = "foobar" - [http.middlewares.Middleware08] - [http.middlewares.Middleware08.forwardAuth] + [http.middlewares.Middleware09] + [http.middlewares.Middleware09.forwardAuth] address = "foobar" trustForwardHeader = true authResponseHeaders = ["foobar", "foobar"] - [http.middlewares.Middleware08.forwardAuth.tls] + [http.middlewares.Middleware09.forwardAuth.tls] ca = "foobar" caOptional = true cert = "foobar" key = "foobar" insecureSkipVerify = true - [http.middlewares.Middleware09] - [http.middlewares.Middleware09.headers] + [http.middlewares.Middleware10] + [http.middlewares.Middleware10.headers] accessControlAllowCredentials = true accessControlAllowHeaders = ["foobar", "foobar"] accessControlAllowMethods = ["foobar", "foobar"] @@ -165,38 +169,38 @@ referrerPolicy = "foobar" featurePolicy = "foobar" isDevelopment = true - [http.middlewares.Middleware09.headers.customRequestHeaders] + [http.middlewares.Middleware10.headers.customRequestHeaders] name0 = "foobar" name1 = "foobar" - [http.middlewares.Middleware09.headers.customResponseHeaders] + [http.middlewares.Middleware10.headers.customResponseHeaders] name0 = "foobar" name1 = "foobar" - [http.middlewares.Middleware09.headers.sslProxyHeaders] + [http.middlewares.Middleware10.headers.sslProxyHeaders] name0 = "foobar" name1 = "foobar" - [http.middlewares.Middleware10] - [http.middlewares.Middleware10.ipWhiteList] + [http.middlewares.Middleware11] + [http.middlewares.Middleware11.ipWhiteList] sourceRange = ["foobar", "foobar"] - [http.middlewares.Middleware10.ipWhiteList.ipStrategy] + [http.middlewares.Middleware11.ipWhiteList.ipStrategy] depth = 42 excludedIPs = ["foobar", "foobar"] - [http.middlewares.Middleware11] - [http.middlewares.Middleware11.inFlightReq] + [http.middlewares.Middleware12] + [http.middlewares.Middleware12.inFlightReq] amount = 42 - [http.middlewares.Middleware11.inFlightReq.sourceCriterion] + [http.middlewares.Middleware12.inFlightReq.sourceCriterion] requestHeaderName = "foobar" requestHost = true - [http.middlewares.Middleware11.inFlightReq.sourceCriterion.ipStrategy] + [http.middlewares.Middleware12.inFlightReq.sourceCriterion.ipStrategy] depth = 42 excludedIPs = ["foobar", "foobar"] - [http.middlewares.Middleware12] - [http.middlewares.Middleware12.passTLSClientCert] + [http.middlewares.Middleware13] + [http.middlewares.Middleware13.passTLSClientCert] pem = true - [http.middlewares.Middleware12.passTLSClientCert.info] + [http.middlewares.Middleware13.passTLSClientCert.info] notAfter = true notBefore = true sans = true - [http.middlewares.Middleware12.passTLSClientCert.info.subject] + [http.middlewares.Middleware13.passTLSClientCert.info.subject] country = true province = true locality = true @@ -204,7 +208,7 @@ commonName = true serialNumber = true domainComponent = true - [http.middlewares.Middleware12.passTLSClientCert.info.issuer] + [http.middlewares.Middleware13.passTLSClientCert.info.issuer] country = true province = true locality = true @@ -212,42 +216,42 @@ commonName = true serialNumber = true domainComponent = true - [http.middlewares.Middleware13] - [http.middlewares.Middleware13.rateLimit] + [http.middlewares.Middleware14] + [http.middlewares.Middleware14.rateLimit] average = 42 burst = 42 - [http.middlewares.Middleware13.rateLimit.sourceCriterion] + [http.middlewares.Middleware14.rateLimit.sourceCriterion] requestHeaderName = "foobar" requestHost = true - [http.middlewares.Middleware13.rateLimit.sourceCriterion.ipStrategy] + [http.middlewares.Middleware14.rateLimit.sourceCriterion.ipStrategy] depth = 42 excludedIPs = ["foobar", "foobar"] - [http.middlewares.Middleware14] - [http.middlewares.Middleware14.redirectRegex] + [http.middlewares.Middleware15] + [http.middlewares.Middleware15.redirectRegex] regex = "foobar" replacement = "foobar" permanent = true - [http.middlewares.Middleware15] - [http.middlewares.Middleware15.redirectScheme] + [http.middlewares.Middleware16] + [http.middlewares.Middleware16.redirectScheme] scheme = "foobar" port = "foobar" permanent = true - [http.middlewares.Middleware16] - [http.middlewares.Middleware16.replacePath] - path = "foobar" [http.middlewares.Middleware17] - [http.middlewares.Middleware17.replacePathRegex] + [http.middlewares.Middleware17.replacePath] + path = "foobar" + [http.middlewares.Middleware18] + [http.middlewares.Middleware18.replacePathRegex] regex = "foobar" replacement = "foobar" - [http.middlewares.Middleware18] - [http.middlewares.Middleware18.retry] - attempts = 42 [http.middlewares.Middleware19] - [http.middlewares.Middleware19.stripPrefix] + [http.middlewares.Middleware19.retry] + attempts = 42 + [http.middlewares.Middleware20] + [http.middlewares.Middleware20.stripPrefix] prefixes = ["foobar", "foobar"] forceSlash = true - [http.middlewares.Middleware20] - [http.middlewares.Middleware20.stripPrefixRegex] + [http.middlewares.Middleware21] + [http.middlewares.Middleware21.stripPrefixRegex] regex = ["foobar", "foobar"] [tcp] @@ -321,8 +325,8 @@ minVersion = "foobar" maxVersion = "foobar" cipherSuites = ["foobar", "foobar"] - sniStrict = true curvePreferences = ["foobar", "foobar"] + sniStrict = true [tls.options.Options0.clientAuth] caFiles = ["foobar", "foobar"] clientAuthType = "foobar" @@ -330,8 +334,8 @@ minVersion = "foobar" maxVersion = "foobar" cipherSuites = ["foobar", "foobar"] - sniStrict = true curvePreferences = ["foobar", "foobar"] + sniStrict = true [tls.options.Options1.clientAuth] caFiles = ["foobar", "foobar"] clientAuthType = "foobar" diff --git a/docs/content/reference/dynamic-configuration/file.yaml b/docs/content/reference/dynamic-configuration/file.yaml index d6e091940..dbbb95361 100644 --- a/docs/content/reference/dynamic-configuration/file.yaml +++ b/docs/content/reference/dynamic-configuration/file.yaml @@ -117,8 +117,14 @@ http: circuitBreaker: expression: foobar Middleware05: - compress: {} + compress: + excludedContentTypes: + - foobar + - foobar Middleware06: + contentType: + autoDetect: true + Middleware07: digestAuth: users: - foobar @@ -127,14 +133,14 @@ http: removeHeader: true realm: foobar headerField: foobar - Middleware07: + Middleware08: errors: status: - foobar - foobar service: foobar query: foobar - Middleware08: + Middleware09: forwardAuth: address: foobar tls: @@ -147,7 +153,7 @@ http: authResponseHeaders: - foobar - foobar - Middleware09: + Middleware10: headers: customRequestHeaders: name0: foobar @@ -195,7 +201,7 @@ http: referrerPolicy: foobar featurePolicy: foobar isDevelopment: true - Middleware10: + Middleware11: ipWhiteList: sourceRange: - foobar @@ -205,7 +211,7 @@ http: excludedIPs: - foobar - foobar - Middleware11: + Middleware12: inFlightReq: amount: 42 sourceCriterion: @@ -216,7 +222,7 @@ http: - foobar requestHeaderName: foobar requestHost: true - Middleware12: + Middleware13: passTLSClientCert: pem: true info: @@ -239,7 +245,7 @@ http: commonName: true serialNumber: true domainComponent: true - Middleware13: + Middleware14: rateLimit: average: 42 burst: 42 @@ -251,33 +257,33 @@ http: - foobar requestHeaderName: foobar requestHost: true - Middleware14: + Middleware15: redirectRegex: regex: foobar replacement: foobar permanent: true - Middleware15: + Middleware16: redirectScheme: scheme: foobar port: foobar permanent: true - Middleware16: + Middleware17: replacePath: path: foobar - Middleware17: + Middleware18: replacePathRegex: regex: foobar replacement: foobar - Middleware18: + Middleware19: retry: attempts: 42 - Middleware19: + Middleware20: stripPrefix: prefixes: - foobar - foobar forceSlash: true - Middleware20: + Middleware21: stripPrefixRegex: regex: - foobar @@ -353,8 +359,8 @@ tls: minVersion: foobar maxVersion: foobar cipherSuites: - - foobar - - foobar + - foobar + - foobar curvePreferences: - foobar - foobar @@ -368,8 +374,8 @@ tls: minVersion: foobar maxVersion: foobar cipherSuites: - - foobar - - foobar + - foobar + - foobar curvePreferences: - foobar - foobar diff --git a/docs/content/reference/dynamic-configuration/marathon-labels.json b/docs/content/reference/dynamic-configuration/marathon-labels.json index 4294c82e0..c466602c8 100644 --- a/docs/content/reference/dynamic-configuration/marathon-labels.json +++ b/docs/content/reference/dynamic-configuration/marathon-labels.json @@ -12,100 +12,102 @@ "traefik.http.middlewares.middleware03.chain.middlewares": "foobar, foobar", "traefik.http.middlewares.middleware04.circuitbreaker.expression": "foobar", "traefik.http.middlewares.middleware05.compress": "true", -"traefik.http.middlewares.middleware06.digestauth.headerfield": "foobar", -"traefik.http.middlewares.middleware06.digestauth.realm": "foobar", -"traefik.http.middlewares.middleware06.digestauth.removeheader": "true", -"traefik.http.middlewares.middleware06.digestauth.users": "foobar, foobar", -"traefik.http.middlewares.middleware06.digestauth.usersfile": "foobar", -"traefik.http.middlewares.middleware07.errors.query": "foobar", -"traefik.http.middlewares.middleware07.errors.service": "foobar", -"traefik.http.middlewares.middleware07.errors.status": "foobar, foobar", -"traefik.http.middlewares.middleware08.forwardauth.address": "foobar", -"traefik.http.middlewares.middleware08.forwardauth.authresponseheaders": "foobar, foobar", -"traefik.http.middlewares.middleware08.forwardauth.tls.ca": "foobar", -"traefik.http.middlewares.middleware08.forwardauth.tls.caoptional": "true", -"traefik.http.middlewares.middleware08.forwardauth.tls.cert": "foobar", -"traefik.http.middlewares.middleware08.forwardauth.tls.insecureskipverify": "true", -"traefik.http.middlewares.middleware08.forwardauth.tls.key": "foobar", -"traefik.http.middlewares.middleware08.forwardauth.trustforwardheader": "true", -"traefik.http.middlewares.middleware09.headers.accesscontrolallowcredentials": "true", -"traefik.http.middlewares.middleware09.headers.accesscontrolallowheaders": "foobar, foobar", -"traefik.http.middlewares.middleware09.headers.accesscontrolallowmethods": "foobar, foobar", -"traefik.http.middlewares.middleware09.headers.accesscontrolalloworigin": "foobar", -"traefik.http.middlewares.middleware09.headers.accesscontrolexposeheaders": "foobar, foobar", -"traefik.http.middlewares.middleware09.headers.accesscontrolmaxage": "42", -"traefik.http.middlewares.middleware09.headers.addvaryheader": "true", -"traefik.http.middlewares.middleware09.headers.allowedhosts": "foobar, foobar", -"traefik.http.middlewares.middleware09.headers.browserxssfilter": "true", -"traefik.http.middlewares.middleware09.headers.contentsecuritypolicy": "foobar", -"traefik.http.middlewares.middleware09.headers.contenttypenosniff": "true", -"traefik.http.middlewares.middleware09.headers.custombrowserxssvalue": "foobar", -"traefik.http.middlewares.middleware09.headers.customframeoptionsvalue": "foobar", -"traefik.http.middlewares.middleware09.headers.customrequestheaders.name0": "foobar", -"traefik.http.middlewares.middleware09.headers.customrequestheaders.name1": "foobar", -"traefik.http.middlewares.middleware09.headers.customresponseheaders.name0": "foobar", -"traefik.http.middlewares.middleware09.headers.customresponseheaders.name1": "foobar", -"traefik.http.middlewares.middleware09.headers.featurepolicy": "foobar", -"traefik.http.middlewares.middleware09.headers.forcestsheader": "true", -"traefik.http.middlewares.middleware09.headers.framedeny": "true", -"traefik.http.middlewares.middleware09.headers.hostsproxyheaders": "foobar, foobar", -"traefik.http.middlewares.middleware09.headers.isdevelopment": "true", -"traefik.http.middlewares.middleware09.headers.publickey": "foobar", -"traefik.http.middlewares.middleware09.headers.referrerpolicy": "foobar", -"traefik.http.middlewares.middleware09.headers.sslforcehost": "true", -"traefik.http.middlewares.middleware09.headers.sslhost": "foobar", -"traefik.http.middlewares.middleware09.headers.sslproxyheaders.name0": "foobar", -"traefik.http.middlewares.middleware09.headers.sslproxyheaders.name1": "foobar", -"traefik.http.middlewares.middleware09.headers.sslredirect": "true", -"traefik.http.middlewares.middleware09.headers.ssltemporaryredirect": "true", -"traefik.http.middlewares.middleware09.headers.stsincludesubdomains": "true", -"traefik.http.middlewares.middleware09.headers.stspreload": "true", -"traefik.http.middlewares.middleware09.headers.stsseconds": "42", -"traefik.http.middlewares.middleware10.ipwhitelist.ipstrategy.depth": "42", -"traefik.http.middlewares.middleware10.ipwhitelist.ipstrategy.excludedips": "foobar, foobar", -"traefik.http.middlewares.middleware10.ipwhitelist.sourcerange": "foobar, foobar", -"traefik.http.middlewares.middleware11.inflightreq.amount": "42", -"traefik.http.middlewares.middleware11.inflightreq.sourcecriterion.ipstrategy.depth": "42", -"traefik.http.middlewares.middleware11.inflightreq.sourcecriterion.ipstrategy.excludedips": "foobar, foobar", -"traefik.http.middlewares.middleware11.inflightreq.sourcecriterion.requestheadername": "foobar", -"traefik.http.middlewares.middleware11.inflightreq.sourcecriterion.requesthost": "true", -"traefik.http.middlewares.middleware12.passtlsclientcert.info.issuer.commonname": "true", -"traefik.http.middlewares.middleware12.passtlsclientcert.info.issuer.country": "true", -"traefik.http.middlewares.middleware12.passtlsclientcert.info.issuer.domaincomponent": "true", -"traefik.http.middlewares.middleware12.passtlsclientcert.info.issuer.locality": "true", -"traefik.http.middlewares.middleware12.passtlsclientcert.info.issuer.organization": "true", -"traefik.http.middlewares.middleware12.passtlsclientcert.info.issuer.province": "true", -"traefik.http.middlewares.middleware12.passtlsclientcert.info.issuer.serialnumber": "true", -"traefik.http.middlewares.middleware12.passtlsclientcert.info.notafter": "true", -"traefik.http.middlewares.middleware12.passtlsclientcert.info.notbefore": "true", -"traefik.http.middlewares.middleware12.passtlsclientcert.info.sans": "true", -"traefik.http.middlewares.middleware12.passtlsclientcert.info.subject.commonname": "true", -"traefik.http.middlewares.middleware12.passtlsclientcert.info.subject.country": "true", -"traefik.http.middlewares.middleware12.passtlsclientcert.info.subject.domaincomponent": "true", -"traefik.http.middlewares.middleware12.passtlsclientcert.info.subject.locality": "true", -"traefik.http.middlewares.middleware12.passtlsclientcert.info.subject.organization": "true", -"traefik.http.middlewares.middleware12.passtlsclientcert.info.subject.province": "true", -"traefik.http.middlewares.middleware12.passtlsclientcert.info.subject.serialnumber": "true", -"traefik.http.middlewares.middleware12.passtlsclientcert.pem": "true", -"traefik.http.middlewares.middleware13.ratelimit.average": "42", -"traefik.http.middlewares.middleware13.ratelimit.burst": "42", -"traefik.http.middlewares.middleware13.ratelimit.sourcecriterion.ipstrategy.depth": "42", -"traefik.http.middlewares.middleware13.ratelimit.sourcecriterion.ipstrategy.excludedips": "foobar, foobar", -"traefik.http.middlewares.middleware13.ratelimit.sourcecriterion.requestheadername": "foobar", -"traefik.http.middlewares.middleware13.ratelimit.sourcecriterion.requesthost": "true", -"traefik.http.middlewares.middleware14.redirectregex.permanent": "true", -"traefik.http.middlewares.middleware14.redirectregex.regex": "foobar", -"traefik.http.middlewares.middleware14.redirectregex.replacement": "foobar", -"traefik.http.middlewares.middleware15.redirectscheme.permanent": "true", -"traefik.http.middlewares.middleware15.redirectscheme.port": "foobar", -"traefik.http.middlewares.middleware15.redirectscheme.scheme": "foobar", -"traefik.http.middlewares.middleware16.replacepath.path": "foobar", -"traefik.http.middlewares.middleware17.replacepathregex.regex": "foobar", -"traefik.http.middlewares.middleware17.replacepathregex.replacement": "foobar", -"traefik.http.middlewares.middleware18.retry.attempts": "42", -"traefik.http.middlewares.middleware19.stripprefix.forceslash": "true", -"traefik.http.middlewares.middleware19.stripprefix.prefixes": "foobar, foobar", -"traefik.http.middlewares.middleware20.stripprefixregex.regex": "foobar, foobar", +"traefik.http.middlewares.middleware05.compress.excludedcontenttypes": "foobar, foobar", +"traefik.http.middlewares.middleware06.contenttype.autodetect": "true", +"traefik.http.middlewares.middleware07.digestauth.headerfield": "foobar", +"traefik.http.middlewares.middleware07.digestauth.realm": "foobar", +"traefik.http.middlewares.middleware07.digestauth.removeheader": "true", +"traefik.http.middlewares.middleware07.digestauth.users": "foobar, foobar", +"traefik.http.middlewares.middleware07.digestauth.usersfile": "foobar", +"traefik.http.middlewares.middleware08.errors.query": "foobar", +"traefik.http.middlewares.middleware08.errors.service": "foobar", +"traefik.http.middlewares.middleware08.errors.status": "foobar, foobar", +"traefik.http.middlewares.middleware09.forwardauth.address": "foobar", +"traefik.http.middlewares.middleware09.forwardauth.authresponseheaders": "foobar, foobar", +"traefik.http.middlewares.middleware09.forwardauth.tls.ca": "foobar", +"traefik.http.middlewares.middleware09.forwardauth.tls.caoptional": "true", +"traefik.http.middlewares.middleware09.forwardauth.tls.cert": "foobar", +"traefik.http.middlewares.middleware09.forwardauth.tls.insecureskipverify": "true", +"traefik.http.middlewares.middleware09.forwardauth.tls.key": "foobar", +"traefik.http.middlewares.middleware09.forwardauth.trustforwardheader": "true", +"traefik.http.middlewares.middleware10.headers.accesscontrolallowcredentials": "true", +"traefik.http.middlewares.middleware10.headers.accesscontrolallowheaders": "foobar, foobar", +"traefik.http.middlewares.middleware10.headers.accesscontrolallowmethods": "foobar, foobar", +"traefik.http.middlewares.middleware10.headers.accesscontrolalloworigin": "foobar", +"traefik.http.middlewares.middleware10.headers.accesscontrolexposeheaders": "foobar, foobar", +"traefik.http.middlewares.middleware10.headers.accesscontrolmaxage": "42", +"traefik.http.middlewares.middleware10.headers.addvaryheader": "true", +"traefik.http.middlewares.middleware10.headers.allowedhosts": "foobar, foobar", +"traefik.http.middlewares.middleware10.headers.browserxssfilter": "true", +"traefik.http.middlewares.middleware10.headers.contentsecuritypolicy": "foobar", +"traefik.http.middlewares.middleware10.headers.contenttypenosniff": "true", +"traefik.http.middlewares.middleware10.headers.custombrowserxssvalue": "foobar", +"traefik.http.middlewares.middleware10.headers.customframeoptionsvalue": "foobar", +"traefik.http.middlewares.middleware10.headers.customrequestheaders.name0": "foobar", +"traefik.http.middlewares.middleware10.headers.customrequestheaders.name1": "foobar", +"traefik.http.middlewares.middleware10.headers.customresponseheaders.name0": "foobar", +"traefik.http.middlewares.middleware10.headers.customresponseheaders.name1": "foobar", +"traefik.http.middlewares.middleware10.headers.featurepolicy": "foobar", +"traefik.http.middlewares.middleware10.headers.forcestsheader": "true", +"traefik.http.middlewares.middleware10.headers.framedeny": "true", +"traefik.http.middlewares.middleware10.headers.hostsproxyheaders": "foobar, foobar", +"traefik.http.middlewares.middleware10.headers.isdevelopment": "true", +"traefik.http.middlewares.middleware10.headers.publickey": "foobar", +"traefik.http.middlewares.middleware10.headers.referrerpolicy": "foobar", +"traefik.http.middlewares.middleware10.headers.sslforcehost": "true", +"traefik.http.middlewares.middleware10.headers.sslhost": "foobar", +"traefik.http.middlewares.middleware10.headers.sslproxyheaders.name0": "foobar", +"traefik.http.middlewares.middleware10.headers.sslproxyheaders.name1": "foobar", +"traefik.http.middlewares.middleware10.headers.sslredirect": "true", +"traefik.http.middlewares.middleware10.headers.ssltemporaryredirect": "true", +"traefik.http.middlewares.middleware10.headers.stsincludesubdomains": "true", +"traefik.http.middlewares.middleware10.headers.stspreload": "true", +"traefik.http.middlewares.middleware10.headers.stsseconds": "42", +"traefik.http.middlewares.middleware11.ipwhitelist.ipstrategy.depth": "42", +"traefik.http.middlewares.middleware11.ipwhitelist.ipstrategy.excludedips": "foobar, foobar", +"traefik.http.middlewares.middleware11.ipwhitelist.sourcerange": "foobar, foobar", +"traefik.http.middlewares.middleware12.inflightreq.amount": "42", +"traefik.http.middlewares.middleware12.inflightreq.sourcecriterion.ipstrategy.depth": "42", +"traefik.http.middlewares.middleware12.inflightreq.sourcecriterion.ipstrategy.excludedips": "foobar, foobar", +"traefik.http.middlewares.middleware12.inflightreq.sourcecriterion.requestheadername": "foobar", +"traefik.http.middlewares.middleware12.inflightreq.sourcecriterion.requesthost": "true", +"traefik.http.middlewares.middleware13.passtlsclientcert.info.issuer.commonname": "true", +"traefik.http.middlewares.middleware13.passtlsclientcert.info.issuer.country": "true", +"traefik.http.middlewares.middleware13.passtlsclientcert.info.issuer.domaincomponent": "true", +"traefik.http.middlewares.middleware13.passtlsclientcert.info.issuer.locality": "true", +"traefik.http.middlewares.middleware13.passtlsclientcert.info.issuer.organization": "true", +"traefik.http.middlewares.middleware13.passtlsclientcert.info.issuer.province": "true", +"traefik.http.middlewares.middleware13.passtlsclientcert.info.issuer.serialnumber": "true", +"traefik.http.middlewares.middleware13.passtlsclientcert.info.notafter": "true", +"traefik.http.middlewares.middleware13.passtlsclientcert.info.notbefore": "true", +"traefik.http.middlewares.middleware13.passtlsclientcert.info.sans": "true", +"traefik.http.middlewares.middleware13.passtlsclientcert.info.subject.commonname": "true", +"traefik.http.middlewares.middleware13.passtlsclientcert.info.subject.country": "true", +"traefik.http.middlewares.middleware13.passtlsclientcert.info.subject.domaincomponent": "true", +"traefik.http.middlewares.middleware13.passtlsclientcert.info.subject.locality": "true", +"traefik.http.middlewares.middleware13.passtlsclientcert.info.subject.organization": "true", +"traefik.http.middlewares.middleware13.passtlsclientcert.info.subject.province": "true", +"traefik.http.middlewares.middleware13.passtlsclientcert.info.subject.serialnumber": "true", +"traefik.http.middlewares.middleware13.passtlsclientcert.pem": "true", +"traefik.http.middlewares.middleware14.ratelimit.average": "42", +"traefik.http.middlewares.middleware14.ratelimit.burst": "42", +"traefik.http.middlewares.middleware14.ratelimit.sourcecriterion.ipstrategy.depth": "42", +"traefik.http.middlewares.middleware14.ratelimit.sourcecriterion.ipstrategy.excludedips": "foobar, foobar", +"traefik.http.middlewares.middleware14.ratelimit.sourcecriterion.requestheadername": "foobar", +"traefik.http.middlewares.middleware14.ratelimit.sourcecriterion.requesthost": "true", +"traefik.http.middlewares.middleware15.redirectregex.permanent": "true", +"traefik.http.middlewares.middleware15.redirectregex.regex": "foobar", +"traefik.http.middlewares.middleware15.redirectregex.replacement": "foobar", +"traefik.http.middlewares.middleware16.redirectscheme.permanent": "true", +"traefik.http.middlewares.middleware16.redirectscheme.port": "foobar", +"traefik.http.middlewares.middleware16.redirectscheme.scheme": "foobar", +"traefik.http.middlewares.middleware17.replacepath.path": "foobar", +"traefik.http.middlewares.middleware18.replacepathregex.regex": "foobar", +"traefik.http.middlewares.middleware18.replacepathregex.replacement": "foobar", +"traefik.http.middlewares.middleware19.retry.attempts": "42", +"traefik.http.middlewares.middleware20.stripprefix.forceslash": "true", +"traefik.http.middlewares.middleware20.stripprefix.prefixes": "foobar, foobar", +"traefik.http.middlewares.middleware21.stripprefixregex.regex": "foobar, foobar", "traefik.http.routers.router0.entrypoints": "foobar, foobar", "traefik.http.routers.router0.middlewares": "foobar, foobar", "traefik.http.routers.router0.priority": "42", diff --git a/docs/content/reference/static-configuration/file.toml b/docs/content/reference/static-configuration/file.toml index cad3042ce..eecb265d7 100644 --- a/docs/content/reference/static-configuration/file.toml +++ b/docs/content/reference/static-configuration/file.toml @@ -96,7 +96,7 @@ namespaces = ["foobar", "foobar"] labelSelector = "foobar" ingressClass = "foobar" - throttleDuration = "10s" + throttleDuration = 42 [providers.rest] insecure = true [providers.rancher] @@ -110,25 +110,28 @@ prefix = "foobar" [providers.consulCatalog] constraints = "foobar" - prefix = "traefik" - defaultRule = "foobar" - exposedByDefault = true - refreshInterval = 15 + prefix = "foobar" + refreshInterval = 42 requireConsistent = true stale = true cache = true + exposedByDefault = true + defaultRule = "foobar" [providers.consulCatalog.endpoint] - address = "foobar" - scheme = "foobar" - datacenter = "foobar" - token = "foobar" - endpointWaitTime = "15s" - [providers.consulCatalog.endpoint.tls] - ca = "foobar" - caOptional = true - cert = "foobar" - key = "foobar" - insecureSkipVerify = true + address = "foobar" + scheme = "foobar" + datacenter = "foobar" + token = "foobar" + endpointWaitTime = 42 + [providers.consulCatalog.endpoint.tls] + ca = "foobar" + caOptional = true + cert = "foobar" + key = "foobar" + insecureSkipVerify = true + [providers.consulCatalog.endpoint.httpAuth] + username = "foobar" + password = "foobar" [api] insecure = true @@ -144,19 +147,19 @@ manualRouting = true [metrics.datadog] address = "foobar" - pushInterval = "10s" + pushInterval = "42s" addEntryPointsLabels = true addServicesLabels = true [metrics.statsD] address = "foobar" - pushInterval = "10s" + pushInterval = "42s" addEntryPointsLabels = true addServicesLabels = true - prefix = "traefik" + prefix = "foobar" [metrics.influxDB] address = "foobar" protocol = "foobar" - pushInterval = "10s" + pushInterval = "42s" database = "foobar" retentionPolicy = "foobar" username = "foobar" diff --git a/docs/content/reference/static-configuration/file.yaml b/docs/content/reference/static-configuration/file.yaml index acee93fe2..f99e7b129 100644 --- a/docs/content/reference/static-configuration/file.yaml +++ b/docs/content/reference/static-configuration/file.yaml @@ -88,7 +88,7 @@ providers: - foobar labelSelector: foobar ingressClass: foobar - throttleDuration: 10s + throttleDuration: 42s ingressEndpoint: ip: foobar hostname: foobar @@ -117,25 +117,28 @@ providers: prefix: foobar consulCatalog: constraints: foobar - prefix: traefik - defaultRule: foobar - exposedByDefault: true - refreshInterval: 15 + prefix: foobar + refreshInterval: 42s requireConsistent: true stale: true cache: true + exposedByDefault: true + defaultRule: foobar endpoint: address: foobar scheme: foobar datacenter: foobar token: foobar - endpointWaitTime: 15s + endpointWaitTime: 42s tls: ca: foobar caOptional: true cert: foobar key: foobar insecureSkipVerify: true + httpAuth: + username: foobar + password: foobar api: insecure: true dashboard: true @@ -159,7 +162,7 @@ metrics: pushInterval: 42 addEntryPointsLabels: true addServicesLabels: true - prefix: traefik + prefix: foobar influxDB: address: foobar protocol: foobar diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index 0e23fbdba..02a5b1382 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -107,6 +107,7 @@ nav: - 'Chain': 'middlewares/chain.md' - 'CircuitBreaker': 'middlewares/circuitbreaker.md' - 'Compress': 'middlewares/compress.md' + - 'ContentType': 'middlewares/contenttype.md' - 'DigestAuth': 'middlewares/digestauth.md' - 'Errors': 'middlewares/errorpages.md' - 'ForwardAuth': 'middlewares/forwardauth.md' diff --git a/integration/fixtures/simple_contenttype.toml b/integration/fixtures/simple_contenttype.toml new file mode 100644 index 000000000..c76967f33 --- /dev/null +++ b/integration/fixtures/simple_contenttype.toml @@ -0,0 +1,61 @@ +[global] + checkNewVersion = false + sendAnonymousUsage = false + +[log] + level = "DEBUG" + +[entryPoints] + [entryPoints.web] + address = ":8000" + +[api] + insecure = true + +[providers.file] + filename = "{{ .SelfFilename }}" + +## dynamic configuration ## + +[http.routers] + [http.routers.router1] + service = "service1" + rule = "PathPrefix(`/css/ct/nomiddleware`) || PathPrefix(`/pdf/ct/nomiddleware`)" + + [http.routers.router2] + service = "service1" + middlewares = ["autodetect"] + rule = "PathPrefix(`/css/ct/middlewareauto`) || PathPrefix(`/pdf/ct/middlewareauto`)" + + [http.routers.router3] + service = "service1" + middlewares = ["noautodetect"] + rule = "PathPrefix(`/css/ct/middlewarenoauto`) || PathPrefix(`/pdf/ct/middlewarenoauto`)" + + [http.routers.router4] + service = "service1" + rule = "PathPrefix(`/css/noct/nomiddleware`) || PathPrefix(`/pdf/noct/nomiddleware`)" + + [http.routers.router5] + service = "service1" + middlewares = ["autodetect"] + rule = "PathPrefix(`/css/noct/middlewareauto`) || PathPrefix(`/pdf/noct/middlewareauto`)" + + [http.routers.router6] + service = "service1" + middlewares = ["noautodetect"] + rule = "PathPrefix(`/css/noct/middlewarenoauto`) || PathPrefix(`/pdf/noct/middlewarenoauto`)" + + +[http.services] + [http.services.service1] + [http.services.service1.loadBalancer] + passHostHeader = true + [[http.services.service1.loadBalancer.servers]] + url = "{{ .Server }}" + +[http.middlewares.autodetect.contentType] +autoDetect=true + +[http.middlewares.noautodetect.contentType] +autoDetect=false \ No newline at end of file diff --git a/integration/fixtures/test.pdf b/integration/fixtures/test.pdf new file mode 100644 index 000000000..b6044e02a Binary files /dev/null and b/integration/fixtures/test.pdf differ diff --git a/integration/simple_test.go b/integration/simple_test.go index 49c35d13f..0fb11a99c 100644 --- a/integration/simple_test.go +++ b/integration/simple_test.go @@ -779,3 +779,98 @@ func (s *SimpleSuite) TestSecureAPI(c *check.C) { err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.StatusCodeIs(http.StatusNotFound)) c.Assert(err, checker.IsNil) } + +func (s *SimpleSuite) TestContentTypeDisableAutoDetect(c *check.C) { + srv1 := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { + rw.Header()["Content-Type"] = nil + switch req.URL.Path[:4] { + case "/css": + if !strings.Contains(req.URL.Path, "noct") { + rw.Header().Set("Content-Type", "text/css") + } + + rw.WriteHeader(http.StatusOK) + + _, err := rw.Write([]byte(".testcss { }")) + c.Assert(err, checker.IsNil) + case "/pdf": + if !strings.Contains(req.URL.Path, "noct") { + rw.Header().Set("Content-Type", "application/pdf") + } + + rw.WriteHeader(http.StatusOK) + + bytes, err := ioutil.ReadFile("fixtures/test.pdf") + c.Assert(err, checker.IsNil) + + _, err = rw.Write(bytes) + c.Assert(err, checker.IsNil) + } + })) + + defer srv1.Close() + + file := s.adaptFile(c, "fixtures/simple_contenttype.toml", struct { + Server string + }{ + Server: srv1.URL, + }) + defer os.Remove(file) + + cmd, display := s.traefikCmd(withConfigFile(file), "--log.level=DEBUG") + defer display(c) + + err := cmd.Start() + c.Assert(err, check.IsNil) + defer cmd.Process.Kill() + + // wait for traefik + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 10*time.Second, try.BodyContains("127.0.0.1")) + c.Assert(err, checker.IsNil) + + err = try.GetRequest("http://127.0.0.1:8000/css/ct/nomiddleware", time.Second, try.HasHeaderValue("Content-Type", "text/css", false)) + c.Assert(err, checker.IsNil) + + err = try.GetRequest("http://127.0.0.1:8000/pdf/ct/nomiddleware", time.Second, try.HasHeaderValue("Content-Type", "application/pdf", false)) + c.Assert(err, checker.IsNil) + + err = try.GetRequest("http://127.0.0.1:8000/css/ct/middlewareauto", time.Second, try.HasHeaderValue("Content-Type", "text/css", false)) + c.Assert(err, checker.IsNil) + + err = try.GetRequest("http://127.0.0.1:8000/pdf/ct/nomiddlewareauto", time.Second, try.HasHeaderValue("Content-Type", "application/pdf", false)) + c.Assert(err, checker.IsNil) + + err = try.GetRequest("http://127.0.0.1:8000/css/ct/middlewarenoauto", time.Second, try.HasHeaderValue("Content-Type", "text/css", false)) + c.Assert(err, checker.IsNil) + + err = try.GetRequest("http://127.0.0.1:8000/pdf/ct/nomiddlewarenoauto", time.Second, try.HasHeaderValue("Content-Type", "application/pdf", false)) + c.Assert(err, checker.IsNil) + + err = try.GetRequest("http://127.0.0.1:8000/css/noct/nomiddleware", time.Second, try.HasHeaderValue("Content-Type", "text/plain; charset=utf-8", false)) + c.Assert(err, checker.IsNil) + + err = try.GetRequest("http://127.0.0.1:8000/pdf/noct/nomiddleware", time.Second, try.HasHeaderValue("Content-Type", "application/pdf", false)) + c.Assert(err, checker.IsNil) + + err = try.GetRequest("http://127.0.0.1:8000/css/noct/middlewareauto", time.Second, try.HasHeaderValue("Content-Type", "text/plain; charset=utf-8", false)) + c.Assert(err, checker.IsNil) + + err = try.GetRequest("http://127.0.0.1:8000/pdf/noct/nomiddlewareauto", time.Second, try.HasHeaderValue("Content-Type", "application/pdf", false)) + c.Assert(err, checker.IsNil) + + err = try.GetRequest("http://127.0.0.1:8000/css/noct/middlewarenoauto", time.Second, func(res *http.Response) error { + if ct, ok := res.Header["Content-Type"]; ok { + return fmt.Errorf("should have no content type and %s is present", ct) + } + return nil + }) + c.Assert(err, checker.IsNil) + + err = try.GetRequest("http://127.0.0.1:8000/pdf/noct/middlewarenoauto", time.Second, func(res *http.Response) error { + if ct, ok := res.Header["Content-Type"]; ok { + return fmt.Errorf("should have no content type and %s is present", ct) + } + return nil + }) + c.Assert(err, checker.IsNil) +} diff --git a/pkg/config/dynamic/middlewares.go b/pkg/config/dynamic/middlewares.go index b729ca563..158f02f09 100644 --- a/pkg/config/dynamic/middlewares.go +++ b/pkg/config/dynamic/middlewares.go @@ -35,6 +35,22 @@ type Middleware struct { Compress *Compress `json:"compress,omitempty" toml:"compress,omitempty" yaml:"compress,omitempty" label:"allowEmpty"` PassTLSClientCert *PassTLSClientCert `json:"passTLSClientCert,omitempty" toml:"passTLSClientCert,omitempty" yaml:"passTLSClientCert,omitempty"` Retry *Retry `json:"retry,omitempty" toml:"retry,omitempty" yaml:"retry,omitempty"` + ContentType *ContentType `json:"contentType,omitempty" toml:"contentType,omitempty" yaml:"contentType,omitempty"` +} + +// +k8s:deepcopy-gen=true + +// ContentType middleware - or rather its unique `autoDetect` option - +// specifies whether to let the `Content-Type` header, +// if it has not been set by the backend, +// be automatically set to a value derived from the contents of the response. +// As a proxy, the default behavior should be to leave the header alone, +// regardless of what the backend did with it. +// However, the historic default was to always auto-detect and set the header if it was nil, +// and it is going to be kept that way in order to support users currently relying on it. +// This middleware exists to enable the correct behavior until at least the default one can be changed in a future version. +type ContentType struct { + AutoDetect bool `json:"autoDetect,omitempty" toml:"autoDetect,omitempty" yaml:"autoDetect,omitempty"` } // +k8s:deepcopy-gen=true diff --git a/pkg/config/dynamic/zz_generated.deepcopy.go b/pkg/config/dynamic/zz_generated.deepcopy.go index 1683909fa..fa544c396 100644 --- a/pkg/config/dynamic/zz_generated.deepcopy.go +++ b/pkg/config/dynamic/zz_generated.deepcopy.go @@ -252,6 +252,22 @@ func (in Configurations) DeepCopy() Configurations { return *out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ContentType) DeepCopyInto(out *ContentType) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContentType. +func (in *ContentType) DeepCopy() *ContentType { + if in == nil { + return nil + } + out := new(ContentType) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Cookie) DeepCopyInto(out *Cookie) { *out = *in @@ -679,6 +695,11 @@ func (in *Middleware) DeepCopyInto(out *Middleware) { *out = new(Retry) **out = **in } + if in.ContentType != nil { + in, out := &in.ContentType, &out.ContentType + *out = new(ContentType) + **out = **in + } return } diff --git a/pkg/provider/consulcatalog/consul_catalog.go b/pkg/provider/consulcatalog/consul_catalog.go index 079f3f9f2..f3c5c5a03 100644 --- a/pkg/provider/consulcatalog/consul_catalog.go +++ b/pkg/provider/consulcatalog/consul_catalog.go @@ -54,7 +54,7 @@ type Provider struct { type EndpointConfig struct { Address string `description:"The address of the Consul server" json:"address,omitempty" toml:"address,omitempty" yaml:"address,omitempty" export:"true"` Scheme string `description:"The URI scheme for the Consul server" json:"scheme,omitempty" toml:"scheme,omitempty" yaml:"scheme,omitempty" export:"true"` - DataCenter string `description:"Data center to use. If not provided, the default agent data center is used" json:"data center,omitempty" toml:"data center,omitempty" yaml:"datacenter,omitempty" export:"true"` + DataCenter string `description:"Data center to use. If not provided, the default agent data center is used" json:"datacenter,omitempty" toml:"datacenter,omitempty" yaml:"datacenter,omitempty" export:"true"` Token string `description:"Token is used to provide a per-request ACL token which overrides the agent's default token" json:"token,omitempty" toml:"token,omitempty" yaml:"token,omitempty" export:"true"` TLS *types.ClientTLS `description:"Enable TLS support." json:"tls,omitempty" toml:"tls,omitempty" yaml:"tls,omitempty" export:"true"` HTTPAuth *EndpointHTTPAuthConfig `description:"Auth info to use for http access" json:"httpAuth,omitempty" toml:"httpAuth,omitempty" yaml:"httpAuth,omitempty" export:"true"` diff --git a/pkg/provider/kubernetes/crd/traefik/v1alpha1/middleware.go b/pkg/provider/kubernetes/crd/traefik/v1alpha1/middleware.go index f1e0213d5..2fa83438d 100644 --- a/pkg/provider/kubernetes/crd/traefik/v1alpha1/middleware.go +++ b/pkg/provider/kubernetes/crd/traefik/v1alpha1/middleware.go @@ -41,6 +41,7 @@ type MiddlewareSpec struct { Compress *dynamic.Compress `json:"compress,omitempty"` PassTLSClientCert *dynamic.PassTLSClientCert `json:"passTLSClientCert,omitempty"` Retry *dynamic.Retry `json:"retry,omitempty"` + ContentType *dynamic.ContentType `json:"contentType,omitempty"` } // +k8s:deepcopy-gen=true diff --git a/pkg/provider/kubernetes/crd/traefik/v1alpha1/zz_generated.deepcopy.go b/pkg/provider/kubernetes/crd/traefik/v1alpha1/zz_generated.deepcopy.go index c58a8e469..ed60cd8cb 100644 --- a/pkg/provider/kubernetes/crd/traefik/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/provider/kubernetes/crd/traefik/v1alpha1/zz_generated.deepcopy.go @@ -606,6 +606,11 @@ func (in *MiddlewareSpec) DeepCopyInto(out *MiddlewareSpec) { *out = new(dynamic.Retry) **out = **in } + if in.ContentType != nil { + in, out := &in.ContentType, &out.ContentType + *out = new(dynamic.ContentType) + **out = **in + } return } diff --git a/pkg/server/middleware/middlewares.go b/pkg/server/middleware/middlewares.go index 16b5fe444..c04d49065 100644 --- a/pkg/server/middleware/middlewares.go +++ b/pkg/server/middleware/middlewares.go @@ -172,6 +172,21 @@ func (b *Builder) buildConstructor(ctx context.Context, middlewareName string) ( } } + // ContentType + if config.ContentType != nil { + if middleware != nil { + return nil, badConf + } + middleware = func(next http.Handler) (http.Handler, error) { + return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { + if !config.ContentType.AutoDetect { + rw.Header()["Content-Type"] = nil + } + next.ServeHTTP(rw, req) + }), nil + } + } + // CustomErrors if config.Errors != nil { if middleware != nil { diff --git a/pkg/server/server_entrypoint_tcp.go b/pkg/server/server_entrypoint_tcp.go index db4dcb5bd..af0104eb8 100644 --- a/pkg/server/server_entrypoint_tcp.go +++ b/pkg/server/server_entrypoint_tcp.go @@ -467,6 +467,7 @@ func createHTTPServer(ctx context.Context, ln net.Listener, configuration *stati configuration.ForwardedHeaders.Insecure, configuration.ForwardedHeaders.TrustedIPs, httpSwitcher) + if err != nil { return nil, err }