Skip to content

Commit c4c5886

Browse files
committed
🩹 Fix(v3;middleware/cache): don't cache if status code is not cacheable
1 parent a42ddc1 commit c4c5886

File tree

2 files changed

+97
-0
lines changed

2 files changed

+97
-0
lines changed

middleware/cache/cache.go

+13
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,13 @@ var ignoreHeaders = map[string]any{
4848
"Content-Encoding": nil, // already stored explicitly by the cache manager
4949
}
5050

51+
var cacheableStatusCodes = []int{
52+
fiber.StatusOK, fiber.StatusNonAuthoritativeInformation, fiber.StatusNoContent, fiber.StatusPartialContent,
53+
fiber.StatusMultipleChoices, fiber.StatusMovedPermanently,
54+
fiber.StatusNotFound, fiber.StatusMethodNotAllowed, fiber.StatusGone, fiber.StatusRequestURITooLong,
55+
fiber.StatusNotImplemented,
56+
}
57+
5158
// New creates a new middleware handler
5259
func New(config ...Config) fiber.Handler {
5360
// Set default config
@@ -170,6 +177,12 @@ func New(config ...Config) fiber.Handler {
170177
return err
171178
}
172179

180+
// Don't cache response if status code is not cacheable
181+
if !slices.Contains(cacheableStatusCodes, c.Response().StatusCode()) {
182+
c.Set(cfg.CacheHeader, cacheUnreachable)
183+
return nil
184+
}
185+
173186
// lock entry back and unlock on finish
174187
mux.Lock()
175188
defer mux.Unlock()

middleware/cache/cache_test.go

+84
Original file line numberDiff line numberDiff line change
@@ -918,6 +918,90 @@ func Test_Cache_MaxBytesSizes(t *testing.T) {
918918
}
919919
}
920920

921+
func Test_Cache_UncacheableStatusCodes(t *testing.T) {
922+
t.Parallel()
923+
app := fiber.New()
924+
app.Use(New())
925+
926+
app.Get("/:statusCode", func(c fiber.Ctx) error {
927+
statusCode, err := strconv.Atoi(c.Params("statusCode"))
928+
if err != nil {
929+
return err
930+
}
931+
return c.Status(statusCode).SendString("foo")
932+
})
933+
934+
uncacheableStatusCodes := []int{
935+
// Informational responses
936+
fiber.StatusContinue,
937+
fiber.StatusSwitchingProtocols,
938+
fiber.StatusProcessing,
939+
fiber.StatusEarlyHints,
940+
941+
// Successful responses
942+
fiber.StatusCreated,
943+
fiber.StatusAccepted,
944+
fiber.StatusResetContent,
945+
fiber.StatusMultiStatus,
946+
fiber.StatusAlreadyReported,
947+
fiber.StatusIMUsed,
948+
949+
// Redirection responses
950+
fiber.StatusFound,
951+
fiber.StatusSeeOther,
952+
fiber.StatusNotModified,
953+
fiber.StatusUseProxy,
954+
fiber.StatusSwitchProxy,
955+
fiber.StatusTemporaryRedirect,
956+
fiber.StatusPermanentRedirect,
957+
958+
// Client error responses
959+
fiber.StatusBadRequest,
960+
fiber.StatusUnauthorized,
961+
fiber.StatusPaymentRequired,
962+
fiber.StatusForbidden,
963+
fiber.StatusNotAcceptable,
964+
fiber.StatusProxyAuthRequired,
965+
fiber.StatusRequestTimeout,
966+
fiber.StatusConflict,
967+
fiber.StatusLengthRequired,
968+
fiber.StatusPreconditionFailed,
969+
fiber.StatusRequestEntityTooLarge,
970+
fiber.StatusUnsupportedMediaType,
971+
fiber.StatusRequestedRangeNotSatisfiable,
972+
fiber.StatusExpectationFailed,
973+
fiber.StatusTeapot,
974+
fiber.StatusMisdirectedRequest,
975+
fiber.StatusUnprocessableEntity,
976+
fiber.StatusLocked,
977+
fiber.StatusFailedDependency,
978+
fiber.StatusTooEarly,
979+
fiber.StatusUpgradeRequired,
980+
fiber.StatusPreconditionRequired,
981+
fiber.StatusTooManyRequests,
982+
fiber.StatusRequestHeaderFieldsTooLarge,
983+
fiber.StatusUnavailableForLegalReasons,
984+
985+
// Server error responses
986+
fiber.StatusInternalServerError,
987+
fiber.StatusBadGateway,
988+
fiber.StatusServiceUnavailable,
989+
fiber.StatusGatewayTimeout,
990+
fiber.StatusHTTPVersionNotSupported,
991+
fiber.StatusVariantAlsoNegotiates,
992+
fiber.StatusInsufficientStorage,
993+
fiber.StatusLoopDetected,
994+
fiber.StatusNotExtended,
995+
fiber.StatusNetworkAuthenticationRequired,
996+
}
997+
for _, v := range uncacheableStatusCodes {
998+
resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, fmt.Sprintf("/%d", v), nil))
999+
require.NoError(t, err)
1000+
require.Equal(t, cacheUnreachable, resp.Header.Get("X-Cache"))
1001+
require.Equal(t, v, resp.StatusCode)
1002+
}
1003+
}
1004+
9211005
// go test -v -run=^$ -bench=Benchmark_Cache -benchmem -count=4
9221006
func Benchmark_Cache(b *testing.B) {
9231007
app := fiber.New()

0 commit comments

Comments
 (0)