From e6d6fbe5a83262d4a7262f03a1bbceca9105a80d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=2E=20Efe=20=C3=87etin?= Date: Wed, 27 Sep 2023 16:06:24 +0300 Subject: [PATCH] :sparkles: middleware: cors: allow disabling caching in preflight requests (#2649) --- docs/api/middleware/cors.md | 20 ++++++++++---------- middleware/cors/cors.go | 5 +++++ middleware/cors/cors_test.go | 14 ++++++++++++++ 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/docs/api/middleware/cors.md b/docs/api/middleware/cors.md index af9b8c5f..d688c7f5 100644 --- a/docs/api/middleware/cors.md +++ b/docs/api/middleware/cors.md @@ -54,16 +54,16 @@ app.Use(cors.New(cors.Config{ ## Config -| Property | Type | Description | Default | -|:-----------------|:---------------------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------------------------------| -| Next | `func(*fiber.Ctx) bool` | Next defines a function to skip this middleware when returned true. | `nil` | -| AllowOriginsFunc | `func(origin string) bool` | AllowOriginsFunc defines a function that will set the 'access-control-allow-origin' response header to the 'origin' request header when returned true. | `nil` | -| AllowOrigins | `string` | AllowOrigin defines a list of origins that may access the resource. | `"*"` | -| AllowMethods | `string` | AllowMethods defines a list methods allowed when accessing the resource. This is used in response to a preflight request. | `"GET,POST,HEAD,PUT,DELETE,PATCH"` | -| AllowHeaders | `string` | AllowHeaders defines a list of request headers that can be used when making the actual request. This is in response to a preflight request. | `""` | -| AllowCredentials | `bool` | AllowCredentials indicates whether or not the response to the request can be exposed when the credentials flag is true. | `false` | -| ExposeHeaders | `string` | ExposeHeaders defines a whitelist headers that clients are allowed to access. | `""` | -| MaxAge | `int` | MaxAge indicates how long (in seconds) the results of a preflight request can be cached. | `0` | +| Property | Type | Description | Default | +|:-----------------|:---------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------------------------------| +| Next | `func(*fiber.Ctx) bool` | Next defines a function to skip this middleware when returned true. | `nil` | +| AllowOriginsFunc | `func(origin string) bool` | AllowOriginsFunc defines a function that will set the 'access-control-allow-origin' response header to the 'origin' request header when returned true. | `nil` | +| AllowOrigins | `string` | AllowOrigin defines a list of origins that may access the resource. | `"*"` | +| AllowMethods | `string` | AllowMethods defines a list methods allowed when accessing the resource. This is used in response to a preflight request. | `"GET,POST,HEAD,PUT,DELETE,PATCH"` | +| AllowHeaders | `string` | AllowHeaders defines a list of request headers that can be used when making the actual request. This is in response to a preflight request. | `""` | +| AllowCredentials | `bool` | AllowCredentials indicates whether or not the response to the request can be exposed when the credentials flag is true. | `false` | +| ExposeHeaders | `string` | ExposeHeaders defines a whitelist headers that clients are allowed to access. | `""` | +| MaxAge | `int` | MaxAge indicates how long (in seconds) the results of a preflight request can be cached. If you pass MaxAge 0, Access-Control-Max-Age header will not be added and browser will use 5 seconds by default. To disable caching completely, pass MaxAge value negative. It will set the Access-Control-Max-Age header 0. | `0` | ## Default Config diff --git a/middleware/cors/cors.go b/middleware/cors/cors.go index 281b2b45..c347e435 100644 --- a/middleware/cors/cors.go +++ b/middleware/cors/cors.go @@ -54,6 +54,9 @@ type Config struct { // MaxAge indicates how long (in seconds) the results of a preflight request // can be cached. + // If you pass MaxAge 0, Access-Control-Max-Age header will not be added and + // browser will use 5 seconds by default. + // To disable caching completely, pass MaxAge value negative. It will set the Access-Control-Max-Age header 0. // // Optional. Default value 0. MaxAge int @@ -187,6 +190,8 @@ func New(config ...Config) fiber.Handler { // Set MaxAge is set if cfg.MaxAge > 0 { c.Set(fiber.HeaderAccessControlMaxAge, maxAge) + } else if cfg.MaxAge < 0 { + c.Set(fiber.HeaderAccessControlMaxAge, "0") } // Send 204 No Content diff --git a/middleware/cors/cors_test.go b/middleware/cors/cors_test.go index 15b51a95..692a24bf 100644 --- a/middleware/cors/cors_test.go +++ b/middleware/cors/cors_test.go @@ -27,6 +27,20 @@ func Test_CORS_Empty_Config(t *testing.T) { testDefaultOrEmptyConfig(t, app) } +func Test_CORS_Negative_MaxAge(t *testing.T) { + t.Parallel() + + app := fiber.New() + app.Use(New(Config{MaxAge: -1})) + + ctx := &fasthttp.RequestCtx{} + ctx.Request.Header.SetMethod(fiber.MethodOptions) + ctx.Request.Header.Set(fiber.HeaderOrigin, "localhost") + app.Handler()(ctx) + + utils.AssertEqual(t, "0", string(ctx.Response.Header.Peek(fiber.HeaderAccessControlMaxAge))) +} + func testDefaultOrEmptyConfig(t *testing.T, app *fiber.App) { t.Helper()