Merge branch v2.1 into master

This commit is contained in:
Fernandez Ludovic 2020-01-21 18:35:31 +01:00
commit 60e247862a
77 changed files with 1128 additions and 514 deletions

View file

@ -47,6 +47,7 @@
"gocognit", "gocognit",
"bodyclose", # Too many false-positive and panics. "bodyclose", # Too many false-positive and panics.
"wsl", # Too strict "wsl", # Too strict
"gomnd", # Too strict
"stylecheck", # skip because report issues related to some generated files. "stylecheck", # skip because report issues related to some generated files.
] ]
@ -92,6 +93,15 @@
[[issues.exclude-rules]] [[issues.exclude-rules]]
path = "cmd/configuration.go" path = "cmd/configuration.go"
text = "string `traefik` has (\\d) occurrences, make it a constant" 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 [[issues.exclude-rules]] # FIXME must be fixed
path = "cmd/context.go" path = "cmd/context.go"
text = "S1000: should use a simple channel send/receive instead of `select` with a single case" text = "S1000: should use a simple channel send/receive instead of `select` with a single case"
[[issues.exclude-rules]]
path = "pkg/tracing/haystack/logger.go"
linters = ["goprintffuncname"]
[[issues.exclude-rules]]
path = "pkg/tracing/tracing.go"
text = "printf-like formatting function 'SetErrorWithEvent' should be named 'SetErrorWithEventf'"

View file

@ -1,3 +1,21 @@
## [v2.1.3](https://github.com/containous/traefik/tree/v2.1.3) (2020-01-21)
[All Commits](https://github.com/containous/traefik/compare/v2.1.2...v2.1.3)
**Bug fixes:**
- **[acme]** Update go-acme/lego to v3.3.0 ([#6192](https://github.com/containous/traefik/pull/6192) by [shilch](https://github.com/shilch))
- **[docker]** Use the calculated port when useBindPortIP is enabled ([#6199](https://github.com/containous/traefik/pull/6199) by [juliens](https://github.com/juliens))
- **[docker]** fix: invalid service definition. ([#6198](https://github.com/containous/traefik/pull/6198) by [ldez](https://github.com/ldez))
- **[server]** Remove Content-Type auto-detection ([#6097](https://github.com/containous/traefik/pull/6097) by [juliens](https://github.com/juliens))
- **[service]** fix memleak in safe.Pool ([#6140](https://github.com/containous/traefik/pull/6140) by [mpl](https://github.com/mpl))
**Documentation:**
- **[docker]** Fix typo in docker routing documentation ([#6147](https://github.com/containous/traefik/pull/6147) by [tvrg](https://github.com/tvrg))
- **[k8s]** Fixed typo in k8s doc ([#6163](https://github.com/containous/traefik/pull/6163) by [MyIgel](https://github.com/MyIgel))
- **[marathon]** Fix typo in Marathon doc. ([#6150](https://github.com/containous/traefik/pull/6150) by [thatshubham](https://github.com/thatshubham))
- **[middleware]** Adding an explanation how to use `htpasswd` for k8s secret ([#6194](https://github.com/containous/traefik/pull/6194) by [jamct](https://github.com/jamct))
- doc: adds an explanation of the global redirection pattern. ([#6195](https://github.com/containous/traefik/pull/6195) by [ldez](https://github.com/ldez))
- Fix small typo in user-guides documentation ([#6154](https://github.com/containous/traefik/pull/6154) by [evert-arias](https://github.com/evert-arias))
## [v2.1.2](https://github.com/containous/traefik/tree/v2.1.2) (2020-01-07) ## [v2.1.2](https://github.com/containous/traefik/tree/v2.1.2) (2020-01-07)
[All Commits](https://github.com/containous/traefik/compare/v2.1.1...v2.1.2) [All Commits](https://github.com/containous/traefik/compare/v2.1.1...v2.1.2)

View file

@ -1,6 +1,6 @@
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016-2018 Containous SAS Copyright (c) 2016-2020 Containous SAS
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -19,7 +19,7 @@ RUN mkdir -p /usr/local/bin \
&& chmod +x /usr/local/bin/go-bindata && chmod +x /usr/local/bin/go-bindata
# Download golangci-lint binary to bin folder in $GOPATH # Download golangci-lint binary to bin folder in $GOPATH
RUN curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | bash -s -- -b $GOPATH/bin v1.20.0 RUN curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | bash -s -- -b $GOPATH/bin v1.23.0
# Download golangci-lint and misspell binary to bin folder in $GOPATH # Download golangci-lint and misspell binary to bin folder in $GOPATH
RUN GO111MODULE=off go get github.com/client9/misspell/cmd/misspell RUN GO111MODULE=off go get github.com/client9/misspell/cmd/misspell

View file

@ -72,7 +72,7 @@ helm install ./traefik-helm-chart
{: #helm-custom-values } {: #helm-custom-values }
The values are not (yet) documented, but are self-explanatory: The values are not (yet) documented, but are self-explanatory:
you can look at the [default `values.yaml`](https://github.com/containous/traefik-helm-chart/blob/master/values.yaml) file to explore possibilities. you can look at the [default `values.yaml`](https://github.com/containous/traefik-helm-chart/blob/master/traefik/values.yaml) file to explore possibilities.
Example of installation with logging set to `DEBUG`: Example of installation with logging set to `DEBUG`:

View file

@ -285,6 +285,7 @@ For example, `CF_API_EMAIL_FILE=/run/secrets/traefik_cf-api-email` could be used
| [Azure](https://azure.microsoft.com/services/dns/) | `azure` | `AZURE_CLIENT_ID`, `AZURE_CLIENT_SECRET`, `AZURE_SUBSCRIPTION_ID`, `AZURE_TENANT_ID`, `AZURE_RESOURCE_GROUP`, `[AZURE_METADATA_ENDPOINT]` | [Additional configuration](https://go-acme.github.io/lego/dns/azure) | | [Azure](https://azure.microsoft.com/services/dns/) | `azure` | `AZURE_CLIENT_ID`, `AZURE_CLIENT_SECRET`, `AZURE_SUBSCRIPTION_ID`, `AZURE_TENANT_ID`, `AZURE_RESOURCE_GROUP`, `[AZURE_METADATA_ENDPOINT]` | [Additional configuration](https://go-acme.github.io/lego/dns/azure) |
| [Bindman](https://github.com/labbsr0x/bindman-dns-webhook) | `bindman` | `BINDMAN_MANAGER_ADDRESS` | [Additional configuration](https://go-acme.github.io/lego/dns/bindman) | | [Bindman](https://github.com/labbsr0x/bindman-dns-webhook) | `bindman` | `BINDMAN_MANAGER_ADDRESS` | [Additional configuration](https://go-acme.github.io/lego/dns/bindman) |
| [Blue Cat](https://www.bluecatnetworks.com/) | `bluecat` | `BLUECAT_SERVER_URL`, `BLUECAT_USER_NAME`, `BLUECAT_PASSWORD`, `BLUECAT_CONFIG_NAME`, `BLUECAT_DNS_VIEW` | [Additional configuration](https://go-acme.github.io/lego/dns/bluecat) | | [Blue Cat](https://www.bluecatnetworks.com/) | `bluecat` | `BLUECAT_SERVER_URL`, `BLUECAT_USER_NAME`, `BLUECAT_PASSWORD`, `BLUECAT_CONFIG_NAME`, `BLUECAT_DNS_VIEW` | [Additional configuration](https://go-acme.github.io/lego/dns/bluecat) |
| [Checkdomain](https://www.checkdomain.de/) | `checkdomain` | `CHECKDOMAIN_TOKEN`, | [Additional configuration](https://go-acme.github.io/lego/dns/checkdomain/) |
| [ClouDNS](https://www.cloudns.net/) | `cloudns` | `CLOUDNS_AUTH_ID`, `CLOUDNS_AUTH_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/cloudns) | | [ClouDNS](https://www.cloudns.net/) | `cloudns` | `CLOUDNS_AUTH_ID`, `CLOUDNS_AUTH_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/cloudns) |
| [Cloudflare](https://www.cloudflare.com) | `cloudflare` | `CF_API_EMAIL`, `CF_API_KEY` [^5] or `CF_DNS_API_TOKEN`, `[CF_ZONE_API_TOKEN]` | [Additional configuration](https://go-acme.github.io/lego/dns/cloudflare) | | [Cloudflare](https://www.cloudflare.com) | `cloudflare` | `CF_API_EMAIL`, `CF_API_KEY` [^5] or `CF_DNS_API_TOKEN`, `[CF_ZONE_API_TOKEN]` | [Additional configuration](https://go-acme.github.io/lego/dns/cloudflare) |
| [CloudXNS](https://www.cloudxns.net) | `cloudxns` | `CLOUDXNS_API_KEY`, `CLOUDXNS_SECRET_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/cloudxns) | | [CloudXNS](https://www.cloudxns.net) | `cloudxns` | `CLOUDXNS_API_KEY`, `CLOUDXNS_SECRET_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/cloudxns) |

View file

@ -90,7 +90,7 @@ The `users` option is an array of authorized users. Each user will be declared u
# Declaring the user list # Declaring the user list
# #
# Note: all dollar signs in the hash need to be doubled for escaping. # Note: all dollar signs in the hash need to be doubled for escaping.
# To create user:password pair, it's possible to use this command: # To create a user:password pair, the following command can be used:
# echo $(htpasswd -nb user password) | sed -e s/\\$/\\$\\$/g # echo $(htpasswd -nb user password) | sed -e s/\\$/\\$\\$/g
labels: labels:
- "traefik.http.middlewares.test-auth.basicauth.users=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/,test2:$$apr1$$d9hr9HBB$$4HxwgUir3HP4EsggP/QNo0" - "traefik.http.middlewares.test-auth.basicauth.users=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/,test2:$$apr1$$d9hr9HBB$$4HxwgUir3HP4EsggP/QNo0"
@ -107,6 +107,10 @@ spec:
secret: authsecret secret: authsecret
--- ---
# Note: in a kubernetes secret the string (e.g. generated by htpasswd) must be base64-encoded first.
# To create an encoded user:password pair, the following command can be used:
# htpasswd -nb user password | openssl base64
apiVersion: v1 apiVersion: v1
kind: Secret kind: Secret
metadata: metadata:

View file

@ -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.

View file

@ -184,7 +184,7 @@ Then any router can refer to an instance of the wanted middleware.
- "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0" - "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"
``` ```
## TLS Configuration Is Now Dynamic, per Router. ## TLS Configuration is Now Dynamic, per Router.
TLS parameters used to be specified in the static configuration, as an entryPoint field. TLS parameters used to be specified in the static configuration, as an entryPoint field.
With Traefik v2, a new dynamic TLS section at the root contains all the desired TLS configurations. With Traefik v2, a new dynamic TLS section at the root contains all the desired TLS configurations.
@ -322,50 +322,216 @@ Then, a [router's TLS field](../routing/routers/index.md#tls) can refer to one o
- "traefik.http.routers.router0.tls.options=myTLSOptions@file" - "traefik.http.routers.router0.tls.options=myTLSOptions@file"
``` ```
## HTTP to HTTPS Redirection Is Now Configured on Routers ## HTTP to HTTPS Redirection is Now Configured on Routers
Previously on Traefik v1, the redirection was applied on an entry point or on a frontend. Previously on Traefik v1, the redirection was applied on an entry point or on a frontend.
With Traefik v2 it is applied on a [Router](../routing/routers/index.md). With Traefik v2 it is applied on a [Router](../routing/routers/index.md).
To apply a redirection, one of the redirect middlewares, [RedirectRegex](../middlewares/redirectregex.md) or [RedirectScheme](../middlewares/redirectscheme.md), has to be configured and added to the router middlewares list. To apply a redirection, one of the redirect middlewares, [RedirectRegex](../middlewares/redirectregex.md) or [RedirectScheme](../middlewares/redirectscheme.md), has to be configured and added to the router middlewares list.
!!! example "HTTP to HTTPS redirection" !!! example "Global HTTP to HTTPS redirection"
!!! info "v1" !!! info "v1"
```toml tab="File (TOML)" ```toml tab="File (TOML)"
# static configuration # static configuration
defaultEntryPoints = ["http", "https"] defaultEntryPoints = ["web", "websecure"]
[entryPoints] [entryPoints]
[entryPoints.http] [entryPoints.web]
address = ":80" address = ":80"
[entryPoints.http.redirect] [entryPoints.web.redirect]
entryPoint = "https" entryPoint = "websecure"
[entryPoints.https] [entryPoints.websecure]
address = ":443" address = ":443"
[entryPoints.https.tls] [entryPoints.websecure.tls]
[[entryPoints.https.tls.certificates]] ```
```bash tab="CLI"
--entrypoints=Name:web Address::80 Redirect.EntryPoint:websecure
--entryPoints='Name:websecure Address::443 TLS'
```
!!! info "v2"
```yaml tab="Docker"
# ...
traefik:
image: traefik:v2.1
command:
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
- --providers.docker=true
ports:
- 80:80
- 443:443
labels:
traefik.http.routers.http_catchall.rule: HostRegexp(`{any:.+}`)
traefik.http.routers.http_catchall.entrypoints: web
traefik.http.routers.http_catchall.middlewares: https_redirect
traefik.http.middlewares.https_redirect.redirectscheme.scheme: https
traefik.http.middlewares.https_redirect.redirectscheme.permanent: true
volumes:
- /var/run/docker.sock:/var/run/docker.sock
```
```yaml tab="K8s IngressRoute"
# The entry points web (port 80) and websecure (port 443) must be defined the static configuration.
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: http_catchall
namespace: traefik
spec:
entryPoints:
- web
routes:
- match: HostRegexp(`{any:.+}`)
kind: Rule
services:
# any service in the namespace
# the service will be never called
- name: noop
port: 80
middlewares:
- name: https_redirect
# if the Middleware has distinct namespace
namespace: traefik
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: https_redirect
namespace: traefik
spec:
redirectScheme:
scheme: https
permanent: true
```
```toml tab="File (TOML)"
# traefik.toml
## static configuration
[entryPoints]
[entryPoints.web]
address = 80
[entryPoints.websecure]
address = 443
[providers.file]
directory = "/dynamic/"
##--------------------##
# /dynamic/redirect.toml
## dynamic configuration
[http.routers]
[http.routers.http_catchall]
entryPoints = ["web"]
middlewares = ["https_redirect"]
rule = "HostRegexp(`{any:.+}`)"
service = "noop"
[http.services]
# noop service, the URL will be never called
[http.services.noop.loadBalancer]
[[http.services.noop.loadBalancer.servers]]
url = "http://192.168.0.1:1337"
[http.middlewares]
[http.middlewares.https_redirect.redirectScheme]
scheme = "https"
permanent = true
```
```yaml tab="File (YAML)"
# traefik.yaml
## static configuration
entryPoints:
web:
address: 80
websecure:
address: 443
providers:
file:
directory: /dynamic/
##--------------------##
# /dynamic/redirect.yml
## dynamic configuration
http:
routers:
http_catchall:
entryPoints:
- web
middlewares:
- https_redirect
rule: "HostRegexp(`{any:.+}`)"
service: noop
services:
# noop service, the URL will be never called
noop:
loadBalancer:
servers:
- url: http://192.168.0.1:1337
middlewares:
https_redirect:
redirectScheme:
scheme: https
permanent: true
```
!!! example "HTTP to HTTPS redirection per domain"
!!! info "v1"
```toml tab="File (TOML)"
# static configuration
defaultEntryPoints = ["web", "websecure"]
[entryPoints]
[entryPoints.web]
address = ":80"
[entryPoints.web.redirect]
entryPoint = "websecure"
[entryPoints.websecure]
address = ":443"
[entryPoints.websecure.tls]
[[entryPoints.websecure.tls.certificates]]
certFile = "examples/traefik.crt" certFile = "examples/traefik.crt"
keyFile = "examples/traefik.key" keyFile = "examples/traefik.key"
``` ```
```bash tab="CLI" ```bash tab="CLI"
--entrypoints=Name:web Address::80 Redirect.EntryPoint:web-secure --entrypoints=Name:web Address::80 Redirect.EntryPoint:websecure
--entryPoints='Name:web-secure Address::443 TLS:path/to/my.cert,path/to/my.key' --entryPoints='Name:websecure Address::443 TLS:path/to/my.cert,path/to/my.key'
``` ```
!!! info "v2" !!! info "v2"
```yaml tab="Docker" ```yaml tab="Docker"
labels: labels:
- traefik.http.routers.web.rule=Host(`foo.com`) traefik.http.routers.app.rule: Host(`foo.com`)
- traefik.http.routers.web.entrypoints=web traefik.http.routers.app.entrypoints: web
- traefik.http.routers.web.middlewares=redirect@file traefik.http.routers.app.middlewares: https_redirect
- traefik.http.routers.web-secured.rule=Host(`foo.com`)
- traefik.http.routers.web-secured.entrypoints=web-secure traefik.http.routers.appsecured.rule: Host(`foo.com`)
- traefik.http.routers.web-secured.tls=true traefik.http.routers.appsecured.entrypoints: websecure
traefik.http.routers.appsecured.tls: true
traefik.http.middlewares.https_redirect.redirectscheme.scheme: https
traefik.http.middlewares.https_redirect.redirectscheme.permanent: true
``` ```
```yaml tab="K8s IngressRoute" ```yaml tab="K8s IngressRoute"
@ -384,7 +550,7 @@ To apply a redirection, one of the redirect middlewares, [RedirectRegex](../midd
- name: whoami - name: whoami
port: 80 port: 80
middlewares: middlewares:
- name: redirect - name: https_redirect
--- ---
apiVersion: traefik.containo.us/v1alpha1 apiVersion: traefik.containo.us/v1alpha1
@ -394,7 +560,7 @@ To apply a redirection, one of the redirect middlewares, [RedirectRegex](../midd
spec: spec:
entryPoints: entryPoints:
- web-secure - websecure
routes: routes:
- match: Host(`foo`) - match: Host(`foo`)
kind: Rule kind: Rule
@ -407,11 +573,11 @@ To apply a redirection, one of the redirect middlewares, [RedirectRegex](../midd
apiVersion: traefik.containo.us/v1alpha1 apiVersion: traefik.containo.us/v1alpha1
kind: Middleware kind: Middleware
metadata: metadata:
name: redirect name: https_redirect
spec: spec:
redirectScheme: redirectScheme:
scheme: https scheme: https
permanent: true
``` ```
```toml tab="File (TOML)" ```toml tab="File (TOML)"
@ -421,7 +587,7 @@ To apply a redirection, one of the redirect middlewares, [RedirectRegex](../midd
[entryPoints.web] [entryPoints.web]
address = ":80" address = ":80"
[entryPoints.web-secure] [entryPoints.websecure]
address = ":443" address = ":443"
##---------------------## ##---------------------##
@ -434,12 +600,12 @@ To apply a redirection, one of the redirect middlewares, [RedirectRegex](../midd
rule = "Host(`foo.com`)" rule = "Host(`foo.com`)"
service = "my-service" service = "my-service"
entrypoints = ["web"] entrypoints = ["web"]
middlewares = ["redirect"] middlewares = ["https_redirect"]
[http.routers.router1] [http.routers.router1]
rule = "Host(`foo.com`)" rule = "Host(`foo.com`)"
service = "my-service" service = "my-service"
entrypoints = ["web-secure"] entrypoints = ["websecure"]
[http.routers.router1.tls] [http.routers.router1.tls]
[http.services] [http.services]
@ -449,8 +615,9 @@ To apply a redirection, one of the redirect middlewares, [RedirectRegex](../midd
url = "http://10.10.10.2:80" url = "http://10.10.10.2:80"
[http.middlewares] [http.middlewares]
[http.middlewares.redirect.redirectScheme] [http.middlewares.https_redirect.redirectScheme]
scheme = "https" scheme = "https"
permanent = true
[[tls.certificates]] [[tls.certificates]]
certFile = "/path/to/domain.cert" certFile = "/path/to/domain.cert"
@ -465,7 +632,7 @@ To apply a redirection, one of the redirect middlewares, [RedirectRegex](../midd
web: web:
address: ":80" address: ":80"
web-secure: websecure:
address: ":443" address: ":443"
##---------------------## ##---------------------##
@ -480,13 +647,13 @@ To apply a redirection, one of the redirect middlewares, [RedirectRegex](../midd
entryPoints: entryPoints:
- web - web
middlewares: middlewares:
- redirect - https_redirect
service: my-service service: my-service
router1: router1:
rule: "Host(`foo.com`)" rule: "Host(`foo.com`)"
entryPoints: entryPoints:
- web-secure - websecure
service: my-service service: my-service
tls: {} tls: {}
@ -498,9 +665,10 @@ To apply a redirection, one of the redirect middlewares, [RedirectRegex](../midd
- url: http://10.10.10.2:80 - url: http://10.10.10.2:80
middlewares: middlewares:
redirect: https_redirect:
redirectScheme: redirectScheme:
scheme: https scheme: https
permanent: true
tls: tls:
certificates: certificates:
@ -512,14 +680,14 @@ To apply a redirection, one of the redirect middlewares, [RedirectRegex](../midd
With the new core notions of v2 (introduced earlier in the section With the new core notions of v2 (introduced earlier in the section
["Frontends and Backends Are Dead... Long Live Routers, Middlewares, and Services"](#frontends-and-backends-are-dead-long-live-routers-middlewares-and-services)), ["Frontends and Backends Are Dead... Long Live Routers, Middlewares, and Services"](#frontends-and-backends-are-dead-long-live-routers-middlewares-and-services)),
transforming the URL path prefix of incoming requests is configured with [middlewares](../../middlewares/overview/), transforming the URL path prefix of incoming requests is configured with [middlewares](../middlewares/overview.md),
after the routing step with [router rule `PathPrefix`](https://docs.traefik.io/v2.0/routing/routers/#rule). after the routing step with [router rule `PathPrefix`](https://docs.traefik.io/v2.0/routing/routers/#rule).
Use Case: Incoming requests to `http://company.org/admin` are forwarded to the webapplication "admin", Use Case: Incoming requests to `http://company.org/admin` are forwarded to the webapplication "admin",
with the path `/admin` stripped, e.g. to `http://<IP>:<port>/`. In this case, you must: with the path `/admin` stripped, e.g. to `http://<IP>:<port>/`. In this case, you must:
* First, configure a router named `admin` with a rule matching at least the path prefix with the `PathPrefix` keyword, * First, configure a router named `admin` with a rule matching at least the path prefix with the `PathPrefix` keyword,
* Then, define a middleware of type [`stripprefix`](../../middlewares/stripprefix/), which remove the prefix `/admin`, associated to the router `admin`. * Then, define a middleware of type [`stripprefix`](../middlewares/stripprefix.md), which removes the prefix `/admin`, associated to the router `admin`.
!!! example "Strip Path Prefix When Forwarding to Backend" !!! example "Strip Path Prefix When Forwarding to Backend"

View file

@ -12,101 +12,103 @@
- "traefik.http.middlewares.middleware03.chain.middlewares=foobar, foobar" - "traefik.http.middlewares.middleware03.chain.middlewares=foobar, foobar"
- "traefik.http.middlewares.middleware04.circuitbreaker.expression=foobar" - "traefik.http.middlewares.middleware04.circuitbreaker.expression=foobar"
- "traefik.http.middlewares.middleware05.compress=true" - "traefik.http.middlewares.middleware05.compress=true"
- "traefik.http.middlewares.middleware06.digestauth.headerfield=foobar" - "traefik.http.middlewares.middleware05.compress.excludedcontenttypes=foobar, foobar"
- "traefik.http.middlewares.middleware06.digestauth.realm=foobar" - "traefik.http.middlewares.middleware06.contenttype.autodetect=true"
- "traefik.http.middlewares.middleware06.digestauth.removeheader=true" - "traefik.http.middlewares.middleware07.digestauth.headerfield=foobar"
- "traefik.http.middlewares.middleware06.digestauth.users=foobar, foobar" - "traefik.http.middlewares.middleware07.digestauth.realm=foobar"
- "traefik.http.middlewares.middleware06.digestauth.usersfile=foobar" - "traefik.http.middlewares.middleware07.digestauth.removeheader=true"
- "traefik.http.middlewares.middleware07.errors.query=foobar" - "traefik.http.middlewares.middleware07.digestauth.users=foobar, foobar"
- "traefik.http.middlewares.middleware07.errors.service=foobar" - "traefik.http.middlewares.middleware07.digestauth.usersfile=foobar"
- "traefik.http.middlewares.middleware07.errors.status=foobar, foobar" - "traefik.http.middlewares.middleware08.errors.query=foobar"
- "traefik.http.middlewares.middleware08.forwardauth.address=foobar" - "traefik.http.middlewares.middleware08.errors.service=foobar"
- "traefik.http.middlewares.middleware08.forwardauth.authresponseheaders=foobar, foobar" - "traefik.http.middlewares.middleware08.errors.status=foobar, foobar"
- "traefik.http.middlewares.middleware08.forwardauth.tls.ca=foobar" - "traefik.http.middlewares.middleware09.forwardauth.address=foobar"
- "traefik.http.middlewares.middleware08.forwardauth.tls.caoptional=true" - "traefik.http.middlewares.middleware09.forwardauth.authresponseheaders=foobar, foobar"
- "traefik.http.middlewares.middleware08.forwardauth.tls.cert=foobar" - "traefik.http.middlewares.middleware09.forwardauth.tls.ca=foobar"
- "traefik.http.middlewares.middleware08.forwardauth.tls.insecureskipverify=true" - "traefik.http.middlewares.middleware09.forwardauth.tls.caoptional=true"
- "traefik.http.middlewares.middleware08.forwardauth.tls.key=foobar" - "traefik.http.middlewares.middleware09.forwardauth.tls.cert=foobar"
- "traefik.http.middlewares.middleware08.forwardauth.trustforwardheader=true" - "traefik.http.middlewares.middleware09.forwardauth.tls.insecureskipverify=true"
- "traefik.http.middlewares.middleware09.headers.accesscontrolallowcredentials=true" - "traefik.http.middlewares.middleware09.forwardauth.tls.key=foobar"
- "traefik.http.middlewares.middleware09.headers.accesscontrolallowheaders=foobar, foobar" - "traefik.http.middlewares.middleware09.forwardauth.trustforwardheader=true"
- "traefik.http.middlewares.middleware09.headers.accesscontrolallowmethods=foobar, foobar" - "traefik.http.middlewares.middleware10.headers.accesscontrolallowcredentials=true"
- "traefik.http.middlewares.middleware09.headers.accesscontrolalloworigin=foobar" - "traefik.http.middlewares.middleware10.headers.accesscontrolallowheaders=foobar, foobar"
- "traefik.http.middlewares.middleware09.headers.accesscontrolexposeheaders=foobar, foobar" - "traefik.http.middlewares.middleware10.headers.accesscontrolallowmethods=foobar, foobar"
- "traefik.http.middlewares.middleware09.headers.accesscontrolmaxage=42" - "traefik.http.middlewares.middleware10.headers.accesscontrolalloworigin=foobar"
- "traefik.http.middlewares.middleware09.headers.addvaryheader=true" - "traefik.http.middlewares.middleware10.headers.accesscontrolexposeheaders=foobar, foobar"
- "traefik.http.middlewares.middleware09.headers.allowedhosts=foobar, foobar" - "traefik.http.middlewares.middleware10.headers.accesscontrolmaxage=42"
- "traefik.http.middlewares.middleware09.headers.browserxssfilter=true" - "traefik.http.middlewares.middleware10.headers.addvaryheader=true"
- "traefik.http.middlewares.middleware09.headers.contentsecuritypolicy=foobar" - "traefik.http.middlewares.middleware10.headers.allowedhosts=foobar, foobar"
- "traefik.http.middlewares.middleware09.headers.contenttypenosniff=true" - "traefik.http.middlewares.middleware10.headers.browserxssfilter=true"
- "traefik.http.middlewares.middleware09.headers.custombrowserxssvalue=foobar" - "traefik.http.middlewares.middleware10.headers.contentsecuritypolicy=foobar"
- "traefik.http.middlewares.middleware09.headers.customframeoptionsvalue=foobar" - "traefik.http.middlewares.middleware10.headers.contenttypenosniff=true"
- "traefik.http.middlewares.middleware09.headers.customrequestheaders.name0=foobar" - "traefik.http.middlewares.middleware10.headers.custombrowserxssvalue=foobar"
- "traefik.http.middlewares.middleware09.headers.customrequestheaders.name1=foobar" - "traefik.http.middlewares.middleware10.headers.customframeoptionsvalue=foobar"
- "traefik.http.middlewares.middleware09.headers.customresponseheaders.name0=foobar" - "traefik.http.middlewares.middleware10.headers.customrequestheaders.name0=foobar"
- "traefik.http.middlewares.middleware09.headers.customresponseheaders.name1=foobar" - "traefik.http.middlewares.middleware10.headers.customrequestheaders.name1=foobar"
- "traefik.http.middlewares.middleware09.headers.featurepolicy=foobar" - "traefik.http.middlewares.middleware10.headers.customresponseheaders.name0=foobar"
- "traefik.http.middlewares.middleware09.headers.forcestsheader=true" - "traefik.http.middlewares.middleware10.headers.customresponseheaders.name1=foobar"
- "traefik.http.middlewares.middleware09.headers.framedeny=true" - "traefik.http.middlewares.middleware10.headers.featurepolicy=foobar"
- "traefik.http.middlewares.middleware09.headers.hostsproxyheaders=foobar, foobar" - "traefik.http.middlewares.middleware10.headers.forcestsheader=true"
- "traefik.http.middlewares.middleware09.headers.isdevelopment=true" - "traefik.http.middlewares.middleware10.headers.framedeny=true"
- "traefik.http.middlewares.middleware09.headers.publickey=foobar" - "traefik.http.middlewares.middleware10.headers.hostsproxyheaders=foobar, foobar"
- "traefik.http.middlewares.middleware09.headers.referrerpolicy=foobar" - "traefik.http.middlewares.middleware10.headers.isdevelopment=true"
- "traefik.http.middlewares.middleware09.headers.sslforcehost=true" - "traefik.http.middlewares.middleware10.headers.publickey=foobar"
- "traefik.http.middlewares.middleware09.headers.sslhost=foobar" - "traefik.http.middlewares.middleware10.headers.referrerpolicy=foobar"
- "traefik.http.middlewares.middleware09.headers.sslproxyheaders.name0=foobar" - "traefik.http.middlewares.middleware10.headers.sslforcehost=true"
- "traefik.http.middlewares.middleware09.headers.sslproxyheaders.name1=foobar" - "traefik.http.middlewares.middleware10.headers.sslhost=foobar"
- "traefik.http.middlewares.middleware09.headers.sslredirect=true" - "traefik.http.middlewares.middleware10.headers.sslproxyheaders.name0=foobar"
- "traefik.http.middlewares.middleware09.headers.ssltemporaryredirect=true" - "traefik.http.middlewares.middleware10.headers.sslproxyheaders.name1=foobar"
- "traefik.http.middlewares.middleware09.headers.stsincludesubdomains=true" - "traefik.http.middlewares.middleware10.headers.sslredirect=true"
- "traefik.http.middlewares.middleware09.headers.stspreload=true" - "traefik.http.middlewares.middleware10.headers.ssltemporaryredirect=true"
- "traefik.http.middlewares.middleware09.headers.stsseconds=42" - "traefik.http.middlewares.middleware10.headers.stsincludesubdomains=true"
- "traefik.http.middlewares.middleware10.ipwhitelist.ipstrategy.depth=42" - "traefik.http.middlewares.middleware10.headers.stspreload=true"
- "traefik.http.middlewares.middleware10.ipwhitelist.ipstrategy.excludedips=foobar, foobar" - "traefik.http.middlewares.middleware10.headers.stsseconds=42"
- "traefik.http.middlewares.middleware10.ipwhitelist.sourcerange=foobar, foobar" - "traefik.http.middlewares.middleware11.ipwhitelist.ipstrategy.depth=42"
- "traefik.http.middlewares.middleware11.inflightreq.amount=42" - "traefik.http.middlewares.middleware11.ipwhitelist.ipstrategy.excludedips=foobar, foobar"
- "traefik.http.middlewares.middleware11.inflightreq.sourcecriterion.ipstrategy.depth=42" - "traefik.http.middlewares.middleware11.ipwhitelist.sourcerange=foobar, foobar"
- "traefik.http.middlewares.middleware11.inflightreq.sourcecriterion.ipstrategy.excludedips=foobar, foobar" - "traefik.http.middlewares.middleware12.inflightreq.amount=42"
- "traefik.http.middlewares.middleware11.inflightreq.sourcecriterion.requestheadername=foobar" - "traefik.http.middlewares.middleware12.inflightreq.sourcecriterion.ipstrategy.depth=42"
- "traefik.http.middlewares.middleware11.inflightreq.sourcecriterion.requesthost=true" - "traefik.http.middlewares.middleware12.inflightreq.sourcecriterion.ipstrategy.excludedips=foobar, foobar"
- "traefik.http.middlewares.middleware12.passtlsclientcert.info.issuer.commonname=true" - "traefik.http.middlewares.middleware12.inflightreq.sourcecriterion.requestheadername=foobar"
- "traefik.http.middlewares.middleware12.passtlsclientcert.info.issuer.country=true" - "traefik.http.middlewares.middleware12.inflightreq.sourcecriterion.requesthost=true"
- "traefik.http.middlewares.middleware12.passtlsclientcert.info.issuer.domaincomponent=true" - "traefik.http.middlewares.middleware13.passtlsclientcert.info.issuer.commonname=true"
- "traefik.http.middlewares.middleware12.passtlsclientcert.info.issuer.locality=true" - "traefik.http.middlewares.middleware13.passtlsclientcert.info.issuer.country=true"
- "traefik.http.middlewares.middleware12.passtlsclientcert.info.issuer.organization=true" - "traefik.http.middlewares.middleware13.passtlsclientcert.info.issuer.domaincomponent=true"
- "traefik.http.middlewares.middleware12.passtlsclientcert.info.issuer.province=true" - "traefik.http.middlewares.middleware13.passtlsclientcert.info.issuer.locality=true"
- "traefik.http.middlewares.middleware12.passtlsclientcert.info.issuer.serialnumber=true" - "traefik.http.middlewares.middleware13.passtlsclientcert.info.issuer.organization=true"
- "traefik.http.middlewares.middleware12.passtlsclientcert.info.notafter=true" - "traefik.http.middlewares.middleware13.passtlsclientcert.info.issuer.province=true"
- "traefik.http.middlewares.middleware12.passtlsclientcert.info.notbefore=true" - "traefik.http.middlewares.middleware13.passtlsclientcert.info.issuer.serialnumber=true"
- "traefik.http.middlewares.middleware12.passtlsclientcert.info.sans=true" - "traefik.http.middlewares.middleware13.passtlsclientcert.info.notafter=true"
- "traefik.http.middlewares.middleware12.passtlsclientcert.info.subject.commonname=true" - "traefik.http.middlewares.middleware13.passtlsclientcert.info.notbefore=true"
- "traefik.http.middlewares.middleware12.passtlsclientcert.info.subject.country=true" - "traefik.http.middlewares.middleware13.passtlsclientcert.info.sans=true"
- "traefik.http.middlewares.middleware12.passtlsclientcert.info.subject.domaincomponent=true" - "traefik.http.middlewares.middleware13.passtlsclientcert.info.subject.commonname=true"
- "traefik.http.middlewares.middleware12.passtlsclientcert.info.subject.locality=true" - "traefik.http.middlewares.middleware13.passtlsclientcert.info.subject.country=true"
- "traefik.http.middlewares.middleware12.passtlsclientcert.info.subject.organization=true" - "traefik.http.middlewares.middleware13.passtlsclientcert.info.subject.domaincomponent=true"
- "traefik.http.middlewares.middleware12.passtlsclientcert.info.subject.province=true" - "traefik.http.middlewares.middleware13.passtlsclientcert.info.subject.locality=true"
- "traefik.http.middlewares.middleware12.passtlsclientcert.info.subject.serialnumber=true" - "traefik.http.middlewares.middleware13.passtlsclientcert.info.subject.organization=true"
- "traefik.http.middlewares.middleware12.passtlsclientcert.pem=true" - "traefik.http.middlewares.middleware13.passtlsclientcert.info.subject.province=true"
- "traefik.http.middlewares.middleware13.ratelimit.average=42" - "traefik.http.middlewares.middleware13.passtlsclientcert.info.subject.serialnumber=true"
- "traefik.http.middlewares.middleware13.ratelimit.period=42" - "traefik.http.middlewares.middleware13.passtlsclientcert.pem=true"
- "traefik.http.middlewares.middleware13.ratelimit.burst=42" - "traefik.http.middlewares.middleware14.ratelimit.average=42"
- "traefik.http.middlewares.middleware13.ratelimit.sourcecriterion.ipstrategy.depth=42" - "traefik.http.middlewares.middleware14.ratelimit.period=42"
- "traefik.http.middlewares.middleware13.ratelimit.sourcecriterion.ipstrategy.excludedips=foobar, foobar" - "traefik.http.middlewares.middleware14.ratelimit.burst=42"
- "traefik.http.middlewares.middleware13.ratelimit.sourcecriterion.requestheadername=foobar" - "traefik.http.middlewares.middleware14.ratelimit.sourcecriterion.ipstrategy.depth=42"
- "traefik.http.middlewares.middleware13.ratelimit.sourcecriterion.requesthost=true" - "traefik.http.middlewares.middleware14.ratelimit.sourcecriterion.ipstrategy.excludedips=foobar, foobar"
- "traefik.http.middlewares.middleware14.redirectregex.permanent=true" - "traefik.http.middlewares.middleware14.ratelimit.sourcecriterion.requestheadername=foobar"
- "traefik.http.middlewares.middleware14.redirectregex.regex=foobar" - "traefik.http.middlewares.middleware14.ratelimit.sourcecriterion.requesthost=true"
- "traefik.http.middlewares.middleware14.redirectregex.replacement=foobar" - "traefik.http.middlewares.middleware15.redirectregex.permanent=true"
- "traefik.http.middlewares.middleware15.redirectscheme.permanent=true" - "traefik.http.middlewares.middleware15.redirectregex.regex=foobar"
- "traefik.http.middlewares.middleware15.redirectscheme.port=foobar" - "traefik.http.middlewares.middleware15.redirectregex.replacement=foobar"
- "traefik.http.middlewares.middleware15.redirectscheme.scheme=foobar" - "traefik.http.middlewares.middleware16.redirectscheme.permanent=true"
- "traefik.http.middlewares.middleware16.replacepath.path=foobar" - "traefik.http.middlewares.middleware16.redirectscheme.port=foobar"
- "traefik.http.middlewares.middleware17.replacepathregex.regex=foobar" - "traefik.http.middlewares.middleware16.redirectscheme.scheme=foobar"
- "traefik.http.middlewares.middleware17.replacepathregex.replacement=foobar" - "traefik.http.middlewares.middleware17.replacepath.path=foobar"
- "traefik.http.middlewares.middleware18.retry.attempts=42" - "traefik.http.middlewares.middleware18.replacepathregex.regex=foobar"
- "traefik.http.middlewares.middleware19.stripprefix.forceslash=true" - "traefik.http.middlewares.middleware18.replacepathregex.replacement=foobar"
- "traefik.http.middlewares.middleware19.stripprefix.prefixes=foobar, foobar" - "traefik.http.middlewares.middleware19.retry.attempts=42"
- "traefik.http.middlewares.middleware20.stripprefixregex.regex=foobar, foobar" - "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.entrypoints=foobar, foobar"
- "traefik.http.routers.router0.middlewares=foobar, foobar" - "traefik.http.routers.router0.middlewares=foobar, foobar"
- "traefik.http.routers.router0.priority=42" - "traefik.http.routers.router0.priority=42"

View file

@ -113,31 +113,35 @@
expression = "foobar" expression = "foobar"
[http.middlewares.Middleware05] [http.middlewares.Middleware05]
[http.middlewares.Middleware05.compress] [http.middlewares.Middleware05.compress]
excludedContentTypes = ["foobar", "foobar"]
[http.middlewares.Middleware06] [http.middlewares.Middleware06]
[http.middlewares.Middleware06.digestAuth] [http.middlewares.Middleware06.contentType]
autoDetect = true
[http.middlewares.Middleware07]
[http.middlewares.Middleware07.digestAuth]
users = ["foobar", "foobar"] users = ["foobar", "foobar"]
usersFile = "foobar" usersFile = "foobar"
removeHeader = true removeHeader = true
realm = "foobar" realm = "foobar"
headerField = "foobar" headerField = "foobar"
[http.middlewares.Middleware07] [http.middlewares.Middleware08]
[http.middlewares.Middleware07.errors] [http.middlewares.Middleware08.errors]
status = ["foobar", "foobar"] status = ["foobar", "foobar"]
service = "foobar" service = "foobar"
query = "foobar" query = "foobar"
[http.middlewares.Middleware08] [http.middlewares.Middleware09]
[http.middlewares.Middleware08.forwardAuth] [http.middlewares.Middleware09.forwardAuth]
address = "foobar" address = "foobar"
trustForwardHeader = true trustForwardHeader = true
authResponseHeaders = ["foobar", "foobar"] authResponseHeaders = ["foobar", "foobar"]
[http.middlewares.Middleware08.forwardAuth.tls] [http.middlewares.Middleware09.forwardAuth.tls]
ca = "foobar" ca = "foobar"
caOptional = true caOptional = true
cert = "foobar" cert = "foobar"
key = "foobar" key = "foobar"
insecureSkipVerify = true insecureSkipVerify = true
[http.middlewares.Middleware09] [http.middlewares.Middleware10]
[http.middlewares.Middleware09.headers] [http.middlewares.Middleware10.headers]
accessControlAllowCredentials = true accessControlAllowCredentials = true
accessControlAllowHeaders = ["foobar", "foobar"] accessControlAllowHeaders = ["foobar", "foobar"]
accessControlAllowMethods = ["foobar", "foobar"] accessControlAllowMethods = ["foobar", "foobar"]
@ -165,39 +169,39 @@
referrerPolicy = "foobar" referrerPolicy = "foobar"
featurePolicy = "foobar" featurePolicy = "foobar"
isDevelopment = true isDevelopment = true
[http.middlewares.Middleware09.headers.customRequestHeaders] [http.middlewares.Middleware10.headers.customRequestHeaders]
name0 = "foobar" name0 = "foobar"
name1 = "foobar" name1 = "foobar"
[http.middlewares.Middleware09.headers.customResponseHeaders] [http.middlewares.Middleware10.headers.customResponseHeaders]
name0 = "foobar" name0 = "foobar"
name1 = "foobar" name1 = "foobar"
[http.middlewares.Middleware09.headers.sslProxyHeaders] [http.middlewares.Middleware10.headers.sslProxyHeaders]
name0 = "foobar" name0 = "foobar"
name1 = "foobar" name1 = "foobar"
[http.middlewares.Middleware10]
[http.middlewares.Middleware10.ipWhiteList]
sourceRange = ["foobar", "foobar"]
[http.middlewares.Middleware10.ipWhiteList.ipStrategy]
depth = 42
excludedIPs = ["foobar", "foobar"]
[http.middlewares.Middleware11] [http.middlewares.Middleware11]
[http.middlewares.Middleware11.inFlightReq] [http.middlewares.Middleware11.ipWhiteList]
amount = 42 sourceRange = ["foobar", "foobar"]
[http.middlewares.Middleware11.inFlightReq.sourceCriterion] [http.middlewares.Middleware11.ipWhiteList.ipStrategy]
requestHeaderName = "foobar"
requestHost = true
[http.middlewares.Middleware11.inFlightReq.sourceCriterion.ipStrategy]
depth = 42 depth = 42
excludedIPs = ["foobar", "foobar"] excludedIPs = ["foobar", "foobar"]
[http.middlewares.Middleware12] [http.middlewares.Middleware12]
[http.middlewares.Middleware12.passTLSClientCert] [http.middlewares.Middleware12.inFlightReq]
amount = 42
[http.middlewares.Middleware12.inFlightReq.sourceCriterion]
requestHeaderName = "foobar"
requestHost = true
[http.middlewares.Middleware12.inFlightReq.sourceCriterion.ipStrategy]
depth = 42
excludedIPs = ["foobar", "foobar"]
[http.middlewares.Middleware13]
[http.middlewares.Middleware13.passTLSClientCert]
pem = true pem = true
[http.middlewares.Middleware12.passTLSClientCert.info] [http.middlewares.Middleware13.passTLSClientCert.info]
notAfter = true notAfter = true
notBefore = true notBefore = true
sans = true sans = true
serialNumber = true serialNumber = true
[http.middlewares.Middleware12.passTLSClientCert.info.subject] [http.middlewares.Middleware13.passTLSClientCert.info.subject]
country = true country = true
province = true province = true
locality = true locality = true
@ -205,7 +209,7 @@
commonName = true commonName = true
serialNumber = true serialNumber = true
domainComponent = true domainComponent = true
[http.middlewares.Middleware12.passTLSClientCert.info.issuer] [http.middlewares.Middleware13.passTLSClientCert.info.issuer]
country = true country = true
province = true province = true
locality = true locality = true
@ -213,43 +217,43 @@
commonName = true commonName = true
serialNumber = true serialNumber = true
domainComponent = true domainComponent = true
[http.middlewares.Middleware13] [http.middlewares.Middleware14]
[http.middlewares.Middleware13.rateLimit] [http.middlewares.Middleware14.rateLimit]
average = 42 average = 42
period = 42 period = 42
burst = 42 burst = 42
[http.middlewares.Middleware13.rateLimit.sourceCriterion] [http.middlewares.Middleware14.rateLimit.sourceCriterion]
requestHeaderName = "foobar" requestHeaderName = "foobar"
requestHost = true requestHost = true
[http.middlewares.Middleware13.rateLimit.sourceCriterion.ipStrategy] [http.middlewares.Middleware14.rateLimit.sourceCriterion.ipStrategy]
depth = 42 depth = 42
excludedIPs = ["foobar", "foobar"] excludedIPs = ["foobar", "foobar"]
[http.middlewares.Middleware14] [http.middlewares.Middleware15]
[http.middlewares.Middleware14.redirectRegex] [http.middlewares.Middleware15.redirectRegex]
regex = "foobar" regex = "foobar"
replacement = "foobar" replacement = "foobar"
permanent = true permanent = true
[http.middlewares.Middleware15] [http.middlewares.Middleware16]
[http.middlewares.Middleware15.redirectScheme] [http.middlewares.Middleware16.redirectScheme]
scheme = "foobar" scheme = "foobar"
port = "foobar" port = "foobar"
permanent = true permanent = true
[http.middlewares.Middleware16]
[http.middlewares.Middleware16.replacePath]
path = "foobar"
[http.middlewares.Middleware17] [http.middlewares.Middleware17]
[http.middlewares.Middleware17.replacePathRegex] [http.middlewares.Middleware17.replacePath]
path = "foobar"
[http.middlewares.Middleware18]
[http.middlewares.Middleware18.replacePathRegex]
regex = "foobar" regex = "foobar"
replacement = "foobar" replacement = "foobar"
[http.middlewares.Middleware18]
[http.middlewares.Middleware18.retry]
attempts = 42
[http.middlewares.Middleware19] [http.middlewares.Middleware19]
[http.middlewares.Middleware19.stripPrefix] [http.middlewares.Middleware19.retry]
attempts = 42
[http.middlewares.Middleware20]
[http.middlewares.Middleware20.stripPrefix]
prefixes = ["foobar", "foobar"] prefixes = ["foobar", "foobar"]
forceSlash = true forceSlash = true
[http.middlewares.Middleware20] [http.middlewares.Middleware21]
[http.middlewares.Middleware20.stripPrefixRegex] [http.middlewares.Middleware21.stripPrefixRegex]
regex = ["foobar", "foobar"] regex = ["foobar", "foobar"]
[tcp] [tcp]
@ -323,8 +327,8 @@
minVersion = "foobar" minVersion = "foobar"
maxVersion = "foobar" maxVersion = "foobar"
cipherSuites = ["foobar", "foobar"] cipherSuites = ["foobar", "foobar"]
sniStrict = true
curvePreferences = ["foobar", "foobar"] curvePreferences = ["foobar", "foobar"]
sniStrict = true
[tls.options.Options0.clientAuth] [tls.options.Options0.clientAuth]
caFiles = ["foobar", "foobar"] caFiles = ["foobar", "foobar"]
clientAuthType = "foobar" clientAuthType = "foobar"
@ -332,8 +336,8 @@
minVersion = "foobar" minVersion = "foobar"
maxVersion = "foobar" maxVersion = "foobar"
cipherSuites = ["foobar", "foobar"] cipherSuites = ["foobar", "foobar"]
sniStrict = true
curvePreferences = ["foobar", "foobar"] curvePreferences = ["foobar", "foobar"]
sniStrict = true
[tls.options.Options1.clientAuth] [tls.options.Options1.clientAuth]
caFiles = ["foobar", "foobar"] caFiles = ["foobar", "foobar"]
clientAuthType = "foobar" clientAuthType = "foobar"

View file

@ -117,8 +117,14 @@ http:
circuitBreaker: circuitBreaker:
expression: foobar expression: foobar
Middleware05: Middleware05:
compress: {} compress:
excludedContentTypes:
- foobar
- foobar
Middleware06: Middleware06:
contentType:
autoDetect: true
Middleware07:
digestAuth: digestAuth:
users: users:
- foobar - foobar
@ -127,14 +133,14 @@ http:
removeHeader: true removeHeader: true
realm: foobar realm: foobar
headerField: foobar headerField: foobar
Middleware07: Middleware08:
errors: errors:
status: status:
- foobar - foobar
- foobar - foobar
service: foobar service: foobar
query: foobar query: foobar
Middleware08: Middleware09:
forwardAuth: forwardAuth:
address: foobar address: foobar
tls: tls:
@ -147,7 +153,7 @@ http:
authResponseHeaders: authResponseHeaders:
- foobar - foobar
- foobar - foobar
Middleware09: Middleware10:
headers: headers:
customRequestHeaders: customRequestHeaders:
name0: foobar name0: foobar
@ -195,7 +201,7 @@ http:
referrerPolicy: foobar referrerPolicy: foobar
featurePolicy: foobar featurePolicy: foobar
isDevelopment: true isDevelopment: true
Middleware10: Middleware11:
ipWhiteList: ipWhiteList:
sourceRange: sourceRange:
- foobar - foobar
@ -205,7 +211,7 @@ http:
excludedIPs: excludedIPs:
- foobar - foobar
- foobar - foobar
Middleware11: Middleware12:
inFlightReq: inFlightReq:
amount: 42 amount: 42
sourceCriterion: sourceCriterion:
@ -216,7 +222,7 @@ http:
- foobar - foobar
requestHeaderName: foobar requestHeaderName: foobar
requestHost: true requestHost: true
Middleware12: Middleware13:
passTLSClientCert: passTLSClientCert:
pem: true pem: true
info: info:
@ -240,7 +246,7 @@ http:
serialNumber: true serialNumber: true
domainComponent: true domainComponent: true
serialNumber: true serialNumber: true
Middleware13: Middleware14:
rateLimit: rateLimit:
average: 42 average: 42
period: 42 period: 42
@ -253,33 +259,33 @@ http:
- foobar - foobar
requestHeaderName: foobar requestHeaderName: foobar
requestHost: true requestHost: true
Middleware14: Middleware15:
redirectRegex: redirectRegex:
regex: foobar regex: foobar
replacement: foobar replacement: foobar
permanent: true permanent: true
Middleware15: Middleware16:
redirectScheme: redirectScheme:
scheme: foobar scheme: foobar
port: foobar port: foobar
permanent: true permanent: true
Middleware16: Middleware17:
replacePath: replacePath:
path: foobar path: foobar
Middleware17: Middleware18:
replacePathRegex: replacePathRegex:
regex: foobar regex: foobar
replacement: foobar replacement: foobar
Middleware18: Middleware19:
retry: retry:
attempts: 42 attempts: 42
Middleware19: Middleware20:
stripPrefix: stripPrefix:
prefixes: prefixes:
- foobar - foobar
- foobar - foobar
forceSlash: true forceSlash: true
Middleware20: Middleware21:
stripPrefixRegex: stripPrefixRegex:
regex: regex:
- foobar - foobar

View file

@ -12,101 +12,103 @@
"traefik.http.middlewares.middleware03.chain.middlewares": "foobar, foobar", "traefik.http.middlewares.middleware03.chain.middlewares": "foobar, foobar",
"traefik.http.middlewares.middleware04.circuitbreaker.expression": "foobar", "traefik.http.middlewares.middleware04.circuitbreaker.expression": "foobar",
"traefik.http.middlewares.middleware05.compress": "true", "traefik.http.middlewares.middleware05.compress": "true",
"traefik.http.middlewares.middleware06.digestauth.headerfield": "foobar", "traefik.http.middlewares.middleware05.compress.excludedcontenttypes": "foobar, foobar",
"traefik.http.middlewares.middleware06.digestauth.realm": "foobar", "traefik.http.middlewares.middleware06.contenttype.autodetect": "true",
"traefik.http.middlewares.middleware06.digestauth.removeheader": "true", "traefik.http.middlewares.middleware07.digestauth.headerfield": "foobar",
"traefik.http.middlewares.middleware06.digestauth.users": "foobar, foobar", "traefik.http.middlewares.middleware07.digestauth.realm": "foobar",
"traefik.http.middlewares.middleware06.digestauth.usersfile": "foobar", "traefik.http.middlewares.middleware07.digestauth.removeheader": "true",
"traefik.http.middlewares.middleware07.errors.query": "foobar", "traefik.http.middlewares.middleware07.digestauth.users": "foobar, foobar",
"traefik.http.middlewares.middleware07.errors.service": "foobar", "traefik.http.middlewares.middleware07.digestauth.usersfile": "foobar",
"traefik.http.middlewares.middleware07.errors.status": "foobar, foobar", "traefik.http.middlewares.middleware08.errors.query": "foobar",
"traefik.http.middlewares.middleware08.forwardauth.address": "foobar", "traefik.http.middlewares.middleware08.errors.service": "foobar",
"traefik.http.middlewares.middleware08.forwardauth.authresponseheaders": "foobar, foobar", "traefik.http.middlewares.middleware08.errors.status": "foobar, foobar",
"traefik.http.middlewares.middleware08.forwardauth.tls.ca": "foobar", "traefik.http.middlewares.middleware09.forwardauth.address": "foobar",
"traefik.http.middlewares.middleware08.forwardauth.tls.caoptional": "true", "traefik.http.middlewares.middleware09.forwardauth.authresponseheaders": "foobar, foobar",
"traefik.http.middlewares.middleware08.forwardauth.tls.cert": "foobar", "traefik.http.middlewares.middleware09.forwardauth.tls.ca": "foobar",
"traefik.http.middlewares.middleware08.forwardauth.tls.insecureskipverify": "true", "traefik.http.middlewares.middleware09.forwardauth.tls.caoptional": "true",
"traefik.http.middlewares.middleware08.forwardauth.tls.key": "foobar", "traefik.http.middlewares.middleware09.forwardauth.tls.cert": "foobar",
"traefik.http.middlewares.middleware08.forwardauth.trustforwardheader": "true", "traefik.http.middlewares.middleware09.forwardauth.tls.insecureskipverify": "true",
"traefik.http.middlewares.middleware09.headers.accesscontrolallowcredentials": "true", "traefik.http.middlewares.middleware09.forwardauth.tls.key": "foobar",
"traefik.http.middlewares.middleware09.headers.accesscontrolallowheaders": "foobar, foobar", "traefik.http.middlewares.middleware09.forwardauth.trustforwardheader": "true",
"traefik.http.middlewares.middleware09.headers.accesscontrolallowmethods": "foobar, foobar", "traefik.http.middlewares.middleware10.headers.accesscontrolallowcredentials": "true",
"traefik.http.middlewares.middleware09.headers.accesscontrolalloworigin": "foobar", "traefik.http.middlewares.middleware10.headers.accesscontrolallowheaders": "foobar, foobar",
"traefik.http.middlewares.middleware09.headers.accesscontrolexposeheaders": "foobar, foobar", "traefik.http.middlewares.middleware10.headers.accesscontrolallowmethods": "foobar, foobar",
"traefik.http.middlewares.middleware09.headers.accesscontrolmaxage": "42", "traefik.http.middlewares.middleware10.headers.accesscontrolalloworigin": "foobar",
"traefik.http.middlewares.middleware09.headers.addvaryheader": "true", "traefik.http.middlewares.middleware10.headers.accesscontrolexposeheaders": "foobar, foobar",
"traefik.http.middlewares.middleware09.headers.allowedhosts": "foobar, foobar", "traefik.http.middlewares.middleware10.headers.accesscontrolmaxage": "42",
"traefik.http.middlewares.middleware09.headers.browserxssfilter": "true", "traefik.http.middlewares.middleware10.headers.addvaryheader": "true",
"traefik.http.middlewares.middleware09.headers.contentsecuritypolicy": "foobar", "traefik.http.middlewares.middleware10.headers.allowedhosts": "foobar, foobar",
"traefik.http.middlewares.middleware09.headers.contenttypenosniff": "true", "traefik.http.middlewares.middleware10.headers.browserxssfilter": "true",
"traefik.http.middlewares.middleware09.headers.custombrowserxssvalue": "foobar", "traefik.http.middlewares.middleware10.headers.contentsecuritypolicy": "foobar",
"traefik.http.middlewares.middleware09.headers.customframeoptionsvalue": "foobar", "traefik.http.middlewares.middleware10.headers.contenttypenosniff": "true",
"traefik.http.middlewares.middleware09.headers.customrequestheaders.name0": "foobar", "traefik.http.middlewares.middleware10.headers.custombrowserxssvalue": "foobar",
"traefik.http.middlewares.middleware09.headers.customrequestheaders.name1": "foobar", "traefik.http.middlewares.middleware10.headers.customframeoptionsvalue": "foobar",
"traefik.http.middlewares.middleware09.headers.customresponseheaders.name0": "foobar", "traefik.http.middlewares.middleware10.headers.customrequestheaders.name0": "foobar",
"traefik.http.middlewares.middleware09.headers.customresponseheaders.name1": "foobar", "traefik.http.middlewares.middleware10.headers.customrequestheaders.name1": "foobar",
"traefik.http.middlewares.middleware09.headers.featurepolicy": "foobar", "traefik.http.middlewares.middleware10.headers.customresponseheaders.name0": "foobar",
"traefik.http.middlewares.middleware09.headers.forcestsheader": "true", "traefik.http.middlewares.middleware10.headers.customresponseheaders.name1": "foobar",
"traefik.http.middlewares.middleware09.headers.framedeny": "true", "traefik.http.middlewares.middleware10.headers.featurepolicy": "foobar",
"traefik.http.middlewares.middleware09.headers.hostsproxyheaders": "foobar, foobar", "traefik.http.middlewares.middleware10.headers.forcestsheader": "true",
"traefik.http.middlewares.middleware09.headers.isdevelopment": "true", "traefik.http.middlewares.middleware10.headers.framedeny": "true",
"traefik.http.middlewares.middleware09.headers.publickey": "foobar", "traefik.http.middlewares.middleware10.headers.hostsproxyheaders": "foobar, foobar",
"traefik.http.middlewares.middleware09.headers.referrerpolicy": "foobar", "traefik.http.middlewares.middleware10.headers.isdevelopment": "true",
"traefik.http.middlewares.middleware09.headers.sslforcehost": "true", "traefik.http.middlewares.middleware10.headers.publickey": "foobar",
"traefik.http.middlewares.middleware09.headers.sslhost": "foobar", "traefik.http.middlewares.middleware10.headers.referrerpolicy": "foobar",
"traefik.http.middlewares.middleware09.headers.sslproxyheaders.name0": "foobar", "traefik.http.middlewares.middleware10.headers.sslforcehost": "true",
"traefik.http.middlewares.middleware09.headers.sslproxyheaders.name1": "foobar", "traefik.http.middlewares.middleware10.headers.sslhost": "foobar",
"traefik.http.middlewares.middleware09.headers.sslredirect": "true", "traefik.http.middlewares.middleware10.headers.sslproxyheaders.name0": "foobar",
"traefik.http.middlewares.middleware09.headers.ssltemporaryredirect": "true", "traefik.http.middlewares.middleware10.headers.sslproxyheaders.name1": "foobar",
"traefik.http.middlewares.middleware09.headers.stsincludesubdomains": "true", "traefik.http.middlewares.middleware10.headers.sslredirect": "true",
"traefik.http.middlewares.middleware09.headers.stspreload": "true", "traefik.http.middlewares.middleware10.headers.ssltemporaryredirect": "true",
"traefik.http.middlewares.middleware09.headers.stsseconds": "42", "traefik.http.middlewares.middleware10.headers.stsincludesubdomains": "true",
"traefik.http.middlewares.middleware10.ipwhitelist.ipstrategy.depth": "42", "traefik.http.middlewares.middleware10.headers.stspreload": "true",
"traefik.http.middlewares.middleware10.ipwhitelist.ipstrategy.excludedips": "foobar, foobar", "traefik.http.middlewares.middleware10.headers.stsseconds": "42",
"traefik.http.middlewares.middleware10.ipwhitelist.sourcerange": "foobar, foobar", "traefik.http.middlewares.middleware11.ipwhitelist.ipstrategy.depth": "42",
"traefik.http.middlewares.middleware11.inflightreq.amount": "42", "traefik.http.middlewares.middleware11.ipwhitelist.ipstrategy.excludedips": "foobar, foobar",
"traefik.http.middlewares.middleware11.inflightreq.sourcecriterion.ipstrategy.depth": "42", "traefik.http.middlewares.middleware11.ipwhitelist.sourcerange": "foobar, foobar",
"traefik.http.middlewares.middleware11.inflightreq.sourcecriterion.ipstrategy.excludedips": "foobar, foobar", "traefik.http.middlewares.middleware12.inflightreq.amount": "42",
"traefik.http.middlewares.middleware11.inflightreq.sourcecriterion.requestheadername": "foobar", "traefik.http.middlewares.middleware12.inflightreq.sourcecriterion.ipstrategy.depth": "42",
"traefik.http.middlewares.middleware11.inflightreq.sourcecriterion.requesthost": "true", "traefik.http.middlewares.middleware12.inflightreq.sourcecriterion.ipstrategy.excludedips": "foobar, foobar",
"traefik.http.middlewares.middleware12.passtlsclientcert.info.issuer.commonname": "true", "traefik.http.middlewares.middleware12.inflightreq.sourcecriterion.requestheadername": "foobar",
"traefik.http.middlewares.middleware12.passtlsclientcert.info.issuer.country": "true", "traefik.http.middlewares.middleware12.inflightreq.sourcecriterion.requesthost": "true",
"traefik.http.middlewares.middleware12.passtlsclientcert.info.issuer.domaincomponent": "true", "traefik.http.middlewares.middleware13.passtlsclientcert.info.issuer.commonname": "true",
"traefik.http.middlewares.middleware12.passtlsclientcert.info.issuer.locality": "true", "traefik.http.middlewares.middleware13.passtlsclientcert.info.issuer.country": "true",
"traefik.http.middlewares.middleware12.passtlsclientcert.info.issuer.organization": "true", "traefik.http.middlewares.middleware13.passtlsclientcert.info.issuer.domaincomponent": "true",
"traefik.http.middlewares.middleware12.passtlsclientcert.info.issuer.province": "true", "traefik.http.middlewares.middleware13.passtlsclientcert.info.issuer.locality": "true",
"traefik.http.middlewares.middleware12.passtlsclientcert.info.issuer.serialnumber": "true", "traefik.http.middlewares.middleware13.passtlsclientcert.info.issuer.organization": "true",
"traefik.http.middlewares.middleware12.passtlsclientcert.info.notafter": "true", "traefik.http.middlewares.middleware13.passtlsclientcert.info.issuer.province": "true",
"traefik.http.middlewares.middleware12.passtlsclientcert.info.notbefore": "true", "traefik.http.middlewares.middleware13.passtlsclientcert.info.issuer.serialnumber": "true",
"traefik.http.middlewares.middleware12.passtlsclientcert.info.sans": "true", "traefik.http.middlewares.middleware13.passtlsclientcert.info.notafter": "true",
"traefik.http.middlewares.middleware12.passtlsclientcert.info.subject.commonname": "true", "traefik.http.middlewares.middleware13.passtlsclientcert.info.notbefore": "true",
"traefik.http.middlewares.middleware12.passtlsclientcert.info.subject.country": "true", "traefik.http.middlewares.middleware13.passtlsclientcert.info.sans": "true",
"traefik.http.middlewares.middleware12.passtlsclientcert.info.subject.domaincomponent": "true", "traefik.http.middlewares.middleware13.passtlsclientcert.info.subject.commonname": "true",
"traefik.http.middlewares.middleware12.passtlsclientcert.info.subject.locality": "true", "traefik.http.middlewares.middleware13.passtlsclientcert.info.subject.country": "true",
"traefik.http.middlewares.middleware12.passtlsclientcert.info.subject.organization": "true", "traefik.http.middlewares.middleware13.passtlsclientcert.info.subject.domaincomponent": "true",
"traefik.http.middlewares.middleware12.passtlsclientcert.info.subject.province": "true", "traefik.http.middlewares.middleware13.passtlsclientcert.info.subject.locality": "true",
"traefik.http.middlewares.middleware12.passtlsclientcert.info.subject.serialnumber": "true", "traefik.http.middlewares.middleware13.passtlsclientcert.info.subject.organization": "true",
"traefik.http.middlewares.middleware12.passtlsclientcert.pem": "true", "traefik.http.middlewares.middleware13.passtlsclientcert.info.subject.province": "true",
"traefik.http.middlewares.middleware13.ratelimit.average": "42", "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.middleware13.ratelimit.period": "42", "traefik.http.middlewares.middleware13.ratelimit.period": "42",
"traefik.http.middlewares.middleware13.ratelimit.burst": "42", "traefik.http.middlewares.middleware14.ratelimit.burst": "42",
"traefik.http.middlewares.middleware13.ratelimit.sourcecriterion.ipstrategy.depth": "42", "traefik.http.middlewares.middleware14.ratelimit.sourcecriterion.ipstrategy.depth": "42",
"traefik.http.middlewares.middleware13.ratelimit.sourcecriterion.ipstrategy.excludedips": "foobar, foobar", "traefik.http.middlewares.middleware14.ratelimit.sourcecriterion.ipstrategy.excludedips": "foobar, foobar",
"traefik.http.middlewares.middleware13.ratelimit.sourcecriterion.requestheadername": "foobar", "traefik.http.middlewares.middleware14.ratelimit.sourcecriterion.requestheadername": "foobar",
"traefik.http.middlewares.middleware13.ratelimit.sourcecriterion.requesthost": "true", "traefik.http.middlewares.middleware14.ratelimit.sourcecriterion.requesthost": "true",
"traefik.http.middlewares.middleware14.redirectregex.permanent": "true", "traefik.http.middlewares.middleware15.redirectregex.permanent": "true",
"traefik.http.middlewares.middleware14.redirectregex.regex": "foobar", "traefik.http.middlewares.middleware15.redirectregex.regex": "foobar",
"traefik.http.middlewares.middleware14.redirectregex.replacement": "foobar", "traefik.http.middlewares.middleware15.redirectregex.replacement": "foobar",
"traefik.http.middlewares.middleware15.redirectscheme.permanent": "true", "traefik.http.middlewares.middleware16.redirectscheme.permanent": "true",
"traefik.http.middlewares.middleware15.redirectscheme.port": "foobar", "traefik.http.middlewares.middleware16.redirectscheme.port": "foobar",
"traefik.http.middlewares.middleware15.redirectscheme.scheme": "foobar", "traefik.http.middlewares.middleware16.redirectscheme.scheme": "foobar",
"traefik.http.middlewares.middleware16.replacepath.path": "foobar", "traefik.http.middlewares.middleware17.replacepath.path": "foobar",
"traefik.http.middlewares.middleware17.replacepathregex.regex": "foobar", "traefik.http.middlewares.middleware18.replacepathregex.regex": "foobar",
"traefik.http.middlewares.middleware17.replacepathregex.replacement": "foobar", "traefik.http.middlewares.middleware18.replacepathregex.replacement": "foobar",
"traefik.http.middlewares.middleware18.retry.attempts": "42", "traefik.http.middlewares.middleware19.retry.attempts": "42",
"traefik.http.middlewares.middleware19.stripprefix.forceslash": "true", "traefik.http.middlewares.middleware20.stripprefix.forceslash": "true",
"traefik.http.middlewares.middleware19.stripprefix.prefixes": "foobar, foobar", "traefik.http.middlewares.middleware20.stripprefix.prefixes": "foobar, foobar",
"traefik.http.middlewares.middleware20.stripprefixregex.regex": "foobar, foobar", "traefik.http.middlewares.middleware21.stripprefixregex.regex": "foobar, foobar",
"traefik.http.routers.router0.entrypoints": "foobar, foobar", "traefik.http.routers.router0.entrypoints": "foobar, foobar",
"traefik.http.routers.router0.middlewares": "foobar, foobar", "traefik.http.routers.router0.middlewares": "foobar, foobar",
"traefik.http.routers.router0.priority": "42", "traefik.http.routers.router0.priority": "42",

View file

@ -96,7 +96,7 @@
namespaces = ["foobar", "foobar"] namespaces = ["foobar", "foobar"]
labelSelector = "foobar" labelSelector = "foobar"
ingressClass = "foobar" ingressClass = "foobar"
throttleDuration = "10s" throttleDuration = 42
[providers.rest] [providers.rest]
insecure = true insecure = true
[providers.rancher] [providers.rancher]
@ -110,25 +110,28 @@
prefix = "foobar" prefix = "foobar"
[providers.consulCatalog] [providers.consulCatalog]
constraints = "foobar" constraints = "foobar"
prefix = "traefik" prefix = "foobar"
defaultRule = "foobar" refreshInterval = 42
exposedByDefault = true
refreshInterval = 15
requireConsistent = true requireConsistent = true
stale = true stale = true
cache = true cache = true
exposedByDefault = true
defaultRule = "foobar"
[providers.consulCatalog.endpoint] [providers.consulCatalog.endpoint]
address = "foobar" address = "foobar"
scheme = "foobar" scheme = "foobar"
datacenter = "foobar" datacenter = "foobar"
token = "foobar" token = "foobar"
endpointWaitTime = "15s" endpointWaitTime = 42
[providers.consulCatalog.endpoint.tls] [providers.consulCatalog.endpoint.tls]
ca = "foobar" ca = "foobar"
caOptional = true caOptional = true
cert = "foobar" cert = "foobar"
key = "foobar" key = "foobar"
insecureSkipVerify = true insecureSkipVerify = true
[providers.consulCatalog.endpoint.httpAuth]
username = "foobar"
password = "foobar"
[providers.consul] [providers.consul]
rootKey = "traefik" rootKey = "traefik"
endpoints = ["foobar", "foobar"] endpoints = ["foobar", "foobar"]
@ -188,19 +191,19 @@
manualRouting = true manualRouting = true
[metrics.datadog] [metrics.datadog]
address = "foobar" address = "foobar"
pushInterval = "10s" pushInterval = "42s"
addEntryPointsLabels = true addEntryPointsLabels = true
addServicesLabels = true addServicesLabels = true
[metrics.statsD] [metrics.statsD]
address = "foobar" address = "foobar"
pushInterval = "10s" pushInterval = "42s"
addEntryPointsLabels = true addEntryPointsLabels = true
addServicesLabels = true addServicesLabels = true
prefix = "traefik" prefix = "foobar"
[metrics.influxDB] [metrics.influxDB]
address = "foobar" address = "foobar"
protocol = "foobar" protocol = "foobar"
pushInterval = "10s" pushInterval = "42s"
database = "foobar" database = "foobar"
retentionPolicy = "foobar" retentionPolicy = "foobar"
username = "foobar" username = "foobar"

View file

@ -88,7 +88,7 @@ providers:
- foobar - foobar
labelSelector: foobar labelSelector: foobar
ingressClass: foobar ingressClass: foobar
throttleDuration: 10s throttleDuration: 42s
ingressEndpoint: ingressEndpoint:
ip: foobar ip: foobar
hostname: foobar hostname: foobar
@ -117,25 +117,28 @@ providers:
prefix: foobar prefix: foobar
consulCatalog: consulCatalog:
constraints: foobar constraints: foobar
prefix: traefik prefix: foobar
defaultRule: foobar refreshInterval: 42s
exposedByDefault: true
refreshInterval: 15
requireConsistent: true requireConsistent: true
stale: true stale: true
cache: true cache: true
exposedByDefault: true
defaultRule: foobar
endpoint: endpoint:
address: foobar address: foobar
scheme: foobar scheme: foobar
datacenter: foobar datacenter: foobar
token: foobar token: foobar
endpointWaitTime: 15s endpointWaitTime: 42s
tls: tls:
ca: foobar ca: foobar
caOptional: true caOptional: true
cert: foobar cert: foobar
key: foobar key: foobar
insecureSkipVerify: true insecureSkipVerify: true
httpAuth:
username: foobar
password: foobar
consul: consul:
rootKey: traefik rootKey: traefik
endpoints: endpoints:
@ -211,7 +214,7 @@ metrics:
pushInterval: 42 pushInterval: 42
addEntryPointsLabels: true addEntryPointsLabels: true
addServicesLabels: true addServicesLabels: true
prefix: traefik prefix: foobar
influxDB: influxDB:
address: foobar address: foobar
protocol: foobar protocol: foobar

View file

@ -178,7 +178,7 @@ For example, to change the rule, you could add the label ```traefik.http.routers
??? info "`traefik.http.routers.<router_name>.service`" ??? info "`traefik.http.routers.<router_name>.service`"
See [rule](../routers/index.md#service) for more information. See [service](../routers/index.md#service) for more information.
```yaml ```yaml
- "traefik.http.routers.myrouter.service=myservice" - "traefik.http.routers.myrouter.service=myservice"

View file

@ -225,7 +225,7 @@ Register the `IngressRoute` kind in the Kubernetes cluster before creating `Ingr
| [11] | `tls.options` | Defines the reference to a [TLSOption](#kind-tlsoption) | | [11] | `tls.options` | Defines the reference to a [TLSOption](#kind-tlsoption) |
| [12] | `options.name` | Defines the [TLSOption](#kind-tlsoption) name | | [12] | `options.name` | Defines the [TLSOption](#kind-tlsoption) name |
| [13] | `options.namespace` | Defines the [TLSOption](#kind-tlsoption) namespace | | [13] | `options.namespace` | Defines the [TLSOption](#kind-tlsoption) namespace |
| [14] | `tls.cetResolver` | Defines the reference to a [CertResolver](../routers/index.md#certresolver) | | [14] | `tls.certResolver` | Defines the reference to a [CertResolver](../routers/index.md#certresolver) |
| [15] | `tls.domains` | List of [domains](../routers/index.md#domains) | | [15] | `tls.domains` | List of [domains](../routers/index.md#domains) |
| [16] | `domains[n].main` | Defines the main domain name | | [16] | `domains[n].main` | Defines the main domain name |
| [17] | `domains[n].sans` | List of SANs (alternative domains) | | [17] | `domains[n].sans` | List of SANs (alternative domains) |
@ -708,7 +708,7 @@ Register the `IngressRouteTCP` kind in the Kubernetes cluster before creating `I
| [11] | `tls.options` | Defines the reference to a [TLSOption](#kind-tlsoption) | | [11] | `tls.options` | Defines the reference to a [TLSOption](#kind-tlsoption) |
| [12] | `options.name` | Defines the [TLSOption](#kind-tlsoption) name | | [12] | `options.name` | Defines the [TLSOption](#kind-tlsoption) name |
| [13] | `options.namespace` | Defines the [TLSOption](#kind-tlsoption) namespace | | [13] | `options.namespace` | Defines the [TLSOption](#kind-tlsoption) namespace |
| [14] | `tls.cetResolver` | Defines the reference to a [CertResolver](../routers/index.md#certresolver_1) | | [14] | `tls.certResolver` | Defines the reference to a [CertResolver](../routers/index.md#certresolver_1) |
| [15] | `tls.domains` | List of [domains](../routers/index.md#domains_1) | | [15] | `tls.domains` | List of [domains](../routers/index.md#domains_1) |
| [16] | `domains[n].main` | Defines the main domain name | | [16] | `domains[n].main` | Defines the main domain name |
| [17] | `domains[n].sans` | List of SANs (alternative domains) | | [17] | `domains[n].sans` | List of SANs (alternative domains) |

View file

@ -1,7 +1,7 @@
# Docker-compose basic example # Docker-compose basic example
In this section we quickly go over a basic docker-compose file exposing a simple service using the docker provider. In this section we quickly go over a basic docker-compose file exposing a simple service using the docker provider.
This will also be used as a starting point for the the other docker-compose guides. This will also be used as a starting point for the other docker-compose guides.
## Setup ## Setup

View file

@ -77,7 +77,7 @@ A failing application always happens unexpectedly, and hence, it is very difficu
Failure reasons vary broadly and could stretch from unacceptable slowness, a task crash, or a network split. Failure reasons vary broadly and could stretch from unacceptable slowness, a task crash, or a network split.
There are two mitigaton efforts: There are two mitigation efforts:
1. Configure [Marathon health checks](https://mesosphere.github.io/marathon/docs/health-checks.html) on each application. 1. Configure [Marathon health checks](https://mesosphere.github.io/marathon/docs/health-checks.html) on each application.
2. Configure Traefik health checks (possibly via the `traefik.http.services.yourServiceName.loadbalancer.healthcheck.*` labels) and make sure they probe with proper frequency. 2. Configure Traefik health checks (possibly via the `traefik.http.services.yourServiceName.loadbalancer.healthcheck.*` labels) and make sure they probe with proper frequency.

View file

@ -113,6 +113,7 @@ nav:
- 'Chain': 'middlewares/chain.md' - 'Chain': 'middlewares/chain.md'
- 'CircuitBreaker': 'middlewares/circuitbreaker.md' - 'CircuitBreaker': 'middlewares/circuitbreaker.md'
- 'Compress': 'middlewares/compress.md' - 'Compress': 'middlewares/compress.md'
- 'ContentType': 'middlewares/contenttype.md'
- 'DigestAuth': 'middlewares/digestauth.md' - 'DigestAuth': 'middlewares/digestauth.md'
- 'Errors': 'middlewares/errorpages.md' - 'Errors': 'middlewares/errorpages.md'
- 'ForwardAuth': 'middlewares/forwardauth.md' - 'ForwardAuth': 'middlewares/forwardauth.md'

3
go.mod
View file

@ -39,7 +39,7 @@ require (
github.com/fatih/structs v1.1.0 github.com/fatih/structs v1.1.0
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 // indirect github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 // indirect
github.com/gambol99/go-marathon v0.0.0-20180614232016-99a156b96fb2 github.com/gambol99/go-marathon v0.0.0-20180614232016-99a156b96fb2
github.com/go-acme/lego/v3 v3.2.0 github.com/go-acme/lego/v3 v3.3.0
github.com/go-check/check v0.0.0-00010101000000-000000000000 github.com/go-check/check v0.0.0-00010101000000-000000000000
github.com/go-kit/kit v0.9.0 github.com/go-kit/kit v0.9.0
github.com/gogo/protobuf v1.3.0 // indirect github.com/gogo/protobuf v1.3.0 // indirect
@ -92,7 +92,6 @@ require (
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 // indirect golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 // indirect
golang.org/x/net v0.0.0-20191204025024-5ee1b9f4859a golang.org/x/net v0.0.0-20191204025024-5ee1b9f4859a
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 golang.org/x/time v0.0.0-20191024005414-555d28b269f0
google.golang.org/genproto v0.0.0-20190522204451-c2c4e71fbf69 // indirect
google.golang.org/grpc v1.22.1 google.golang.org/grpc v1.22.1
gopkg.in/DataDog/dd-trace-go.v1 v1.19.0 gopkg.in/DataDog/dd-trace-go.v1 v1.19.0
gopkg.in/fsnotify.v1 v1.4.7 gopkg.in/fsnotify.v1 v1.4.7

82
go.sum
View file

@ -2,8 +2,19 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0 h1:ROfEUZz+Gh5pa62DJWXSaonyu3StP6EA6lPEXPI6mCo= cloud.google.com/go v0.38.0 h1:ROfEUZz+Gh5pa62DJWXSaonyu3StP6EA6lPEXPI6mCo=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
cloud.google.com/go v0.50.0 h1:0E3eE8MX426vUOs7aHfI7aN1BrIzzzf4ccKCSfSjGmc=
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
contrib.go.opencensus.io/exporter/ocagent v0.4.12 h1:jGFvw3l57ViIVEPKKEUXPcLYIXJmQxLUh6ey1eJhwyc= contrib.go.opencensus.io/exporter/ocagent v0.4.12 h1:jGFvw3l57ViIVEPKKEUXPcLYIXJmQxLUh6ey1eJhwyc=
contrib.go.opencensus.io/exporter/ocagent v0.4.12/go.mod h1:450APlNTSR6FrvC3CTRqYosuDstRB9un7SOx2k/9ckA= contrib.go.opencensus.io/exporter/ocagent v0.4.12/go.mod h1:450APlNTSR6FrvC3CTRqYosuDstRB9un7SOx2k/9ckA=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/Azure/azure-sdk-for-go v32.4.0+incompatible h1:1JP8SKfroEakYiQU2ZyPDosh8w2Tg9UopKt88VyQPt4= github.com/Azure/azure-sdk-for-go v32.4.0+incompatible h1:1JP8SKfroEakYiQU2ZyPDosh8w2Tg9UopKt88VyQPt4=
github.com/Azure/azure-sdk-for-go v32.4.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-sdk-for-go v32.4.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8=
@ -143,8 +154,6 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:ma
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/decker502/dnspod-go v0.2.0 h1:6dwhUFCYbC5bgpebLKn7PrI43e/5mn9tpUL9YcYCdTU=
github.com/decker502/dnspod-go v0.2.0/go.mod h1:qsurYu1FgxcDwfSwXJdLt4kRsBLZeosEb9uq4Sy+08g=
github.com/dgrijalva/jwt-go v0.0.0-20160705203006-01aeca54ebda/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgrijalva/jwt-go v0.0.0-20160705203006-01aeca54ebda/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
@ -211,11 +220,12 @@ github.com/gambol99/go-marathon v0.0.0-20180614232016-99a156b96fb2 h1:df6OFl8WNX
github.com/gambol99/go-marathon v0.0.0-20180614232016-99a156b96fb2/go.mod h1:GLyXJD41gBO/NPKVPGQbhyyC06eugGy15QEZyUkE2/s= github.com/gambol99/go-marathon v0.0.0-20180614232016-99a156b96fb2/go.mod h1:GLyXJD41gBO/NPKVPGQbhyyC06eugGy15QEZyUkE2/s=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-acme/lego/v3 v3.2.0 h1:z0zvNlL1niv/1qA06V5X1BRC5PeLoGKAlVaWthXQz9c= github.com/go-acme/lego/v3 v3.3.0 h1:6BePZsOiYA4/w+M7QDytxQtMfCipMPGnWAHs9pWks98=
github.com/go-acme/lego/v3 v3.2.0/go.mod h1:074uqt+JS6plx+c9Xaiz6+L+GBb+7itGtzfcDM2AhEE= github.com/go-acme/lego/v3 v3.3.0/go.mod h1:iGSY2vQrvQs3WezicSB/oVbO2eCrD88dpWPwb1qLqu0=
github.com/go-cmd/cmd v1.0.5/go.mod h1:y8q8qlK5wQibcw63djSl/ntiHUHXHGdCkPk0j4QeW4s= github.com/go-cmd/cmd v1.0.5/go.mod h1:y8q8qlK5wQibcw63djSl/ntiHUHXHGdCkPk0j4QeW4s=
github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w= github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w=
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-ini/ini v1.44.0 h1:8+SRbfpRFlIunpSum4BEf1ClTtVjOgKzgBv9pHFkI6w= github.com/go-ini/ini v1.44.0 h1:8+SRbfpRFlIunpSum4BEf1ClTtVjOgKzgBv9pHFkI6w=
github.com/go-ini/ini v1.44.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-ini/ini v1.44.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
@ -247,6 +257,8 @@ github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4er
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0 h1:28o5sBqPkBsMGnC6b4MvE2TzSr5/AT4c/1fLqVGIwlk= github.com/golang/mock v1.2.0 h1:28o5sBqPkBsMGnC6b4MvE2TzSr5/AT4c/1fLqVGIwlk=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.1 h1:qGJ6qTW+x6xX/my+8YUVl4WNpX9B7+/l2tRsHGZ7f2s=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@ -274,6 +286,8 @@ github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@ -464,6 +478,8 @@ github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32 h1:W6apQkHrMkS0Muv8G/TipAy
github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms= github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms=
github.com/nrdcg/auroradns v1.0.0 h1:b+NpSqNG6HzMqX2ohGQe4Q/G0WQq8pduWCiZ19vdLY8= github.com/nrdcg/auroradns v1.0.0 h1:b+NpSqNG6HzMqX2ohGQe4Q/G0WQq8pduWCiZ19vdLY8=
github.com/nrdcg/auroradns v1.0.0/go.mod h1:6JPXKzIRzZzMqtTDgueIhTi6rFf1QvYE/HzqidhOhjw= github.com/nrdcg/auroradns v1.0.0/go.mod h1:6JPXKzIRzZzMqtTDgueIhTi6rFf1QvYE/HzqidhOhjw=
github.com/nrdcg/dnspod-go v0.3.0 h1:EbYggdEGFGq17Vp7sUwd9PyHZv5mMxJwX7nBPukKNoU=
github.com/nrdcg/dnspod-go v0.3.0/go.mod h1:vZSoFSFeQVm2gWLMkyX61LZ8HI3BaqtHZWgPTGKr6KQ=
github.com/nrdcg/goinwx v0.6.1 h1:AJnjoWPELyCtofhGcmzzcEMFd9YdF2JB/LgutWsWt/s= github.com/nrdcg/goinwx v0.6.1 h1:AJnjoWPELyCtofhGcmzzcEMFd9YdF2JB/LgutWsWt/s=
github.com/nrdcg/goinwx v0.6.1/go.mod h1:XPiut7enlbEdntAqalBIqcYcTEVhpv/dKWgDCX2SwKQ= github.com/nrdcg/goinwx v0.6.1/go.mod h1:XPiut7enlbEdntAqalBIqcYcTEVhpv/dKWgDCX2SwKQ=
github.com/nrdcg/namesilo v0.2.1 h1:kLjCjsufdW/IlC+iSfAqj0iQGgKjlbUUeDJio5Y6eMg= github.com/nrdcg/namesilo v0.2.1 h1:kLjCjsufdW/IlC+iSfAqj0iQGgKjlbUUeDJio5Y6eMg=
@ -549,6 +565,7 @@ github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a h1:9ZKAASQSHhD
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M= github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/sacloud/libsacloud v1.26.1 h1:td3Kd7lvpSAxxHEVpnaZ9goHmmhi0D/RfP0Rqqf/kek= github.com/sacloud/libsacloud v1.26.1 h1:td3Kd7lvpSAxxHEVpnaZ9goHmmhi0D/RfP0Rqqf/kek=
@ -642,6 +659,8 @@ go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
go.opencensus.io v0.21.0 h1:mU6zScU4U1YAFPHEHYk+3JC4SY7JxgkqS10ZOSyksNg= go.opencensus.io v0.21.0 h1:mU6zScU4U1YAFPHEHYk+3JC4SY7JxgkqS10ZOSyksNg=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.uber.org/atomic v1.3.2 h1:2Oa65PReHzfn29GpvgsYwloV9AVFHPDk8tYxt2c2tr4= go.uber.org/atomic v1.3.2 h1:2Oa65PReHzfn29GpvgsYwloV9AVFHPDk8tYxt2c2tr4=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
@ -660,23 +679,38 @@ golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnf
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc=
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392 h1:ACG4HJsFiNMf47Y4PeRoebLNy/2lXT9EtprMuTFWt1M= golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392 h1:ACG4HJsFiNMf47Y4PeRoebLNy/2lXT9EtprMuTFWt1M=
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 h1:ULYEB3JvPRE/IfO+9uO7vKV/xzVTO7XPAwm8xbf4w2g= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 h1:ULYEB3JvPRE/IfO+9uO7vKV/xzVTO7XPAwm8xbf4w2g=
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495 h1:I6A9Ag9FpEKOjcKrRNjQkPHawoXIhKyTGfvvjFAiiAk= golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495 h1:I6A9Ag9FpEKOjcKrRNjQkPHawoXIhKyTGfvvjFAiiAk=
golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
golang.org/x/exp v0.0.0-20191129062945-2f5052295587 h1:5Uz0rkjCFu9BC9gCRN7EkwVvhNyQgGWb8KNJrPwBoHY=
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/net v0.0.0-20180611182652-db08ff08e862/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180611182652-db08ff08e862/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -691,7 +725,9 @@ golang.org/x/net v0.0.0-20190206173232-65e2d4e15006/go.mod h1:mL1N/T3taQHkDXs73r
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 h1:Ao/3l156eZf2AW5wK8a7/smtodRU+gha3+BeqJ69lRk= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 h1:Ao/3l156eZf2AW5wK8a7/smtodRU+gha3+BeqJ69lRk=
@ -699,6 +735,8 @@ golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190930134127-c5a3c61f89f3 h1:6KET3Sqa7fkVfD63QnAM81ZeYg5n4HwApOJkufONnHA= golang.org/x/net v0.0.0-20190930134127-c5a3c61f89f3 h1:6KET3Sqa7fkVfD63QnAM81ZeYg5n4HwApOJkufONnHA=
golang.org/x/net v0.0.0-20190930134127-c5a3c61f89f3/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190930134127-c5a3c61f89f3/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191027093000-83d349e8ac1a h1:Yu34BogBivvmu7SAzHHaB9nZWH5D1C+z3F1jyIaYZSQ=
golang.org/x/net v0.0.0-20191027093000-83d349e8ac1a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191204025024-5ee1b9f4859a h1:+HHJiFUXVOIS9mr1ThqkQD1N8vpFCfCShqADBM12KTc= golang.org/x/net v0.0.0-20191204025024-5ee1b9f4859a h1:+HHJiFUXVOIS9mr1ThqkQD1N8vpFCfCShqADBM12KTc=
golang.org/x/net v0.0.0-20191204025024-5ee1b9f4859a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191204025024-5ee1b9f4859a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@ -712,6 +750,8 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180622082034-63fc586f45fe/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180622082034-63fc586f45fe/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -727,8 +767,12 @@ golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b h1:ag/x1USPSsqHud38I9BAC88qdNLDHHtQ4mlgQIZPPNA= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b h1:ag/x1USPSsqHud38I9BAC88qdNLDHHtQ4mlgQIZPPNA=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe h1:6fAMxZRR6sl1Uq8U61gxU+kPTs2tR8uOySCbBP7BN/M= golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe h1:6fAMxZRR6sl1Uq8U61gxU+kPTs2tR8uOySCbBP7BN/M=
@ -760,14 +804,26 @@ golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c h1:97SnQk1GYRXJgvwZ8fadnxDOWfKvkNQHH3CtZntPSrM= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c h1:97SnQk1GYRXJgvwZ8fadnxDOWfKvkNQHH3CtZntPSrM=
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135 h1:5Beo0mZN8dRzgrMMkDp0jc8YXQKx9DiJ2k1dkvGsn5A= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135 h1:5Beo0mZN8dRzgrMMkDp0jc8YXQKx9DiJ2k1dkvGsn5A=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190907020128-2ca718005c18 h1:xFbv3LvlvQAmbNJFCBKRv1Ccvnh9FVsW0FX2kTWWowE= golang.org/x/tools v0.0.0-20190907020128-2ca718005c18 h1:xFbv3LvlvQAmbNJFCBKRv1Ccvnh9FVsW0FX2kTWWowE=
golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361 h1:RIIXAeV6GvDBuADKumTODatUqANFZ+5BPMnzsy4hulY=
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 h1:/atklqdjdhuosWIl6AIbOeHJjicWYPqR9bpxqxYG2pA=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485 h1:OB/uP/Puiu5vS5QMRPrXCDWUPb+kt8f1KW8oQzFejQw= gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485 h1:OB/uP/Puiu5vS5QMRPrXCDWUPb+kt8f1KW8oQzFejQw=
gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0= gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0=
gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
@ -775,25 +831,36 @@ gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e h1:jRyg0XfpwWlhEV8mDfdNGB
gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ= gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ=
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
google.golang.org/api v0.8.0 h1:VGGbLNyPF7dvYHhcUGYBBGCRDDK0RRJAI6KCvo0CL+E= google.golang.org/api v0.8.0 h1:VGGbLNyPF7dvYHhcUGYBBGCRDDK0RRJAI6KCvo0CL+E=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.14.0 h1:uMf5uLi4eQMRrMKhCplNik4U4H8Z6C1br3zOtAa/aDE=
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c= google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873 h1:nfPFGzJkUDX6uBmpN/pSw7MbOAWegH5QDQuoXFHedLg= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873 h1:nfPFGzJkUDX6uBmpN/pSw7MbOAWegH5QDQuoXFHedLg=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190522204451-c2c4e71fbf69 h1:4rNOqY4ULrKzS6twXa619uQgI7h9PaVd4ZhjFQ7C5zs= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190522204451-c2c4e71fbf69/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1 h1:aQktFqmDE2yjveXJlVIfslDFmFnUXSqG0i6KRcJAeMc=
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
google.golang.org/grpc v1.20.1 h1:Hz2g2wirWK7H0qIIhGIqRGTuMwTE8HEKFnDZZ7lm9NU= google.golang.org/grpc v1.20.1 h1:Hz2g2wirWK7H0qIIhGIqRGTuMwTE8HEKFnDZZ7lm9NU=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.22.1 h1:/7cs52RnTJmD43s3uxzlq2U7nqVTd/37viQwMrMNlOM= google.golang.org/grpc v1.22.1 h1:/7cs52RnTJmD43s3uxzlq2U7nqVTd/37viQwMrMNlOM=
google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
gopkg.in/DataDog/dd-trace-go.v1 v1.19.0 h1:aFSFd6oDMdvPYiToGqTv7/ERA6QrPhGaXSuueRCaM88= gopkg.in/DataDog/dd-trace-go.v1 v1.19.0 h1:aFSFd6oDMdvPYiToGqTv7/ERA6QrPhGaXSuueRCaM88=
@ -802,6 +869,7 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/h2non/gock.v1 v1.0.15 h1:SzLqcIlb/fDfg7UvukMpNcWsu7sI5tWwL+KCATZqks0= gopkg.in/h2non/gock.v1 v1.0.15 h1:SzLqcIlb/fDfg7UvukMpNcWsu7sI5tWwL+KCATZqks0=
@ -845,6 +913,7 @@ honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
howett.net/plist v0.0.0-20181124034731-591f970eefbb h1:jhnBjNi9UFpfpl8YZhA9CrOqpnJdvzuiHsl/dnxl11M= howett.net/plist v0.0.0-20181124034731-591f970eefbb h1:jhnBjNi9UFpfpl8YZhA9CrOqpnJdvzuiHsl/dnxl11M=
howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0= howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0=
k8s.io/api v0.0.0-20190718183219-b59d8169aab5 h1:X3LHYU4fwu75lvvWypbppCKuhqg1KrvcZ1lLaAgmE/g= k8s.io/api v0.0.0-20190718183219-b59d8169aab5 h1:X3LHYU4fwu75lvvWypbppCKuhqg1KrvcZ1lLaAgmE/g=
@ -870,5 +939,6 @@ modernc.org/strutil v1.0.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs
modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I= modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I=
mvdan.cc/xurls/v2 v2.1.0 h1:KaMb5GLhlcSX+e+qhbRJODnUUBvlw01jt4yrjFIHAuA= mvdan.cc/xurls/v2 v2.1.0 h1:KaMb5GLhlcSX+e+qhbRJODnUUBvlw01jt4yrjFIHAuA=
mvdan.cc/xurls/v2 v2.1.0/go.mod h1:5GrSd9rOnKOpZaji1OZLYL/yeAAtGDlo/cFe+8K5n8E= mvdan.cc/xurls/v2 v2.1.0/go.mod h1:5GrSd9rOnKOpZaji1OZLYL/yeAAtGDlo/cFe+8K5n8E=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=

View file

@ -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

Binary file not shown.

View file

@ -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)) err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.StatusCodeIs(http.StatusNotFound))
c.Assert(err, checker.IsNil) 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)
}

View file

@ -37,6 +37,22 @@ type Middleware struct {
Compress *Compress `json:"compress,omitempty" toml:"compress,omitempty" yaml:"compress,omitempty" label:"allowEmpty"` Compress *Compress `json:"compress,omitempty" toml:"compress,omitempty" yaml:"compress,omitempty" label:"allowEmpty"`
PassTLSClientCert *PassTLSClientCert `json:"passTLSClientCert,omitempty" toml:"passTLSClientCert,omitempty" yaml:"passTLSClientCert,omitempty"` PassTLSClientCert *PassTLSClientCert `json:"passTLSClientCert,omitempty" toml:"passTLSClientCert,omitempty" yaml:"passTLSClientCert,omitempty"`
Retry *Retry `json:"retry,omitempty" toml:"retry,omitempty" yaml:"retry,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 // +k8s:deepcopy-gen=true

View file

@ -3,7 +3,7 @@
/* /*
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016-2019 Containous SAS Copyright (c) 2016-2020 Containous SAS
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@ -252,6 +252,22 @@ func (in Configurations) DeepCopy() Configurations {
return *out 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. // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Cookie) DeepCopyInto(out *Cookie) { func (in *Cookie) DeepCopyInto(out *Cookie) {
*out = *in *out = *in
@ -679,6 +695,11 @@ func (in *Middleware) DeepCopyInto(out *Middleware) {
*out = new(Retry) *out = new(Retry)
**out = **in **out = **in
} }
if in.ContentType != nil {
in, out := &in.ContentType, &out.ContentType
*out = new(ContentType)
**out = **in
}
return return
} }

View file

@ -54,7 +54,7 @@ type Provider struct {
type EndpointConfig struct { type EndpointConfig struct {
Address string `description:"The address of the Consul server" json:"address,omitempty" toml:"address,omitempty" yaml:"address,omitempty" export:"true"` 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"` 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"` 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"` 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"` HTTPAuth *EndpointHTTPAuthConfig `description:"Auth info to use for http access" json:"httpAuth,omitempty" toml:"httpAuth,omitempty" yaml:"httpAuth,omitempty" export:"true"`

View file

@ -89,7 +89,7 @@ func (p *Provider) buildTCPServiceConfiguration(ctx context.Context, container d
ctxSvc := log.With(ctx, log.Str(log.ServiceName, name)) ctxSvc := log.With(ctx, log.Str(log.ServiceName, name))
err := p.addServerTCP(ctxSvc, container, service.LoadBalancer) err := p.addServerTCP(ctxSvc, container, service.LoadBalancer)
if err != nil { if err != nil {
return err return fmt.Errorf("service %q error: %w", name, err)
} }
} }
@ -112,7 +112,7 @@ func (p *Provider) buildServiceConfiguration(ctx context.Context, container dock
ctxSvc := log.With(ctx, log.Str(log.ServiceName, name)) ctxSvc := log.With(ctx, log.Str(log.ServiceName, name))
err := p.addServer(ctxSvc, container, service.LoadBalancer) err := p.addServer(ctxSvc, container, service.LoadBalancer)
if err != nil { if err != nil {
return err return fmt.Errorf("service %q error: %w", name, err)
} }
} }
@ -146,10 +146,16 @@ func (p *Provider) keepContainer(ctx context.Context, container dockerData) bool
} }
func (p *Provider) addServerTCP(ctx context.Context, container dockerData, loadBalancer *dynamic.TCPServersLoadBalancer) error { func (p *Provider) addServerTCP(ctx context.Context, container dockerData, loadBalancer *dynamic.TCPServersLoadBalancer) error {
serverPort := "" if loadBalancer == nil {
if loadBalancer != nil && len(loadBalancer.Servers) > 0 { return errors.New("load-balancer is not defined")
serverPort = loadBalancer.Servers[0].Port
} }
var serverPort string
if len(loadBalancer.Servers) > 0 {
serverPort = loadBalancer.Servers[0].Port
loadBalancer.Servers[0].Port = ""
}
ip, port, err := p.getIPPort(ctx, container, serverPort) ip, port, err := p.getIPPort(ctx, container, serverPort)
if err != nil { if err != nil {
return err return err
@ -161,11 +167,6 @@ func (p *Provider) addServerTCP(ctx context.Context, container dockerData, loadB
loadBalancer.Servers = []dynamic.TCPServer{server} loadBalancer.Servers = []dynamic.TCPServer{server}
} }
if serverPort != "" {
port = serverPort
loadBalancer.Servers[0].Port = ""
}
if port == "" { if port == "" {
return errors.New("port is missing") return errors.New("port is missing")
} }
@ -175,7 +176,16 @@ func (p *Provider) addServerTCP(ctx context.Context, container dockerData, loadB
} }
func (p *Provider) addServer(ctx context.Context, container dockerData, loadBalancer *dynamic.ServersLoadBalancer) error { func (p *Provider) addServer(ctx context.Context, container dockerData, loadBalancer *dynamic.ServersLoadBalancer) error {
serverPort := getLBServerPort(loadBalancer) if loadBalancer == nil {
return errors.New("load-balancer is not defined")
}
var serverPort string
if len(loadBalancer.Servers) > 0 {
serverPort = loadBalancer.Servers[0].Port
loadBalancer.Servers[0].Port = ""
}
ip, port, err := p.getIPPort(ctx, container, serverPort) ip, port, err := p.getIPPort(ctx, container, serverPort)
if err != nil { if err != nil {
return err return err
@ -188,11 +198,6 @@ func (p *Provider) addServer(ctx context.Context, container dockerData, loadBala
loadBalancer.Servers = []dynamic.Server{server} loadBalancer.Servers = []dynamic.Server{server}
} }
if serverPort != "" {
port = serverPort
loadBalancer.Servers[0].Port = ""
}
if port == "" { if port == "" {
return errors.New("port is missing") return errors.New("port is missing")
} }
@ -294,13 +299,6 @@ func (p *Provider) getPortBinding(container dockerData, serverPort string) (*nat
return nil, fmt.Errorf("unable to find the external IP:Port for the container %q", container.Name) return nil, fmt.Errorf("unable to find the external IP:Port for the container %q", container.Name)
} }
func getLBServerPort(loadBalancer *dynamic.ServersLoadBalancer) string {
if loadBalancer != nil && len(loadBalancer.Servers) > 0 {
return loadBalancer.Servers[0].Port
}
return ""
}
func getPort(container dockerData, serverPort string) string { func getPort(container dockerData, serverPort string) string {
if len(serverPort) > 0 { if len(serverPort) > 0 {
return serverPort return serverPort

View file

@ -341,9 +341,78 @@ func Test_buildConfiguration(t *testing.T) {
testCases := []struct { testCases := []struct {
desc string desc string
containers []dockerData containers []dockerData
useBindPortIP bool
constraints string constraints string
expected *dynamic.Configuration expected *dynamic.Configuration
}{ }{
{
desc: "invalid HTTP service definition",
containers: []dockerData{
{
ServiceName: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.http.services.test": "",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
Name: "bridge",
Addr: "127.0.0.1",
},
},
},
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Services: map[string]*dynamic.TCPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{},
},
},
},
{
desc: "invalid TCP service definition",
containers: []dockerData{
{
ServiceName: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.tcp.services.test": "",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{},
},
Networks: map[string]*networkData{
"bridge": {
Name: "bridge",
Addr: "127.0.0.1",
},
},
},
},
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Services: map[string]*dynamic.TCPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{},
},
},
},
{ {
desc: "one container no label", desc: "one container no label",
containers: []dockerData{ containers: []dockerData{
@ -2447,6 +2516,64 @@ func Test_buildConfiguration(t *testing.T) {
}, },
}, },
}, },
{
desc: "useBindPortIP with LblPort | ExtIp:ExtPort:LblPort => ExtIp:ExtPort",
containers: []dockerData{
{
ServiceName: "Test",
Name: "Test",
Labels: map[string]string{
"traefik.http.services.Test.loadbalancer.server.port": "80",
},
NetworkSettings: networkSettings{
Ports: nat.PortMap{
nat.Port("79/tcp"): []nat.PortBinding{{
HostIP: "192.168.0.1",
HostPort: "8080",
}},
nat.Port("80/tcp"): []nat.PortBinding{{
HostIP: "192.168.0.1",
HostPort: "8081",
}},
},
Networks: map[string]*networkData{
"bridge": {
Name: "bridge",
Addr: "127.0.0.1",
},
},
},
},
},
useBindPortIP: true,
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Services: map[string]*dynamic.TCPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"Test": {
Service: "Test",
Rule: "Host(`Test.traefik.wtf`)",
},
},
Middlewares: map[string]*dynamic.Middleware{},
Services: map[string]*dynamic.Service{
"Test": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "http://192.168.0.1:8081",
},
},
PassHostHeader: Bool(true),
},
},
},
},
},
},
} }
for _, test := range testCases { for _, test := range testCases {
@ -2458,6 +2585,7 @@ func Test_buildConfiguration(t *testing.T) {
p := Provider{ p := Provider{
ExposedByDefault: true, ExposedByDefault: true,
DefaultRule: "Host(`{{ normalize .Name }}.traefik.wtf`)", DefaultRule: "Host(`{{ normalize .Name }}.traefik.wtf`)",
UseBindPortIP: test.useBindPortIP,
} }
p.Constraints = test.constraints p.Constraints = test.constraints

View file

@ -1,7 +1,7 @@
/* /*
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016-2019 Containous SAS Copyright (c) 2016-2020 Containous SAS
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -1,7 +1,7 @@
/* /*
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016-2019 Containous SAS Copyright (c) 2016-2020 Containous SAS
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -1,7 +1,7 @@
/* /*
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016-2019 Containous SAS Copyright (c) 2016-2020 Containous SAS
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -1,7 +1,7 @@
/* /*
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016-2019 Containous SAS Copyright (c) 2016-2020 Containous SAS
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -1,7 +1,7 @@
/* /*
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016-2019 Containous SAS Copyright (c) 2016-2020 Containous SAS
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -1,7 +1,7 @@
/* /*
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016-2019 Containous SAS Copyright (c) 2016-2020 Containous SAS
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -1,7 +1,7 @@
/* /*
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016-2019 Containous SAS Copyright (c) 2016-2020 Containous SAS
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -1,7 +1,7 @@
/* /*
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016-2019 Containous SAS Copyright (c) 2016-2020 Containous SAS
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -1,7 +1,7 @@
/* /*
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016-2019 Containous SAS Copyright (c) 2016-2020 Containous SAS
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -1,7 +1,7 @@
/* /*
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016-2019 Containous SAS Copyright (c) 2016-2020 Containous SAS
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -1,7 +1,7 @@
/* /*
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016-2019 Containous SAS Copyright (c) 2016-2020 Containous SAS
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -1,7 +1,7 @@
/* /*
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016-2019 Containous SAS Copyright (c) 2016-2020 Containous SAS
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -1,7 +1,7 @@
/* /*
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016-2019 Containous SAS Copyright (c) 2016-2020 Containous SAS
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -1,7 +1,7 @@
/* /*
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016-2019 Containous SAS Copyright (c) 2016-2020 Containous SAS
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -1,7 +1,7 @@
/* /*
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016-2019 Containous SAS Copyright (c) 2016-2020 Containous SAS
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -1,7 +1,7 @@
/* /*
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016-2019 Containous SAS Copyright (c) 2016-2020 Containous SAS
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -1,7 +1,7 @@
/* /*
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016-2019 Containous SAS Copyright (c) 2016-2020 Containous SAS
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -1,7 +1,7 @@
/* /*
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016-2019 Containous SAS Copyright (c) 2016-2020 Containous SAS
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -1,7 +1,7 @@
/* /*
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016-2019 Containous SAS Copyright (c) 2016-2020 Containous SAS
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -1,7 +1,7 @@
/* /*
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016-2019 Containous SAS Copyright (c) 2016-2020 Containous SAS
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -1,7 +1,7 @@
/* /*
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016-2019 Containous SAS Copyright (c) 2016-2020 Containous SAS
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -1,7 +1,7 @@
/* /*
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016-2019 Containous SAS Copyright (c) 2016-2020 Containous SAS
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -1,7 +1,7 @@
/* /*
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016-2019 Containous SAS Copyright (c) 2016-2020 Containous SAS
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -1,7 +1,7 @@
/* /*
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016-2019 Containous SAS Copyright (c) 2016-2020 Containous SAS
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -1,7 +1,7 @@
/* /*
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016-2019 Containous SAS Copyright (c) 2016-2020 Containous SAS
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -1,7 +1,7 @@
/* /*
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016-2019 Containous SAS Copyright (c) 2016-2020 Containous SAS
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -1,7 +1,7 @@
/* /*
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016-2019 Containous SAS Copyright (c) 2016-2020 Containous SAS
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -1,7 +1,7 @@
/* /*
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016-2019 Containous SAS Copyright (c) 2016-2020 Containous SAS
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -1,7 +1,7 @@
/* /*
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016-2019 Containous SAS Copyright (c) 2016-2020 Containous SAS
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -1,7 +1,7 @@
/* /*
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016-2019 Containous SAS Copyright (c) 2016-2020 Containous SAS
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -1,7 +1,7 @@
/* /*
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016-2019 Containous SAS Copyright (c) 2016-2020 Containous SAS
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -1,7 +1,7 @@
/* /*
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016-2019 Containous SAS Copyright (c) 2016-2020 Containous SAS
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -1,7 +1,7 @@
/* /*
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016-2019 Containous SAS Copyright (c) 2016-2020 Containous SAS
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -1,7 +1,7 @@
/* /*
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016-2019 Containous SAS Copyright (c) 2016-2020 Containous SAS
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -1,7 +1,7 @@
/* /*
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016-2019 Containous SAS Copyright (c) 2016-2020 Containous SAS
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -1,7 +1,7 @@
/* /*
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016-2019 Containous SAS Copyright (c) 2016-2020 Containous SAS
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -1,7 +1,7 @@
/* /*
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016-2019 Containous SAS Copyright (c) 2016-2020 Containous SAS
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -1,7 +1,7 @@
/* /*
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016-2019 Containous SAS Copyright (c) 2016-2020 Containous SAS
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -41,6 +41,7 @@ type MiddlewareSpec struct {
Compress *dynamic.Compress `json:"compress,omitempty"` Compress *dynamic.Compress `json:"compress,omitempty"`
PassTLSClientCert *dynamic.PassTLSClientCert `json:"passTLSClientCert,omitempty"` PassTLSClientCert *dynamic.PassTLSClientCert `json:"passTLSClientCert,omitempty"`
Retry *dynamic.Retry `json:"retry,omitempty"` Retry *dynamic.Retry `json:"retry,omitempty"`
ContentType *dynamic.ContentType `json:"contentType,omitempty"`
} }
// +k8s:deepcopy-gen=true // +k8s:deepcopy-gen=true

View file

@ -3,7 +3,7 @@
/* /*
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016-2019 Containous SAS Copyright (c) 2016-2020 Containous SAS
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@ -606,6 +606,11 @@ func (in *MiddlewareSpec) DeepCopyInto(out *MiddlewareSpec) {
*out = new(dynamic.Retry) *out = new(dynamic.Retry)
**out = **in **out = **in
} }
if in.ContentType != nil {
in, out := &in.ContentType, &out.ContentType
*out = new(dynamic.ContentType)
**out = **in
}
return return
} }

View file

@ -20,7 +20,6 @@ type routineCtx func(ctx context.Context)
// Pool is a pool of go routines // Pool is a pool of go routines
type Pool struct { type Pool struct {
routines []routine routines []routine
routinesCtx []routineCtx
waitGroup sync.WaitGroup waitGroup sync.WaitGroup
lock sync.Mutex lock sync.Mutex
baseCtx context.Context baseCtx context.Context
@ -46,17 +45,9 @@ func (p *Pool) Ctx() context.Context {
return p.baseCtx return p.baseCtx
} }
// AddGoCtx adds a recoverable goroutine with a context without starting it
func (p *Pool) AddGoCtx(goroutine routineCtx) {
p.lock.Lock()
p.routinesCtx = append(p.routinesCtx, goroutine)
p.lock.Unlock()
}
// GoCtx starts a recoverable goroutine with a context // GoCtx starts a recoverable goroutine with a context
func (p *Pool) GoCtx(goroutine routineCtx) { func (p *Pool) GoCtx(goroutine routineCtx) {
p.lock.Lock() p.lock.Lock()
p.routinesCtx = append(p.routinesCtx, goroutine)
p.waitGroup.Add(1) p.waitGroup.Add(1)
Go(func() { Go(func() {
defer p.waitGroup.Done() defer p.waitGroup.Done()
@ -65,17 +56,6 @@ func (p *Pool) GoCtx(goroutine routineCtx) {
p.lock.Unlock() p.lock.Unlock()
} }
// addGo adds a recoverable goroutine, and can be stopped with stop chan
func (p *Pool) addGo(goroutine func(stop chan bool)) {
p.lock.Lock()
newRoutine := routine{
goroutine: goroutine,
stop: make(chan bool, 1),
}
p.routines = append(p.routines, newRoutine)
p.lock.Unlock()
}
// Go starts a recoverable goroutine, and can be stopped with stop chan // Go starts a recoverable goroutine, and can be stopped with stop chan
func (p *Pool) Go(goroutine func(stop chan bool)) { func (p *Pool) Go(goroutine func(stop chan bool)) {
p.lock.Lock() p.lock.Lock()
@ -114,29 +94,6 @@ func (p *Pool) Cleanup() {
p.baseCancel() p.baseCancel()
} }
// Start starts all stopped routines
func (p *Pool) Start() {
p.lock.Lock()
defer p.lock.Unlock()
p.ctx, p.cancel = context.WithCancel(p.baseCtx)
for i := range p.routines {
p.waitGroup.Add(1)
p.routines[i].stop = make(chan bool, 1)
Go(func() {
defer p.waitGroup.Done()
p.routines[i].goroutine(p.routines[i].stop)
})
}
for _, routine := range p.routinesCtx {
p.waitGroup.Add(1)
Go(func() {
defer p.waitGroup.Done()
routine(p.ctx)
})
}
}
// Go starts a recoverable goroutine // Go starts a recoverable goroutine
func Go(goroutine func()) { func Go(goroutine func()) {
GoWithRecover(goroutine, defaultRecoverGoroutine) GoWithRecover(goroutine, defaultRecoverGoroutine)

View file

@ -67,13 +67,6 @@ func TestPoolWithCtx(t *testing.T) {
p.GoCtx(testRoutine.routineCtx) p.GoCtx(testRoutine.routineCtx)
}, },
}, },
{
desc: "AddGoCtx()",
fn: func(p *Pool) {
p.AddGoCtx(testRoutine.routineCtx)
p.Start()
},
},
} }
for _, test := range testCases { for _, test := range testCases {
@ -87,9 +80,6 @@ func TestPoolWithCtx(t *testing.T) {
test.fn(p) test.fn(p)
defer p.Cleanup() defer p.Cleanup()
if len(p.routinesCtx) != 1 {
t.Fatalf("After %s, Pool did have %d goroutineCtxs, expected 1", test.desc, len(p.routinesCtx))
}
testDone := make(chan bool, 1) testDone := make(chan bool, 1)
go func() { go func() {
@ -140,40 +130,6 @@ func TestPoolWithStopChan(t *testing.T) {
} }
} }
func TestPoolStartWithStopChan(t *testing.T) {
testRoutine := newFakeRoutine()
p := NewPool(context.Background())
timer := time.NewTimer(500 * time.Millisecond)
defer timer.Stop()
// Insert the stopped test goroutine via private fields into the Pool.
// There currently is no way to insert a routine via exported funcs that is not started immediately.
p.lock.Lock()
newRoutine := routine{
goroutine: testRoutine.routine,
}
p.routines = append(p.routines, newRoutine)
p.lock.Unlock()
p.Start()
testDone := make(chan bool, 1)
go func() {
<-testRoutine.startSig
p.Cleanup()
testDone <- true
}()
select {
case <-timer.C:
testRoutine.Lock()
defer testRoutine.Unlock()
t.Fatalf("Pool.Start() did not complete in time, goroutine started equals '%t'", testRoutine.started)
case <-testDone:
return
}
}
func TestPoolCleanupWithGoPanicking(t *testing.T) { func TestPoolCleanupWithGoPanicking(t *testing.T) {
testRoutine := func(stop chan bool) { testRoutine := func(stop chan bool) {
panic("BOOM") panic("BOOM")
@ -193,26 +149,12 @@ func TestPoolCleanupWithGoPanicking(t *testing.T) {
p.Go(testRoutine) p.Go(testRoutine)
}, },
}, },
{
desc: "addGo() and Start()",
fn: func(p *Pool) {
p.addGo(testRoutine)
p.Start()
},
},
{ {
desc: "GoCtx()", desc: "GoCtx()",
fn: func(p *Pool) { fn: func(p *Pool) {
p.GoCtx(testCtxRoutine) p.GoCtx(testCtxRoutine)
}, },
}, },
{
desc: "AddGoCtx() and Start()",
fn: func(p *Pool) {
p.AddGoCtx(testCtxRoutine)
p.Start()
},
},
} }
for _, test := range testCases { for _, test := range testCases {

View file

@ -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 // CustomErrors
if config.Errors != nil { if config.Errors != nil {
if middleware != nil { if middleware != nil {

View file

@ -467,6 +467,7 @@ func createHTTPServer(ctx context.Context, ln net.Listener, configuration *stati
configuration.ForwardedHeaders.Insecure, configuration.ForwardedHeaders.Insecure,
configuration.ForwardedHeaders.TrustedIPs, configuration.ForwardedHeaders.TrustedIPs,
httpSwitcher) httpSwitcher)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -100,7 +100,7 @@ type blackholeResponseWriter struct{}
func (b blackholeResponseWriter) Flush() {} func (b blackholeResponseWriter) Flush() {}
func (b blackholeResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) { func (b blackholeResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
return nil, nil, errors.New("you can hijack connection on blackholeResponseWriter") return nil, nil, errors.New("connection on blackholeResponseWriter cannot be hijacked")
} }
func (b blackholeResponseWriter) Header() http.Header { func (b blackholeResponseWriter) Header() http.Header {

View file

@ -3,7 +3,7 @@
/* /*
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016-2019 Containous SAS Copyright (c) 2016-2020 Containous SAS
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -3,7 +3,7 @@
/* /*
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016-2019 Containous SAS Copyright (c) 2016-2020 Containous SAS
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal