mirror of
https://github.com/containous/traefik.git
synced 2025-11-01 00:23:52 +03:00
Compare commits
77 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
998868450f | ||
|
|
ffd82c92cb | ||
|
|
34d7091f31 | ||
|
|
b04759a80b | ||
|
|
8441c476f1 | ||
|
|
4ff8eca572 | ||
|
|
1986610363 | ||
|
|
5cc2a8344c | ||
|
|
fc5359b6f6 | ||
|
|
c5d448fba9 | ||
|
|
c820d18ada | ||
|
|
19a2e2efc5 | ||
|
|
bcdb70b689 | ||
|
|
9896192efb | ||
|
|
c6daab54e3 | ||
|
|
a59bcb29b5 | ||
|
|
50931813f2 | ||
|
|
5ef853a0c5 | ||
|
|
b2b4b66b08 | ||
|
|
27326e6569 | ||
|
|
7ca90a4b18 | ||
|
|
a3685ee9fa | ||
|
|
8ae0379171 | ||
|
|
b0d8e08e2b | ||
|
|
ae79d4e5f0 | ||
|
|
bfcef58a4f | ||
|
|
f7a6f32784 | ||
|
|
92f798dfcd | ||
|
|
f174014d96 | ||
|
|
cd16321dd9 | ||
|
|
5f35c88805 | ||
|
|
23c7c78a1a | ||
|
|
08d5dfee01 | ||
|
|
b669981018 | ||
|
|
aa5f2b92d4 | ||
|
|
6b9738e675 | ||
|
|
b82290ac5b | ||
|
|
49b598d087 | ||
|
|
448785d830 | ||
|
|
9bc71b0010 | ||
|
|
160edff257 | ||
|
|
8816cb86a4 | ||
|
|
316be0782c | ||
|
|
14da838a21 | ||
|
|
a75b2384ea | ||
|
|
8bdca45861 | ||
|
|
7442162e3f | ||
|
|
dd5cb68cb1 | ||
|
|
299a16f0a4 | ||
|
|
545f2feacc | ||
|
|
e3caaf0791 | ||
|
|
f794f8a294 | ||
|
|
8cf22207b5 | ||
|
|
b7be71c02a | ||
|
|
6e9d713668 | ||
|
|
ddb32ef86f | ||
|
|
2087e11f55 | ||
|
|
a5d46fc6ef | ||
|
|
84742275a4 | ||
|
|
54a2d657f3 | ||
|
|
08b90ade94 | ||
|
|
8ba99adc50 | ||
|
|
b02946147d | ||
|
|
137c632793 | ||
|
|
e76b65f44d | ||
|
|
55ebaee4a7 | ||
|
|
4ff76e13c4 | ||
|
|
14e400bcd0 | ||
|
|
7cfd10db62 | ||
|
|
9d8a42111f | ||
|
|
0dfd12ee61 | ||
|
|
a3fd484728 | ||
|
|
f196de90e1 | ||
|
|
c2a294c872 | ||
|
|
8e5d4c6ae9 | ||
|
|
eb07a5ca1a | ||
|
|
84e20aa9c3 |
4
.github/workflows/build.yaml
vendored
4
.github/workflows/build.yaml
vendored
@@ -10,7 +10,7 @@ on:
|
||||
- 'script/gcg/**'
|
||||
|
||||
env:
|
||||
GO_VERSION: '1.23'
|
||||
GO_VERSION: '1.24'
|
||||
CGO_ENABLED: 0
|
||||
|
||||
jobs:
|
||||
@@ -51,7 +51,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
|
||||
2
.github/workflows/check_doc.yml
vendored
2
.github/workflows/check_doc.yml
vendored
@@ -13,7 +13,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
|
||||
2
.github/workflows/codeql.yml
vendored
2
.github/workflows/codeql.yml
vendored
@@ -28,7 +28,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: setup go
|
||||
uses: actions/setup-go@v5
|
||||
|
||||
9
.github/workflows/documentation.yml
vendored
9
.github/workflows/documentation.yml
vendored
@@ -1,6 +1,7 @@
|
||||
name: Build and Publish Documentation
|
||||
|
||||
on:
|
||||
workflow_dispatch: {}
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
@@ -19,7 +20,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -39,9 +40,9 @@ jobs:
|
||||
run: curl -sSfL https://raw.githubusercontent.com/traefik/mixtus/master/godownloader.sh | sh -s -- -b $HOME/bin ${MIXTUS_VERSION}
|
||||
|
||||
- name: Build documentation
|
||||
run: $HOME/bin/structor -o traefik -r traefik --dockerfile-url="https://raw.githubusercontent.com/traefik/traefik/v1.7/docs.Dockerfile" --menu.js-url="https://raw.githubusercontent.com/traefik/structor/master/traefik-menu.js.gotmpl" --rqts-url="https://raw.githubusercontent.com/traefik/structor/master/requirements-override.txt" --force-edit-url --exp-branch=master --debug
|
||||
env:
|
||||
STRUCTOR_LATEST_TAG: ${{ vars.STRUCTOR_LATEST_TAG }}
|
||||
run: |
|
||||
STRUCTOR_LATEST_TAG=$(curl -s https://api.github.com/repos/traefik/traefik/releases/latest | jq -r '.tag_name')
|
||||
$HOME/bin/structor -o traefik -r traefik --dockerfile-url="https://raw.githubusercontent.com/traefik/traefik/v1.7/docs.Dockerfile" --menu.js-url="https://raw.githubusercontent.com/traefik/structor/master/traefik-menu.js.gotmpl" --rqts-url="https://raw.githubusercontent.com/traefik/structor/master/requirements-override.txt" --force-edit-url --exp-branch=master --debug
|
||||
|
||||
- name: Apply seo
|
||||
run: $HOME/bin/seo -path=./site -product=traefik
|
||||
|
||||
4
.github/workflows/experimental.yaml
vendored
4
.github/workflows/experimental.yaml
vendored
@@ -7,7 +7,7 @@ on:
|
||||
- v*
|
||||
|
||||
env:
|
||||
GO_VERSION: '1.23'
|
||||
GO_VERSION: '1.24'
|
||||
CGO_ENABLED: 0
|
||||
|
||||
jobs:
|
||||
@@ -23,7 +23,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
|
||||
10
.github/workflows/release.yaml
vendored
10
.github/workflows/release.yaml
vendored
@@ -6,7 +6,7 @@ on:
|
||||
- 'v*.*.*'
|
||||
|
||||
env:
|
||||
GO_VERSION: '1.23'
|
||||
GO_VERSION: '1.24'
|
||||
CGO_ENABLED: 0
|
||||
VERSION: ${{ github.ref_name }}
|
||||
TRAEFIKER_EMAIL: "traefiker@traefik.io"
|
||||
@@ -30,7 +30,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -89,7 +89,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -126,13 +126,11 @@ jobs:
|
||||
tar cfz "dist/traefik-${VERSION}.src.tar.gz" \
|
||||
--exclude-vcs \
|
||||
--exclude .idea \
|
||||
--exclude .travis \
|
||||
--exclude .semaphoreci \
|
||||
--exclude .github \
|
||||
--exclude dist .
|
||||
|
||||
chown -R "$(id -u)":"$(id -g)" dist/
|
||||
gh release create ${VERSION} ./dist/**/traefik*.{zip,tar.gz} ./dist/traefik*.{tar.gz,txt} --repo traefik/traefik --title ${VERSION} --notes ${VERSION}
|
||||
gh release create ${VERSION} ./dist/**/traefik*.{zip,tar.gz} ./dist/traefik*.{tar.gz,txt} --repo traefik/traefik --title ${VERSION} --notes ${VERSION} --latest=false
|
||||
|
||||
./script/deploy.sh
|
||||
|
||||
|
||||
2
.github/workflows/template-webui.yaml
vendored
2
.github/workflows/template-webui.yaml
vendored
@@ -8,7 +8,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
|
||||
39
.github/workflows/test-integration.yaml
vendored
39
.github/workflows/test-integration.yaml
vendored
@@ -10,7 +10,7 @@ on:
|
||||
- 'script/gcg/**'
|
||||
|
||||
env:
|
||||
GO_VERSION: '1.23'
|
||||
GO_VERSION: '1.24'
|
||||
CGO_ENABLED: 0
|
||||
|
||||
jobs:
|
||||
@@ -20,7 +20,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -34,7 +34,21 @@ jobs:
|
||||
run: touch webui/static/index.html
|
||||
|
||||
- name: Build binary
|
||||
run: make binary
|
||||
run: make binary-linux-amd64
|
||||
|
||||
- name: Save go cache build
|
||||
uses: actions/cache/save@v4
|
||||
with:
|
||||
path: |
|
||||
~/.cache/go-build
|
||||
key: ${{ runner.os }}-go-build-cache-${{ env.GO_VERSION }}-${{ hashFiles('**/go.sum') }}
|
||||
|
||||
- name: Artifact traefik binary
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: traefik
|
||||
path: ./dist/linux/amd64/traefik
|
||||
retention-days: 1
|
||||
|
||||
test-integration:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -48,7 +62,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -61,8 +75,21 @@ jobs:
|
||||
- name: Avoid generating webui
|
||||
run: touch webui/static/index.html
|
||||
|
||||
- name: Build binary
|
||||
run: make binary
|
||||
- name: Download traefik binary
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: traefik
|
||||
path: ./dist/linux/amd64/
|
||||
|
||||
- name: Make binary executable
|
||||
run: chmod +x ./dist/linux/amd64/traefik
|
||||
|
||||
- name: Restore go cache build
|
||||
uses: actions/cache/restore@v4
|
||||
with:
|
||||
path: |
|
||||
~/.cache/go-build
|
||||
key: ${{ runner.os }}-go-build-cache-${{ env.GO_VERSION }}-${{ hashFiles('**/go.sum') }}
|
||||
|
||||
- name: Generate go test Slice
|
||||
id: test_split
|
||||
|
||||
37
.github/workflows/test-unit.yaml
vendored
37
.github/workflows/test-unit.yaml
vendored
@@ -10,16 +10,44 @@ on:
|
||||
- 'script/gcg/**'
|
||||
|
||||
env:
|
||||
GO_VERSION: '1.23'
|
||||
GO_VERSION: '1.24'
|
||||
|
||||
jobs:
|
||||
|
||||
generate-packages:
|
||||
name: List Go Packages
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
matrix: ${{ steps.set-matrix.outputs.matrix }}
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up Go ${{ env.GO_VERSION }}
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
check-latest: true
|
||||
|
||||
- name: Generate matrix
|
||||
id: set-matrix
|
||||
run: |
|
||||
matrix_output=$(go run ./internal/testsci/genmatrix.go)
|
||||
echo "$matrix_output"
|
||||
echo "$matrix_output" >> $GITHUB_OUTPUT
|
||||
|
||||
test-unit:
|
||||
runs-on: ubuntu-latest
|
||||
needs: generate-packages
|
||||
strategy:
|
||||
matrix:
|
||||
package: ${{ fromJson(needs.generate-packages.outputs.matrix) }}
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -33,14 +61,15 @@ jobs:
|
||||
run: touch webui/static/index.html
|
||||
|
||||
- name: Tests
|
||||
run: make test-unit
|
||||
run: |
|
||||
go test -v -parallel 8 ${{ matrix.package.group }}
|
||||
|
||||
test-ui-unit:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
|
||||
14
.github/workflows/validate.yaml
vendored
14
.github/workflows/validate.yaml
vendored
@@ -6,8 +6,8 @@ on:
|
||||
- '*'
|
||||
|
||||
env:
|
||||
GO_VERSION: '1.23'
|
||||
GOLANGCI_LINT_VERSION: v1.63.3
|
||||
GO_VERSION: '1.24'
|
||||
GOLANGCI_LINT_VERSION: v2.0.2
|
||||
MISSPELL_VERSION: v0.6.0
|
||||
|
||||
jobs:
|
||||
@@ -17,7 +17,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -28,7 +28,7 @@ jobs:
|
||||
check-latest: true
|
||||
|
||||
- name: golangci-lint
|
||||
uses: golangci/golangci-lint-action@v6
|
||||
uses: golangci/golangci-lint-action@v7
|
||||
with:
|
||||
version: "${{ env.GOLANGCI_LINT_VERSION }}"
|
||||
|
||||
@@ -37,7 +37,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -48,7 +48,7 @@ jobs:
|
||||
check-latest: true
|
||||
|
||||
- name: Install misspell ${{ env.MISSPELL_VERSION }}
|
||||
run: curl -sfL https://raw.githubusercontent.com/golangci/misspell/master/install-misspell.sh | sh -s -- -b $(go env GOPATH)/bin ${MISSPELL_VERSION}
|
||||
run: curl -sfL https://raw.githubusercontent.com/golangci/misspell/HEAD/install-misspell.sh | sh -s -- -b $(go env GOPATH)/bin ${MISSPELL_VERSION}
|
||||
|
||||
- name: Avoid generating webui
|
||||
run: touch webui/static/index.html
|
||||
@@ -61,7 +61,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
|
||||
572
.golangci.yml
572
.golangci.yml
@@ -1,287 +1,313 @@
|
||||
run:
|
||||
timeout: 10m
|
||||
version: "2"
|
||||
|
||||
linters-settings:
|
||||
govet:
|
||||
enable-all: true
|
||||
disable:
|
||||
- shadow
|
||||
- fieldalignment
|
||||
gocyclo:
|
||||
min-complexity: 14
|
||||
goconst:
|
||||
min-len: 3
|
||||
min-occurrences: 4
|
||||
misspell:
|
||||
locale: US
|
||||
funlen:
|
||||
lines: -1
|
||||
statements: 120
|
||||
forbidigo:
|
||||
forbid:
|
||||
- ^print(ln)?$
|
||||
- ^spew\.Print(f|ln)?$
|
||||
- ^spew\.Dump$
|
||||
depguard:
|
||||
rules:
|
||||
main:
|
||||
deny:
|
||||
- pkg: "github.com/instana/testify"
|
||||
desc: not allowed
|
||||
- pkg: "github.com/pkg/errors"
|
||||
desc: Should be replaced by standard lib errors package
|
||||
godox:
|
||||
keywords:
|
||||
- FIXME
|
||||
importas:
|
||||
no-unaliased: true
|
||||
alias:
|
||||
- alias: composeapi
|
||||
pkg: github.com/docker/compose/v2/pkg/api
|
||||
formatters:
|
||||
enable:
|
||||
- gci
|
||||
- gofumpt
|
||||
exclusions:
|
||||
generated: lax
|
||||
paths:
|
||||
- pkg/provider/kubernetes/crd/generated/
|
||||
|
||||
# Standard Kubernetes rewrites:
|
||||
- alias: corev1
|
||||
pkg: "k8s.io/api/core/v1"
|
||||
- alias: netv1
|
||||
pkg: "k8s.io/api/networking/v1"
|
||||
- alias: netv1beta1
|
||||
pkg: "k8s.io/api/networking/v1beta1"
|
||||
- alias: admv1
|
||||
pkg: "k8s.io/api/admission/v1"
|
||||
- alias: admv1beta1
|
||||
pkg: "k8s.io/api/admission/v1beta1"
|
||||
- alias: extv1beta1
|
||||
pkg: "k8s.io/api/extensions/v1beta1"
|
||||
- alias: metav1
|
||||
pkg: "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
- alias: ktypes
|
||||
pkg: "k8s.io/apimachinery/pkg/types"
|
||||
- alias: kerror
|
||||
pkg: "k8s.io/apimachinery/pkg/api/errors"
|
||||
- alias: kclientset
|
||||
pkg: "k8s.io/client-go/kubernetes"
|
||||
- alias: kinformers
|
||||
pkg: "k8s.io/client-go/informers"
|
||||
- alias: ktesting
|
||||
pkg: "k8s.io/client-go/testing"
|
||||
- alias: kschema
|
||||
pkg: "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
- alias: kscheme
|
||||
pkg: "k8s.io/client-go/kubernetes/scheme"
|
||||
- alias: kversion
|
||||
pkg: "k8s.io/apimachinery/pkg/version"
|
||||
- alias: kubefake
|
||||
pkg: "k8s.io/client-go/kubernetes/fake"
|
||||
- alias: discoveryfake
|
||||
pkg: "k8s.io/client-go/discovery/fake"
|
||||
|
||||
# Kubernetes Gateway rewrites:
|
||||
- alias: gateclientset
|
||||
pkg: "sigs.k8s.io/gateway-api/pkg/client/clientset/gateway/versioned"
|
||||
- alias: gateinformers
|
||||
pkg: "sigs.k8s.io/gateway-api/pkg/client/informers/gateway/externalversions"
|
||||
- alias: gatev1alpha2
|
||||
pkg: "sigs.k8s.io/gateway-api/apis/v1alpha2"
|
||||
|
||||
# Traefik Kubernetes rewrites:
|
||||
- alias: containousv1alpha1
|
||||
pkg: "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefikcontainous/v1alpha1"
|
||||
- alias: traefikv1alpha1
|
||||
pkg: "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefikio/v1alpha1"
|
||||
- alias: traefikclientset
|
||||
pkg: "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned"
|
||||
- alias: traefikinformers
|
||||
pkg: "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/informers/externalversions"
|
||||
- alias: traefikscheme
|
||||
pkg: "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned/scheme"
|
||||
- alias: traefikcrdfake
|
||||
pkg: "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned/fake"
|
||||
tagalign:
|
||||
align: false
|
||||
sort: true
|
||||
order:
|
||||
- description
|
||||
- json
|
||||
- toml
|
||||
- yaml
|
||||
- yml
|
||||
- label
|
||||
- label-slice-as-struct
|
||||
- file
|
||||
- kv
|
||||
- export
|
||||
revive:
|
||||
rules:
|
||||
- name: struct-tag
|
||||
- name: blank-imports
|
||||
- name: context-as-argument
|
||||
- name: context-keys-type
|
||||
- name: dot-imports
|
||||
- name: error-return
|
||||
- name: error-strings
|
||||
- name: error-naming
|
||||
- name: exported
|
||||
disabled: true
|
||||
- name: if-return
|
||||
- name: increment-decrement
|
||||
- name: var-naming
|
||||
- name: var-declaration
|
||||
- name: package-comments
|
||||
disabled: true
|
||||
- name: range
|
||||
- name: receiver-naming
|
||||
- name: time-naming
|
||||
- name: unexported-return
|
||||
- name: indent-error-flow
|
||||
- name: errorf
|
||||
- name: empty-block
|
||||
- name: superfluous-else
|
||||
- name: unused-parameter
|
||||
disabled: true
|
||||
- name: unreachable-code
|
||||
- name: redefines-builtin-id
|
||||
gomoddirectives:
|
||||
tool-forbidden: true
|
||||
toolchain-pattern: 'go1\.\d+\.\d+$'
|
||||
go-version-pattern: '^1\.\d+(\.0)?$'
|
||||
replace-allow-list:
|
||||
- github.com/abbot/go-http-auth
|
||||
- github.com/gorilla/mux
|
||||
- github.com/mailgun/minheap
|
||||
- github.com/mailgun/multibuf
|
||||
- github.com/jaguilar/vt100
|
||||
- github.com/cucumber/godog
|
||||
testifylint:
|
||||
disable:
|
||||
- suite-dont-use-pkg
|
||||
- require-error
|
||||
- go-require
|
||||
errcheck:
|
||||
exclude-functions:
|
||||
- fmt.Fprintln
|
||||
linters:
|
||||
enable-all: true
|
||||
default: all
|
||||
disable:
|
||||
- sqlclosecheck # not relevant (SQL)
|
||||
- rowserrcheck # not relevant (SQL)
|
||||
- bodyclose # too many false-positive
|
||||
- containedctx # too many false-positive
|
||||
- contextcheck # too many false-positive
|
||||
- cyclop # duplicate of gocyclo
|
||||
- lll # Not relevant
|
||||
- gocyclo # FIXME must be fixed
|
||||
- gocognit # Too strict
|
||||
- nestif # Too many false-positive.
|
||||
- prealloc # Too many false-positive.
|
||||
- makezero # Not relevant
|
||||
- dupl # Too strict
|
||||
- gosec # Too strict
|
||||
- gochecknoinits
|
||||
- gochecknoglobals
|
||||
- wsl # Too strict
|
||||
- nlreturn # Not relevant
|
||||
- mnd # Too strict
|
||||
- stylecheck # skip because report issues related to some generated files.
|
||||
- testpackage # Too strict
|
||||
- tparallel # Not relevant
|
||||
- paralleltest # Not relevant
|
||||
- err113 # Too strict
|
||||
- exhaustive # Not relevant
|
||||
- exhaustruct # Not relevant
|
||||
- err113 # Too strict
|
||||
- wrapcheck # Too strict
|
||||
- noctx # Too strict
|
||||
- bodyclose # too many false-positive
|
||||
- forcetypeassert # Too strict
|
||||
- tagliatelle # Too strict
|
||||
- varnamelen # Not relevant
|
||||
- nilnil # Not relevant
|
||||
- ireturn # Not relevant
|
||||
- contextcheck # too many false-positive
|
||||
- containedctx # too many false-positive
|
||||
- maintidx # kind of duplicate of gocyclo
|
||||
- nonamedreturns # Too strict
|
||||
- gochecknoglobals
|
||||
- gochecknoinits
|
||||
- gocognit # Too strict
|
||||
- gocyclo # FIXME must be fixed
|
||||
- gosec # Too strict
|
||||
- gosmopolitan # not relevant
|
||||
- exportloopref # Not relevant since go1.22
|
||||
- ireturn # Not relevant
|
||||
- lll # Not relevant
|
||||
- maintidx # kind of duplicate of gocyclo
|
||||
- makezero # Not relevant
|
||||
- mnd # Too strict
|
||||
- nestif # Too many false-positive.
|
||||
- nilnil # Not relevant
|
||||
- nlreturn # Not relevant
|
||||
- noctx # Too strict
|
||||
- nonamedreturns # Too strict
|
||||
- paralleltest # Not relevant
|
||||
- prealloc # Too many false-positive.
|
||||
- rowserrcheck # not relevant (SQL)
|
||||
- sqlclosecheck # not relevant (SQL)
|
||||
- tagliatelle # Too strict
|
||||
- testpackage # Too strict
|
||||
- tparallel # Not relevant
|
||||
- varnamelen # Not relevant
|
||||
- wrapcheck # Too strict
|
||||
- wsl # Too strict
|
||||
|
||||
settings:
|
||||
depguard:
|
||||
rules:
|
||||
main:
|
||||
deny:
|
||||
- pkg: github.com/instana/testify
|
||||
desc: not allowed
|
||||
- pkg: github.com/pkg/errors
|
||||
desc: Should be replaced by standard lib errors package
|
||||
errcheck:
|
||||
exclude-functions:
|
||||
- fmt.Fprintln
|
||||
forbidigo:
|
||||
forbid:
|
||||
- pattern: ^print(ln)?$
|
||||
- pattern: ^spew\.Print(f|ln)?$
|
||||
- pattern: ^spew\.Dump$
|
||||
funlen:
|
||||
lines: -1
|
||||
statements: 120
|
||||
goconst:
|
||||
min-len: 3
|
||||
min-occurrences: 4
|
||||
gocyclo:
|
||||
min-complexity: 14
|
||||
godox:
|
||||
keywords:
|
||||
- FIXME
|
||||
gomoddirectives:
|
||||
toolchain-pattern: go1\.\d+\.\d+$
|
||||
tool-forbidden: true
|
||||
go-version-pattern: ^1\.\d+(\.0)?$
|
||||
replace-allow-list:
|
||||
- github.com/abbot/go-http-auth
|
||||
- github.com/gorilla/mux
|
||||
- github.com/mailgun/minheap
|
||||
- github.com/mailgun/multibuf
|
||||
- github.com/jaguilar/vt100
|
||||
- github.com/cucumber/godog
|
||||
govet:
|
||||
enable-all: true
|
||||
disable:
|
||||
- shadow
|
||||
- fieldalignment
|
||||
importas:
|
||||
no-unaliased: true
|
||||
alias:
|
||||
- pkg: github.com/docker/compose/v2/pkg/api
|
||||
alias: composeapi
|
||||
|
||||
# Standard Kubernetes rewrites:
|
||||
- pkg: k8s.io/api/core/v1
|
||||
alias: corev1
|
||||
- pkg: k8s.io/api/networking/v1
|
||||
alias: netv1
|
||||
- pkg: k8s.io/api/networking/v1beta1
|
||||
alias: netv1beta1
|
||||
- pkg: k8s.io/api/admission/v1
|
||||
alias: admv1
|
||||
- pkg: k8s.io/api/admission/v1beta1
|
||||
alias: admv1beta1
|
||||
- pkg: k8s.io/api/extensions/v1beta1
|
||||
alias: extv1beta1
|
||||
- pkg: k8s.io/apimachinery/pkg/apis/meta/v1
|
||||
alias: metav1
|
||||
- pkg: k8s.io/apimachinery/pkg/types
|
||||
alias: ktypes
|
||||
- pkg: k8s.io/apimachinery/pkg/api/errors
|
||||
alias: kerror
|
||||
- pkg: k8s.io/client-go/kubernetes
|
||||
alias: kclientset
|
||||
- pkg: k8s.io/client-go/informers
|
||||
alias: kinformers
|
||||
- pkg: k8s.io/client-go/testing
|
||||
alias: ktesting
|
||||
- pkg: k8s.io/apimachinery/pkg/runtime/schema
|
||||
alias: kschema
|
||||
- pkg: k8s.io/client-go/kubernetes/scheme
|
||||
alias: kscheme
|
||||
- pkg: k8s.io/apimachinery/pkg/version
|
||||
alias: kversion
|
||||
- pkg: k8s.io/client-go/kubernetes/fake
|
||||
alias: kubefake
|
||||
- pkg: k8s.io/client-go/discovery/fake
|
||||
alias: discoveryfake
|
||||
|
||||
# Kubernetes Gateway rewrites:
|
||||
- pkg: sigs.k8s.io/gateway-api/pkg/client/clientset/gateway/versioned
|
||||
alias: gateclientset
|
||||
- pkg: sigs.k8s.io/gateway-api/pkg/client/informers/gateway/externalversions
|
||||
alias: gateinformers
|
||||
- pkg: sigs.k8s.io/gateway-api/apis/v1alpha2
|
||||
alias: gatev1alpha2
|
||||
|
||||
# Traefik Kubernetes rewrites:
|
||||
- pkg: github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefikcontainous/v1alpha1
|
||||
alias: containousv1alpha1
|
||||
- pkg: github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefikio/v1alpha1
|
||||
alias: traefikv1alpha1
|
||||
- pkg: github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned
|
||||
alias: traefikclientset
|
||||
- pkg: github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/informers/externalversions
|
||||
alias: traefikinformers
|
||||
- pkg: github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned/scheme
|
||||
alias: traefikscheme
|
||||
- pkg: github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned/fake
|
||||
alias: traefikcrdfake
|
||||
misspell:
|
||||
locale: US
|
||||
revive:
|
||||
rules:
|
||||
- name: struct-tag
|
||||
- name: blank-imports
|
||||
- name: context-as-argument
|
||||
- name: context-keys-type
|
||||
- name: dot-imports
|
||||
- name: error-return
|
||||
- name: error-strings
|
||||
- name: error-naming
|
||||
- name: exported
|
||||
disabled: true
|
||||
- name: if-return
|
||||
- name: increment-decrement
|
||||
- name: var-naming
|
||||
- name: var-declaration
|
||||
- name: package-comments
|
||||
disabled: true
|
||||
- name: range
|
||||
- name: receiver-naming
|
||||
- name: time-naming
|
||||
- name: unexported-return
|
||||
- name: indent-error-flow
|
||||
- name: errorf
|
||||
- name: empty-block
|
||||
- name: superfluous-else
|
||||
- name: unused-parameter
|
||||
disabled: true
|
||||
- name: unreachable-code
|
||||
- name: redefines-builtin-id
|
||||
tagalign:
|
||||
align: false
|
||||
sort: true
|
||||
order:
|
||||
- description
|
||||
- json
|
||||
- toml
|
||||
- yaml
|
||||
- yml
|
||||
- label
|
||||
- label-slice-as-struct
|
||||
- file
|
||||
- kv
|
||||
- export
|
||||
testifylint:
|
||||
disable:
|
||||
- suite-dont-use-pkg
|
||||
- require-error
|
||||
- go-require
|
||||
perfsprint:
|
||||
err-error: true
|
||||
errorf: true
|
||||
sprintf1: true
|
||||
strconcat: false
|
||||
staticcheck:
|
||||
checks:
|
||||
- all
|
||||
- '-ST1000'
|
||||
- '-ST1003'
|
||||
- '-ST1016'
|
||||
- '-ST1020'
|
||||
- '-ST1021'
|
||||
- '-ST1022'
|
||||
- '-QF1001'
|
||||
- '-QF1008' # TODO must be fixed
|
||||
|
||||
exclusions:
|
||||
generated: lax
|
||||
presets:
|
||||
- comments
|
||||
- std-error-handling
|
||||
rules:
|
||||
- path: (.+)_test.go
|
||||
linters:
|
||||
- canonicalheader
|
||||
- fatcontext
|
||||
- funlen
|
||||
- goconst
|
||||
- godot
|
||||
- path: (.+)_test.go
|
||||
text: ' always receives '
|
||||
linters:
|
||||
- unparam
|
||||
- path: pkg/server/service/bufferpool.go
|
||||
text: 'SA6002: argument should be pointer-like to avoid allocations'
|
||||
- path: pkg/server/middleware/middlewares.go
|
||||
text: Function 'buildConstructor' has too many statements
|
||||
linters:
|
||||
- funlen
|
||||
- path: pkg/tracing/haystack/logger.go
|
||||
linters:
|
||||
- goprintffuncname
|
||||
- path: pkg/tracing/tracing.go
|
||||
text: printf-like formatting function 'SetErrorWithEvent' should be named 'SetErrorWithEventf'
|
||||
linters:
|
||||
- goprintffuncname
|
||||
- path: pkg/tls/tlsmanager_test.go
|
||||
text: 'SA1019: config.ClientCAs.Subjects has been deprecated since Go 1.18'
|
||||
- path: pkg/types/tls_test.go
|
||||
text: 'SA1019: tlsConfig.RootCAs.Subjects has been deprecated since Go 1.18'
|
||||
- path: pkg/provider/kubernetes/(crd|gateway)/client.go
|
||||
linters:
|
||||
- interfacebloat
|
||||
- path: pkg/metrics/metrics.go
|
||||
linters:
|
||||
- interfacebloat
|
||||
- path: integration/healthcheck_test.go
|
||||
text: Duplicate words \(wsp2,\) found
|
||||
linters:
|
||||
- dupword
|
||||
- path: pkg/types/domain_test.go
|
||||
text: Duplicate words \(sub\) found
|
||||
linters:
|
||||
- dupword
|
||||
- path: pkg/provider/kubernetes/gateway/client_mock_test.go
|
||||
text: 'unusedwrite: unused write to field'
|
||||
linters:
|
||||
- govet
|
||||
- path: pkg/provider/acme/local_store.go
|
||||
linters:
|
||||
- musttag
|
||||
- path: pkg/tls/certificate.go
|
||||
text: the methods of "Certificates" use pointer receiver and non-pointer receiver.
|
||||
linters:
|
||||
- recvcheck
|
||||
- path: pkg/config/static/static_config.go
|
||||
source: 'errors.New\("Consul Catalog provider'
|
||||
text: 'ST1005: error strings should not be capitalized'
|
||||
- path: pkg/config/static/static_config.go
|
||||
source: 'errors.New\("Consul provider'
|
||||
text: 'ST1005: error strings should not be capitalized'
|
||||
- path: pkg/config/static/static_config.go
|
||||
source: 'errors.New\("Nomad provider'
|
||||
text: 'ST1005: error strings should not be capitalized'
|
||||
- path: (.+)\.go
|
||||
text: 'struct-tag: unknown option ''inline'' in JSON tag'
|
||||
linters:
|
||||
- revive
|
||||
- path: (.+)\.go
|
||||
text: 'struct-tag: unknown option ''omitzero'' in TOML tag'
|
||||
linters:
|
||||
- revive
|
||||
- path: (.+)\.go$
|
||||
text: 'SA1019: http.CloseNotifier has been deprecated' # FIXME must be fixed
|
||||
- path: (.+)\.go$
|
||||
text: 'SA1019: cfg.(SSLRedirect|SSLTemporaryRedirect|SSLHost|SSLForceHost|FeaturePolicy) is deprecated'
|
||||
- path: (.+)\.go$
|
||||
text: 'SA1019: c.Providers.(ConsulCatalog|Consul|Nomad).Namespace is deprecated'
|
||||
paths:
|
||||
- pkg/provider/kubernetes/crd/generated/
|
||||
|
||||
issues:
|
||||
exclude-use-default: false
|
||||
max-issues-per-linter: 0
|
||||
max-same-issues: 0
|
||||
exclude-dirs:
|
||||
- pkg/provider/kubernetes/crd/generated/
|
||||
exclude:
|
||||
- 'Error return value of .((os\.)?std(out|err)\..*|.*Close|.*Flush|os\.Remove(All)?|.*printf?|os\.(Un)?Setenv). is not checked'
|
||||
- "should have a package comment, unless it's in another file for this package"
|
||||
- 'SA1019: http.CloseNotifier has been deprecated' # FIXME must be fixed
|
||||
- 'SA1019: cfg.SSLRedirect is deprecated'
|
||||
- 'SA1019: cfg.SSLTemporaryRedirect is deprecated'
|
||||
- 'SA1019: cfg.SSLHost is deprecated'
|
||||
- 'SA1019: cfg.SSLForceHost is deprecated'
|
||||
- 'SA1019: cfg.FeaturePolicy is deprecated'
|
||||
- 'SA1019: c.Providers.ConsulCatalog.Namespace is deprecated'
|
||||
- 'SA1019: c.Providers.Consul.Namespace is deprecated'
|
||||
- 'SA1019: c.Providers.Nomad.Namespace is deprecated'
|
||||
- 'fmt.Sprintf can be replaced with string'
|
||||
- 'SA1019: dockertypes.ContainerNode is deprecated'
|
||||
exclude-rules:
|
||||
- path: '(.+)_test.go'
|
||||
linters:
|
||||
- goconst
|
||||
- funlen
|
||||
- godot
|
||||
- canonicalheader
|
||||
- fatcontext
|
||||
- path: '(.+)_test.go'
|
||||
text: ' always receives '
|
||||
linters:
|
||||
- unparam
|
||||
- path: '(.+)\.go'
|
||||
text: 'struct-tag: unknown option ''inline'' in JSON tag'
|
||||
linters:
|
||||
- revive
|
||||
- path: pkg/server/service/bufferpool.go
|
||||
text: 'SA6002: argument should be pointer-like to avoid allocations'
|
||||
- path: pkg/server/middleware/middlewares.go
|
||||
text: "Function 'buildConstructor' has too many statements"
|
||||
linters:
|
||||
- funlen
|
||||
- path: pkg/tracing/haystack/logger.go
|
||||
linters:
|
||||
- goprintffuncname
|
||||
- path: pkg/tracing/tracing.go
|
||||
text: "printf-like formatting function 'SetErrorWithEvent' should be named 'SetErrorWithEventf'"
|
||||
linters:
|
||||
- goprintffuncname
|
||||
- path: pkg/tls/tlsmanager_test.go
|
||||
text: 'SA1019: config.ClientCAs.Subjects has been deprecated since Go 1.18'
|
||||
- path: pkg/types/tls_test.go
|
||||
text: 'SA1019: tlsConfig.RootCAs.Subjects has been deprecated since Go 1.18'
|
||||
- path: pkg/provider/kubernetes/(crd|gateway)/client.go
|
||||
linters:
|
||||
- interfacebloat
|
||||
- path: pkg/metrics/metrics.go
|
||||
linters:
|
||||
- interfacebloat
|
||||
- path: integration/healthcheck_test.go
|
||||
text: 'Duplicate words \(wsp2,\) found'
|
||||
linters:
|
||||
- dupword
|
||||
- path: pkg/types/domain_test.go
|
||||
text: 'Duplicate words \(sub\) found'
|
||||
linters:
|
||||
- dupword
|
||||
- path: pkg/provider/kubernetes/gateway/client_mock_test.go
|
||||
text: 'unusedwrite: unused write to field'
|
||||
linters:
|
||||
- govet
|
||||
- path: pkg/provider/acme/local_store.go
|
||||
linters:
|
||||
- musttag
|
||||
- path: pkg/tls/certificate.go
|
||||
text: 'the methods of "Certificates" use pointer receiver and non-pointer receiver.'
|
||||
linters:
|
||||
- recvcheck
|
||||
|
||||
output:
|
||||
show-stats: true
|
||||
sort-results: true
|
||||
sort-order:
|
||||
- linter
|
||||
- file
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
version: v1.0
|
||||
name: Traefik Release - deprecated
|
||||
agent:
|
||||
machine:
|
||||
type: f1-standard-2
|
||||
os_image: ubuntu2204
|
||||
blocks:
|
||||
- name: 'Do nothing'
|
||||
task:
|
||||
jobs:
|
||||
- name: 'Do nothing'
|
||||
commands:
|
||||
- echo "Do nothing"
|
||||
112
CHANGELOG.md
112
CHANGELOG.md
@@ -1,3 +1,115 @@
|
||||
## [v2.11.30](https://github.com/traefik/traefik/tree/v2.11.30) (2025-10-28)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.11.29...v2.11.30)
|
||||
|
||||
**Bug fixes:**
|
||||
- **[http3]** Bump github.com/quic-go/quic-go to v0.55.0 ([#12156](https://github.com/traefik/traefik/pull/12156) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- **[kv]** Fix KV key name used to check if connection is alive ([#12162](https://github.com/traefik/traefik/pull/12162) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- **[server]** Bump golang.org/x/net to v0.46.0 ([#12143](https://github.com/traefik/traefik/pull/12143) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- **[tracing]** Bump gopkg.in/DataDog/dd-trace-go.v1 to v1.74.6 ([#12083](https://github.com/traefik/traefik/pull/12083) by [hannahkm](https://github.com/hannahkm))
|
||||
|
||||
## [v2.11.29](https://github.com/traefik/traefik/tree/v2.11.29) (2025-08-26)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.11.28...v2.11.29)
|
||||
|
||||
**Bug fixes:**
|
||||
- **[acme]** Bump github.com/go-acme/lego/v4 to v4.25.2 ([#11983](https://github.com/traefik/traefik/pull/11983) by [ldez](https://github.com/ldez))
|
||||
- **[docker]** Bump github.com/docker/docker to v28.3.3 ([#12007](https://github.com/traefik/traefik/pull/12007) by [kevinpollet](https://github.com/kevinpollet))
|
||||
|
||||
**Documentation:**
|
||||
- Fix invalid links in documentation ([#11960](https://github.com/traefik/traefik/pull/11960) by [mloiseleur](https://github.com/mloiseleur))
|
||||
- Update releases docs for v3.5 ([#11949](https://github.com/traefik/traefik/pull/11949) by [jnoordsij](https://github.com/jnoordsij))
|
||||
|
||||
## [v2.11.28](https://github.com/traefik/traefik/tree/v2.11.28) (2025-07-23)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.11.27...v2.11.28)
|
||||
|
||||
**Bug fixes:**
|
||||
- **[logs]** Redact logged install configuration ([#11907](https://github.com/traefik/traefik/pull/11907) by [jspdown](https://github.com/jspdown))
|
||||
- **[plugins]** Fix client arbitrary file access during archive extraction zipslip ([#11911](https://github.com/traefik/traefik/pull/11911) by [odaysec](https://github.com/odaysec))
|
||||
- **[server]** Disable MPTCP by default ([#11918](https://github.com/traefik/traefik/pull/11918) by [rtribotte](https://github.com/rtribotte))
|
||||
|
||||
**Documentation:**
|
||||
- **[k8s/crd,k8s]** Remove all mentions of ordering for TLSOption CurvePreferences field ([#11924](https://github.com/traefik/traefik/pull/11924) by [jnoordsij](https://github.com/jnoordsij))
|
||||
|
||||
## [v2.11.27](https://github.com/traefik/traefik/tree/v2.11.27) (2025-07-11)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.11.26...v2.11.27)
|
||||
|
||||
**Bug fixes:**
|
||||
- Bump github.com/go-viper/mapstructure/v2 to v2.3.0 ([#11880](https://github.com/traefik/traefik/pull/11880) by [kevinpollet](https://github.com/kevinpollet))
|
||||
|
||||
## [v2.11.26](https://github.com/traefik/traefik/tree/v2.11.26) (2025-06-26)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.11.25...v2.11.26)
|
||||
|
||||
**Bug fixes:**
|
||||
- **[middleware]** Do not log redis sentinel username and password ([#11819](https://github.com/traefik/traefik/pull/11819) by [kevinpollet](https://github.com/kevinpollet))
|
||||
|
||||
**Documentation:**
|
||||
- **[kv]** Fix KV reference rendering ([#11815](https://github.com/traefik/traefik/pull/11815) by [rtribotte](https://github.com/rtribotte))
|
||||
- **[middleware,k8s/crd]** Fix typo in redirect middleware documentation ([#11830](https://github.com/traefik/traefik/pull/11830) by [rtribotte](https://github.com/rtribotte))
|
||||
- Update supported versions ([#11811](https://github.com/traefik/traefik/pull/11811) by [jnoordsij](https://github.com/jnoordsij))
|
||||
|
||||
## [v2.11.25](https://github.com/traefik/traefik/tree/v2.11.25) (2025-05-27)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.11.24...v2.11.25)
|
||||
|
||||
**Bug fixes:**
|
||||
- **[k8s/ingress]** Fix panic for ingress with backend resource ([#11777](https://github.com/traefik/traefik/pull/11777) by [rtribotte](https://github.com/rtribotte))
|
||||
- **[server]** Normalize request path ([#11768](https://github.com/traefik/traefik/pull/11768) by [kevinpollet](https://github.com/kevinpollet))
|
||||
|
||||
**Documentation:**
|
||||
- **[middleware,k8s]** Add multi-tenant TLS guidance to the docs ([#11724](https://github.com/traefik/traefik/pull/11724) by [sheddy-traefik](https://github.com/sheddy-traefik))
|
||||
- **[service]** Add a note about how to disable connection reuse with backends ([#11716](https://github.com/traefik/traefik/pull/11716) by [rtribotte](https://github.com/rtribotte))
|
||||
- Fix broken link in documentation ([#11761](https://github.com/traefik/traefik/pull/11761) by [sheddy-traefik](https://github.com/sheddy-traefik))
|
||||
- Change version for path sanitization migration guide ([#11702](https://github.com/traefik/traefik/pull/11702) by [rtribotte](https://github.com/rtribotte))
|
||||
|
||||
## [v2.11.24](https://github.com/traefik/traefik/tree/v2.11.24) (2025-04-18)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.11.22...v2.11.24)
|
||||
|
||||
**Bug fixes:**
|
||||
- **[acme]** Bump github.com/go-acme/lego/v4 to v4.23.1 ([#11690](https://github.com/traefik/traefik/pull/11690) by [ldez](https://github.com/ldez))
|
||||
- **[metrics]** Bump gopkg.in/DataDog/dd-trace-go.v1 to v1.72.2 ([#11693](https://github.com/traefik/traefik/pull/11693) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- **[middleware]** Add Content-Length header to preflight response ([#11682](https://github.com/traefik/traefik/pull/11682) by [lbenguigui](https://github.com/lbenguigui))
|
||||
- **[server]** Sanitize request path ([#11684](https://github.com/traefik/traefik/pull/11684) by [rtribotte](https://github.com/rtribotte))
|
||||
- Bump github.com/redis/go-redis/v9 to v9.7.3 ([#11695](https://github.com/traefik/traefik/pull/11695) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- Bump golang.org/x/net to v0.38.0 ([#11691](https://github.com/traefik/traefik/pull/11691) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- Bump golang.org/x/oauth2 to v0.28.0 ([#11689](https://github.com/traefik/traefik/pull/11689) by [rtribotte](https://github.com/rtribotte))
|
||||
|
||||
**Documentation:**
|
||||
- **[middleware]** Add content-length best practice documentation ([#11697](https://github.com/traefik/traefik/pull/11697) by [sheddy-traefik](https://github.com/sheddy-traefik))
|
||||
- Typo fix on the Explanation Section for User Guide HTTP Challenge. ([#11676](https://github.com/traefik/traefik/pull/11676) by [YapWC](https://github.com/YapWC))
|
||||
|
||||
## [v2.11.23](https://github.com/traefik/traefik/tree/v2.11.23) (2025-04-17)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.11.22...v2.11.23)
|
||||
|
||||
Release canceled.
|
||||
|
||||
## [v2.11.22](https://github.com/traefik/traefik/tree/v2.11.22) (2025-03-31)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.11.21...v2.11.22)
|
||||
|
||||
**Bug fixes:**
|
||||
- **[ecs,logs]** Bump AWS SDK to v2 ([#11359](https://github.com/traefik/traefik/pull/11359) by [Juneezee](https://github.com/Juneezee))
|
||||
- **[logs,tls]** Error level log for configuration-related TLS errors with backends ([#11611](https://github.com/traefik/traefik/pull/11611) by [rtribotte](https://github.com/rtribotte))
|
||||
- **[rules]** Allow underscore character in HostSNI matcher ([#11557](https://github.com/traefik/traefik/pull/11557) by [rohitlohar45](https://github.com/rohitlohar45))
|
||||
- **[server]** Bump github.com/vulcand/oxy/v2 to v2.0.3 ([#11649](https://github.com/traefik/traefik/pull/11649) by [adamvduke](https://github.com/adamvduke))
|
||||
- **[server]** Bump golang.org/x/net to v0.37.0 ([#11632](https://github.com/traefik/traefik/pull/11632) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- **[webui]** Change boolean module properties default value to undefined ([#11639](https://github.com/traefik/traefik/pull/11639) by [rtribotte](https://github.com/rtribotte))
|
||||
- Bump github.com/golang-jwt/jwt to v4.5.2 and v5.2.2 ([#11634](https://github.com/traefik/traefik/pull/11634) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- Bump github.com/redis/go-redis/v9 to v9.6.3 ([#11633](https://github.com/traefik/traefik/pull/11633) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- Bump golang.org/x/net to v0.36.0 ([#11608](https://github.com/traefik/traefik/pull/11608) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- Bump github.com/go-jose/go-jose/v4 to v4.0.5 ([#11571](https://github.com/traefik/traefik/pull/11571) by [kevinpollet](https://github.com/kevinpollet))
|
||||
|
||||
**Documentation:**
|
||||
- **[accesslogs]** Remove documentation for OriginStatusLine and DownstreamStatusLine accessLogs fields ([#11599](https://github.com/traefik/traefik/pull/11599) by [rtribotte](https://github.com/rtribotte))
|
||||
- **[middleware]** Clarifies that retry middleware uses TCP, not HTTP status codes ([#11603](https://github.com/traefik/traefik/pull/11603) by [geraldcroes](https://github.com/geraldcroes))
|
||||
- **[redis]** Add tip for dynamic configuration updates of Redis ([#11577](https://github.com/traefik/traefik/pull/11577) by [Alanxtl](https://github.com/Alanxtl))
|
||||
- Add Security Support ([#11610](https://github.com/traefik/traefik/pull/11610) by [nmengin](https://github.com/nmengin))
|
||||
|
||||
# [v2.11.21](https://github.com/traefik/traefik/tree/v2.11.21) (2025-02-24)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.11.20...v2.11.21)
|
||||
|
||||
**Bug fixes:**
|
||||
- **[acme]** Bump github.com/go-acme/lego/v4 to v4.22.2 ([#11537](https://github.com/traefik/traefik/pull/11537) by [ldez](https://github.com/ldez))
|
||||
- **[cli]** Bump github.com/traefik/paerser to v0.2.2 ([#11530](https://github.com/traefik/traefik/pull/11530) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- **[middleware]** Enable the retry middleware in the proxy ([#11536](https://github.com/traefik/traefik/pull/11536) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- **[middleware]** Retry should send headers on Write ([#11534](https://github.com/traefik/traefik/pull/11534) by [kevinpollet](https://github.com/kevinpollet))
|
||||
|
||||
## [v2.11.20](https://github.com/traefik/traefik/tree/v2.11.20) (2025-01-31)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.11.19...v2.11.20)
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# syntax=docker/dockerfile:1.2
|
||||
FROM alpine:3.21
|
||||
FROM alpine:3.22
|
||||
|
||||
RUN apk add --no-cache --no-progress ca-certificates tzdata
|
||||
|
||||
|
||||
12
Makefile
12
Makefile
@@ -13,6 +13,7 @@ DATE := $(shell date -u '+%Y-%m-%d_%I:%M:%S%p')
|
||||
# Default build target
|
||||
GOOS := $(shell go env GOOS)
|
||||
GOARCH := $(shell go env GOARCH)
|
||||
GOGC ?=
|
||||
|
||||
LINT_EXECUTABLES = misspell shellcheck
|
||||
|
||||
@@ -56,7 +57,7 @@ generate:
|
||||
#? binary: Build the binary
|
||||
binary: generate-webui dist
|
||||
@echo SHA: $(VERSION) $(CODENAME) $(DATE)
|
||||
CGO_ENABLED=0 GOGC=off GOOS=${GOOS} GOARCH=${GOARCH} go build ${FLAGS[*]} -ldflags "-s -w \
|
||||
CGO_ENABLED=0 GOGC=${GOGC} GOOS=${GOOS} GOARCH=${GOARCH} go build ${FLAGS[*]} -ldflags "-s -w \
|
||||
-X github.com/traefik/traefik/v2/pkg/version.Version=$(VERSION) \
|
||||
-X github.com/traefik/traefik/v2/pkg/version.Codename=$(CODENAME) \
|
||||
-X github.com/traefik/traefik/v2/pkg/version.BuildDate=$(DATE)" \
|
||||
@@ -94,7 +95,7 @@ test-unit:
|
||||
|
||||
.PHONY: test-integration
|
||||
#? test-integration: Run the integration tests
|
||||
test-integration: binary
|
||||
test-integration:
|
||||
GOOS=$(GOOS) GOARCH=$(GOARCH) go test ./integration -test.timeout=20m -failfast -v $(TESTFLAGS)
|
||||
|
||||
.PHONY: test-ui-unit
|
||||
@@ -169,18 +170,13 @@ docs-pull-images:
|
||||
.PHONY: generate-crd
|
||||
#? generate-crd: Generate CRD clientset and CRD manifests
|
||||
generate-crd:
|
||||
@$(CURDIR)/script/code-gen-docker.sh
|
||||
@$(CURDIR)/script/code-gen.sh
|
||||
|
||||
.PHONY: generate-genconf
|
||||
#? generate-genconf: Generate code from dynamic configuration github.com/traefik/genconf
|
||||
generate-genconf:
|
||||
go run ./cmd/internal/gen/
|
||||
|
||||
.PHONY: release-packages
|
||||
#? release-packages: Create packages for the release
|
||||
release-packages: generate-webui
|
||||
$(CURDIR)/script/release-packages.sh
|
||||
|
||||
.PHONY: fmt
|
||||
#? fmt: Format the Code
|
||||
fmt:
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
</picture>
|
||||
</p>
|
||||
|
||||
[](https://traefik-oss.semaphoreci.com/projects/traefik)
|
||||
[](https://doc.traefik.io/traefik)
|
||||
[](https://goreportcard.com/report/traefik/traefik)
|
||||
[](https://github.com/traefik/traefik/blob/master/LICENSE.md)
|
||||
|
||||
@@ -3,7 +3,6 @@ package main
|
||||
import (
|
||||
"context"
|
||||
"crypto/x509"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
stdlog "log"
|
||||
"net/http"
|
||||
@@ -23,7 +22,6 @@ import (
|
||||
"github.com/traefik/traefik/v2/cmd"
|
||||
"github.com/traefik/traefik/v2/cmd/healthcheck"
|
||||
cmdVersion "github.com/traefik/traefik/v2/cmd/version"
|
||||
_ "github.com/traefik/traefik/v2/init"
|
||||
tcli "github.com/traefik/traefik/v2/pkg/cli"
|
||||
"github.com/traefik/traefik/v2/pkg/collector"
|
||||
"github.com/traefik/traefik/v2/pkg/config/dynamic"
|
||||
@@ -35,6 +33,7 @@ import (
|
||||
"github.com/traefik/traefik/v2/pkg/provider/acme"
|
||||
"github.com/traefik/traefik/v2/pkg/provider/aggregator"
|
||||
"github.com/traefik/traefik/v2/pkg/provider/traefik"
|
||||
"github.com/traefik/traefik/v2/pkg/redactor"
|
||||
"github.com/traefik/traefik/v2/pkg/safe"
|
||||
"github.com/traefik/traefik/v2/pkg/server"
|
||||
"github.com/traefik/traefik/v2/pkg/server/middleware"
|
||||
@@ -101,12 +100,11 @@ func runCmd(staticConfiguration *static.Configuration) error {
|
||||
|
||||
log.WithoutContext().Infof("Traefik version %s built on %s", version.Version, version.BuildDate)
|
||||
|
||||
jsonConf, err := json.Marshal(staticConfiguration)
|
||||
redactedStaticConfiguration, err := redactor.RemoveCredentials(staticConfiguration)
|
||||
if err != nil {
|
||||
log.WithoutContext().Errorf("Could not marshal static configuration: %v", err)
|
||||
log.WithoutContext().Debugf("Static configuration loaded [struct] %#v", staticConfiguration)
|
||||
log.WithoutContext().Errorf("Could not redact static configuration: %v", err)
|
||||
} else {
|
||||
log.WithoutContext().Debugf("Static configuration loaded %s", string(jsonConf))
|
||||
log.WithoutContext().Debugf("Static configuration loaded %s", redactedStaticConfiguration)
|
||||
}
|
||||
|
||||
if staticConfiguration.Global.CheckNewVersion {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM alpine:3.21
|
||||
FROM alpine:3.22
|
||||
|
||||
RUN apk --no-cache --no-progress add \
|
||||
build-base \
|
||||
@@ -9,13 +9,11 @@ RUN apk --no-cache --no-progress add \
|
||||
ruby \
|
||||
ruby-bigdecimal \
|
||||
ruby-dev \
|
||||
ruby-etc \
|
||||
ruby-ffi \
|
||||
ruby-json \
|
||||
zlib-dev
|
||||
|
||||
RUN gem install nokogiri --version 1.16.8 --no-document -- --use-system-libraries
|
||||
RUN gem install html-proofer --version 5.0.7 --no-document -- --use-system-libraries
|
||||
RUN gem install nokogiri --version 1.18.6 --no-document -- --use-system-libraries
|
||||
RUN gem install html-proofer --version 5.0.10 --no-document -- --use-system-libraries
|
||||
|
||||
# After Ruby, some NodeJS YAY!
|
||||
RUN apk --no-cache --no-progress add \
|
||||
|
||||
@@ -4,25 +4,33 @@
|
||||
|
||||
Below is a non-exhaustive list of versions and their maintenance status:
|
||||
|
||||
| Version | Release Date | Community Support |
|
||||
|---------|--------------|--------------------|
|
||||
| 3.3 | Jan 06, 2025 | Yes |
|
||||
| 3.2 | Oct 28, 2024 | Ended Jan 06, 2025 |
|
||||
| 3.1 | Jul 15, 2024 | Ended Oct 28, 2024 |
|
||||
| 3.0 | Apr 29, 2024 | Ended Jul 15, 2024 |
|
||||
| 2.11 | Feb 12, 2024 | Ends Apr 29, 2025 |
|
||||
| 2.10 | Apr 24, 2023 | Ended Feb 12, 2024 |
|
||||
| 2.9 | Oct 03, 2022 | Ended Apr 24, 2023 |
|
||||
| 2.8 | Jun 29, 2022 | Ended Oct 03, 2022 |
|
||||
| 2.7 | May 24, 2022 | Ended Jun 29, 2022 |
|
||||
| 2.6 | Jan 24, 2022 | Ended May 24, 2022 |
|
||||
| 2.5 | Aug 17, 2021 | Ended Jan 24, 2022 |
|
||||
| 2.4 | Jan 19, 2021 | Ended Aug 17, 2021 |
|
||||
| 2.3 | Sep 23, 2020 | Ended Jan 19, 2021 |
|
||||
| 2.2 | Mar 25, 2020 | Ended Sep 23, 2020 |
|
||||
| 2.1 | Dec 11, 2019 | Ended Mar 25, 2020 |
|
||||
| 2.0 | Sep 16, 2019 | Ended Dec 11, 2019 |
|
||||
| 1.7 | Sep 24, 2018 | Ended Dec 31, 2021 |
|
||||
| Version | Release Date | Active Support | Security Support |
|
||||
|---------|--------------|--------------------|-------------------|
|
||||
| 3.5 | Jul 23, 2025 | Yes | Yes |
|
||||
| 3.4 | May 05, 2025 | Ended Jul 23, 2025 | No |
|
||||
| 3.3 | Jan 06, 2025 | Ended May 05, 2025 | No |
|
||||
| 3.2 | Oct 28, 2024 | Ended Jan 06, 2025 | No |
|
||||
| 3.1 | Jul 15, 2024 | Ended Oct 28, 2024 | No |
|
||||
| 3.0 | Apr 29, 2024 | Ended Jul 15, 2024 | No |
|
||||
| 2.11 | Feb 12, 2024 | Ended Apr 29, 2025 | Ends Feb 01, 2026 |
|
||||
| 2.10 | Apr 24, 2023 | Ended Feb 12, 2024 | No |
|
||||
| 2.9 | Oct 03, 2022 | Ended Apr 24, 2023 | No |
|
||||
| 2.8 | Jun 29, 2022 | Ended Oct 03, 2022 | No |
|
||||
| 2.7 | May 24, 2022 | Ended Jun 29, 2022 | No |
|
||||
| 2.6 | Jan 24, 2022 | Ended May 24, 2022 | No |
|
||||
| 2.5 | Aug 17, 2021 | Ended Jan 24, 2022 | No |
|
||||
| 2.4 | Jan 19, 2021 | Ended Aug 17, 2021 | No |
|
||||
| 2.3 | Sep 23, 2020 | Ended Jan 19, 2021 | No |
|
||||
| 2.2 | Mar 25, 2020 | Ended Sep 23, 2020 | No |
|
||||
| 2.1 | Dec 11, 2019 | Ended Mar 25, 2020 | No |
|
||||
| 2.0 | Sep 16, 2019 | Ended Dec 11, 2019 | No |
|
||||
| 1.7 | Sep 24, 2018 | Ended Dec 31, 2021 | No |
|
||||
|
||||
??? example "Active Support / Security Support"
|
||||
|
||||
- **Active support**: Receives any bug fixes.
|
||||
|
||||
- **Security support**: Receives only critical bug and security fixes.
|
||||
|
||||
This page is maintained and updated periodically to reflect our roadmap and any decisions affecting the end of support for Traefik Proxy.
|
||||
|
||||
|
||||
@@ -316,17 +316,22 @@ For complete details, refer to your provider's _Additional configuration_ link.
|
||||
|
||||
| Provider Name | Provider Code | Environment Variables | |
|
||||
|------------------------------------------------------------------------|--------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------|
|
||||
| [ACME DNS](https://github.com/joohoi/acme-dns) | `acme-dns` | `ACME_DNS_API_BASE`, `ACME_DNS_STORAGE_PATH` | [Additional configuration](https://go-acme.github.io/lego/dns/acme-dns) |
|
||||
| [ACME DNS](https://github.com/joohoi/acme-dns) | `acme-dns` | `ACME_DNS_API_BASE`, `ACME_DNS_STORAGE_PATH`, `ACME_DNS_STORAGE_BASE_URL` | [Additional configuration](https://go-acme.github.io/lego/dns/acme-dns) |
|
||||
| [Active24](https://www.active24.cz) | `active24` | `ACTIVE24_API_KEY`, `ACTIVE24_SECRET` | [Additional configuration](https://go-acme.github.io/lego/dns/active24) |
|
||||
| [Alibaba Cloud](https://www.alibabacloud.com) | `alidns` | `ALICLOUD_ACCESS_KEY`, `ALICLOUD_SECRET_KEY`, `ALICLOUD_REGION_ID` | [Additional configuration](https://go-acme.github.io/lego/dns/alidns) |
|
||||
| [all-inkl](https://all-inkl.com) | `allinkl` | `ALL_INKL_LOGIN`, `ALL_INKL_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/allinkl) |
|
||||
| [ArvanCloud](https://www.arvancloud.ir/en) | `arvancloud` | `ARVANCLOUD_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/arvancloud) |
|
||||
| [Auroradns](https://www.pcextreme.com/dns-health-checks) | `auroradns` | `AURORA_USER_ID`, `AURORA_KEY`, `AURORA_ENDPOINT` | [Additional configuration](https://go-acme.github.io/lego/dns/auroradns) |
|
||||
| [Autodns](https://www.internetx.com/domains/autodns/) | `autodns` | `AUTODNS_API_USER`, `AUTODNS_API_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/autodns) |
|
||||
| [Azure](https://azure.microsoft.com/services/dns/) (DEPRECATED) | `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) |
|
||||
| [Axelname](https://axelname.ru) | `axelname` | `AXELNAME_NICKNAME`, `AXELNAME_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/axelname) |
|
||||
| [Azion](https://www.azion.com/en/products/edge-dns/) | `azion` | `AZION_PERSONAL_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/azion) |
|
||||
| [Azure](https://azure.microsoft.com/services/dns/) (DEPRECATED) | `azure` | DEPRECATED use `azuredns` instead. | [Additional configuration](https://go-acme.github.io/lego/dns/azure) |
|
||||
| [AzureDNS](https://azure.microsoft.com/services/dns/) | `azuredns` | `AZURE_CLIENT_ID`, `AZURE_CLIENT_SECRET`, `AZURE_TENANT_ID`, `AZURE_SUBSCRIPTION_ID`, `AZURE_RESOURCE_GROUP`, `[AZURE_ENVIRONMENT]`, `[AZURE_PRIVATE_ZONE]`, `[AZURE_ZONE_NAME]` | [Additional configuration](https://go-acme.github.io/lego/dns/azuredns) |
|
||||
| [Baidu Cloud](https://cloud.baidu.com) | `baiducloud` | `BAIDUCLOUD_ACCESS_KEY_ID`, `BAIDUCLOUD_SECRET_ACCESS_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/baiducloud) |
|
||||
| [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) |
|
||||
| [Brandit](https://www.brandit.com) (DEPRECATED) | `brandit` | `BRANDIT_API_USERNAME`, `BRANDIT_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/brandit) |
|
||||
| [BookMyName](https://www.bookmyname.com) | `bookmyname` | `BOOKMYNAME_USERNAME`, `BOOKMYNAME_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/bookmyname) |
|
||||
| [Brandit](https://www.brandit.com) (DEPRECATED) | `brandit` | DEPRECATED | [Additional configuration](https://go-acme.github.io/lego/dns/brandit) |
|
||||
| [Bunny](https://bunny.net) | `bunny` | `BUNNY_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/bunny) |
|
||||
| [Checkdomain](https://www.checkdomain.de/) | `checkdomain` | `CHECKDOMAIN_TOKEN`, | [Additional configuration](https://go-acme.github.io/lego/dns/checkdomain/) |
|
||||
| [Civo](https://www.civo.com/) | `civo` | `CIVO_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/civo) |
|
||||
@@ -334,7 +339,8 @@ For complete details, refer to your provider's _Additional configuration_ link.
|
||||
| [CloudDNS](https://vshosting.eu/) | `clouddns` | `CLOUDDNS_CLIENT_ID`, `CLOUDDNS_EMAIL`, `CLOUDDNS_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/clouddns) |
|
||||
| [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) |
|
||||
| [ClouDNS](https://www.cloudns.net/) | `cloudns` | `CLOUDNS_AUTH_ID`, `CLOUDNS_AUTH_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/cloudns) |
|
||||
| [CloudXNS](https://www.cloudxns.net) (DEPRECATED) | `cloudxns` | `CLOUDXNS_API_KEY`, `CLOUDXNS_SECRET_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/cloudxns) |
|
||||
| [CloudXNS](https://www.cloudxns.net) (DEPRECATED) | `cloudxns` | DEPRECATED | [Additional configuration](https://go-acme.github.io/lego/dns/cloudxns) |
|
||||
| [ConoHa v3](https://www.conoha.jp/) | `conohav3` | `CONOHAV3_TENANT_ID`, `CONOHAV3_API_USER_ID`, `CONOHAV3_API_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/conohav3) |
|
||||
| [ConoHa](https://www.conoha.jp) | `conoha` | `CONOHA_TENANT_ID`, `CONOHA_API_USERNAME`, `CONOHA_API_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/conoha) |
|
||||
| [Constellix](https://constellix.com) | `constellix` | `CONSTELLIX_API_KEY`, `CONSTELLIX_SECRET_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/constellix) |
|
||||
| [Core-Networks](https://www.core-networks.de) | `corenetworks` | `CORENETWORKS_LOGIN`, `CORENETWORKS_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/corenetworks) |
|
||||
@@ -346,18 +352,20 @@ For complete details, refer to your provider's _Additional configuration_ link.
|
||||
| [DNS Made Easy](https://dnsmadeeasy.com) | `dnsmadeeasy` | `DNSMADEEASY_API_KEY`, `DNSMADEEASY_API_SECRET`, `DNSMADEEASY_SANDBOX` | [Additional configuration](https://go-acme.github.io/lego/dns/dnsmadeeasy) |
|
||||
| [dnsHome.de](https://www.dnshome.de) | `dnsHomede` | `DNSHOMEDE_CREDENTIALS` | [Additional configuration](https://go-acme.github.io/lego/dns/dnshomede) |
|
||||
| [DNSimple](https://dnsimple.com) | `dnsimple` | `DNSIMPLE_OAUTH_TOKEN`, `DNSIMPLE_BASE_URL` | [Additional configuration](https://go-acme.github.io/lego/dns/dnsimple) |
|
||||
| [DNSPod](https://www.dnspod.com/) | `dnspod` | `DNSPOD_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/dnspod) |
|
||||
| [DNSPod](https://www.dnspod.com/) (DEPRECATED) | `dnspod` | DEPRECATED use `tencentcloud` instead. | [Additional configuration](https://go-acme.github.io/lego/dns/dnspod) |
|
||||
| [Domain Offensive (do.de)](https://www.do.de/) | `dode` | `DODE_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/dode) |
|
||||
| [Domeneshop](https://domene.shop) | `domeneshop` | `DOMENESHOP_API_TOKEN`, `DOMENESHOP_API_SECRET` | [Additional configuration](https://go-acme.github.io/lego/dns/domeneshop) |
|
||||
| [DreamHost](https://www.dreamhost.com/) | `dreamhost` | `DREAMHOST_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/dreamhost) |
|
||||
| [Duck DNS](https://www.duckdns.org/) | `duckdns` | `DUCKDNS_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/duckdns) |
|
||||
| [Dyn](https://dyn.com) | `dyn` | `DYN_CUSTOMER_NAME`, `DYN_USER_NAME`, `DYN_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/dyn) |
|
||||
| [DynDnsFree.de](https://www.dyndnsfree.de) | `dyndnsfree` | `DYNDNSFREE_USERNAME`, `DYNDNSFREE_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/dyndnsfree) |
|
||||
| [Dynu](https://www.dynu.com) | `dynu` | `DYNU_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/dynu) |
|
||||
| [EasyDNS](https://easydns.com/) | `easydns` | `EASYDNS_TOKEN`, `EASYDNS_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/easydns) |
|
||||
| [EdgeDNS](https://www.akamai.com/) | `edgedns` | `AKAMAI_CLIENT_TOKEN`, `AKAMAI_CLIENT_SECRET`, `AKAMAI_ACCESS_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/edgedns) |
|
||||
| [Efficient IP](https://efficientip.com) | `efficientip` | `EFFICIENTIP_USERNAME`, `EFFICIENTIP_PASSWORD`, `EFFICIENTIP_HOSTNAME`, `EFFICIENTIP_DNS_NAME` | [Additional configuration](https://go-acme.github.io/lego/dns/efficientip) |
|
||||
| [Epik](https://www.epik.com) | `epik` | `EPIK_SIGNATURE` | [Additional configuration](https://go-acme.github.io/lego/dns/epik) |
|
||||
| [Exoscale](https://www.exoscale.com) | `exoscale` | `EXOSCALE_API_KEY`, `EXOSCALE_API_SECRET`, `EXOSCALE_ENDPOINT` | [Additional configuration](https://go-acme.github.io/lego/dns/exoscale) |
|
||||
| [F5 XC](https://www.f5.com/products/distributed-cloud-services) | `f5xc` | `F5XC_API_TOKEN`, `F5XC_TENANT_NAME`, `F5XC_GROUP_NAME` | [Additional configuration](https://go-acme.github.io/lego/dns/f5xc) |
|
||||
| [Fast DNS](https://www.akamai.com/) | `fastdns` | `AKAMAI_CLIENT_TOKEN`, `AKAMAI_CLIENT_SECRET`, `AKAMAI_ACCESS_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/edgedns) |
|
||||
| [Freemyip.com](https://freemyip.com) | `freemyip` | `FREEMYIP_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/freemyip) |
|
||||
| [G-Core](https://gcore.com/dns/) | `gcore` | `GCORE_PERMANENT_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/gcore) |
|
||||
@@ -366,7 +374,7 @@ For complete details, refer to your provider's _Additional configuration_ link.
|
||||
| [Glesys](https://glesys.com/) | `glesys` | `GLESYS_API_USER`, `GLESYS_API_KEY`, `GLESYS_DOMAIN` | [Additional configuration](https://go-acme.github.io/lego/dns/glesys) |
|
||||
| [GoDaddy](https://www.godaddy.com) | `godaddy` | `GODADDY_API_KEY`, `GODADDY_API_SECRET` | [Additional configuration](https://go-acme.github.io/lego/dns/godaddy) |
|
||||
| [Google Cloud DNS](https://cloud.google.com/dns/docs/) | `gcloud` | `GCE_PROJECT`, Application Default Credentials [^2] [^3], [`GCE_SERVICE_ACCOUNT_FILE`] | [Additional configuration](https://go-acme.github.io/lego/dns/gcloud) |
|
||||
| [Google Domains](https://domains.google) | `googledomains` | `GOOGLE_DOMAINS_ACCESS_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/googledomains) |
|
||||
| [Google Domains](https://domains.google) (DEPRECATED) | `googledomains` | DEPRECATED | [Additional configuration](https://go-acme.github.io/lego/dns/googledomains) |
|
||||
| [Hetzner](https://hetzner.com) | `hetzner` | `HETZNER_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/hetzner) |
|
||||
| [hosting.de](https://www.hosting.de) | `hostingde` | `HOSTINGDE_API_KEY`, `HOSTINGDE_ZONE_NAME` | [Additional configuration](https://go-acme.github.io/lego/dns/hostingde) |
|
||||
| [Hosttech](https://www.hosttech.eu) | `hosttech` | `HOSTTECH_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/hosttech) |
|
||||
@@ -395,8 +403,10 @@ For complete details, refer to your provider's _Additional configuration_ link.
|
||||
| [Mail-in-a-Box](https://mailinabox.email) | `mailinabox` | `MAILINABOX_EMAIL`, `MAILINABOX_PASSWORD`, `MAILINABOX_BASE_URL` | [Additional configuration](https://go-acme.github.io/lego/dns/mailinabox) |
|
||||
| [ManageEngine CloudDNS](https://clouddns.manageengine.com) | `manageengine` | `MANAGEENGINE_CLIENT_ID`, `MANAGEENGINE_CLIENT_SECRET` | [Additional configuration](https://go-acme.github.io/lego/dns/manageengine) |
|
||||
| [Metaname](https://metaname.net) | `metaname` | `METANAME_ACCOUNT_REFERENCE`, `METANAME_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/metaname) |
|
||||
| [Metaregistrar](https://metaregistrar.com) | `metaregistrar` | `METAREGISTRAR_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/metaregistrar) |
|
||||
| [mijn.host](https://mijn.host/) | `mijnhost` | `MIJNHOST_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/mijnhost) |
|
||||
| [Mittwald](https://www.mittwald.de) | `mittwald` | `MITTWALD_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/mittwald) |
|
||||
| [myaddr.{tools,dev,io}](https://myaddr.tools/) | `myaddr` | `MYADDR_PRIVATE_KEYS_MAPPING` | [Additional configuration](https://go-acme.github.io/lego/dns/myaddr) |
|
||||
| [MyDNS.jp](https://www.mydns.jp/) | `mydnsjp` | `MYDNSJP_MASTER_ID`, `MYDNSJP_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/mydnsjp) |
|
||||
| [Mythic Beasts](https://www.mythic-beasts.com) | `mythicbeasts` | `MYTHICBEASTS_USER_NAME`, `MYTHICBEASTS_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/mythicbeasts) |
|
||||
| [name.com](https://www.name.com/) | `namedotcom` | `NAMECOM_USERNAME`, `NAMECOM_API_TOKEN`, `NAMECOM_SERVER` | [Additional configuration](https://go-acme.github.io/lego/dns/namedotcom) |
|
||||
@@ -425,6 +435,7 @@ For complete details, refer to your provider's _Additional configuration_ link.
|
||||
| [RFC2136](https://tools.ietf.org/html/rfc2136) | `rfc2136` | `RFC2136_TSIG_KEY`, `RFC2136_TSIG_SECRET`, `RFC2136_TSIG_ALGORITHM`, `RFC2136_NAMESERVER` | [Additional configuration](https://go-acme.github.io/lego/dns/rfc2136) |
|
||||
| [RimuHosting](https://rimuhosting.com) | `rimuhosting` | `RIMUHOSTING_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/rimuhosting) |
|
||||
| [Route 53](https://aws.amazon.com/route53/) | `route53` | `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `[AWS_REGION]`, `[AWS_HOSTED_ZONE_ID]` or a configured user/instance IAM profile. | [Additional configuration](https://go-acme.github.io/lego/dns/route53) |
|
||||
| [RU Center](https://nic.ru/) | `nicru` | `NICRU_USER`, `NICRU_PASSWORD`, `NICRU_SERVICE_ID`, `NICRU_SECRET`, `NICRU_SERVICE_NAME` | [Additional configuration](https://go-acme.github.io/lego/dns/nicru) |
|
||||
| [Sakura Cloud](https://cloud.sakura.ad.jp/) | `sakuracloud` | `SAKURACLOUD_ACCESS_TOKEN`, `SAKURACLOUD_ACCESS_TOKEN_SECRET` | [Additional configuration](https://go-acme.github.io/lego/dns/sakuracloud) |
|
||||
| [Scaleway](https://www.scaleway.com) | `scaleway` | `SCW_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/scaleway) |
|
||||
| [Selectel v2](https://selectel.ru/en/) | `selectelv2` | `SELECTELV2_ACCOUNT_ID`, `SELECTELV2_PASSWORD`, `SELECTELV2_PROJECT_ID`, `SELECTELV2_USERNAME` | [Additional configuration](https://go-acme.github.io/lego/dns/selectelv2) |
|
||||
@@ -434,6 +445,7 @@ For complete details, refer to your provider's _Additional configuration_ link.
|
||||
| [Shellrent](https://www.shellrent.com) | `shellrent` | `SHELLRENT_USERNAME`, `SHELLRENT_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/shellrent) |
|
||||
| [Simply.com](https://www.simply.com/en/domains/) | `simply` | `SIMPLY_ACCOUNT_NAME`, `SIMPLY_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/simply) |
|
||||
| [Sonic](https://www.sonic.com/) | `sonic` | `SONIC_USER_ID`, `SONIC_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/sonic) |
|
||||
| [Spaceship](https://spaceship.com) | `spaceship` | `SPACESHIP_API_KEY`, `SPACESHIP_API_SECRET` | [Additional configuration](https://go-acme.github.io/lego/dns/spaceship) |
|
||||
| [Stackpath](https://www.stackpath.com/) | `stackpath` | `STACKPATH_CLIENT_ID`, `STACKPATH_CLIENT_SECRET`, `STACKPATH_STACK_ID` | [Additional configuration](https://go-acme.github.io/lego/dns/stackpath) |
|
||||
| [Technitium](https://technitium.com) | `technitium` | `TECHNITIUM_SERVER_BASE_URL`, `TECHNITIUM_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/technitium) |
|
||||
| [Tencent Cloud DNS](https://cloud.tencent.com/product/cns) | `tencentcloud` | `TENCENTCLOUD_SECRET_ID`, `TENCENTCLOUD_SECRET_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/tencentcloud) |
|
||||
@@ -458,6 +470,7 @@ For complete details, refer to your provider's _Additional configuration_ link.
|
||||
| [Yandex Cloud](https://cloud.yandex.com/en/) | `yandexcloud` | `YANDEX_CLOUD_FOLDER_ID`, `YANDEX_CLOUD_IAM_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/yandexcloud) |
|
||||
| [Yandex](https://yandex.com) | `yandex` | `YANDEX_PDD_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/yandex) |
|
||||
| [Zone.ee](https://www.zone.ee) | `zoneee` | `ZONEEE_API_USER`, `ZONEEE_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/zoneee) |
|
||||
| [ZoneEdit](https://www.zoneedit.com) | `zoneedit` | `ZONEEDIT_USER`, `ZONEEDIT_AUTH_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/zoneedit) |
|
||||
| [Zonomi](https://zonomi.com) | `zonomi` | `ZONOMI_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/zonomi) |
|
||||
| External Program | `exec` | `EXEC_PATH` | [Additional configuration](https://go-acme.github.io/lego/dns/exec) |
|
||||
| HTTP request | `httpreq` | `HTTPREQ_ENDPOINT`, `HTTPREQ_MODE`, `HTTPREQ_USERNAME`, `HTTPREQ_PASSWORD` [^1] | [Additional configuration](https://go-acme.github.io/lego/dns/httpreq) |
|
||||
|
||||
@@ -242,7 +242,7 @@ The TLS options allow one to configure some parameters of the TLS connection.
|
||||
|
||||
!!! important "TLSOption in Kubernetes"
|
||||
|
||||
When using the [TLSOption resource](../../routing/providers/kubernetes-crd#kind-tlsoption) in Kubernetes, one might setup a default set of options that,
|
||||
When using the [TLSOption resource](../../routing/providers/kubernetes-crd/#kind-tlsoption) in Kubernetes, one might setup a default set of options that,
|
||||
if not explicitly overwritten, should apply to all ingresses.
|
||||
To achieve that, you'll have to create a TLSOption resource with the name `default`.
|
||||
There may exist only one TLSOption with the name `default` (across all namespaces) - otherwise they will be dropped.
|
||||
@@ -392,11 +392,11 @@ spec:
|
||||
|
||||
### Curve Preferences
|
||||
|
||||
This option allows to set the preferred elliptic curves in a specific order.
|
||||
This option allows to set the enabled elliptic curves for key exchange.
|
||||
|
||||
The names of the curves defined by [`crypto`](https://godoc.org/crypto/tls#CurveID) (e.g. `CurveP521`) and the [RFC defined names](https://tools.ietf.org/html/rfc8446#section-4.2.7) (e. g. `secp521r1`) can be used.
|
||||
|
||||
See [CurveID](https://godoc.org/crypto/tls#CurveID) for more information.
|
||||
See [CurvePreferences](https://godoc.org/crypto/tls#Config.CurvePreferences) and [CurveID](https://godoc.org/crypto/tls#CurveID) for more information.
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
# Dynamic configuration
|
||||
|
||||
@@ -331,3 +331,7 @@ The retry expression is defined as a logical combination of the functions below
|
||||
- `Attempts()` number of attempts (the first one counts)
|
||||
- `ResponseCode()` response code of the service
|
||||
- `IsNetworkError()` whether the response code is related to networking error
|
||||
|
||||
### Content-Length
|
||||
|
||||
See [Best Practices: Content‑Length](../../security/content-length.md)
|
||||
|
||||
@@ -12,8 +12,11 @@ Retrying until it Succeeds
|
||||
TODO: add schema
|
||||
-->
|
||||
|
||||
The Retry middleware reissues requests a given number of times to a backend server if that server does not reply.
|
||||
As soon as the server answers, the middleware stops retrying, regardless of the response status.
|
||||
The Retry middleware reissues requests a given number of times when it cannot contact the backend service.
|
||||
This applies at the transport level (TCP).
|
||||
If the service does not respond to the initial connection attempt, the middleware retries.
|
||||
However, once the service responds, regardless of the HTTP status code, the middleware considers it operational and stops retrying.
|
||||
This means that the retry mechanism does not handle HTTP errors; it only retries when there is no response at the TCP level.
|
||||
The Retry middleware has an optional configuration to enable an exponential backoff.
|
||||
|
||||
## Configuration Examples
|
||||
|
||||
@@ -656,3 +656,61 @@ Please check out the [entrypoint forwarded headers connection option configurati
|
||||
|
||||
In `v2.11.14`, the `X-Forwarded-Prefix` header is now handled like the other `X-Forwarded-*` headers: Traefik removes it when it's sent from an untrusted source.
|
||||
Please refer to the Forwarded headers [documentation](../routing/entrypoints.md#forwarded-headers) for more details.
|
||||
|
||||
## v2.11.24
|
||||
|
||||
### Request Path Sanitization
|
||||
|
||||
Since `v2.11.24`, the incoming request path is now cleaned before being used to match the router rules and sent to the backends.
|
||||
Any `/../`, `/./` or duplicate slash segments in the request path is interpreted and/or collapsed.
|
||||
|
||||
If you want to disable this behavior, you can set the [`sanitizePath` option](../routing/entrypoints.md#sanitizepath) to `false` in the entryPoint HTTP configuration.
|
||||
This can be useful when dealing with legacy clients that are not url-encoding data in the request path.
|
||||
For example, as base64 uses the “/” character internally,
|
||||
if it's not url encoded,
|
||||
it can lead to unsafe routing when the `sanitizePath` option is set to `false`.
|
||||
|
||||
!!! warning "Security"
|
||||
|
||||
Setting the `sanitizePath` option to `false` is not safe.
|
||||
Ensure every request is properly url encoded instead.
|
||||
|
||||
## v2.11.25
|
||||
|
||||
### Request Path Normalization
|
||||
|
||||
Since `v2.11.25`, the request path is now normalized by decoding unreserved characters in the request path,
|
||||
and also uppercasing the percent-encoded characters.
|
||||
This follows [RFC 3986 percent-encoding normalization](https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2.2),
|
||||
and [RFC 3986 case normalization](https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2.1).
|
||||
|
||||
The normalization happens before the request path is sanitized,
|
||||
and cannot be disabled.
|
||||
This notably helps with encoded dots characters (which are unreserved characters) to be sanitized properly.
|
||||
|
||||
### Routing Path
|
||||
|
||||
Since `v2.11.25`, the reserved characters [(as per RFC 3986)](https://datatracker.ietf.org/doc/html/rfc3986#section-2.2) are kept encoded in the request path when matching the router rules.
|
||||
Those characters, when decoded, change the meaning of the request path for routing purposes,
|
||||
and Traefik now keeps them encoded to avoid any ambiguity.
|
||||
|
||||
### Request Path Matching Examples
|
||||
|
||||
| Request Path | Router Rule | Traefik v2.11.24 | Traefik v2.11.25 |
|
||||
|-------------------|------------------------|------------------|------------------|
|
||||
| `/foo%2Fbar` | PathPrefix(`/foo/bar`) | Match | No match |
|
||||
| `/foo/../bar` | PathPrefix(`/foo`) | No match | No match |
|
||||
| `/foo/../bar` | PathPrefix(`/bar`) | Match | Match |
|
||||
| `/foo/%2E%2E/bar` | PathPrefix(`/foo`) | Match | No match |
|
||||
| `/foo/%2E%2E/bar` | PathPrefix(`/bar`) | No match | Match |
|
||||
|
||||
## v2.11.28
|
||||
|
||||
### MultiPath TCP
|
||||
|
||||
Since `v2.11.28`, the MultiPath TCP support introduced with `v2.11.26` has been removed.
|
||||
It appears that enabling MPTCP on some platforms can cause Traefik to stop with the following error logs message:
|
||||
|
||||
- `set tcp X.X.X.X:X->X.X.X.X:X: setsockopt: operation not supported`
|
||||
|
||||
However, it can be re-enabled by setting the `multipathtcp` variable in the GODEBUG environment variable, see the related [go documentation](https://go.dev/doc/godebug#go-124).
|
||||
|
||||
@@ -236,9 +236,7 @@ accessLog:
|
||||
| `OriginDuration` | The time taken (in nanoseconds) by the origin server ('upstream') to return its response. |
|
||||
| `OriginContentSize` | The content length specified by the origin server, or 0 if unspecified. |
|
||||
| `OriginStatus` | The HTTP status code returned by the origin server. If the request was handled by this Traefik instance (e.g. with a redirect), then this value will be absent (0). |
|
||||
| `OriginStatusLine` | `OriginStatus` + Status code explanation |
|
||||
| `DownstreamStatus` | The HTTP status code returned to the client. |
|
||||
| `DownstreamStatusLine` | `DownstreamStatus` + Status code explanation |
|
||||
| `DownstreamContentSize` | The number of bytes in the response entity returned to the client. This is in addition to the "Content-Length" header, which may be present in the origin response. |
|
||||
| `RequestCount` | The number of requests received since the Traefik instance started. |
|
||||
| `GzipRatio` | The response body compression ratio achieved. |
|
||||
|
||||
@@ -46,7 +46,7 @@ And then define a routing configuration on Traefik itself with the
|
||||
|
||||
--8<-- "content/operations/include-api-examples.md"
|
||||
|
||||
??? warning "The router's [rule](../../routing/routers#rule) must catch requests for the URI path `/api`"
|
||||
??? warning "The router's [rule](../../routing/routers/#rule) must catch requests for the URI path `/api`"
|
||||
Using an "Host" rule is recommended, by catching all the incoming traffic on this host domain to the API.
|
||||
However, you can also use "path prefix" rule or any combination or rules.
|
||||
|
||||
|
||||
@@ -301,7 +301,8 @@ _Optional_
|
||||
If `region` is not provided, it is resolved from the EC2 metadata endpoint for EC2 tasks.
|
||||
In a FARGATE context it is resolved from the `AWS_REGION` environment variable.
|
||||
|
||||
If `accessKeyID` and `secretAccessKey` are not provided, credentials are resolved in the following order:
|
||||
If `accessKeyID` and `secretAccessKey` are not provided, credentials are resolved in the order specified by the
|
||||
[default credential chain of AWS SDK for Go V2](https://docs.aws.amazon.com/sdk-for-go/v2/developer-guide/configure-gosdk.html#specifying-credentials):
|
||||
|
||||
- Using the environment variables `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, and `AWS_SESSION_TOKEN`.
|
||||
- Using shared credentials, determined by `AWS_PROFILE` and `AWS_SHARED_CREDENTIALS_FILE`, defaults to `default` and `~/.aws/credentials`.
|
||||
|
||||
@@ -10,6 +10,12 @@ A Story of KV store & Containers
|
||||
|
||||
Store your configuration in Redis and let Traefik do the rest!
|
||||
|
||||
!!! tip "Dynamic configuration updates"
|
||||
|
||||
Dynamic configuration updates require Redis [keyspace notifications](https://redis.io/docs/latest/develop/use/keyspace-notifications) to be enabled.
|
||||
Cloud-managed Redis services (e.g., GCP Memorystore, AWS ElastiCache) may disable this by default due to CPU performance issues.
|
||||
For more information, see the [Redis](https://redis.io/docs/latest/develop/use/keyspace-notifications/) documentation or refer to your cloud provider's documentation for specific configuration steps.
|
||||
|
||||
## Routing Configuration
|
||||
|
||||
See the dedicated section in [routing](../routing/providers/kv.md).
|
||||
|
||||
@@ -1478,7 +1478,7 @@ spec:
|
||||
properties:
|
||||
permanent:
|
||||
description: Permanent defines whether the redirection is permanent
|
||||
(301).
|
||||
(308).
|
||||
type: boolean
|
||||
regex:
|
||||
description: Regex defines the regex used to match and capture
|
||||
@@ -1497,7 +1497,7 @@ spec:
|
||||
properties:
|
||||
permanent:
|
||||
description: Permanent defines whether the redirection is permanent
|
||||
(301).
|
||||
(308).
|
||||
type: boolean
|
||||
port:
|
||||
description: Port defines the port of the new URL.
|
||||
@@ -1886,7 +1886,7 @@ spec:
|
||||
type: object
|
||||
curvePreferences:
|
||||
description: |-
|
||||
CurvePreferences defines the preferred elliptic curves in a specific order.
|
||||
CurvePreferences defines the preferred elliptic curves.
|
||||
More info: https://doc.traefik.io/traefik/v2.11/https/tls/#curve-preferences
|
||||
items:
|
||||
type: string
|
||||
@@ -3908,7 +3908,7 @@ spec:
|
||||
properties:
|
||||
permanent:
|
||||
description: Permanent defines whether the redirection is permanent
|
||||
(301).
|
||||
(308).
|
||||
type: boolean
|
||||
regex:
|
||||
description: Regex defines the regex used to match and capture
|
||||
@@ -3927,7 +3927,7 @@ spec:
|
||||
properties:
|
||||
permanent:
|
||||
description: Permanent defines whether the redirection is permanent
|
||||
(301).
|
||||
(308).
|
||||
type: boolean
|
||||
port:
|
||||
description: Port defines the port of the new URL.
|
||||
@@ -4316,7 +4316,7 @@ spec:
|
||||
type: object
|
||||
curvePreferences:
|
||||
description: |-
|
||||
CurvePreferences defines the preferred elliptic curves in a specific order.
|
||||
CurvePreferences defines the preferred elliptic curves.
|
||||
More info: https://doc.traefik.io/traefik/v2.11/https/tls/#curve-preferences
|
||||
items:
|
||||
type: string
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
CODE GENERATED AUTOMATICALLY
|
||||
THIS FILE MUST NOT BE EDITED BY HAND
|
||||
-->
|
||||
|
||||
| Key (Path) | Value |
|
||||
|------------|-------|
|
||||
| `traefik/http/middlewares/Middleware01/addPrefix/prefix` | `foobar` |
|
||||
| `traefik/http/middlewares/Middleware02/basicAuth/headerField` | `foobar` |
|
||||
| `traefik/http/middlewares/Middleware02/basicAuth/realm` | `foobar` |
|
||||
|
||||
@@ -8,6 +8,4 @@ description: "Read the technical documentation to learn the Traefik Dynamic Conf
|
||||
Dynamic configuration with KV stores.
|
||||
{: .subtitle }
|
||||
|
||||
| Key (Path) | Value |
|
||||
|----------------------------------------------------------------------------------------------|-------------|
|
||||
--8<-- "content/reference/dynamic-configuration/kv-ref.md"
|
||||
|
||||
@@ -863,7 +863,7 @@ spec:
|
||||
properties:
|
||||
permanent:
|
||||
description: Permanent defines whether the redirection is permanent
|
||||
(301).
|
||||
(308).
|
||||
type: boolean
|
||||
regex:
|
||||
description: Regex defines the regex used to match and capture
|
||||
@@ -882,7 +882,7 @@ spec:
|
||||
properties:
|
||||
permanent:
|
||||
description: Permanent defines whether the redirection is permanent
|
||||
(301).
|
||||
(308).
|
||||
type: boolean
|
||||
port:
|
||||
description: Port defines the port of the new URL.
|
||||
|
||||
@@ -78,7 +78,7 @@ spec:
|
||||
type: object
|
||||
curvePreferences:
|
||||
description: |-
|
||||
CurvePreferences defines the preferred elliptic curves in a specific order.
|
||||
CurvePreferences defines the preferred elliptic curves.
|
||||
More info: https://doc.traefik.io/traefik/v2.11/https/tls/#curve-preferences
|
||||
items:
|
||||
type: string
|
||||
|
||||
@@ -863,7 +863,7 @@ spec:
|
||||
properties:
|
||||
permanent:
|
||||
description: Permanent defines whether the redirection is permanent
|
||||
(301).
|
||||
(308).
|
||||
type: boolean
|
||||
regex:
|
||||
description: Regex defines the regex used to match and capture
|
||||
@@ -882,7 +882,7 @@ spec:
|
||||
properties:
|
||||
permanent:
|
||||
description: Permanent defines whether the redirection is permanent
|
||||
(301).
|
||||
(308).
|
||||
type: boolean
|
||||
port:
|
||||
description: Port defines the port of the new URL.
|
||||
|
||||
@@ -78,7 +78,7 @@ spec:
|
||||
type: object
|
||||
curvePreferences:
|
||||
description: |-
|
||||
CurvePreferences defines the preferred elliptic curves in a specific order.
|
||||
CurvePreferences defines the preferred elliptic curves.
|
||||
More info: https://doc.traefik.io/traefik/v2.11/https/tls/#curve-preferences
|
||||
items:
|
||||
type: string
|
||||
|
||||
@@ -141,6 +141,9 @@ Scheme used for the redirection. (Default: ```https```)
|
||||
`--entrypoints.<name>.http.redirections.entrypoint.to`:
|
||||
Targeted entry point of the redirection.
|
||||
|
||||
`--entrypoints.<name>.http.sanitizepath`:
|
||||
Defines whether to enable request path sanitization (removal of /./, /../ and multiple slash sequences). (Default: ```true```)
|
||||
|
||||
`--entrypoints.<name>.http.tls`:
|
||||
Default TLS configuration for the routers linked to the entry point. (Default: ```false```)
|
||||
|
||||
|
||||
@@ -150,6 +150,9 @@ Scheme used for the redirection. (Default: ```https```)
|
||||
`TRAEFIK_ENTRYPOINTS_<NAME>_HTTP_REDIRECTIONS_ENTRYPOINT_TO`:
|
||||
Targeted entry point of the redirection.
|
||||
|
||||
`TRAEFIK_ENTRYPOINTS_<NAME>_HTTP_SANITIZEPATH`:
|
||||
Defines whether to enable request path sanitization (removal of /./, /../ and multiple slash sequences). (Default: ```true```)
|
||||
|
||||
`TRAEFIK_ENTRYPOINTS_<NAME>_HTTP_TLS`:
|
||||
Default TLS configuration for the routers linked to the entry point. (Default: ```false```)
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
[entryPoints.EntryPoint0.http]
|
||||
middlewares = ["foobar", "foobar"]
|
||||
encodeQuerySemicolons = true
|
||||
sanitizePath = true
|
||||
[entryPoints.EntryPoint0.http.redirections]
|
||||
[entryPoints.EntryPoint0.http.redirections.entryPoint]
|
||||
to = "foobar"
|
||||
|
||||
@@ -63,6 +63,7 @@ entryPoints:
|
||||
- foobar
|
||||
- foobar
|
||||
encodeQuerySemicolons: true
|
||||
sanitizePath: true
|
||||
http2:
|
||||
maxConcurrentStreams: 42
|
||||
http3:
|
||||
|
||||
@@ -994,6 +994,56 @@ entryPoints:
|
||||
| false | foo=bar&baz=bar;foo | foo=bar&baz=bar&foo |
|
||||
| true | foo=bar&baz=bar;foo | foo=bar&baz=bar%3Bfoo |
|
||||
|
||||
### SanitizePath
|
||||
|
||||
_Optional, Default=true_
|
||||
|
||||
The `sanitizePath` option defines whether to enable the request path sanitization.
|
||||
When disabled, the incoming request path is passed to the backend as is.
|
||||
This can be useful when dealing with legacy clients that are not url-encoding data in the request path.
|
||||
For example, as base64 uses the “/” character internally,
|
||||
if it's not url encoded,
|
||||
it can lead to unsafe routing when the `sanitizePath` option is set to `false`.
|
||||
|
||||
!!! warning "Security"
|
||||
|
||||
Setting the sanitizePath option to false is not safe.
|
||||
Ensure every request is properly url encoded instead.
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
entryPoints:
|
||||
websecure:
|
||||
address: ':443'
|
||||
http:
|
||||
sanitizePath: false
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[entryPoints.websecure]
|
||||
address = ":443"
|
||||
|
||||
[entryPoints.websecure.http]
|
||||
sanitizePath = false
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--entryPoints.websecure.address=:443
|
||||
--entryPoints.websecure.http.sanitizePath=false
|
||||
```
|
||||
|
||||
#### Examples
|
||||
|
||||
| SanitizePath | Request Path | Resulting Request Path |
|
||||
|--------------|-----------------|------------------------|
|
||||
| false | /./foo/bar | /./foo/bar |
|
||||
| true | /./foo/bar | /foo/bar |
|
||||
| false | /foo/../bar | /foo/../bar |
|
||||
| true | /foo/../bar | /bar |
|
||||
| false | /foo/bar// | /foo/bar// |
|
||||
| true | /foo/bar// | /foo/bar/ |
|
||||
| false | /./foo/../bar// | /./foo/../bar// |
|
||||
| true | /./foo/../bar// | /bar/ |
|
||||
|
||||
### Middlewares
|
||||
|
||||
The list of middlewares that are prepended by default to the list of middlewares of each router associated to the named entry point.
|
||||
|
||||
@@ -10,8 +10,8 @@ What's Happening to the Requests?
|
||||
|
||||
Let's zoom in on Traefik's architecture and talk about the components that enable the routes to be created.
|
||||
|
||||
First, when you start Traefik, you define [entrypoints](../entrypoints) (in their most basic forms, they are port numbers).
|
||||
Then, connected to these entrypoints, [routers](../routers) analyze the incoming requests to see if they match a set of [rules](../routers#rule).
|
||||
First, when you start Traefik, you define [entrypoints](../entrypoints/) (in their most basic forms, they are port numbers).
|
||||
Then, connected to these entrypoints, [routers](../routers/) analyze the incoming requests to see if they match a set of [rules](../routers/#rule).
|
||||
If they do, the router might transform the request using pieces of [middleware](../middlewares/overview.md) before forwarding them to your [services](./services/index.md).
|
||||
|
||||

|
||||
@@ -325,6 +325,11 @@ serversTransport:
|
||||
--serversTransport.maxIdleConnsPerHost=7
|
||||
```
|
||||
|
||||
!!! info "Disable connection reuse"
|
||||
|
||||
The default value of `maxIdleConnsPerHost` is 2, and the zero value is the fallback to the default (2).
|
||||
If you want to disable connection reuse, set `maxIdleConnsPerHost` to -1.
|
||||
|
||||
### `forwardingTimeouts`
|
||||
|
||||
`forwardingTimeouts` is about a number of timeouts relevant to when forwarding requests to the backend servers.
|
||||
|
||||
@@ -1644,7 +1644,7 @@ or referencing TLS options in the [`IngressRoute`](#kind-ingressroute) / [`Ingre
|
||||
| [2] | `minVersion` | Defines the [minimum TLS version](../../https/tls.md#minimum-tls-version) that is acceptable. |
|
||||
| [3] | `maxVersion` | Defines the [maximum TLS version](../../https/tls.md#maximum-tls-version) that is acceptable. |
|
||||
| [4] | `cipherSuites` | list of supported [cipher suites](../../https/tls.md#cipher-suites) for TLS versions up to TLS 1.2. |
|
||||
| [5] | `curvePreferences` | List of the [elliptic curves references](../../https/tls.md#curve-preferences) that will be used in an ECDHE handshake, in preference order. |
|
||||
| [5] | `curvePreferences` | List of the [elliptic curves references](../../https/tls.md#curve-preferences) that will be used in an ECDHE handshake. |
|
||||
| [6] | `clientAuth` | determines the server's policy for TLS [Client Authentication](../../https/tls.md#client-authentication-mtls). |
|
||||
| [7] | `clientAuth.secretNames` | list of names of the referenced Kubernetes [Secrets](https://kubernetes.io/docs/concepts/configuration/secret/) (in TLSOption namespace). The secret must contain a certificate under either a `tls.ca` or a `ca.crt` key. |
|
||||
| [8] | `clientAuth.clientAuthType` | defines the client authentication type to apply. The available values are: `NoClientCert`, `RequestClientCert`, `VerifyClientCertIfGiven` and `RequireAndVerifyClientCert`. |
|
||||
|
||||
@@ -907,7 +907,7 @@ TLS certificates can be managed in Secrets objects.
|
||||
whether the LB's children are directly the pods IPs or if the only child is the Kubernetes Service clusterIP.
|
||||
|
||||
One alternative is to use an `ExternalName` service to forward requests to the Kubernetes service through DNS.
|
||||
To do so, one must [allow external name services](https://doc.traefik.io/traefik/providers/kubernetes-ingress/#allowexternalnameservices "Link to docs about allowing external name services").
|
||||
To do so, one must [allow external name services](../../../providers/kubernetes-ingress/#allowexternalnameservices "Link to docs about allowing external name services").
|
||||
|
||||
Traefik automatically requests endpoint information based on the service provided in the ingress spec.
|
||||
Although Traefik will connect directly to the endpoints (pods),
|
||||
|
||||
24
docs/content/security/content-length.md
Normal file
24
docs/content/security/content-length.md
Normal file
@@ -0,0 +1,24 @@
|
||||
---
|
||||
title: "Content-Length"
|
||||
description: "Enforce strict Content‑Length validation in Traefik by streaming or full buffering to prevent truncated or over‑long requests and responses. Read the technical documentation."
|
||||
---
|
||||
|
||||
Traefik acts as a streaming proxy. By default, it checks each chunk of data against the `Content-Length` header as it passes it on to the backend or client. This live check blocks truncated or over‑long streams without holding the entire message.
|
||||
|
||||
If you need Traefik to read and verify the full body before any data moves on, add the [buffering middleware](../middlewares/http/buffering.md):
|
||||
|
||||
```yaml
|
||||
http:
|
||||
middlewares:
|
||||
buffer-and-validate:
|
||||
buffering: {}
|
||||
```
|
||||
|
||||
With buffering enabled, Traefik will:
|
||||
|
||||
- Read the entire request or response into memory.
|
||||
- Compare the actual byte count to the `Content-Length` header.
|
||||
- Reject the message if the counts do not match.
|
||||
|
||||
!!!warning
|
||||
Buffering adds overhead. Every request and response is held in full before forwarding, which can increase memory use and latency. Use it when strict content validation is critical to your security posture.
|
||||
@@ -0,0 +1,38 @@
|
||||
---
|
||||
title: "TLS Certificates in Multi‑Tenant Kubernetes"
|
||||
description: "Isolate TLS certificates in multi‑tenant clusters by keeping Secrets and routes in the same namespace and disabling cross‑namespace look‑ups in Traefik. Read the technical guidelines."
|
||||
---
|
||||
|
||||
# TLS Certificates in Multi‑Tenant Kubernetes
|
||||
|
||||
In a shared cluster, different teams can create `Ingress` or `IngressRoute` objects that Traefik consumes.
|
||||
|
||||
Traefik does not support multi-tenancy when using the Kubernetes `Ingress` or `IngressRoute` specifications due to the way TLS certificate management is handled.
|
||||
|
||||
At the core of this limitation is the TLS Store, which holds all the TLS certificates used by Traefik.
|
||||
As this Store is global in Traefik, it is shared across all namespaces, meaning any `Ingress` or `IngressRoute` in the cluster can potentially reference or affect TLS configurations intended for other tenants.
|
||||
|
||||
This lack of isolation poses a risk in multi-tenant environments where different teams or applications require strict boundaries between resources, especially around sensitive data like TLS certificates.
|
||||
|
||||
In contrast, the [Kubernetes Gateway API](../providers/kubernetes-gateway.md) provides better primitives for secure multi-tenancy.
|
||||
Specifically, the `Listener` resource in the Gateway API allows administrators to explicitly define which Route resources (e.g., `HTTPRoute`) are permitted to bind to which domain names or ports.
|
||||
This capability enforces stricter ownership and isolation, making it a safer choice for multi-tenant use cases.
|
||||
|
||||
## Recommended setup
|
||||
|
||||
When strict boundaries are required between resources and teams, we recommend using one Traefik instance per tenant.
|
||||
|
||||
In Kubernetes one way to isolate a tenant is to restrict it to a namespace.
|
||||
In that case, the namespace options from the Kubernetes [CRD](../providers/kubernetes-crd.md#namespaces) and [Ingress](../providers/kubernetes-ingress.md#namespaces) providers can be leveraged.
|
||||
|
||||
!!! tip "Dedicate one Traefik instance per tenant using the Helm Chart"
|
||||
|
||||
```yaml
|
||||
providers:
|
||||
kubernetesCRD:
|
||||
namespaces:
|
||||
- tenant
|
||||
kubernetesIngress:
|
||||
namespaces:
|
||||
- tenant
|
||||
```
|
||||
@@ -6,7 +6,7 @@ description: "Learn how to create a certificate with the Let's Encrypt DNS chall
|
||||
# Docker-compose with Let's Encrypt: DNS Challenge
|
||||
|
||||
This guide aims to demonstrate how to create a certificate with the Let's Encrypt DNS challenge to use https on a simple service exposed with Traefik.
|
||||
Please also read the [basic example](../basic-example) for details on how to expose such a service.
|
||||
Please also read the [basic example](../basic-example/) for details on how to expose such a service.
|
||||
|
||||
## Prerequisite
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ ports:
|
||||
- "443:443"
|
||||
```
|
||||
|
||||
- We configure the HTTPS Let's Encrypt challenge:
|
||||
- We configure the HTTP Let's Encrypt challenge:
|
||||
|
||||
```yaml
|
||||
command:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM alpine:3.21
|
||||
FROM alpine:3.22
|
||||
|
||||
ENV PATH="${PATH}:/venv/bin"
|
||||
|
||||
|
||||
@@ -165,6 +165,10 @@ nav:
|
||||
- 'Instana': 'observability/tracing/instana.md'
|
||||
- 'Haystack': 'observability/tracing/haystack.md'
|
||||
- 'Elastic': 'observability/tracing/elastic.md'
|
||||
- 'OpenTelemetry': 'observability/tracing/opentelemetry.md'
|
||||
- 'Security':
|
||||
- 'Content-Length': 'security/content-length.md'
|
||||
- 'TLS in Multi-Tenant Kubernetes': 'security/tls-certs-in-multi-tenant-kubernetes.md'
|
||||
- 'User Guides':
|
||||
- 'Kubernetes and Let''s Encrypt': 'user-guides/crd-acme/index.md'
|
||||
- 'gRPC Examples': 'user-guides/grpc.md'
|
||||
|
||||
376
go.mod
376
go.mod
@@ -1,29 +1,35 @@
|
||||
module github.com/traefik/traefik/v2
|
||||
|
||||
go 1.23.0
|
||||
go 1.24.0
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v1.4.0
|
||||
github.com/BurntSushi/toml v1.5.0
|
||||
github.com/ExpediaDotCom/haystack-client-go v0.0.0-20190315171017-e7edbdf53a61 // No tag on the repo.
|
||||
github.com/Masterminds/sprig/v3 v3.2.3
|
||||
github.com/abbot/go-http-auth v0.0.0-00010101000000-000000000000
|
||||
github.com/aws/aws-sdk-go v1.44.327
|
||||
github.com/aws/aws-sdk-go-v2 v1.36.6
|
||||
github.com/aws/aws-sdk-go-v2/config v1.29.18
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.71
|
||||
github.com/aws/aws-sdk-go-v2/service/ec2 v1.203.1
|
||||
github.com/aws/aws-sdk-go-v2/service/ecs v1.53.15
|
||||
github.com/aws/aws-sdk-go-v2/service/ssm v1.56.13
|
||||
github.com/aws/smithy-go v1.22.4
|
||||
github.com/cenkalti/backoff/v4 v4.3.0
|
||||
github.com/containous/alice v0.0.0-20181107144136-d83ebdd94cbd // No tag on the repo.
|
||||
github.com/coreos/go-systemd/v22 v22.5.0
|
||||
github.com/docker/cli v27.1.1+incompatible
|
||||
github.com/docker/docker v27.1.1+incompatible
|
||||
github.com/docker/cli v28.3.3+incompatible
|
||||
github.com/docker/docker v28.3.3+incompatible
|
||||
github.com/docker/go-connections v0.5.0
|
||||
github.com/fatih/structs v1.1.0
|
||||
github.com/fsnotify/fsnotify v1.8.0
|
||||
github.com/fsnotify/fsnotify v1.9.0
|
||||
github.com/gambol99/go-marathon v0.0.0-20180614232016-99a156b96fb2 // No tag on the repo.
|
||||
github.com/go-acme/lego/v4 v4.21.0
|
||||
github.com/go-acme/lego/v4 v4.25.2
|
||||
github.com/go-kit/kit v0.13.0
|
||||
github.com/go-kit/log v0.2.1
|
||||
github.com/golang/protobuf v1.5.4
|
||||
github.com/google/go-github/v28 v28.1.1
|
||||
github.com/gorilla/mux v1.8.1
|
||||
github.com/gorilla/websocket v1.5.0
|
||||
github.com/gorilla/websocket v1.5.3
|
||||
github.com/hashicorp/consul/api v1.26.1
|
||||
github.com/hashicorp/go-hclog v1.6.3
|
||||
github.com/hashicorp/go-multierror v1.1.1
|
||||
@@ -32,176 +38,192 @@ require (
|
||||
github.com/influxdata/influxdb-client-go/v2 v2.7.0
|
||||
github.com/influxdata/influxdb1-client v0.0.0-20200827194710-b269163b24ab // No tag on the repo.
|
||||
github.com/instana/go-sensor v1.38.3
|
||||
github.com/klauspost/compress v1.17.11-0.20241004063537-dbd6c381492a // Required to have the content-type fix: https://github.com/klauspost/compress/pull/1013
|
||||
github.com/klauspost/compress v1.18.0
|
||||
github.com/kvtools/consul v1.0.2
|
||||
github.com/kvtools/etcdv3 v1.0.2
|
||||
github.com/kvtools/redis v1.1.0
|
||||
github.com/kvtools/valkeyrie v1.0.0
|
||||
github.com/kvtools/zookeeper v1.0.2
|
||||
github.com/mailgun/ttlmap v0.0.0-20170619185759-c1c17f74874f // No tag on the repo.
|
||||
github.com/miekg/dns v1.1.62
|
||||
github.com/miekg/dns v1.1.67
|
||||
github.com/mitchellh/copystructure v1.2.0
|
||||
github.com/mitchellh/hashstructure v1.0.0
|
||||
github.com/mitchellh/mapstructure v1.5.0
|
||||
github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c
|
||||
github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // No tag on the repo.
|
||||
github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5
|
||||
github.com/openzipkin/zipkin-go v0.2.5
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||
github.com/pires/go-proxyproto v0.6.1
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // No tag on the repo.
|
||||
github.com/prometheus/client_golang v1.19.1
|
||||
github.com/prometheus/client_model v0.5.0
|
||||
github.com/quic-go/quic-go v0.48.2
|
||||
github.com/prometheus/client_golang v1.22.0
|
||||
github.com/prometheus/client_model v0.6.1
|
||||
github.com/quic-go/quic-go v0.55.0
|
||||
github.com/rancher/go-rancher-metadata v0.0.0-20200311180630-7f4c936a06ac // No tag on the repo.
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
github.com/stretchr/testify v1.10.0
|
||||
github.com/stvp/go-udp-testing v0.0.0-20191102171040-06b61409b154 // No tag on the repo.
|
||||
github.com/testcontainers/testcontainers-go v0.32.0
|
||||
github.com/traefik/paerser v0.2.1
|
||||
github.com/traefik/paerser v0.2.2
|
||||
github.com/traefik/yaegi v0.16.1
|
||||
github.com/uber/jaeger-client-go v2.30.0+incompatible
|
||||
github.com/uber/jaeger-lib v2.4.1+incompatible
|
||||
github.com/unrolled/render v1.0.2
|
||||
github.com/unrolled/secure v1.0.9
|
||||
github.com/vulcand/oxy/v2 v2.0.0
|
||||
github.com/vulcand/oxy/v2 v2.0.3
|
||||
github.com/vulcand/predicate v1.2.0
|
||||
go.elastic.co/apm/module/apmot/v2 v2.4.8
|
||||
go.elastic.co/apm/v2 v2.4.8
|
||||
golang.org/x/mod v0.22.0
|
||||
golang.org/x/net v0.33.0
|
||||
golang.org/x/text v0.21.0
|
||||
golang.org/x/time v0.8.0
|
||||
golang.org/x/tools v0.28.0
|
||||
google.golang.org/grpc v1.67.1
|
||||
gopkg.in/DataDog/dd-trace-go.v1 v1.56.1
|
||||
golang.org/x/mod v0.28.0
|
||||
golang.org/x/net v0.46.0
|
||||
golang.org/x/text v0.30.0
|
||||
golang.org/x/time v0.12.0
|
||||
golang.org/x/tools v0.37.0
|
||||
google.golang.org/grpc v1.73.0
|
||||
gopkg.in/DataDog/dd-trace-go.v1 v1.74.6
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
k8s.io/api v0.26.3
|
||||
k8s.io/api v0.32.3
|
||||
k8s.io/apiextensions-apiserver v0.26.3
|
||||
k8s.io/apimachinery v0.26.3
|
||||
k8s.io/client-go v0.26.3
|
||||
k8s.io/utils v0.0.0-20230313181309-38a27ef9d749 // No tag on the repo.
|
||||
k8s.io/apimachinery v0.32.3
|
||||
k8s.io/client-go v0.32.3
|
||||
k8s.io/utils v0.0.0-20241210054802-24370beab758 // No tag on the repo.
|
||||
mvdan.cc/xurls/v2 v2.5.0
|
||||
sigs.k8s.io/gateway-api v0.4.0
|
||||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go/auth v0.13.0 // indirect
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.6 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.6.0 // indirect
|
||||
dario.cat/mergo v1.0.0 // indirect
|
||||
cloud.google.com/go/auth v0.16.2 // indirect
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.7.0 // indirect
|
||||
dario.cat/mergo v1.0.1 // indirect
|
||||
github.com/AdamSLevy/jsonrpc2/v14 v14.1.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go v68.0.0+incompatible // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.16.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.1 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.10.1 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/dns/armdns v1.2.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/privatedns/armprivatedns v1.3.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resourcegraph/armresourcegraph v0.9.0 // indirect
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
|
||||
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
|
||||
github.com/Azure/go-autorest/autorest v0.11.29 // indirect
|
||||
github.com/Azure/go-autorest/autorest v0.11.30 // indirect
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.22 // indirect
|
||||
github.com/Azure/go-autorest/autorest/azure/auth v0.5.13 // indirect
|
||||
github.com/Azure/go-autorest/autorest/azure/cli v0.4.6 // indirect
|
||||
github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect
|
||||
github.com/Azure/go-autorest/autorest/to v0.4.0 // indirect
|
||||
github.com/Azure/go-autorest/autorest/to v0.4.1 // indirect
|
||||
github.com/Azure/go-autorest/logger v0.2.1 // indirect
|
||||
github.com/Azure/go-autorest/tracing v0.6.0 // indirect
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 // indirect
|
||||
github.com/DataDog/appsec-internal-go v1.0.0 // indirect
|
||||
github.com/DataDog/datadog-agent/pkg/obfuscate v0.48.0 // indirect
|
||||
github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.48.0-devel.0.20230725154044-2549ba9058df // indirect
|
||||
github.com/DataDog/datadog-go/v5 v5.3.0 // indirect
|
||||
github.com/DataDog/go-libddwaf v1.5.0 // indirect
|
||||
github.com/DataDog/go-tuf v1.0.2-0.5.2 // indirect
|
||||
github.com/DataDog/sketches-go v1.4.2 // indirect
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 // indirect
|
||||
github.com/DataDog/appsec-internal-go v1.13.0 // indirect
|
||||
github.com/DataDog/datadog-agent/comp/core/tagger/origindetection v0.67.0 // indirect
|
||||
github.com/DataDog/datadog-agent/pkg/obfuscate v0.67.0 // indirect
|
||||
github.com/DataDog/datadog-agent/pkg/proto v0.67.0 // indirect
|
||||
github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.69.0 // indirect
|
||||
github.com/DataDog/datadog-agent/pkg/trace v0.67.0 // indirect
|
||||
github.com/DataDog/datadog-agent/pkg/util/log v0.67.0 // indirect
|
||||
github.com/DataDog/datadog-agent/pkg/util/scrubber v0.67.0 // indirect
|
||||
github.com/DataDog/datadog-agent/pkg/version v0.67.0 // indirect
|
||||
github.com/DataDog/datadog-go/v5 v5.6.0 // indirect
|
||||
github.com/DataDog/dd-trace-go/v2 v2.2.3 // indirect
|
||||
github.com/DataDog/go-libddwaf/v4 v4.3.2 // indirect
|
||||
github.com/DataDog/go-runtime-metrics-internal v0.0.4-0.20250721125240-fdf1ef85b633 // indirect
|
||||
github.com/DataDog/go-sqllexer v0.1.6 // indirect
|
||||
github.com/DataDog/go-tuf v1.1.0-0.5.2 // indirect
|
||||
github.com/DataDog/opentelemetry-mapping-go/pkg/otlp/attributes v0.27.0 // indirect
|
||||
github.com/DataDog/sketches-go v1.4.7 // indirect
|
||||
github.com/HdrHistogram/hdrhistogram-go v1.1.2 // indirect
|
||||
github.com/Masterminds/goutils v1.1.1 // indirect
|
||||
github.com/Masterminds/semver/v3 v3.2.1 // indirect
|
||||
github.com/Masterminds/semver/v3 v3.3.1 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.2 // indirect
|
||||
github.com/Microsoft/hcsshim v0.11.7 // indirect
|
||||
github.com/Microsoft/hcsshim v0.13.0 // indirect
|
||||
github.com/OpenDNS/vegadns2client v0.0.0-20180418235048-a3fa4a771d87 // indirect
|
||||
github.com/VividCortex/gohistogram v1.0.0 // indirect
|
||||
github.com/akamai/AkamaiOPEN-edgegrid-golang v1.2.2 // indirect
|
||||
github.com/aliyun/alibaba-cloud-sdk-go v1.63.72 // indirect
|
||||
github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.5 // indirect
|
||||
github.com/alibabacloud-go/darabonba-openapi/v2 v2.1.8 // indirect
|
||||
github.com/alibabacloud-go/debug v1.0.1 // indirect
|
||||
github.com/alibabacloud-go/endpoint-util v1.1.0 // indirect
|
||||
github.com/alibabacloud-go/openapi-util v0.1.1 // indirect
|
||||
github.com/alibabacloud-go/tea v1.3.9 // indirect
|
||||
github.com/alibabacloud-go/tea-utils/v2 v2.0.7 // indirect
|
||||
github.com/aliyun/credentials-go v1.4.6 // indirect
|
||||
github.com/armon/go-metrics v0.4.1 // indirect
|
||||
github.com/armon/go-radix v1.0.1-0.20221118154546-54df44f2176c // indirect
|
||||
github.com/aws/aws-sdk-go-v2 v1.32.7 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/config v1.28.7 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.48 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.22 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.26 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.26 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.7 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/lightsail v1.42.8 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/route53 v1.46.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.24.8 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.7 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.33.3 // indirect
|
||||
github.com/aws/smithy-go v1.22.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.33 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.37 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.37 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.18 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/lightsail v1.43.5 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/route53 v1.53.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.25.6 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.34.1 // indirect
|
||||
github.com/aziontech/azionapi-go-sdk v0.142.0 // indirect
|
||||
github.com/baidubce/bce-sdk-go v0.9.235 // indirect
|
||||
github.com/benbjohnson/clock v1.3.0 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/civo/civogo v0.3.11 // indirect
|
||||
github.com/cloudflare/cloudflare-go v0.112.0 // indirect
|
||||
github.com/containerd/containerd v1.7.20 // indirect
|
||||
github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575 // indirect
|
||||
github.com/clbanning/mxj/v2 v2.7.0 // indirect
|
||||
github.com/containerd/containerd v1.7.23 // indirect
|
||||
github.com/containerd/errdefs v1.0.0 // indirect
|
||||
github.com/containerd/errdefs/pkg v0.3.0 // indirect
|
||||
github.com/containerd/log v0.1.0 // indirect
|
||||
github.com/containerd/platforms v0.2.1 // indirect
|
||||
github.com/containerd/platforms v1.0.0-rc.1 // indirect
|
||||
github.com/coreos/go-semver v0.3.0 // indirect
|
||||
github.com/cpu/goacmedns v0.1.1 // indirect
|
||||
github.com/cpuguy83/dockercfg v0.3.1 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/deepmap/oapi-codegen v1.9.1 // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/dimchansky/utfbom v1.1.1 // indirect
|
||||
github.com/distribution/reference v0.6.0 // indirect
|
||||
github.com/dnsimple/dnsimple-go v1.7.0 // indirect
|
||||
github.com/dnsimple/dnsimple-go/v4 v4.0.0 // indirect
|
||||
github.com/docker/go-units v0.5.0 // indirect
|
||||
github.com/donovanhide/eventsource v0.0.0-20170630084216-b8f31a59085e // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/ebitengine/purego v0.5.0-alpha.1 // indirect
|
||||
github.com/eapache/queue/v2 v2.0.0-20230407133247-75960ed334e4 // indirect
|
||||
github.com/ebitengine/purego v0.8.3 // indirect
|
||||
github.com/elastic/go-sysinfo v1.7.1 // indirect
|
||||
github.com/elastic/go-windows v1.0.0 // indirect
|
||||
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
|
||||
github.com/evanphx/json-patch v4.12.0+incompatible // indirect
|
||||
github.com/exoscale/egoscale/v3 v3.1.7 // indirect
|
||||
github.com/exoscale/egoscale/v3 v3.1.24 // indirect
|
||||
github.com/fatih/color v1.16.0 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
|
||||
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
|
||||
github.com/ghodss/yaml v1.0.0 // indirect
|
||||
github.com/go-acme/alidns-20150109/v4 v4.5.10 // indirect
|
||||
github.com/go-acme/tencentclouddnspod v1.0.1208 // indirect
|
||||
github.com/go-errors/errors v1.0.1 // indirect
|
||||
github.com/go-jose/go-jose/v4 v4.0.4 // indirect
|
||||
github.com/go-jose/go-jose/v4 v4.1.1 // indirect
|
||||
github.com/go-logfmt/logfmt v0.5.1 // indirect
|
||||
github.com/go-logr/logr v1.4.2 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.5 // indirect
|
||||
github.com/go-openapi/jsonreference v0.20.0 // indirect
|
||||
github.com/go-openapi/swag v0.19.14 // indirect
|
||||
github.com/go-ole/go-ole v1.3.0 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.21.0 // indirect
|
||||
github.com/go-openapi/jsonreference v0.20.2 // indirect
|
||||
github.com/go-openapi/swag v0.23.0 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.16.0 // indirect
|
||||
github.com/go-resty/resty/v2 v2.16.2 // indirect
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.23.0 // indirect
|
||||
github.com/go-resty/resty/v2 v2.16.5 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
|
||||
github.com/go-zookeeper/zk v1.0.3 // indirect
|
||||
github.com/goccy/go-json v0.10.4 // indirect
|
||||
github.com/gofrs/flock v0.12.1 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.5.1 // indirect
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1 // indirect
|
||||
github.com/google/gnostic v0.5.7-v3refs // indirect
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.5.2 // indirect
|
||||
github.com/golang-jwt/jwt/v5 v5.2.2 // indirect
|
||||
github.com/google/gnostic-models v0.6.8 // indirect
|
||||
github.com/google/go-cmp v0.7.0 // indirect
|
||||
github.com/google/go-querystring v1.1.0 // indirect
|
||||
github.com/google/gofuzz v1.2.0 // indirect
|
||||
github.com/google/pprof v0.0.0-20240910150728-a0b0bb1d4134 // indirect
|
||||
github.com/google/s2a-go v0.1.8 // indirect
|
||||
github.com/google/s2a-go v0.1.9 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.4 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.14.0 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.14.2 // indirect
|
||||
github.com/gophercloud/gophercloud v1.14.1 // indirect
|
||||
github.com/gophercloud/utils v0.0.0-20231010081019-80377eca5d56 // indirect
|
||||
github.com/gravitational/trace v1.1.16-0.20220114165159-14a9a7dd6aaf // indirect
|
||||
@@ -209,19 +231,18 @@ require (
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
|
||||
github.com/hashicorp/go-retryablehttp v0.7.7 // indirect
|
||||
github.com/hashicorp/go-retryablehttp v0.7.8 // indirect
|
||||
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
|
||||
github.com/hashicorp/go-uuid v1.0.3 // indirect
|
||||
github.com/hashicorp/golang-lru v1.0.2 // indirect
|
||||
github.com/hashicorp/hcl v1.0.1-vault-5 // indirect
|
||||
github.com/hashicorp/serf v0.10.1 // indirect
|
||||
github.com/huandu/xstrings v1.5.0 // indirect
|
||||
github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.128 // indirect
|
||||
github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.159 // indirect
|
||||
github.com/iij/doapi v0.0.0-20190504054126-0bbf12d6d7df // indirect
|
||||
github.com/imdario/mergo v0.3.16 // indirect
|
||||
github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 // indirect
|
||||
github.com/infobloxopen/infoblox-go-client v1.1.1 // indirect
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
github.com/infobloxopen/infoblox-go-client/v2 v2.10.0 // indirect
|
||||
github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 // indirect
|
||||
github.com/jonboulle/clockwork v0.4.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
@@ -231,149 +252,162 @@ require (
|
||||
github.com/kylelemons/godebug v1.1.0 // indirect
|
||||
github.com/labbsr0x/bindman-dns-webhook v1.0.2 // indirect
|
||||
github.com/labbsr0x/goh v1.0.1 // indirect
|
||||
github.com/leodido/go-urn v1.2.4 // indirect
|
||||
github.com/linode/linodego v1.44.0 // indirect
|
||||
github.com/leodido/go-urn v1.4.0 // indirect
|
||||
github.com/linode/linodego v1.53.0 // indirect
|
||||
github.com/liquidweb/liquidweb-cli v0.6.9 // indirect
|
||||
github.com/liquidweb/liquidweb-go v1.6.4 // indirect
|
||||
github.com/looplab/fsm v0.1.0 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20250317134145-8bc96cf8fc35 // indirect
|
||||
github.com/magiconair/properties v1.8.7 // indirect
|
||||
github.com/mailgun/minheap v0.0.0-20170619185613-3dbe6c6bf55f // indirect
|
||||
github.com/mailgun/multibuf v0.1.2 // indirect
|
||||
github.com/mailgun/timetools v0.0.0-20141028012446-7e6055773c51 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mimuret/golang-iij-dpf v0.9.1 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
||||
github.com/moby/docker-image-spec v1.3.1 // indirect
|
||||
github.com/moby/go-archive v0.1.0 // indirect
|
||||
github.com/moby/patternmatcher v0.6.0 // indirect
|
||||
github.com/moby/sys/sequential v0.5.0 // indirect
|
||||
github.com/moby/sys/user v0.2.0 // indirect
|
||||
github.com/moby/term v0.5.0 // indirect
|
||||
github.com/moby/sys/atomicwriter v0.1.0 // indirect
|
||||
github.com/moby/sys/sequential v0.6.0 // indirect
|
||||
github.com/moby/sys/user v0.4.0 // indirect
|
||||
github.com/moby/sys/userns v0.1.0 // indirect
|
||||
github.com/moby/term v0.5.2 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
|
||||
github.com/morikuni/aec v1.0.0 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04 // indirect
|
||||
github.com/namedotcom/go/v4 v4.0.2 // indirect
|
||||
github.com/nrdcg/auroradns v1.1.0 // indirect
|
||||
github.com/nrdcg/bunny-go v0.0.0-20240207213615-dde5bf4577a3 // indirect
|
||||
github.com/nrdcg/desec v0.10.0 // indirect
|
||||
github.com/nrdcg/bunny-go v0.0.0-20250327222614-988a091fc7ea // indirect
|
||||
github.com/nrdcg/desec v0.11.0 // indirect
|
||||
github.com/nrdcg/dnspod-go v0.4.0 // indirect
|
||||
github.com/nrdcg/freemyip v0.3.0 // indirect
|
||||
github.com/nrdcg/goinwx v0.10.0 // indirect
|
||||
github.com/nrdcg/goacmedns v0.2.0 // indirect
|
||||
github.com/nrdcg/goinwx v0.11.0 // indirect
|
||||
github.com/nrdcg/mailinabox v0.2.0 // indirect
|
||||
github.com/nrdcg/namesilo v0.2.1 // indirect
|
||||
github.com/nrdcg/nodion v0.1.0 // indirect
|
||||
github.com/nrdcg/oci-go-sdk/common/v1065 v1065.95.2 // indirect
|
||||
github.com/nrdcg/oci-go-sdk/dns/v1065 v1065.95.2 // indirect
|
||||
github.com/nrdcg/porkbun v0.4.0 // indirect
|
||||
github.com/nzdjb/go-metaname v1.0.0 // indirect
|
||||
github.com/onsi/ginkgo v1.16.5 // indirect
|
||||
github.com/onsi/ginkgo/v2 v2.20.2 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.1.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.1.1 // indirect
|
||||
github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492 // indirect
|
||||
github.com/oracle/oci-go-sdk/v65 v65.81.1 // indirect
|
||||
github.com/outcaste-io/ristretto v0.2.3 // indirect
|
||||
github.com/ovh/go-ovh v1.6.0 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
|
||||
github.com/ovh/go-ovh v1.9.0 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
||||
github.com/peterhellberg/link v1.2.0 // indirect
|
||||
github.com/philhofer/fwd v1.1.2 // indirect
|
||||
github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c // indirect
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
|
||||
github.com/pquerna/otp v1.4.0 // indirect
|
||||
github.com/prometheus/common v0.48.0 // indirect
|
||||
github.com/prometheus/procfs v0.15.1 // indirect
|
||||
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
|
||||
github.com/pquerna/otp v1.5.0 // indirect
|
||||
github.com/prometheus/common v0.62.0 // indirect
|
||||
github.com/prometheus/procfs v0.16.1 // indirect
|
||||
github.com/puzpuzpuz/xsync/v3 v3.5.1 // indirect
|
||||
github.com/quic-go/qpack v0.5.1 // indirect
|
||||
github.com/redis/go-redis/v9 v9.6.1 // indirect
|
||||
github.com/redis/go-redis/v9 v9.8.0 // indirect
|
||||
github.com/regfish/regfish-dnsapi-go v0.1.1 // indirect
|
||||
github.com/sacloud/api-client-go v0.2.10 // indirect
|
||||
github.com/sacloud/go-http v0.1.8 // indirect
|
||||
github.com/sacloud/iaas-api-go v1.14.0 // indirect
|
||||
github.com/sacloud/packages-go v0.0.10 // indirect
|
||||
github.com/sacloud/api-client-go v0.3.2 // indirect
|
||||
github.com/sacloud/go-http v0.1.9 // indirect
|
||||
github.com/sacloud/iaas-api-go v1.16.1 // indirect
|
||||
github.com/sacloud/packages-go v0.0.11 // indirect
|
||||
github.com/sagikazarmark/locafero v0.4.0 // indirect
|
||||
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
|
||||
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.30 // indirect
|
||||
github.com/secure-systems-lab/go-securesystemslib v0.7.0 // indirect
|
||||
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.34 // indirect
|
||||
github.com/secure-systems-lab/go-securesystemslib v0.9.0 // indirect
|
||||
github.com/segmentio/fasthash v1.0.3 // indirect
|
||||
github.com/selectel/domains-go v1.1.0 // indirect
|
||||
github.com/selectel/go-selvpcclient/v3 v3.2.1 // indirect
|
||||
github.com/shirou/gopsutil/v3 v3.23.12 // indirect
|
||||
github.com/selectel/go-selvpcclient/v4 v4.1.0 // indirect
|
||||
github.com/shirou/gopsutil/v3 v3.24.4 // indirect
|
||||
github.com/shirou/gopsutil/v4 v4.25.3 // indirect
|
||||
github.com/shoenig/go-m1cpu v0.1.6 // indirect
|
||||
github.com/shopspring/decimal v1.4.0 // indirect
|
||||
github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9 // indirect
|
||||
github.com/softlayer/softlayer-go v1.1.7 // indirect
|
||||
github.com/softlayer/xmlrpc v0.0.0-20200409220501-5f089df7cb7e // indirect
|
||||
github.com/sony/gobreaker v0.5.0 // indirect
|
||||
github.com/sony/gobreaker v1.0.0 // indirect
|
||||
github.com/sourcegraph/conc v0.3.0 // indirect
|
||||
github.com/spf13/afero v1.11.0 // indirect
|
||||
github.com/spf13/cast v1.7.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/spf13/pflag v1.0.6 // indirect
|
||||
github.com/spf13/viper v1.18.2 // indirect
|
||||
github.com/stretchr/objx v0.5.2 // indirect
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1065 // indirect
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1065 // indirect
|
||||
github.com/tinylib/msgp v1.1.8 // indirect
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1210 // indirect
|
||||
github.com/tinylib/msgp v1.2.5 // indirect
|
||||
github.com/tjfoc/gmsm v1.4.1 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.12 // indirect
|
||||
github.com/tklauser/numcpus v0.6.1 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.15 // indirect
|
||||
github.com/tklauser/numcpus v0.10.0 // indirect
|
||||
github.com/transip/gotransip/v6 v6.26.0 // indirect
|
||||
github.com/ultradns/ultradns-go-sdk v1.8.0-20241010134910-243eeec // indirect
|
||||
github.com/vinyldns/go-vinyldns v0.9.16 // indirect
|
||||
github.com/volcengine/volc-sdk-golang v1.0.189 // indirect
|
||||
github.com/vultr/govultr/v3 v3.9.1 // indirect
|
||||
github.com/yandex-cloud/go-genproto v0.0.0-20241220122821-aeb3b05efd1c // indirect
|
||||
github.com/yandex-cloud/go-sdk v0.0.0-20241220131134-2393e243c134 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.3 // indirect
|
||||
github.com/volcengine/volc-sdk-golang v1.0.216 // indirect
|
||||
github.com/vultr/govultr/v3 v3.21.1 // indirect
|
||||
github.com/x448/float16 v0.8.4 // indirect
|
||||
github.com/yandex-cloud/go-genproto v0.14.0 // indirect
|
||||
github.com/yandex-cloud/go-sdk/services/dns v0.0.3 // indirect
|
||||
github.com/yandex-cloud/go-sdk/v2 v2.0.8 // indirect
|
||||
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.4 // indirect
|
||||
go.elastic.co/apm/module/apmhttp/v2 v2.4.8 // indirect
|
||||
go.elastic.co/fastjson v1.1.0 // indirect
|
||||
go.etcd.io/etcd/api/v3 v3.5.10 // indirect
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.10 // indirect
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.16 // indirect
|
||||
go.etcd.io/etcd/client/v3 v3.5.10 // indirect
|
||||
go.mongodb.org/mongo-driver v1.12.1 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 // indirect
|
||||
go.opentelemetry.io/otel v1.29.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.29.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.29.0 // indirect
|
||||
go.mongodb.org/mongo-driver v1.13.1 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||
go.opentelemetry.io/collector/component v1.31.0 // indirect
|
||||
go.opentelemetry.io/collector/featuregate v1.31.0 // indirect
|
||||
go.opentelemetry.io/collector/internal/telemetry v0.125.0 // indirect
|
||||
go.opentelemetry.io/collector/pdata v1.31.0 // indirect
|
||||
go.opentelemetry.io/collector/semconv v0.125.0 // indirect
|
||||
go.opentelemetry.io/contrib/bridges/otelzap v0.10.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect
|
||||
go.opentelemetry.io/otel v1.36.0 // indirect
|
||||
go.opentelemetry.io/otel/log v0.11.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.36.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.36.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.36.0 // indirect
|
||||
go.uber.org/atomic v1.11.0 // indirect
|
||||
go.uber.org/goleak v1.3.0 // indirect
|
||||
go.uber.org/mock v0.4.0 // indirect
|
||||
go.uber.org/multierr v1.9.0 // indirect
|
||||
go.uber.org/ratelimit v0.3.0 // indirect
|
||||
go.uber.org/zap v1.21.0 // indirect
|
||||
go4.org/intern v0.0.0-20230525184215-6c62f75575cb // indirect
|
||||
go4.org/unsafe/assume-no-moving-gc v0.0.0-20230525183740-e7c30c78aeb2 // indirect
|
||||
golang.org/x/crypto v0.31.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20241210194714-1829a127f884 // indirect
|
||||
golang.org/x/oauth2 v0.24.0 // indirect
|
||||
golang.org/x/sync v0.10.0 // indirect
|
||||
golang.org/x/sys v0.28.0 // indirect
|
||||
golang.org/x/term v0.27.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
||||
google.golang.org/api v0.214.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20241021214115-324edc3d5d38 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241118233622-e639e219e697 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 // indirect
|
||||
google.golang.org/protobuf v1.35.2 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/ratelimit v0.3.1 // indirect
|
||||
go.uber.org/zap v1.27.0 // indirect
|
||||
golang.org/x/crypto v0.43.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 // indirect
|
||||
golang.org/x/oauth2 v0.30.0 // indirect
|
||||
golang.org/x/sync v0.17.0 // indirect
|
||||
golang.org/x/sys v0.37.0 // indirect
|
||||
golang.org/x/term v0.36.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect
|
||||
google.golang.org/api v0.242.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250707201910-8d1bb00bc6a7 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7 // indirect
|
||||
google.golang.org/protobuf v1.36.6 // indirect
|
||||
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/ns1/ns1-go.v2 v2.13.0 // indirect
|
||||
gopkg.in/ns1/ns1-go.v2 v2.14.4 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
howett.net/plist v0.0.0-20181124034731-591f970eefbb // indirect
|
||||
inet.af/netaddr v0.0.0-20230525184311-b8eac61e914a // indirect
|
||||
k8s.io/klog/v2 v2.90.1 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
|
||||
sigs.k8s.io/yaml v1.3.0 // indirect
|
||||
k8s.io/klog/v2 v2.130.1 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f // indirect
|
||||
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.4.2 // indirect
|
||||
sigs.k8s.io/yaml v1.4.0 // indirect
|
||||
)
|
||||
|
||||
// Containous forks
|
||||
replace (
|
||||
github.com/abbot/go-http-auth => github.com/containous/go-http-auth v0.4.1-0.20200324110947-a37a7636d23e
|
||||
github.com/gorilla/mux => github.com/containous/mux v0.0.0-20220627093034-b2dd784e613f
|
||||
github.com/gorilla/mux => github.com/containous/mux v0.0.0-20250523120546-41b6ec3aed59
|
||||
github.com/mailgun/minheap => github.com/containous/minheap v0.0.0-20190809180810-6e71eb837595
|
||||
)
|
||||
|
||||
|
||||
21
init/init.go
21
init/init.go
@@ -1,21 +0,0 @@
|
||||
package init
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// This makes use of the GODEBUG flag `http2xconnect` to deactivate the connect setting for HTTP2 by default.
|
||||
// This type of upgrade is yet incompatible with `net/http` http1 reverse proxy.
|
||||
// Please see https://github.com/golang/go/issues/71128#issuecomment-2574193636.
|
||||
func init() {
|
||||
goDebug := os.Getenv("GODEBUG")
|
||||
if strings.Contains(goDebug, "http2xconnect") {
|
||||
return
|
||||
}
|
||||
|
||||
if len(goDebug) > 0 {
|
||||
goDebug += ","
|
||||
}
|
||||
os.Setenv("GODEBUG", goDebug+"http2xconnect=0")
|
||||
}
|
||||
28
integration/fixtures/https/max_concurrent_stream.toml
Normal file
28
integration/fixtures/https/max_concurrent_stream.toml
Normal file
@@ -0,0 +1,28 @@
|
||||
[global]
|
||||
checkNewVersion = false
|
||||
sendAnonymousUsage = false
|
||||
|
||||
[log]
|
||||
level = "DEBUG"
|
||||
|
||||
[serversTransport]
|
||||
insecureSkipVerify=true
|
||||
|
||||
[entryPoints]
|
||||
[entryPoints.web]
|
||||
address = ":8000"
|
||||
[entryPoints.web.http2]
|
||||
maxConcurrentStreams = 42
|
||||
|
||||
[api]
|
||||
insecure = true
|
||||
|
||||
[providers.file]
|
||||
filename = "{{ .SelfFilename }}"
|
||||
|
||||
## dynamic configuration ##
|
||||
|
||||
[tls.stores]
|
||||
[tls.stores.default.defaultCertificate]
|
||||
certFile = "resources/tls/local.cert"
|
||||
keyFile = "resources/tls/local.key"
|
||||
@@ -1478,7 +1478,7 @@ spec:
|
||||
properties:
|
||||
permanent:
|
||||
description: Permanent defines whether the redirection is permanent
|
||||
(301).
|
||||
(308).
|
||||
type: boolean
|
||||
regex:
|
||||
description: Regex defines the regex used to match and capture
|
||||
@@ -1497,7 +1497,7 @@ spec:
|
||||
properties:
|
||||
permanent:
|
||||
description: Permanent defines whether the redirection is permanent
|
||||
(301).
|
||||
(308).
|
||||
type: boolean
|
||||
port:
|
||||
description: Port defines the port of the new URL.
|
||||
@@ -1886,7 +1886,7 @@ spec:
|
||||
type: object
|
||||
curvePreferences:
|
||||
description: |-
|
||||
CurvePreferences defines the preferred elliptic curves in a specific order.
|
||||
CurvePreferences defines the preferred elliptic curves.
|
||||
More info: https://doc.traefik.io/traefik/v2.11/https/tls/#curve-preferences
|
||||
items:
|
||||
type: string
|
||||
@@ -3908,7 +3908,7 @@ spec:
|
||||
properties:
|
||||
permanent:
|
||||
description: Permanent defines whether the redirection is permanent
|
||||
(301).
|
||||
(308).
|
||||
type: boolean
|
||||
regex:
|
||||
description: Regex defines the regex used to match and capture
|
||||
@@ -3927,7 +3927,7 @@ spec:
|
||||
properties:
|
||||
permanent:
|
||||
description: Permanent defines whether the redirection is permanent
|
||||
(301).
|
||||
(308).
|
||||
type: boolean
|
||||
port:
|
||||
description: Port defines the port of the new URL.
|
||||
@@ -4316,7 +4316,7 @@ spec:
|
||||
type: object
|
||||
curvePreferences:
|
||||
description: |-
|
||||
CurvePreferences defines the preferred elliptic curves in a specific order.
|
||||
CurvePreferences defines the preferred elliptic curves.
|
||||
More info: https://doc.traefik.io/traefik/v2.11/https/tls/#curve-preferences
|
||||
items:
|
||||
type: string
|
||||
|
||||
41
integration/fixtures/simple_clean_path.toml
Normal file
41
integration/fixtures/simple_clean_path.toml
Normal file
@@ -0,0 +1,41 @@
|
||||
[global]
|
||||
checkNewVersion = false
|
||||
sendAnonymousUsage = false
|
||||
|
||||
[entryPoints]
|
||||
[entryPoints.web]
|
||||
address = ":8000"
|
||||
[entryPoints.web2]
|
||||
address = ":8001"
|
||||
[entryPoints.web2.http]
|
||||
sanitizePath = false
|
||||
|
||||
[log]
|
||||
level = "DEBUG"
|
||||
|
||||
[api]
|
||||
insecure = true
|
||||
|
||||
[providers.file]
|
||||
filename = "{{ .SelfFilename }}"
|
||||
|
||||
# dynamic configuration
|
||||
[http.routers]
|
||||
[http.routers.without]
|
||||
rule = "PathPrefix(`/without`)"
|
||||
service = "whoami"
|
||||
|
||||
[http.routers.with]
|
||||
rule = "PathPrefix(`/with`)"
|
||||
middlewares = ["test-redirectscheme"]
|
||||
service = "whoami"
|
||||
|
||||
[http.middlewares]
|
||||
[http.middlewares.test-redirectscheme.redirectScheme]
|
||||
scheme = "https"
|
||||
permanent = false
|
||||
|
||||
[http.services]
|
||||
[http.services.whoami.loadBalancer]
|
||||
[[http.services.whoami.loadBalancer.servers]]
|
||||
url = "{{ .Server1 }}"
|
||||
@@ -3,6 +3,7 @@ package integration
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
@@ -18,6 +19,7 @@ import (
|
||||
"github.com/traefik/traefik/v2/integration/try"
|
||||
"github.com/traefik/traefik/v2/pkg/config/dynamic"
|
||||
traefiktls "github.com/traefik/traefik/v2/pkg/tls"
|
||||
"golang.org/x/net/http2"
|
||||
)
|
||||
|
||||
// HTTPSSuite tests suite.
|
||||
@@ -937,11 +939,6 @@ func (s *HTTPSSuite) TestEntryPointHttpsRedirectAndPathModification() {
|
||||
hosts: []string{"example.com", "example2.com", "foo.com", "foo2.com", "bar.com", "bar2.com"},
|
||||
path: "/api/",
|
||||
},
|
||||
{
|
||||
desc: "Stripped URL with double trailing slash redirect",
|
||||
hosts: []string{"example.com", "example2.com", "foo.com", "foo2.com", "bar.com", "bar2.com"},
|
||||
path: "/api//",
|
||||
},
|
||||
{
|
||||
desc: "Stripped URL with path redirect",
|
||||
hosts: []string{"example.com", "example2.com", "foo.com", "foo2.com", "bar.com", "bar2.com"},
|
||||
@@ -952,21 +949,11 @@ func (s *HTTPSSuite) TestEntryPointHttpsRedirectAndPathModification() {
|
||||
hosts: []string{"example.com", "example2.com", "foo.com", "foo2.com", "bar.com", "bar2.com"},
|
||||
path: "/api/bacon/",
|
||||
},
|
||||
{
|
||||
desc: "Stripped URL with path and double trailing slash redirect",
|
||||
hosts: []string{"example.com", "example2.com", "foo.com", "foo2.com", "bar.com", "bar2.com"},
|
||||
path: "/api/bacon//",
|
||||
},
|
||||
{
|
||||
desc: "Root Path with redirect",
|
||||
hosts: []string{"test.com", "test2.com", "pow.com", "pow2.com"},
|
||||
path: "/",
|
||||
},
|
||||
{
|
||||
desc: "Root Path with double trailing slash redirect",
|
||||
hosts: []string{"test.com", "test2.com", "pow.com", "pow2.com"},
|
||||
path: "//",
|
||||
},
|
||||
{
|
||||
desc: "Path modify with redirect",
|
||||
hosts: []string{"test.com", "test2.com", "pow.com", "pow2.com"},
|
||||
@@ -1188,3 +1175,38 @@ func (s *HTTPSSuite) TestWithInvalidTLSOption() {
|
||||
assert.Nil(s.T(), conn)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SimpleSuite) TestMaxConcurrentStream() {
|
||||
file := s.adaptFile("fixtures/https/max_concurrent_stream.toml", struct{}{})
|
||||
|
||||
s.traefikCmd(withConfigFile(file), "--log.level=DEBUG", "--accesslog")
|
||||
|
||||
// Wait for traefik.
|
||||
err := try.GetRequest("http://127.0.0.1:8080/api/rawdata", time.Second, try.BodyContains("api@internal"))
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
// Add client self-signed cert.
|
||||
roots := x509.NewCertPool()
|
||||
certContent, err := os.ReadFile("./resources/tls/local.cert")
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
roots.AppendCertsFromPEM(certContent)
|
||||
|
||||
// Open a connection to inspect SettingsFrame.
|
||||
conn, err := tls.Dial("tcp", "127.0.0.1:8000", &tls.Config{
|
||||
RootCAs: roots,
|
||||
NextProtos: []string{"h2"},
|
||||
})
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
framer := http2.NewFramer(nil, conn)
|
||||
frame, err := framer.ReadFrame()
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
fr, ok := frame.(*http2.SettingsFrame)
|
||||
require.True(s.T(), ok)
|
||||
|
||||
maxConcurrentStream, ok := fr.Value(http2.SettingMaxConcurrentStreams)
|
||||
assert.True(s.T(), ok)
|
||||
assert.Equal(s.T(), uint32(42), maxConcurrentStream)
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ func (s *BaseSuite) displayTraefikLogFile(path string) {
|
||||
// fmt.Printf("%s: Traefik logs: \n", c.TestName())
|
||||
fmt.Print("Traefik logs: \n")
|
||||
if errRead == nil {
|
||||
fmt.Println(content)
|
||||
fmt.Println(string(content))
|
||||
} else {
|
||||
fmt.Println(errRead)
|
||||
}
|
||||
|
||||
@@ -92,6 +92,9 @@ func (s *RedisSentinelSuite) setupSentinelConfiguration(ports []string) {
|
||||
require.NoError(s.T(), err)
|
||||
defer tmpFile.Close()
|
||||
|
||||
err = tmpFile.Chmod(0o666)
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
model := structs.Map(templateValue)
|
||||
model["SelfFilename"] = tmpFile.Name()
|
||||
|
||||
|
||||
@@ -1385,3 +1385,100 @@ func (s *SimpleSuite) TestDenyFragment() {
|
||||
require.NoError(s.T(), err)
|
||||
assert.Equal(s.T(), http.StatusBadRequest, resp.StatusCode)
|
||||
}
|
||||
|
||||
func (s *SimpleSuite) TestSanitizePath() {
|
||||
s.createComposeProject("base")
|
||||
|
||||
s.composeUp()
|
||||
defer s.composeDown()
|
||||
|
||||
whoami1URL := "http://" + net.JoinHostPort(s.getComposeServiceIP("whoami1"), "80")
|
||||
|
||||
file := s.adaptFile("fixtures/simple_clean_path.toml", struct {
|
||||
Server1 string
|
||||
}{whoami1URL})
|
||||
|
||||
s.traefikCmd(withConfigFile(file))
|
||||
|
||||
err := try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains("PathPrefix(`/with`)"))
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
testCases := []struct {
|
||||
desc string
|
||||
request string
|
||||
target string
|
||||
body string
|
||||
expected int
|
||||
}{
|
||||
{
|
||||
desc: "Explicit call to the route with a middleware",
|
||||
request: "GET /with HTTP/1.1\r\nHost: other.localhost\r\n\r\n",
|
||||
target: "127.0.0.1:8000",
|
||||
expected: http.StatusFound,
|
||||
},
|
||||
{
|
||||
desc: "Explicit call to the route without a middleware",
|
||||
request: "GET /without HTTP/1.1\r\nHost: other.localhost\r\n\r\n",
|
||||
target: "127.0.0.1:8000",
|
||||
expected: http.StatusOK,
|
||||
body: "GET /without HTTP/1.1",
|
||||
},
|
||||
{
|
||||
desc: "Implicit call to the route with a middleware",
|
||||
request: "GET /without/../with HTTP/1.1\r\nHost: other.localhost\r\n\r\n",
|
||||
target: "127.0.0.1:8000",
|
||||
expected: http.StatusFound,
|
||||
},
|
||||
{
|
||||
desc: "Implicit encoded dot dots call to the route with a middleware",
|
||||
request: "GET /without/%2E%2E/with HTTP/1.1\r\nHost: other.localhost\r\n\r\n",
|
||||
target: "127.0.0.1:8000",
|
||||
expected: http.StatusFound,
|
||||
},
|
||||
{
|
||||
desc: "Implicit with encoded unreserved character call to the route with a middleware",
|
||||
request: "GET /%77ith HTTP/1.1\r\nHost: other.localhost\r\n\r\n",
|
||||
target: "127.0.0.1:8000",
|
||||
expected: http.StatusFound,
|
||||
},
|
||||
{
|
||||
desc: "Explicit call to the route with a middleware, and disable path sanitization",
|
||||
request: "GET /with HTTP/1.1\r\nHost: other.localhost\r\n\r\n",
|
||||
target: "127.0.0.1:8001",
|
||||
expected: http.StatusFound,
|
||||
},
|
||||
{
|
||||
desc: "Explicit call to the route without a middleware, and disable path sanitization",
|
||||
request: "GET /without HTTP/1.1\r\nHost: other.localhost\r\n\r\n",
|
||||
target: "127.0.0.1:8001",
|
||||
expected: http.StatusOK,
|
||||
body: "GET /without HTTP/1.1",
|
||||
},
|
||||
{
|
||||
desc: "Implicit call to the route with a middleware, and disable path sanitization",
|
||||
request: "GET /without/../with HTTP/1.1\r\nHost: other.localhost\r\n\r\n",
|
||||
target: "127.0.0.1:8001",
|
||||
// The whoami is redirecting to /with, but the path is not sanitized.
|
||||
expected: http.StatusMovedPermanently,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
conn, err := net.Dial("tcp", test.target)
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
_, err = conn.Write([]byte(test.request))
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
resp, err := http.ReadResponse(bufio.NewReader(conn), nil)
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
assert.Equalf(s.T(), test.expected, resp.StatusCode, "%s failed with %d instead of %d", test.desc, resp.StatusCode, test.expected)
|
||||
|
||||
if test.body != "" {
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
require.NoError(s.T(), err)
|
||||
assert.Contains(s.T(), string(body), test.body)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -278,7 +278,7 @@ func (s *TCPSuite) TestWRR() {
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
|
||||
assert.EqualValues(s.T(), map[string]int{"whoami-b": 3, "whoami-ab": 1}, call)
|
||||
assert.Equal(s.T(), map[string]int{"whoami-b": 3, "whoami-ab": 1}, call)
|
||||
}
|
||||
|
||||
func welcome(addr string) (string, error) {
|
||||
|
||||
@@ -96,7 +96,7 @@ func (s *UDPSuite) TestWRR() {
|
||||
call["unknown"]++
|
||||
}
|
||||
}
|
||||
assert.EqualValues(s.T(), map[string]int{"whoami-a": 3, "whoami-b": 2, "whoami-c": 3}, call)
|
||||
assert.Equal(s.T(), map[string]int{"whoami-a": 3, "whoami-b": 2, "whoami-c": 3}, call)
|
||||
close(stop)
|
||||
}()
|
||||
|
||||
|
||||
@@ -349,6 +349,11 @@ func genKVDynConfDoc(outputFile string) {
|
||||
CODE GENERATED AUTOMATICALLY
|
||||
THIS FILE MUST NOT BE EDITED BY HAND
|
||||
-->
|
||||
`)
|
||||
|
||||
_, _ = fmt.Fprintf(file, `
|
||||
| Key (Path) | Value |
|
||||
|------------|-------|
|
||||
`)
|
||||
|
||||
for _, k := range keys {
|
||||
|
||||
66
internal/testsci/genmatrix.go
Normal file
66
internal/testsci/genmatrix.go
Normal file
@@ -0,0 +1,66 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/traefik/traefik/v2/pkg/log"
|
||||
"golang.org/x/tools/go/packages"
|
||||
)
|
||||
|
||||
const groupCount = 12
|
||||
|
||||
type group struct {
|
||||
Group string `json:"group"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
logger := log.WithoutContext()
|
||||
|
||||
cfg := &packages.Config{
|
||||
Mode: packages.NeedName,
|
||||
Dir: ".",
|
||||
}
|
||||
|
||||
pkgs, err := packages.Load(cfg, "./cmd/...", "./pkg/...")
|
||||
if err != nil {
|
||||
logger.Fatalf("Loading packages: %v", err)
|
||||
}
|
||||
|
||||
var packageNames []string
|
||||
for _, pkg := range pkgs {
|
||||
if pkg.PkgPath != "" {
|
||||
packageNames = append(packageNames, pkg.PkgPath)
|
||||
}
|
||||
}
|
||||
|
||||
total := len(packageNames)
|
||||
perGroup := (total + groupCount - 1) / groupCount
|
||||
|
||||
fmt.Fprintf(os.Stderr, "Total packages: %d\n", total)
|
||||
fmt.Fprintf(os.Stderr, "Packages per group: %d\n", perGroup)
|
||||
|
||||
var matrix []group
|
||||
for i := range groupCount {
|
||||
start := i * perGroup
|
||||
end := start + perGroup
|
||||
if start >= total {
|
||||
break
|
||||
}
|
||||
if end > total {
|
||||
end = total
|
||||
}
|
||||
g := strings.Join(packageNames[start:end], " ")
|
||||
matrix = append(matrix, group{Group: g})
|
||||
}
|
||||
|
||||
jsonBytes, err := json.Marshal(matrix)
|
||||
if err != nil {
|
||||
logger.Fatalf("Failed to marshal matrix: %v", err)
|
||||
}
|
||||
|
||||
// Output for GitHub Actions
|
||||
fmt.Printf("matrix=%s\n", string(jsonBytes))
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
@@ -926,8 +925,8 @@ func TestHandler_HTTP(t *testing.T) {
|
||||
rtConf := &test.conf
|
||||
// To lazily initialize the Statuses.
|
||||
rtConf.PopulateUsedBy()
|
||||
rtConf.GetRoutersByEntryPoints(context.Background(), []string{"web"}, false)
|
||||
rtConf.GetRoutersByEntryPoints(context.Background(), []string{"web"}, true)
|
||||
rtConf.GetRoutersByEntryPoints(t.Context(), []string{"web"}, false)
|
||||
rtConf.GetRoutersByEntryPoints(t.Context(), []string{"web"}, true)
|
||||
|
||||
handler := New(static.Configuration{API: &static.API{}, Global: &static.Global{}}, rtConf)
|
||||
server := httptest.NewServer(handler.createRouter())
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
@@ -797,7 +796,7 @@ func TestHandler_TCP(t *testing.T) {
|
||||
rtConf := &test.conf
|
||||
// To lazily initialize the Statuses.
|
||||
rtConf.PopulateUsedBy()
|
||||
rtConf.GetTCPRoutersByEntryPoints(context.Background(), []string{"web"})
|
||||
rtConf.GetTCPRoutersByEntryPoints(t.Context(), []string{"web"})
|
||||
|
||||
handler := New(static.Configuration{API: &static.API{}, Global: &static.Global{}}, rtConf)
|
||||
server := httptest.NewServer(handler.createRouter())
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
@@ -536,7 +535,7 @@ func TestHandler_UDP(t *testing.T) {
|
||||
rtConf := &test.conf
|
||||
// To lazily initialize the Statuses.
|
||||
rtConf.PopulateUsedBy()
|
||||
rtConf.GetUDPRoutersByEntryPoints(context.Background(), []string{"web"})
|
||||
rtConf.GetUDPRoutersByEntryPoints(t.Context(), []string{"web"})
|
||||
|
||||
handler := New(static.Configuration{API: &static.API{}, Global: &static.Global{}}, rtConf)
|
||||
server := httptest.NewServer(handler.createRouter())
|
||||
|
||||
@@ -489,7 +489,7 @@ type RedirectRegex struct {
|
||||
Regex string `json:"regex,omitempty" toml:"regex,omitempty" yaml:"regex,omitempty"`
|
||||
// Replacement defines how to modify the URL to have the new target URL.
|
||||
Replacement string `json:"replacement,omitempty" toml:"replacement,omitempty" yaml:"replacement,omitempty"`
|
||||
// Permanent defines whether the redirection is permanent (301).
|
||||
// Permanent defines whether the redirection is permanent (308).
|
||||
Permanent bool `json:"permanent,omitempty" toml:"permanent,omitempty" yaml:"permanent,omitempty" export:"true"`
|
||||
}
|
||||
|
||||
@@ -503,7 +503,7 @@ type RedirectScheme struct {
|
||||
Scheme string `json:"scheme,omitempty" toml:"scheme,omitempty" yaml:"scheme,omitempty" export:"true"`
|
||||
// Port defines the port of the new URL.
|
||||
Port string `json:"port,omitempty" toml:"port,omitempty" yaml:"port,omitempty" export:"true"`
|
||||
// Permanent defines whether the redirection is permanent (301).
|
||||
// Permanent defines whether the redirection is permanent (308).
|
||||
Permanent bool `json:"permanent,omitempty" toml:"permanent,omitempty" yaml:"permanent,omitempty" export:"true"`
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -211,7 +210,7 @@ func TestGetRoutersByEntryPoints(t *testing.T) {
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
runtimeConfig := NewConfig(test.conf)
|
||||
actual := runtimeConfig.GetRoutersByEntryPoints(context.Background(), test.entryPoints, false)
|
||||
actual := runtimeConfig.GetRoutersByEntryPoints(t.Context(), test.entryPoints, false)
|
||||
assert.Equal(t, test.expected, actual)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -211,7 +210,7 @@ func TestGetTCPRoutersByEntryPoints(t *testing.T) {
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
runtimeConfig := NewConfig(test.conf)
|
||||
actual := runtimeConfig.GetTCPRoutersByEntryPoints(context.Background(), test.entryPoints)
|
||||
actual := runtimeConfig.GetTCPRoutersByEntryPoints(t.Context(), test.entryPoints)
|
||||
assert.Equal(t, test.expected, actual)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -192,7 +191,7 @@ func TestGetUDPRoutersByEntryPoints(t *testing.T) {
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
runtimeConfig := NewConfig(test.conf)
|
||||
actual := runtimeConfig.GetUDPRoutersByEntryPoints(context.Background(), test.entryPoints)
|
||||
actual := runtimeConfig.GetUDPRoutersByEntryPoints(t.Context(), test.entryPoints)
|
||||
assert.Equal(t, test.expected, actual)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@ func (ep *EntryPoint) SetDefaults() {
|
||||
ep.ForwardedHeaders = &ForwardedHeaders{}
|
||||
ep.UDP = &UDPConfig{}
|
||||
ep.UDP.SetDefaults()
|
||||
ep.HTTP.SetDefaults()
|
||||
ep.HTTP2 = &HTTP2Config{}
|
||||
ep.HTTP2.SetDefaults()
|
||||
}
|
||||
@@ -61,7 +62,14 @@ type HTTPConfig struct {
|
||||
Redirections *Redirections `description:"Set of redirection" json:"redirections,omitempty" toml:"redirections,omitempty" yaml:"redirections,omitempty" export:"true"`
|
||||
Middlewares []string `description:"Default middlewares for the routers linked to the entry point." json:"middlewares,omitempty" toml:"middlewares,omitempty" yaml:"middlewares,omitempty" export:"true"`
|
||||
TLS *TLSConfig `description:"Default TLS configuration for the routers linked to the entry point." json:"tls,omitempty" toml:"tls,omitempty" yaml:"tls,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
|
||||
EncodeQuerySemicolons bool `description:"Defines whether request query semicolons should be URLEncoded." json:"encodeQuerySemicolons,omitempty" toml:"encodeQuerySemicolons,omitempty" yaml:"encodeQuerySemicolons,omitempty"`
|
||||
EncodeQuerySemicolons bool `description:"Defines whether request query semicolons should be URLEncoded." json:"encodeQuerySemicolons,omitempty" toml:"encodeQuerySemicolons,omitempty" yaml:"encodeQuerySemicolons,omitempty" export:"true"`
|
||||
SanitizePath *bool `description:"Defines whether to enable request path sanitization (removal of /./, /../ and multiple slash sequences)." json:"sanitizePath,omitempty" toml:"sanitizePath,omitempty" yaml:"sanitizePath,omitempty" export:"true"`
|
||||
}
|
||||
|
||||
// SetDefaults sets the default values.
|
||||
func (h *HTTPConfig) SetDefaults() {
|
||||
sanitizePath := true
|
||||
h.SanitizePath = &sanitizePath
|
||||
}
|
||||
|
||||
// HTTP2Config is the HTTP2 configuration of an entry point.
|
||||
|
||||
@@ -273,6 +273,25 @@ func (c *Configuration) SetEffectiveConfiguration() {
|
||||
c.Providers.KubernetesGateway.EntryPoints = entryPoints
|
||||
}
|
||||
|
||||
for _, resolver := range c.CertificatesResolvers {
|
||||
if resolver.ACME == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if resolver.ACME.DNSChallenge == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
switch resolver.ACME.DNSChallenge.Provider {
|
||||
case "googledomains", "cloudxns", "brandit":
|
||||
log.WithoutContext().Warnf("%s DNS provider is deprecated.", resolver.ACME.DNSChallenge.Provider)
|
||||
case "dnspod":
|
||||
log.WithoutContext().Warnf("%s provider is deprecated, please use 'tencentcloud' provider instead.", resolver.ACME.DNSChallenge.Provider)
|
||||
case "azure":
|
||||
log.WithoutContext().Warnf("%s provider is deprecated, please use 'azuredns' provider instead.", resolver.ACME.DNSChallenge.Provider)
|
||||
}
|
||||
}
|
||||
|
||||
c.initACMEProvider()
|
||||
}
|
||||
|
||||
|
||||
@@ -101,7 +101,7 @@ func TestSetBackendsConfiguration(t *testing.T) {
|
||||
|
||||
// The context is passed to the health check and canonically canceled by
|
||||
// the test server once all expected requests have been received.
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
ts := newTestServer(cancel, test.healthSequence)
|
||||
defer ts.Close()
|
||||
@@ -568,7 +568,7 @@ func TestNotFollowingRedirects(t *testing.T) {
|
||||
}))
|
||||
defer redirectTestServer.Close()
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
|
||||
@@ -2,7 +2,6 @@ package log
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
@@ -42,7 +41,7 @@ func TestLog(t *testing.T) {
|
||||
var buffer bytes.Buffer
|
||||
SetOutput(&buffer)
|
||||
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
|
||||
for key, value := range test.fields {
|
||||
ctx = With(ctx, Str(key, value))
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"testing"
|
||||
@@ -17,7 +16,7 @@ func TestDatadog(t *testing.T) {
|
||||
// This is needed to make sure that UDP Listener listens for data a bit longer, otherwise it will quit after a millisecond
|
||||
udp.Timeout = 5 * time.Second
|
||||
|
||||
datadogRegistry := RegisterDatadog(context.Background(), &types.Datadog{Address: ":18125", PushInterval: ptypes.Duration(time.Second), AddEntryPointsLabels: true, AddRoutersLabels: true, AddServicesLabels: true})
|
||||
datadogRegistry := RegisterDatadog(t.Context(), &types.Datadog{Address: ":18125", PushInterval: ptypes.Duration(time.Second), AddEntryPointsLabels: true, AddRoutersLabels: true, AddServicesLabels: true})
|
||||
defer StopDatadog()
|
||||
|
||||
if !datadogRegistry.IsEpEnabled() || !datadogRegistry.IsRouterEnabled() || !datadogRegistry.IsSvcEnabled() {
|
||||
@@ -35,7 +34,7 @@ func TestDatadogWithPrefix(t *testing.T) {
|
||||
// This is needed to make sure that UDP Listener listens for data a bit longer, otherwise it will quit after a millisecond
|
||||
udp.Timeout = 5 * time.Second
|
||||
|
||||
datadogRegistry := RegisterDatadog(context.Background(), &types.Datadog{Prefix: "testPrefix", Address: ":18125", PushInterval: ptypes.Duration(time.Second), AddEntryPointsLabels: true, AddRoutersLabels: true, AddServicesLabels: true})
|
||||
datadogRegistry := RegisterDatadog(t.Context(), &types.Datadog{Prefix: "testPrefix", Address: ":18125", PushInterval: ptypes.Duration(time.Second), AddEntryPointsLabels: true, AddRoutersLabels: true, AddServicesLabels: true})
|
||||
|
||||
testDatadogRegistry(t, "testPrefix", datadogRegistry)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
@@ -27,7 +26,7 @@ func TestInfluxDB2(t *testing.T) {
|
||||
}))
|
||||
defer ts.Close()
|
||||
|
||||
influxDB2Registry := RegisterInfluxDB2(context.Background(),
|
||||
influxDB2Registry := RegisterInfluxDB2(t.Context(),
|
||||
&types.InfluxDB2{
|
||||
Address: ts.URL,
|
||||
Token: "test-token",
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
@@ -23,7 +22,7 @@ func TestInfluxDB(t *testing.T) {
|
||||
udp.Timeout = 5 * time.Second
|
||||
|
||||
influxDBClient = nil
|
||||
influxDBRegistry := RegisterInfluxDB(context.Background(),
|
||||
influxDBRegistry := RegisterInfluxDB(t.Context(),
|
||||
&types.InfluxDB{
|
||||
Address: ":8089",
|
||||
PushInterval: ptypes.Duration(time.Second),
|
||||
@@ -147,7 +146,7 @@ func TestInfluxDBHTTP(t *testing.T) {
|
||||
defer ts.Close()
|
||||
|
||||
influxDBClient = nil
|
||||
influxDBRegistry := RegisterInfluxDB(context.Background(),
|
||||
influxDBRegistry := RegisterInfluxDB(t.Context(),
|
||||
&types.InfluxDB{
|
||||
Address: ts.URL,
|
||||
Protocol: "http",
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
@@ -70,7 +69,7 @@ func TestRegisterPromState(t *testing.T) {
|
||||
if test.initPromState {
|
||||
initStandardRegistry(prom)
|
||||
}
|
||||
if registerPromState(context.Background()) {
|
||||
if registerPromState(t.Context()) {
|
||||
actualNbRegistries++
|
||||
}
|
||||
if test.unregisterPromState {
|
||||
@@ -91,7 +90,7 @@ func TestPrometheus(t *testing.T) {
|
||||
promRegistry = prometheus.NewRegistry()
|
||||
t.Cleanup(promState.reset)
|
||||
|
||||
prometheusRegistry := RegisterPrometheus(context.Background(), &types.Prometheus{
|
||||
prometheusRegistry := RegisterPrometheus(t.Context(), &types.Prometheus{
|
||||
AddEntryPointsLabels: true,
|
||||
AddRoutersLabels: true,
|
||||
AddServicesLabels: true,
|
||||
@@ -443,7 +442,7 @@ func TestPrometheusMetricRemoval(t *testing.T) {
|
||||
promRegistry = prometheus.NewRegistry()
|
||||
t.Cleanup(promState.reset)
|
||||
|
||||
prometheusRegistry := RegisterPrometheus(context.Background(), &types.Prometheus{AddEntryPointsLabels: true, AddServicesLabels: true, AddRoutersLabels: true})
|
||||
prometheusRegistry := RegisterPrometheus(t.Context(), &types.Prometheus{AddEntryPointsLabels: true, AddServicesLabels: true, AddRoutersLabels: true})
|
||||
defer promRegistry.Unregister(promState)
|
||||
|
||||
conf1 := dynamic.Configuration{
|
||||
@@ -534,7 +533,7 @@ func TestPrometheusMetricRemoveEndpointForRecoveredService(t *testing.T) {
|
||||
promRegistry = prometheus.NewRegistry()
|
||||
t.Cleanup(promState.reset)
|
||||
|
||||
prometheusRegistry := RegisterPrometheus(context.Background(), &types.Prometheus{AddServicesLabels: true})
|
||||
prometheusRegistry := RegisterPrometheus(t.Context(), &types.Prometheus{AddServicesLabels: true})
|
||||
defer promRegistry.Unregister(promState)
|
||||
|
||||
conf1 := dynamic.Configuration{
|
||||
@@ -573,7 +572,7 @@ func TestPrometheusMetricRemoveEndpointForRecoveredService(t *testing.T) {
|
||||
func TestPrometheusRemovedMetricsReset(t *testing.T) {
|
||||
t.Cleanup(promState.reset)
|
||||
|
||||
prometheusRegistry := RegisterPrometheus(context.Background(), &types.Prometheus{AddEntryPointsLabels: true, AddServicesLabels: true})
|
||||
prometheusRegistry := RegisterPrometheus(t.Context(), &types.Prometheus{AddEntryPointsLabels: true, AddServicesLabels: true})
|
||||
defer promRegistry.Unregister(promState)
|
||||
|
||||
conf1 := dynamic.Configuration{
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"testing"
|
||||
@@ -21,7 +20,7 @@ func TestStatsD(t *testing.T) {
|
||||
// This is needed to make sure that UDP Listener listens for data a bit longer, otherwise it will quit after a millisecond
|
||||
udp.Timeout = 5 * time.Second
|
||||
|
||||
statsdRegistry := RegisterStatsd(context.Background(), &types.Statsd{Address: ":18125", PushInterval: ptypes.Duration(time.Second), AddEntryPointsLabels: true, AddRoutersLabels: true, AddServicesLabels: true})
|
||||
statsdRegistry := RegisterStatsd(t.Context(), &types.Statsd{Address: ":18125", PushInterval: ptypes.Duration(time.Second), AddEntryPointsLabels: true, AddRoutersLabels: true, AddServicesLabels: true})
|
||||
|
||||
testRegistry(t, defaultMetricsPrefix, statsdRegistry)
|
||||
}
|
||||
@@ -35,7 +34,7 @@ func TestStatsDWithPrefix(t *testing.T) {
|
||||
// This is needed to make sure that UDP Listener listens for data a bit longer, otherwise it will quit after a millisecond
|
||||
udp.Timeout = 5 * time.Second
|
||||
|
||||
statsdRegistry := RegisterStatsd(context.Background(), &types.Statsd{Address: ":18125", PushInterval: ptypes.Duration(time.Second), AddEntryPointsLabels: true, AddRoutersLabels: true, AddServicesLabels: true, Prefix: "testPrefix"})
|
||||
statsdRegistry := RegisterStatsd(t.Context(), &types.Statsd{Address: ":18125", PushInterval: ptypes.Duration(time.Second), AddEntryPointsLabels: true, AddRoutersLabels: true, AddServicesLabels: true, Prefix: "testPrefix"})
|
||||
|
||||
testRegistry(t, "testPrefix", statsdRegistry)
|
||||
}
|
||||
|
||||
@@ -364,9 +364,10 @@ func (h *Handler) logTheRoundTrip(logDataTable *LogData) {
|
||||
func (h *Handler) redactHeaders(headers http.Header, fields logrus.Fields, prefix string) {
|
||||
for k := range headers {
|
||||
v := h.config.Fields.KeepHeader(k)
|
||||
if v == types.AccessLogKeep {
|
||||
switch v {
|
||||
case types.AccessLogKeep:
|
||||
fields[prefix+k] = strings.Join(headers.Values(k), ",")
|
||||
} else if v == types.AccessLogRedact {
|
||||
case types.AccessLogRedact:
|
||||
fields[prefix+k] = "REDACTED"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -271,7 +271,7 @@ func assertNotEmpty() func(t *testing.T, actual interface{}) {
|
||||
return func(t *testing.T, actual interface{}) {
|
||||
t.Helper()
|
||||
|
||||
assert.NotEqual(t, "", actual)
|
||||
assert.NotEmpty(t, actual)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -510,7 +510,7 @@ func TestLoggerJSON(t *testing.T) {
|
||||
err = json.Unmarshal(logData, &jsonData)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, len(test.expected), len(jsonData))
|
||||
assert.Len(t, jsonData, len(test.expected))
|
||||
|
||||
for field, assertion := range test.expected {
|
||||
assertion(t, jsonData[field])
|
||||
@@ -567,7 +567,7 @@ func TestLogger_AbortedRequest(t *testing.T) {
|
||||
err = json.Unmarshal(logData, &jsonData)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, len(expected), len(jsonData))
|
||||
assert.Len(t, jsonData, len(expected))
|
||||
|
||||
for field, assertion := range expected {
|
||||
assertion(t, jsonData[field])
|
||||
@@ -798,7 +798,7 @@ func assertValidLogData(t *testing.T, expected string, logData []byte) {
|
||||
|
||||
formatErrMessage := fmt.Sprintf("Expected:\t%q\nActual:\t%q", expected, string(logData))
|
||||
|
||||
require.Equal(t, len(resultExpected), len(result), formatErrMessage)
|
||||
require.Len(t, result, len(resultExpected), formatErrMessage)
|
||||
assert.Equal(t, resultExpected[ClientHost], result[ClientHost], formatErrMessage)
|
||||
assert.Equal(t, resultExpected[ClientUsername], result[ClientUsername], formatErrMessage)
|
||||
assert.Equal(t, resultExpected[RequestMethod], result[RequestMethod], formatErrMessage)
|
||||
@@ -926,7 +926,7 @@ func doLoggingWithAbortedStream(t *testing.T, config *types.AccessLog) {
|
||||
require.NoError(t, err, "logger should create "+config.FilePath)
|
||||
}
|
||||
|
||||
reqContext, cancelRequest := context.WithCancel(context.Background())
|
||||
reqContext, cancelRequest := context.WithCancel(t.Context())
|
||||
|
||||
req := &http.Request{
|
||||
Header: map[string][]string{
|
||||
|
||||
@@ -65,7 +65,7 @@ func TestParseAccessLog(t *testing.T) {
|
||||
|
||||
result, err := ParseAccessLog(test.value)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, len(test.expected), len(result))
|
||||
assert.Len(t, result, len(test.expected))
|
||||
for key, value := range test.expected {
|
||||
assert.Equal(t, value, result[key])
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package addprefix
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
@@ -34,7 +33,7 @@ func TestNewAddPrefix(t *testing.T) {
|
||||
|
||||
next := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})
|
||||
|
||||
_, err := New(context.Background(), next, test.prefix, "foo-add-prefix")
|
||||
_, err := New(t.Context(), next, test.prefix, "foo-add-prefix")
|
||||
if test.expectsError {
|
||||
assert.Error(t, err)
|
||||
} else {
|
||||
@@ -87,7 +86,7 @@ func TestAddPrefix(t *testing.T) {
|
||||
|
||||
req := testhelpers.MustNewRequest(http.MethodGet, "http://localhost"+test.path, nil)
|
||||
|
||||
handler, err := New(context.Background(), next, test.prefix, "foo-add-prefix")
|
||||
handler, err := New(t.Context(), next, test.prefix, "foo-add-prefix")
|
||||
require.NoError(t, err)
|
||||
|
||||
handler.ServeHTTP(nil, req)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
@@ -23,13 +22,13 @@ func TestBasicAuthFail(t *testing.T) {
|
||||
auth := dynamic.BasicAuth{
|
||||
Users: []string{"test"},
|
||||
}
|
||||
_, err := NewBasic(context.Background(), next, auth, "authName")
|
||||
_, err := NewBasic(t.Context(), next, auth, "authName")
|
||||
require.Error(t, err)
|
||||
|
||||
auth2 := dynamic.BasicAuth{
|
||||
Users: []string{"test:test"},
|
||||
}
|
||||
authMiddleware, err := NewBasic(context.Background(), next, auth2, "authTest")
|
||||
authMiddleware, err := NewBasic(t.Context(), next, auth2, "authTest")
|
||||
require.NoError(t, err)
|
||||
|
||||
ts := httptest.NewServer(authMiddleware)
|
||||
@@ -52,7 +51,7 @@ func TestBasicAuthSuccess(t *testing.T) {
|
||||
auth := dynamic.BasicAuth{
|
||||
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/"},
|
||||
}
|
||||
authMiddleware, err := NewBasic(context.Background(), next, auth, "authName")
|
||||
authMiddleware, err := NewBasic(t.Context(), next, auth, "authName")
|
||||
require.NoError(t, err)
|
||||
|
||||
ts := httptest.NewServer(authMiddleware)
|
||||
@@ -83,7 +82,7 @@ func TestBasicAuthUserHeader(t *testing.T) {
|
||||
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/"},
|
||||
HeaderField: "X-Webauth-User",
|
||||
}
|
||||
middleware, err := NewBasic(context.Background(), next, auth, "authName")
|
||||
middleware, err := NewBasic(t.Context(), next, auth, "authName")
|
||||
require.NoError(t, err)
|
||||
|
||||
ts := httptest.NewServer(middleware)
|
||||
@@ -114,7 +113,7 @@ func TestBasicAuthHeaderRemoved(t *testing.T) {
|
||||
RemoveHeader: true,
|
||||
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/"},
|
||||
}
|
||||
middleware, err := NewBasic(context.Background(), next, auth, "authName")
|
||||
middleware, err := NewBasic(t.Context(), next, auth, "authName")
|
||||
require.NoError(t, err)
|
||||
|
||||
ts := httptest.NewServer(middleware)
|
||||
@@ -145,7 +144,7 @@ func TestBasicAuthHeaderPresent(t *testing.T) {
|
||||
auth := dynamic.BasicAuth{
|
||||
Users: []string{"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/"},
|
||||
}
|
||||
middleware, err := NewBasic(context.Background(), next, auth, "authName")
|
||||
middleware, err := NewBasic(t.Context(), next, auth, "authName")
|
||||
require.NoError(t, err)
|
||||
|
||||
ts := httptest.NewServer(middleware)
|
||||
@@ -231,7 +230,7 @@ func TestBasicAuthUsersFromFile(t *testing.T) {
|
||||
fmt.Fprintln(w, "traefik")
|
||||
})
|
||||
|
||||
authenticator, err := NewBasic(context.Background(), next, authenticatorConfiguration, "authName")
|
||||
authenticator, err := NewBasic(t.Context(), next, authenticatorConfiguration, "authName")
|
||||
require.NoError(t, err)
|
||||
|
||||
ts := httptest.NewServer(authenticator)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
@@ -23,7 +22,7 @@ func TestDigestAuthError(t *testing.T) {
|
||||
auth := dynamic.DigestAuth{
|
||||
Users: []string{"test"},
|
||||
}
|
||||
_, err := NewDigest(context.Background(), next, auth, "authName")
|
||||
_, err := NewDigest(t.Context(), next, auth, "authName")
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
@@ -35,7 +34,7 @@ func TestDigestAuthFail(t *testing.T) {
|
||||
auth := dynamic.DigestAuth{
|
||||
Users: []string{"test:traefik:a2688e031edb4be6a3797f3882655c05"},
|
||||
}
|
||||
authMiddleware, err := NewDigest(context.Background(), next, auth, "authName")
|
||||
authMiddleware, err := NewDigest(t.Context(), next, auth, "authName")
|
||||
require.NoError(t, err)
|
||||
assert.NotNil(t, authMiddleware, "this should not be nil")
|
||||
|
||||
@@ -109,7 +108,7 @@ func TestDigestAuthUsersFromFile(t *testing.T) {
|
||||
fmt.Fprintln(w, "traefik")
|
||||
})
|
||||
|
||||
authenticator, err := NewDigest(context.Background(), next, authenticatorConfiguration, "authName")
|
||||
authenticator, err := NewDigest(t.Context(), next, authenticatorConfiguration, "authName")
|
||||
require.NoError(t, err)
|
||||
|
||||
ts := httptest.NewServer(authenticator)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
@@ -30,7 +29,7 @@ func TestForwardAuthFail(t *testing.T) {
|
||||
}))
|
||||
t.Cleanup(server.Close)
|
||||
|
||||
middleware, err := NewForward(context.Background(), next, dynamic.ForwardAuth{
|
||||
middleware, err := NewForward(t.Context(), next, dynamic.ForwardAuth{
|
||||
Address: server.URL,
|
||||
}, "authTest")
|
||||
require.NoError(t, err)
|
||||
@@ -77,7 +76,7 @@ func TestForwardAuthSuccess(t *testing.T) {
|
||||
AuthResponseHeaders: []string{"X-Auth-User", "X-Auth-Group"},
|
||||
AuthResponseHeadersRegex: "^Foo-",
|
||||
}
|
||||
middleware, err := NewForward(context.Background(), next, auth, "authTest")
|
||||
middleware, err := NewForward(t.Context(), next, auth, "authTest")
|
||||
require.NoError(t, err)
|
||||
|
||||
ts := httptest.NewServer(middleware)
|
||||
@@ -110,7 +109,7 @@ func TestForwardAuthRedirect(t *testing.T) {
|
||||
|
||||
auth := dynamic.ForwardAuth{Address: authTs.URL}
|
||||
|
||||
authMiddleware, err := NewForward(context.Background(), next, auth, "authTest")
|
||||
authMiddleware, err := NewForward(t.Context(), next, auth, "authTest")
|
||||
require.NoError(t, err)
|
||||
|
||||
ts := httptest.NewServer(authMiddleware)
|
||||
@@ -161,7 +160,7 @@ func TestForwardAuthRemoveHopByHopHeaders(t *testing.T) {
|
||||
|
||||
auth := dynamic.ForwardAuth{Address: authTs.URL}
|
||||
|
||||
authMiddleware, err := NewForward(context.Background(), next, auth, "authTest")
|
||||
authMiddleware, err := NewForward(t.Context(), next, auth, "authTest")
|
||||
require.NoError(t, err)
|
||||
|
||||
ts := httptest.NewServer(authMiddleware)
|
||||
@@ -179,7 +178,7 @@ func TestForwardAuthRemoveHopByHopHeaders(t *testing.T) {
|
||||
assert.Equal(t, http.StatusFound, res.StatusCode, "they should be equal")
|
||||
|
||||
for _, header := range forward.HopHeaders {
|
||||
assert.Equal(t, "", res.Header.Get(header), "hop-by-hop header '%s' mustn't be set", header)
|
||||
assert.Empty(t, res.Header.Get(header), "hop-by-hop header '%s' mustn't be set", header)
|
||||
}
|
||||
|
||||
location, err := res.Location()
|
||||
@@ -207,7 +206,7 @@ func TestForwardAuthFailResponseHeaders(t *testing.T) {
|
||||
auth := dynamic.ForwardAuth{
|
||||
Address: authTs.URL,
|
||||
}
|
||||
authMiddleware, err := NewForward(context.Background(), next, auth, "authTest")
|
||||
authMiddleware, err := NewForward(t.Context(), next, auth, "authTest")
|
||||
require.NoError(t, err)
|
||||
|
||||
ts := httptest.NewServer(authMiddleware)
|
||||
@@ -469,10 +468,10 @@ func TestForwardAuthUsesTracing(t *testing.T) {
|
||||
|
||||
tr, _ := tracing.NewTracing("testApp", 100, &mockBackend{tracer})
|
||||
|
||||
next, err := NewForward(context.Background(), next, auth, "authTest")
|
||||
next, err := NewForward(t.Context(), next, auth, "authTest")
|
||||
require.NoError(t, err)
|
||||
|
||||
next = tracingMiddleware.NewEntryPoint(context.Background(), tr, "tracingTest", next)
|
||||
next = tracingMiddleware.NewEntryPoint(t.Context(), tr, "tracingTest", next)
|
||||
|
||||
ts := httptest.NewServer(next)
|
||||
t.Cleanup(ts.Close)
|
||||
|
||||
@@ -2,7 +2,6 @@ package buffering
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"math"
|
||||
"net/http"
|
||||
@@ -57,7 +56,7 @@ func TestBuffering(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
})
|
||||
|
||||
buffMiddleware, err := New(context.Background(), next, test.config, "foo")
|
||||
buffMiddleware, err := New(t.Context(), next, test.config, "foo")
|
||||
require.NoError(t, err)
|
||||
|
||||
req := httptest.NewRequest(http.MethodPost, "http://localhost", bytes.NewBuffer(test.body))
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package compress
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
@@ -34,7 +33,7 @@ func TestShouldCompressWhenNoContentEncodingHeader(t *testing.T) {
|
||||
_, err := rw.Write(baseBody)
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
handler, err := New(context.Background(), next, dynamic.Compress{}, "testing")
|
||||
handler, err := New(t.Context(), next, dynamic.Compress{}, "testing")
|
||||
require.NoError(t, err)
|
||||
|
||||
rw := httptest.NewRecorder()
|
||||
@@ -61,7 +60,7 @@ func TestShouldNotCompressWhenContentEncodingHeader(t *testing.T) {
|
||||
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
})
|
||||
handler, err := New(context.Background(), next, dynamic.Compress{}, "testing")
|
||||
handler, err := New(t.Context(), next, dynamic.Compress{}, "testing")
|
||||
require.NoError(t, err)
|
||||
|
||||
rw := httptest.NewRecorder()
|
||||
@@ -70,7 +69,7 @@ func TestShouldNotCompressWhenContentEncodingHeader(t *testing.T) {
|
||||
assert.Equal(t, gzipValue, rw.Header().Get(contentEncodingHeader))
|
||||
assert.Equal(t, acceptEncodingHeader, rw.Header().Get(varyHeader))
|
||||
|
||||
assert.EqualValues(t, rw.Body.Bytes(), fakeCompressedBody)
|
||||
assert.Equal(t, rw.Body.Bytes(), fakeCompressedBody)
|
||||
}
|
||||
|
||||
func TestShouldNotCompressWhenNoAcceptEncodingHeader(t *testing.T) {
|
||||
@@ -83,14 +82,14 @@ func TestShouldNotCompressWhenNoAcceptEncodingHeader(t *testing.T) {
|
||||
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
})
|
||||
handler, err := New(context.Background(), next, dynamic.Compress{}, "testing")
|
||||
handler, err := New(t.Context(), next, dynamic.Compress{}, "testing")
|
||||
require.NoError(t, err)
|
||||
|
||||
rw := httptest.NewRecorder()
|
||||
handler.ServeHTTP(rw, req)
|
||||
|
||||
assert.Empty(t, rw.Header().Get(contentEncodingHeader))
|
||||
assert.EqualValues(t, rw.Body.Bytes(), fakeBody)
|
||||
assert.Equal(t, rw.Body.Bytes(), fakeBody)
|
||||
}
|
||||
|
||||
func TestShouldNotCompressWhenSpecificContentType(t *testing.T) {
|
||||
@@ -144,7 +143,7 @@ func TestShouldNotCompressWhenSpecificContentType(t *testing.T) {
|
||||
}
|
||||
})
|
||||
|
||||
handler, err := New(context.Background(), next, test.conf, "test")
|
||||
handler, err := New(t.Context(), next, test.conf, "test")
|
||||
require.NoError(t, err)
|
||||
|
||||
rw := httptest.NewRecorder()
|
||||
@@ -152,7 +151,7 @@ func TestShouldNotCompressWhenSpecificContentType(t *testing.T) {
|
||||
|
||||
assert.Empty(t, rw.Header().Get(acceptEncodingHeader))
|
||||
assert.Empty(t, rw.Header().Get(contentEncodingHeader))
|
||||
assert.EqualValues(t, rw.Body.Bytes(), baseBody)
|
||||
assert.Equal(t, rw.Body.Bytes(), baseBody)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -194,7 +193,7 @@ func TestIntegrationShouldNotCompress(t *testing.T) {
|
||||
|
||||
for _, test := range testCases {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
compress, err := New(context.Background(), test.handler, dynamic.Compress{}, "testing")
|
||||
compress, err := New(t.Context(), test.handler, dynamic.Compress{}, "testing")
|
||||
require.NoError(t, err)
|
||||
|
||||
ts := httptest.NewServer(compress)
|
||||
@@ -213,7 +212,7 @@ func TestIntegrationShouldNotCompress(t *testing.T) {
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
require.NoError(t, err)
|
||||
assert.EqualValues(t, fakeCompressedBody, body)
|
||||
assert.Equal(t, fakeCompressedBody, body)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -229,7 +228,7 @@ func TestShouldWriteHeaderWhenFlush(t *testing.T) {
|
||||
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
})
|
||||
handler, err := New(context.Background(), next, dynamic.Compress{}, "testing")
|
||||
handler, err := New(t.Context(), next, dynamic.Compress{}, "testing")
|
||||
require.NoError(t, err)
|
||||
|
||||
ts := httptest.NewServer(handler)
|
||||
@@ -280,7 +279,7 @@ func TestIntegrationShouldCompress(t *testing.T) {
|
||||
|
||||
for _, test := range testCases {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
compress, err := New(context.Background(), test.handler, dynamic.Compress{}, "testing")
|
||||
compress, err := New(t.Context(), test.handler, dynamic.Compress{}, "testing")
|
||||
require.NoError(t, err)
|
||||
|
||||
ts := httptest.NewServer(compress)
|
||||
@@ -337,7 +336,7 @@ func TestMinResponseBodyBytes(t *testing.T) {
|
||||
}
|
||||
})
|
||||
|
||||
handler, err := New(context.Background(), next, dynamic.Compress{MinResponseBodyBytes: test.minResponseBodyBytes}, "testing")
|
||||
handler, err := New(t.Context(), next, dynamic.Compress{MinResponseBodyBytes: test.minResponseBodyBytes}, "testing")
|
||||
require.NoError(t, err)
|
||||
|
||||
rw := httptest.NewRecorder()
|
||||
@@ -345,12 +344,12 @@ func TestMinResponseBodyBytes(t *testing.T) {
|
||||
|
||||
if test.expectedCompression {
|
||||
assert.Equal(t, gzipValue, rw.Header().Get(contentEncodingHeader))
|
||||
assert.NotEqualValues(t, rw.Body.Bytes(), fakeBody)
|
||||
assert.NotEqual(t, rw.Body.Bytes(), fakeBody)
|
||||
return
|
||||
}
|
||||
|
||||
assert.Empty(t, rw.Header().Get(contentEncodingHeader))
|
||||
assert.EqualValues(t, rw.Body.Bytes(), fakeBody)
|
||||
assert.Equal(t, rw.Body.Bytes(), fakeBody)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -373,7 +372,7 @@ func Test1xxResponses(t *testing.T) {
|
||||
}
|
||||
})
|
||||
|
||||
compress, err := New(context.Background(), next, dynamic.Compress{MinResponseBodyBytes: 1024}, "testing")
|
||||
compress, err := New(t.Context(), next, dynamic.Compress{MinResponseBodyBytes: 1024}, "testing")
|
||||
require.NoError(t, err)
|
||||
|
||||
server := httptest.NewServer(compress)
|
||||
@@ -417,7 +416,7 @@ func Test1xxResponses(t *testing.T) {
|
||||
return nil
|
||||
},
|
||||
}
|
||||
req, _ := http.NewRequestWithContext(httptrace.WithClientTrace(context.Background(), trace), http.MethodGet, server.URL, nil)
|
||||
req, _ := http.NewRequestWithContext(httptrace.WithClientTrace(t.Context(), trace), http.MethodGet, server.URL, nil)
|
||||
req.Header.Add(acceptEncodingHeader, gzipValue)
|
||||
|
||||
res, err := frontendClient.Do(req)
|
||||
@@ -432,7 +431,7 @@ func Test1xxResponses(t *testing.T) {
|
||||
|
||||
assert.Equal(t, gzipValue, res.Header.Get(contentEncodingHeader))
|
||||
body, _ := io.ReadAll(res.Body)
|
||||
assert.NotEqualValues(t, body, fakeBody)
|
||||
assert.NotEqual(t, body, fakeBody)
|
||||
}
|
||||
|
||||
func BenchmarkCompress(b *testing.B) {
|
||||
@@ -478,7 +477,7 @@ func BenchmarkCompress(b *testing.B) {
|
||||
_, err := rw.Write(baseBody)
|
||||
assert.NoError(b, err)
|
||||
})
|
||||
handler, _ := New(context.Background(), next, dynamic.Compress{}, "testing")
|
||||
handler, _ := New(b.Context(), next, dynamic.Compress{}, "testing")
|
||||
|
||||
req, _ := http.NewRequest(http.MethodGet, "/whatever", nil)
|
||||
req.Header.Set("Accept-Encoding", "gzip")
|
||||
|
||||
@@ -170,7 +170,7 @@ func TestHandler(t *testing.T) {
|
||||
}
|
||||
_, _ = fmt.Fprintln(w, http.StatusText(test.backendCode))
|
||||
})
|
||||
errorPageHandler, err := New(context.Background(), handler, *test.errorPage, serviceBuilderMock, "test")
|
||||
errorPageHandler, err := New(t.Context(), handler, *test.errorPage, serviceBuilderMock, "test")
|
||||
require.NoError(t, err)
|
||||
|
||||
req := testhelpers.MustNewRequest(http.MethodGet, "http://localhost/test?foo=bar&baz=buz", nil)
|
||||
@@ -205,7 +205,7 @@ func Test1xxResponses(t *testing.T) {
|
||||
|
||||
config := dynamic.ErrorPage{Service: "error", Query: "/", Status: []string{"200"}}
|
||||
|
||||
errorPageHandler, err := New(context.Background(), next, config, serviceBuilderMock, "test")
|
||||
errorPageHandler, err := New(t.Context(), next, config, serviceBuilderMock, "test")
|
||||
require.NoError(t, err)
|
||||
|
||||
server := httptest.NewServer(errorPageHandler)
|
||||
@@ -249,7 +249,7 @@ func Test1xxResponses(t *testing.T) {
|
||||
return nil
|
||||
},
|
||||
}
|
||||
req, _ := http.NewRequestWithContext(httptrace.WithClientTrace(context.Background(), trace), http.MethodGet, server.URL, nil)
|
||||
req, _ := http.NewRequestWithContext(httptrace.WithClientTrace(t.Context(), trace), http.MethodGet, server.URL, nil)
|
||||
|
||||
res, err := frontendClient.Do(req)
|
||||
assert.NoError(t, err)
|
||||
|
||||
@@ -53,6 +53,7 @@ func NewHeader(next http.Handler, cfg dynamic.Headers) (*Header, error) {
|
||||
func (s *Header) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||
// Handle Cors headers and preflight if configured.
|
||||
if isPreflight := s.processCorsHeaders(rw, req); isPreflight {
|
||||
rw.Header().Set("Content-Length", "0")
|
||||
rw.WriteHeader(http.StatusOK)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -134,6 +134,7 @@ func TestNewHeader_CORSPreflights(t *testing.T) {
|
||||
"Origin": {"https://foo.bar.org"},
|
||||
},
|
||||
expected: map[string][]string{
|
||||
"Content-Length": {"0"},
|
||||
"Access-Control-Allow-Origin": {"https://foo.bar.org"},
|
||||
"Access-Control-Max-Age": {"600"},
|
||||
"Access-Control-Allow-Methods": {"GET,OPTIONS,PUT"},
|
||||
@@ -152,6 +153,7 @@ func TestNewHeader_CORSPreflights(t *testing.T) {
|
||||
"Origin": {"https://foo.bar.org"},
|
||||
},
|
||||
expected: map[string][]string{
|
||||
"Content-Length": {"0"},
|
||||
"Access-Control-Allow-Origin": {"*"},
|
||||
"Access-Control-Max-Age": {"600"},
|
||||
"Access-Control-Allow-Methods": {"GET,OPTIONS,PUT"},
|
||||
@@ -171,6 +173,7 @@ func TestNewHeader_CORSPreflights(t *testing.T) {
|
||||
"Origin": {"https://foo.bar.org"},
|
||||
},
|
||||
expected: map[string][]string{
|
||||
"Content-Length": {"0"},
|
||||
"Access-Control-Allow-Origin": {"*"},
|
||||
"Access-Control-Max-Age": {"600"},
|
||||
"Access-Control-Allow-Methods": {"GET,OPTIONS,PUT"},
|
||||
@@ -191,6 +194,7 @@ func TestNewHeader_CORSPreflights(t *testing.T) {
|
||||
"Origin": {"https://foo.bar.org"},
|
||||
},
|
||||
expected: map[string][]string{
|
||||
"Content-Length": {"0"},
|
||||
"Access-Control-Allow-Origin": {"*"},
|
||||
"Access-Control-Max-Age": {"600"},
|
||||
"Access-Control-Allow-Methods": {"GET,OPTIONS,PUT"},
|
||||
@@ -210,6 +214,7 @@ func TestNewHeader_CORSPreflights(t *testing.T) {
|
||||
"Origin": {"https://foo.bar.org"},
|
||||
},
|
||||
expected: map[string][]string{
|
||||
"Content-Length": {"0"},
|
||||
"Access-Control-Allow-Origin": {"*"},
|
||||
"Access-Control-Max-Age": {"600"},
|
||||
"Access-Control-Allow-Methods": {"GET,OPTIONS,PUT"},
|
||||
|
||||
@@ -3,7 +3,6 @@ package headers
|
||||
// Middleware tests based on https://github.com/unrolled/secure
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
@@ -20,7 +19,7 @@ import (
|
||||
func TestNew_withoutOptions(t *testing.T) {
|
||||
next := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) })
|
||||
|
||||
mid, err := New(context.Background(), next, dynamic.Headers{}, "testing")
|
||||
mid, err := New(t.Context(), next, dynamic.Headers{}, "testing")
|
||||
require.Errorf(t, err, "headers configuration not valid")
|
||||
|
||||
assert.Nil(t, mid)
|
||||
@@ -55,7 +54,7 @@ func TestNew_allowedHosts(t *testing.T) {
|
||||
AllowedHosts: []string{"foo.com", "bar.com"},
|
||||
}
|
||||
|
||||
mid, err := New(context.Background(), emptyHandler, cfg, "foo")
|
||||
mid, err := New(t.Context(), emptyHandler, cfg, "foo")
|
||||
require.NoError(t, err)
|
||||
|
||||
for _, test := range testCases {
|
||||
@@ -86,7 +85,7 @@ func TestNew_customHeaders(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
mid, err := New(context.Background(), next, cfg, "testing")
|
||||
mid, err := New(t.Context(), next, cfg, "testing")
|
||||
require.NoError(t, err)
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/foo", nil)
|
||||
@@ -134,7 +133,7 @@ func Test1xxResponses(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
mid, err := New(context.Background(), next, cfg, "testing")
|
||||
mid, err := New(t.Context(), next, cfg, "testing")
|
||||
require.NoError(t, err)
|
||||
|
||||
server := httptest.NewServer(mid)
|
||||
@@ -178,7 +177,7 @@ func Test1xxResponses(t *testing.T) {
|
||||
return nil
|
||||
},
|
||||
}
|
||||
req, _ := http.NewRequestWithContext(httptrace.WithClientTrace(context.Background(), trace), http.MethodGet, server.URL, nil)
|
||||
req, _ := http.NewRequestWithContext(httptrace.WithClientTrace(t.Context(), trace), http.MethodGet, server.URL, nil)
|
||||
|
||||
res, err := frontendClient.Do(req)
|
||||
assert.NoError(t, err)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package ipallowlist
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
@@ -37,7 +36,7 @@ func TestNewIPAllowLister(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
next := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})
|
||||
allowLister, err := New(context.Background(), next, test.allowList, "traefikTest")
|
||||
allowLister, err := New(t.Context(), next, test.allowList, "traefikTest")
|
||||
|
||||
if test.expectedError {
|
||||
assert.Error(t, err)
|
||||
@@ -79,7 +78,7 @@ func TestIPAllowLister_ServeHTTP(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
next := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})
|
||||
allowLister, err := New(context.Background(), next, test.allowList, "traefikTest")
|
||||
allowLister, err := New(t.Context(), next, test.allowList, "traefikTest")
|
||||
require.NoError(t, err)
|
||||
|
||||
recorder := httptest.NewRecorder()
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package ipwhitelist
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
@@ -37,7 +36,7 @@ func TestNewIPWhiteLister(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
next := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})
|
||||
whiteLister, err := New(context.Background(), next, test.whiteList, "traefikTest")
|
||||
whiteLister, err := New(t.Context(), next, test.whiteList, "traefikTest")
|
||||
|
||||
if test.expectedError {
|
||||
assert.Error(t, err)
|
||||
@@ -79,7 +78,7 @@ func TestIPWhiteLister_ServeHTTP(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
next := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})
|
||||
whiteLister, err := New(context.Background(), next, test.whiteList, "traefikTest")
|
||||
whiteLister, err := New(t.Context(), next, test.whiteList, "traefikTest")
|
||||
require.NoError(t, err)
|
||||
|
||||
recorder := httptest.NewRecorder()
|
||||
|
||||
@@ -227,11 +227,11 @@ func getIssuerDNInfo(ctx context.Context, options *IssuerDistinguishedNameOption
|
||||
|
||||
content := &strings.Builder{}
|
||||
|
||||
// Manage non standard attributes
|
||||
// Manage non-standard attributes
|
||||
for _, name := range cs.Names {
|
||||
// Domain Component - RFC 2247
|
||||
if options.DomainComponent && attributeTypeNames[name.Type.String()] == "DC" {
|
||||
content.WriteString(fmt.Sprintf("DC=%s%s", name.Value, subFieldSeparator))
|
||||
_, _ = fmt.Fprintf(content, "DC=%s%s", name.Value, subFieldSeparator)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -273,7 +273,7 @@ func getSubjectDNInfo(ctx context.Context, options *SubjectDistinguishedNameOpti
|
||||
for _, name := range cs.Names {
|
||||
// Domain Component - RFC 2247
|
||||
if options.DomainComponent && attributeTypeNames[name.Type.String()] == "DC" {
|
||||
content.WriteString(fmt.Sprintf("DC=%s%s", name.Value, subFieldSeparator))
|
||||
_, _ = fmt.Fprintf(content, "DC=%s%s", name.Value, subFieldSeparator)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package passtlsclientcert
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
@@ -313,7 +312,7 @@ func TestPassTLSClientCert_PEM(t *testing.T) {
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tlsClientHeaders, err := New(context.Background(), next, test.config, "foo")
|
||||
tlsClientHeaders, err := New(t.Context(), next, test.config, "foo")
|
||||
require.NoError(t, err)
|
||||
|
||||
res := httptest.NewRecorder()
|
||||
@@ -535,7 +534,7 @@ func TestPassTLSClientCert_certInfo(t *testing.T) {
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tlsClientHeaders, err := New(context.Background(), next, test.config, "foo")
|
||||
tlsClientHeaders, err := New(t.Context(), next, test.config, "foo")
|
||||
require.NoError(t, err)
|
||||
|
||||
res := httptest.NewRecorder()
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package pipelining
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
@@ -62,7 +61,7 @@ func TestNew(t *testing.T) {
|
||||
assert.Equal(t, test.implementCloseNotifier, ok)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
})
|
||||
handler := New(context.Background(), nextHandler, "pipe")
|
||||
handler := New(t.Context(), nextHandler, "pipe")
|
||||
|
||||
req := httptest.NewRequest(test.HTTPMethod, "http://localhost", nil)
|
||||
|
||||
@@ -87,7 +86,7 @@ func Test1xxResponses(t *testing.T) {
|
||||
_, _ = w.Write([]byte("Hello"))
|
||||
})
|
||||
|
||||
pipe := New(context.Background(), next, "pipe")
|
||||
pipe := New(t.Context(), next, "pipe")
|
||||
|
||||
server := httptest.NewServer(pipe)
|
||||
t.Cleanup(server.Close)
|
||||
@@ -130,7 +129,7 @@ func Test1xxResponses(t *testing.T) {
|
||||
return nil
|
||||
},
|
||||
}
|
||||
req, _ := http.NewRequestWithContext(httptrace.WithClientTrace(context.Background(), trace), http.MethodGet, server.URL, nil)
|
||||
req, _ := http.NewRequestWithContext(httptrace.WithClientTrace(t.Context(), trace), http.MethodGet, server.URL, nil)
|
||||
|
||||
res, err := frontendClient.Do(req)
|
||||
assert.NoError(t, err)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package ratelimiter
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
@@ -94,7 +93,7 @@ func TestNewRateLimiter(t *testing.T) {
|
||||
|
||||
next := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})
|
||||
|
||||
h, err := New(context.Background(), next, test.config, "rate-limiter")
|
||||
h, err := New(t.Context(), next, test.config, "rate-limiter")
|
||||
if test.expectedError != "" {
|
||||
assert.EqualError(t, err, test.expectedError)
|
||||
} else {
|
||||
@@ -258,7 +257,7 @@ func TestRateLimit(t *testing.T) {
|
||||
next := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
reqCount++
|
||||
})
|
||||
h, err := New(context.Background(), next, test.config, "rate-limiter")
|
||||
h, err := New(t.Context(), next, test.config, "rate-limiter")
|
||||
require.NoError(t, err)
|
||||
|
||||
loadPeriod := time.Duration(1e9 / test.incomingLoad)
|
||||
@@ -266,11 +265,7 @@ func TestRateLimit(t *testing.T) {
|
||||
end := start.Add(test.loadDuration)
|
||||
ticker := time.NewTicker(loadPeriod)
|
||||
defer ticker.Stop()
|
||||
for {
|
||||
if time.Now().After(end) {
|
||||
break
|
||||
}
|
||||
|
||||
for !time.Now().After(end) {
|
||||
req := testhelpers.MustNewRequest(http.MethodGet, "http://localhost", nil)
|
||||
req.RemoteAddr = "127.0.0.1:1234"
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package recovery
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
"net/http"
|
||||
@@ -47,7 +46,7 @@ func TestRecoverHandler(t *testing.T) {
|
||||
}
|
||||
panic(test.panicErr)
|
||||
}
|
||||
recovery, err := New(context.Background(), http.HandlerFunc(fn))
|
||||
recovery, err := New(t.Context(), http.HandlerFunc(fn))
|
||||
require.NoError(t, err)
|
||||
|
||||
server := httptest.NewServer(recovery)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package redirect
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
@@ -158,7 +157,7 @@ func TestRedirectRegexHandler(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
next := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})
|
||||
handler, err := NewRedirectRegex(context.Background(), next, test.config, "traefikTest")
|
||||
handler, err := NewRedirectRegex(t.Context(), next, test.config, "traefikTest")
|
||||
|
||||
if test.errorExpected {
|
||||
require.Error(t, err)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user