diff --git a/.github/README_ar_SA.md b/.github/README_ar_SA.md
index 7d811fc5..2ab3b33d 100644
--- a/.github/README_ar_SA.md
+++ b/.github/README_ar_SA.md
@@ -577,16 +577,17 @@ List of externally hosted middleware modules and maintained by the [Fiber team](
## 🌱 Third Party Middlewares
هذه قائمة middlewares التي تم إنشاؤها من قبل المجتمع Fiber , الرجاء إنشاءPR إذا كنت تريد أن ترى ذلك!
-- [arsmn/fiber-swagger](https://github.com/arsmn/fiber-swagger)
- [arsmn/fiber-casbin](https://github.com/arsmn/fiber-casbin)
- [arsmn/fiber-introspect](https://github.com/arsmn/fiber-introspect)
-- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
-- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
-- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
+- [arsmn/fiber-swagger](https://github.com/arsmn/fiber-swagger)
- [arsmn/gqlgen](https://github.com/arsmn/gqlgen)
-- [kiyonlin/fiber_limiter](https://github.com/kiyonlin/fiber_limiter)
-- [juandiii/go-jwk-security](https://github.com/juandiii/go-jwk-security)
+- [codemicro/fiber-cache](https://github.com/codemicro/fiber-cache)
- [itsursujit/fiber-boilerplate](https://github.com/itsursujit/fiber-boilerplate)
+- [juandiii/go-jwk-security](https://github.com/juandiii/go-jwk-security)
+- [kiyonlin/fiber_limiter](https://github.com/kiyonlin/fiber_limiter)
+- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
+- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
+- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
## 👍 مساهمة
diff --git a/.github/README_de.md b/.github/README_de.md
index 42b6824d..834f7a91 100644
--- a/.github/README_de.md
+++ b/.github/README_de.md
@@ -513,16 +513,17 @@ List of externally hosted middleware modules and maintained by the [Fiber team](
## 🌱 Third Party Middlewares
This is a list of middlewares that are created by the Fiber community, please create a PR if you want to see yours!
-- [arsmn/fiber-swagger](https://github.com/arsmn/fiber-swagger)
- [arsmn/fiber-casbin](https://github.com/arsmn/fiber-casbin)
- [arsmn/fiber-introspect](https://github.com/arsmn/fiber-introspect)
-- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
-- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
-- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
+- [arsmn/fiber-swagger](https://github.com/arsmn/fiber-swagger)
- [arsmn/gqlgen](https://github.com/arsmn/gqlgen)
-- [kiyonlin/fiber_limiter](https://github.com/kiyonlin/fiber_limiter)
-- [juandiii/go-jwk-security](https://github.com/juandiii/go-jwk-security)
+- [codemicro/fiber-cache](https://github.com/codemicro/fiber-cache)
- [itsursujit/fiber-boilerplate](https://github.com/itsursujit/fiber-boilerplate)
+- [juandiii/go-jwk-security](https://github.com/juandiii/go-jwk-security)
+- [kiyonlin/fiber_limiter](https://github.com/kiyonlin/fiber_limiter)
+- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
+- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
+- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
## 👍 Mitwirken
diff --git a/.github/README_es.md b/.github/README_es.md
index 0a6f429b..a9efea02 100644
--- a/.github/README_es.md
+++ b/.github/README_es.md
@@ -513,16 +513,17 @@ List of externally hosted middleware modules and maintained by the [Fiber team](
## 🌱 Third Party Middlewares
This is a list of middlewares that are created by the Fiber community, please create a PR if you want to see yours!
-- [arsmn/fiber-swagger](https://github.com/arsmn/fiber-swagger)
- [arsmn/fiber-casbin](https://github.com/arsmn/fiber-casbin)
- [arsmn/fiber-introspect](https://github.com/arsmn/fiber-introspect)
-- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
-- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
-- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
+- [arsmn/fiber-swagger](https://github.com/arsmn/fiber-swagger)
- [arsmn/gqlgen](https://github.com/arsmn/gqlgen)
-- [kiyonlin/fiber_limiter](https://github.com/kiyonlin/fiber_limiter)
-- [juandiii/go-jwk-security](https://github.com/juandiii/go-jwk-security)
+- [codemicro/fiber-cache](https://github.com/codemicro/fiber-cache)
- [itsursujit/fiber-boilerplate](https://github.com/itsursujit/fiber-boilerplate)
+- [juandiii/go-jwk-security](https://github.com/juandiii/go-jwk-security)
+- [kiyonlin/fiber_limiter](https://github.com/kiyonlin/fiber_limiter)
+- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
+- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
+- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
## 👍 Contribuir
diff --git a/.github/README_fr.md b/.github/README_fr.md
index 04e1fc6b..78dd95c6 100644
--- a/.github/README_fr.md
+++ b/.github/README_fr.md
@@ -513,16 +513,17 @@ List of externally hosted middleware modules and maintained by the [Fiber team](
## 🌱 Third Party Middlewares
This is a list of middlewares that are created by the Fiber community, please create a PR if you want to see yours!
-- [arsmn/fiber-swagger](https://github.com/arsmn/fiber-swagger)
- [arsmn/fiber-casbin](https://github.com/arsmn/fiber-casbin)
- [arsmn/fiber-introspect](https://github.com/arsmn/fiber-introspect)
-- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
-- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
-- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
+- [arsmn/fiber-swagger](https://github.com/arsmn/fiber-swagger)
- [arsmn/gqlgen](https://github.com/arsmn/gqlgen)
-- [kiyonlin/fiber_limiter](https://github.com/kiyonlin/fiber_limiter)
-- [juandiii/go-jwk-security](https://github.com/juandiii/go-jwk-security)
+- [codemicro/fiber-cache](https://github.com/codemicro/fiber-cache)
- [itsursujit/fiber-boilerplate](https://github.com/itsursujit/fiber-boilerplate)
+- [juandiii/go-jwk-security](https://github.com/juandiii/go-jwk-security)
+- [kiyonlin/fiber_limiter](https://github.com/kiyonlin/fiber_limiter)
+- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
+- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
+- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
## 👍 Contribuer
diff --git a/.github/README_he.md b/.github/README_he.md
index 11e28219..5aa2db6b 100644
--- a/.github/README_he.md
+++ b/.github/README_he.md
@@ -631,16 +631,17 @@ This is a list of middlewares that are created by the Fiber community, please cr
-- [arsmn/fiber-swagger](https://github.com/arsmn/fiber-swagger)
- [arsmn/fiber-casbin](https://github.com/arsmn/fiber-casbin)
- [arsmn/fiber-introspect](https://github.com/arsmn/fiber-introspect)
-- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
-- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
-- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
+- [arsmn/fiber-swagger](https://github.com/arsmn/fiber-swagger)
- [arsmn/gqlgen](https://github.com/arsmn/gqlgen)
-- [kiyonlin/fiber_limiter](https://github.com/kiyonlin/fiber_limiter)
-- [juandiii/go-jwk-security](https://github.com/juandiii/go-jwk-security)
+- [codemicro/fiber-cache](https://github.com/codemicro/fiber-cache)
- [itsursujit/fiber-boilerplate](https://github.com/itsursujit/fiber-boilerplate)
+- [juandiii/go-jwk-security](https://github.com/juandiii/go-jwk-security)
+- [kiyonlin/fiber_limiter](https://github.com/kiyonlin/fiber_limiter)
+- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
+- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
+- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
diff --git a/.github/README_id.md b/.github/README_id.md
index 3bdf94be..88454f10 100644
--- a/.github/README_id.md
+++ b/.github/README_id.md
@@ -515,16 +515,17 @@ List of externally hosted middleware modules and maintained by the [Fiber team](
## 🌱 Third Party Middlewares
This is a list of middlewares that are created by the Fiber community, please create a PR if you want to see yours!
-- [arsmn/fiber-swagger](https://github.com/arsmn/fiber-swagger)
- [arsmn/fiber-casbin](https://github.com/arsmn/fiber-casbin)
- [arsmn/fiber-introspect](https://github.com/arsmn/fiber-introspect)
-- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
-- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
-- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
+- [arsmn/fiber-swagger](https://github.com/arsmn/fiber-swagger)
- [arsmn/gqlgen](https://github.com/arsmn/gqlgen)
-- [kiyonlin/fiber_limiter](https://github.com/kiyonlin/fiber_limiter)
-- [juandiii/go-jwk-security](https://github.com/juandiii/go-jwk-security)
+- [codemicro/fiber-cache](https://github.com/codemicro/fiber-cache)
- [itsursujit/fiber-boilerplate](https://github.com/itsursujit/fiber-boilerplate)
+- [juandiii/go-jwk-security](https://github.com/juandiii/go-jwk-security)
+- [kiyonlin/fiber_limiter](https://github.com/kiyonlin/fiber_limiter)
+- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
+- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
+- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
## 👍 Berkontribusi
diff --git a/.github/README_ja.md b/.github/README_ja.md
index 57b9889b..ace64b4e 100644
--- a/.github/README_ja.md
+++ b/.github/README_ja.md
@@ -516,16 +516,17 @@ List of externally hosted middleware modules and maintained by the [Fiber team](
## 🌱 Third Party Middlewares
This is a list of middlewares that are created by the Fiber community, please create a PR if you want to see yours!
-- [arsmn/fiber-swagger](https://github.com/arsmn/fiber-swagger)
- [arsmn/fiber-casbin](https://github.com/arsmn/fiber-casbin)
- [arsmn/fiber-introspect](https://github.com/arsmn/fiber-introspect)
-- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
-- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
-- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
+- [arsmn/fiber-swagger](https://github.com/arsmn/fiber-swagger)
- [arsmn/gqlgen](https://github.com/arsmn/gqlgen)
-- [kiyonlin/fiber_limiter](https://github.com/kiyonlin/fiber_limiter)
-- [juandiii/go-jwk-security](https://github.com/juandiii/go-jwk-security)
+- [codemicro/fiber-cache](https://github.com/codemicro/fiber-cache)
- [itsursujit/fiber-boilerplate](https://github.com/itsursujit/fiber-boilerplate)
+- [juandiii/go-jwk-security](https://github.com/juandiii/go-jwk-security)
+- [kiyonlin/fiber_limiter](https://github.com/kiyonlin/fiber_limiter)
+- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
+- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
+- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
## 👍 貢献する
diff --git a/.github/README_ko.md b/.github/README_ko.md
index 3bc581cd..27d2d68f 100644
--- a/.github/README_ko.md
+++ b/.github/README_ko.md
@@ -518,16 +518,17 @@ List of externally hosted middleware modules and maintained by the [Fiber team](
## 🌱 Third Party Middlewares
This is a list of middlewares that are created by the Fiber community, please create a PR if you want to see yours!
-- [arsmn/fiber-swagger](https://github.com/arsmn/fiber-swagger)
- [arsmn/fiber-casbin](https://github.com/arsmn/fiber-casbin)
- [arsmn/fiber-introspect](https://github.com/arsmn/fiber-introspect)
-- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
-- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
-- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
+- [arsmn/fiber-swagger](https://github.com/arsmn/fiber-swagger)
- [arsmn/gqlgen](https://github.com/arsmn/gqlgen)
-- [kiyonlin/fiber_limiter](https://github.com/kiyonlin/fiber_limiter)
-- [juandiii/go-jwk-security](https://github.com/juandiii/go-jwk-security)
+- [codemicro/fiber-cache](https://github.com/codemicro/fiber-cache)
- [itsursujit/fiber-boilerplate](https://github.com/itsursujit/fiber-boilerplate)
+- [juandiii/go-jwk-security](https://github.com/juandiii/go-jwk-security)
+- [kiyonlin/fiber_limiter](https://github.com/kiyonlin/fiber_limiter)
+- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
+- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
+- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
## 👍 기여
diff --git a/.github/README_nl.md b/.github/README_nl.md
index 656c46cb..ea7229d4 100644
--- a/.github/README_nl.md
+++ b/.github/README_nl.md
@@ -517,17 +517,17 @@ List of externally hosted middleware modules and maintained by the [Fiber team](
## 🌱 Third Party Middlewares
This is a list of middlewares that are created by the Fiber community, please create a PR if you want to see yours!
-- [arsmn/fiber-swagger](https://github.com/arsmn/fiber-swagger)
- [arsmn/fiber-casbin](https://github.com/arsmn/fiber-casbin)
- [arsmn/fiber-introspect](https://github.com/arsmn/fiber-introspect)
-- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
-- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
-- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
+- [arsmn/fiber-swagger](https://github.com/arsmn/fiber-swagger)
- [arsmn/gqlgen](https://github.com/arsmn/gqlgen)
-- [kiyonlin/fiber_limiter](https://github.com/kiyonlin/fiber_limiter)
-- [juandiii/go-jwk-security](https://github.com/juandiii/go-jwk-security)
+- [codemicro/fiber-cache](https://github.com/codemicro/fiber-cache)
- [itsursujit/fiber-boilerplate](https://github.com/itsursujit/fiber-boilerplate)
-
+- [juandiii/go-jwk-security](https://github.com/juandiii/go-jwk-security)
+- [kiyonlin/fiber_limiter](https://github.com/kiyonlin/fiber_limiter)
+- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
+- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
+- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
## 👍 Bijdragen
Om de actieve ontwikkelingen van `Fiber` te ondersteunen of om een **bedankje** te geven:
diff --git a/.github/README_pt.md b/.github/README_pt.md
index effdc33d..cfd77a0d 100644
--- a/.github/README_pt.md
+++ b/.github/README_pt.md
@@ -511,16 +511,17 @@ List of externally hosted middleware modules and maintained by the [Fiber team](
## 🌱 Middlewares Third Party
Esta é uma lista de middlewares criados pela comunidade do Fiber, se quiser ter o seu middleware aqui, é só abrir um PR!
-- [arsmn/fiber-swagger](https://github.com/arsmn/fiber-swagger)
- [arsmn/fiber-casbin](https://github.com/arsmn/fiber-casbin)
- [arsmn/fiber-introspect](https://github.com/arsmn/fiber-introspect)
-- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
-- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
-- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
+- [arsmn/fiber-swagger](https://github.com/arsmn/fiber-swagger)
- [arsmn/gqlgen](https://github.com/arsmn/gqlgen)
-- [kiyonlin/fiber_limiter](https://github.com/kiyonlin/fiber_limiter)
-- [juandiii/go-jwk-security](https://github.com/juandiii/go-jwk-security)
+- [codemicro/fiber-cache](https://github.com/codemicro/fiber-cache)
- [itsursujit/fiber-boilerplate](https://github.com/itsursujit/fiber-boilerplate)
+- [juandiii/go-jwk-security](https://github.com/juandiii/go-jwk-security)
+- [kiyonlin/fiber_limiter](https://github.com/kiyonlin/fiber_limiter)
+- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
+- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
+- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
## 👍 Contribuindo
diff --git a/.github/README_ru.md b/.github/README_ru.md
index 68b0449d..49a16102 100644
--- a/.github/README_ru.md
+++ b/.github/README_ru.md
@@ -516,16 +516,17 @@ List of externally hosted middleware modules and maintained by the [Fiber team](
Это список middlewares, созданных сообществом Fiber. Пожалуйста, [создайте PR](https://github.com/gofiber/fiber/pulls), если хотите добавить в этот список свой или известный вам middleware для веб фреймворка Fiber!
-- [arsmn/fiber-swagger](https://github.com/arsmn/fiber-swagger)
- [arsmn/fiber-casbin](https://github.com/arsmn/fiber-casbin)
- [arsmn/fiber-introspect](https://github.com/arsmn/fiber-introspect)
-- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
-- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
-- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
+- [arsmn/fiber-swagger](https://github.com/arsmn/fiber-swagger)
- [arsmn/gqlgen](https://github.com/arsmn/gqlgen)
-- [kiyonlin/fiber_limiter](https://github.com/kiyonlin/fiber_limiter)
-- [juandiii/go-jwk-security](https://github.com/juandiii/go-jwk-security)
+- [codemicro/fiber-cache](https://github.com/codemicro/fiber-cache)
- [itsursujit/fiber-boilerplate](https://github.com/itsursujit/fiber-boilerplate)
+- [juandiii/go-jwk-security](https://github.com/juandiii/go-jwk-security)
+- [kiyonlin/fiber_limiter](https://github.com/kiyonlin/fiber_limiter)
+- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
+- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
+- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
## 👍 Помощь проекту
diff --git a/.github/README_tr.md b/.github/README_tr.md
index 99da4997..76cb8424 100644
--- a/.github/README_tr.md
+++ b/.github/README_tr.md
@@ -510,16 +510,17 @@ List of externally hosted middleware modules and maintained by the [Fiber team](
## 🌱 Third Party Middlewares
This is a list of middlewares that are created by the Fiber community, please create a PR if you want to see yours!
-- [arsmn/fiber-swagger](https://github.com/arsmn/fiber-swagger)
- [arsmn/fiber-casbin](https://github.com/arsmn/fiber-casbin)
- [arsmn/fiber-introspect](https://github.com/arsmn/fiber-introspect)
-- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
-- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
-- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
+- [arsmn/fiber-swagger](https://github.com/arsmn/fiber-swagger)
- [arsmn/gqlgen](https://github.com/arsmn/gqlgen)
-- [kiyonlin/fiber_limiter](https://github.com/kiyonlin/fiber_limiter)
-- [juandiii/go-jwk-security](https://github.com/juandiii/go-jwk-security)
+- [codemicro/fiber-cache](https://github.com/codemicro/fiber-cache)
- [itsursujit/fiber-boilerplate](https://github.com/itsursujit/fiber-boilerplate)
+- [juandiii/go-jwk-security](https://github.com/juandiii/go-jwk-security)
+- [kiyonlin/fiber_limiter](https://github.com/kiyonlin/fiber_limiter)
+- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
+- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
+- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
## 👍 Destek
diff --git a/.github/README_zh-CN.md b/.github/README_zh-CN.md
index 0dc3d718..58c03363 100644
--- a/.github/README_zh-CN.md
+++ b/.github/README_zh-CN.md
@@ -515,16 +515,17 @@ List of externally hosted middleware modules and maintained by the [Fiber team](
## 🌱 第三方中间件
这是由`Fiber`社区创建的中间件列表,如果您想看到自己的中间件,请创建`PR`。
-- [arsmn/fiber-swagger](https://github.com/arsmn/fiber-swagger)
- [arsmn/fiber-casbin](https://github.com/arsmn/fiber-casbin)
- [arsmn/fiber-introspect](https://github.com/arsmn/fiber-introspect)
-- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
-- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
-- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
+- [arsmn/fiber-swagger](https://github.com/arsmn/fiber-swagger)
- [arsmn/gqlgen](https://github.com/arsmn/gqlgen)
-- [kiyonlin/fiber_limiter](https://github.com/kiyonlin/fiber_limiter)
-- [juandiii/go-jwk-security](https://github.com/juandiii/go-jwk-security)
+- [codemicro/fiber-cache](https://github.com/codemicro/fiber-cache)
- [itsursujit/fiber-boilerplate](https://github.com/itsursujit/fiber-boilerplate)
+- [juandiii/go-jwk-security](https://github.com/juandiii/go-jwk-security)
+- [kiyonlin/fiber_limiter](https://github.com/kiyonlin/fiber_limiter)
+- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
+- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
+- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
## 👍 贡献
diff --git a/.github/README_zh-TW.md b/.github/README_zh-TW.md
index 7f805603..78c6d7e1 100644
--- a/.github/README_zh-TW.md
+++ b/.github/README_zh-TW.md
@@ -514,16 +514,17 @@ List of externally hosted middleware modules and maintained by the [Fiber team](
由社群建立的中介器列表,要新增請發PR!
-- [arsmn/fiber-swagger](https://github.com/arsmn/fiber-swagger)
- [arsmn/fiber-casbin](https://github.com/arsmn/fiber-casbin)
- [arsmn/fiber-introspect](https://github.com/arsmn/fiber-introspect)
-- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
-- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
-- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
+- [arsmn/fiber-swagger](https://github.com/arsmn/fiber-swagger)
- [arsmn/gqlgen](https://github.com/arsmn/gqlgen)
-- [kiyonlin/fiber_limiter](https://github.com/kiyonlin/fiber_limiter)
-- [juandiii/go-jwk-security](https://github.com/juandiii/go-jwk-security)
+- [codemicro/fiber-cache](https://github.com/codemicro/fiber-cache)
- [itsursujit/fiber-boilerplate](https://github.com/itsursujit/fiber-boilerplate)
+- [juandiii/go-jwk-security](https://github.com/juandiii/go-jwk-security)
+- [kiyonlin/fiber_limiter](https://github.com/kiyonlin/fiber_limiter)
+- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
+- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
+- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
## 👍 貢獻
diff --git a/app.go b/app.go
index 478208f7..2e1daa11 100644
--- a/app.go
+++ b/app.go
@@ -706,9 +706,9 @@ func (app *App) startupMessage(addr string, tls bool, pids string) {
addr = "https://" + host + ":" + port
}
- isPrefork := "disabled"
+ isPrefork := "Disabled"
if app.config.Prefork {
- isPrefork = "enabled"
+ isPrefork = "Enabled"
}
out := colorable.NewColorableStdout()
diff --git a/app_test.go b/app_test.go
index 853c92fe..4150bd33 100644
--- a/app_test.go
+++ b/app_test.go
@@ -433,15 +433,29 @@ func Test_App_New(t *testing.T) {
appConfig.Get("/", testEmptyHandler)
}
-func Test_App_Shutdown(t *testing.T) {
+func Test_App_Config(t *testing.T) {
app := New(Config{
DisableStartupMessage: true,
})
- if err := app.Shutdown(); err != nil {
- if err.Error() != "shutdown: server is not running" {
- t.Fatal()
+ utils.AssertEqual(t, true, app.Config().DisableStartupMessage)
+}
+
+func Test_App_Shutdown(t *testing.T) {
+ t.Run("success", func(t *testing.T) {
+ app := New(Config{
+ DisableStartupMessage: true,
+ })
+ utils.AssertEqual(t, true, app.Shutdown() == nil)
+ })
+
+ t.Run("no server", func(t *testing.T) {
+ app := &App{}
+ if err := app.Shutdown(); err != nil {
+ if err.Error() != "shutdown: server is not running" {
+ t.Fatal()
+ }
}
- }
+ })
}
// go test -run Test_App_Static_Index_Default
@@ -750,7 +764,9 @@ func Test_App_Next_Method(t *testing.T) {
// go test -run Test_App_Listen
func Test_App_Listen(t *testing.T) {
- app := New()
+ app := New(Config{DisableStartupMessage: true})
+
+ utils.AssertEqual(t, false, app.Listen(":99999") == nil)
go func() {
time.Sleep(1000 * time.Millisecond)
@@ -758,13 +774,6 @@ func Test_App_Listen(t *testing.T) {
}()
utils.AssertEqual(t, nil, app.Listen(":4003"))
-
- go func() {
- time.Sleep(1000 * time.Millisecond)
- utils.AssertEqual(t, nil, app.Shutdown())
- }()
-
- utils.AssertEqual(t, nil, app.Listen(":4010"))
}
// go test -run Test_App_Listener
@@ -990,3 +999,8 @@ func Test_App_SmallReadBuffer(t *testing.T) {
utils.AssertEqual(t, nil, app.Listen(":4006"))
}
+
+func Test_App_Master_Process_Show_Startup_Message(t *testing.T) {
+ New(Config{Prefork: true}).
+ startupMessage(":3000", true, "")
+}
diff --git a/helpers_test.go b/helpers_test.go
index d965e70d..87d2a9d9 100644
--- a/helpers_test.go
+++ b/helpers_test.go
@@ -5,7 +5,9 @@
package fiber
import (
+ "crypto/tls"
"fmt"
+ "net"
"testing"
"time"
@@ -300,3 +302,45 @@ func Benchmark_Utils_IsNoCache(b *testing.B) {
}
utils.AssertEqual(b, true, ok)
}
+
+func Test_Utils_lnMetadata(t *testing.T) {
+ t.Run("closed listen", func(t *testing.T) {
+ ln, err := net.Listen("tcp", ":0")
+ utils.AssertEqual(t, nil, err)
+
+ utils.AssertEqual(t, nil, ln.Close())
+
+ addr, config := lnMetadata(ln)
+
+ utils.AssertEqual(t, ln.Addr().String(), addr)
+ utils.AssertEqual(t, true, config == nil)
+ })
+
+ t.Run("non tls", func(t *testing.T) {
+ ln, err := net.Listen("tcp", ":0")
+
+ utils.AssertEqual(t, nil, err)
+
+ addr, config := lnMetadata(ln)
+
+ utils.AssertEqual(t, ln.Addr().String(), addr)
+ utils.AssertEqual(t, true, config == nil)
+ })
+
+ t.Run("tls", func(t *testing.T) {
+ cer, err := tls.LoadX509KeyPair("./.github/testdata/ssl.pem", "./.github/testdata/ssl.key")
+ utils.AssertEqual(t, nil, err)
+
+ config := &tls.Config{Certificates: []tls.Certificate{cer}}
+
+ ln, err := net.Listen("tcp4", ":0")
+ utils.AssertEqual(t, nil, err)
+
+ ln = tls.NewListener(ln, config)
+
+ addr, config := lnMetadata(ln)
+
+ utils.AssertEqual(t, ln.Addr().String(), addr)
+ utils.AssertEqual(t, true, config != nil)
+ })
+}
diff --git a/middleware/basicauth/basicauth_test.go b/middleware/basicauth/basicauth_test.go
index 2becceae..00c00567 100644
--- a/middleware/basicauth/basicauth_test.go
+++ b/middleware/basicauth/basicauth_test.go
@@ -12,6 +12,22 @@ import (
"github.com/gofiber/fiber/v2/utils"
)
+// go test -run Test_BasicAuth_Next
+func Test_BasicAuth_Next(t *testing.T) {
+ app := fiber.New(fiber.Config{
+ DisableStartupMessage: true,
+ })
+ app.Use(New(Config{
+ Next: func(_ *fiber.Ctx) bool {
+ return true
+ },
+ }))
+
+ resp, err := app.Test(httptest.NewRequest("GET", "/", nil))
+ utils.AssertEqual(t, nil, err)
+ utils.AssertEqual(t, fiber.StatusNotFound, resp.StatusCode)
+}
+
func Test_Middleware_BasicAuth(t *testing.T) {
app := fiber.New()
diff --git a/middleware/compress/compress.go b/middleware/compress/compress.go
index 05f7d21e..c9553d3a 100644
--- a/middleware/compress/compress.go
+++ b/middleware/compress/compress.go
@@ -46,9 +46,6 @@ func New(config ...Config) fiber.Handler {
cfg = config[0]
// Set default values
- if cfg.Next == nil {
- cfg.Next = ConfigDefault.Next
- }
if cfg.Level < -1 || cfg.Level > 2 {
cfg.Level = ConfigDefault.Level
}
@@ -62,13 +59,13 @@ func New(config ...Config) fiber.Handler {
// Setup compression algorithm
switch cfg.Level {
- case 0:
+ case LevelDefault:
// LevelDefault
compressor = fasthttp.CompressHandlerBrotliLevel(fctx, fasthttp.CompressBrotliDefaultCompression, fasthttp.CompressDefaultCompression)
- case 1:
+ case LevelBestSpeed:
// LevelBestSpeed
compressor = fasthttp.CompressHandlerBrotliLevel(fctx, fasthttp.CompressBrotliBestSpeed, fasthttp.CompressBestSpeed)
- case 2:
+ case LevelBestCompression:
// LevelBestCompression
compressor = fasthttp.CompressHandlerBrotliLevel(fctx, fasthttp.CompressBrotliBestCompression, fasthttp.CompressBestCompression)
default:
diff --git a/middleware/compress/compress_test.go b/middleware/compress/compress_test.go
index 66aa64f5..6e3032fc 100644
--- a/middleware/compress/compress_test.go
+++ b/middleware/compress/compress_test.go
@@ -1,6 +1,8 @@
package compress
import (
+ "errors"
+ "fmt"
"io/ioutil"
"net/http/httptest"
"testing"
@@ -19,7 +21,7 @@ func init() {
filedata = dat
}
-// go test -run Test_Compress
+// go test -run Test_Compress_Gzip
func Test_Compress_Gzip(t *testing.T) {
app := fiber.New()
@@ -40,12 +42,33 @@ func Test_Compress_Gzip(t *testing.T) {
// Validate the file size is shrinked
body, err := ioutil.ReadAll(resp.Body)
- if err != nil {
- utils.AssertEqual(t, nil, err)
- }
+ utils.AssertEqual(t, nil, err)
utils.AssertEqual(t, true, len(body) < len(filedata))
}
+// go test -run Test_Compress_Different_Level
+func Test_Compress_Different_Level(t *testing.T) {
+ levels := []int{LevelBestSpeed, LevelBestCompression, 10}
+ for _, level := range levels {
+ t.Run(fmt.Sprintf("level %d", level), func(t *testing.T) {
+ app := fiber.New()
+
+ app.Use(New(Config{Level: level}))
+
+ app.Get("/", func(c *fiber.Ctx) error {
+ c.Set(fiber.HeaderContentType, fiber.MIMETextPlainCharsetUTF8)
+ return c.Send(filedata)
+ })
+
+ req := httptest.NewRequest("GET", "/", nil)
+
+ resp, err := app.Test(req)
+ utils.AssertEqual(t, nil, err, "app.Test(req)")
+ utils.AssertEqual(t, 200, resp.StatusCode, "Status code")
+ })
+ }
+}
+
func Test_Compress_Deflate(t *testing.T) {
app := fiber.New()
@@ -65,9 +88,7 @@ func Test_Compress_Deflate(t *testing.T) {
// Validate the file size is shrinked
body, err := ioutil.ReadAll(resp.Body)
- if err != nil {
- utils.AssertEqual(t, nil, err)
- }
+ utils.AssertEqual(t, nil, err)
utils.AssertEqual(t, true, len(body) < len(filedata))
}
@@ -83,15 +104,74 @@ func Test_Compress_Brotli(t *testing.T) {
req := httptest.NewRequest("GET", "/", nil)
req.Header.Set("Accept-Encoding", "br")
- resp, err := app.Test(req)
+ resp, err := app.Test(req, 10000)
utils.AssertEqual(t, nil, err, "app.Test(req)")
utils.AssertEqual(t, 200, resp.StatusCode, "Status code")
utils.AssertEqual(t, "br", resp.Header.Get(fiber.HeaderContentEncoding))
// Validate the file size is shrinked
body, err := ioutil.ReadAll(resp.Body)
- if err != nil {
- utils.AssertEqual(t, nil, err)
- }
+ utils.AssertEqual(t, nil, err)
utils.AssertEqual(t, true, len(body) < len(filedata))
}
+
+func Test_Compress_Disabled(t *testing.T) {
+ app := fiber.New()
+
+ app.Use(New(Config{Level: LevelDisabled}))
+
+ app.Get("/", func(c *fiber.Ctx) error {
+ return c.Send(filedata)
+ })
+
+ req := httptest.NewRequest("GET", "/", nil)
+ req.Header.Set("Accept-Encoding", "br")
+
+ resp, err := app.Test(req)
+ utils.AssertEqual(t, nil, err, "app.Test(req)")
+ utils.AssertEqual(t, 200, resp.StatusCode, "Status code")
+ utils.AssertEqual(t, "", resp.Header.Get(fiber.HeaderContentEncoding))
+
+ // Validate the file size is not shrinked
+ body, err := ioutil.ReadAll(resp.Body)
+ utils.AssertEqual(t, nil, err)
+ utils.AssertEqual(t, true, len(body) == len(filedata))
+}
+
+func Test_Compress_Next_Error(t *testing.T) {
+ app := fiber.New()
+
+ app.Use(New())
+
+ app.Get("/", func(c *fiber.Ctx) error {
+ return errors.New("next error")
+ })
+
+ req := httptest.NewRequest("GET", "/", nil)
+ req.Header.Set("Accept-Encoding", "gzip")
+
+ resp, err := app.Test(req)
+ utils.AssertEqual(t, nil, err, "app.Test(req)")
+ utils.AssertEqual(t, 500, resp.StatusCode, "Status code")
+ utils.AssertEqual(t, "", resp.Header.Get(fiber.HeaderContentEncoding))
+
+ body, err := ioutil.ReadAll(resp.Body)
+ utils.AssertEqual(t, nil, err)
+ utils.AssertEqual(t, "next error", string(body))
+}
+
+// go test -run Test_Compress_Next
+func Test_Compress_Next(t *testing.T) {
+ app := fiber.New(fiber.Config{
+ DisableStartupMessage: true,
+ })
+ app.Use(New(Config{
+ Next: func(_ *fiber.Ctx) bool {
+ return true
+ },
+ }))
+
+ resp, err := app.Test(httptest.NewRequest("GET", "/", nil))
+ utils.AssertEqual(t, nil, err)
+ utils.AssertEqual(t, fiber.StatusNotFound, resp.StatusCode)
+}
diff --git a/middleware/cors/cors.go b/middleware/cors/cors.go
index cb69fd55..60a93fa4 100644
--- a/middleware/cors/cors.go
+++ b/middleware/cors/cors.go
@@ -81,15 +81,12 @@ func New(config ...Config) fiber.Handler {
cfg = config[0]
// Set default values
- if cfg.Next == nil {
- cfg.Next = ConfigDefault.Next
+ if cfg.AllowMethods == "" {
+ cfg.AllowMethods = ConfigDefault.AllowMethods
}
if cfg.AllowOrigins == "" {
cfg.AllowOrigins = ConfigDefault.AllowOrigins
}
- if cfg.AllowMethods == "" {
- cfg.AllowMethods = ConfigDefault.AllowMethods
- }
}
// Convert string to slice
diff --git a/middleware/cors/cors_test.go b/middleware/cors/cors_test.go
index 1f7081b1..2b57a5ff 100644
--- a/middleware/cors/cors_test.go
+++ b/middleware/cors/cors_test.go
@@ -1,6 +1,7 @@
package cors
import (
+ "net/http/httptest"
"testing"
"github.com/gofiber/fiber/v2"
@@ -12,6 +13,17 @@ func Test_CORS_Defaults(t *testing.T) {
app := fiber.New()
app.Use(New())
+ testDefaultOrEmptyConfig(t, app)
+}
+
+func Test_CORS_Empty_Config(t *testing.T) {
+ app := fiber.New()
+ app.Use(New(Config{}))
+
+ testDefaultOrEmptyConfig(t, app)
+}
+
+func testDefaultOrEmptyConfig(t *testing.T, app *fiber.App) {
h := app.Handler()
// Test default GET response headers
@@ -41,7 +53,13 @@ func Test_CORS_Wildcard(t *testing.T) {
handler := app.Handler()
// OPTIONS (preflight) response headers when AllowOrigins is *
- app.Use(New(Config{AllowOrigins: "*", AllowCredentials: true, MaxAge: 3600}))
+ app.Use(New(Config{
+ AllowOrigins: "*",
+ AllowCredentials: true,
+ MaxAge: 3600,
+ ExposeHeaders: "X-Request-ID",
+ AllowHeaders: "Authentication",
+ }))
// Make request
ctx := &fasthttp.RequestCtx{}
@@ -56,6 +74,16 @@ func Test_CORS_Wildcard(t *testing.T) {
utils.AssertEqual(t, "localhost", string(ctx.Response.Header.Peek(fiber.HeaderAccessControlAllowOrigin)))
utils.AssertEqual(t, "true", string(ctx.Response.Header.Peek(fiber.HeaderAccessControlAllowCredentials)))
utils.AssertEqual(t, "3600", string(ctx.Response.Header.Peek(fiber.HeaderAccessControlMaxAge)))
+ utils.AssertEqual(t, "Authentication", string(ctx.Response.Header.Peek(fiber.HeaderAccessControlAllowHeaders)))
+
+ // Test non OPTIONS (preflight) response headers
+ ctx = &fasthttp.RequestCtx{}
+ ctx.Request.Header.SetMethod(fiber.MethodGet)
+ handler(ctx)
+
+ utils.AssertEqual(t, "true", string(ctx.Response.Header.Peek(fiber.HeaderAccessControlAllowCredentials)))
+ utils.AssertEqual(t, "X-Request-ID", string(ctx.Response.Header.Peek(fiber.HeaderAccessControlExposeHeaders)))
+
}
// go test -run -v Test_CORS_Subdomain
@@ -193,3 +221,19 @@ func Test_CORS_AllowOriginScheme(t *testing.T) {
}
}
}
+
+// go test -run Test_CORS_Next
+func Test_CORS_Next(t *testing.T) {
+ app := fiber.New(fiber.Config{
+ DisableStartupMessage: true,
+ })
+ app.Use(New(Config{
+ Next: func(_ *fiber.Ctx) bool {
+ return true
+ },
+ }))
+
+ resp, err := app.Test(httptest.NewRequest("GET", "/", nil))
+ utils.AssertEqual(t, nil, err)
+ utils.AssertEqual(t, fiber.StatusNotFound, resp.StatusCode)
+}
diff --git a/middleware/csrf/csrf.go b/middleware/csrf/csrf.go
index ad03ef46..9c822b10 100644
--- a/middleware/csrf/csrf.go
+++ b/middleware/csrf/csrf.go
@@ -85,6 +85,10 @@ func New(config ...Config) fiber.Handler {
// Generate the correct extractor to get the token from the correct location
selectors := strings.Split(cfg.TokenLookup, ":")
+ if len(selectors) != 2 {
+ panic("csrf: Token lookup must in the form of :")
+ }
+
// By default we extract from a header
extractor := csrfFromHeader(selectors[1])
@@ -169,7 +173,7 @@ func csrfFromHeader(param string) func(c *fiber.Ctx) (string, error) {
}
}
-// csrfcsrfFromQuery returns a function that extracts token from the query string.
+// csrfFromQuery returns a function that extracts token from the query string.
func csrfFromQuery(param string) func(c *fiber.Ctx) (string, error) {
return func(c *fiber.Ctx) (string, error) {
token := c.Query(param)
diff --git a/middleware/csrf/csrf_test.go b/middleware/csrf/csrf_test.go
index 79b6a085..6a4739a8 100644
--- a/middleware/csrf/csrf_test.go
+++ b/middleware/csrf/csrf_test.go
@@ -1,6 +1,7 @@
package csrf
import (
+ "net/http/httptest"
"strings"
"testing"
@@ -51,3 +52,114 @@ func Test_CSRF(t *testing.T) {
h(ctx)
utils.AssertEqual(t, 200, ctx.Response.StatusCode())
}
+
+// go test -run Test_CSRF_Next
+func Test_CSRF_Next(t *testing.T) {
+ app := fiber.New(fiber.Config{
+ DisableStartupMessage: true,
+ })
+ app.Use(New(Config{
+ Next: func(_ *fiber.Ctx) bool {
+ return true
+ },
+ }))
+
+ resp, err := app.Test(httptest.NewRequest("GET", "/", nil))
+ utils.AssertEqual(t, nil, err)
+ utils.AssertEqual(t, fiber.StatusNotFound, resp.StatusCode)
+}
+
+func Test_CSRF_Invalid_TokenLookup(t *testing.T) {
+ defer func() {
+ utils.AssertEqual(t, "csrf: Token lookup must in the form of :", recover())
+ }()
+ app := fiber.New()
+
+ app.Use(New(Config{TokenLookup: "I:am:invalid"}))
+
+ app.Post("/", func(c *fiber.Ctx) error {
+ return c.SendStatus(fiber.StatusOK)
+ })
+
+ h := app.Handler()
+ ctx := &fasthttp.RequestCtx{}
+ ctx.Request.Header.SetMethod("GET")
+ h(ctx)
+}
+
+func Test_CSRF_From_Form(t *testing.T) {
+ app := fiber.New()
+
+ app.Use(New(Config{TokenLookup: "form:_csrf"}))
+
+ app.Post("/", func(c *fiber.Ctx) error {
+ return c.SendStatus(fiber.StatusOK)
+ })
+
+ h := app.Handler()
+ ctx := &fasthttp.RequestCtx{}
+
+ // Valid CSRF token
+ token := utils.UUID()
+ ctx.Request.Header.SetMethod("POST")
+ ctx.Request.Header.Set(fiber.HeaderCookie, "_csrf="+token)
+ ctx.Request.Header.Set(fiber.HeaderContentType, fiber.MIMEApplicationForm)
+ h(ctx)
+ utils.AssertEqual(t, 403, ctx.Response.StatusCode())
+
+ ctx.Request.Reset()
+ ctx.Request.Header.SetMethod("POST")
+ ctx.Request.Header.Set(fiber.HeaderCookie, "_csrf="+token)
+ ctx.Request.Header.Set(fiber.HeaderContentType, fiber.MIMEApplicationForm)
+ ctx.Request.SetBodyString("_csrf=" + token)
+ h(ctx)
+ utils.AssertEqual(t, 200, ctx.Response.StatusCode())
+}
+
+func Test_CSRF_From_Query(t *testing.T) {
+ app := fiber.New()
+
+ app.Use(New(Config{TokenLookup: "query:_csrf"}))
+
+ app.Post("/", func(c *fiber.Ctx) error {
+ return c.SendStatus(fiber.StatusOK)
+ })
+
+ h := app.Handler()
+ ctx := &fasthttp.RequestCtx{}
+
+ // Valid CSRF token
+ token := utils.UUID()
+ ctx.Request.Header.SetMethod("POST")
+ ctx.Request.Header.Set(fiber.HeaderCookie, "_csrf="+token)
+ ctx.Request.SetRequestURI("/?_csrf=" + token)
+ h(ctx)
+ utils.AssertEqual(t, 200, ctx.Response.StatusCode())
+
+ ctx.Request.SetRequestURI("/")
+ ctx.Response.Reset()
+ h(ctx)
+ utils.AssertEqual(t, 403, ctx.Response.StatusCode())
+ utils.AssertEqual(t, "Forbidden", string(ctx.Response.Body()))
+}
+
+func Test_CSRF_From_Param(t *testing.T) {
+ app := fiber.New()
+
+ csrfGroup := app.Group("/:csrf", New(Config{TokenLookup: "param:csrf"}))
+
+ csrfGroup.Post("/", func(c *fiber.Ctx) error {
+ return c.SendStatus(fiber.StatusOK)
+ })
+
+ h := app.Handler()
+ ctx := &fasthttp.RequestCtx{}
+
+ // Valid CSRF token
+ token := utils.UUID()
+ ctx.Request.Header.SetMethod("POST")
+ ctx.Request.Header.Set(fiber.HeaderCookie, "_csrf="+token)
+ ctx.Request.SetRequestURI("/" + token)
+ h(ctx)
+ utils.AssertEqual(t, 200, ctx.Response.StatusCode())
+}
diff --git a/middleware/favicon/favicon_test.go b/middleware/favicon/favicon_test.go
index 78cf63a4..6803593c 100644
--- a/middleware/favicon/favicon_test.go
+++ b/middleware/favicon/favicon_test.go
@@ -88,3 +88,19 @@ func Benchmark_Middleware_Favicon(b *testing.B) {
handler(c)
}
}
+
+// go test -run Test_Favicon_Next
+func Test_Favicon_Next(t *testing.T) {
+ app := fiber.New(fiber.Config{
+ DisableStartupMessage: true,
+ })
+ app.Use(New(Config{
+ Next: func(_ *fiber.Ctx) bool {
+ return true
+ },
+ }))
+
+ resp, err := app.Test(httptest.NewRequest("GET", "/", nil))
+ utils.AssertEqual(t, nil, err)
+ utils.AssertEqual(t, fiber.StatusNotFound, resp.StatusCode)
+}
diff --git a/middleware/filesystem/filesystem.go b/middleware/filesystem/filesystem.go
index f4f3f435..3c1414d6 100644
--- a/middleware/filesystem/filesystem.go
+++ b/middleware/filesystem/filesystem.go
@@ -1,7 +1,6 @@
package filesystem
import (
- "log"
"net/http"
"os"
"strings"
@@ -62,8 +61,11 @@ func New(config Config) fiber.Handler {
if !strings.HasPrefix(cfg.Index, "/") {
cfg.Index = "/" + cfg.Index
}
+ if cfg.NotFoundFile != "" && !strings.HasPrefix(cfg.NotFoundFile, "/") {
+ cfg.NotFoundFile = "/" + cfg.NotFoundFile
+ }
if cfg.Root == nil {
- log.Fatal("filesystem: Root cannot be nil")
+ panic("filesystem: Root cannot be nil")
}
var once sync.Once
diff --git a/middleware/filesystem/filesystem_test.go b/middleware/filesystem/filesystem_test.go
index 7c0661a4..bda939a1 100644
--- a/middleware/filesystem/filesystem_test.go
+++ b/middleware/filesystem/filesystem_test.go
@@ -2,6 +2,7 @@ package filesystem
import (
"net/http"
+ "net/http/httptest"
"testing"
"github.com/gofiber/fiber/v2"
@@ -110,3 +111,20 @@ func Test_FileSystem(t *testing.T) {
})
}
}
+
+// go test -run Test_FileSystem_Next
+func Test_FileSystem_Next(t *testing.T) {
+ app := fiber.New(fiber.Config{
+ DisableStartupMessage: true,
+ })
+ app.Use(New(Config{
+ Root: http.Dir("../../.github/testdata/fs"),
+ Next: func(_ *fiber.Ctx) bool {
+ return true
+ },
+ }))
+
+ resp, err := app.Test(httptest.NewRequest("GET", "/", nil))
+ utils.AssertEqual(t, nil, err)
+ utils.AssertEqual(t, fiber.StatusNotFound, resp.StatusCode)
+}
diff --git a/middleware/limiter/limiter_test.go b/middleware/limiter/limiter_test.go
index fe336aa3..ebb2fe35 100644
--- a/middleware/limiter/limiter_test.go
+++ b/middleware/limiter/limiter_test.go
@@ -88,3 +88,19 @@ func Benchmark_Limiter(b *testing.B) {
utils.AssertEqual(b, "100", string(fctx.Response.Header.Peek("X-RateLimit-Limit")))
}
+
+// go test -run Test_Limiter_Next
+func Test_Limiter_Next(t *testing.T) {
+ app := fiber.New(fiber.Config{
+ DisableStartupMessage: true,
+ })
+ app.Use(New(Config{
+ Next: func(_ *fiber.Ctx) bool {
+ return true
+ },
+ }))
+
+ resp, err := app.Test(httptest.NewRequest("GET", "/", nil))
+ utils.AssertEqual(t, nil, err)
+ utils.AssertEqual(t, fiber.StatusNotFound, resp.StatusCode)
+}
diff --git a/middleware/logger/logger__test.go b/middleware/logger/logger__test.go
index 1bb797c8..7c3052f7 100644
--- a/middleware/logger/logger__test.go
+++ b/middleware/logger/logger__test.go
@@ -31,3 +31,19 @@ func Test_Logger(t *testing.T) {
utils.AssertEqual(t, fiber.StatusInternalServerError, resp.StatusCode)
utils.AssertEqual(t, "some random error", buf.String())
}
+
+// go test -run Test_Logger_Next
+func Test_Logger_Next(t *testing.T) {
+ app := fiber.New(fiber.Config{
+ DisableStartupMessage: true,
+ })
+ app.Use(New(Config{
+ Next: func(_ *fiber.Ctx) bool {
+ return true
+ },
+ }))
+
+ resp, err := app.Test(httptest.NewRequest("GET", "/", nil))
+ utils.AssertEqual(t, nil, err)
+ utils.AssertEqual(t, fiber.StatusNotFound, resp.StatusCode)
+}
diff --git a/middleware/pprof/pprof.go b/middleware/pprof/pprof.go
index f122b73e..63446a3c 100644
--- a/middleware/pprof/pprof.go
+++ b/middleware/pprof/pprof.go
@@ -35,7 +35,6 @@ func New() fiber.Handler {
// Switch to original path without stripped slashes
switch path {
case "/debug/pprof/":
- c.Context().SetContentType(fiber.MIMETextHTML)
pprofIndex(c.Context())
case "/debug/pprof/cmdline":
pprofCmdline(c.Context())
diff --git a/middleware/pprof/pprof_test.go b/middleware/pprof/pprof_test.go
new file mode 100644
index 00000000..2b22159f
--- /dev/null
+++ b/middleware/pprof/pprof_test.go
@@ -0,0 +1,88 @@
+package pprof
+
+import (
+ "bytes"
+ "github.com/gofiber/fiber/v2"
+ "github.com/gofiber/fiber/v2/utils"
+ "io/ioutil"
+ "net/http/httptest"
+ "testing"
+)
+
+func Test_Non_Pprof_Path(t *testing.T) {
+ app := fiber.New(fiber.Config{DisableStartupMessage: true})
+
+ app.Use(New())
+
+ app.Get("/", func(c *fiber.Ctx) error {
+ return c.SendString("escaped")
+ })
+
+ resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/", nil))
+ utils.AssertEqual(t, nil, err)
+ utils.AssertEqual(t, 200, resp.StatusCode)
+
+ b, err := ioutil.ReadAll(resp.Body)
+ utils.AssertEqual(t, nil, err)
+ utils.AssertEqual(t, "escaped", string(b))
+}
+
+func Test_Pprof_Index(t *testing.T) {
+ app := fiber.New(fiber.Config{DisableStartupMessage: true})
+
+ app.Use(New())
+
+ app.Get("/", func(c *fiber.Ctx) error {
+ return c.SendString("escaped")
+ })
+
+ resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/debug/pprof/", nil))
+ utils.AssertEqual(t, nil, err)
+ utils.AssertEqual(t, 200, resp.StatusCode)
+ utils.AssertEqual(t, fiber.MIMETextHTMLCharsetUTF8, resp.Header.Get(fiber.HeaderContentType))
+
+ b, err := ioutil.ReadAll(resp.Body)
+ utils.AssertEqual(t, nil, err)
+ utils.AssertEqual(t, true, bytes.Contains(b, []byte("/debug/pprof/ ")))
+}
+
+func Test_Pprof_Subs(t *testing.T) {
+ app := fiber.New(fiber.Config{DisableStartupMessage: true})
+
+ app.Use(New())
+
+ app.Get("/", func(c *fiber.Ctx) error {
+ return c.SendString("escaped")
+ })
+
+ subs := []string{
+ "cmdline", "profile", "symbol", "trace", "allocs", "block",
+ "goroutine", "heap", "mutex", "threadcreate",
+ }
+
+ for _, sub := range subs {
+ t.Run(sub, func(t *testing.T) {
+ target := "/debug/pprof/" + sub
+ if sub == "profile" {
+ target += "?seconds=1"
+ }
+ resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, target, nil), 5000)
+ utils.AssertEqual(t, nil, err)
+ utils.AssertEqual(t, 200, resp.StatusCode)
+ })
+ }
+}
+
+func Test_Pprof_Other(t *testing.T) {
+ app := fiber.New(fiber.Config{DisableStartupMessage: true})
+
+ app.Use(New())
+
+ app.Get("/", func(c *fiber.Ctx) error {
+ return c.SendString("escaped")
+ })
+
+ resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/debug/pprof/302", nil))
+ utils.AssertEqual(t, nil, err)
+ utils.AssertEqual(t, 302, resp.StatusCode)
+}
diff --git a/middleware/recover/recover.go b/middleware/recover/recover.go
index fe3ea5e2..8ee4b30f 100644
--- a/middleware/recover/recover.go
+++ b/middleware/recover/recover.go
@@ -27,11 +27,6 @@ func New(config ...Config) fiber.Handler {
// Override config if provided
if len(config) > 0 {
cfg = config[0]
-
- // Set default values
- if cfg.Next == nil {
- cfg.Next = ConfigDefault.Next
- }
}
// Return new handler
diff --git a/middleware/recover/recover_test.go b/middleware/recover/recover_test.go
index 05e7c34a..dd76573a 100644
--- a/middleware/recover/recover_test.go
+++ b/middleware/recover/recover_test.go
@@ -27,3 +27,19 @@ func Test_Recover(t *testing.T) {
utils.AssertEqual(t, nil, err)
utils.AssertEqual(t, fiber.StatusTeapot, resp.StatusCode)
}
+
+// go test -run Test_Recover_Next
+func Test_Recover_Next(t *testing.T) {
+ app := fiber.New(fiber.Config{
+ DisableStartupMessage: true,
+ })
+ app.Use(New(Config{
+ Next: func(_ *fiber.Ctx) bool {
+ return true
+ },
+ }))
+
+ resp, err := app.Test(httptest.NewRequest("GET", "/", nil))
+ utils.AssertEqual(t, nil, err)
+ utils.AssertEqual(t, fiber.StatusNotFound, resp.StatusCode)
+}
diff --git a/middleware/requestid/requestid.go b/middleware/requestid/requestid.go
index 68f6faff..fbee5203 100644
--- a/middleware/requestid/requestid.go
+++ b/middleware/requestid/requestid.go
@@ -44,9 +44,6 @@ func New(config ...Config) fiber.Handler {
cfg = config[0]
// Set default values
- if cfg.Next == nil {
- cfg.Next = ConfigDefault.Next
- }
if cfg.Header == "" {
cfg.Header = ConfigDefault.Header
}
diff --git a/middleware/requestid/requestid_test.go b/middleware/requestid/requestid_test.go
index 84db2d19..a01c161f 100644
--- a/middleware/requestid/requestid_test.go
+++ b/middleware/requestid/requestid_test.go
@@ -33,3 +33,19 @@ func Test_RequestID(t *testing.T) {
utils.AssertEqual(t, fiber.StatusOK, resp.StatusCode)
utils.AssertEqual(t, reqid, resp.Header.Get(fiber.HeaderXRequestID))
}
+
+// go test -run Test_RequestID_Next
+func Test_RequestID_Next(t *testing.T) {
+ app := fiber.New(fiber.Config{
+ DisableStartupMessage: true,
+ })
+ app.Use(New(Config{
+ Next: func(_ *fiber.Ctx) bool {
+ return true
+ },
+ }))
+
+ resp, err := app.Test(httptest.NewRequest("GET", "/", nil))
+ utils.AssertEqual(t, nil, err)
+ utils.AssertEqual(t, fiber.StatusNotFound, resp.StatusCode)
+}
diff --git a/prefork_test.go b/prefork_test.go
index 0f162f2b..74bb3f74 100644
--- a/prefork_test.go
+++ b/prefork_test.go
@@ -14,8 +14,8 @@ func Test_App_Prefork_Child_Process(t *testing.T) {
// Reset test var
testPreforkMaster = true
- utils.AssertEqual(t, nil, os.Setenv(envPreforkChildKey, envPreforkChildVal))
- defer os.Setenv(envPreforkChildKey, "")
+ setupIsChild(t)
+ defer teardownIsChild(t)
app := New()
@@ -64,8 +64,8 @@ func Test_App_Prefork_Master_Process(t *testing.T) {
}
func Test_App_Prefork_Child_Process_Never_Show_Startup_Message(t *testing.T) {
- utils.AssertEqual(t, nil, os.Setenv(envPreforkChildKey, envPreforkChildVal))
- defer os.Setenv(envPreforkChildKey, "")
+ setupIsChild(t)
+ defer teardownIsChild(t)
rescueStdout := os.Stdout
defer func() { os.Stdout = rescueStdout }()
@@ -83,3 +83,11 @@ func Test_App_Prefork_Child_Process_Never_Show_Startup_Message(t *testing.T) {
utils.AssertEqual(t, nil, err)
utils.AssertEqual(t, 0, len(out))
}
+
+func setupIsChild(t *testing.T) {
+ utils.AssertEqual(t, nil, os.Setenv(envPreforkChildKey, envPreforkChildVal))
+}
+
+func teardownIsChild(t *testing.T) {
+ utils.AssertEqual(t, nil, os.Setenv(envPreforkChildKey, ""))
+}
diff --git a/utils/common.go b/utils/common.go
index fabf4786..e045870b 100644
--- a/utils/common.go
+++ b/utils/common.go
@@ -10,6 +10,7 @@ import (
"encoding/hex"
"reflect"
"runtime"
+ "sync"
"sync/atomic"
)
@@ -22,14 +23,18 @@ const toUpperTable = "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11
var uuidSeed [24]byte
var uuidCounter uint64
+var uuidSetup sync.Once
func UUID() string {
// Setup seed & counter once
- if uuidCounter <= 0 {
+ uuidSetup.Do(func() {
if _, err := rand.Read(uuidSeed[:]); err != nil {
- return "00000000-0000-0000-0000-000000000000"
+ return
}
uuidCounter = binary.LittleEndian.Uint64(uuidSeed[:8])
+ })
+ if atomic.LoadUint64(&uuidCounter) <= 0 {
+ return "00000000-0000-0000-0000-000000000000"
}
// first 8 bytes differ, taking a slice of the first 16 bytes
x := atomic.AddUint64(&uuidCounter, 1)
diff --git a/utils/common_test.go b/utils/common_test.go
index f31652d8..740ae439 100644
--- a/utils/common_test.go
+++ b/utils/common_test.go
@@ -24,6 +24,25 @@ func Test_Utils_UUID(t *testing.T) {
t.Parallel()
res := UUID()
AssertEqual(t, 36, len(res))
+ AssertEqual(t, true, res != "00000000-0000-0000-0000-000000000000")
+}
+
+func Test_Utils_UUID_Concurrency(t *testing.T) {
+ t.Parallel()
+ iterations := 10000
+ var res string
+ ch := make(chan string, iterations)
+ results := make(map[string]string)
+ for i := 0; i < iterations; i++ {
+ go func() {
+ ch <- UUID()
+ }()
+ }
+ for i := 0; i < iterations; i++ {
+ res = <-ch
+ results[res] = res
+ }
+ AssertEqual(t, iterations, len(results))
}
// go test -v -run=^$ -bench=Benchmark_UUID -benchmem -count=2