diff --git a/docs/content/middlewares/http/buffering.md b/docs/content/middlewares/http/buffering.md index 7610e2d81..f172faffa 100644 --- a/docs/content/middlewares/http/buffering.md +++ b/docs/content/middlewares/http/buffering.md @@ -72,9 +72,11 @@ http: ### `maxRequestBodyBytes` +_Optional, Default=0_ + The `maxRequestBodyBytes` option configures the maximum allowed body size for the request (in bytes). -If the request exceeds the allowed size, it is not forwarded to the service, and the client gets a `413 (Request Entity Too Large)` response. +If the request exceeds the allowed size, it is not forwarded to the service, and the client gets a `413` (Request Entity Too Large) response. ```yaml tab="Docker" labels: @@ -122,6 +124,8 @@ http: ### `memRequestBodyBytes` +_Optional, Default=1048576_ + You can configure a threshold (in bytes) from which the request will be buffered on disk instead of in memory with the `memRequestBodyBytes` option. ```yaml tab="Docker" @@ -170,9 +174,11 @@ http: ### `maxResponseBodyBytes` +_Optional, Default=0_ + The `maxResponseBodyBytes` option configures the maximum allowed response size from the service (in bytes). -If the response exceeds the allowed size, it is not forwarded to the client. The client gets a `413` (Request Entity Too Large) response instead. +If the response exceeds the allowed size, it is not forwarded to the client. The client gets a `500` (Internal Server Error) response instead. ```yaml tab="Docker" labels: @@ -220,6 +226,8 @@ http: ### `memResponseBodyBytes` +_Optional, Default=1048576_ + You can configure a threshold (in bytes) from which the response will be buffered on disk instead of in memory with the `memResponseBodyBytes` option. ```yaml tab="Docker" @@ -268,6 +276,8 @@ http: ### `retryExpression` +_Optional, Default=""_ + You can have the Buffering middleware replay the request using `retryExpression`. ??? example "Retries once in the case of a network error" diff --git a/docs/scripts/verify.sh b/docs/scripts/verify.sh index 81584223d..640572ec5 100755 --- a/docs/scripts/verify.sh +++ b/docs/scripts/verify.sh @@ -22,7 +22,7 @@ find "${PATH_TO_SITE}" -type f -not -path "/app/site/theme/*" \ --alt_ignore="/traefikproxy-vertical-logo-color.svg/" \ --http_status_ignore="0,500,501,503" \ --file_ignore="/404.html/" \ - --url_ignore="/https://groups.google.com/a/traefik.io/forum/#!forum/security/,/localhost:/,/127.0.0.1:/,/fonts.gstatic.com/,/.minikube/,/github.com\/traefik\/traefik\/*edit*/,/github.com\/traefik\/traefik/,/doc.traefik.io/,/github\.com\/golang\/oauth2\/blob\/36a7019397c4c86cf59eeab3bc0d188bac444277\/.+/,/www.akamai.com/,/pilot.traefik.io\/profile/,/traefik.io/,/doc.traefik.io\/traefik-mesh/,/www.mkdocs.org/,/squidfunk.github.io/,/ietf.org/,/www.namesilo.com/,/www.youtube.com/,/www.linode.com/,/www.alibabacloud.com/,/www.cloudxns.net/,/www.vultr.com/,/vscale.io/,/hetzner.com/,/docs.github.com/" \ + --url_ignore="/https://groups.google.com/a/traefik.io/forum/#!forum/security/,/localhost:/,/127.0.0.1:/,/fonts.gstatic.com/,/.minikube/,/github.com\/traefik\/traefik\/*edit*/,/github.com\/traefik\/traefik/,/doc.traefik.io/,/github\.com\/golang\/oauth2\/blob\/36a7019397c4c86cf59eeab3bc0d188bac444277\/.+/,/www.akamai.com/,/pilot.traefik.io\/profile/,/traefik.io/,/doc.traefik.io\/traefik-mesh/,/www.mkdocs.org/,/squidfunk.github.io/,/ietf.org/,/www.namesilo.com/,/www.youtube.com/,/www.linode.com/,/www.alibabacloud.com/,/www.cloudxns.net/,/www.vultr.com/,/vscale.io/,/hetzner.com/,/docs.github.com/,/njal.la/" \ '{}' 1>/dev/null ## HTML-proofer options at https://github.com/gjtorikian/html-proofer#configuration diff --git a/go.mod b/go.mod index ba442f80b..ffae61f86 100644 --- a/go.mod +++ b/go.mod @@ -95,7 +95,7 @@ replace ( github.com/go-check/check => github.com/containous/check v0.0.0-20170915194414-ca0bf163426a github.com/gorilla/mux => github.com/containous/mux v0.0.0-20220113180107-8ffa4f6d063c github.com/mailgun/minheap => github.com/containous/minheap v0.0.0-20190809180810-6e71eb837595 - github.com/mailgun/multibuf => github.com/containous/multibuf v0.0.0-20190809014333-8b6c9a7e6bba + github.com/mailgun/multibuf => github.com/containous/multibuf v0.0.0-20220419123348-2d0b12e116c6 ) // https://github.com/docker/compose/blob/e44222664abd07ce1d1fe6796d84d93cbc7468c3/go.mod#L131 diff --git a/go.sum b/go.sum index 90d60d4a6..9745085b3 100644 --- a/go.sum +++ b/go.sum @@ -426,8 +426,8 @@ github.com/containous/go-http-auth v0.4.1-0.20200324110947-a37a7636d23e h1:D+uTE github.com/containous/go-http-auth v0.4.1-0.20200324110947-a37a7636d23e/go.mod h1:s8kLgBQolDbsJOPVIGCEEv9zGAKUUf/685Gi0Qqg8z8= github.com/containous/minheap v0.0.0-20190809180810-6e71eb837595 h1:aPspFRO6b94To3gl4yTDOEtpjFwXI7V2W+z0JcNljQ4= github.com/containous/minheap v0.0.0-20190809180810-6e71eb837595/go.mod h1:+lHFbEasIiQVGzhVDVw/cn0ZaOzde2OwNncp1NhXV4c= -github.com/containous/multibuf v0.0.0-20190809014333-8b6c9a7e6bba h1:PhR03pep+5eO/9BSvCY9RyG8rjogB3uYS4X/WBYNTT8= -github.com/containous/multibuf v0.0.0-20190809014333-8b6c9a7e6bba/go.mod h1:zkWcASFUJEst6QwCrxLdkuw1gvaKqmflEipm+iecV5M= +github.com/containous/multibuf v0.0.0-20220419123348-2d0b12e116c6 h1:KzERnBo5Jn4RRKjo8hdDPS4llWjHlJtM6kfm4mRkIew= +github.com/containous/multibuf v0.0.0-20220419123348-2d0b12e116c6/go.mod h1:zkWcASFUJEst6QwCrxLdkuw1gvaKqmflEipm+iecV5M= github.com/containous/mux v0.0.0-20220113180107-8ffa4f6d063c h1:g6JvgTtfpS6AfhRjY87NZ0g39CrNDbdm8R+1CD85Cfo= github.com/containous/mux v0.0.0-20220113180107-8ffa4f6d063c/go.mod h1:z8WW7n06n8/1xF9Jl9WmuDeZuHAhfL+bwarNjsciwwg= github.com/coredns/coredns v1.1.2/go.mod h1:zASH/MVDgR6XZTbxvOnsZfffS+31vg6Ackf/wo1+AM0= diff --git a/pkg/middlewares/buffering/buffering_test.go b/pkg/middlewares/buffering/buffering_test.go new file mode 100644 index 000000000..22477785a --- /dev/null +++ b/pkg/middlewares/buffering/buffering_test.go @@ -0,0 +1,72 @@ +package buffering + +import ( + "bytes" + "context" + "math" + "math/rand" + "net/http" + "net/http/httptest" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/traefik/traefik/v2/pkg/config/dynamic" +) + +func TestBuffering(t *testing.T) { + payload := make([]byte, math.MaxInt8) + rand.Read(payload) + + testCases := []struct { + desc string + config dynamic.Buffering + body []byte + expectedCode int + }{ + { + desc: "Unlimited response and request body size", + body: payload, + expectedCode: http.StatusOK, + }, + { + desc: "Limited request body size", + config: dynamic.Buffering{ + MaxRequestBodyBytes: 1, + }, + body: payload, + expectedCode: http.StatusRequestEntityTooLarge, + }, + { + desc: "Limited response body size", + config: dynamic.Buffering{ + MaxResponseBodyBytes: 1, + }, + body: payload, + expectedCode: http.StatusInternalServerError, + }, + } + + for _, test := range testCases { + test := test + t.Run(test.desc, func(t *testing.T) { + t.Parallel() + + next := http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { + rw.WriteHeader(http.StatusOK) + _, err := rw.Write(test.body) + require.NoError(t, err) + }) + + buffMiddleware, err := New(context.Background(), next, test.config, "foo") + require.NoError(t, err) + + req := httptest.NewRequest(http.MethodPost, "http://localhost", bytes.NewBuffer(test.body)) + + recorder := httptest.NewRecorder() + buffMiddleware.ServeHTTP(recorder, req) + + assert.Equal(t, test.expectedCode, recorder.Code) + }) + } +}