From 27353d07404baf4d12bf5dea105d31739c827612 Mon Sep 17 00:00:00 2001 From: Ludovic Fernandez Date: Wed, 7 Jun 2023 09:30:05 +0200 Subject: [PATCH 01/13] Update go-acme/lego to v4.12.1 --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 06a0f01f1..1b0b9e117 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( github.com/docker/go-connections v0.4.0 github.com/fatih/structs v1.1.0 github.com/gambol99/go-marathon v0.0.0-20180614232016-99a156b96fb2 - github.com/go-acme/lego/v4 v4.12.0 + github.com/go-acme/lego/v4 v4.12.1 github.com/go-check/check v0.0.0-00010101000000-000000000000 github.com/go-kit/kit v0.10.1-0.20200915143503-439c4d2ed3ea github.com/golang/protobuf v1.5.2 diff --git a/go.sum b/go.sum index e0b106419..f24f2569e 100644 --- a/go.sum +++ b/go.sum @@ -657,8 +657,8 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.7.4/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY= github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= -github.com/go-acme/lego/v4 v4.12.0 h1:jox3II6YRjt1EXvrymSQuSNgEUOcbUkF2je0kyuv6YM= -github.com/go-acme/lego/v4 v4.12.0/go.mod h1:UZoOlhVmUYP/N0z4tEbfUjoCNHRZNObzqWZtT76DIsc= +github.com/go-acme/lego/v4 v4.12.1 h1:Cy3FS7wADLNBqCLpz2wdfdNrThW9rZy8RCAfnUrL2uE= +github.com/go-acme/lego/v4 v4.12.1/go.mod h1:UZoOlhVmUYP/N0z4tEbfUjoCNHRZNObzqWZtT76DIsc= github.com/go-asn1-ber/asn1-ber v1.3.1/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs= github.com/go-cmd/cmd v1.0.5/go.mod h1:y8q8qlK5wQibcw63djSl/ntiHUHXHGdCkPk0j4QeW4s= From 878e7de56a875ccb09d05d61d4ffc3e2e22eda87 Mon Sep 17 00:00:00 2001 From: Dylan Rodgers <94392934+tomatokoolaid@users.noreply.github.com> Date: Fri, 9 Jun 2023 01:18:05 -0600 Subject: [PATCH 02/13] Add business callouts --- .../getting-started/quick-start-with-kubernetes.md | 2 ++ .../includes/traefik-api-management-kubernetes.md | 11 +++++++++++ docs/content/providers/kubernetes-crd.md | 2 +- docs/content/providers/kubernetes-gateway.md | 2 ++ docs/content/providers/kubernetes-ingress.md | 2 +- .../reference/dynamic-configuration/kubernetes-crd.md | 2 ++ .../dynamic-configuration/kubernetes-gateway.md | 2 ++ docs/content/routing/providers/kubernetes-crd.md | 2 +- docs/content/routing/providers/kubernetes-gateway.md | 2 ++ docs/content/routing/providers/kubernetes-ingress.md | 2 +- 10 files changed, 25 insertions(+), 4 deletions(-) create mode 100644 docs/content/includes/traefik-api-management-kubernetes.md diff --git a/docs/content/getting-started/quick-start-with-kubernetes.md b/docs/content/getting-started/quick-start-with-kubernetes.md index 8962e7e05..4d0d3b604 100644 --- a/docs/content/getting-started/quick-start-with-kubernetes.md +++ b/docs/content/getting-started/quick-start-with-kubernetes.md @@ -316,3 +316,5 @@ curl -v http://localhost/ - [Filter the ingresses](../providers/kubernetes-ingress.md#ingressclass) to use with [IngressClass](https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-class) - Use [IngressRoute CRD](../providers/kubernetes-crd.md) - Protect [ingresses with TLS](../routing/providers/kubernetes-ingress.md#enabling-tls-via-annotations) + +{!traefik-api-management-kubernetes.md!} diff --git a/docs/content/includes/traefik-api-management-kubernetes.md b/docs/content/includes/traefik-api-management-kubernetes.md new file mode 100644 index 000000000..f89712319 --- /dev/null +++ b/docs/content/includes/traefik-api-management-kubernetes.md @@ -0,0 +1,11 @@ +--- + +!!! question "Managing APIs in Kubernetes?" + + If your organization is publishing, securing, and managing APIs, consider [Traefik Hub](https://traefik.io/traefik-hub/) for your API management solution. + + - K8s services auto-discovery, 100% CRDs configuration, & full GitOps compliance + - Centralized control plane for all APIs, users, & infrastructure components + - Self-serve API portal with API discovery, documentation, testing, & access control + + Traefik Hub makes managing APIs easier than ever before. See for yourself in this [short video walkthrough](https://info.traefik.io/watch-traefik-hub-demo). diff --git a/docs/content/providers/kubernetes-crd.md b/docs/content/providers/kubernetes-crd.md index f0c2635bc..5b9d19735 100644 --- a/docs/content/providers/kubernetes-crd.md +++ b/docs/content/providers/kubernetes-crd.md @@ -345,4 +345,4 @@ providers: For additional information, refer to the [full example](../user-guides/crd-acme/index.md) with Let's Encrypt. -{!traefik-for-business-applications.md!} +{!traefik-api-management-kubernetes.md!} diff --git a/docs/content/providers/kubernetes-gateway.md b/docs/content/providers/kubernetes-gateway.md index 759ca989e..809e5630a 100644 --- a/docs/content/providers/kubernetes-gateway.md +++ b/docs/content/providers/kubernetes-gateway.md @@ -268,3 +268,5 @@ providers: ```bash tab="CLI" --providers.kubernetesgateway.throttleDuration=10s ``` + +{!traefik-api-management-kubernetes.md!} diff --git a/docs/content/providers/kubernetes-ingress.md b/docs/content/providers/kubernetes-ingress.md index c9e9d8289..0414ca9ce 100644 --- a/docs/content/providers/kubernetes-ingress.md +++ b/docs/content/providers/kubernetes-ingress.md @@ -504,4 +504,4 @@ providers: To learn more about the various aspects of the Ingress specification that Traefik supports, many examples of Ingresses definitions are located in the test [examples](https://github.com/traefik/traefik/tree/v2.10/pkg/provider/kubernetes/ingress/fixtures) of the Traefik repository. -{!traefik-for-business-applications.md!} +{!traefik-api-management-kubernetes.md!} diff --git a/docs/content/reference/dynamic-configuration/kubernetes-crd.md b/docs/content/reference/dynamic-configuration/kubernetes-crd.md index 29228f252..5519ad0f5 100644 --- a/docs/content/reference/dynamic-configuration/kubernetes-crd.md +++ b/docs/content/reference/dynamic-configuration/kubernetes-crd.md @@ -35,3 +35,5 @@ Dynamic configuration with Kubernetes Custom Resource ```yaml --8<-- "content/reference/dynamic-configuration/kubernetes-crd-rbac.yml" ``` + +{!traefik-api-management-kubernetes.md!} diff --git a/docs/content/reference/dynamic-configuration/kubernetes-gateway.md b/docs/content/reference/dynamic-configuration/kubernetes-gateway.md index 1c0d4ce04..6700a218d 100644 --- a/docs/content/reference/dynamic-configuration/kubernetes-gateway.md +++ b/docs/content/reference/dynamic-configuration/kubernetes-gateway.md @@ -29,3 +29,5 @@ Dynamic configuration with Kubernetes Gateway provider. ```yaml --8<-- "content/reference/dynamic-configuration/kubernetes-gateway-rbac.yml" ``` + +{!traefik-api-management-kubernetes.md!} diff --git a/docs/content/routing/providers/kubernetes-crd.md b/docs/content/routing/providers/kubernetes-crd.md index 17f8bf8e5..30e44377d 100644 --- a/docs/content/routing/providers/kubernetes-crd.md +++ b/docs/content/routing/providers/kubernetes-crd.md @@ -1904,4 +1904,4 @@ If the ServersTransport CRD is defined in another provider the cross-provider fo Also see the [full example](../../user-guides/crd-acme/index.md) with Let's Encrypt. -{!traefik-for-business-applications.md!} +{!traefik-api-management-kubernetes.md!} diff --git a/docs/content/routing/providers/kubernetes-gateway.md b/docs/content/routing/providers/kubernetes-gateway.md index e82e0ae59..430b66316 100644 --- a/docs/content/routing/providers/kubernetes-gateway.md +++ b/docs/content/routing/providers/kubernetes-gateway.md @@ -354,3 +354,5 @@ Kubernetes cluster before creating `TLSRoute` objects. | [10] | `port` | The port of the referent service. | | [11] | `group` | Group is the group of the referent. Only `traefik.io`, `traefik.containo.us` and `gateway.networking.k8s.io` values are supported. | | [12] | `kind` | Kind is kind of the referent. Only `TraefikService` and `Service` values are supported. | + +{!traefik-api-management-kubernetes.md!} diff --git a/docs/content/routing/providers/kubernetes-ingress.md b/docs/content/routing/providers/kubernetes-ingress.md index 9156cc67e..fc9c31d4c 100644 --- a/docs/content/routing/providers/kubernetes-ingress.md +++ b/docs/content/routing/providers/kubernetes-ingress.md @@ -969,4 +969,4 @@ This will allow users to create a "default router" that will match all unmatched To do this, use the `traefik.ingress.kubernetes.io/router.priority` annotation (as seen in [Annotations on Ingress](#on-ingress)) on your ingresses accordingly. -{!traefik-for-business-applications.md!} +{!traefik-api-management-kubernetes.md!} From d1bdeb3a92ba539021dbc5c33939587239e53639 Mon Sep 17 00:00:00 2001 From: Romain Date: Wed, 14 Jun 2023 14:48:05 +0200 Subject: [PATCH 03/13] Fix missing trailer with custom errors middleware Co-authored-by: LandryBe --- pkg/middlewares/customerrors/custom_errors.go | 62 +++++++++++-------- 1 file changed, 35 insertions(+), 27 deletions(-) diff --git a/pkg/middlewares/customerrors/custom_errors.go b/pkg/middlewares/customerrors/custom_errors.go index b24a6b04c..c764b2cf8 100644 --- a/pkg/middlewares/customerrors/custom_errors.go +++ b/pkg/middlewares/customerrors/custom_errors.go @@ -32,7 +32,7 @@ type serviceBuilder interface { BuildHTTP(ctx context.Context, serviceName string) (http.Handler, error) } -// customErrors is a middleware that provides the custom error pages.. +// customErrors is a middleware that provides the custom error pages. type customErrors struct { name string next http.Handler @@ -131,10 +131,10 @@ type responseInterceptor interface { isFilteredCode() bool } -// codeCatcher is a response writer that detects as soon as possible whether the -// response is a code within the ranges of codes it watches for. If it is, it -// simply drops the data from the response. Otherwise, it forwards it directly to -// the original client (its responseWriter) without any buffering. +// codeCatcher is a response writer that detects as soon as possible +// whether the response is a code within the ranges of codes it watches for. +// If it is, it simply drops the data from the response. +// Otherwise, it forwards it directly to the original client (its responseWriter) without any buffering. type codeCatcher struct { headerMap http.Header code int @@ -144,16 +144,6 @@ type codeCatcher struct { headersSent bool } -type codeCatcherWithCloseNotify struct { - *codeCatcher -} - -// CloseNotify returns a channel that receives at most a -// single value (true) when the client connection has gone away. -func (cc *codeCatcherWithCloseNotify) CloseNotify() <-chan bool { - return cc.responseWriter.(http.CloseNotifier).CloseNotify() -} - func newCodeCatcher(rw http.ResponseWriter, httpCodeRanges types.HTTPCodeRanges) responseInterceptor { catcher := &codeCatcher{ headerMap: make(http.Header), @@ -168,6 +158,10 @@ func newCodeCatcher(rw http.ResponseWriter, httpCodeRanges types.HTTPCodeRanges) } func (cc *codeCatcher) Header() http.Header { + if cc.headersSent { + return cc.responseWriter.Header() + } + if cc.headerMap == nil { cc.headerMap = make(http.Header) } @@ -247,6 +241,16 @@ func (cc *codeCatcher) Flush() { } } +type codeCatcherWithCloseNotify struct { + *codeCatcher +} + +// CloseNotify returns a channel that receives at most a single value (true) +// when the client connection has gone away. +func (cc *codeCatcherWithCloseNotify) CloseNotify() <-chan bool { + return cc.responseWriter.(http.CloseNotifier).CloseNotify() +} + // codeModifier forwards a response back to the client, // while enforcing a given response code. type codeModifier interface { @@ -277,18 +281,12 @@ type codeModifierWithoutCloseNotify struct { responseWriter http.ResponseWriter } -type codeModifierWithCloseNotify struct { - *codeModifierWithoutCloseNotify -} - -// CloseNotify returns a channel that receives at most a -// single value (true) when the client connection has gone away. -func (r *codeModifierWithCloseNotify) CloseNotify() <-chan bool { - return r.responseWriter.(http.CloseNotifier).CloseNotify() -} - // Header returns the response headers. func (r *codeModifierWithoutCloseNotify) Header() http.Header { + if r.headerSent { + return r.responseWriter.Header() + } + if r.headerMap == nil { r.headerMap = make(http.Header) } @@ -303,8 +301,8 @@ func (r *codeModifierWithoutCloseNotify) Write(buf []byte) (int, error) { return r.responseWriter.Write(buf) } -// WriteHeader sends the headers, with the enforced code (the code in argument -// is always ignored), if it hasn't already been done. +// WriteHeader sends the headers, with the enforced code (the code in argument is always ignored), +// if it hasn't already been done. func (r *codeModifierWithoutCloseNotify) WriteHeader(_ int) { if r.headerSent { return @@ -332,3 +330,13 @@ func (r *codeModifierWithoutCloseNotify) Flush() { flusher.Flush() } } + +type codeModifierWithCloseNotify struct { + *codeModifierWithoutCloseNotify +} + +// CloseNotify returns a channel that receives at most a single value (true) +// when the client connection has gone away. +func (r *codeModifierWithCloseNotify) CloseNotify() <-chan bool { + return r.responseWriter.(http.CloseNotifier).CloseNotify() +} From 68ed875966ee8b57f636db1368fb6f620a86ce43 Mon Sep 17 00:00:00 2001 From: Philipp Trulson Date: Wed, 14 Jun 2023 17:00:06 +0200 Subject: [PATCH 04/13] Update DataDog tracing dependency to v1.50.1 --- go.mod | 22 +++++++++++++--------- go.sum | 56 ++++++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 53 insertions(+), 25 deletions(-) diff --git a/go.mod b/go.mod index 1b0b9e117..d4e045bb3 100644 --- a/go.mod +++ b/go.mod @@ -57,7 +57,7 @@ require ( github.com/quic-go/quic-go v0.33.0 github.com/rancher/go-rancher-metadata v0.0.0-20200311180630-7f4c936a06ac github.com/sirupsen/logrus v1.9.0 - github.com/stretchr/testify v1.8.1 + github.com/stretchr/testify v1.8.2 github.com/stvp/go-udp-testing v0.0.0-20191102171040-06b61409b154 github.com/traefik/paerser v0.2.0 github.com/traefik/yaegi v0.15.1 @@ -76,7 +76,7 @@ require ( golang.org/x/time v0.3.0 golang.org/x/tools v0.6.0 google.golang.org/grpc v1.53.0 - gopkg.in/DataDog/dd-trace-go.v1 v1.43.1 + gopkg.in/DataDog/dd-trace-go.v1 v1.51.0 gopkg.in/fsnotify.v1 v1.4.7 gopkg.in/yaml.v3 v3.0.1 k8s.io/api v0.26.3 @@ -104,9 +104,13 @@ require ( github.com/Azure/go-autorest/autorest/validation v0.3.1 // indirect github.com/Azure/go-autorest/logger v0.2.1 // indirect github.com/Azure/go-autorest/tracing v0.6.0 // indirect - github.com/DataDog/datadog-agent/pkg/obfuscate v0.0.0-20211129110424-6491aa3bf583 // indirect + github.com/DataDog/appsec-internal-go v1.0.0 // indirect + github.com/DataDog/datadog-agent/pkg/obfuscate v0.45.0-rc.1 // indirect + github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.45.0-rc.1 // indirect github.com/DataDog/datadog-go v4.8.2+incompatible // indirect - github.com/DataDog/datadog-go/v5 v5.0.2 // indirect + github.com/DataDog/datadog-go/v5 v5.1.1 // indirect + github.com/DataDog/go-libddwaf v1.2.0 // indirect + github.com/DataDog/go-tuf v0.3.0--fix-localmeta-fork // indirect github.com/DataDog/sketches-go v1.2.1 // indirect github.com/HdrHistogram/hdrhistogram-go v1.1.2 // indirect github.com/Masterminds/goutils v1.1.1 // indirect @@ -140,7 +144,6 @@ require ( github.com/coreos/go-systemd/v22 v22.3.2 // indirect github.com/cpu/goacmedns v0.1.1 // indirect github.com/deepmap/oapi-codegen v1.9.1 // indirect - github.com/dgraph-io/ristretto v0.1.0 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/dimchansky/utfbom v1.1.1 // indirect github.com/distribution/distribution/v3 v3.0.0-20210316161203-a01c71e2477e // indirect @@ -178,7 +181,6 @@ require ( github.com/gogo/googleapis v1.4.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt/v4 v4.2.0 // indirect - github.com/golang/glog v1.0.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/mock v1.6.0 // indirect github.com/google/btree v1.0.1 // indirect @@ -274,6 +276,7 @@ require ( github.com/opencontainers/runc v1.1.4 // indirect github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492 // indirect github.com/oracle/oci-go-sdk v24.3.0+incompatible // indirect + github.com/outcaste-io/ristretto v0.2.1 // indirect github.com/ovh/go-ovh v1.1.0 // indirect github.com/philhofer/fwd v1.1.1 // indirect github.com/pkg/errors v0.9.1 // indirect @@ -291,6 +294,7 @@ require ( github.com/santhosh-tekuri/jsonschema v1.2.4 // indirect github.com/scaleway/scaleway-sdk-go v1.0.0-beta.9 // indirect github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect + github.com/secure-systems-lab/go-securesystemslib v0.5.0 // indirect github.com/segmentio/fasthash v1.0.3 // indirect github.com/shopspring/decimal v1.2.0 // indirect github.com/simplesurance/bunny-go v0.0.0-20221115111006-e11d9dc91f04 // indirect @@ -304,7 +308,7 @@ require ( github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.490 // indirect github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.490 // indirect github.com/theupdateframework/notary v0.6.1 // indirect - github.com/tinylib/msgp v1.1.2 // indirect + github.com/tinylib/msgp v1.1.6 // indirect github.com/tonistiigi/fsutil v0.0.0-20201103201449-0834f99b7b85 // indirect github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea // indirect github.com/transip/gotransip/v6 v6.17.0 // indirect @@ -323,7 +327,7 @@ require ( go.etcd.io/etcd/client/pkg/v3 v3.5.5 // indirect go.etcd.io/etcd/client/v3 v3.5.5 // indirect go.opencensus.io v0.24.0 // indirect - go.uber.org/atomic v1.7.0 // indirect + go.uber.org/atomic v1.10.0 // indirect go.uber.org/multierr v1.6.0 // indirect go.uber.org/ratelimit v0.2.0 // indirect go.uber.org/zap v1.19.0 // indirect @@ -346,7 +350,7 @@ require ( gopkg.in/ns1/ns1-go.v2 v2.6.5 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect howett.net/plist v0.0.0-20181124034731-591f970eefbb // indirect - inet.af/netaddr v0.0.0-20220617031823-097006376321 // indirect + inet.af/netaddr v0.0.0-20220811202034-502d2d690317 // indirect k8s.io/klog/v2 v2.80.1 // indirect k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 // indirect sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect diff --git a/go.sum b/go.sum index f24f2569e..1de390a94 100644 --- a/go.sum +++ b/go.sum @@ -112,14 +112,23 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak= github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/DataDog/datadog-agent/pkg/obfuscate v0.0.0-20211129110424-6491aa3bf583 h1:3nVO1nQyh64IUY6BPZUpMYMZ738Pu+LsMt3E0eqqIYw= -github.com/DataDog/datadog-agent/pkg/obfuscate v0.0.0-20211129110424-6491aa3bf583/go.mod h1:EP9f4GqaDJyP1F5jTNMtzdIpw3JpNs3rMSJOnYywCiw= +github.com/DataDog/appsec-internal-go v1.0.0 h1:2u5IkF4DBj3KVeQn5Vg2vjPUtt513zxEYglcqnd500U= +github.com/DataDog/appsec-internal-go v1.0.0/go.mod h1:+Y+4klVWKPOnZx6XESG7QHydOaUGEXyH2j/vSg9JiNM= +github.com/DataDog/datadog-agent/pkg/obfuscate v0.45.0-rc.1 h1:XyYvstMFpSyZtfJHWJm1Sf1meNyCdfhKJrjB6+rUNOk= +github.com/DataDog/datadog-agent/pkg/obfuscate v0.45.0-rc.1/go.mod h1:e933RWa4kAWuHi5jpzEuOiULlv21HcCFEVIYegmaB5c= +github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.45.0-rc.1 h1:0OK84DbAucLUwoDYoBFve1cuhDWtoquruVVDjgucYlI= +github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.45.0-rc.1/go.mod h1:VVMDDibJxYEkwcLdZBT2g8EHKpbMT4JdOhRbQ9GdjbM= github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/datadog-go v4.8.2+incompatible h1:qbcKSx29aBLD+5QLvlQZlGmRMF/FfGqFLFev/1TDzRo= github.com/DataDog/datadog-go v4.8.2+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= -github.com/DataDog/datadog-go/v5 v5.0.2 h1:UFtEe7662/Qojxkw1d6SboAeA0CPI3naKhVASwFn+04= -github.com/DataDog/datadog-go/v5 v5.0.2/go.mod h1:ZI9JFB4ewXbw1sBnF4sxsR2k1H3xjV+PUAOUsHvKpcU= +github.com/DataDog/datadog-go/v5 v5.1.1 h1:JLZ6s2K1pG2h9GkvEvMdEGqMDyVLEAccdX5TltWcLMU= +github.com/DataDog/datadog-go/v5 v5.1.1/go.mod h1:KhiYb2Badlv9/rofz+OznKoEF5XKTonWyhx5K83AP8E= +github.com/DataDog/go-libddwaf v1.2.0 h1:fKHP5U29E597eV2hU501fcW40bL8zcQ081jEGuRw2kM= +github.com/DataDog/go-libddwaf v1.2.0/go.mod h1:DI5y8obPajk+Tvy2o+nZc2g/5Ria/Rfq5/624k7pHpE= +github.com/DataDog/go-tuf v0.3.0--fix-localmeta-fork h1:yBq5PrAtrM4yVeSzQ+bn050+Ysp++RKF1QmtkL4VqvU= +github.com/DataDog/go-tuf v0.3.0--fix-localmeta-fork/go.mod h1:yA5JwkZsHTLuqq3zaRgUQf35DfDkpOZqgtBqHKpwrBs= +github.com/DataDog/gostackparse v0.5.0 h1:jb72P6GFHPHz2W0onsN51cS3FkaMDcjb0QzgxxA4gDk= github.com/DataDog/sketches-go v1.2.1 h1:qTBzWLnZ3kM2kw39ymh6rMcnN+5VULwFs++lEYUUsro= github.com/DataDog/sketches-go v1.2.1/go.mod h1:1xYmPLY1So10AwxV6MJV0J53XVH+WL9Ad1KetxVivVI= github.com/DataDog/zstd v1.3.6-0.20190409195224-796139022798 h1:2T/jmrHeTezcCM58lvEQXs0UpQJCo5SoGAcg+mbSTIg= @@ -325,6 +334,7 @@ github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:z github.com/codahale/hdrhistogram v0.0.0-20160425231609-f8ad88b59a58/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd h1:qMd81Ts1T2OTKmB4acZcyKaMtRnY5Y44NuXGX2GFJ1w= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= +github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb/go.mod h1:ZjrT6AXHbDs86ZSdt/osfBi5qfexBrKUdONk989Wnk4= github.com/compose-spec/compose-go v1.0.2/go.mod h1:gCIA3No0j5nNszz2X0yd/mkigTIWcOgHiPa9guWvoec= github.com/compose-spec/compose-go v1.0.3 h1:yvut1x9H4TUMptNA4mZ63VGVtDNX1OKy2TZCi6yFw8Q= github.com/compose-spec/compose-go v1.0.3/go.mod h1:gCIA3No0j5nNszz2X0yd/mkigTIWcOgHiPa9guWvoec= @@ -497,8 +507,6 @@ github.com/denisenkom/go-mssqldb v0.0.0-20190315220205-a8ed825ac853/go.mod h1:xN github.com/denisenkom/go-mssqldb v0.0.0-20190515213511-eb9f6a1743f3/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM= github.com/denverdino/aliyungo v0.0.0-20170926055100-d3308649c661/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0= github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0= -github.com/dgraph-io/ristretto v0.1.0 h1:Jv3CGQHp9OjuMBSne1485aDpUkTKEcUqF+jm/LuerPI= -github.com/dgraph-io/ristretto v0.1.0/go.mod h1:fux0lOrBhrVCJd3lcTHsIJhq1T2rokOu6v9Vcb3Q9ug= github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= @@ -630,6 +638,7 @@ github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYF github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/flynn/go-docopt v0.0.0-20140912013429-f6dd2ebbb31e/go.mod h1:HyVoz1Mz5Co8TFO8EupIdlcpwShBmY98dkT2xeHkvEI= github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= @@ -771,8 +780,6 @@ github.com/golang-jwt/jwt/v4 v4.2.0 h1:besgBTC8w8HjP6NzQdxwKH9Z5oQMZ24ThTrHp3cZ8 github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= -github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -813,6 +820,7 @@ github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y= github.com/gomodule/redigo v1.8.2/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0= github.com/google/btree v0.0.0-20180124185431-e89373fe6b4a/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -1482,6 +1490,8 @@ github.com/openzipkin/zipkin-go v0.2.2 h1:nY8Hti+WKaP0cRsSeQ026wU03QsM762XBeCXBb github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/oracle/oci-go-sdk v24.3.0+incompatible h1:x4mcfb4agelf1O4/1/auGlZ1lr97jXRSSN5MxTgG/zU= github.com/oracle/oci-go-sdk v24.3.0+incompatible/go.mod h1:VQb79nF8Z2cwLkLS35ukwStZIg5F66tcBccjip/j888= +github.com/outcaste-io/ristretto v0.2.1 h1:KCItuNIGJZcursqHr3ghO7fc5ddZLEHspL9UR0cQM64= +github.com/outcaste-io/ristretto v0.2.1/go.mod h1:W8HywhmtlopSB1jeMg3JtdIhf+DYkLAr0VN/s4+MHac= github.com/ovh/go-ovh v1.1.0 h1:bHXZmw8nTgZin4Nv7JuaLs0KG5x54EQR7migYTd1zrk= github.com/ovh/go-ovh v1.1.0/go.mod h1:AxitLZ5HBRPyUd+Zl60Ajaag+rNTdVXWIkzfrVuTXWA= github.com/packethost/packngo v0.1.1-0.20180711074735-b9cb5096f54c/go.mod h1:otzZQXgoO96RTzDB/Hycg0qZcXZsWJGJRSXbmEIJ+4M= @@ -1599,6 +1609,7 @@ github.com/rboyer/safeio v0.2.1/go.mod h1:Cq/cEPK+YXFn622lsQ0K4KsPZSPtaptHHEldsy github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a h1:9ZKAASQSHhDYGoxY8uLVpewe1GDZ2vu2Tr/vTdVAkFQ= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/renier/xmlrpc v0.0.0-20170708154548-ce4a1a486c03/go.mod h1:gRAiPF5C5Nd0eyyRdqIu9qTiFSoZzpTq727b5B8fkkU= +github.com/richardartoul/molecule v1.0.1-0.20221107223329-32cfee06a052 h1:Qp27Idfgi6ACvFQat5+VJvlYToylpM/hcyLBI3WaKPA= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc= @@ -1637,6 +1648,9 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUt github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= +github.com/secure-systems-lab/go-securesystemslib v0.3.1/go.mod h1:o8hhjkbNl2gOamKUA/eNW3xUrntHT9L4W89W1nfj43U= +github.com/secure-systems-lab/go-securesystemslib v0.5.0 h1:oTiNu0QnulMQgN/hLK124wJD/r2f9ZhIUuKIeBsCBT8= +github.com/secure-systems-lab/go-securesystemslib v0.5.0/go.mod h1:uoCqUC0Ap7jrBSEanxT+SdACYJTVplRXWLkGMuDjXqk= github.com/segmentio/fasthash v1.0.3 h1:EI9+KE1EwvMLBWwjpRDc+fEM+prwxDYbslddQGtrmhM= github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= @@ -1675,6 +1689,7 @@ github.com/softlayer/xmlrpc v0.0.0-20200409220501-5f089df7cb7e/go.mod h1:fKZCUVd github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.1/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= @@ -1732,8 +1747,9 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stvp/go-udp-testing v0.0.0-20191102171040-06b61409b154 h1:XGopsea1Dw7ecQ8JscCNQXDGYAKDiWjDeXnpN/+BY9g= github.com/stvp/go-udp-testing v0.0.0-20191102171040-06b61409b154/go.mod h1:7jxmlfBCDBXRzr0eAQJ48XC1hBu1np4CS5+cHEYfwpc= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= @@ -1741,6 +1757,7 @@ github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69 github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.490 h1:mmz27tVi2r70JYnm5y0Zk8w0Qzsx+vfUw3oqSyrEfP8= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.490/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y= @@ -1749,8 +1766,8 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.490/go.mod github.com/tent/http-link-go v0.0.0-20130702225549-ac974c61c2f9/go.mod h1:RHkNRtSLfOK7qBTHaeSX1D6BNpI3qw7NTxsmNr4RvN8= github.com/theupdateframework/notary v0.6.1 h1:7wshjstgS9x9F5LuB1L5mBI2xNMObWqjz+cjWoom6l0= github.com/theupdateframework/notary v0.6.1/go.mod h1:MOfgIfmox8s7/7fduvB2xyPPMJCrjRLRizA8OFwpnKY= -github.com/tinylib/msgp v1.1.2 h1:gWmO7n0Ys2RBEb7GPYB9Ujq8Mk5p2U08lRnmMcGy6BQ= -github.com/tinylib/msgp v1.1.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= +github.com/tinylib/msgp v1.1.6 h1:i+SbKraHhnrf9M5MYmvQhFnbLhAXSDWF8WWsuyRdocw= +github.com/tinylib/msgp v1.1.6/go.mod h1:75BAfg2hauQhs3qedfdDZmWAPcFMAvJE5b9rGOMufyw= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tonistiigi/fsutil v0.0.0-20201103201449-0834f99b7b85 h1:014iQD8i8EabPWK2XgUuOTxg5s2nhfDmq6GupskfUO8= @@ -1892,8 +1909,10 @@ go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqe go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= -go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= +go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= @@ -1955,6 +1974,7 @@ golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5 golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20211202192323-5770296d904e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= @@ -2050,6 +2070,7 @@ golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= @@ -2184,6 +2205,7 @@ golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200817155316-9781c653f443/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -2234,6 +2256,7 @@ golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220224120231-95c6836cb0e7/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220627191245-f75cf1eec38b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -2334,6 +2357,7 @@ golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= golang.org/x/tools v0.0.0-20200918232735-d647fc253266/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= +golang.org/x/tools v0.0.0-20201022035929-9cf592e881e9/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= @@ -2499,8 +2523,8 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -gopkg.in/DataDog/dd-trace-go.v1 v1.43.1 h1:Dez4VzRQWAI5YXJRBx58BiC0gONGuW/oY4l8fWKzOXY= -gopkg.in/DataDog/dd-trace-go.v1 v1.43.1/go.mod h1:YL9g+nlUY7ByCffD5pDytAqy99GNbytRV0EBpKuldM4= +gopkg.in/DataDog/dd-trace-go.v1 v1.51.0 h1:nFsTjolqdh8slG6F1B7AGdFHX7/kp26Jkb8UvGSIIFY= +gopkg.in/DataDog/dd-trace-go.v1 v1.51.0/go.mod h1:+m1wWLyQfqd6fX0uy6YFbP1soWgmjQ+5TveksDt/fHc= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -2582,8 +2606,8 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= howett.net/plist v0.0.0-20181124034731-591f970eefbb h1:jhnBjNi9UFpfpl8YZhA9CrOqpnJdvzuiHsl/dnxl11M= howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0= -inet.af/netaddr v0.0.0-20220617031823-097006376321 h1:B4dC8ySKTQXasnjDTMsoCMf1sQG4WsMej0WXaHxunmU= -inet.af/netaddr v0.0.0-20220617031823-097006376321/go.mod h1:OIezDfdzOgFhuw4HuWapWq2e9l0H9tK4F1j+ETRtF3k= +inet.af/netaddr v0.0.0-20220811202034-502d2d690317 h1:U2fwK6P2EqmopP/hFLTOAjWTki0qgd4GMJn5X8wOleU= +inet.af/netaddr v0.0.0-20220811202034-502d2d690317/go.mod h1:OIezDfdzOgFhuw4HuWapWq2e9l0H9tK4F1j+ETRtF3k= k8s.io/api v0.0.0-20180904230853-4e7be11eab3f/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA= k8s.io/api v0.0.0-20191016110408-35e52d86657a/go.mod h1:/L5qH+AD540e7Cetbui1tuJeXdmNhO8jM6VkXeDdDhQ= k8s.io/api v0.16.9/go.mod h1:Y7dZNHs1Xy0mSwSlzL9QShi6qkljnN41yR8oWCRTDe8= From 6885e410f0f4ff4c39a2f4340f27ff24e6cb9cd0 Mon Sep 17 00:00:00 2001 From: Romain Date: Wed, 14 Jun 2023 17:42:44 +0200 Subject: [PATCH 05/13] Support informational headers in middlewares redefining the response writer. Co-authored-by: LandryBe --- go.mod | 2 +- go.sum | 4 +- pkg/middlewares/compress/compress_test.go | 82 +++++++++++++++++ pkg/middlewares/customerrors/custom_errors.go | 40 ++++++++- .../customerrors/custom_errors_test.go | 85 ++++++++++++++++++ pkg/middlewares/headers/headers_test.go | 87 +++++++++++++++++++ pkg/middlewares/headers/responsewriter.go | 9 ++ pkg/middlewares/pipelining/pipelining_test.go | 80 +++++++++++++++++ pkg/middlewares/retry/retry.go | 9 +- pkg/middlewares/retry/retry_test.go | 80 +++++++++++++++++ 10 files changed, 471 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index d4e045bb3..27de095eb 100644 --- a/go.mod +++ b/go.mod @@ -35,7 +35,7 @@ require ( github.com/influxdata/influxdb-client-go/v2 v2.7.0 github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d github.com/instana/go-sensor v1.38.3 - github.com/klauspost/compress v1.15.0 + github.com/klauspost/compress v1.16.6 github.com/kvtools/consul v1.0.2 github.com/kvtools/etcdv3 v1.0.2 github.com/kvtools/redis v1.0.2 diff --git a/go.sum b/go.sum index 1de390a94..c444150a2 100644 --- a/go.sum +++ b/go.sum @@ -1158,8 +1158,8 @@ github.com/kisielk/sqlstruct v0.0.0-20150923205031-648daed35d49/go.mod h1:yyMNCy github.com/kisom/goutils v1.1.0/go.mod h1:+UBTfd78habUYWFbNWTJNG+jNG/i/lGURakr4A/yNRw= github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.15.0 h1:xqfchp4whNFxn5A4XFyyYtitiWI8Hy5EW59jEwcyL6U= -github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/compress v1.16.6 h1:91SKEy4K37vkp255cJ8QesJhjyRO0hn9i9G0GoUwLsk= +github.com/klauspost/compress v1.16.6/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/kolo/xmlrpc v0.0.0-20200310150728-e0350524596b h1:DzHy0GlWeF0KAglaTMY7Q+khIFoG8toHP+wLFBVBQJc= github.com/kolo/xmlrpc v0.0.0-20200310150728-e0350524596b/go.mod h1:o03bZfuBwAXHetKXuInt4S7omeXUu62/A845kiycsSQ= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= diff --git a/pkg/middlewares/compress/compress_test.go b/pkg/middlewares/compress/compress_test.go index 8f7e85ae0..4a1fd2196 100644 --- a/pkg/middlewares/compress/compress_test.go +++ b/pkg/middlewares/compress/compress_test.go @@ -5,6 +5,8 @@ import ( "io" "net/http" "net/http/httptest" + "net/http/httptrace" + "net/textproto" "testing" "github.com/klauspost/compress/gzhttp" @@ -356,6 +358,86 @@ func TestMinResponseBodyBytes(t *testing.T) { } } +// This test is an adapted version of net/http/httputil.Test1xxResponses test. +func Test1xxResponses(t *testing.T) { + fakeBody := generateBytes(100000) + + next := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + h := w.Header() + h.Add("Link", "; rel=preload; as=style") + h.Add("Link", "; rel=preload; as=script") + w.WriteHeader(http.StatusEarlyHints) + + h.Add("Link", "; rel=preload; as=script") + w.WriteHeader(http.StatusProcessing) + + if _, err := w.Write(fakeBody); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + } + }) + + compress, err := New(context.Background(), next, dynamic.Compress{MinResponseBodyBytes: 1024}, "testing") + require.NoError(t, err) + + server := httptest.NewServer(compress) + t.Cleanup(server.Close) + frontendClient := server.Client() + + checkLinkHeaders := func(t *testing.T, expected, got []string) { + t.Helper() + + if len(expected) != len(got) { + t.Errorf("Expected %d link headers; got %d", len(expected), len(got)) + } + + for i := range expected { + if i >= len(got) { + t.Errorf("Expected %q link header; got nothing", expected[i]) + + continue + } + + if expected[i] != got[i] { + t.Errorf("Expected %q link header; got %q", expected[i], got[i]) + } + } + } + + var respCounter uint8 + trace := &httptrace.ClientTrace{ + Got1xxResponse: func(code int, header textproto.MIMEHeader) error { + switch code { + case http.StatusEarlyHints: + checkLinkHeaders(t, []string{"; rel=preload; as=style", "; rel=preload; as=script"}, header["Link"]) + case http.StatusProcessing: + checkLinkHeaders(t, []string{"; rel=preload; as=style", "; rel=preload; as=script", "; rel=preload; as=script"}, header["Link"]) + default: + t.Error("Unexpected 1xx response") + } + + respCounter++ + + return nil + }, + } + req, _ := http.NewRequestWithContext(httptrace.WithClientTrace(context.Background(), trace), http.MethodGet, server.URL, nil) + req.Header.Add(acceptEncodingHeader, gzipValue) + + res, err := frontendClient.Do(req) + assert.Nil(t, err) + + defer res.Body.Close() + + if respCounter != 2 { + t.Errorf("Expected 2 1xx responses; got %d", respCounter) + } + checkLinkHeaders(t, []string{"; rel=preload; as=style", "; rel=preload; as=script", "; rel=preload; as=script"}, res.Header["Link"]) + + assert.Equal(t, gzipValue, res.Header.Get(contentEncodingHeader)) + body, _ := io.ReadAll(res.Body) + assert.NotEqualValues(t, body, fakeBody) +} + func BenchmarkCompress(b *testing.B) { testCases := []struct { name string diff --git a/pkg/middlewares/customerrors/custom_errors.go b/pkg/middlewares/customerrors/custom_errors.go index c764b2cf8..39d411622 100644 --- a/pkg/middlewares/customerrors/custom_errors.go +++ b/pkg/middlewares/customerrors/custom_errors.go @@ -193,11 +193,25 @@ func (cc *codeCatcher) Write(buf []byte) (int, error) { return cc.responseWriter.Write(buf) } +// WriteHeader is, in the specific case of 1xx status codes, a direct call to the wrapped ResponseWriter, without marking headers as sent, +// allowing so further calls. func (cc *codeCatcher) WriteHeader(code int) { if cc.headersSent || cc.caughtFilteredCode { return } + // Handling informational headers. + if code >= 100 && code <= 199 { + // Multiple informational status codes can be used, + // so here the copy is not appending the values to not repeat them. + for k, v := range cc.Header() { + cc.responseWriter.Header()[k] = v + } + + cc.responseWriter.WriteHeader(code) + return + } + cc.code = code for _, block := range cc.httpCodeRanges { if cc.code >= block[0] && cc.code <= block[1] { @@ -208,7 +222,11 @@ func (cc *codeCatcher) WriteHeader(code int) { } } - utils.CopyHeaders(cc.responseWriter.Header(), cc.Header()) + // The copy is not appending the values, + // to not repeat them in case any informational status code has been written. + for k, v := range cc.Header() { + cc.responseWriter.Header()[k] = v + } cc.responseWriter.WriteHeader(cc.code) cc.headersSent = true } @@ -303,12 +321,28 @@ func (r *codeModifierWithoutCloseNotify) Write(buf []byte) (int, error) { // WriteHeader sends the headers, with the enforced code (the code in argument is always ignored), // if it hasn't already been done. -func (r *codeModifierWithoutCloseNotify) WriteHeader(_ int) { +// WriteHeader is, in the specific case of 1xx status codes, a direct call to the wrapped ResponseWriter, without marking headers as sent, +// allowing so further calls. +func (r *codeModifierWithoutCloseNotify) WriteHeader(code int) { if r.headerSent { return } - utils.CopyHeaders(r.responseWriter.Header(), r.Header()) + // Handling informational headers. + if code >= 100 && code <= 199 { + // Multiple informational status codes can be used, + // so here the copy is not appending the values to not repeat them. + for k, v := range r.headerMap { + r.responseWriter.Header()[k] = v + } + + r.responseWriter.WriteHeader(code) + return + } + + for k, v := range r.headerMap { + r.responseWriter.Header()[k] = v + } r.responseWriter.WriteHeader(r.code) r.headerSent = true } diff --git a/pkg/middlewares/customerrors/custom_errors_test.go b/pkg/middlewares/customerrors/custom_errors_test.go index c291b15d5..84e3579b7 100644 --- a/pkg/middlewares/customerrors/custom_errors_test.go +++ b/pkg/middlewares/customerrors/custom_errors_test.go @@ -3,8 +3,11 @@ package customerrors import ( "context" "fmt" + "io" "net/http" "net/http/httptest" + "net/http/httptrace" + "net/textproto" "testing" "github.com/stretchr/testify/assert" @@ -181,6 +184,88 @@ func TestHandler(t *testing.T) { } } +// This test is an adapted version of net/http/httputil.Test1xxResponses test. +func Test1xxResponses(t *testing.T) { + next := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + h := w.Header() + h.Add("Link", "; rel=preload; as=style") + h.Add("Link", "; rel=preload; as=script") + w.WriteHeader(http.StatusEarlyHints) + + h.Add("Link", "; rel=preload; as=script") + w.WriteHeader(http.StatusProcessing) + + h.Add("User-Agent", "foobar") + _, _ = w.Write([]byte("Hello")) + w.WriteHeader(http.StatusBadGateway) + }) + + serviceBuilderMock := &mockServiceBuilder{handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + _, _ = fmt.Fprintln(w, "My error page.") + })} + + config := dynamic.ErrorPage{Service: "error", Query: "/", Status: []string{"200"}} + + errorPageHandler, err := New(context.Background(), next, config, serviceBuilderMock, "test") + require.NoError(t, err) + + server := httptest.NewServer(errorPageHandler) + t.Cleanup(server.Close) + frontendClient := server.Client() + + checkLinkHeaders := func(t *testing.T, expected, got []string) { + t.Helper() + + if len(expected) != len(got) { + t.Errorf("Expected %d link headers; got %d", len(expected), len(got)) + } + + for i := range expected { + if i >= len(got) { + t.Errorf("Expected %q link header; got nothing", expected[i]) + + continue + } + + if expected[i] != got[i] { + t.Errorf("Expected %q link header; got %q", expected[i], got[i]) + } + } + } + + var respCounter uint8 + trace := &httptrace.ClientTrace{ + Got1xxResponse: func(code int, header textproto.MIMEHeader) error { + switch code { + case http.StatusEarlyHints: + checkLinkHeaders(t, []string{"; rel=preload; as=style", "; rel=preload; as=script"}, header["Link"]) + case http.StatusProcessing: + checkLinkHeaders(t, []string{"; rel=preload; as=style", "; rel=preload; as=script", "; rel=preload; as=script"}, header["Link"]) + default: + t.Error("Unexpected 1xx response") + } + + respCounter++ + + return nil + }, + } + req, _ := http.NewRequestWithContext(httptrace.WithClientTrace(context.Background(), trace), http.MethodGet, server.URL, nil) + + res, err := frontendClient.Do(req) + assert.Nil(t, err) + + defer res.Body.Close() + + if respCounter != 2 { + t.Errorf("Expected 2 1xx responses; got %d", respCounter) + } + checkLinkHeaders(t, []string{"; rel=preload; as=style", "; rel=preload; as=script", "; rel=preload; as=script"}, res.Header["Link"]) + + body, _ := io.ReadAll(res.Body) + assert.Equal(t, "My error page.\n", string(body)) +} + type mockServiceBuilder struct { handler http.Handler } diff --git a/pkg/middlewares/headers/headers_test.go b/pkg/middlewares/headers/headers_test.go index efbcdb0b2..c345efd60 100644 --- a/pkg/middlewares/headers/headers_test.go +++ b/pkg/middlewares/headers/headers_test.go @@ -4,8 +4,11 @@ package headers import ( "context" + "io" "net/http" "net/http/httptest" + "net/http/httptrace" + "net/textproto" "testing" "github.com/stretchr/testify/assert" @@ -111,3 +114,87 @@ func Test_headers_getTracingInformation(t *testing.T) { assert.Equal(t, "testing", name) assert.Equal(t, tracing.SpanKindNoneEnum, trace) } + +// This test is an adapted version of net/http/httputil.Test1xxResponses test. +func Test1xxResponses(t *testing.T) { + next := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + h := w.Header() + h.Add("Link", "; rel=preload; as=style") + h.Add("Link", "; rel=preload; as=script") + w.WriteHeader(http.StatusEarlyHints) + + h.Add("Link", "; rel=preload; as=script") + w.WriteHeader(http.StatusProcessing) + + _, _ = w.Write([]byte("Hello")) + }) + + cfg := dynamic.Headers{ + CustomResponseHeaders: map[string]string{ + "X-Custom-Response-Header": "test_response", + }, + } + + mid, err := New(context.Background(), next, cfg, "testing") + require.NoError(t, err) + + server := httptest.NewServer(mid) + t.Cleanup(server.Close) + frontendClient := server.Client() + + checkLinkHeaders := func(t *testing.T, expected, got []string) { + t.Helper() + + if len(expected) != len(got) { + t.Errorf("Expected %d link headers; got %d", len(expected), len(got)) + } + + for i := range expected { + if i >= len(got) { + t.Errorf("Expected %q link header; got nothing", expected[i]) + + continue + } + + if expected[i] != got[i] { + t.Errorf("Expected %q link header; got %q", expected[i], got[i]) + } + } + } + + var respCounter uint8 + trace := &httptrace.ClientTrace{ + Got1xxResponse: func(code int, header textproto.MIMEHeader) error { + switch code { + case http.StatusEarlyHints: + checkLinkHeaders(t, []string{"; rel=preload; as=style", "; rel=preload; as=script"}, header["Link"]) + case http.StatusProcessing: + checkLinkHeaders(t, []string{"; rel=preload; as=style", "; rel=preload; as=script", "; rel=preload; as=script"}, header["Link"]) + default: + t.Error("Unexpected 1xx response") + } + + respCounter++ + + return nil + }, + } + req, _ := http.NewRequestWithContext(httptrace.WithClientTrace(context.Background(), trace), http.MethodGet, server.URL, nil) + + res, err := frontendClient.Do(req) + assert.Nil(t, err) + + defer res.Body.Close() + + if respCounter != 2 { + t.Errorf("Expected 2 1xx responses; got %d", respCounter) + } + checkLinkHeaders(t, []string{"; rel=preload; as=style", "; rel=preload; as=script", "; rel=preload; as=script"}, res.Header["Link"]) + + body, _ := io.ReadAll(res.Body) + if string(body) != "Hello" { + t.Errorf("Read body %q; want Hello", body) + } + + assert.Equal(t, "test_response", res.Header.Get("X-Custom-Response-Header")) +} diff --git a/pkg/middlewares/headers/responsewriter.go b/pkg/middlewares/headers/responsewriter.go index 15201b1fd..c36674a05 100644 --- a/pkg/middlewares/headers/responsewriter.go +++ b/pkg/middlewares/headers/responsewriter.go @@ -36,10 +36,19 @@ func newResponseModifier(w http.ResponseWriter, r *http.Request, modifier func(* return rm } +// WriteHeader is, in the specific case of 1xx status codes, a direct call to the wrapped ResponseWriter, without marking headers as sent, +// allowing so further calls. func (r *responseModifier) WriteHeader(code int) { if r.headersSent { return } + + // Handling informational headers. + if code >= 100 && code <= 199 { + r.rw.WriteHeader(code) + return + } + defer func() { r.code = code r.headersSent = true diff --git a/pkg/middlewares/pipelining/pipelining_test.go b/pkg/middlewares/pipelining/pipelining_test.go index b26e5fc6b..181fcb328 100644 --- a/pkg/middlewares/pipelining/pipelining_test.go +++ b/pkg/middlewares/pipelining/pipelining_test.go @@ -2,8 +2,11 @@ package pipelining import ( "context" + "io" "net/http" "net/http/httptest" + "net/http/httptrace" + "net/textproto" "testing" "github.com/stretchr/testify/assert" @@ -68,3 +71,80 @@ func TestNew(t *testing.T) { }) } } + +// This test is an adapted version of net/http/httputil.Test1xxResponses test. +// This test is only here to guarantee that there would not be any regression in the future, +// because the pipelining middleware is already supporting informational headers. +func Test1xxResponses(t *testing.T) { + next := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + h := w.Header() + h.Add("Link", "; rel=preload; as=style") + h.Add("Link", "; rel=preload; as=script") + w.WriteHeader(http.StatusEarlyHints) + + h.Add("Link", "; rel=preload; as=script") + w.WriteHeader(http.StatusProcessing) + + _, _ = w.Write([]byte("Hello")) + }) + + pipe := New(context.Background(), next, "pipe") + + server := httptest.NewServer(pipe) + t.Cleanup(server.Close) + frontendClient := server.Client() + + checkLinkHeaders := func(t *testing.T, expected, got []string) { + t.Helper() + + if len(expected) != len(got) { + t.Errorf("Expected %d link headers; got %d", len(expected), len(got)) + } + + for i := range expected { + if i >= len(got) { + t.Errorf("Expected %q link header; got nothing", expected[i]) + + continue + } + + if expected[i] != got[i] { + t.Errorf("Expected %q link header; got %q", expected[i], got[i]) + } + } + } + + var respCounter uint8 + trace := &httptrace.ClientTrace{ + Got1xxResponse: func(code int, header textproto.MIMEHeader) error { + switch code { + case http.StatusEarlyHints: + checkLinkHeaders(t, []string{"; rel=preload; as=style", "; rel=preload; as=script"}, header["Link"]) + case http.StatusProcessing: + checkLinkHeaders(t, []string{"; rel=preload; as=style", "; rel=preload; as=script", "; rel=preload; as=script"}, header["Link"]) + default: + t.Error("Unexpected 1xx response") + } + + respCounter++ + + return nil + }, + } + req, _ := http.NewRequestWithContext(httptrace.WithClientTrace(context.Background(), trace), http.MethodGet, server.URL, nil) + + res, err := frontendClient.Do(req) + assert.Nil(t, err) + + defer res.Body.Close() + + if respCounter != 2 { + t.Errorf("Expected 2 1xx responses; got %d", respCounter) + } + checkLinkHeaders(t, []string{"; rel=preload; as=style", "; rel=preload; as=script", "; rel=preload; as=script"}, res.Header["Link"]) + + body, _ := io.ReadAll(res.Body) + if string(body) != "Hello" { + t.Errorf("Read body %q; want Hello", body) + } +} diff --git a/pkg/middlewares/retry/retry.go b/pkg/middlewares/retry/retry.go index 37dd4abef..75367ebc7 100644 --- a/pkg/middlewares/retry/retry.go +++ b/pkg/middlewares/retry/retry.go @@ -209,7 +209,7 @@ func (r *responseWriterWithoutCloseNotify) WriteHeader(code int) { r.DisableRetries() } - if r.ShouldRetry() { + if r.ShouldRetry() || r.written { return } @@ -223,6 +223,13 @@ func (r *responseWriterWithoutCloseNotify) WriteHeader(code int) { } r.responseWriter.WriteHeader(code) + + // Handling informational headers. + // This allows to keep writing to r.headers map until a final status code is written. + if code >= 100 && code <= 199 { + return + } + r.written = true } diff --git a/pkg/middlewares/retry/retry_test.go b/pkg/middlewares/retry/retry_test.go index 4622093af..75ef5831b 100644 --- a/pkg/middlewares/retry/retry_test.go +++ b/pkg/middlewares/retry/retry_test.go @@ -7,6 +7,7 @@ import ( "net/http" "net/http/httptest" "net/http/httptrace" + "net/textproto" "strings" "testing" "time" @@ -309,3 +310,82 @@ func TestRetryWebsocket(t *testing.T) { }) } } + +// This test is an adapted version of net/http/httputil.Test1xxResponses test. +func Test1xxResponses(t *testing.T) { + next := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + h := w.Header() + h.Add("Link", "; rel=preload; as=style") + h.Add("Link", "; rel=preload; as=script") + w.WriteHeader(http.StatusEarlyHints) + + h.Add("Link", "; rel=preload; as=script") + w.WriteHeader(http.StatusProcessing) + + _, _ = w.Write([]byte("Hello")) + }) + + retryListener := &countingRetryListener{} + retry, err := New(context.Background(), next, dynamic.Retry{Attempts: 1}, retryListener, "traefikTest") + require.NoError(t, err) + + server := httptest.NewServer(retry) + t.Cleanup(server.Close) + frontendClient := server.Client() + + checkLinkHeaders := func(t *testing.T, expected, got []string) { + t.Helper() + + if len(expected) != len(got) { + t.Errorf("Expected %d link headers; got %d", len(expected), len(got)) + } + + for i := range expected { + if i >= len(got) { + t.Errorf("Expected %q link header; got nothing", expected[i]) + + continue + } + + if expected[i] != got[i] { + t.Errorf("Expected %q link header; got %q", expected[i], got[i]) + } + } + } + + var respCounter uint8 + trace := &httptrace.ClientTrace{ + Got1xxResponse: func(code int, header textproto.MIMEHeader) error { + switch code { + case http.StatusEarlyHints: + checkLinkHeaders(t, []string{"; rel=preload; as=style", "; rel=preload; as=script"}, header["Link"]) + case http.StatusProcessing: + checkLinkHeaders(t, []string{"; rel=preload; as=style", "; rel=preload; as=script", "; rel=preload; as=script"}, header["Link"]) + default: + t.Error("Unexpected 1xx response") + } + + respCounter++ + + return nil + }, + } + req, _ := http.NewRequestWithContext(httptrace.WithClientTrace(context.Background(), trace), http.MethodGet, server.URL, nil) + + res, err := frontendClient.Do(req) + assert.Nil(t, err) + + defer res.Body.Close() + + if respCounter != 2 { + t.Errorf("Expected 2 1xx responses; got %d", respCounter) + } + checkLinkHeaders(t, []string{"; rel=preload; as=style", "; rel=preload; as=script", "; rel=preload; as=script"}, res.Header["Link"]) + + body, _ := io.ReadAll(res.Body) + if string(body) != "Hello" { + t.Errorf("Read body %q; want Hello", body) + } + + assert.Equal(t, 0, retryListener.timesCalled) +} From e62fe64ec931e06942f85f384b0d475cf44fe18c Mon Sep 17 00:00:00 2001 From: LandryBe Date: Thu, 15 Jun 2023 18:20:06 +0200 Subject: [PATCH 06/13] Encode query semicolons Co-authored-by: Romain --- .../reference/static-configuration/cli-ref.md | 3 + .../reference/static-configuration/env-ref.md | 3 + .../reference/static-configuration/file.toml | 1 + .../reference/static-configuration/file.yaml | 1 + docs/content/routing/entrypoints.md | 38 +++++++++++ .../fixtures/simple_encode_semicolons.toml | 32 +++++++++ integration/simple_test.go | 68 +++++++++++++++++++ pkg/config/static/entrypoints.go | 7 +- pkg/server/server_entrypoint_tcp.go | 26 ++++++- pkg/server/service/proxy.go | 1 + 10 files changed, 176 insertions(+), 4 deletions(-) create mode 100644 integration/fixtures/simple_encode_semicolons.toml diff --git a/docs/content/reference/static-configuration/cli-ref.md b/docs/content/reference/static-configuration/cli-ref.md index 6b8537a7d..e9385b08b 100644 --- a/docs/content/reference/static-configuration/cli-ref.md +++ b/docs/content/reference/static-configuration/cli-ref.md @@ -114,6 +114,9 @@ Trust only forwarded headers from selected IPs. `--entrypoints..http`: HTTP configuration. +`--entrypoints..http.encodequerysemicolons`: +Defines whether request query semicolons should be URLEncoded. (Default: ```false```) + `--entrypoints..http.middlewares`: Default middlewares for the routers linked to the entry point. diff --git a/docs/content/reference/static-configuration/env-ref.md b/docs/content/reference/static-configuration/env-ref.md index f4b2b6def..184c4202b 100644 --- a/docs/content/reference/static-configuration/env-ref.md +++ b/docs/content/reference/static-configuration/env-ref.md @@ -123,6 +123,9 @@ HTTP/3 configuration. (Default: ```false```) `TRAEFIK_ENTRYPOINTS__HTTP3_ADVERTISEDPORT`: UDP port to advertise, on which HTTP/3 is available. (Default: ```0```) +`TRAEFIK_ENTRYPOINTS__HTTP_ENCODEQUERYSEMICOLONS`: +Defines whether request query semicolons should be URLEncoded. (Default: ```false```) + `TRAEFIK_ENTRYPOINTS__HTTP_MIDDLEWARES`: Default middlewares for the routers linked to the entry point. diff --git a/docs/content/reference/static-configuration/file.toml b/docs/content/reference/static-configuration/file.toml index 7d96d87f4..ca95739c9 100644 --- a/docs/content/reference/static-configuration/file.toml +++ b/docs/content/reference/static-configuration/file.toml @@ -30,6 +30,7 @@ trustedIPs = ["foobar", "foobar"] [entryPoints.EntryPoint0.http] middlewares = ["foobar", "foobar"] + encodeQuerySemicolons = true [entryPoints.EntryPoint0.http.redirections] [entryPoints.EntryPoint0.http.redirections.entryPoint] to = "foobar" diff --git a/docs/content/reference/static-configuration/file.yaml b/docs/content/reference/static-configuration/file.yaml index 435efb1ce..c3b6e830c 100644 --- a/docs/content/reference/static-configuration/file.yaml +++ b/docs/content/reference/static-configuration/file.yaml @@ -33,6 +33,7 @@ entryPoints: - foobar - foobar http: + encodeQuerySemicolons: true redirections: entryPoint: to: foobar diff --git a/docs/content/routing/entrypoints.md b/docs/content/routing/entrypoints.md index f20c0b456..305e69cd1 100644 --- a/docs/content/routing/entrypoints.md +++ b/docs/content/routing/entrypoints.md @@ -833,6 +833,44 @@ This section is a convenience to enable (permanent) redirecting of all incoming --entrypoints.foo.http.redirections.entrypoint.priority=10 ``` +### EncodeQuerySemicolons + +_Optional, Default=false_ + +The `encodeQuerySemicolons` option allows to enable query semicolons encoding. +One could use this option to avoid non-encoded semicolons to be interpreted as query parameter separators by Traefik. +When using this option, the non-encoded semicolons characters in query will be transmitted encoded to the backend. + +```yaml tab="File (YAML)" +entryPoints: + websecure: + address: ':443' + http: + encodeQuerySemicolons: true +``` + +```toml tab="File (TOML)" +[entryPoints.websecure] + address = ":443" + + [entryPoints.websecure.http] + encodeQuerySemicolons = true +``` + +```bash tab="CLI" +--entrypoints.websecure.address=:443 +--entrypoints.websecure.http.encodequerysemicolons=true +``` + +#### Examples + +| EncodeQuerySemicolons | Request Query | Resulting Request Query | +|-----------------------|---------------------|-------------------------| +| false | foo=bar;baz=bar | foo=bar&baz=bar | +| true | foo=bar;baz=bar | foo=bar%3Bbaz=bar | +| false | foo=bar&baz=bar;foo | foo=bar&baz=bar&foo | +| true | foo=bar&baz=bar;foo | foo=bar&baz=bar%3Bfoo | + ### Middlewares The list of middlewares that are prepended by default to the list of middlewares of each router associated to the named entry point. diff --git a/integration/fixtures/simple_encode_semicolons.toml b/integration/fixtures/simple_encode_semicolons.toml new file mode 100644 index 000000000..c460f361f --- /dev/null +++ b/integration/fixtures/simple_encode_semicolons.toml @@ -0,0 +1,32 @@ +[global] + checkNewVersion = false + sendAnonymousUsage = false + +[log] + level = "DEBUG" + +[entryPoints] + [entryPoints.web] + address = ":8000" + [entryPoints.encodeSemicolons] + address = ":8001" + [entryPoints.encodeSemicolons.http] + encodeQuerySemicolons = true + +[api] + insecure = true + +[providers.file] + filename = "{{ .SelfFilename }}" + +## dynamic configuration ## + +[http.routers] + [http.routers.router] + service = "service1" + rule = "Host(`other.localhost`)" + +[http.services] + [http.services.service1.loadBalancer] + [[http.services.service1.loadBalancer.servers]] + url = "{{ .Server1 }}" diff --git a/integration/simple_test.go b/integration/simple_test.go index e25f25cfb..baf7aa230 100644 --- a/integration/simple_test.go +++ b/integration/simple_test.go @@ -1412,3 +1412,71 @@ func (s *SimpleSuite) TestDebugLog(c *check.C) { c.Fail() } } + +func (s *SimpleSuite) TestEncodeSemicolons(c *check.C) { + s.createComposeProject(c, "base") + + s.composeUp(c) + defer s.composeDown(c) + + whoami1URL := "http://" + net.JoinHostPort(s.getComposeServiceIP(c, "whoami1"), "80") + + file := s.adaptFile(c, "fixtures/simple_encode_semicolons.toml", struct { + Server1 string + }{whoami1URL}) + defer os.Remove(file) + + cmd, output := s.traefikCmd(withConfigFile(file)) + defer output(c) + + err := cmd.Start() + c.Assert(err, checker.IsNil) + defer s.killCmd(cmd) + + err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains("Host(`other.localhost`)")) + c.Assert(err, checker.IsNil) + + testCases := []struct { + desc string + request string + target string + body string + expected int + }{ + { + desc: "Transforming semicolons", + request: "GET /?bar=toto;boo=titi HTTP/1.1\r\nHost: other.localhost\r\n\r\n", + target: "127.0.0.1:8000", + expected: http.StatusOK, + body: "bar=toto&boo=titi", + }, + { + desc: "Encoding semicolons", + request: "GET /?bar=toto&boo=titi;aaaa HTTP/1.1\r\nHost: other.localhost\r\n\r\n", + target: "127.0.0.1:8001", + expected: http.StatusOK, + body: "bar=toto&boo=titi%3Baaaa", + }, + } + + for _, test := range testCases { + conn, err := net.Dial("tcp", test.target) + c.Assert(err, checker.IsNil) + + _, err = conn.Write([]byte(test.request)) + c.Assert(err, checker.IsNil) + + resp, err := http.ReadResponse(bufio.NewReader(conn), nil) + c.Assert(err, checker.IsNil) + + if resp.StatusCode != test.expected { + c.Errorf("%s failed with %d instead of %d", test.desc, resp.StatusCode, test.expected) + } + + if test.body != "" { + body, err := io.ReadAll(resp.Body) + c.Assert(err, checker.IsNil) + c.Assert(string(body), checker.Contains, test.body) + } + } +} diff --git a/pkg/config/static/entrypoints.go b/pkg/config/static/entrypoints.go index f97d78e22..68ac9285e 100644 --- a/pkg/config/static/entrypoints.go +++ b/pkg/config/static/entrypoints.go @@ -57,9 +57,10 @@ func (ep *EntryPoint) SetDefaults() { // HTTPConfig is the HTTP configuration of an entry point. 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"` + 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"` } // HTTP2Config is the HTTP2 configuration of an entry point. diff --git a/pkg/server/server_entrypoint_tcp.go b/pkg/server/server_entrypoint_tcp.go index 5d7095768..96cc29dc4 100644 --- a/pkg/server/server_entrypoint_tcp.go +++ b/pkg/server/server_entrypoint_tcp.go @@ -535,7 +535,11 @@ func createHTTPServer(ctx context.Context, ln net.Listener, configuration *stati return nil, err } - handler = http.AllowQuerySemicolons(handler) + if configuration.HTTP.EncodeQuerySemicolons { + handler = encodeQuerySemicolons(handler) + } else { + handler = http.AllowQuerySemicolons(handler) + } if withH2c { handler = h2c.NewHandler(handler, &http2.Server{ @@ -596,3 +600,23 @@ func (t *trackedConnection) Close() error { t.tracker.RemoveConnection(t.WriteCloser) return t.WriteCloser.Close() } + +// This function is inspired by http.AllowQuerySemicolons. +func encodeQuerySemicolons(h http.Handler) http.Handler { + return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { + if strings.Contains(req.URL.RawQuery, ";") { + r2 := new(http.Request) + *r2 = *req + r2.URL = new(url.URL) + *r2.URL = *req.URL + + r2.URL.RawQuery = strings.ReplaceAll(req.URL.RawQuery, ";", "%3B") + // Because the reverse proxy director is building query params from requestURI it needs to be updated as well. + r2.RequestURI = r2.URL.RequestURI() + + h.ServeHTTP(rw, r2) + } else { + h.ServeHTTP(rw, req) + } + }) +} diff --git a/pkg/server/service/proxy.go b/pkg/server/service/proxy.go index 2669499bf..257c4ce0d 100644 --- a/pkg/server/service/proxy.go +++ b/pkg/server/service/proxy.go @@ -48,6 +48,7 @@ func buildProxy(passHostHeader *bool, responseForwarding *dynamic.ResponseForwar outReq.URL.Path = u.Path outReq.URL.RawPath = u.RawPath + // If a plugin/middleware adds semicolons in query params, they should be urlEncoded. outReq.URL.RawQuery = strings.ReplaceAll(u.RawQuery, ";", "&") outReq.RequestURI = "" // Outgoing request should not have RequestURI From 9cc9ed6a0c00403743fb70acd327f7251abd4bda Mon Sep 17 00:00:00 2001 From: green1052 Date: Sun, 18 Jun 2023 04:52:05 +0900 Subject: [PATCH 07/13] Fix typo --- docs/content/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/index.md b/docs/content/index.md index 11d996ea6..6bb820f50 100644 --- a/docs/content/index.md +++ b/docs/content/index.md @@ -24,7 +24,7 @@ Developing Traefik, our main goal is to make it simple to use, and we're sure yo !!! info - Join our user friendly and active [Community Forum]((https://community.traefik.io "Link to Traefik Community Forum") to discuss, learn, and connect with the traefik community. + Join our user friendly and active [Community Forum](https://community.traefik.io "Link to Traefik Community Forum") to discuss, learn, and connect with the traefik community. Using Traefik in your organization? Consider [Traefik Enterprise](https://traefik.io/traefik-enterprise/ "Lino to Traefik Enterprise"), our unified API Gateway and Ingress that simplifies the discovery, security, and deployment of APIs and microservices across any environment. From aae76408e22d173137cd5551bd0b955f21f40807 Mon Sep 17 00:00:00 2001 From: Ludovic Fernandez Date: Mon, 19 Jun 2023 12:00:06 +0200 Subject: [PATCH 08/13] Prepare release v2.10.2 --- CHANGELOG.md | 24 ++++++++++++++++++++++++ script/gcg/traefik-bugfix.toml | 6 +++--- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c1901b001..85ee95b67 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,27 @@ +## [v2.10.2](https://github.com/traefik/traefik/tree/v2.10.2) (2023-06-17) +[All Commits](https://github.com/traefik/traefik/compare/v2.10.1...v2.10.2) + +**Bug fixes:** +- **[acme]** Update go-acme/lego to v4.12.1 ([#9935](https://github.com/traefik/traefik/pull/9935) by [ldez](https://github.com/ldez)) +- **[acme]** Update go-acme/lego to v4.12.0 ([#9918](https://github.com/traefik/traefik/pull/9918) by [ldez](https://github.com/ldez)) +- **[acme]** Update go-acme/lego to v4.11.0 ([#9883](https://github.com/traefik/traefik/pull/9883) by [ldez](https://github.com/ldez)) +- **[acme]** Do not check for wildcard domains for non DNS challenge ([#9881](https://github.com/traefik/traefik/pull/9881) by [erkexzcx](https://github.com/erkexzcx)) +- **[k8s/crd]** Fix multiple subsets endpoint ([#9914](https://github.com/traefik/traefik/pull/9914) by [joaosilva15](https://github.com/joaosilva15)) +- **[k8s/ingress,k8s/crd,k8s,hub]** Clean code related to Hub ([#9894](https://github.com/traefik/traefik/pull/9894) by [ldez](https://github.com/ldez)) +- **[metrics]** Enable Prometheus provider cleanup when only the router's metrics level is activated ([#9887](https://github.com/traefik/traefik/pull/9887) by [rtribotte](https://github.com/rtribotte)) +- **[middleware]** Encode query semicolons ([#9943](https://github.com/traefik/traefik/pull/9943) by [LandryBe](https://github.com/LandryBe)) +- **[middleware]** Mssing trailer with custom errors middleware ([#9942](https://github.com/traefik/traefik/pull/9942) by [rtribotte](https://github.com/rtribotte)) +- **[middleware]** Support informational headers in middlewares redefining the response writer. ([#9938](https://github.com/traefik/traefik/pull/9938) by [rtribotte](https://github.com/rtribotte)) +- **[plugins]** Improve error messages related to plugins ([#9924](https://github.com/traefik/traefik/pull/9924) by [ldez](https://github.com/ldez)) +- **[tracing]** Update DataDog tracing dependency to v1.50.1 ([#9953](https://github.com/traefik/traefik/pull/9953) by [der-eismann](https://github.com/der-eismann)) + +**Documentation:** +- **[accesslogs]** Fix over-indented yaml configuration of access logs ([#9930](https://github.com/traefik/traefik/pull/9930) by [ufUNnxagpM](https://github.com/ufUNnxagpM)) +- **[tls]** Add FAQ documentation about TLS certificates ([#9868](https://github.com/traefik/traefik/pull/9868) by [rtribotte](https://github.com/rtribotte)) +- Fix typo ([#9966](https://github.com/traefik/traefik/pull/9966) by [green1052](https://github.com/green1052)) +- Add business callouts ([#9940](https://github.com/traefik/traefik/pull/9940) by [tomatokoolaid](https://github.com/tomatokoolaid)) +- Add logo for GitHub dark mode ([#9890](https://github.com/traefik/traefik/pull/9890) by [ldez](https://github.com/ldez)) + ## [v2.10.1](https://github.com/traefik/traefik/tree/v2.10.1) (2023-04-27) [All Commits](https://github.com/traefik/traefik/compare/v2.10.0...v2.10.1) diff --git a/script/gcg/traefik-bugfix.toml b/script/gcg/traefik-bugfix.toml index bc6c422ee..6a485662b 100644 --- a/script/gcg/traefik-bugfix.toml +++ b/script/gcg/traefik-bugfix.toml @@ -4,11 +4,11 @@ RepositoryName = "traefik" OutputType = "file" FileName = "traefik_changelog.md" -# example new bugfix v2.10.1 +# example new bugfix v2.10.2 CurrentRef = "v2.10" -PreviousRef = "v2.10.0" +PreviousRef = "v2.10.1" BaseBranch = "v2.10" -FutureCurrentRefName = "v2.10.1" +FutureCurrentRefName = "v2.10.2" ThresholdPreviousRef = 10 ThresholdCurrentRef = 10 From 0e5898b2f8f3af433b100596ad75517dbac9af78 Mon Sep 17 00:00:00 2001 From: Jakob Miksch Date: Mon, 19 Jun 2023 14:36:05 +0200 Subject: [PATCH 09/13] Minor Typo --- docs/content/getting-started/concepts.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/getting-started/concepts.md b/docs/content/getting-started/concepts.md index 2e99906a3..10e1787e4 100644 --- a/docs/content/getting-started/concepts.md +++ b/docs/content/getting-started/concepts.md @@ -11,7 +11,7 @@ This page explains the base concepts of Traefik. ## Introduction -Traefik is based on the concept of EntryPoints, Routers, Middelwares and Services. +Traefik is based on the concept of EntryPoints, Routers, Middlewares and Services. The main features include dynamic configuration, automatic service discovery, and support for multiple backends and protocols. From fa555d0d297991b0259edcc754fc50316eca3dad Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 19 Jun 2023 17:34:05 +0200 Subject: [PATCH 10/13] fix: Remove unnecessary data on release ci --- .semaphore/semaphore.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.semaphore/semaphore.yml b/.semaphore/semaphore.yml index 349249162..746cf0d68 100644 --- a/.semaphore/semaphore.yml +++ b/.semaphore/semaphore.yml @@ -73,7 +73,7 @@ blocks: - curl -sSL -o /tmp/gh_${GH_VERSION}_linux_amd64.tar.gz https://github.com/cli/cli/releases/download/v${GH_VERSION}/gh_${GH_VERSION}_linux_amd64.tar.gz - tar -zxvf /tmp/gh_${GH_VERSION}_linux_amd64.tar.gz -C /tmp - sudo mv /tmp/gh_${GH_VERSION}_linux_amd64/bin/gh /usr/local/bin/gh - - sudo rm -rf ~/.phpbrew ~/.kerl ~/.sbt ~/.nvm ~/.npm ~/.kiex /usr/lib/jvm /opt/az /opt/firefox # Remove unnecessary data. + - sudo rm -rf ~/.phpbrew ~/.kerl ~/.sbt ~/.nvm ~/.npm ~/.kiex /usr/lib/jvm /opt/az /opt/firefox /usr/lib/google-cloud-sdk ~/.rbenv ~/.pip_download_cache # Remove unnecessary data. - sudo service docker stop && sudo umount /var/lib/docker && sudo service docker start # Unmounts the docker disk and the whole system disk is usable. jobs: - name: Release From 18077ff69a7195492743ec1b97e79d8306aa942a Mon Sep 17 00:00:00 2001 From: Ludovic Fernandez Date: Mon, 19 Jun 2023 18:08:05 +0200 Subject: [PATCH 11/13] Update go-acme/lego to v4.12.2 --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 27de095eb..bfcaf2529 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( github.com/docker/go-connections v0.4.0 github.com/fatih/structs v1.1.0 github.com/gambol99/go-marathon v0.0.0-20180614232016-99a156b96fb2 - github.com/go-acme/lego/v4 v4.12.1 + github.com/go-acme/lego/v4 v4.12.2 github.com/go-check/check v0.0.0-00010101000000-000000000000 github.com/go-kit/kit v0.10.1-0.20200915143503-439c4d2ed3ea github.com/golang/protobuf v1.5.2 diff --git a/go.sum b/go.sum index c444150a2..cec22e6eb 100644 --- a/go.sum +++ b/go.sum @@ -666,8 +666,8 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.7.4/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY= github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= -github.com/go-acme/lego/v4 v4.12.1 h1:Cy3FS7wADLNBqCLpz2wdfdNrThW9rZy8RCAfnUrL2uE= -github.com/go-acme/lego/v4 v4.12.1/go.mod h1:UZoOlhVmUYP/N0z4tEbfUjoCNHRZNObzqWZtT76DIsc= +github.com/go-acme/lego/v4 v4.12.2 h1:JyrneGpom0HdVAvPQdyo+6gEciOnFgSZwH42vaL/hxc= +github.com/go-acme/lego/v4 v4.12.2/go.mod h1:UZoOlhVmUYP/N0z4tEbfUjoCNHRZNObzqWZtT76DIsc= github.com/go-asn1-ber/asn1-ber v1.3.1/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs= github.com/go-cmd/cmd v1.0.5/go.mod h1:y8q8qlK5wQibcw63djSl/ntiHUHXHGdCkPk0j4QeW4s= From 7741c68eaa719d114c6d7444c965b7ae373e46a6 Mon Sep 17 00:00:00 2001 From: Ludovic Fernandez Date: Mon, 19 Jun 2023 18:14:30 +0200 Subject: [PATCH 12/13] Prepare release v2.10.3 --- CHANGELOG.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 85ee95b67..3596578bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## [v2.10.3](https://github.com/traefik/traefik/tree/v2.10.3) (2023-06-17) +[All Commits](https://github.com/traefik/traefik/compare/v2.10.2...v2.10.3) + +**Bug fixes:** +- **[acme]** Update go-acme/lego to v4.12.2 ([#9935](https://github.com/traefik/traefik/pull/9971) by [ldez](https://github.com/ldez)) + ## [v2.10.2](https://github.com/traefik/traefik/tree/v2.10.2) (2023-06-17) [All Commits](https://github.com/traefik/traefik/compare/v2.10.1...v2.10.2) @@ -10,7 +16,7 @@ - **[k8s/ingress,k8s/crd,k8s,hub]** Clean code related to Hub ([#9894](https://github.com/traefik/traefik/pull/9894) by [ldez](https://github.com/ldez)) - **[metrics]** Enable Prometheus provider cleanup when only the router's metrics level is activated ([#9887](https://github.com/traefik/traefik/pull/9887) by [rtribotte](https://github.com/rtribotte)) - **[middleware]** Encode query semicolons ([#9943](https://github.com/traefik/traefik/pull/9943) by [LandryBe](https://github.com/LandryBe)) -- **[middleware]** Mssing trailer with custom errors middleware ([#9942](https://github.com/traefik/traefik/pull/9942) by [rtribotte](https://github.com/rtribotte)) +- **[middleware]** Missing trailer with custom errors middleware ([#9942](https://github.com/traefik/traefik/pull/9942) by [rtribotte](https://github.com/rtribotte)) - **[middleware]** Support informational headers in middlewares redefining the response writer. ([#9938](https://github.com/traefik/traefik/pull/9938) by [rtribotte](https://github.com/rtribotte)) - **[plugins]** Improve error messages related to plugins ([#9924](https://github.com/traefik/traefik/pull/9924) by [ldez](https://github.com/ldez)) - **[tracing]** Update DataDog tracing dependency to v1.50.1 ([#9953](https://github.com/traefik/traefik/pull/9953) by [der-eismann](https://github.com/der-eismann)) From 0a861716d422ff42fc5ad53c1fbac09cda0922cc Mon Sep 17 00:00:00 2001 From: Romain Date: Tue, 20 Jun 2023 17:12:05 +0200 Subject: [PATCH 13/13] Update release documentation --- docs/content/deprecation/releases.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/content/deprecation/releases.md b/docs/content/deprecation/releases.md index 6d23f06c0..1e73eda6d 100644 --- a/docs/content/deprecation/releases.md +++ b/docs/content/deprecation/releases.md @@ -6,7 +6,8 @@ Below is a non-exhaustive list of versions and their maintenance status: | Version | Release Date | Active Support | Security Support | |---------|--------------|--------------------|------------------| -| 2.9 | Oct 03, 2022 | Yes | Yes | +| 2.10 | Apr 24, 2023 | Yes | Yes | +| 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 |