diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000000..6a4ec76843
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,8 @@
+; This file is for unifying the coding style for different editors and IDEs.
+; More information at http://editorconfig.org
+; This style originates from https://github.com/fewagency/best-practices
+root = true
+
+[*]
+charset = utf-8
+end_of_line = lf
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000000..963a68ec2d
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,12 @@
+# Handle line endings automatically for files detected as text
+# and leave all files detected as binary untouched.
+* text=auto eol=lf
+
+# Force batch scripts to always use CRLF line endings so that if a repo is accessed
+# in Windows via a file share from Linux, the scripts will work.
+*.{cmd,[cC][mM][dD]} text eol=crlf
+*.{bat,[bB][aA][tT]} text eol=crlf
+
+# Force bash scripts to always use LF line endings so that if a repo is accessed
+# in Unix via a file share from Windows, the scripts will work.
+*.sh text eol=lf
diff --git a/.github/ISSUE_TEMPLATE/bug-report.yaml b/.github/ISSUE_TEMPLATE/bug-report.yaml
index 0452c7c5a4..84408f69f2 100644
--- a/.github/ISSUE_TEMPLATE/bug-report.yaml
+++ b/.github/ISSUE_TEMPLATE/bug-report.yaml
@@ -10,15 +10,15 @@ body:
value: |
### Notice
**This repository is not related to external or third-part Fiber modules. If you have a problem with them, open an issue under their repos. If you think the problem is related to Fiber, open the issue here.**
- - Dont't forget you can ask your questions on our [Discord server](https://gofiber.io/discord).
- - If you think Fiber doesn't have a nice feature that you think, open the issue with **✏️ Feature Request** template.
+ - Don't forget you can ask your questions in our [Discord server](https://gofiber.io/discord).
+ - If you have a suggestion for a Fiber feature you would like to see, open the issue with the **✏️ Feature Request** template.
- Write your issue with clear and understandable English.
- type: textarea
id: description
attributes:
label: "Bug Description"
description: "A clear and detailed description of what the bug is."
- placeholder: "Explain your problem as clear and detailed."
+ placeholder: "Explain your problem clearly and in detail."
validations:
required: true
- type: textarea
@@ -39,7 +39,7 @@ body:
id: expected-behavior
attributes:
label: Expected Behavior
- description: "A clear and detailed description of what you think should happens."
+ description: "A clear and detailed description of what you think should happen."
placeholder: "Tell us what Fiber should normally do."
validations:
required: true
@@ -56,7 +56,7 @@ body:
attributes:
label: "Code Snippet (optional)"
description: "For some issues, we need to know some parts of your code."
- placeholder: "Share a code you think related to the issue."
+ placeholder: "Share a code snippet that you think is related to the issue."
render: go
value: |
package main
diff --git a/.github/ISSUE_TEMPLATE/feature-request.yaml b/.github/ISSUE_TEMPLATE/feature-request.yaml
index 83bbcafdc8..91a05fd6cc 100644
--- a/.github/ISSUE_TEMPLATE/feature-request.yaml
+++ b/.github/ISSUE_TEMPLATE/feature-request.yaml
@@ -9,15 +9,15 @@ body:
attributes:
value: |
### Notice
- - Dont't forget you can ask your questions on our [Discord server](https://gofiber.io/discord).
- - If you think this is just a bug, open the issue with **☢️ Bug Report** template.
+ - Don't forget you can ask your questions in our [Discord server](https://gofiber.io/discord).
+ - If you think this is just a bug, open the issue with the **☢️ Bug Report** template.
- Write your issue with clear and understandable English.
- type: textarea
id: description
attributes:
label: "Feature Description"
- description: "A clear and detailed description of the feature we need to do."
- placeholder: "Explain your feature as clear and detailed."
+ description: "A clear and detailed description of the feature you would like to see added."
+ placeholder: "Explain your feature clearly, and in detail."
validations:
required: true
- type: textarea
@@ -31,7 +31,7 @@ body:
attributes:
label: "Code Snippet (optional)"
description: "Code snippet may be really helpful to describe some features."
- placeholder: "Share a code to explain the feature better."
+ placeholder: "Share a code snippet to explain the feature better."
render: go
value: |
package main
diff --git a/.github/ISSUE_TEMPLATE/question.yaml b/.github/ISSUE_TEMPLATE/question.yaml
index 6e06c16788..d5df2a3d87 100644
--- a/.github/ISSUE_TEMPLATE/question.yaml
+++ b/.github/ISSUE_TEMPLATE/question.yaml
@@ -9,16 +9,16 @@ body:
attributes:
value: |
### Notice
- - Dont't forget you can ask your questions on our [Discord server](https://gofiber.io/discord).
- - If you think this is just a bug, open the issue with **☢️ Bug Report** template.
- - If you think Fiber doesn't have a nice feature that you think, open the issue with **✏️ Feature Request** template.
+ - Don't forget you can ask your questions in our [Discord server](https://gofiber.io/discord).
+ - If you think this is just a bug, open the issue with the **☢️ Bug Report** template.
+ - If you have a suggestion for a Fiber feature you would like to see, open the issue with the **✏️ Feature Request** template.
- Write your issue with clear and understandable English.
- type: textarea
id: description
attributes:
label: "Question Description"
description: "A clear and detailed description of the question."
- placeholder: "Explain your question as clear and detailed."
+ placeholder: "Explain your question clearly, and in detail."
validations:
required: true
- type: textarea
@@ -26,7 +26,7 @@ body:
attributes:
label: "Code Snippet (optional)"
description: "Code snippet may be really helpful to describe some features."
- placeholder: "Share a code to explain the feature better."
+ placeholder: "Share a code snippet to explain the feature better."
render: go
value: |
package main
diff --git a/.github/README.md b/.github/README.md
index 45f428f037..03c596440e 100644
--- a/.github/README.md
+++ b/.github/README.md
@@ -1,6 +1,9 @@
Fiber is an Express inspired web framework built on top of Fasthttp, the fastest HTTP engine for Go. Designed to ease things up for fast development with zero memory allocation and performance in mind.
@@ -109,13 +118,13 @@ func main() {
These tests are performed by [TechEmpower](https://www.techempower.com/benchmarks/#section=data-r19&hw=ph&test=plaintext) and [Go Web](https://github.com/smallnest/go-web-framework-benchmark). If you want to see all the results, please visit our [Wiki](https://docs.gofiber.io/extra/benchmarks).
-
-
+
+
## ⚙️ Installation
-Make sure you have Go installed ([download](https://go.dev/dl/)). Version `1.14` or higher is required.
+Make sure you have Go installed ([download](https://go.dev/dl/)). Version `1.17` or higher is required.
Initialize your project by creating a folder and then running `go mod init github.com/your/repo` ([learn more](https://go.dev/blog/using-go-modules)) inside the folder. Then install Fiber with the [`go get`](https://pkg.go.dev/cmd/go/#hdr-Add_dependencies_to_current_module_and_install_them) command:
@@ -125,12 +134,12 @@ go get -u github.com/gofiber/fiber/v3
## 🎯 Features
-- Robust [routing](https://docs.gofiber.io/routing)
+- Robust [routing](https://docs.gofiber.io/guide/routing)
- Serve [static files](https://docs.gofiber.io/api/app#static)
- Extreme [performance](https://docs.gofiber.io/extra/benchmarks)
- [Low memory](https://docs.gofiber.io/extra/benchmarks) footprint
- [API endpoints](https://docs.gofiber.io/api/ctx)
-- [Middleware](https://docs.gofiber.io/middleware) & [Next](https://docs.gofiber.io/api/ctx#next) support
+- [Middleware](https://docs.gofiber.io/category/-middleware) & [Next](https://docs.gofiber.io/api/ctx#next) support
- [Rapid](https://dev.to/koddr/welcome-to-fiber-an-express-js-styled-fastest-web-framework-written-with-on-golang-497) server-side programming
- [Template engines](https://github.com/gofiber/template)
- [WebSocket support](https://github.com/gofiber/websocket)
@@ -148,12 +157,12 @@ Fiber is **inspired** by Express, the most popular web framework on the Internet
We **listen** to our users in [issues](https://github.com/gofiber/fiber/issues), Discord [channel](https://gofiber.io/discord) _and all over the Internet_ to create a **fast**, **flexible** and **friendly** Go web framework for **any** task, **deadline** and developer **skill**! Just like Express does in the JavaScript world.
## ⚠️ Limitations
-* Due to Fiber's usage of unsafe, the library may not always be compatible with the latest Go version. Fiber 2.40.0 has been tested with Go versions 1.16 to 1.19.
+* Due to Fiber's usage of unsafe, the library may not always be compatible with the latest Go version. Fiber 2.40.0 has been tested with Go versions 1.17 to 1.20.
* Fiber is not compatible with net/http interfaces. This means you will not be able to use projects like gqlgen, go-swagger, or any others which are part of the net/http ecosystem.
## 👀 Examples
-Listed below are some of the common examples. If you want to see more code examples , please visit our [Recipes repository](https://github.com/gofiber/recipes) or visit our hosted [API documentation](https://docs.gofiber.io).
+Listed below are some of the common examples. If you want to see more code examples, please visit our [Recipes repository](https://github.com/gofiber/recipes) or visit our hosted [API documentation](https://docs.gofiber.io).
#### 📖 [**Basic Routing**](https://docs.gofiber.io/#basic-routing)
@@ -437,7 +446,7 @@ func main() {
### JSON Response
-📖 [JSON](https://docs.gofiber.io/ctx#json)
+📖 [JSON](https://docs.gofiber.io/api/ctx#json)
```go
type User struct {
@@ -521,7 +530,7 @@ func main() {
c.Context().SetBodyStreamWriter(fasthttp.StreamWriter(func(w *bufio.Writer) {
fmt.Println("WRITER")
var i int
-
+
for {
i++
msg := fmt.Sprintf("%d - the time is %v", i, time.Now())
@@ -579,7 +588,7 @@ func main() {
app := fiber.New(fiber.Config{
EnableTrustedProxyCheck: true,
TrustedProxies: []string{"0.0.0.0", "1.1.1.1/30"}, // IP address or IP address range
- ProxyHeader: fiber.HeaderXForwardedFor},
+ ProxyHeader: fiber.HeaderXForwardedFor,
})
// ...
@@ -616,7 +625,12 @@ Here is a list of middleware that are included within the Fiber framework.
| [requestid](https://github.com/gofiber/fiber/tree/master/middleware/requestid) | Adds a requestid to every request. |
| [session](https://github.com/gofiber/fiber/tree/master/middleware/session) | Session middleware. NOTE: This middleware uses our Storage package. |
| [skip](https://github.com/gofiber/fiber/tree/master/middleware/skip) | Skip middleware that skips a wrapped handler if a predicate is true. |
+| [rewrite](https://github.com/gofiber/rewrite) | Rewrite middleware rewrites the URL path based on provided rules. It can be helpful for backward compatibility or just creating cleaner and more descriptive links. |
| [timeout](https://github.com/gofiber/fiber/tree/master/middleware/timeout) | Adds a max time for a request and forwards to ErrorHandler if it is exceeded. |
+| [adaptor](https://github.com/gofiber/adaptor) | Converter for net/http handlers to/from Fiber request handlers, special thanks to @arsmn! |
+| [helmet](https://github.com/gofiber/helmet) | Helps secure your apps by setting various HTTP headers. |
+| [redirect](https://github.com/gofiber/redirect) | Redirect middleware |
+| [keyauth](https://github.com/gofiber/keyauth) | Key auth middleware provides a key based authentication. |
## 🧬 External Middleware
@@ -624,12 +638,7 @@ List of externally hosted middleware modules and maintained by the [Fiber team](
| Middleware | Description |
| :------------------------------------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
-| [adaptor](https://github.com/gofiber/adaptor) | Converter for net/http handlers to/from Fiber request handlers, special thanks to @arsmn! |
-| [helmet](https://github.com/gofiber/helmet) | Helps secure your apps by setting various HTTP headers. |
| [jwt](https://github.com/gofiber/jwt) | JWT returns a JSON Web Token \(JWT\) auth middleware. |
-| [keyauth](https://github.com/gofiber/keyauth) | Key auth middleware provides a key based authentication. |
-| [redirect](https://github.com/gofiber/redirect) | Redirect middleware |
-| [rewrite](https://github.com/gofiber/rewrite) | Rewrite middleware rewrites the URL path based on provided rules. It can be helpful for backward compatibility or just creating cleaner and more descriptive links. |
| [storage](https://github.com/gofiber/storage) | Premade storage drivers that implement the Storage interface, designed to be used with various Fiber middlewares. |
| [template](https://github.com/gofiber/template) | This package contains 8 template engines that can be used with Fiber `v1.10.x` Go version 1.13 or higher is required. |
| [websocket](https://github.com/gofiber/websocket) | Based on Fasthttp WebSocket for Fiber with Locals support! |
@@ -691,7 +700,6 @@ Copyright (c) 2019-present [Fenny](https://github.com/fenny) and [Contributors](
- [runewidth](https://github.com/mattn/go-runewidth/blob/master/LICENSE)
- [fasthttp](https://github.com/valyala/fasthttp/blob/master/LICENSE)
- [bytebufferpool](https://github.com/valyala/bytebufferpool/blob/master/LICENSE)
-- [dictpool](https://github.com/savsgio/dictpool/blob/master/LICENSE)
- [fwd](https://github.com/philhofer/fwd/blob/master/LICENSE.md)
- [go-ole](https://github.com/go-ole/go-ole/blob/master/LICENSE)
- [gopsutil](https://github.com/shirou/gopsutil/blob/master/LICENSE)
diff --git a/.github/README_az.md b/.github/README_az.md
new file mode 100644
index 0000000000..f6486333eb
--- /dev/null
+++ b/.github/README_az.md
@@ -0,0 +1,710 @@
+
+ FiberGo dili üçün ən sürətli HTTP mühərriki Fasthttp və Express kitabxanasına bənzər arxitektura üzərində qurulmuş bir web framework-dür. Sıfır yaddaş ayrılması (zero-memory allocation) və performans səbəbilə development prosesini sürətləndirmək və asanlaşdırmaq üçün tərtib edilmişdir.
+
+
+## ⚡️ Sürətli Başlanğıc
+
+```go
+package main
+
+import "github.com/gofiber/fiber/v2"
+
+func main() {
+ app := fiber.New()
+
+ app.Get("/", func(c *fiber.Ctx) error {
+ return c.SendString("Hello, World 👋!")
+ })
+
+ app.Listen(":3000")
+}
+```
+
+## 🤖 Performans Dəyərləri
+
+Bu testlər [TechEmpower](https://www.techempower.com/benchmarks/#section=data-r19&hw=ph&test=plaintext) və [Go Web](https://github.com/smallnest/go-web-framework-benchmark) tərəfindən aparılıb. Bütün nəticələri görmək üçün [Wiki](https://docs.gofiber.io/extra/benchmarks) səhifəsinə keçid edə bilərsiniz.
+
+
+
+
+
+
+## ⚙️ Quraşdırılması
+
+Go dilinin `1.17` və ya daha yuxarı versiyanın [yükləndiyindən](https://go.dev/dl/) əmin olun.
+
+
+Bir qovluq yaratdıqdan sonra, `go mod init github.com/your/repo` komandasını eyni qovluğun daxilində işə salaraq layihənizi başladın ([go modulları haqqında əlavə bilgilər](https://go.dev/blog/using-go-modules)). Növbəti addım olaraq Fiber-i [`go get`](https://pkg.go.dev/cmd/go/#hdr-Add_dependencies_to_current_module_and_install_them) komandasını işlədərək yükləyin:
+
+```bash
+go get -u github.com/gofiber/fiber/v2
+```
+
+## 🎯 Özəllikləri
+
+- Güclü [routing](https://docs.gofiber.io/guide/routing)
+- [Static faylların](https://docs.gofiber.io/api/app#static) təqdimatı
+- Yüksək [performans](https://docs.gofiber.io/extra/benchmarks)
+- [Daha az yaddaş istifadəsi](https://docs.gofiber.io/extra/benchmarks)
+- [API son nöqtələri (endpoint)](https://docs.gofiber.io/api/ctx)
+- [Middleware](https://docs.gofiber.io/category/-middleware) & [Next](https://docs.gofiber.io/api/ctx#next) dəstəyi
+- [Rapid](https://dev.to/koddr/welcome-to-fiber-an-express-js-styled-fastest-web-framework-written-with-on-golang-497) server yönümlü proqramlaşdırma
+- [Template mühərrikləri](https://github.com/gofiber/template)
+- [WebSocket dəstəyi](https://github.com/gofiber/websocket)
+- [Server-Sent events](https://github.com/gofiber/recipes/tree/master/sse)
+- [Rate Limiter](https://docs.gofiber.io/api/middleware/limiter)
+- [18 dildə](https://docs.gofiber.io/) mövcudluğu
+
+Daha ətraflı məlumat üçün [rəsmi sənədləşməyə](https://docs.gofiber.io/) baxış keçirə bilərsiniz.
+
+## 💡 Fəlsəfə
+
+[Node.js](https://nodejs.org/en/about/)-dən [Go](https://go.dev/doc/)-ya yeni keçən gopher-lər veb tətbiqlər və mikroservislər yazmadan öncə dilin özünəməxsus sintaksisini öyrənməklə məşğul olurlar. Fiber Minimalizm və UNIX-in yaradılış prinsiplərinə uyğun şəkildə qurulmuş bir web framework-dür. Bu sahədə yeni olan gopher-lər Go dünyasında özlərini doğma və güvənli hiss edə biləcək şəkildə bir ab-hava ilə rastlaşa bilərlər.
+
+Fiber internet üzərində olan ən məşhur web framework-lərdən biri olan Express-dən ilhamlanaraq ərsəyə gəlmişdir. Biz Express-in rahatlıq və asanlıq xüsusiyyətlərini, Go-nun çiy performansı ilə birləşdirmişik; əgər əvvəldən Node.js üzərində (Express və ya bənzərləri) veb tətbiqi yaratmısınızsa, onda əksər metodlar və prinsiplər sizə tanış gələcəkdir.
+
+Biz istifadəçilərdən gələn [issue-a](https://github.com/gofiber/fiber/issues), Discord [kanalımıza](https://gofiber.io/discord) və bütün interneti əhatə edən vasitələrdən gələn rəyləri nəzərə alırıq. Bunun nəzdində, biz sürətli və rahat şəkildə hər bir tapşırığın səviyyəsinə uyğun olan — dostcasına bir Go web framework-ü olmağı hədəfləmişik (Express-in JavaScript dünyasında etdiyi kimi).
+
+## ⚠️ Limitlər
+* Fiber unsafe prinsiplərə əsaslanaraq çalışdığından, o hər zaman Go-nun son versiyası ilə uyğunlaşmaya bilər. Buna görə də, Fiber 2.40.0 — Go 1.17 və 1.20 versiyaları ilə test edilərək saz vəziyyətə gətirilmişdir.
+* Fiber net/http interfeysləri ilə uyğun deyil. Yəni gqlgen, go-swagger kimi net/http ekosisteminin parçası olan layihələri istifadə edə bilməzsiniz.
+
+## 👀 Misallar
+
+Aşağıda geniş istifadə olunan misallardan bəziləri siyahı şəklində qeyd olunub. Əgər daha çox koda dair misalları görmək istəyirsinizsə, onda [Əlavə misallardan ibarət github deposunu](https://github.com/gofiber/recipes) və ya [API sənədləşməni](https://docs.gofiber.io) nəzərdən keçirin.
+
+#### 📖 [**Sadə Routing**](https://docs.gofiber.io/#basic-routing)
+
+```go
+func main() {
+ app := fiber.New()
+
+ // GET /api/register
+ app.Get("/api/*", func(c *fiber.Ctx) error {
+ msg := fmt.Sprintf("✋ %s", c.Params("*"))
+ return c.SendString(msg) // => ✋ register
+ })
+
+ // GET /flights/LAX-SFO
+ app.Get("/flights/:from-:to", func(c *fiber.Ctx) error {
+ msg := fmt.Sprintf("💸 From: %s, To: %s", c.Params("from"), c.Params("to"))
+ return c.SendString(msg) // => 💸 From: LAX, To: SFO
+ })
+
+ // GET /dictionary.txt
+ app.Get("/:file.:ext", func(c *fiber.Ctx) error {
+ msg := fmt.Sprintf("📃 %s.%s", c.Params("file"), c.Params("ext"))
+ return c.SendString(msg) // => 📃 dictionary.txt
+ })
+
+ // GET /john/75
+ app.Get("/:name/:age/:gender?", func(c *fiber.Ctx) error {
+ msg := fmt.Sprintf("👴 %s is %s years old", c.Params("name"), c.Params("age"))
+ return c.SendString(msg) // => 👴 john is 75 years old
+ })
+
+ // GET /john
+ app.Get("/:name", func(c *fiber.Ctx) error {
+ msg := fmt.Sprintf("Hello, %s 👋!", c.Params("name"))
+ return c.SendString(msg) // => Hello john 👋!
+ })
+
+ log.Fatal(app.Listen(":3000"))
+}
+
+```
+
+#### 📖 [**Route-un Adlandırılması**](https://docs.gofiber.io/api/app#name)
+
+```go
+func main() {
+ app := fiber.New()
+
+ // GET /api/register
+ app.Get("/api/*", func(c *fiber.Ctx) error {
+ msg := fmt.Sprintf("✋ %s", c.Params("*"))
+ return c.SendString(msg) // => ✋ register
+ }).Name("api")
+
+ data, _ := json.MarshalIndent(app.GetRoute("api"), "", " ")
+ fmt.Print(string(data))
+ // Prints:
+ // {
+ // "method": "GET",
+ // "name": "api",
+ // "path": "/api/*",
+ // "params": [
+ // "*1"
+ // ]
+ // }
+
+
+ log.Fatal(app.Listen(":3000"))
+}
+
+```
+
+#### 📖 [**Static Fayl Təqdimatı**](https://docs.gofiber.io/api/app#static)
+
+```go
+func main() {
+ app := fiber.New()
+
+ app.Static("/", "./public")
+ // => http://localhost:3000/js/script.js
+ // => http://localhost:3000/css/style.css
+
+ app.Static("/prefix", "./public")
+ // => http://localhost:3000/prefix/js/script.js
+ // => http://localhost:3000/prefix/css/style.css
+
+ app.Static("*", "./public/index.html")
+ // => http://localhost:3000/any/path/shows/index/html
+
+ log.Fatal(app.Listen(":3000"))
+}
+
+```
+
+#### 📖 [**Middleware & Next**](https://docs.gofiber.io/api/ctx#next)
+
+```go
+func main() {
+ app := fiber.New()
+
+ // Match any route
+ app.Use(func(c *fiber.Ctx) error {
+ fmt.Println("🥇 First handler")
+ return c.Next()
+ })
+
+ // Match all routes starting with /api
+ app.Use("/api", func(c *fiber.Ctx) error {
+ fmt.Println("🥈 Second handler")
+ return c.Next()
+ })
+
+ // GET /api/list
+ app.Get("/api/list", func(c *fiber.Ctx) error {
+ fmt.Println("🥉 Last handler")
+ return c.SendString("Hello, World 👋!")
+ })
+
+ log.Fatal(app.Listen(":3000"))
+}
+
+```
+
+
+ 📚 Daha çox misalllar
+
+### Baxış mühərriki (View Engine)
+
+📖 [Config](https://docs.gofiber.io/api/fiber#config)
+📖 [Mühərriklər](https://github.com/gofiber/template)
+📖 [Render](https://docs.gofiber.io/api/ctx#render)
+
+Fiber baxış mühərriki təyin edilmədikdə [html/template-in](https://pkg.go.dev/html/template/) default formasını alır.
+
+Əgər siz partial-ı və ya müxtəlif tipdə olan mühərrikləri istifadə etmək istəyirsinizsə, o zaman [amber](https://github.com/eknkc/amber), [handlebars](https://github.com/aymerick/raymond), [mustache](https://github.com/cbroglie/mustache), [pug](https://github.com/Joker/jade) və s. kimi misallara baxa bilərsiniz.
+
+Çoxsaylı baxış mühərriklərini dəstəkləyən [template](https://github.com/gofiber/template) package-ə göstərilən link vasitəsilə nəzərdən keçirə bilərsiniz.
+
+```go
+package main
+
+import (
+ "github.com/gofiber/fiber/v2"
+ "github.com/gofiber/template/pug"
+)
+
+func main() {
+ // Baxış mühərrikini tətbiqi başlatzmadan əvvəl quraşdıra bilərsiniz:
+ app := fiber.New(fiber.Config{
+ Views: pug.New("./views", ".pug"),
+ })
+
+ // Və indi `./views/home.pug` template-i bu şəkildə çağıra bilərsiniz:
+ app.Get("/", func(c *fiber.Ctx) error {
+ return c.Render("home", fiber.Map{
+ "title": "Homepage",
+ "year": 1999,
+ })
+ })
+
+ log.Fatal(app.Listen(":3000"))
+}
+```
+
+### Route-ın zəncirlərdə qruplaşdırılması
+
+📖 [Group](https://docs.gofiber.io/api/app#group)
+
+```go
+func middleware(c *fiber.Ctx) error {
+ fmt.Println("Don't mind me!")
+ return c.Next()
+}
+
+func handler(c *fiber.Ctx) error {
+ return c.SendString(c.Path())
+}
+
+func main() {
+ app := fiber.New()
+
+ // Root API route
+ api := app.Group("/api", middleware) // /api
+
+ // API v1 routes
+ v1 := api.Group("/v1", middleware) // /api/v1
+ v1.Get("/list", handler) // /api/v1/list
+ v1.Get("/user", handler) // /api/v1/user
+
+ // API v2 routes
+ v2 := api.Group("/v2", middleware) // /api/v2
+ v2.Get("/list", handler) // /api/v2/list
+ v2.Get("/user", handler) // /api/v2/user
+
+ // ...
+}
+
+```
+
+### Middleware Logger
+
+📖 [Logger](https://docs.gofiber.io/api/middleware/logger)
+
+```go
+package main
+
+import (
+ "log"
+
+ "github.com/gofiber/fiber/v2"
+ "github.com/gofiber/fiber/v2/middleware/logger"
+)
+
+func main() {
+ app := fiber.New()
+
+ app.Use(logger.New())
+
+ // ...
+
+ log.Fatal(app.Listen(":3000"))
+}
+```
+
+### Cross-Origin Resource Sharing (CORS)
+
+📖 [CORS](https://docs.gofiber.io/api/middleware/cors)
+
+```go
+import (
+ "log"
+
+ "github.com/gofiber/fiber/v2"
+ "github.com/gofiber/fiber/v2/middleware/cors"
+)
+
+func main() {
+ app := fiber.New()
+
+ app.Use(cors.New())
+
+ // ...
+
+ log.Fatal(app.Listen(":3000"))
+}
+```
+
+"Origin" başlığında istənilən domeni keçməklə CORS-un yoxlanması:
+
+```bash
+curl -H "Origin: http://example.com" --verbose http://localhost:3000
+```
+
+### Custom 404 response
+
+📖 [HTTP Methods](https://docs.gofiber.io/api/ctx#status)
+
+```go
+func main() {
+ app := fiber.New()
+
+ app.Static("/", "./public")
+
+ app.Get("/demo", func(c *fiber.Ctx) error {
+ return c.SendString("This is a demo!")
+ })
+
+ app.Post("/register", func(c *fiber.Ctx) error {
+ return c.SendString("Welcome!")
+ })
+
+ // Sonuncu middleware-in hər şeyə uyğunlaşdırılması
+ app.Use(func(c *fiber.Ctx) error {
+ return c.SendStatus(404)
+ // => 404 "Not Found"
+ })
+
+ log.Fatal(app.Listen(":3000"))
+}
+```
+
+### JSON Response
+
+📖 [JSON](https://docs.gofiber.io/api/ctx#json)
+
+```go
+type User struct {
+ Name string `json:"name"`
+ Age int `json:"age"`
+}
+
+func main() {
+ app := fiber.New()
+
+ app.Get("/user", func(c *fiber.Ctx) error {
+ return c.JSON(&User{"John", 20})
+ // => {"name":"John", "age":20}
+ })
+
+ app.Get("/json", func(c *fiber.Ctx) error {
+ return c.JSON(fiber.Map{
+ "success": true,
+ "message": "Hi John!",
+ })
+ // => {"success":true, "message":"Hi John!"}
+ })
+
+ log.Fatal(app.Listen(":3000"))
+}
+```
+
+### WebSocket-in təkminləşdirilməsi (upgrade)
+
+📖 [Websocket](https://github.com/gofiber/websocket)
+
+```go
+import (
+ "github.com/gofiber/fiber/v2"
+ "github.com/gofiber/fiber/v2/middleware/websocket"
+)
+
+func main() {
+ app := fiber.New()
+
+ app.Get("/ws", websocket.New(func(c *websocket.Conn) {
+ for {
+ mt, msg, err := c.ReadMessage()
+ if err != nil {
+ log.Println("read:", err)
+ break
+ }
+ log.Printf("recv: %s", msg)
+ err = c.WriteMessage(mt, msg)
+ if err != nil {
+ log.Println("write:", err)
+ break
+ }
+ }
+ }))
+
+ log.Fatal(app.Listen(":3000"))
+ // ws://localhost:3000/ws
+}
+```
+
+### Server-Sent Events
+
+📖 [More Info](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events)
+
+```go
+import (
+ "github.com/gofiber/fiber/v2"
+ "github.com/valyala/fasthttp"
+)
+
+func main() {
+ app := fiber.New()
+
+ app.Get("/sse", func(c *fiber.Ctx) error {
+ c.Set("Content-Type", "text/event-stream")
+ c.Set("Cache-Control", "no-cache")
+ c.Set("Connection", "keep-alive")
+ c.Set("Transfer-Encoding", "chunked")
+
+ c.Context().SetBodyStreamWriter(fasthttp.StreamWriter(func(w *bufio.Writer) {
+ fmt.Println("WRITER")
+ var i int
+
+ for {
+ i++
+ msg := fmt.Sprintf("%d - the time is %v", i, time.Now())
+ fmt.Fprintf(w, "data: Message: %s\n\n", msg)
+ fmt.Println(msg)
+
+ w.Flush()
+ time.Sleep(5 * time.Second)
+ }
+ }))
+
+ return nil
+ })
+
+ log.Fatal(app.Listen(":3000"))
+}
+```
+
+### Middleware-in Bərpası
+
+📖 [Recover](https://docs.gofiber.io/api/middleware/recover)
+
+```go
+import (
+ "github.com/gofiber/fiber/v2"
+ "github.com/gofiber/fiber/v2/middleware/recover"
+)
+
+func main() {
+ app := fiber.New()
+
+ app.Use(recover.New())
+
+ app.Get("/", func(c *fiber.Ctx) error {
+ panic("normally this would crash your app")
+ })
+
+ log.Fatal(app.Listen(":3000"))
+}
+```
+
+
+
+### Etibarlı Proxy İstifadəsi
+
+📖 [Config](https://docs.gofiber.io/api/fiber#config)
+
+```go
+import (
+ "github.com/gofiber/fiber/v2"
+ "github.com/gofiber/fiber/v2/middleware/recover"
+)
+
+func main() {
+ app := fiber.New(fiber.Config{
+ EnableTrustedProxyCheck: true,
+ TrustedProxies: []string{"0.0.0.0", "1.1.1.1/30"}, // IP address or IP address range
+ ProxyHeader: fiber.HeaderXForwardedFor,
+ })
+
+ // ...
+
+ log.Fatal(app.Listen(":3000"))
+}
+```
+
+
+
+## 🧬 Daxili Middleware
+
+Aşağıda Fiber-in daxilində olan middleware-lər siyahı şəklində göstərilmişdir.
+
+| Middleware | Açıqlama |
+|:---------------------------------------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| [basicauth](https://github.com/gofiber/fiber/tree/master/middleware/basicauth) | Sadə bir auth middleware-dir və HTTP Basic Auth yaratmaq üçün istifadə olunur. Keçərli vəsiqə (credentials) bilgiləri üçün sonrakı handler-i, əksik və ya keçərsiz vəsiqə bilgiləri üçün 401 qaytarır. |
+| [cache](https://github.com/gofiber/fiber/tree/master/middleware/cache) | Response-ı dayandırır və keşə yerləşdirir. |
+| [compress](https://github.com/gofiber/fiber/tree/master/middleware/compress) | Fiber üçün sıxışdırma (compression) middleware-dir. Default olaraq `deflate`, `gzip` və `brotli` dəstəkləyir. |
+| [cors](https://github.com/gofiber/fiber/tree/master/middleware/cors) | Çeşidli seçimlərlə başlanğıclar arası mənbə paylaşımı (CORS) aktivləşdirir. |
+| [csrf](https://github.com/gofiber/fiber/tree/master/middleware/csrf) | CSRF exploit-dən qorunmasını təmin edir. |
+| [encryptcookie](https://github.com/gofiber/fiber/tree/master/middleware/encryptcookie) | Encrypt middleware-i cookie dəyərlərini şifrələyir. |
+| [envvar](https://github.com/gofiber/fiber/tree/master/middleware/envvar) | Environment dəyərlərini göstərilən config-ə görə təyin edir. |
+| [etag](https://github.com/gofiber/fiber/tree/master/middleware/etag) | Keşlərin daha səmərəli istifadəsinə və bant genişliyinə qənaət etməyə imkan verən ETag middleware-i; məzmun dəyişməyibsə veb serverin response-nı təkrar göndərməsinin qarşısını alır. |
+| [expvar](https://github.com/gofiber/fiber/tree/master/middleware/expvar) | Expvar middleware, HTTP serverlərinin bəzi runtime dəyərlərini JSON formatında göstərir. |
+| [favicon](https://github.com/gofiber/fiber/tree/master/middleware/favicon) | Əgər faylın yolu (path) göstərilmişdirsə, artıq loglarda olan favicon-u yox sayıb onu saxlanan depodan götürür. |
+| [filesystem](https://github.com/gofiber/fiber/tree/master/middleware/filesystem) | Fiber üçün fayl sistem middleware-i. Alireza Salary-ə xüsusi təşəkkürlər. |
+| [limiter](https://github.com/gofiber/fiber/tree/master/middleware/limiter) | Fiber üçün rate limitləyən middleware. Açıq API-ə və ya şifrə yeniləmə kimi endpoint-ə yönəlik təkrarlanan request-in qarşısını alır. |
+| [logger](https://github.com/gofiber/fiber/tree/master/middleware/logger) | HTTP istək/cavab (request/response) logger-i. |
+| [monitor](https://github.com/gofiber/fiber/tree/master/middleware/monitor) | Monitor middleware-i serverin metriklərini report edər ("Express-status-monitor"-dan qaynaqlanıb). |
+| [pprof](https://github.com/gofiber/fiber/tree/master/middleware/pprof) | Matthew Lee-yə xüsusi təşəkkürlər \(@mthli\). |
+| [proxy](https://github.com/gofiber/fiber/tree/master/middleware/proxy) | Birdən çox server-ə proxy istəyi göndərməyiniz üçündür. |
+| [recover](https://github.com/gofiber/fiber/tree/master/middleware/recover) | Recover middleware-i stack chain-ni hər hansı bir yerindəki paniklərdən qurtulmasına kömək edir və kontrolu mərkəzləşdirilmiş [ErrorHandler-ə](https://docs.gofiber.io/guide/error-handling) ötürür.|
+| [requestid](https://github.com/gofiber/fiber/tree/master/middleware/requestid) | Hər request üçün ayrı request id yaradır. |
+| [session](https://github.com/gofiber/fiber/tree/master/middleware/session) | Session üçün middleware. Qeyd: Bu middleware Fiber-in öz storage struktrunu istifadə edir. |
+| [skip](https://github.com/gofiber/fiber/tree/master/middleware/skip) | Skip middleware-i verilən şərt true olduğu halda handler-i görməyərək üstündən ötüb keçir. |
+| [timeout](https://github.com/gofiber/fiber/tree/master/middleware/timeout) | Bir request üçün maksimum vaxt əlavə edir. Əgər arada fasilə yaranarsa, onda proses məhz ErrorHandler-ə göndərilərək icra edilir. |
+| [keyauth](https://github.com/gofiber/keyauth) | Key giriş middleware-i, key əsaslı bir authentication metodudur. |
+| [redirect](https://github.com/gofiber/redirect) | Yönləndirmə üçün middleware. |
+| [rewrite](https://github.com/gofiber/rewrite) | Rewrite middleware-i verilən qanunlara əsasən URL yolunu (path) yenidən yazır. Geri dönüşün icrası üçün uyğunluq təşkil edən təsviri linklərin yaradılması üçün nəzərdə tutulmuşdur. |
+| [adaptor](https://github.com/gofiber/adaptor) | Fiber request handler-dən net/http handler-ə çevirici. @arsmn-ə xüsusi təşəkkürlər! |
+| [helmet](https://github.com/gofiber/helmet) | Fərqli HTTP header istifadə edərək tətbiqi daha təhlükəsiz saxlamağa kömək edir. |
+
+## 🧬 Xarici Middleware
+
+[Fiber komandası](https://github.com/orgs/gofiber/people) tərəfindən dəstəklənən və inkişaf etdirilən middleware-in siyahısı.
+
+| Middleware | Description |
+| :------------------------------------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| [jwt](https://github.com/gofiber/jwt) | JWT, JSON Web Token(JWT) girişi qaytaran bir middleware-dir. |
+| [storage](https://github.com/gofiber/storage) | Fiber-in Storage arxitekturasını dəstəkləyən bir sıra storage driver verir. Bu sayədə storage-ə ehtiyac duyan Fiber middleware-də rahatlıqla istifadə oluna bilər. |
+| [template](https://github.com/gofiber/template) | Bu paket, Fiber `v1.10.x`, Go versiyası 1.13 və ya daha yuxarı olduqda istifadə oluna bilər. 8 template mühərriki var. |
+| [websocket](https://github.com/gofiber/websocket) | Yerlilərin dəstəyi ilə WebSocket-ə əsaslanan Fiber üçün Fasthttp. |
+
+## 🕶️ Möhtəşəm Siyahı
+
+Əlavə yazılar, middleware-lər, misallar, və alətlər üçün bizim [möhtəşəm siyahımıza](https://github.com/gofiber/awesome-fiber) göz atın.
+
+## 👍 Dəstək Nümayişi
+
+Əgər `Fiber`-ə dəstək olmaq və ya **təşəkkür etmək** istəyirsinizsə:
+
+1. Layihəni [GitHub Ulduzu](https://github.com/gofiber/fiber/stargazers) ilə işarələyin.
+2. Layihə haqqında [şəxsi twitter hesabınızda](https://twitter.com/intent/tweet?text=Fiber%20is%20an%20Express%20inspired%20%23web%20%23framework%20built%20on%20top%20of%20Fasthttp%2C%20the%20fastest%20HTTP%20engine%20for%20%23Go.%20Designed%20to%20ease%20things%20up%20for%20%23fast%20development%20with%20zero%20memory%20allocation%20and%20%23performance%20in%20mind%20%F0%9F%9A%80%20https%3A%2F%2Fgithub.com%2Fgofiber%2Ffiber) paylaşın.
+3. [Medium](https://medium.com/), [Dev.to](https://dev.to/) və ya şəxsi bloqunuz üzərindən bir incələmə və ya tədris yönümlü bir yazı dərc edin.
+4. Bizim üçün, sadəcə bir [fincan kofe alın](https://buymeacoff.ee/fenny).
+
+## ☕ "Bir fincan kofe almaq" məsələsi
+
+Fiber açıq qaynaqlı bir layihə olduğu üçün, gəlirlərini yalnız ianələr vasitəsilə təmin edir və bu da domain adı, gitbook, netlify, serverless hosting xərcləri üçün istifadə olunur. Belə olduğu halda, Fiber-ə ən yaxşı dəstək elə bizim üçün ☕ [**bir kofe almaqdan gələ bilər**](https://buymeacoff.ee/fenny).
+
+| | İstifadəçi | İanə |
+| :--------------------------------------------------------- | :----------------------------------------------- | :------- |
+| ![](https://avatars.githubusercontent.com/u/204341?s=25) | [@destari](https://github.com/destari) | ☕ x 10 |
+| ![](https://avatars.githubusercontent.com/u/63164982?s=25) | [@dembygenesis](https://github.com/dembygenesis) | ☕ x 5 |
+| ![](https://avatars.githubusercontent.com/u/56607882?s=25) | [@thomasvvugt](https://github.com/thomasvvugt) | ☕ x 5 |
+| ![](https://avatars.githubusercontent.com/u/27820675?s=25) | [@hendratommy](https://github.com/hendratommy) | ☕ x 5 |
+| ![](https://avatars.githubusercontent.com/u/1094221?s=25) | [@ekaputra07](https://github.com/ekaputra07) | ☕ x 5 |
+| ![](https://avatars.githubusercontent.com/u/194590?s=25) | [@jorgefuertes](https://github.com/jorgefuertes) | ☕ x 5 |
+| ![](https://avatars.githubusercontent.com/u/186637?s=25) | [@candidosales](https://github.com/candidosales) | ☕ x 5 |
+| ![](https://avatars.githubusercontent.com/u/29659953?s=25) | [@l0nax](https://github.com/l0nax) | ☕ x 3 |
+| ![](https://avatars.githubusercontent.com/u/635852?s=25) | [@bihe](https://github.com/bihe) | ☕ x 3 |
+| ![](https://avatars.githubusercontent.com/u/307334?s=25) | [@justdave](https://github.com/justdave) | ☕ x 3 |
+| ![](https://avatars.githubusercontent.com/u/11155743?s=25) | [@koddr](https://github.com/koddr) | ☕ x 1 |
+| ![](https://avatars.githubusercontent.com/u/29042462?s=25) | [@lapolinar](https://github.com/lapolinar) | ☕ x 1 |
+| ![](https://avatars.githubusercontent.com/u/2978730?s=25) | [@diegowifi](https://github.com/diegowifi) | ☕ x 1 |
+| ![](https://avatars.githubusercontent.com/u/44171355?s=25) | [@ssimk0](https://github.com/ssimk0) | ☕ x 1 |
+| ![](https://avatars.githubusercontent.com/u/5638101?s=25) | [@raymayemir](https://github.com/raymayemir) | ☕ x 1 |
+| ![](https://avatars.githubusercontent.com/u/619996?s=25) | [@melkorm](https://github.com/melkorm) | ☕ x 1 |
+| ![](https://avatars.githubusercontent.com/u/31022056?s=25) | [@marvinjwendt](https://github.com/marvinjwendt) | ☕ x 1 |
+| ![](https://avatars.githubusercontent.com/u/31921460?s=25) | [@toishy](https://github.com/toishy) | ☕ x 1 |
+
+## 💻 Koda Töhfə Verənlər
+
+
+
+## ⭐️ Layihəni Ulduzlayanlar
+
+
+
+## ⚠️ Lisenziya Haqqında
+
+Müəllif Hüququ (c) 2019-bugün [Fenny](https://github.com/fenny) və [Contributors](https://github.com/gofiber/fiber/graphs/contributors). `Fiber` pulsuz və açıq qaynaqlı bir proqram təminatıdır və [MIT License](https://github.com/gofiber/fiber/blob/master/LICENSE) altında lisenziyalaşmışdır. Rəsmi loqo [Vic Shóstak](https://github.com/koddr) tərəfindən yaradılmış və [Creative Commons](https://creativecommons.org/licenses/by-sa/4.0/) lisenziyası altında paylanmışdır (CC BY-SA 4.0 International).
+
+**Üçüncü Tərəf Kitabxana Lisenziyaları**
+
+- [colorable](https://github.com/mattn/go-colorable/blob/master/LICENSE)
+- [isatty](https://github.com/mattn/go-isatty/blob/master/LICENSE)
+- [runewidth](https://github.com/mattn/go-runewidth/blob/master/LICENSE)
+- [fasthttp](https://github.com/valyala/fasthttp/blob/master/LICENSE)
+- [bytebufferpool](https://github.com/valyala/bytebufferpool/blob/master/LICENSE)
+- [fwd](https://github.com/philhofer/fwd/blob/master/LICENSE.md)
+- [go-ole](https://github.com/go-ole/go-ole/blob/master/LICENSE)
+- [gopsutil](https://github.com/shirou/gopsutil/blob/master/LICENSE)
+- [msgp](https://github.com/tinylib/msgp/blob/master/LICENSE)
+- [schema](https://github.com/gorilla/schema/blob/master/LICENSE)
+- [uuid](https://github.com/google/uuid/blob/master/LICENSE)
+- [wmi](https://github.com/StackExchange/wmi/blob/master/LICENSE)
diff --git a/.github/README_ckb.md b/.github/README_ckb.md
index 92fdba37d6..5358572752 100644
--- a/.github/README_ckb.md
+++ b/.github/README_ckb.md
@@ -1,6 +1,11 @@
-مطمئن شوید Go را نصب (دانلود) کرده اید. نسخه 1.14 یا بیشتر مورد نیاز است.
+مطمئن شوید Go را نصب (دانلود) کرده اید. نسخه 1.17 یا بیشتر مورد نیاز است.
پروژه خود را با ساختن یک پوشه و سپس اجرای go mod init github.com/your/repo داخل پوشه (یادگیری بیشتر) راه اندازی کنید. سپس Fiber را با دستور go get نصب کنید :
@@ -150,12 +161,12 @@ go get -u github.com/gofiber/fiber/v3
-- [مسیریابی](https://docs.gofiber.io/routing) قدرتمند
+- [مسیریابی](https://docs.gofiber.io/guide/routing) قدرتمند
- Serve [پرونده های ثابت](https://docs.gofiber.io/api/app#static)
- حداکثر [عملکرد](https://docs.gofiber.io/extra/benchmarks)
- مصرف [حافظه کم](https://docs.gofiber.io/extra/benchmarks)
- قابلیت [API endpoints](https://docs.gofiber.io/api/ctx)
-- پشتیبانی از [Middleware](https://docs.gofiber.io/middleware) & [Next](https://docs.gofiber.io/api/ctx#next)
+- پشتیبانی از [Middleware](https://docs.gofiber.io/category/-middleware) & [Next](https://docs.gofiber.io/api/ctx#next)
- برنامه نویسی سمت سرور [سریع](https://dev.to/koddr/welcome-to-fiber-an-express-js-styled-fastest-web-framework-written-with-on-golang-497)
- دارای [Template engines](https://github.com/gofiber/template) اختصاصی
- [پشتیبانی از وب سوکت](https://github.com/gofiber/websocket)
@@ -182,7 +193,7 @@ Fiber از Express الهام گرفته, که محبوب ترین فری
## ⚠️ محدودیت ها
-* به دلیل استفاده ناامن از Fiber, ممکن است کتابخانه همیشه با آخرین نسخه Go سازگار نباشد. Fiber 2.40.0 با زبان گو نسخه 1.16 تا 1.19 تست شده است.
+* به دلیل استفاده ناامن از Fiber, ممکن است کتابخانه همیشه با آخرین نسخه Go سازگار نباشد. Fiber 2.40.0 با زبان گو نسخه 1.17 تا 1.20 تست شده است.
* فریمورک Fiber با پکیج net/http سازگار نیست. این بدان معناست شما نمی توانید از پکیج های مانند go-swagger, gqlgen یا سایر پروژه هایی که بخشی از اکوسیستم net/http هستند استفاده کنید.
@@ -527,7 +538,7 @@ func main() {
### JSON Response
-📖 [JSON](https://docs.gofiber.io/ctx#json)
+📖 [JSON](https://docs.gofiber.io/api/ctx#json)
@@ -617,7 +628,7 @@ func main() {
c.Context().SetBodyStreamWriter(fasthttp.StreamWriter(func(w *bufio.Writer) {
fmt.Println("WRITER")
var i int
-
+
for {
i++
msg := fmt.Sprintf("%d - the time is %v", i, time.Now())
@@ -663,6 +674,28 @@ func main() {
}
```
+### Using Trusted Proxy
+
+📖 [Config](https://docs.gofiber.io/api/fiber#config)
+
+```go
+import (
+ "github.com/gofiber/fiber/v2"
+ "github.com/gofiber/fiber/v2/middleware/recover"
+)
+
+func main() {
+ app := fiber.New(fiber.Config{
+ EnableTrustedProxyCheck: true,
+ TrustedProxies: []string{"0.0.0.0", "1.1.1.1/30"}, // IP address or IP address range
+ ProxyHeader: fiber.HeaderXForwardedFor,
+ })
+
+ // ...
+
+ log.Fatal(app.Listen(":3000"))
+}
+```
@@ -701,6 +734,11 @@ func main() {
| [session](https://github.com/gofiber/fiber/tree/master/middleware/session) |برای ذخیره و مدیریت شناسه کاربری یا session بازدید کنندگان استفاده .میشود|
| [skip](https://github.com/gofiber/fiber/tree/master/middleware/skip) |این میدلور میتواند با استفاده از شرط های تعیین شده درخواست هایی را نادیده بگیرد.|
| [timeout](https://github.com/gofiber/fiber/tree/master/middleware/timeout) |این میدلور محدودیت زمانی ای را برای درخواست ها تنظیم میکند، در صورتی که محدودیت به پایان برسد ErrorHandler صدا زده میشود.|
+| [keyauth](https://github.com/gofiber/keyauth) | این میدلور احراز هویت مبتنی بر کلید را فراهم می کند. |
+| [redirect](https://github.com/gofiber/redirect) | برای ریدایرکت کردن از این میدلور میتوانید استفاده کنید. |
+| [rewrite](https://github.com/gofiber/rewrite) | مسیر URL را براساس قوانین مشخص شده بازنویسی می کند. این میتواند برای سازگاری با ورژن های قبلی یا برای ساخت لینک های تمیز تر و توصیفی تر مفید باشد. |
+| [adaptor](https://github.com/gofiber/adaptor) | Converter for net/http handlers to/from Fiber request handlers, special thanks to @arsmn! |
+| [helmet](https://github.com/gofiber/helmet) | با استفاده از HTTP هدر های مختلف به ایمن سازی برنامه شما کمک می کند. |
@@ -717,19 +755,14 @@ func main() {
| Middleware | توضیحات |
| :------------------------------------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
-| [adaptor](https://github.com/gofiber/adaptor) | Converter for net/http handlers to/from Fiber request handlers, special thanks to @arsmn! |
-| [helmet](https://github.com/gofiber/helmet) | Helps secure your apps by setting various HTTP headers. |
| [jwt](https://github.com/gofiber/jwt) | JWT returns a JSON Web Token \(JWT\) auth middleware. |
-| [keyauth](https://github.com/gofiber/keyauth) | Key auth middleware provides a key based authentication. |
-| [redirect](https://github.com/gofiber/redirect) | Redirect middleware |
-| [rewrite](https://github.com/gofiber/rewrite) | Rewrite middleware rewrites the URL path based on provided rules. It can be helpful for backward compatibility or just creating cleaner and more descriptive links. |
| [storage](https://github.com/gofiber/storage) | Premade storage drivers that implement the Storage interface, designed to be used with various Fiber middlewares. |
| [template](https://github.com/gofiber/template) | This package contains 8 template engines that can be used with Fiber `v1.10.x` Go version 1.13 or higher is required. |
| [websocket](https://github.com/gofiber/websocket) | Based on Fasthttp WebSocket for Fiber with Locals support! |
## 🕶️ Awesome List
-For more articles, middlewares, examples or tools check our [awesome list](https://github.com/gofiber/awesome-fiber).
+ [awesome list](https://github.com/gofiber/awesome-fiber) برای مقاله، میدلور، مثال ها و ابزار های بیشتر لطفا از این لینک بازدید کنید
@@ -812,7 +845,6 @@ Copyright (c) 2019-present [Fenny](https://github.com/fenny) and [Contributors](
- [runewidth](https://github.com/mattn/go-runewidth/blob/master/LICENSE)
- [fasthttp](https://github.com/valyala/fasthttp/blob/master/LICENSE)
- [bytebufferpool](https://github.com/valyala/bytebufferpool/blob/master/LICENSE)
-- [dictpool](https://github.com/savsgio/dictpool/blob/master/LICENSE)
- [fwd](https://github.com/philhofer/fwd/blob/master/LICENSE.md)
- [go-ole](https://github.com/go-ole/go-ole/blob/master/LICENSE)
- [gopsutil](https://github.com/shirou/gopsutil/blob/master/LICENSE)
diff --git a/.github/README_fr.md b/.github/README_fr.md
index 11d3db369d..6229d13b1e 100644
--- a/.github/README_fr.md
+++ b/.github/README_fr.md
@@ -1,6 +1,11 @@
## ⚙️ התקנה
-Make sure you have Go installed ([download](https://go.dev/dl/)). Version `1.14` or higher is required.
+Make sure you have Go installed ([download](https://go.dev/dl/)). Version `1.17` or higher is required.
Initialize your project by creating a folder and then running `go mod init github.com/your/repo` ([learn more](https://go.dev/blog/using-go-modules)) inside the folder. Then install Fiber with the [`go get`](https://pkg.go.dev/cmd/go/#hdr-Add_dependencies_to_current_module_and_install_them) command:
@@ -144,14 +155,14 @@ go get -u github.com/gofiber/fiber/v3
-- [ניתוב](https://docs.gofiber.io/routing) רובסטי
+- [ניתוב](https://docs.gofiber.io/guide/routing) רובסטי
- הנגשת [קבצים סטטיים](https://docs.gofiber.io/api/app#static)
- [ביצועים](https://docs.gofiber.io/extra/benchmarks) גבוהים במיוחד
- צורך כמות [זכרון קטנה](https://docs.gofiber.io/extra/benchmarks)
- [נקודות קצה עבור API](https://docs.gofiber.io/api/ctx)
-- תמיכה ב-[Middleware](https://docs.gofiber.io/middleware) & [Next](https://docs.gofiber.io/api/ctx#next)
+- תמיכה ב-[Middleware](https://docs.gofiber.io/category/-middleware) & [Next](https://docs.gofiber.io/api/ctx#next)
- תכנות [מהיר](https://dev.to/koddr/welcome-to-fiber-an-express-js-styled-fastest-web-framework-written-with-on-golang-497) של צד שרת
-- [מנועי תבניות](https://docs.gofiber.io/middleware#template)
+- [מנועי תבניות](https://docs.gofiber.io/category/-middleware#template)
- [תמיכה ב-WebSocket](https://github.com/gofiber/websocket)
- [Server-Sent events](https://github.com/gofiber/recipes/tree/master/sse)
- [הגבלת קצבים ובקשות](https://docs.gofiber.io/api/middleware/limiter)
@@ -187,7 +198,7 @@ Fiber נוצרה **בהשראת** Express, ה-web framework הפופולרית
## ⚠️ Limitations
-* Due to Fiber's usage of unsafe, the library may not always be compatible with the latest Go version. Fiber 2.40.0 has been tested with Go versions 1.16 to 1.19.
+* Due to Fiber's usage of unsafe, the library may not always be compatible with the latest Go version. Fiber 2.40.0 has been tested with Go versions 1.17 to 1.20.
* Fiber is not compatible with net/http interfaces. This means you will not be able to use projects like gqlgen, go-swagger, or any others which are part of the net/http ecosystem.
## 👀 דוגמאות
@@ -523,7 +534,7 @@ func main() {
### תגובת JSON
-📖 [JSON](https://docs.gofiber.io/ctx#json)
+📖 [JSON](https://docs.gofiber.io/api/ctx#json)
@@ -617,7 +628,7 @@ func main() {
c.Context().SetBodyStreamWriter(fasthttp.StreamWriter(func(w *bufio.Writer) {
fmt.Println("WRITER")
var i int
-
+
for {
i++
msg := fmt.Sprintf("%d - the time is %v", i, time.Now())
@@ -704,6 +715,11 @@ Here is a list of middleware that are included within the Fiber framework.
| [session](https://github.com/gofiber/fiber/tree/master/middleware/session) | Session middleware. NOTE: This middleware uses our Storage package. |
| [skip](https://github.com/gofiber/fiber/tree/master/middleware/skip) | Skip middleware that skips a wrapped handler is a predicate is true. |
| [timeout](https://github.com/gofiber/fiber/tree/master/middleware/timeout) | Adds a max time for a request and forwards to ErrorHandler if it is exceeded. |
+| [keyauth](https://github.com/gofiber/keyauth) | Key auth middleware provides a key based authentication. |
+| [redirect](https://github.com/gofiber/redirect) | Redirect middleware |
+| [rewrite](https://github.com/gofiber/rewrite) | Rewrite middleware rewrites the URL path based on provided rules. It can be helpful for backward compatibility or just creating cleaner and more descriptive links. |
+| [adaptor](https://github.com/gofiber/adaptor) | Converter for net/http handlers to/from Fiber request handlers, special thanks to @arsmn! |
+| [helmet](https://github.com/gofiber/helmet) | Helps secure your apps by setting various HTTP headers. |
@@ -723,12 +739,7 @@ Here is a list of middleware that are included within the Fiber framework.
| Middleware | Description |
| :------------------------------------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
-| [adaptor](https://github.com/gofiber/adaptor) | Converter for net/http handlers to/from Fiber request handlers, special thanks to @arsmn! |
-| [helmet](https://github.com/gofiber/helmet) | Helps secure your apps by setting various HTTP headers. |
| [jwt](https://github.com/gofiber/jwt) | JWT returns a JSON Web Token \(JWT\) auth middleware. |
-| [keyauth](https://github.com/gofiber/keyauth) | Key auth middleware provides a key based authentication. |
-| [redirect](https://github.com/gofiber/redirect) | Redirect middleware |
-| [rewrite](https://github.com/gofiber/rewrite) | Rewrite middleware rewrites the URL path based on provided rules. It can be helpful for backward compatibility or just creating cleaner and more descriptive links. |
| [storage](https://github.com/gofiber/storage) | Premade storage drivers that implement the Storage interface, designed to be used with various Fiber middlewares. |
| [template](https://github.com/gofiber/template) | This package contains 8 template engines that can be used with Fiber `v1.10.x` Go version 1.13 or higher is required. |
| [websocket](https://github.com/gofiber/websocket) | Based on Fasthttp WebSocket for Fiber with Locals support! |
@@ -837,7 +848,6 @@ Copyright (c) 2019-present [Fenny](https://github.com/fenny) and [Contributors](
- [runewidth](https://github.com/mattn/go-runewidth/blob/master/LICENSE)
- [fasthttp](https://github.com/valyala/fasthttp/blob/master/LICENSE)
- [bytebufferpool](https://github.com/valyala/bytebufferpool/blob/master/LICENSE)
-- [dictpool](https://github.com/savsgio/dictpool/blob/master/LICENSE)
- [fwd](https://github.com/philhofer/fwd/blob/master/LICENSE.md)
- [go-ole](https://github.com/go-ole/go-ole/blob/master/LICENSE)
- [gopsutil](https://github.com/shirou/gopsutil/blob/master/LICENSE)
diff --git a/.github/README_id.md b/.github/README_id.md
index 84066b1ce8..4f31f2a7b5 100644
--- a/.github/README_id.md
+++ b/.github/README_id.md
@@ -1,6 +1,11 @@
+ Fiber — це веб фреймворк, який був натхненний Express
+ і заснований на Fasthttp, найшвидшому HTTP-двигунові написаному на
+ Go. Фреймворк розроблено з метою спростити процес швидкої розробки
+ високопродуктивних веб-додатків з нульовим розподілом пам'яті.
+
+
+## ⚡️ Швидкий старт
+
+```go
+package main
+
+import "github.com/gofiber/fiber/v2"
+
+func main() {
+ app := fiber.New()
+
+ app.Get("/", func(c *fiber.Ctx) error {
+ return c.SendString("Hello, World 👋!")
+ })
+
+ app.Listen(":3000")
+}
+```
+
+## 🤖 Еталонні показники
+
+Тестування проводилося за допомогою [TechEmpower](https://www.techempower.com/benchmarks/#section=data-r19&hw=ph&test=plaintext)
+та [Go Web](https://github.com/smallnest/go-web-framework-benchmark). Якщо ви хочете побачити всі результати, будь ласка
+відвідайте наш [Wiki](https://docs.gofiber.io/extra/benchmarks).
+
+
+
+
+
+
+## ⚙️ Встановлення
+
+Переконайтеся, що Go встановлено ([завантажити](https://go.dev/dl/)). Потрібна версія `1.17` або вища.
+
+Ініціалізуйте проект, створивши папку, а потім запустивши `go mod init github.com/your/repo`
+([детальніше](https://go.dev/blog/using-go-modules)) всередині цієї папки. Далі встановіть Fiber за допомогою
+команди [`go get`](https://pkg.go.dev/cmd/go/#hdr-Add_dependencies_to_current_module_and_install_them):
+
+```bash
+go get -u github.com/gofiber/fiber/v2
+```
+
+## 🎯 Особливості
+
+- Надійна [маршрутизація](https://docs.gofiber.io/routing)
+- Доступ до [статичних файлів](https://docs.gofiber.io/api/app#static)
+- Екстремальна [продуктивність](https://docs.gofiber.io/extra/benchmarks)
+- [Низький обсяг споживання пам'яті](https://docs.gofiber.io/extra/benchmarks)
+- [Кінцеві точки API](https://docs.gofiber.io/api/ctx)
+- [Middleware](https://docs.gofiber.io/middleware) та підтримка [Next](https://docs.gofiber.io/api/ctx#next)
+- [Швидке](https://dev.to/koddr/welcome-to-fiber-an-express-js-styled-fastest-web-framework-written-with-on-golang-497) програмування на стороні сервера
+- [Двигуни шаблонів](https://github.com/gofiber/template)
+- [Підтримка WebSocket](https://github.com/gofiber/websocket)
+- [Server-Sent Events](https://github.com/gofiber/recipes/tree/master/sse)
+- [Обмежувач швидкості](https://docs.gofiber.io/api/middleware/limiter)
+- Документація доступна [18 мовами](https://docs.gofiber.io/)
+- І багато іншого, [відвідайте наш Wiki](https://docs.gofiber.io/)
+
+## 💡 Філософія
+
+Нові програмісти, які переходять із [Node.js](https://nodejs.org/en/about/) на [Go](https://go.dev/doc/), мають справу зі звивистою кривою навчання, перш ніж можуть розпочати створення своїх веб-додатків або мікросервісів. Fiber, як **веб-фреймворк**, було створено з ідеєю **мінімалізму** та слідує **шляху UNIX**, щоб нові програмісти могли швидко увійти у світ Go з теплим та надійним прийомом.
+
+Fiber **натхненний** Express, найпопулярнішим веб-фреймворком в Інтернеті. Ми поєднали **легкість** Express і **чисту продуктивність** Go. Якщо ви коли-небудь реалізовували веб-додаток у Node.js (_з використанням Express або подібного_), то багато методів і принципів здадуться вам **дуже звичайними**.
+
+Ми **прислухаємося** до наших користувачів у [issues](https://github.com/gofiber/fiber/issues), Discord [сервері](https://gofiber.io/discord) та в інших місцях Інтернета, щоб створити **швидкий**, **гнучкий** та **доброзичливий** веб фреймворк на Go для **будь-яких** завдань, **дедлайнів** та **рівнів** розробників! Як це робить Express у світі JavaScript.
+
+## ⚠️ Обмеження
+
+- Через те, що Fiber використовує unsafe, бібліотека не завжди може бути сумісною з останньою версією Go. Fiber 2.40.0 було протестовано з Go версій 1.17 до 1.20.
+- Fiber не сумісний з інтерфейсами net/http. Це означає, що ви не зможете використовувати такі проекти, як gqlgen, go-swagger або будь-які інші, які є частиною екосистеми net/http.
+
+## 👀 Приклади
+
+Нижче наведено деякі типові приклади. Якщо ви хочете переглянути більше прикладів коду, відвідайте наше [репозиторій рецептів](https://github.com/gofiber/recipes) або відвідайте нашу розміщену [документацію API](https://docs.gofiber.io).
+
+#### 📖 [**Основна маршрутизація**](https://docs.gofiber.io/#basic-routing)
+
+```go
+func main() {
+ app := fiber.New()
+
+ // GET /api/register
+ app.Get("/api/*", func(c *fiber.Ctx) error {
+ msg := fmt.Sprintf("✋ %s", c.Params("*"))
+ return c.SendString(msg) // => ✋ register
+ })
+
+ // GET /flights/LAX-SFO
+ app.Get("/flights/:from-:to", func(c *fiber.Ctx) error {
+ msg := fmt.Sprintf("💸 From: %s, To: %s", c.Params("from"), c.Params("to"))
+ return c.SendString(msg) // => 💸 From: LAX, To: SFO
+ })
+
+ // GET /dictionary.txt
+ app.Get("/:file.:ext", func(c *fiber.Ctx) error {
+ msg := fmt.Sprintf("📃 %s.%s", c.Params("file"), c.Params("ext"))
+ return c.SendString(msg) // => 📃 dictionary.txt
+ })
+
+ // GET /john/75
+ app.Get("/:name/:age/:gender?", func(c *fiber.Ctx) error {
+ msg := fmt.Sprintf("👴 %s is %s years old", c.Params("name"), c.Params("age"))
+ return c.SendString(msg) // => 👴 john is 75 years old
+ })
+
+ // GET /john
+ app.Get("/:name", func(c *fiber.Ctx) error {
+ msg := fmt.Sprintf("Hello, %s 👋!", c.Params("name"))
+ return c.SendString(msg) // => Hello john 👋!
+ })
+
+ log.Fatal(app.Listen(":3000"))
+}
+```
+
+#### 📖 [**Назви маршруту**](https://docs.gofiber.io/api/app#name)
+
+```go
+func main() {
+ app := fiber.New()
+
+ // GET /api/register
+ app.Get("/api/*", func(c *fiber.Ctx) error {
+ msg := fmt.Sprintf("✋ %s", c.Params("*"))
+ return c.SendString(msg) // => ✋ register
+ }).Name("api")
+
+ data, _ := json.MarshalIndent(app.GetRoute("api"), "", " ")
+ fmt.Print(string(data))
+ // Prints:
+ // {
+ // "method": "GET",
+ // "name": "api",
+ // "path": "/api/*",
+ // "params": [
+ // "*1"
+ // ]
+ // }
+
+
+ log.Fatal(app.Listen(":3000"))
+}
+```
+
+#### 📖 [**Обслуговування статичних файлів**](https://docs.gofiber.io/api/app#static)
+
+```go
+func main() {
+ app := fiber.New()
+
+ app.Static("/", "./public")
+ // => http://localhost:3000/js/script.js
+ // => http://localhost:3000/css/style.css
+
+ app.Static("/prefix", "./public")
+ // => http://localhost:3000/prefix/js/script.js
+ // => http://localhost:3000/prefix/css/style.css
+
+ app.Static("*", "./public/index.html")
+ // => http://localhost:3000/any/path/shows/index/html
+
+ log.Fatal(app.Listen(":3000"))
+}
+```
+
+#### 📖 [**Middleware & Next**](https://docs.gofiber.io/api/ctx#next)
+
+```go
+func main() {
+ app := fiber.New()
+
+ // Match any route
+ app.Use(func(c *fiber.Ctx) error {
+ fmt.Println("🥇 First handler")
+ return c.Next()
+ })
+
+ // Match all routes starting with /api
+ app.Use("/api", func(c *fiber.Ctx) error {
+ fmt.Println("🥈 Second handler")
+ return c.Next()
+ })
+
+ // GET /api/list
+ app.Get("/api/list", func(c *fiber.Ctx) error {
+ fmt.Println("🥉 Last handler")
+ return c.SendString("Hello, World 👋!")
+ })
+
+ log.Fatal(app.Listen(":3000"))
+}
+```
+
+
+ 📚 Показати більше прикладів коду
+
+### Двигуни перегляду
+
+📖 [Конфігурація](https://docs.gofiber.io/api/fiber#config)
+📖 [Двигуни](https://github.com/gofiber/template)
+📖 [Рендер](https://docs.gofiber.io/api/ctx#render)
+
+Fiber за умовчанням використовує [html/template](https://pkg.go.dev/html/template/), якщо жодного двигуна не було вказано.
+
+Якщо ви хочете виконати частково або використовувати інший двигун, наприклад [amber](https://github.com/eknkc/amber), [handlebars](https://github.com/aymerick/raymond), [mustache]( https://github.com/cbroglie/mustache) або [jade](https://github.com/Joker/jade), тощо.
+
+Перегляньте наш пакет [Шаблон](https://github.com/gofiber/template), який підтримує кілька двигунів перегляду.
+
+```go
+package main
+
+import (
+ "github.com/gofiber/fiber/v2"
+ "github.com/gofiber/template/pug"
+)
+
+func main() {
+ // You can setup Views engine before initiation app:
+ app := fiber.New(fiber.Config{
+ Views: pug.New("./views", ".pug"),
+ })
+
+ // And now, you can call template `./views/home.pug` like this:
+ app.Get("/", func(c *fiber.Ctx) error {
+ return c.Render("home", fiber.Map{
+ "title": "Homepage",
+ "year": 1999,
+ })
+ })
+
+ log.Fatal(app.Listen(":3000"))
+}
+```
+
+### Групування маршрутів у ланцюги
+
+📖 [Група](https://docs.gofiber.io/api/app#group)
+
+```go
+func middleware(c *fiber.Ctx) error {
+ fmt.Println("Don't mind me!")
+ return c.Next()
+}
+
+func handler(c *fiber.Ctx) error {
+ return c.SendString(c.Path())
+}
+
+func main() {
+ app := fiber.New()
+
+ // Root API route
+ api := app.Group("/api", middleware) // /api
+
+ // API v1 routes
+ v1 := api.Group("/v1", middleware) // /api/v1
+ v1.Get("/list", handler) // /api/v1/list
+ v1.Get("/user", handler) // /api/v1/user
+
+ // API v2 routes
+ v2 := api.Group("/v2", middleware) // /api/v2
+ v2.Get("/list", handler) // /api/v2/list
+ v2.Get("/user", handler) // /api/v2/user
+
+ // ...
+}
+```
+
+### Middleware логування
+
+📖 [Логування](https://docs.gofiber.io/api/middleware/logger)
+
+```go
+package main
+
+import (
+ "log"
+
+ "github.com/gofiber/fiber/v2"
+ "github.com/gofiber/fiber/v2/middleware/logger"
+)
+
+func main() {
+ app := fiber.New()
+
+ app.Use(logger.New())
+
+ // ...
+
+ log.Fatal(app.Listen(":3000"))
+}
+```
+
+### Спільне використання ресурсів між джерелами (CORS)
+
+📖 [CORS](https://docs.gofiber.io/api/middleware/cors)
+
+```go
+import (
+ "log"
+
+ "github.com/gofiber/fiber/v2"
+ "github.com/gofiber/fiber/v2/middleware/cors"
+)
+
+func main() {
+ app := fiber.New()
+
+ app.Use(cors.New())
+
+ // ...
+
+ log.Fatal(app.Listen(":3000"))
+}
+```
+
+Перевірте CORS, передавши будь-який домен у заголовку `Origin`:
+
+```bash
+curl -H "Origin: http://example.com" --verbose http://localhost:3000
+```
+
+### Власна відповідь 404
+
+📖 [HTTP Методи](https://docs.gofiber.io/api/ctx#status)
+
+```go
+func main() {
+ app := fiber.New()
+
+ app.Static("/", "./public")
+
+ app.Get("/demo", func(c *fiber.Ctx) error {
+ return c.SendString("This is a demo!")
+ })
+
+ app.Post("/register", func(c *fiber.Ctx) error {
+ return c.SendString("Welcome!")
+ })
+
+ // Last middleware to match anything
+ app.Use(func(c *fiber.Ctx) error {
+ return c.SendStatus(404)
+ // => 404 "Not Found"
+ })
+
+ log.Fatal(app.Listen(":3000"))
+}
+```
+
+### JSON Відповідь
+
+📖 [JSON](https://docs.gofiber.io/ctx#json)
+
+```go
+type User struct {
+ Name string `json:"name"`
+ Age int `json:"age"`
+}
+
+func main() {
+ app := fiber.New()
+
+ app.Get("/user", func(c *fiber.Ctx) error {
+ return c.JSON(&User{"John", 20})
+ // => {"name":"John", "age":20}
+ })
+
+ app.Get("/json", func(c *fiber.Ctx) error {
+ return c.JSON(fiber.Map{
+ "success": true,
+ "message": "Hi John!",
+ })
+ // => {"success":true, "message":"Hi John!"}
+ })
+
+ log.Fatal(app.Listen(":3000"))
+}
+```
+
+### WebSocket Upgrade
+
+📖 [Websocket](https://github.com/gofiber/websocket)
+
+```go
+import (
+ "github.com/gofiber/fiber/v2"
+ "github.com/gofiber/fiber/v2/middleware/websocket"
+)
+
+func main() {
+ app := fiber.New()
+
+ app.Get("/ws", websocket.New(func(c *websocket.Conn) {
+ for {
+ mt, msg, err := c.ReadMessage()
+ if err != nil {
+ log.Println("read:", err)
+ break
+ }
+ log.Printf("recv: %s", msg)
+ err = c.WriteMessage(mt, msg)
+ if err != nil {
+ log.Println("write:", err)
+ break
+ }
+ }
+ }))
+
+ log.Fatal(app.Listen(":3000"))
+ // ws://localhost:3000/ws
+}
+```
+
+### Server-Sent Events
+
+📖 [Більше інформації](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events)
+
+```go
+import (
+ "github.com/gofiber/fiber/v2"
+ "github.com/valyala/fasthttp"
+)
+
+func main() {
+ app := fiber.New()
+
+ app.Get("/sse", func(c *fiber.Ctx) error {
+ c.Set("Content-Type", "text/event-stream")
+ c.Set("Cache-Control", "no-cache")
+ c.Set("Connection", "keep-alive")
+ c.Set("Transfer-Encoding", "chunked")
+
+ c.Context().SetBodyStreamWriter(fasthttp.StreamWriter(func(w *bufio.Writer) {
+ fmt.Println("WRITER")
+ var i int
+
+ for {
+ i++
+ msg := fmt.Sprintf("%d - the time is %v", i, time.Now())
+ fmt.Fprintf(w, "data: Message: %s\n\n", msg)
+ fmt.Println(msg)
+
+ w.Flush()
+ time.Sleep(5 * time.Second)
+ }
+ }))
+
+ return nil
+ })
+
+ log.Fatal(app.Listen(":3000"))
+}
+```
+
+### Recover middleware
+
+📖 [Recover](https://docs.gofiber.io/api/middleware/recover)
+
+```go
+import (
+ "github.com/gofiber/fiber/v2"
+ "github.com/gofiber/fiber/v2/middleware/recover"
+)
+
+func main() {
+ app := fiber.New()
+
+ app.Use(recover.New())
+
+ app.Get("/", func(c *fiber.Ctx) error {
+ panic("normally this would crash your app")
+ })
+
+ log.Fatal(app.Listen(":3000"))
+}
+```
+
+
+
+### Використання довіреного проксі
+
+📖 [Конфігурація](https://docs.gofiber.io/api/fiber#config)
+
+```go
+import (
+ "github.com/gofiber/fiber/v2"
+ "github.com/gofiber/fiber/v2/middleware/recover"
+)
+
+func main() {
+ app := fiber.New(fiber.Config{
+ EnableTrustedProxyCheck: true,
+ TrustedProxies: []string{"0.0.0.0", "1.1.1.1/30"}, // IP address or IP address range
+ ProxyHeader: fiber.HeaderXForwardedFor,
+ })
+
+ // ...
+
+ log.Fatal(app.Listen(":3000"))
+}
+```
+
+
+
+## 🧬 Внутрішні Middleware
+
+Ось список middleware, яке входить до складу Fiber фреймворку.
+
+| Middleware | Опис |
+|:---------------------------------------------------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| [basicauth](https://github.com/gofiber/fiber/tree/master/middleware/basicauth) | Middleware який забезпечує базову автентифікацію по HTTP. |
+| [cache](https://github.com/gofiber/fiber/tree/master/middleware/cache) | Middleware який перехоплює та кешує відповіді |
+| [compress](https://github.com/gofiber/fiber/tree/master/middleware/compress) | стиснення для Fiber, воно за замовчуванням підтримує `deflate`, `gzip` і `brotli`. |
+| [cors](https://github.com/gofiber/fiber/tree/master/middleware/cors) | Middleware який вмикає перехресне використання ресурсів \(CORS\) із різними параметрами. |
+| [csrf](https://github.com/gofiber/fiber/tree/master/middleware/csrf) | Захист від експлойтів CSRF. |
+| [encryptcookie](https://github.com/gofiber/fiber/tree/master/middleware/encryptcookie) | Шифрування значень файлів cookie. |
+| [envvar](https://github.com/gofiber/fiber/tree/master/middleware/envvar) | Middleware для відкриття змінних середевищ. |
+| [etag](https://github.com/gofiber/fiber/tree/master/middleware/etag) | Middleware яке робить кеш-пам’ять більш ефективним і заощаджує пропускну здатність, оскільки веб-серверу не потрібно повторно надсилати повну відповідь, якщо вміст не змінився. |
+| [expvar](https://github.com/gofiber/fiber/tree/master/middleware/expvar) | Middleware який обслуговує доступні варіанти середовища виконання HTTP у форматі JSON. |
+| [favicon](https://github.com/gofiber/fiber/tree/master/middleware/favicon) | Ігнорування значка із журналів або обслуговувати з пам’яті, якщо вказано шлях до файлу. |
+| [filesystem](https://github.com/gofiber/fiber/tree/master/middleware/filesystem) | Middleware файлової системи, особлива подяка та кредити Alireza Salary. |
+| [limiter](https://github.com/gofiber/fiber/tree/master/middleware/limiter) | Ообмеження швидкості для Fiber. Використовуйте для обмеження повторних запитів до загальнодоступних API та/або кінцевих точок, таких як скидання пароля. |
+| [logger](https://github.com/gofiber/fiber/tree/master/middleware/logger) | Реєстратор запитів/відповідей HTTP. |
+| [monitor](https://github.com/gofiber/fiber/tree/master/middleware/monitor) | Middleware який повідомляє показники сервера. |
+| [pprof](https://github.com/gofiber/fiber/tree/master/middleware/pprof) | Особлива подяка Метью Лі \(@mthli\) . |
+| [proxy](https://github.com/gofiber/fiber/tree/master/middleware/proxy) | Дозволяє надсилати проксі-запити до кількох серверів. |
+| [recover](https://github.com/gofiber/fiber/tree/master/middleware/recover) | Middleware який відновлює паніки будь-де в ланцюжку стека та передає керування централізованому [обробнику помилок](https://docs.gofiber.io/guide/error-handling). |
+| [requestid](https://github.com/gofiber/fiber/tree/master/middleware/requestid) | До кожного запиту додає ідентифікатор запиту. |
+| [session](https://github.com/gofiber/fiber/tree/master/middleware/session) | Middleware для сеансів. ПРИМІТКА: Цей middleware використовує наш пакет зберігання. |
+| [skip](https://github.com/gofiber/fiber/tree/master/middleware/skip) | Middleware який пропускає упакований обробник, якщо предикат є істинним. |
+| [timeout](https://github.com/gofiber/fiber/tree/master/middleware/timeout) | Додає максимальний час для запиту та пересилає до ErrorHandler, якщо його перевищено. |
+| [keyauth](https://github.com/gofiber/keyauth) | Middleware для автентифікації по ключам. |
+| [redirect](https://github.com/gofiber/redirect) | Middleware для перенаправлення. |
+| [rewrite](https://github.com/gofiber/rewrite) | Middleware для перезапису URL-адреси на основі наданих правил. |
+| [adaptor](https://github.com/gofiber/adaptor) | Конвентор для обробників net/http до/з обробників запитів Fiber, особлива подяка @arsmn! |
+| [helmet](https://github.com/gofiber/helmet) | Допомагає захистити ваші програми, встановлюючи різні заголовки HTTP. |
+
+## 🧬 Зовнішні Middleware
+
+Список зовнішніх middleware модулів, які підтримуються [командою Fiber](https://github.com/orgs/gofiber/people).
+
+| Middleware | Опис |
+| :------------------------------------------------ | :-------------------------------------------------------------------------------------------------------------------- |
+| [jwt](https://github.com/gofiber/jwt) | JWT повертає middleware автентифікації JSON Web Token \(JWT\). |
+| [storage](https://github.com/gofiber/storage) | Драйвер зберігання який може використовуватися в різних middleware. |
+| [template](https://github.com/gofiber/template) | Цей пакет містить 8 модулів шаблонів, які можна використовувати з Fiber `v1.10.x` Потрібно версія Go 1.13 або новішу. |
+| [websocket](https://github.com/gofiber/websocket) | На основі Fasthttp WebSocket для Fiber з підтримкою місцевих користувачів! |
+
+## 🕶️ Чудовий список
+
+Більше статей, middleware, прикладів або інструментів дивіться у нашому [чудовому списку](https://github.com/gofiber/awesome-fiber).
+
+## 👍 Внести свій внесок
+
+Якщо ви хочете сказати **дякую** та/або підтримати активний розвиток `Fiber`:
+
+1. Додайте [зірку GitHub](https://github.com/gofiber/fiber/stargazers) до проекту.
+2. Напишіть про проект [у своєму Twitter](https://twitter.com/intent/tweet?text=Fiber%20is%20an%20Express%20inspired%20%23web%20%23framework%20built%20on%20top%20of%20Fasthttp%2C%20the%20fastest%20HTTP%20engine%20for%20%23Go.%20Designed%20to%20ease%20things%20up%20for%20%23fast%20development%20with%20zero%20memory%20allocation%20and%20%23performance%20in%20mind%20%F0%9F%9A%80%20https%3A%2F%2Fgithub.com%2Fgofiber%2Ffiber).
+3. Напишіть огляд або підручник на [Medium](https://medium.com/), [Dev.to](https://dev.to/) або особистому блогу.
+4. Підтримайте проект, пожертвувавши [чашку кави](https://buymeacoff.ee/fenny).
+
+## ☕ Прихильники
+
+Fiber – це проект із відкритим вихідним кодом, який працює за рахунок пожертвувань для оплати рахунків, наприклад наше доменне ім’я, gitbook, netlify і безсерверний хостинг. Якщо ви хочете підтримати Fiber, ви можете ☕ [**купити каву тут**](https://buymeacoff.ee/fenny).
+
+| | Користувач | Пожертвування |
+| :--------------------------------------------------------- | :----------------------------------------------- | :------------ |
+| ![](https://avatars.githubusercontent.com/u/204341?s=25) | [@destari](https://github.com/destari) | ☕ x 10 |
+| ![](https://avatars.githubusercontent.com/u/63164982?s=25) | [@dembygenesis](https://github.com/dembygenesis) | ☕ x 5 |
+| ![](https://avatars.githubusercontent.com/u/56607882?s=25) | [@thomasvvugt](https://github.com/thomasvvugt) | ☕ x 5 |
+| ![](https://avatars.githubusercontent.com/u/27820675?s=25) | [@hendratommy](https://github.com/hendratommy) | ☕ x 5 |
+| ![](https://avatars.githubusercontent.com/u/1094221?s=25) | [@ekaputra07](https://github.com/ekaputra07) | ☕ x 5 |
+| ![](https://avatars.githubusercontent.com/u/194590?s=25) | [@jorgefuertes](https://github.com/jorgefuertes) | ☕ x 5 |
+| ![](https://avatars.githubusercontent.com/u/186637?s=25) | [@candidosales](https://github.com/candidosales) | ☕ x 5 |
+| ![](https://avatars.githubusercontent.com/u/29659953?s=25) | [@l0nax](https://github.com/l0nax) | ☕ x 3 |
+| ![](https://avatars.githubusercontent.com/u/635852?s=25) | [@bihe](https://github.com/bihe) | ☕ x 3 |
+| ![](https://avatars.githubusercontent.com/u/307334?s=25) | [@justdave](https://github.com/justdave) | ☕ x 3 |
+| ![](https://avatars.githubusercontent.com/u/11155743?s=25) | [@koddr](https://github.com/koddr) | ☕ x 1 |
+| ![](https://avatars.githubusercontent.com/u/29042462?s=25) | [@lapolinar](https://github.com/lapolinar) | ☕ x 1 |
+| ![](https://avatars.githubusercontent.com/u/2978730?s=25) | [@diegowifi](https://github.com/diegowifi) | ☕ x 1 |
+| ![](https://avatars.githubusercontent.com/u/44171355?s=25) | [@ssimk0](https://github.com/ssimk0) | ☕ x 1 |
+| ![](https://avatars.githubusercontent.com/u/5638101?s=25) | [@raymayemir](https://github.com/raymayemir) | ☕ x 1 |
+| ![](https://avatars.githubusercontent.com/u/619996?s=25) | [@melkorm](https://github.com/melkorm) | ☕ x 1 |
+| ![](https://avatars.githubusercontent.com/u/31022056?s=25) | [@marvinjwendt](https://github.com/marvinjwendt) | ☕ x 1 |
+| ![](https://avatars.githubusercontent.com/u/31921460?s=25) | [@toishy](https://github.com/toishy) | ☕ x 1 |
+
+## 💻 Автори коду
+
+
+
+## ⭐️ Звіздарі
+
+
+
+## ⚠️ Ліцензія
+
+Авторське право (c) 2019-дотепер [Fenny](https://github.com/fenny) та [Contributors](https://github.com/gofiber/fiber/graphs/contributors). `Fiber` це безкоштовне програмне забезпечення з відкритим вихідним кодом, ліцензоване згідно [MIT License](https://github.com/gofiber/fiber/blob/master/LICENSE). Офіційний логотип створено [Vic Shóstak](https://github.com/koddr) і поширюється під [Creative Commons](https://creativecommons.org/licenses/by-sa/4.0/) ліцензією (CC BY-SA 4.0 International).
+
+**Ліцензії сторонніх бібліотек**
+
+- [colorable](https://github.com/mattn/go-colorable/blob/master/LICENSE)
+- [isatty](https://github.com/mattn/go-isatty/blob/master/LICENSE)
+- [runewidth](https://github.com/mattn/go-runewidth/blob/master/LICENSE)
+- [fasthttp](https://github.com/valyala/fasthttp/blob/master/LICENSE)
+- [bytebufferpool](https://github.com/valyala/bytebufferpool/blob/master/LICENSE)
+- [fwd](https://github.com/philhofer/fwd/blob/master/LICENSE.md)
+- [go-ole](https://github.com/go-ole/go-ole/blob/master/LICENSE)
+- [gopsutil](https://github.com/shirou/gopsutil/blob/master/LICENSE)
+- [msgp](https://github.com/tinylib/msgp/blob/master/LICENSE)
+- [schema](https://github.com/gorilla/schema/blob/master/LICENSE)
+- [uuid](https://github.com/google/uuid/blob/master/LICENSE)
+- [wmi](https://github.com/StackExchange/wmi/blob/master/LICENSE)
diff --git a/.github/README_zh-CN.md b/.github/README_zh-CN.md
index 4c7fd347e9..d9122531d9 100644
--- a/.github/README_zh-CN.md
+++ b/.github/README_zh-CN.md
@@ -1,6 +1,11 @@
", string(c.Response().Body()))
}
func Test_Ctx_RenderWithLocalsAndBinding(t *testing.T) {
@@ -2500,10 +2722,10 @@ func Benchmark_Ctx_RenderWithLocalsAndBindVars(b *testing.B) {
})
c := app.NewCtx(&fasthttp.RequestCtx{})
- c.BindVars(Map{
+ err = c.BindVars(Map{
"Title": "Hello, World!",
})
- require.Equal(b, nil, err)
+ require.NoError(b, err)
c.Locals("Summary", "Test")
b.ReportAllocs()
@@ -2548,10 +2770,10 @@ func Benchmark_Ctx_RenderBindVars(b *testing.B) {
app.config.Views = engine
c := app.NewCtx(&fasthttp.RequestCtx{})
- c.BindVars(Map{
+ err = c.BindVars(Map{
"Title": "Hello, World!",
})
- require.Equal(b, nil, err)
+ require.NoError(b, err)
b.ReportAllocs()
b.ResetTimer()
@@ -2566,6 +2788,7 @@ func Benchmark_Ctx_RenderBindVars(b *testing.B) {
// go test -run Test_Ctx_RestartRouting
func Test_Ctx_RestartRouting(t *testing.T) {
+ t.Parallel()
app := New()
calls := 0
app.Get("/", func(c Ctx) error {
@@ -2583,9 +2806,9 @@ func Test_Ctx_RestartRouting(t *testing.T) {
// go test -run Test_Ctx_RestartRoutingWithChangedPath
func Test_Ctx_RestartRoutingWithChangedPath(t *testing.T) {
+ t.Parallel()
app := New()
- executedOldHandler := false
- executedNewHandler := false
+ var executedOldHandler, executedNewHandler bool
app.Get("/old", func(c Ctx) error {
c.Path("/new")
@@ -2609,6 +2832,7 @@ func Test_Ctx_RestartRoutingWithChangedPath(t *testing.T) {
// go test -run Test_Ctx_RestartRoutingWithChangedPathAnd404
func Test_Ctx_RestartRoutingWithChangedPathAndCatchAll(t *testing.T) {
+ t.Parallel()
app := New()
app.Get("/new", func(c Ctx) error {
return nil
@@ -2634,10 +2858,18 @@ type testTemplateEngine struct {
func (t *testTemplateEngine) Render(w io.Writer, name string, bind any, layout ...string) error {
if len(layout) == 0 {
- return t.templates.ExecuteTemplate(w, name, bind)
+ if err := t.templates.ExecuteTemplate(w, name, bind); err != nil {
+ return fmt.Errorf("failed to execute template without layout: %w", err)
+ }
+ return nil
+ }
+ if err := t.templates.ExecuteTemplate(w, name, bind); err != nil {
+ return fmt.Errorf("failed to execute template: %w", err)
}
- _ = t.templates.ExecuteTemplate(w, name, bind)
- return t.templates.ExecuteTemplate(w, layout[0], bind)
+ if err := t.templates.ExecuteTemplate(w, layout[0], bind); err != nil {
+ return fmt.Errorf("failed to execute template with layout: %w", err)
+ }
+ return nil
}
func (t *testTemplateEngine) Load() error {
@@ -2650,6 +2882,7 @@ func (t *testTemplateEngine) Load() error {
// go test -run Test_Ctx_Render_Engine
func Test_Ctx_Render_Engine(t *testing.T) {
+ t.Parallel()
engine := &testTemplateEngine{}
require.Equal(t, nil, engine.Load())
app := New()
@@ -2665,6 +2898,7 @@ func Test_Ctx_Render_Engine(t *testing.T) {
// go test -run Test_Ctx_Render_Engine_With_View_Layout
func Test_Ctx_Render_Engine_With_View_Layout(t *testing.T) {
+ t.Parallel()
engine := &testTemplateEngine{}
require.Equal(t, nil, engine.Load())
app := New(Config{ViewsLayout: "main.tmpl"})
@@ -2701,7 +2935,7 @@ func Benchmark_Ctx_Render_Engine(b *testing.B) {
// go test -v -run=^$ -bench=Benchmark_Ctx_Get_Location_From_Route -benchmem -count=4
func Benchmark_Ctx_Get_Location_From_Route(b *testing.B) {
app := New()
- c := app.NewCtx(&fasthttp.RequestCtx{}).(*DefaultCtx)
+ c := app.NewCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed
app.Get("/user/:name", func(c Ctx) error {
return c.SendString(c.Params("name"))
@@ -2712,14 +2946,17 @@ func Benchmark_Ctx_Get_Location_From_Route(b *testing.B) {
for n := 0; n < b.N; n++ {
location, err = c.getLocationFromRoute(app.GetRoute("User"), Map{"name": "fiber"})
}
+
require.Equal(b, "/user/fiber", location)
require.Equal(b, nil, err)
-
}
// go test -run Test_Ctx_Get_Location_From_Route_name
func Test_Ctx_Get_Location_From_Route_name(t *testing.T) {
+ t.Parallel()
+
t.Run("case insensitive", func(t *testing.T) {
+ t.Parallel()
app := New()
c := app.NewCtx(&fasthttp.RequestCtx{})
app.Get("/user/:name", func(c Ctx) error {
@@ -2736,6 +2973,7 @@ func Test_Ctx_Get_Location_From_Route_name(t *testing.T) {
})
t.Run("case sensitive", func(t *testing.T) {
+ t.Parallel()
app := New(Config{CaseSensitive: true})
c := app.NewCtx(&fasthttp.RequestCtx{})
defer app.ReleaseCtx(c)
@@ -2755,6 +2993,7 @@ func Test_Ctx_Get_Location_From_Route_name(t *testing.T) {
// go test -run Test_Ctx_Get_Location_From_Route_name_Optional_greedy
func Test_Ctx_Get_Location_From_Route_name_Optional_greedy(t *testing.T) {
+ t.Parallel()
app := New()
c := app.NewCtx(&fasthttp.RequestCtx{})
@@ -2773,6 +3012,7 @@ func Test_Ctx_Get_Location_From_Route_name_Optional_greedy(t *testing.T) {
// go test -run Test_Ctx_Get_Location_From_Route_name_Optional_greedy_one_param
func Test_Ctx_Get_Location_From_Route_name_Optional_greedy_one_param(t *testing.T) {
+ t.Parallel()
app := New()
c := app.NewCtx(&fasthttp.RequestCtx{})
@@ -2790,14 +3030,15 @@ func Test_Ctx_Get_Location_From_Route_name_Optional_greedy_one_param(t *testing.
type errorTemplateEngine struct{}
-func (t errorTemplateEngine) Render(w io.Writer, name string, bind any, layout ...string) error {
+func (errorTemplateEngine) Render(_ io.Writer, _ string, _ any, _ ...string) error {
return errors.New("errorTemplateEngine")
}
-func (t errorTemplateEngine) Load() error { return nil }
+func (errorTemplateEngine) Load() error { return nil }
// go test -run Test_Ctx_Render_Engine_Error
func Test_Ctx_Render_Engine_Error(t *testing.T) {
+ t.Parallel()
app := New()
app.config.Views = errorTemplateEngine{}
c := app.NewCtx(&fasthttp.RequestCtx{})
@@ -2809,10 +3050,12 @@ func Test_Ctx_Render_Engine_Error(t *testing.T) {
// go test -run Test_Ctx_Render_Go_Template
func Test_Ctx_Render_Go_Template(t *testing.T) {
t.Parallel()
-
file, err := os.CreateTemp(os.TempDir(), "fiber")
require.NoError(t, err)
- defer os.Remove(file.Name())
+ defer func() {
+ err := os.Remove(file.Name())
+ require.NoError(t, err)
+ }()
_, err = file.Write([]byte("template"))
require.NoError(t, err)
@@ -2887,13 +3130,16 @@ func Test_Ctx_SendStream(t *testing.T) {
app := New()
c := app.NewCtx(&fasthttp.RequestCtx{})
- c.SendStream(bytes.NewReader([]byte("Don't crash please")))
+ err := c.SendStream(bytes.NewReader([]byte("Don't crash please")))
+ require.NoError(t, err)
require.Equal(t, "Don't crash please", string(c.Response().Body()))
- c.SendStream(bytes.NewReader([]byte("Don't crash please")), len([]byte("Don't crash please")))
+ err = c.SendStream(bytes.NewReader([]byte("Don't crash please")), len([]byte("Don't crash please")))
+ require.NoError(t, err)
require.Equal(t, "Don't crash please", string(c.Response().Body()))
- c.SendStream(bufio.NewReader(bytes.NewReader([]byte("Hello bufio"))))
+ err = c.SendStream(bufio.NewReader(bytes.NewReader([]byte("Hello bufio"))))
+ require.NoError(t, err)
require.Equal(t, "Hello bufio", string(c.Response().Body()))
}
@@ -2989,7 +3235,7 @@ func Benchmark_Ctx_Type(b *testing.B) {
// go test -v -run=^$ -bench=Benchmark_Ctx_Type_Charset -benchmem -count=4
func Benchmark_Ctx_Type_Charset(b *testing.B) {
app := New()
- c := app.NewCtx(&fasthttp.RequestCtx{}).(*DefaultCtx)
+ c := app.NewCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed
b.ReportAllocs()
b.ResetTimer()
@@ -3014,7 +3260,7 @@ func Test_Ctx_Vary(t *testing.T) {
// go test -v -run=^$ -bench=Benchmark_Ctx_Vary -benchmem -count=4
func Benchmark_Ctx_Vary(b *testing.B) {
app := New()
- c := app.NewCtx(&fasthttp.RequestCtx{}).(*DefaultCtx)
+ c := app.NewCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed
b.ReportAllocs()
b.ResetTimer()
@@ -3029,8 +3275,10 @@ func Test_Ctx_Write(t *testing.T) {
app := New()
c := app.NewCtx(&fasthttp.RequestCtx{})
- c.Write([]byte("Hello, "))
- c.Write([]byte("World!"))
+ _, err := c.Write([]byte("Hello, "))
+ require.NoError(t, err)
+ _, err = c.Write([]byte("World!"))
+ require.NoError(t, err)
require.Equal(t, "Hello, World!", string(c.Response().Body()))
}
@@ -3065,7 +3313,7 @@ func Test_Ctx_Writef(t *testing.T) {
// go test -v -run=^$ -bench=Benchmark_Ctx_Writef -benchmem -count=4
func Benchmark_Ctx_Writef(b *testing.B) {
app := New()
- c := app.NewCtx(&fasthttp.RequestCtx{}).(*DefaultCtx)
+ c := app.NewCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed
world := "World!"
b.ReportAllocs()
@@ -3084,8 +3332,10 @@ func Test_Ctx_WriteString(t *testing.T) {
app := New()
c := app.NewCtx(&fasthttp.RequestCtx{})
- c.WriteString("Hello, ")
- c.WriteString("World!")
+ _, err := c.WriteString("Hello, ")
+ require.NoError(t, err)
+ _, err = c.WriteString("World!")
+ require.NoError(t, err)
require.Equal(t, "Hello, World!", string(c.Response().Body()))
}
@@ -3134,7 +3384,6 @@ func Benchmark_Ctx_SendString_B(b *testing.B) {
// go test -run Test_Ctx_BodyStreamWriter
func Test_Ctx_BodyStreamWriter(t *testing.T) {
t.Parallel()
-
ctx := &fasthttp.RequestCtx{}
ctx.SetBodyStreamWriter(func(w *bufio.Writer) {
@@ -3185,7 +3434,6 @@ func Benchmark_Ctx_BodyStreamWriter(b *testing.B) {
func Test_Ctx_String(t *testing.T) {
t.Parallel()
-
app := New()
c := app.NewCtx(&fasthttp.RequestCtx{})
@@ -3194,8 +3442,8 @@ func Test_Ctx_String(t *testing.T) {
func TestCtx_ParamsInt(t *testing.T) {
// Create a test context and set some strings (or params)
-
// create a fake app to be used within this test
+ t.Parallel()
app := New()
// Create some test endpoints
@@ -3281,20 +3529,21 @@ func TestCtx_ParamsInt(t *testing.T) {
})
_, err := app.Test(httptest.NewRequest(MethodGet, "/test/1111", nil))
- require.Equal(t, nil, err)
+ require.NoError(t, err)
_, err = app.Test(httptest.NewRequest(MethodGet, "/testnoint/xd", nil))
- require.Equal(t, nil, err)
+ require.NoError(t, err)
_, err = app.Test(httptest.NewRequest(MethodGet, "/testignoredefault/2222", nil))
- require.Equal(t, nil, err)
+ require.NoError(t, err)
_, err = app.Test(httptest.NewRequest(MethodGet, "/testdefault/xd", nil))
- require.Equal(t, nil, err)
+ require.NoError(t, err)
}
// go test -run Test_Ctx_GetRespHeader
func Test_Ctx_GetRespHeader(t *testing.T) {
+ t.Parallel()
app := New()
c := app.NewCtx(&fasthttp.RequestCtx{})
diff --git a/docs/api/_category_.json b/docs/api/_category_.json
new file mode 100644
index 0000000000..c0fc66388a
--- /dev/null
+++ b/docs/api/_category_.json
@@ -0,0 +1,8 @@
+{
+ "label": "API",
+ "position": 2,
+ "link": {
+ "type": "generated-index",
+ "description": "API documentation for Fiber."
+ }
+}
diff --git a/docs/api/app.md b/docs/api/app.md
new file mode 100644
index 0000000000..5f788ca356
--- /dev/null
+++ b/docs/api/app.md
@@ -0,0 +1,657 @@
+---
+id: app
+title: 🚀 App
+description: The app instance conventionally denotes the Fiber application.
+sidebar_position: 2
+---
+
+import RoutingHandler from './../partials/routing/handler.md';
+
+## Static
+
+Use the **Static** method to serve static files such as **images**, **CSS,** and **JavaScript**.
+
+:::info
+By default, **Static** will serve `index.html` files in response to a request on a directory.
+:::
+
+```go title="Signature"
+func (app *App) Static(prefix, root string, config ...Static) Router
+```
+
+Use the following code to serve files in a directory named `./public`
+
+```go
+app.Static("/", "./public")
+
+// => http://localhost:3000/hello.html
+// => http://localhost:3000/js/jquery.js
+// => http://localhost:3000/css/style.css
+```
+
+```go title="Examples"
+// Serve files from multiple directories
+app.Static("/", "./public")
+
+// Serve files from "./files" directory:
+app.Static("/", "./files")
+```
+
+You can use any virtual path prefix \(_where the path does not actually exist in the file system_\) for files that are served by the **Static** method, specify a prefix path for the static directory, as shown below:
+
+```go title="Examples"
+app.Static("/static", "./public")
+
+// => http://localhost:3000/static/hello.html
+// => http://localhost:3000/static/js/jquery.js
+// => http://localhost:3000/static/css/style.css
+```
+
+If you want to have a little bit more control regarding the settings for serving static files. You could use the `fiber.Static` struct to enable specific settings.
+
+```go title="fiber.Static{}"
+// Static defines configuration options when defining static assets.
+type Static struct {
+ // When set to true, the server tries minimizing CPU usage by caching compressed files.
+ // This works differently than the github.com/gofiber/compression middleware.
+ // Optional. Default value false
+ Compress bool `json:"compress"`
+
+ // When set to true, enables byte range requests.
+ // Optional. Default value false
+ ByteRange bool `json:"byte_range"`
+
+ // When set to true, enables directory browsing.
+ // Optional. Default value false.
+ Browse bool `json:"browse"`
+
+ // When set to true, enables direct download.
+ // Optional. Default value false.
+ Download bool `json:"download"`
+
+ // The name of the index file for serving a directory.
+ // Optional. Default value "index.html".
+ Index string `json:"index"`
+
+ // Expiration duration for inactive file handlers.
+ // Use a negative time.Duration to disable it.
+ //
+ // Optional. Default value 10 * time.Second.
+ CacheDuration time.Duration `json:"cache_duration"`
+
+ // The value for the Cache-Control HTTP-header
+ // that is set on the file response. MaxAge is defined in seconds.
+ //
+ // Optional. Default value 0.
+ MaxAge int `json:"max_age"`
+
+ // ModifyResponse defines a function that allows you to alter the response.
+ //
+ // Optional. Default: nil
+ ModifyResponse Handler
+
+ // Next defines a function to skip this middleware when returned true.
+ //
+ // Optional. Default: nil
+ Next func(c *Ctx) bool
+}
+```
+
+```go title="Example"
+// Custom config
+app.Static("/", "./public", fiber.Static{
+ Compress: true,
+ ByteRange: true,
+ Browse: true,
+ Index: "john.html",
+ CacheDuration: 10 * time.Second,
+ MaxAge: 3600,
+})
+```
+
+## Route Handlers
+
+
+
+## Mount
+
+You can Mount Fiber instance by creating a `*Mount`
+
+```go title="Signature"
+func (a *App) Mount(prefix string, app *App) Router
+```
+
+```go title="Examples"
+func main() {
+ app := fiber.New()
+ micro := fiber.New()
+ app.Mount("/john", micro) // GET /john/doe -> 200 OK
+
+ micro.Get("/doe", func(c *fiber.Ctx) error {
+ return c.SendStatus(fiber.StatusOK)
+ })
+
+ log.Fatal(app.Listen(":3000"))
+}
+```
+
+## MountPath
+
+The `MountPath` property contains one or more path patterns on which a sub-app was mounted.
+
+```go title="Signature"
+func (app *App) MountPath() string
+```
+
+```go title="Examples"
+func main() {
+ app := fiber.New()
+ one := fiber.New()
+ two := fiber.New()
+ three := fiber.New()
+
+ two.Mount("/three", three)
+ one.Mount("/two", two)
+ app.Mount("/one", one)
+
+ one.MountPath() // "/one"
+ two.MountPath() // "/one/two"
+ three.MountPath() // "/one/two/three"
+ app.MountPath() // ""
+}
+```
+
+:::caution
+Mounting order is important for MountPath. If you want to get mount paths properly, you should start mounting from the deepest app.
+:::
+
+## Group
+
+You can group routes by creating a `*Group` struct.
+
+```go title="Signature"
+func (app *App) Group(prefix string, handlers ...Handler) Router
+```
+
+```go title="Examples"
+func main() {
+ app := fiber.New()
+
+ api := app.Group("/api", handler) // /api
+
+ v1 := api.Group("/v1", handler) // /api/v1
+ v1.Get("/list", handler) // /api/v1/list
+ v1.Get("/user", handler) // /api/v1/user
+
+ v2 := api.Group("/v2", handler) // /api/v2
+ v2.Get("/list", handler) // /api/v2/list
+ v2.Get("/user", handler) // /api/v2/user
+
+ log.Fatal(app.Listen(":3000"))
+}
+```
+
+## Route
+
+You can define routes with a common prefix inside the common function.
+
+```go title="Signature"
+func (app *App) Route(prefix string, fn func(router Router), name ...string) Router
+```
+
+```go title="Examples"
+func main() {
+ app := fiber.New()
+
+ app.Route("/test", func(api fiber.Router) {
+ api.Get("/foo", handler).Name("foo") // /test/foo (name: test.foo)
+ api.Get("/bar", handler).Name("bar") // /test/bar (name: test.bar)
+ }, "test.")
+
+ log.Fatal(app.Listen(":3000"))
+}
+```
+
+## Server
+
+Server returns the underlying [fasthttp server](https://godoc.org/github.com/valyala/fasthttp#Server)
+
+```go title="Signature"
+func (app *App) Server() *fasthttp.Server
+```
+
+```go title="Examples"
+func main() {
+ app := fiber.New()
+
+ app.Server().MaxConnsPerIP = 1
+
+ // ...
+}
+```
+
+## Server Shutdown
+
+Shutdown gracefully shuts down the server without interrupting any active connections. Shutdown works by first closing all open listeners and then waits indefinitely for all connections to return to idle before shutting down.
+
+ShutdownWithTimeout will forcefully close any active connections after the timeout expires.
+
+ShutdownWithContext shuts down the server including by force if the context's deadline is exceeded.
+
+```go
+func (app *App) Shutdown() error
+func (app *App) ShutdownWithTimeout(timeout time.Duration) error
+func (app *App) ShutdownWithContext(ctx context.Context) error
+```
+
+## HandlersCount
+
+This method returns the amount of registered handlers.
+
+```go title="Signature"
+func (app *App) HandlersCount() uint32
+```
+
+## Stack
+
+This method returns the original router stack
+
+```go title="Signature"
+func (app *App) Stack() [][]*Route
+```
+
+```go title="Examples"
+var handler = func(c *fiber.Ctx) error { return nil }
+
+func main() {
+ app := fiber.New()
+
+ app.Get("/john/:age", handler)
+ app.Post("/register", handler)
+
+ data, _ := json.MarshalIndent(app.Stack(), "", " ")
+ fmt.Println(string(data))
+
+ app.Listen(":3000")
+}
+```
+
+```javascript title="Result"
+[
+ [
+ {
+ "method": "GET",
+ "path": "/john/:age",
+ "params": [
+ "age"
+ ]
+ }
+ ],
+ [
+ {
+ "method": "HEAD",
+ "path": "/john/:age",
+ "params": [
+ "age"
+ ]
+ }
+ ],
+ [
+ {
+ "method": "POST",
+ "path": "/register",
+ "params": null
+ }
+ ]
+]
+```
+
+## Name
+
+This method assigns the name of latest created route.
+
+```go title="Signature"
+func (app *App) Name(name string) Router
+```
+
+```go title="Examples"
+var handler = func(c *fiber.Ctx) error { return nil }
+
+func main() {
+ app := fiber.New()
+
+ app.Get("/", handler)
+ app.Name("index")
+
+ app.Get("/doe", handler).Name("home")
+
+ app.Trace("/tracer", handler).Name("tracert")
+
+ app.Delete("/delete", handler).Name("delete")
+
+ a := app.Group("/a")
+ a.Name("fd.")
+
+ a.Get("/test", handler).Name("test")
+
+ data, _ := json.MarshalIndent(app.Stack(), "", " ")
+ fmt.Print(string(data))
+
+ app.Listen(":3000")
+
+}
+```
+
+```javascript title="Result"
+[
+ [
+ {
+ "method": "GET",
+ "name": "index",
+ "path": "/",
+ "params": null
+ },
+ {
+ "method": "GET",
+ "name": "home",
+ "path": "/doe",
+ "params": null
+ },
+ {
+ "method": "GET",
+ "name": "fd.test",
+ "path": "/a/test",
+ "params": null
+ }
+ ],
+ [
+ {
+ "method": "HEAD",
+ "name": "",
+ "path": "/",
+ "params": null
+ },
+ {
+ "method": "HEAD",
+ "name": "",
+ "path": "/doe",
+ "params": null
+ },
+ {
+ "method": "HEAD",
+ "name": "",
+ "path": "/a/test",
+ "params": null
+ }
+ ],
+ null,
+ null,
+ [
+ {
+ "method": "DELETE",
+ "name": "delete",
+ "path": "/delete",
+ "params": null
+ }
+ ],
+ null,
+ null,
+ [
+ {
+ "method": "TRACE",
+ "name": "tracert",
+ "path": "/tracer",
+ "params": null
+ }
+ ],
+ null
+]
+```
+
+## GetRoute
+
+This method gets the route by name.
+
+```go title="Signature"
+func (app *App) GetRoute(name string) Route
+```
+
+```go title="Examples"
+var handler = func(c *fiber.Ctx) error { return nil }
+
+func main() {
+ app := fiber.New()
+
+ app.Get("/", handler).Name("index")
+
+ data, _ := json.MarshalIndent(app.GetRoute("index"), "", " ")
+ fmt.Print(string(data))
+
+
+ app.Listen(":3000")
+
+}
+```
+
+```javascript title="Result"
+{
+ "method": "GET",
+ "name": "index",
+ "path": "/",
+ "params": null
+}
+```
+
+## GetRoutes
+
+This method gets all routes.
+
+```go title="Signature"
+func (app *App) GetRoutes(filterUseOption ...bool) []Route
+```
+
+When filterUseOption equal to true, it will filter the routes registered by the middleware.
+```go title="Examples"
+func main() {
+ app := fiber.New()
+ app.Post("/", func (c *fiber.Ctx) error {
+ return c.SendString("Hello, World!")
+ }).Name("index")
+ data, _ := json.MarshalIndent(app.GetRoutes(true), "", " ")
+ fmt.Print(string(data))
+}
+```
+
+```javascript title="Result"
+[
+ {
+ "method": "POST",
+ "name": "index",
+ "path": "/",
+ "params": null
+ }
+]
+```
+
+## Config
+
+Config returns the app config as value \( read-only \).
+
+```go title="Signature"
+func (app *App) Config() Config
+```
+
+## Handler
+
+Handler returns the server handler that can be used to serve custom \*fasthttp.RequestCtx requests.
+
+```go title="Signature"
+func (app *App) Handler() fasthttp.RequestHandler
+```
+
+## Listen
+
+Listen serves HTTP requests from the given address.
+
+```go title="Signature"
+func (app *App) Listen(addr string) error
+```
+
+```go title="Examples"
+// Listen on port :8080
+app.Listen(":8080")
+
+// Custom host
+app.Listen("127.0.0.1:8080")
+```
+
+## ListenTLS
+
+ListenTLS serves HTTPs requests from the given address using certFile and keyFile paths to as TLS certificate and key file.
+
+```go title="Signature"
+func (app *App) ListenTLS(addr, certFile, keyFile string) error
+```
+
+```go title="Examples"
+app.ListenTLS(":443", "./cert.pem", "./cert.key");
+```
+
+Using `ListenTLS` defaults to the following config \( use `Listener` to provide your own config \)
+
+```go title="Default \*tls.Config"
+&tls.Config{
+ MinVersion: tls.VersionTLS12,
+ Certificates: []tls.Certificate{
+ cert,
+ },
+}
+```
+
+## ListenTLSWithCertificate
+
+```go title="Signature"
+func (app *App) ListenTLS(addr string, cert tls.Certificate) error
+```
+
+```go title="Examples"
+app.ListenTLSWithCertificate(":443", cert);
+```
+
+Using `ListenTLSWithCertificate` defaults to the following config \( use `Listener` to provide your own config \)
+
+```go title="Default \*tls.Config"
+&tls.Config{
+ MinVersion: tls.VersionTLS12,
+ Certificates: []tls.Certificate{
+ cert,
+ },
+}
+```
+
+## ListenMutualTLS
+
+ListenMutualTLS serves HTTPs requests from the given address using certFile, keyFile and clientCertFile are the paths to TLS certificate and key file
+
+```go title="Signature"
+func (app *App) ListenMutualTLS(addr, certFile, keyFile, clientCertFile string) error
+```
+
+```go title="Examples"
+app.ListenMutualTLS(":443", "./cert.pem", "./cert.key", "./ca-chain-cert.pem");
+```
+
+Using `ListenMutualTLS` defaults to the following config \( use `Listener` to provide your own config \)
+
+```go title="Default \*tls.Config"
+&tls.Config{
+ MinVersion: tls.VersionTLS12,
+ ClientAuth: tls.RequireAndVerifyClientCert,
+ ClientCAs: clientCertPool,
+ Certificates: []tls.Certificate{
+ cert,
+ },
+}
+```
+
+## ListenMutualTLSWithCertificate
+
+ListenMutualTLSWithCertificate serves HTTPs requests from the given address using certFile, keyFile and clientCertFile are the paths to TLS certificate and key file
+
+```go title="Signature"
+func (app *App) ListenMutualTLSWithCertificate(addr string, cert tls.Certificate, clientCertPool *x509.CertPool) error
+```
+
+```go title="Examples"
+app.ListenMutualTLSWithCertificate(":443", cert, clientCertPool);
+```
+
+Using `ListenMutualTLSWithCertificate` defaults to the following config \( use `Listener` to provide your own config \)
+
+```go title="Default \*tls.Config"
+&tls.Config{
+ MinVersion: tls.VersionTLS12,
+ ClientAuth: tls.RequireAndVerifyClientCert,
+ ClientCAs: clientCertPool,
+ Certificates: []tls.Certificate{
+ cert,
+ },
+}
+```
+
+## Listener
+
+You can pass your own [`net.Listener`](https://pkg.go.dev/net/#Listener) using the `Listener` method. This method can be used to enable **TLS/HTTPS** with a custom tls.Config.
+
+```go title="Signature"
+func (app *App) Listener(ln net.Listener) error
+```
+
+```go title="Examples"
+ln, _ := net.Listen("tcp", ":3000")
+
+cer, _:= tls.LoadX509KeyPair("server.crt", "server.key")
+
+ln = tls.NewListener(ln, &tls.Config{Certificates: []tls.Certificate{cer}})
+
+app.Listener(ln)
+```
+
+## Test
+
+Testing your application is done with the **Test** method. Use this method for creating `_test.go` files or when you need to debug your routing logic. The default timeout is `1s` if you want to disable a timeout altogether, pass `-1` as a second argument.
+
+```go title="Signature"
+func (app *App) Test(req *http.Request, msTimeout ...int) (*http.Response, error)
+```
+
+```go title="Examples"
+// Create route with GET method for test:
+app.Get("/", func(c *fiber.Ctx) error {
+ fmt.Println(c.BaseURL()) // => http://google.com
+ fmt.Println(c.Get("X-Custom-Header")) // => hi
+
+ return c.SendString("hello, World!")
+})
+
+// http.Request
+req := httptest.NewRequest("GET", "http://google.com", nil)
+req.Header.Set("X-Custom-Header", "hi")
+
+// http.Response
+resp, _ := app.Test(req)
+
+// Do something with results:
+if resp.StatusCode == fiber.StatusOK {
+ body, _ := ioutil.ReadAll(resp.Body)
+ fmt.Println(string(body)) // => Hello, World!
+}
+```
+
+## Hooks
+
+Hooks is a method to return [hooks](../guide/hooks.md) property.
+
+```go title="Signature"
+func (app *App) Hooks() *Hooks
+```
diff --git a/docs/api/client.md b/docs/api/client.md
new file mode 100644
index 0000000000..c3ed4b11a6
--- /dev/null
+++ b/docs/api/client.md
@@ -0,0 +1,607 @@
+---
+id: client
+title: 🌎 Client
+description: The Client struct represents the Fiber HTTP Client.
+sidebar_position: 5
+---
+
+## Start request
+
+Start a http request with http method and url.
+
+```go title="Signatures"
+// Client http methods
+func (c *Client) Get(url string) *Agent
+func (c *Client) Head(url string) *Agent
+func (c *Client) Post(url string) *Agent
+func (c *Client) Put(url string) *Agent
+func (c *Client) Patch(url string) *Agent
+func (c *Client) Delete(url string) *Agent
+```
+
+Here we present a brief example demonstrating the simulation of a proxy using our `*fiber.Agent` methods.
+```go
+// Get something
+func getSomething(c *fiber.Ctx) (err error) {
+ agent := fiber.Get("")
+ statusCode, body, errs := agent.Bytes()
+ if len(errs) > 0 {
+ return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
+ "errs": errs,
+ })
+ }
+
+ var something fiber.Map
+ err = json.Unmarshal(body, &something)
+ if err != nil {
+ return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
+ "err": err,
+ })
+ }
+
+ return c.Status(statusCode).JSON(something)
+}
+
+// Post something
+func createSomething(c *fiber.Ctx) (err error) {
+ agent := fiber.Post("")
+ agent.Body(c.Body()) // set body received by request
+ statusCode, body, errs := agent.Bytes()
+ if len(errs) > 0 {
+ return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
+ "errs": errs,
+ })
+ }
+
+ // pass status code and body received by the proxy
+ return c.Status(statusCode).Send(body)
+}
+```
+Based on this short example, we can perceive that using the `*fiber.Client` is very straightforward and intuitive.
+
+
+## ✨ Agent
+`Agent` is built on top of FastHTTP's [`HostClient`](https://github.com/valyala/fasthttp/blob/master/client.go#L603) which has lots of convenient helper methods such as dedicated methods for request methods.
+
+### Parse
+
+Parse initializes a HostClient.
+
+```go title="Parse"
+a := AcquireAgent()
+req := a.Request()
+req.Header.SetMethod(MethodGet)
+req.SetRequestURI("http://example.com")
+
+if err := a.Parse(); err != nil {
+ panic(err)
+}
+
+code, body, errs := a.Bytes() // ...
+```
+
+### Set
+
+Set sets the given `key: value` header.
+
+```go title="Signature"
+func (a *Agent) Set(k, v string) *Agent
+func (a *Agent) SetBytesK(k []byte, v string) *Agent
+func (a *Agent) SetBytesV(k string, v []byte) *Agent
+func (a *Agent) SetBytesKV(k []byte, v []byte) *Agent
+```
+
+```go title="Example"
+agent.Set("k1", "v1").
+ SetBytesK([]byte("k1"), "v1").
+ SetBytesV("k1", []byte("v1")).
+ SetBytesKV([]byte("k2"), []byte("v2"))
+// ...
+```
+
+### Add
+
+Add adds the given `key: value` header. Multiple headers with the same key may be added with this function.
+
+```go title="Signature"
+func (a *Agent) Add(k, v string) *Agent
+func (a *Agent) AddBytesK(k []byte, v string) *Agent
+func (a *Agent) AddBytesV(k string, v []byte) *Agent
+func (a *Agent) AddBytesKV(k []byte, v []byte) *Agent
+```
+
+```go title="Example"
+agent.Add("k1", "v1").
+ AddBytesK([]byte("k1"), "v1").
+ AddBytesV("k1", []byte("v1")).
+ AddBytesKV([]byte("k2"), []byte("v2"))
+// Headers:
+// K1: v1
+// K1: v1
+// K1: v1
+// K2: v2
+```
+
+### ConnectionClose
+
+ConnectionClose adds the `Connection: close` header.
+
+```go title="Signature"
+func (a *Agent) ConnectionClose() *Agent
+```
+
+```go title="Example"
+agent.ConnectionClose()
+// ...
+```
+
+### UserAgent
+
+UserAgent sets `User-Agent` header value.
+
+```go title="Signature"
+func (a *Agent) UserAgent(userAgent string) *Agent
+func (a *Agent) UserAgentBytes(userAgent []byte) *Agent
+```
+
+```go title="Example"
+agent.UserAgent("fiber")
+// ...
+```
+
+### Cookie
+
+Cookie sets a cookie in `key: value` form. `Cookies` can be used to set multiple cookies.
+
+```go title="Signature"
+func (a *Agent) Cookie(key, value string) *Agent
+func (a *Agent) CookieBytesK(key []byte, value string) *Agent
+func (a *Agent) CookieBytesKV(key, value []byte) *Agent
+func (a *Agent) Cookies(kv ...string) *Agent
+func (a *Agent) CookiesBytesKV(kv ...[]byte) *Agent
+```
+
+```go title="Example"
+agent.Cookie("k", "v")
+agent.Cookies("k1", "v1", "k2", "v2")
+// ...
+```
+
+### Referer
+
+Referer sets the Referer header value.
+
+```go title="Signature"
+func (a *Agent) Referer(referer string) *Agent
+func (a *Agent) RefererBytes(referer []byte) *Agent
+```
+
+```go title="Example"
+agent.Referer("https://docs.gofiber.io")
+// ...
+```
+
+### ContentType
+
+ContentType sets Content-Type header value.
+
+```go title="Signature"
+func (a *Agent) ContentType(contentType string) *Agent
+func (a *Agent) ContentTypeBytes(contentType []byte) *Agent
+```
+
+```go title="Example"
+agent.ContentType("custom-type")
+// ...
+```
+
+### Host
+
+Host sets the Host header.
+
+```go title="Signature"
+func (a *Agent) Host(host string) *Agent
+func (a *Agent) HostBytes(host []byte) *Agent
+```
+
+```go title="Example"
+agent.Host("example.com")
+// ...
+```
+
+### QueryString
+
+QueryString sets the URI query string.
+
+```go title="Signature"
+func (a *Agent) QueryString(queryString string) *Agent
+func (a *Agent) QueryStringBytes(queryString []byte) *Agent
+```
+
+```go title="Example"
+agent.QueryString("foo=bar")
+// ...
+```
+
+### BasicAuth
+
+BasicAuth sets the URI username and password using HTTP Basic Auth.
+
+```go title="Signature"
+func (a *Agent) BasicAuth(username, password string) *Agent
+func (a *Agent) BasicAuthBytes(username, password []byte) *Agent
+```
+
+```go title="Example"
+agent.BasicAuth("foo", "bar")
+// ...
+```
+
+### Body
+
+There are several ways to set request body.
+
+```go title="Signature"
+func (a *Agent) BodyString(bodyString string) *Agent
+func (a *Agent) Body(body []byte) *Agent
+
+// BodyStream sets request body stream and, optionally body size.
+//
+// If bodySize is >= 0, then the bodyStream must provide exactly bodySize bytes
+// before returning io.EOF.
+//
+// If bodySize < 0, then bodyStream is read until io.EOF.
+//
+// bodyStream.Close() is called after finishing reading all body data
+// if it implements io.Closer.
+//
+// Note that GET and HEAD requests cannot have body.
+func (a *Agent) BodyStream(bodyStream io.Reader, bodySize int) *Agent
+```
+
+```go title="Example"
+agent.BodyString("foo=bar")
+agent.Body([]byte("bar=baz"))
+agent.BodyStream(strings.NewReader("body=stream"), -1)
+// ...
+```
+
+### JSON
+
+JSON sends a JSON request by setting the Content-Type header to `application/json`.
+
+```go title="Signature"
+func (a *Agent) JSON(v interface{}) *Agent
+```
+
+```go title="Example"
+agent.JSON(fiber.Map{"success": true})
+// ...
+```
+
+### XML
+
+XML sends an XML request by setting the Content-Type header to `application/xml`.
+
+```go title="Signature"
+func (a *Agent) XML(v interface{}) *Agent
+```
+
+```go title="Example"
+agent.XML(fiber.Map{"success": true})
+// ...
+```
+
+### Form
+
+Form sends a form request by setting the Content-Type header to `application/x-www-form-urlencoded`.
+
+```go title="Signature"
+// Form sends form request with body if args is non-nil.
+//
+// It is recommended obtaining args via AcquireArgs and release it
+// manually in performance-critical code.
+func (a *Agent) Form(args *Args) *Agent
+```
+
+```go title="Example"
+args := AcquireArgs()
+args.Set("foo", "bar")
+
+agent.Form(args)
+// ...
+ReleaseArgs(args)
+```
+
+### MultipartForm
+
+MultipartForm sends multipart form request by setting the Content-Type header to `multipart/form-data`. These requests can include key-value's and files.
+
+```go title="Signature"
+// MultipartForm sends multipart form request with k-v and files.
+//
+// It is recommended to obtain args via AcquireArgs and release it
+// manually in performance-critical code.
+func (a *Agent) MultipartForm(args *Args) *Agent
+```
+
+```go title="Example"
+args := AcquireArgs()
+args.Set("foo", "bar")
+
+agent.MultipartForm(args)
+// ...
+ReleaseArgs(args)
+```
+
+Fiber provides several methods for sending files. Note that they must be called before `MultipartForm`.
+
+#### Boundary
+
+Boundary sets boundary for multipart form request.
+
+```go title="Signature"
+func (a *Agent) Boundary(boundary string) *Agent
+```
+
+```go title="Example"
+agent.Boundary("myBoundary")
+ .MultipartForm(nil)
+// ...
+```
+
+#### SendFile\(s\)
+
+SendFile read a file and appends it to a multipart form request. Sendfiles can be used to append multiple files.
+
+```go title="Signature"
+func (a *Agent) SendFile(filename string, fieldname ...string) *Agent
+func (a *Agent) SendFiles(filenamesAndFieldnames ...string) *Agent
+```
+
+```go title="Example"
+agent.SendFile("f", "field name")
+ .SendFiles("f1", "field name1", "f2").
+ .MultipartForm(nil)
+// ...
+```
+
+#### FileData
+
+FileData appends file data for multipart form request.
+
+```go
+// FormFile represents multipart form file
+type FormFile struct {
+ // Fieldname is form file's field name
+ Fieldname string
+ // Name is form file's name
+ Name string
+ // Content is form file's content
+ Content []byte
+}
+```
+
+```go title="Signature"
+// FileData appends files for multipart form request.
+//
+// It is recommended obtaining formFile via AcquireFormFile and release it
+// manually in performance-critical code.
+func (a *Agent) FileData(formFiles ...*FormFile) *Agent
+```
+
+```go title="Example"
+ff1 := &FormFile{"filename1", "field name1", []byte("content")}
+ff2 := &FormFile{"filename2", "field name2", []byte("content")}
+agent.FileData(ff1, ff2).
+ MultipartForm(nil)
+// ...
+```
+
+### Debug
+
+Debug mode enables logging request and response detail to `io.writer`\(default is `os.Stdout`\).
+
+```go title="Signature"
+func (a *Agent) Debug(w ...io.Writer) *Agent
+```
+
+```go title="Example"
+agent.Debug()
+// ...
+```
+
+### Timeout
+
+Timeout sets request timeout duration.
+
+```go title="Signature"
+func (a *Agent) Timeout(timeout time.Duration) *Agent
+```
+
+```go title="Example"
+agent.Timeout(time.Second)
+// ...
+```
+
+### Reuse
+
+Reuse enables the Agent instance to be used again after one request. If agent is reusable, then it should be released manually when it is no longer used.
+
+```go title="Signature"
+func (a *Agent) Reuse() *Agent
+```
+
+```go title="Example"
+agent.Reuse()
+// ...
+```
+
+### InsecureSkipVerify
+
+InsecureSkipVerify controls whether the Agent verifies the server certificate chain and host name.
+
+```go title="Signature"
+func (a *Agent) InsecureSkipVerify() *Agent
+```
+
+```go title="Example"
+agent.InsecureSkipVerify()
+// ...
+```
+
+### TLSConfig
+
+TLSConfig sets tls config.
+
+```go title="Signature"
+func (a *Agent) TLSConfig(config *tls.Config) *Agent
+```
+
+```go title="Example"
+// Create tls certificate
+cer, _ := tls.LoadX509KeyPair("pem", "key")
+
+config := &tls.Config{
+ Certificates: []tls.Certificate{cer},
+}
+
+agent.TLSConfig(config)
+// ...
+```
+
+### MaxRedirectsCount
+
+MaxRedirectsCount sets max redirect count for GET and HEAD.
+
+```go title="Signature"
+func (a *Agent) MaxRedirectsCount(count int) *Agent
+```
+
+```go title="Example"
+agent.MaxRedirectsCount(7)
+// ...
+```
+
+### JSONEncoder
+
+JSONEncoder sets custom json encoder.
+
+```go title="Signature"
+func (a *Agent) JSONEncoder(jsonEncoder utils.JSONMarshal) *Agent
+```
+
+```go title="Example"
+agent.JSONEncoder(json.Marshal)
+// ...
+```
+
+### JSONDecoder
+
+JSONDecoder sets custom json decoder.
+
+```go title="Signature"
+func (a *Agent) JSONDecoder(jsonDecoder utils.JSONUnmarshal) *Agent
+```
+
+```go title="Example"
+agent.JSONDecoder(json.Unmarshal)
+// ...
+```
+
+### Request
+
+Request returns Agent request instance.
+
+```go title="Signature"
+func (a *Agent) Request() *Request
+```
+
+```go title="Example"
+req := agent.Request()
+// ...
+```
+
+### SetResponse
+
+SetResponse sets custom response for the Agent instance. It is recommended obtaining custom response via AcquireResponse and release it manually in performance-critical code.
+
+```go title="Signature"
+func (a *Agent) SetResponse(customResp *Response) *Agent
+```
+
+```go title="Example"
+resp := AcquireResponse()
+agent.SetResponse(resp)
+// ...
+ReleaseResponse(resp)
+```
+
+### Dest
+
+Dest sets custom dest. The contents of dest will be replaced by the response body, if the dest is too small a new slice will be allocated.
+
+```go title="Signature"
+func (a *Agent) Dest(dest []byte) *Agent {
+```
+
+```go title="Example"
+agent.Dest(nil)
+// ...
+```
+
+### Bytes
+
+Bytes returns the status code, bytes body and errors of url.
+
+```go title="Signature"
+func (a *Agent) Bytes() (code int, body []byte, errs []error)
+```
+
+```go title="Example"
+code, body, errs := agent.Bytes()
+// ...
+```
+
+### String
+
+String returns the status code, string body and errors of url.
+
+```go title="Signature"
+func (a *Agent) String() (int, string, []error)
+```
+
+```go title="Example"
+code, body, errs := agent.String()
+// ...
+```
+
+### Struct
+
+Struct returns the status code, bytes body and errors of url. And bytes body will be unmarshalled to given v.
+
+```go title="Signature"
+func (a *Agent) Struct(v interface{}) (code int, body []byte, errs []error)
+```
+
+```go title="Example"
+var d data
+code, body, errs := agent.Struct(&d)
+// ...
+```
+
+### RetryIf
+
+RetryIf controls whether a retry should be attempted after an error.
+By default, will use isIdempotent function from fasthttp
+
+```go title="Signature"
+func (a *Agent) RetryIf(retryIf RetryIfFunc) *Agent
+```
+
+```go title="Example"
+agent.Get("https://example.com").RetryIf(func (req *fiber.Request) bool {
+ return req.URI() == "https://example.com"
+})
+// ...
+```
diff --git a/docs/api/constants.md b/docs/api/constants.md
new file mode 100644
index 0000000000..8a436a9f3b
--- /dev/null
+++ b/docs/api/constants.md
@@ -0,0 +1,291 @@
+---
+id: constants
+title: 📋 Constants
+description: Some constants for Fiber.
+sidebar_position: 4
+---
+
+HTTP methods were copied from net/http.
+
+```go
+const (
+ MethodGet = "GET" // RFC 7231, 4.3.1
+ MethodHead = "HEAD" // RFC 7231, 4.3.2
+ MethodPost = "POST" // RFC 7231, 4.3.3
+ MethodPut = "PUT" // RFC 7231, 4.3.4
+ MethodPatch = "PATCH" // RFC 5789
+ MethodDelete = "DELETE" // RFC 7231, 4.3.5
+ MethodConnect = "CONNECT" // RFC 7231, 4.3.6
+ MethodOptions = "OPTIONS" // RFC 7231, 4.3.7
+ MethodTrace = "TRACE" // RFC 7231, 4.3.8
+ methodUse = "USE"
+)
+```
+
+MIME types that are commonly used
+
+```go
+const (
+ MIMETextXML = "text/xml"
+ MIMETextHTML = "text/html"
+ MIMETextPlain = "text/plain"
+ MIMEApplicationXML = "application/xml"
+ MIMEApplicationJSON = "application/json"
+ MIMEApplicationJavaScript = "application/javascript"
+ MIMEApplicationForm = "application/x-www-form-urlencoded"
+ MIMEOctetStream = "application/octet-stream"
+ MIMEMultipartForm = "multipart/form-data"
+
+ MIMETextXMLCharsetUTF8 = "text/xml; charset=utf-8"
+ MIMETextHTMLCharsetUTF8 = "text/html; charset=utf-8"
+ MIMETextPlainCharsetUTF8 = "text/plain; charset=utf-8"
+ MIMEApplicationXMLCharsetUTF8 = "application/xml; charset=utf-8"
+ MIMEApplicationJSONCharsetUTF8 = "application/json; charset=utf-8"
+ MIMEApplicationJavaScriptCharsetUTF8 = "application/javascript; charset=utf-8"
+)
+```
+
+HTTP status codes were copied from net/http.
+
+```go
+const (
+ StatusContinue = 100 // RFC 7231, 6.2.1
+ StatusSwitchingProtocols = 101 // RFC 7231, 6.2.2
+ StatusProcessing = 102 // RFC 2518, 10.1
+ StatusEarlyHints = 103 // RFC 8297
+ StatusOK = 200 // RFC 7231, 6.3.1
+ StatusCreated = 201 // RFC 7231, 6.3.2
+ StatusAccepted = 202 // RFC 7231, 6.3.3
+ StatusNonAuthoritativeInformation = 203 // RFC 7231, 6.3.4
+ StatusNoContent = 204 // RFC 7231, 6.3.5
+ StatusResetContent = 205 // RFC 7231, 6.3.6
+ StatusPartialContent = 206 // RFC 7233, 4.1
+ StatusMultiStatus = 207 // RFC 4918, 11.1
+ StatusAlreadyReported = 208 // RFC 5842, 7.1
+ StatusIMUsed = 226 // RFC 3229, 10.4.1
+ StatusMultipleChoices = 300 // RFC 7231, 6.4.1
+ StatusMovedPermanently = 301 // RFC 7231, 6.4.2
+ StatusFound = 302 // RFC 7231, 6.4.3
+ StatusSeeOther = 303 // RFC 7231, 6.4.4
+ StatusNotModified = 304 // RFC 7232, 4.1
+ StatusUseProxy = 305 // RFC 7231, 6.4.5
+ StatusTemporaryRedirect = 307 // RFC 7231, 6.4.7
+ StatusPermanentRedirect = 308 // RFC 7538, 3
+ StatusBadRequest = 400 // RFC 7231, 6.5.1
+ StatusUnauthorized = 401 // RFC 7235, 3.1
+ StatusPaymentRequired = 402 // RFC 7231, 6.5.2
+ StatusForbidden = 403 // RFC 7231, 6.5.3
+ StatusNotFound = 404 // RFC 7231, 6.5.4
+ StatusMethodNotAllowed = 405 // RFC 7231, 6.5.5
+ StatusNotAcceptable = 406 // RFC 7231, 6.5.6
+ StatusProxyAuthRequired = 407 // RFC 7235, 3.2
+ StatusRequestTimeout = 408 // RFC 7231, 6.5.7
+ StatusConflict = 409 // RFC 7231, 6.5.8
+ StatusGone = 410 // RFC 7231, 6.5.9
+ StatusLengthRequired = 411 // RFC 7231, 6.5.10
+ StatusPreconditionFailed = 412 // RFC 7232, 4.2
+ StatusRequestEntityTooLarge = 413 // RFC 7231, 6.5.11
+ StatusRequestURITooLong = 414 // RFC 7231, 6.5.12
+ StatusUnsupportedMediaType = 415 // RFC 7231, 6.5.13
+ StatusRequestedRangeNotSatisfiable = 416 // RFC 7233, 4.4
+ StatusExpectationFailed = 417 // RFC 7231, 6.5.14
+ StatusTeapot = 418 // RFC 7168, 2.3.3
+ StatusMisdirectedRequest = 421 // RFC 7540, 9.1.2
+ StatusUnprocessableEntity = 422 // RFC 4918, 11.2
+ StatusLocked = 423 // RFC 4918, 11.3
+ StatusFailedDependency = 424 // RFC 4918, 11.4
+ StatusTooEarly = 425 // RFC 8470, 5.2.
+ StatusUpgradeRequired = 426 // RFC 7231, 6.5.15
+ StatusPreconditionRequired = 428 // RFC 6585, 3
+ StatusTooManyRequests = 429 // RFC 6585, 4
+ StatusRequestHeaderFieldsTooLarge = 431 // RFC 6585, 5
+ StatusUnavailableForLegalReasons = 451 // RFC 7725, 3
+ StatusInternalServerError = 500 // RFC 7231, 6.6.1
+ StatusNotImplemented = 501 // RFC 7231, 6.6.2
+ StatusBadGateway = 502 // RFC 7231, 6.6.3
+ StatusServiceUnavailable = 503 // RFC 7231, 6.6.4
+ StatusGatewayTimeout = 504 // RFC 7231, 6.6.5
+ StatusHTTPVersionNotSupported = 505 // RFC 7231, 6.6.6
+ StatusVariantAlsoNegotiates = 506 // RFC 2295, 8.1
+ StatusInsufficientStorage = 507 // RFC 4918, 11.5
+ StatusLoopDetected = 508 // RFC 5842, 7.2
+ StatusNotExtended = 510 // RFC 2774, 7
+ StatusNetworkAuthenticationRequired = 511 // RFC 6585, 6
+)
+```
+
+Errors
+
+```go
+var (
+ ErrBadRequest = NewError(StatusBadRequest) // RFC 7231, 6.5.1
+ ErrUnauthorized = NewError(StatusUnauthorized) // RFC 7235, 3.1
+ ErrPaymentRequired = NewError(StatusPaymentRequired) // RFC 7231, 6.5.2
+ ErrForbidden = NewError(StatusForbidden) // RFC 7231, 6.5.3
+ ErrNotFound = NewError(StatusNotFound) // RFC 7231, 6.5.4
+ ErrMethodNotAllowed = NewError(StatusMethodNotAllowed) // RFC 7231, 6.5.5
+ ErrNotAcceptable = NewError(StatusNotAcceptable) // RFC 7231, 6.5.6
+ ErrProxyAuthRequired = NewError(StatusProxyAuthRequired) // RFC 7235, 3.2
+ ErrRequestTimeout = NewError(StatusRequestTimeout) // RFC 7231, 6.5.7
+ ErrConflict = NewError(StatusConflict) // RFC 7231, 6.5.8
+ ErrGone = NewError(StatusGone) // RFC 7231, 6.5.9
+ ErrLengthRequired = NewError(StatusLengthRequired) // RFC 7231, 6.5.10
+ ErrPreconditionFailed = NewError(StatusPreconditionFailed) // RFC 7232, 4.2
+ ErrRequestEntityTooLarge = NewError(StatusRequestEntityTooLarge) // RFC 7231, 6.5.11
+ ErrRequestURITooLong = NewError(StatusRequestURITooLong) // RFC 7231, 6.5.12
+ ErrUnsupportedMediaType = NewError(StatusUnsupportedMediaType) // RFC 7231, 6.5.13
+ ErrRequestedRangeNotSatisfiable = NewError(StatusRequestedRangeNotSatisfiable) // RFC 7233, 4.4
+ ErrExpectationFailed = NewError(StatusExpectationFailed) // RFC 7231, 6.5.14
+ ErrTeapot = NewError(StatusTeapot) // RFC 7168, 2.3.3
+ ErrMisdirectedRequest = NewError(StatusMisdirectedRequest) // RFC 7540, 9.1.2
+ ErrUnprocessableEntity = NewError(StatusUnprocessableEntity) // RFC 4918, 11.2
+ ErrLocked = NewError(StatusLocked) // RFC 4918, 11.3
+ ErrFailedDependency = NewError(StatusFailedDependency) // RFC 4918, 11.4
+ ErrTooEarly = NewError(StatusTooEarly) // RFC 8470, 5.2.
+ ErrUpgradeRequired = NewError(StatusUpgradeRequired) // RFC 7231, 6.5.15
+ ErrPreconditionRequired = NewError(StatusPreconditionRequired) // RFC 6585, 3
+ ErrTooManyRequests = NewError(StatusTooManyRequests) // RFC 6585, 4
+ ErrRequestHeaderFieldsTooLarge = NewError(StatusRequestHeaderFieldsTooLarge) // RFC 6585, 5
+ ErrUnavailableForLegalReasons = NewError(StatusUnavailableForLegalReasons) // RFC 7725, 3
+ ErrInternalServerError = NewError(StatusInternalServerError) // RFC 7231, 6.6.1
+ ErrNotImplemented = NewError(StatusNotImplemented) // RFC 7231, 6.6.2
+ ErrBadGateway = NewError(StatusBadGateway) // RFC 7231, 6.6.3
+ ErrServiceUnavailable = NewError(StatusServiceUnavailable) // RFC 7231, 6.6.4
+ ErrGatewayTimeout = NewError(StatusGatewayTimeout) // RFC 7231, 6.6.5
+ ErrHTTPVersionNotSupported = NewError(StatusHTTPVersionNotSupported) // RFC 7231, 6.6.6
+ ErrVariantAlsoNegotiates = NewError(StatusVariantAlsoNegotiates) // RFC 2295, 8.1
+ ErrInsufficientStorage = NewError(StatusInsufficientStorage) // RFC 4918, 11.5
+ ErrLoopDetected = NewError(StatusLoopDetected) // RFC 5842, 7.2
+ ErrNotExtended = NewError(StatusNotExtended) // RFC 2774, 7
+ ErrNetworkAuthenticationRequired = NewError(StatusNetworkAuthenticationRequired) // RFC 6585, 6
+)
+```
+
+HTTP Headers were copied from net/http.
+
+```go
+const (
+ HeaderAuthorization = "Authorization"
+ HeaderProxyAuthenticate = "Proxy-Authenticate"
+ HeaderProxyAuthorization = "Proxy-Authorization"
+ HeaderWWWAuthenticate = "WWW-Authenticate"
+ HeaderAge = "Age"
+ HeaderCacheControl = "Cache-Control"
+ HeaderClearSiteData = "Clear-Site-Data"
+ HeaderExpires = "Expires"
+ HeaderPragma = "Pragma"
+ HeaderWarning = "Warning"
+ HeaderAcceptCH = "Accept-CH"
+ HeaderAcceptCHLifetime = "Accept-CH-Lifetime"
+ HeaderContentDPR = "Content-DPR"
+ HeaderDPR = "DPR"
+ HeaderEarlyData = "Early-Data"
+ HeaderSaveData = "Save-Data"
+ HeaderViewportWidth = "Viewport-Width"
+ HeaderWidth = "Width"
+ HeaderETag = "ETag"
+ HeaderIfMatch = "If-Match"
+ HeaderIfModifiedSince = "If-Modified-Since"
+ HeaderIfNoneMatch = "If-None-Match"
+ HeaderIfUnmodifiedSince = "If-Unmodified-Since"
+ HeaderLastModified = "Last-Modified"
+ HeaderVary = "Vary"
+ HeaderConnection = "Connection"
+ HeaderKeepAlive = "Keep-Alive"
+ HeaderAccept = "Accept"
+ HeaderAcceptCharset = "Accept-Charset"
+ HeaderAcceptEncoding = "Accept-Encoding"
+ HeaderAcceptLanguage = "Accept-Language"
+ HeaderCookie = "Cookie"
+ HeaderExpect = "Expect"
+ HeaderMaxForwards = "Max-Forwards"
+ HeaderSetCookie = "Set-Cookie"
+ HeaderAccessControlAllowCredentials = "Access-Control-Allow-Credentials"
+ HeaderAccessControlAllowHeaders = "Access-Control-Allow-Headers"
+ HeaderAccessControlAllowMethods = "Access-Control-Allow-Methods"
+ HeaderAccessControlAllowOrigin = "Access-Control-Allow-Origin"
+ HeaderAccessControlExposeHeaders = "Access-Control-Expose-Headers"
+ HeaderAccessControlMaxAge = "Access-Control-Max-Age"
+ HeaderAccessControlRequestHeaders = "Access-Control-Request-Headers"
+ HeaderAccessControlRequestMethod = "Access-Control-Request-Method"
+ HeaderOrigin = "Origin"
+ HeaderTimingAllowOrigin = "Timing-Allow-Origin"
+ HeaderXPermittedCrossDomainPolicies = "X-Permitted-Cross-Domain-Policies"
+ HeaderDNT = "DNT"
+ HeaderTk = "Tk"
+ HeaderContentDisposition = "Content-Disposition"
+ HeaderContentEncoding = "Content-Encoding"
+ HeaderContentLanguage = "Content-Language"
+ HeaderContentLength = "Content-Length"
+ HeaderContentLocation = "Content-Location"
+ HeaderContentType = "Content-Type"
+ HeaderForwarded = "Forwarded"
+ HeaderVia = "Via"
+ HeaderXForwardedFor = "X-Forwarded-For"
+ HeaderXForwardedHost = "X-Forwarded-Host"
+ HeaderXForwardedProto = "X-Forwarded-Proto"
+ HeaderXForwardedProtocol = "X-Forwarded-Protocol"
+ HeaderXForwardedSsl = "X-Forwarded-Ssl"
+ HeaderXUrlScheme = "X-Url-Scheme"
+ HeaderLocation = "Location"
+ HeaderFrom = "From"
+ HeaderHost = "Host"
+ HeaderReferer = "Referer"
+ HeaderReferrerPolicy = "Referrer-Policy"
+ HeaderUserAgent = "User-Agent"
+ HeaderAllow = "Allow"
+ HeaderServer = "Server"
+ HeaderAcceptRanges = "Accept-Ranges"
+ HeaderContentRange = "Content-Range"
+ HeaderIfRange = "If-Range"
+ HeaderRange = "Range"
+ HeaderContentSecurityPolicy = "Content-Security-Policy"
+ HeaderContentSecurityPolicyReportOnly = "Content-Security-Policy-Report-Only"
+ HeaderCrossOriginResourcePolicy = "Cross-Origin-Resource-Policy"
+ HeaderExpectCT = "Expect-CT"
+ HeaderFeaturePolicy = "Feature-Policy"
+ HeaderPublicKeyPins = "Public-Key-Pins"
+ HeaderPublicKeyPinsReportOnly = "Public-Key-Pins-Report-Only"
+ HeaderStrictTransportSecurity = "Strict-Transport-Security"
+ HeaderUpgradeInsecureRequests = "Upgrade-Insecure-Requests"
+ HeaderXContentTypeOptions = "X-Content-Type-Options"
+ HeaderXDownloadOptions = "X-Download-Options"
+ HeaderXFrameOptions = "X-Frame-Options"
+ HeaderXPoweredBy = "X-Powered-By"
+ HeaderXXSSProtection = "X-XSS-Protection"
+ HeaderLastEventID = "Last-Event-ID"
+ HeaderNEL = "NEL"
+ HeaderPingFrom = "Ping-From"
+ HeaderPingTo = "Ping-To"
+ HeaderReportTo = "Report-To"
+ HeaderTE = "TE"
+ HeaderTrailer = "Trailer"
+ HeaderTransferEncoding = "Transfer-Encoding"
+ HeaderSecWebSocketAccept = "Sec-WebSocket-Accept"
+ HeaderSecWebSocketExtensions = "Sec-WebSocket-Extensions"
+ HeaderSecWebSocketKey = "Sec-WebSocket-Key"
+ HeaderSecWebSocketProtocol = "Sec-WebSocket-Protocol"
+ HeaderSecWebSocketVersion = "Sec-WebSocket-Version"
+ HeaderAcceptPatch = "Accept-Patch"
+ HeaderAcceptPushPolicy = "Accept-Push-Policy"
+ HeaderAcceptSignature = "Accept-Signature"
+ HeaderAltSvc = "Alt-Svc"
+ HeaderDate = "Date"
+ HeaderIndex = "Index"
+ HeaderLargeAllocation = "Large-Allocation"
+ HeaderLink = "Link"
+ HeaderPushPolicy = "Push-Policy"
+ HeaderRetryAfter = "Retry-After"
+ HeaderServerTiming = "Server-Timing"
+ HeaderSignature = "Signature"
+ HeaderSignedHeaders = "Signed-Headers"
+ HeaderSourceMap = "SourceMap"
+ HeaderUpgrade = "Upgrade"
+ HeaderXDNSPrefetchControl = "X-DNS-Prefetch-Control"
+ HeaderXPingback = "X-Pingback"
+ HeaderXRequestID = "X-Request-ID"
+ HeaderXRequestedWith = "X-Requested-With"
+ HeaderXRobotsTag = "X-Robots-Tag"
+ HeaderXUACompatible = "X-UA-Compatible"
+)
+```
\ No newline at end of file
diff --git a/docs/api/ctx.md b/docs/api/ctx.md
new file mode 100644
index 0000000000..aa48c60929
--- /dev/null
+++ b/docs/api/ctx.md
@@ -0,0 +1,2046 @@
+---
+id: ctx
+title: 🧠 Ctx
+description: >-
+ The Ctx struct represents the Context which hold the HTTP request and
+ response. It has methods for the request query string, parameters, body, HTTP
+ headers, and so on.
+sidebar_position: 3
+---
+
+## Accepts
+
+Checks, if the specified **extensions** or **content** **types** are acceptable.
+
+:::info
+Based on the request’s [Accept](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept) HTTP header.
+:::
+
+```go title="Signature"
+func (c *Ctx) Accepts(offers ...string) string
+func (c *Ctx) AcceptsCharsets(offers ...string) string
+func (c *Ctx) AcceptsEncodings(offers ...string) string
+func (c *Ctx) AcceptsLanguages(offers ...string) string
+```
+
+```go title="Example"
+// Accept: text/html, application/json; q=0.8, text/plain; q=0.5; charset="utf-8"
+
+app.Get("/", func(c *fiber.Ctx) error {
+ c.Accepts("html") // "html"
+ c.Accepts("text/html") // "text/html"
+ c.Accepts("json", "text") // "json"
+ c.Accepts("application/json") // "application/json"
+ c.Accepts("text/plain", "application/json") // "application/json", due to quality
+ c.Accepts("image/png") // ""
+ c.Accepts("png") // ""
+ // ...
+})
+```
+
+```go title="Example 2"
+// Accept: text/html, text/*, application/json, */*; q=0
+
+app.Get("/", func(c *fiber.Ctx) error {
+ c.Accepts("text/plain", "application/json") // "application/json", due to specificity
+ c.Accepts("application/json", "text/html") // "text/html", due to first match
+ c.Accepts("image/png") // "", due to */* without q factor 0 is Not Acceptable
+ // ...
+})
+```
+
+Fiber provides similar functions for the other accept headers.
+
+```go
+// Accept-Charset: utf-8, iso-8859-1;q=0.2
+// Accept-Encoding: gzip, compress;q=0.2
+// Accept-Language: en;q=0.8, nl, ru
+
+app.Get("/", func(c *fiber.Ctx) error {
+ c.AcceptsCharsets("utf-16", "iso-8859-1")
+ // "iso-8859-1"
+
+ c.AcceptsEncodings("compress", "br")
+ // "compress"
+
+ c.AcceptsLanguages("pt", "nl", "ru")
+ // "nl"
+ // ...
+})
+```
+
+## AllParams
+
+Params is used to get all route parameters.
+Using Params method to get params.
+
+```go title="Signature"
+func (c *Ctx) AllParams() map[string]string
+```
+
+```go title="Example"
+// GET http://example.com/user/fenny
+app.Get("/user/:name", func(c *fiber.Ctx) error {
+ c.AllParams() // "{"name": "fenny"}"
+
+ // ...
+})
+
+// GET http://example.com/user/fenny/123
+app.Get("/user/*", func(c *fiber.Ctx) error {
+ c.AllParams() // "{"*1": "fenny/123"}"
+
+ // ...
+})
+```
+
+## App
+
+Returns the [\*App](ctx.md) reference so you could easily access all application settings.
+
+```go title="Signature"
+func (c *Ctx) App() *App
+```
+
+```go title="Example"
+app.Get("/stack", func(c *fiber.Ctx) error {
+ return c.JSON(c.App().Stack())
+})
+```
+
+## Append
+
+Appends the specified **value** to the HTTP response header field.
+
+:::caution
+If the header is **not** already set, it creates the header with the specified value.
+:::
+
+```go title="Signature"
+func (c *Ctx) Append(field string, values ...string)
+```
+
+```go title="Example"
+app.Get("/", func(c *fiber.Ctx) error {
+ c.Append("Link", "http://google.com", "http://localhost")
+ // => Link: http://localhost, http://google.com
+
+ c.Append("Link", "Test")
+ // => Link: http://localhost, http://google.com, Test
+
+ // ...
+})
+```
+
+## Attachment
+
+Sets the HTTP response [Content-Disposition](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition) header field to `attachment`.
+
+```go title="Signature"
+func (c *Ctx) Attachment(filename ...string)
+```
+
+```go title="Example"
+app.Get("/", func(c *fiber.Ctx) error {
+ c.Attachment()
+ // => Content-Disposition: attachment
+
+ c.Attachment("./upload/images/logo.png")
+ // => Content-Disposition: attachment; filename="logo.png"
+ // => Content-Type: image/png
+
+ // ...
+})
+```
+
+## BaseURL
+
+Returns the base URL \(**protocol** + **host**\) as a `string`.
+
+```go title="Signature"
+func (c *Ctx) BaseURL() string
+```
+
+```go title="Example"
+// GET https://example.com/page#chapter-1
+
+app.Get("/", func(c *fiber.Ctx) error {
+ c.BaseURL() // https://example.com
+ // ...
+})
+```
+
+## Bind
+Add vars to default view var map binding to template engine.
+Variables are read by the Render method and may be overwritten.
+
+```go title="Signature"
+func (c *Ctx) Bind(vars Map) error
+```
+
+```go title="Example"
+app.Use(func(c *fiber.Ctx) error {
+ c.Bind(fiber.Map{
+ "Title": "Hello, World!",
+ })
+})
+
+app.Get("/", func(c *fiber.Ctx) error {
+ return c.Render("xxx.tmpl", fiber.Map{}) // Render will use Title variable
+})
+```
+
+## Body
+
+Returns the raw request **body**.
+
+```go title="Signature"
+func (c *Ctx) Body() []byte
+```
+
+```go title="Example"
+// curl -X POST http://localhost:8080 -d user=john
+
+app.Post("/", func(c *fiber.Ctx) error {
+ // Get raw body from POST request:
+ return c.Send(c.Body()) // []byte("user=john")
+})
+```
+
+> _Returned value is only valid within the handler. Do not store any references.
+> Make copies or use the_ [_**`Immutable`**_](ctx.md) _setting instead._ [_Read more..._](../#zero-allocation)
+
+## BodyParser
+
+Binds the request body to a struct.
+
+It is important to specify the correct struct tag based on the content type to be parsed. For example, if you want to parse a JSON body with a field called Pass, you would use a struct field of `json:"pass"`.
+
+| content-type | struct tag |
+|---|---|
+| `application/x-www-form-urlencoded` | form |
+| `multipart/form-data` | form |
+| `application/json` | json |
+| `application/xml` | xml |
+| `text/xml` | xml |
+
+```go title="Signature"
+func (c *Ctx) BodyParser(out interface{}) error
+```
+
+```go title="Example"
+// Field names should start with an uppercase letter
+type Person struct {
+ Name string `json:"name" xml:"name" form:"name"`
+ Pass string `json:"pass" xml:"pass" form:"pass"`
+}
+
+app.Post("/", func(c *fiber.Ctx) error {
+ p := new(Person)
+
+ if err := c.BodyParser(p); err != nil {
+ return err
+ }
+
+ log.Println(p.Name) // john
+ log.Println(p.Pass) // doe
+
+ // ...
+})
+
+// Run tests with the following curl commands
+
+// curl -X POST -H "Content-Type: application/json" --data "{\"name\":\"john\",\"pass\":\"doe\"}" localhost:3000
+
+// curl -X POST -H "Content-Type: application/xml" --data "johndoe" localhost:3000
+
+// curl -X POST -H "Content-Type: application/x-www-form-urlencoded" --data "name=john&pass=doe" localhost:3000
+
+// curl -X POST -F name=john -F pass=doe http://localhost:3000
+
+// curl -X POST "http://localhost:3000/?name=john&pass=doe"
+```
+
+> _Returned value is only valid within the handler. Do not store any references.
+> Make copies or use the_ [_**`Immutable`**_](ctx.md) _setting instead._ [_Read more..._](../#zero-allocation)
+
+## ClearCookie
+
+Expire a client cookie \(_or all cookies if left empty\)_
+
+```go title="Signature"
+func (c *Ctx) ClearCookie(key ...string)
+```
+
+```go title="Example"
+app.Get("/", func(c *fiber.Ctx) error {
+ // Clears all cookies:
+ c.ClearCookie()
+
+ // Expire specific cookie by name:
+ c.ClearCookie("user")
+
+ // Expire multiple cookies by names:
+ c.ClearCookie("token", "session", "track_id", "version")
+ // ...
+})
+```
+
+:::caution
+Web browsers and other compliant clients will only clear the cookie if the given options are identical to those when creating the cookie, excluding expires and maxAge. ClearCookie will not set these values for you - a technique similar to the one shown below should be used to ensure your cookie is deleted.
+:::
+
+```go title="Example"
+app.Get("/set", func(c *fiber.Ctx) error {
+ c.Cookie(&fiber.Cookie{
+ Name: "token",
+ Value: "randomvalue",
+ Expires: time.Now().Add(24 * time.Hour),
+ HTTPOnly: true,
+ SameSite: "lax",
+ })
+
+ // ...
+})
+
+app.Get("/delete", func(c *fiber.Ctx) error {
+ c.Cookie(&fiber.Cookie{
+ Name: "token",
+ // Set expiry date to the past
+ Expires: time.Now().Add(-(time.Hour * 2)),
+ HTTPOnly: true,
+ SameSite: "lax",
+ })
+
+ // ...
+})
+```
+
+## ClientHelloInfo
+
+ClientHelloInfo contains information from a ClientHello message in order to guide application logic in the GetCertificate and GetConfigForClient callbacks.
+You can refer to the [ClientHelloInfo](https://golang.org/pkg/crypto/tls/#ClientHelloInfo) struct documentation for more information on the returned struct.
+
+```go title="Signature"
+func (c *Ctx) ClientHelloInfo() *tls.ClientHelloInfo
+```
+
+```go title="Example"
+// GET http://example.com/hello
+app.Get("/hello", func(c *fiber.Ctx) error {
+ chi := c.ClientHelloInfo()
+ // ...
+})
+```
+
+## Context
+
+Returns [\*fasthttp.RequestCtx](https://godoc.org/github.com/valyala/fasthttp#RequestCtx) that is compatible with the context.Context interface that requires a deadline, a cancellation signal, and other values across API boundaries.
+
+```go title="Signature"
+func (c *Ctx) Context() *fasthttp.RequestCtx
+```
+
+:::info
+Please read the [Fasthttp Documentation](https://pkg.go.dev/github.com/valyala/fasthttp?tab=doc) for more information.
+:::
+
+## Cookie
+
+Set cookie
+
+```go title="Signature"
+func (c *Ctx) Cookie(cookie *Cookie)
+```
+
+```go
+type Cookie struct {
+ Name string `json:"name"`
+ Value string `json:"value"`
+ Path string `json:"path"`
+ Domain string `json:"domain"`
+ MaxAge int `json:"max_age"`
+ Expires time.Time `json:"expires"`
+ Secure bool `json:"secure"`
+ HTTPOnly bool `json:"http_only"`
+ SameSite string `json:"same_site"`
+ SessionOnly bool `json:"session_only"`
+}
+```
+
+```go title="Example"
+app.Get("/", func(c *fiber.Ctx) error {
+ // Create cookie
+ cookie := new(fiber.Cookie)
+ cookie.Name = "john"
+ cookie.Value = "doe"
+ cookie.Expires = time.Now().Add(24 * time.Hour)
+
+ // Set cookie
+ c.Cookie(cookie)
+ // ...
+})
+```
+
+## Cookies
+
+Get cookie value by key, you could pass an optional default value that will be returned if the cookie key does not exist.
+
+```go title="Signature"
+func (c *Ctx) Cookies(key string, defaultValue ...string) string
+```
+
+```go title="Example"
+app.Get("/", func(c *fiber.Ctx) error {
+ // Get cookie by key:
+ c.Cookies("name") // "john"
+ c.Cookies("empty", "doe") // "doe"
+ // ...
+})
+```
+
+> _Returned value is only valid within the handler. Do not store any references.
+> Make copies or use the_ [_**`Immutable`**_](ctx.md) _setting instead._ [_Read more..._](../#zero-allocation)
+
+## Download
+
+Transfers the file from path as an `attachment`.
+
+Typically, browsers will prompt the user to download. By default, the [Content-Disposition](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition) header `filename=` parameter is the file path \(_this typically appears in the browser dialog_\).
+
+Override this default with the **filename** parameter.
+
+```go title="Signature"
+func (c *Ctx) Download(file string, filename ...string) error
+```
+
+```go title="Example"
+app.Get("/", func(c *fiber.Ctx) error {
+ return c.Download("./files/report-12345.pdf");
+ // => Download report-12345.pdf
+
+ return c.Download("./files/report-12345.pdf", "report.pdf");
+ // => Download report.pdf
+})
+```
+
+## Format
+
+Performs content-negotiation on the [Accept](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept) HTTP header. It uses [Accepts](ctx.md#accepts) to select a proper format.
+
+:::info
+If the header is **not** specified or there is **no** proper format, **text/plain** is used.
+:::
+
+```go title="Signature"
+func (c *Ctx) Format(body interface{}) error
+```
+
+```go title="Example"
+app.Get("/", func(c *fiber.Ctx) error {
+ // Accept: text/plain
+ c.Format("Hello, World!")
+ // => Hello, World!
+
+ // Accept: text/html
+ c.Format("Hello, World!")
+ // =>
Hello, World!
+
+ // Accept: application/json
+ c.Format("Hello, World!")
+ // => "Hello, World!"
+ // ..
+})
+```
+
+## FormFile
+
+MultipartForm files can be retrieved by name, the **first** file from the given key is returned.
+
+```go title="Signature"
+func (c *Ctx) FormFile(key string) (*multipart.FileHeader, error)
+```
+
+```go title="Example"
+app.Post("/", func(c *fiber.Ctx) error {
+ // Get first file from form field "document":
+ file, err := c.FormFile("document")
+
+ // Save file to root directory:
+ return c.SaveFile(file, fmt.Sprintf("./%s", file.Filename))
+})
+```
+
+## FormValue
+
+Any form values can be retrieved by name, the **first** value from the given key is returned.
+
+```go title="Signature"
+func (c *Ctx) FormValue(key string, defaultValue ...string) string
+```
+
+```go title="Example"
+app.Post("/", func(c *fiber.Ctx) error {
+ // Get first value from form field "name":
+ c.FormValue("name")
+ // => "john" or "" if not exist
+
+ // ..
+})
+```
+
+> _Returned value is only valid within the handler. Do not store any references.
+> Make copies or use the_ [_**`Immutable`**_](ctx.md) _setting instead._ [_Read more..._](../#zero-allocation)
+
+## Fresh
+
+When the response is still **fresh** in the client's cache **true** is returned, otherwise **false** is returned to indicate that the client cache is now stale and the full response should be sent.
+
+When a client sends the Cache-Control: no-cache request header to indicate an end-to-end reload request, `Fresh` will return false to make handling these requests transparent.
+
+Read more on [https://expressjs.com/en/4x/api.html\#req.fresh](https://expressjs.com/en/4x/api.html#req.fresh)
+
+```go title="Signature"
+func (c *Ctx) Fresh() bool
+```
+
+## Get
+
+Returns the HTTP request header specified by the field.
+
+:::tip
+The match is **case-insensitive**.
+:::
+
+```go title="Signature"
+func (c *Ctx) Get(key string, defaultValue ...string) string
+```
+
+```go title="Example"
+app.Get("/", func(c *fiber.Ctx) error {
+ c.Get("Content-Type") // "text/plain"
+ c.Get("CoNtEnT-TypE") // "text/plain"
+ c.Get("something", "john") // "john"
+ // ..
+})
+```
+
+> _Returned value is only valid within the handler. Do not store any references.
+> Make copies or use the_ [_**`Immutable`**_](ctx.md) _setting instead._ [_Read more..._](../#zero-allocation)
+
+## GetReqHeaders
+
+Returns the HTTP request headers.
+
+```go title="Signature"
+func (c *Ctx) GetReqHeaders() map[string]string
+```
+
+> _Returned value is only valid within the handler. Do not store any references.
+> Make copies or use the_ [_**`Immutable`**_](ctx.md) _setting instead._ [_Read more..._](../#zero-allocation)
+
+## GetRespHeader
+
+Returns the HTTP response header specified by the field.
+
+:::tip
+The match is **case-insensitive**.
+:::
+
+```go title="Signature"
+func (c *Ctx) GetRespHeader(key string, defaultValue ...string) string
+```
+
+```go title="Example"
+app.Get("/", func(c *fiber.Ctx) error {
+ c.GetRespHeader("X-Request-Id") // "8d7ad5e3-aaf3-450b-a241-2beb887efd54"
+ c.GetRespHeader("Content-Type") // "text/plain"
+ c.GetRespHeader("something", "john") // "john"
+ // ..
+})
+```
+
+> _Returned value is only valid within the handler. Do not store any references.
+> Make copies or use the_ [_**`Immutable`**_](ctx.md) _setting instead._ [_Read more..._](../#zero-allocation)
+
+## GetRespHeaders
+
+Returns the HTTP response headers.
+
+```go title="Signature"
+func (c *Ctx) GetRespHeaders() map[string]string
+```
+
+> _Returned value is only valid within the handler. Do not store any references.
+> Make copies or use the_ [_**`Immutable`**_](ctx.md) _setting instead._ [_Read more..._](../#zero-allocation)
+
+## GetRouteURL
+
+Generates URLs to named routes, with parameters. URLs are relative, for example: "/user/1831"
+
+```go title="Signature"
+func (c *Ctx) GetRouteURL(routeName string, params Map) (string, error)
+```
+
+```go title="Example"
+app.Get("/", func(c *fiber.Ctx) error {
+ return c.SendString("Home page")
+}).Name("home")
+
+app.Get("/user/:id", func(c *fiber.Ctx) error {
+ return c.SendString(c.Params("id"))
+}).Name("user.show")
+
+app.Get("/test", func(c *fiber.Ctx) error {
+ location, _ := c.GetRouteURL("user.show", fiber.Map{"id": 1})
+ return c.SendString(location)
+})
+
+// /test returns "/user/1"
+```
+
+## Hostname
+
+Returns the hostname derived from the [Host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Host) HTTP header.
+
+```go title="Signature"
+func (c *Ctx) Hostname() string
+```
+
+```go title="Example"
+// GET http://google.com/search
+
+app.Get("/", func(c *fiber.Ctx) error {
+ c.Hostname() // "google.com"
+
+ // ...
+})
+```
+
+> _Returned value is only valid within the handler. Do not store any references.
+> Make copies or use the_ [_**`Immutable`**_](ctx.md) _setting instead._ [_Read more..._](../#zero-allocation)
+
+## IP
+
+Returns the remote IP address of the request.
+
+```go title="Signature"
+func (c *Ctx) IP() string
+```
+
+```go title="Example"
+app.Get("/", func(c *fiber.Ctx) error {
+ c.IP() // "127.0.0.1"
+
+ // ...
+})
+```
+
+When registering the proxy request header in the fiber app, the ip address of the header is returned [(Fiber configuration)](fiber.md#config)
+
+```go
+app := fiber.New(fiber.Config{
+ ProxyHeader: fiber.HeaderXForwardedFor,
+})
+```
+
+## IPs
+
+Returns an array of IP addresses specified in the [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For) request header.
+
+```go title="Signature"
+func (c *Ctx) IPs() []string
+```
+
+```go title="Example"
+// X-Forwarded-For: proxy1, 127.0.0.1, proxy3
+
+app.Get("/", func(c *fiber.Ctx) error {
+ c.IPs() // ["proxy1", "127.0.0.1", "proxy3"]
+
+ // ...
+})
+```
+
+:::caution
+Improper use of the X-Forwarded-For header can be a security risk. For details, see the [Security and privacy concerns](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For#security_and_privacy_concerns) section.
+:::
+
+## Is
+
+Returns the matching **content type**, if the incoming request’s [Content-Type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type) HTTP header field matches the [MIME type](https://developer.mozilla.org/ru/docs/Web/HTTP/Basics_of_HTTP/MIME_types) specified by the type parameter.
+
+:::info
+If the request has **no** body, it returns **false**.
+:::
+
+```go title="Signature"
+func (c *Ctx) Is(extension string) bool
+```
+
+```go title="Example"
+// Content-Type: text/html; charset=utf-8
+
+app.Get("/", func(c *fiber.Ctx) error {
+ c.Is("html") // true
+ c.Is(".html") // true
+ c.Is("json") // false
+
+ // ...
+})
+```
+
+## IsFromLocal
+
+Returns true if request came from localhost
+```go title="Signature"
+func (c *Ctx) IsFromLocal() bool {
+```
+
+```go title="Example"
+
+app.Get("/", func(c *fiber.Ctx) error {
+ // If request came from localhost, return true else return false
+ c.IsFromLocal()
+
+ // ...
+})
+```
+
+## JSON
+
+Converts any **interface** or **string** to JSON using the [encoding/json](https://pkg.go.dev/encoding/json) package.
+
+:::info
+JSON also sets the content header to **application/json**.
+:::
+
+```go title="Signature"
+func (c *Ctx) JSON(data interface{}) error
+```
+
+```go title="Example"
+type SomeStruct struct {
+ Name string
+ Age uint8
+}
+
+app.Get("/json", func(c *fiber.Ctx) error {
+ // Create data struct:
+ data := SomeStruct{
+ Name: "Grame",
+ Age: 20,
+ }
+
+ return c.JSON(data)
+ // => Content-Type: application/json
+ // => "{"Name": "Grame", "Age": 20}"
+
+ return c.JSON(fiber.Map{
+ "name": "Grame",
+ "age": 20,
+ })
+ // => Content-Type: application/json
+ // => "{"name": "Grame", "age": 20}"
+})
+```
+
+## JSONP
+
+Sends a JSON response with JSONP support. This method is identical to [JSON](ctx.md#json), except that it opts-in to JSONP callback support. By default, the callback name is simply callback.
+
+Override this by passing a **named string** in the method.
+
+```go title="Signature"
+func (c *Ctx) JSONP(data interface{}, callback ...string) error
+```
+
+```go title="Example"
+type SomeStruct struct {
+ name string
+ age uint8
+}
+
+app.Get("/", func(c *fiber.Ctx) error {
+ // Create data struct:
+ data := SomeStruct{
+ name: "Grame",
+ age: 20,
+ }
+
+ return c.JSONP(data)
+ // => callback({"name": "Grame", "age": 20})
+
+ return c.JSONP(data, "customFunc")
+ // => customFunc({"name": "Grame", "age": 20})
+})
+```
+
+## Links
+
+Joins the links followed by the property to populate the response’s [Link](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Link) HTTP header field.
+
+```go title="Signature"
+func (c *Ctx) Links(link ...string)
+```
+
+```go title="Example"
+app.Get("/", func(c *fiber.Ctx) error {
+ c.Links(
+ "http://api.example.com/users?page=2", "next",
+ "http://api.example.com/users?page=5", "last",
+ )
+ // Link: ; rel="next",
+ // ; rel="last"
+
+ // ...
+})
+```
+
+## Locals
+
+A method that stores variables scoped to the request and, therefore, are available only to the routes that match the request.
+
+:::tip
+This is useful if you want to pass some **specific** data to the next middleware.
+:::
+
+```go title="Signature"
+func (c *Ctx) Locals(key interface{}, value ...interface{}) interface{}
+```
+
+```go title="Example"
+app.Use(func(c *fiber.Ctx) error {
+ c.Locals("user", "admin")
+ return c.Next()
+})
+
+app.Get("/admin", func(c *fiber.Ctx) error {
+ if c.Locals("user") == "admin" {
+ return c.Status(fiber.StatusOK).SendString("Welcome, admin!")
+ }
+ return c.SendStatus(fiber.StatusForbidden)
+
+})
+```
+
+## Location
+
+Sets the response [Location](https://developer.mozilla.org/ru/docs/Web/HTTP/Headers/Location) HTTP header to the specified path parameter.
+
+```go title="Signature"
+func (c *Ctx) Location(path string)
+```
+
+```go title="Example"
+app.Post("/", func(c *fiber.Ctx) error {
+ c.Location("http://example.com")
+
+ c.Location("/foo/bar")
+
+ return nil
+})
+```
+
+## Method
+
+Returns a string corresponding to the HTTP method of the request: `GET`, `POST`, `PUT`, and so on.
+Optionally, you could override the method by passing a string.
+
+```go title="Signature"
+func (c *Ctx) Method(override ...string) string
+```
+
+```go title="Example"
+app.Post("/", func(c *fiber.Ctx) error {
+ c.Method() // "POST"
+
+ c.Method("GET")
+ c.Method() // GET
+
+ // ...
+})
+```
+
+## MultipartForm
+
+To access multipart form entries, you can parse the binary with `MultipartForm()`. This returns a `map[string][]string`, so given a key, the value will be a string slice.
+
+```go title="Signature"
+func (c *Ctx) MultipartForm() (*multipart.Form, error)
+```
+
+```go title="Example"
+app.Post("/", func(c *fiber.Ctx) error {
+ // Parse the multipart form:
+ if form, err := c.MultipartForm(); err == nil {
+ // => *multipart.Form
+
+ if token := form.Value["token"]; len(token) > 0 {
+ // Get key value:
+ fmt.Println(token[0])
+ }
+
+ // Get all files from "documents" key:
+ files := form.File["documents"]
+ // => []*multipart.FileHeader
+
+ // Loop through files:
+ for _, file := range files {
+ fmt.Println(file.Filename, file.Size, file.Header["Content-Type"][0])
+ // => "tutorial.pdf" 360641 "application/pdf"
+
+ // Save the files to disk:
+ if err := c.SaveFile(file, fmt.Sprintf("./%s", file.Filename)); err != nil {
+ return err
+ }
+ }
+ }
+
+ return err
+})
+```
+
+## Next
+
+When **Next** is called, it executes the next method in the stack that matches the current route. You can pass an error struct within the method that will end the chaining and call the [error handler](https://docs.gofiber.io/guide/error-handling).
+
+```go title="Signature"
+func (c *Ctx) Next() error
+```
+
+```go title="Example"
+app.Get("/", func(c *fiber.Ctx) error {
+ fmt.Println("1st route!")
+ return c.Next()
+})
+
+app.Get("*", func(c *fiber.Ctx) error {
+ fmt.Println("2nd route!")
+ return c.Next()
+})
+
+app.Get("/", func(c *fiber.Ctx) error {
+ fmt.Println("3rd route!")
+ return c.SendString("Hello, World!")
+})
+```
+
+## OriginalURL
+
+Returns the original request URL.
+
+```go title="Signature"
+func (c *Ctx) OriginalURL() string
+```
+
+```go title="Example"
+// GET http://example.com/search?q=something
+
+app.Get("/", func(c *fiber.Ctx) error {
+ c.OriginalURL() // "/search?q=something"
+
+ // ...
+})
+```
+
+> _Returned value is only valid within the handler. Do not store any references.
+> Make copies or use the_ [_**`Immutable`**_](ctx.md) _setting instead._ [_Read more..._](../#zero-allocation)
+
+## Params
+
+Method can be used to get the route parameters, you could pass an optional default value that will be returned if the param key does not exist.
+
+:::info
+Defaults to empty string \(`""`\), if the param **doesn't** exist.
+:::
+
+```go title="Signature"
+func (c *Ctx) Params(key string, defaultValue ...string) string
+```
+
+```go title="Example"
+// GET http://example.com/user/fenny
+app.Get("/user/:name", func(c *fiber.Ctx) error {
+ c.Params("name") // "fenny"
+
+ // ...
+})
+
+// GET http://example.com/user/fenny/123
+app.Get("/user/*", func(c *fiber.Ctx) error {
+ c.Params("*") // "fenny/123"
+ c.Params("*1") // "fenny/123"
+
+ // ...
+})
+```
+
+Unnamed route parameters\(\*, +\) can be fetched by the **character** and the **counter** in the route.
+
+```go title="Example"
+// ROUTE: /v1/*/shop/*
+// GET: /v1/brand/4/shop/blue/xs
+c.Params("*1") // "brand/4"
+c.Params("*2") // "blue/xs"
+```
+
+For reasons of **downward compatibility**, the first parameter segment for the parameter character can also be accessed without the counter.
+
+```go title="Example"
+app.Get("/v1/*/shop/*", func(c *fiber.Ctx) error {
+ c.Params("*") // outputs the values of the first wildcard segment
+})
+```
+
+> _Returned value is only valid within the handler. Do not store any references.
+> Make copies or use the_ [_**`Immutable`**_](ctx.md) _setting instead._ [_Read more..._](../#zero-allocation)
+
+## ParamsInt
+
+Method can be used to get an integer from the route parameters.
+Please note if that parameter is not in the request, zero
+will be returned. If the parameter is NOT a number, zero and an error
+will be returned
+
+:::info
+Defaults to the integer zero \(`0`\), if the param **doesn't** exist.
+:::
+
+```go title="Signature"
+func (c *Ctx) ParamsInt(key string) (int, error)
+```
+
+```go title="Example"
+// GET http://example.com/user/123
+app.Get("/user/:id", func(c *fiber.Ctx) error {
+ id, err := c.ParamsInt("id") // int 123 and no error
+
+ // ...
+})
+
+```
+
+This method is equivalent of using `atoi` with ctx.Params
+
+## ParamsParser
+This method is similar to BodyParser, but for path parameters. It is important to use the struct tag "params". For example, if you want to parse a path parameter with a field called Pass, you would use a struct field of params:"pass"
+
+```go title="Signature"
+func (c *Ctx) ParamsParser(out interface{}) error
+```
+
+```go title="Example"
+// GET http://example.com/user/111
+app.Get("/user/:id", func(c *fiber.Ctx) error {
+ param := struct {ID uint `params:"id"`}{}
+
+ c.ParamsParser(¶m) // "{"id": 111}"
+
+ // ...
+})
+
+```
+
+## Path
+
+Contains the path part of the request URL. Optionally, you could override the path by passing a string. For internal redirects, you might want to call [RestartRouting](ctx.md#restartrouting) instead of [Next](ctx.md#next).
+
+```go title="Signature"
+func (c *Ctx) Path(override ...string) string
+```
+
+```go title="Example"
+// GET http://example.com/users?sort=desc
+
+app.Get("/users", func(c *fiber.Ctx) error {
+ c.Path() // "/users"
+
+ c.Path("/john")
+ c.Path() // "/john"
+
+ // ...
+})
+```
+
+## Protocol
+
+Contains the request protocol string: `http` or `https` for **TLS** requests.
+
+```go title="Signature"
+func (c *Ctx) Protocol() string
+```
+
+```go title="Example"
+// GET http://example.com
+
+app.Get("/", func(c *fiber.Ctx) error {
+ c.Protocol() // "http"
+
+ // ...
+})
+```
+
+## Queries
+
+Queries is a function that returns an object containing a property for each query string parameter in the route.
+
+```go title="Signature"
+func (c *Ctx) Queries() map[string]string
+```
+
+```go title="Example"
+// GET http://example.com/?name=alex&want_pizza=false&id=
+
+app.Get("/", func(c *fiber.Ctx) error {
+ m := c.Queries()
+ m["name"] // "alex"
+ m["want_pizza"] // "false"
+ m["id"] // ""
+ // ...
+})
+```
+
+```go title="Example"
+// GET http://example.com/?field1=value1&field1=value2&field2=value3
+
+app.Get("/", func (c *fiber.Ctx) error {
+ m := c.Queries()
+ m["field1"] // "value2"
+ m["field2"] // value3
+})
+```
+
+```go title="Example"
+// GET http://example.com/?list_a=1&list_a=2&list_a=3&list_b[]=1&list_b[]=2&list_b[]=3&list_c=1,2,3
+
+app.Get("/", func(c *fiber.Ctx) error {
+ m := c.Queries()
+ m["list_a"] // "3"
+ m["list_b[]"] // "3"
+ m["list_c"] // "1,2,3"
+})
+```
+
+```go title="Example"
+// GET /api/posts?filters.author.name=John&filters.category.name=Technology
+
+app.Get("/", func(c *fiber.Ctx) error {
+ m := c.Queries()
+ m["filters.author.name"] // John
+ m["filters.category.name"] // Technology
+})
+```
+
+```go title="Example"
+// GET /api/posts?tags=apple,orange,banana&filters[tags]=apple,orange,banana&filters[category][name]=fruits&filters.tags=apple,orange,banana&filters.category.name=fruits
+
+app.Get("/", func(c *fiber.Ctx) error {
+ m := c.Queries()
+ m["tags"] // apple,orange,banana
+ m["filters[tags]"] // apple,orange,banana
+ m["filters[category][name]"] // fruits
+ m["filters.tags"] // apple,orange,banana
+ m["filters.category.name"] // fruits
+})
+```
+
+## Query
+
+This property is an object containing a property for each query string parameter in the route, you could pass an optional default value that will be returned if the query key does not exist.
+
+:::info
+If there is **no** query string, it returns an **empty string**.
+:::
+
+```go title="Signature"
+func (c *Ctx) Query(key string, defaultValue ...string) string
+```
+
+```go title="Example"
+// GET http://example.com/?order=desc&brand=nike
+
+app.Get("/", func(c *fiber.Ctx) error {
+ c.Query("order") // "desc"
+ c.Query("brand") // "nike"
+ c.Query("empty", "nike") // "nike"
+
+ // ...
+})
+```
+
+> _Returned value is only valid within the handler. Do not store any references.
+> Make copies or use the_ [_**`Immutable`**_](ctx.md) _setting instead._ [_Read more..._](../#zero-allocation)
+
+## QueryBool
+
+This property is an object containing a property for each query boolean parameter in the route, you could pass an optional default value that will be returned if the query key does not exist.
+
+
+:::caution
+Please note if that parameter is not in the request, false will be returned.
+If the parameter is not a boolean, it is still tried to be converted and usually returned as false.
+:::
+
+```go title="Signature"
+func (c *Ctx) QueryBool(key string, defaultValue ...bool) bool
+```
+
+```go title="Example"
+// GET http://example.com/?name=alex&want_pizza=false&id=
+
+app.Get("/", func(c *fiber.Ctx) error {
+ c.QueryBool("want_pizza") // false
+ c.QueryBool("want_pizza", true) // false
+ c.QueryBool("name") // false
+ c.QueryBool("name", true) // true
+ c.QueryBool("id") // false
+ c.QueryBool("id", true) // true
+
+ // ...
+})
+```
+
+## QueryFloat
+
+This property is an object containing a property for each query float64 parameter in the route, you could pass an optional default value that will be returned if the query key does not exist.
+
+:::caution
+Please note if that parameter is not in the request, zero will be returned.
+If the parameter is not a number, it is still tried to be converted and usually returned as 1.
+:::
+
+:::info
+Defaults to the float64 zero \(`0`\), if the param **doesn't** exist.
+:::
+
+```go title="Signature"
+func (c *Ctx) QueryFloat(key string, defaultValue ...float64) float64
+```
+
+```go title="Example"
+// GET http://example.com/?name=alex&amount=32.23&id=
+
+app.Get("/", func(c *fiber.Ctx) error {
+ c.QueryFloat("amount") // 32.23
+ c.QueryFloat("amount", 3) // 32.23
+ c.QueryFloat("name", 1) // 1
+ c.QueryFloat("name") // 0
+ c.QueryFloat("id", 3) // 3
+
+ // ...
+})
+```
+
+
+## QueryInt
+
+This property is an object containing a property for each query integer parameter in the route, you could pass an optional default value that will be returned if the query key does not exist.
+
+
+:::caution
+Please note if that parameter is not in the request, zero will be returned.
+If the parameter is not a number, it is still tried to be converted and usually returned as 1.
+:::
+
+:::info
+Defaults to the integer zero \(`0`\), if the param **doesn't** exist.
+:::
+
+```go title="Signature"
+func (c *Ctx) QueryInt(key string, defaultValue ...int) int
+```
+
+```go title="Example"
+// GET http://example.com/?name=alex&wanna_cake=2&id=
+
+app.Get("/", func(c *fiber.Ctx) error {
+ c.QueryInt("wanna_cake", 1) // 2
+ c.QueryInt("name", 1) // 1
+ c.QueryInt("id", 1) // 1
+ c.QueryInt("id") // 0
+
+ // ...
+})
+```
+
+## QueryParser
+
+This method is similar to [BodyParser](ctx.md#bodyparser), but for query parameters.
+It is important to use the struct tag "query". For example, if you want to parse a query parameter with a field called Pass, you would use a struct field of `query:"pass"`.
+
+```go title="Signature"
+func (c *Ctx) QueryParser(out interface{}) error
+```
+
+```go title="Example"
+// Field names should start with an uppercase letter
+type Person struct {
+ Name string `query:"name"`
+ Pass string `query:"pass"`
+ Products []string `query:"products"`
+}
+
+app.Get("/", func(c *fiber.Ctx) error {
+ p := new(Person)
+
+ if err := c.QueryParser(p); err != nil {
+ return err
+ }
+
+ log.Println(p.Name) // john
+ log.Println(p.Pass) // doe
+ log.Println(p.Products) // [shoe, hat]
+
+ // ...
+})
+// Run tests with the following curl command
+
+// curl "http://localhost:3000/?name=john&pass=doe&products=shoe,hat"
+```
+
+## Range
+
+A struct containing the type and a slice of ranges will be returned.
+
+```go title="Signature"
+func (c *Ctx) Range(size int) (Range, error)
+```
+
+```go title="Example"
+// Range: bytes=500-700, 700-900
+app.Get("/", func(c *fiber.Ctx) error {
+ b := c.Range(1000)
+ if b.Type == "bytes" {
+ for r := range r.Ranges {
+ fmt.Println(r)
+ // [500, 700]
+ }
+ }
+})
+```
+
+## Redirect
+
+Redirects to the URL derived from the specified path, with specified status, a positive integer that corresponds to an HTTP status code.
+
+:::info
+If **not** specified, status defaults to **302 Found**.
+:::
+
+```go title="Signature"
+func (c *Ctx) Redirect(location string, status ...int) error
+```
+
+```go title="Example"
+app.Get("/coffee", func(c *fiber.Ctx) error {
+ return c.Redirect("/teapot")
+})
+
+app.Get("/teapot", func(c *fiber.Ctx) error {
+ return c.Status(fiber.StatusTeapot).Send("🍵 short and stout 🍵")
+})
+```
+
+```go title="More examples"
+app.Get("/", func(c *fiber.Ctx) error {
+ return c.Redirect("/foo/bar")
+ return c.Redirect("../login")
+ return c.Redirect("http://example.com")
+ return c.Redirect("http://example.com", 301)
+})
+```
+
+## RedirectToRoute
+
+Redirects to the specific route along with the parameters and with specified status, a positive integer that corresponds to an HTTP status code.
+
+:::info
+If **not** specified, status defaults to **302 Found**.
+:::
+
+:::info
+If you want to send queries to route, you must add **"queries"** key typed as **map[string]string** to params.
+:::
+
+```go title="Signature"
+func (c *Ctx) RedirectToRoute(routeName string, params fiber.Map, status ...int) error
+```
+
+```go title="Example"
+app.Get("/", func(c *fiber.Ctx) error {
+ // /user/fiber
+ return c.RedirectToRoute("user", fiber.Map{
+ "name": "fiber"
+ })
+})
+
+app.Get("/with-queries", func(c *fiber.Ctx) error {
+ // /user/fiber?data[0][name]=john&data[0][age]=10&test=doe
+ return c.RedirectToRoute("user", fiber.Map{
+ "name": "fiber",
+ "queries": map[string]string{"data[0][name]": "john", "data[0][age]": "10", "test": "doe"},
+ })
+})
+
+app.Get("/user/:name", func(c *fiber.Ctx) error {
+ return c.SendString(c.Params("name"))
+}).Name("user")
+```
+
+## RedirectBack
+
+Redirects back to refer URL. It redirects to fallback URL if refer header doesn't exists, with specified status, a positive integer that corresponds to an HTTP status code.
+
+:::info
+If **not** specified, status defaults to **302 Found**.
+:::
+
+```go title="Signature"
+func (c *Ctx) RedirectBack(fallback string, status ...int) error
+```
+
+```go title="Example"
+app.Get("/", func(c *fiber.Ctx) error {
+ return c.SendString("Home page")
+})
+app.Get("/test", func(c *fiber.Ctx) error {
+ c.Set("Content-Type", "text/html")
+ return c.SendString(`Back`)
+})
+
+app.Get("/back", func(c *fiber.Ctx) error {
+ return c.RedirectBack("/")
+})
+```
+
+## Render
+
+Renders a view with data and sends a `text/html` response. By default `Render` uses the default [**Go Template engine**](https://pkg.go.dev/html/template/). If you want to use another View engine, please take a look at our [**Template middleware**](https://docs.gofiber.io/template).
+
+```go title="Signature"
+func (c *Ctx) Render(name string, bind interface{}, layouts ...string) error
+```
+
+## Request
+
+Request return the [\*fasthttp.Request](https://godoc.org/github.com/valyala/fasthttp#Request) pointer
+
+```go title="Signature"
+func (c *Ctx) Request() *fasthttp.Request
+```
+
+```go title="Example"
+app.Get("/", func(c *fiber.Ctx) error {
+ c.Request().Header.Method()
+ // => []byte("GET")
+})
+```
+
+## ReqHeaderParser
+
+This method is similar to [BodyParser](ctx.md#bodyparser), but for request headers.
+It is important to use the struct tag "reqHeader". For example, if you want to parse a request header with a field called Pass, you would use a struct field of `reqHeader:"pass"`.
+
+```go title="Signature"
+func (c *Ctx) ReqHeaderParser(out interface{}) error
+```
+
+```go title="Example"
+// Field names should start with an uppercase letter
+type Person struct {
+ Name string `reqHeader:"name"`
+ Pass string `reqHeader:"pass"`
+ Products []string `reqHeader:"products"`
+}
+
+app.Get("/", func(c *fiber.Ctx) error {
+ p := new(Person)
+
+ if err := c.ReqHeaderParser(p); err != nil {
+ return err
+ }
+
+ log.Println(p.Name) // john
+ log.Println(p.Pass) // doe
+ log.Println(p.Products) // [shoe, hat]
+
+ // ...
+})
+// Run tests with the following curl command
+
+// curl "http://localhost:3000/" -H "name: john" -H "pass: doe" -H "products: shoe,hat"
+```
+
+## Response
+
+Response return the [\*fasthttp.Response](https://godoc.org/github.com/valyala/fasthttp#Response) pointer
+
+```go title="Signature"
+func (c *Ctx) Response() *fasthttp.Response
+```
+
+```go title="Example"
+app.Get("/", func(c *fiber.Ctx) error {
+ c.Response().BodyWriter().Write([]byte("Hello, World!"))
+ // => "Hello, World!"
+ return nil
+})
+```
+
+## RestartRouting
+
+Instead of executing the next method when calling [Next](ctx.md#next), **RestartRouting** restarts execution from the first method that matches the current route. This may be helpful after overriding the path, i. e. an internal redirect. Note that handlers might be executed again which could result in an infinite loop.
+
+```go title="Signature"
+func (c *Ctx) RestartRouting() error
+```
+
+```go title="Example"
+app.Get("/new", func(c *fiber.Ctx) error {
+ return c.SendString("From /new")
+})
+
+app.Get("/old", func(c *fiber.Ctx) error {
+ c.Path("/new")
+ return c.RestartRouting()
+})
+```
+
+## Route
+
+Returns the matched [Route](https://pkg.go.dev/github.com/gofiber/fiber?tab=doc#Route) struct.
+
+```go title="Signature"
+func (c *Ctx) Route() *Route
+```
+
+```go title="Example"
+// http://localhost:8080/hello
+
+
+app.Get("/hello/:name", func(c *fiber.Ctx) error {
+ r := c.Route()
+ fmt.Println(r.Method, r.Path, r.Params, r.Handlers)
+ // GET /hello/:name handler [name]
+
+ // ...
+})
+```
+
+:::caution
+Do not rely on `c.Route()` in middlewares **before** calling `c.Next()` - `c.Route()` returns the **last executed route**.
+:::
+
+```go title="Example"
+func MyMiddleware() fiber.Handler {
+ return func(c *fiber.Ctx) error {
+ beforeNext := c.Route().Path // Will be '/'
+ err := c.Next()
+ afterNext := c.Route().Path // Will be '/hello/:name'
+ return err
+ }
+}
+```
+
+## SaveFile
+
+Method is used to save **any** multipart file to disk.
+
+```go title="Signature"
+func (c *Ctx) SaveFile(fh *multipart.FileHeader, path string) error
+```
+
+```go title="Example"
+app.Post("/", func(c *fiber.Ctx) error {
+ // Parse the multipart form:
+ if form, err := c.MultipartForm(); err == nil {
+ // => *multipart.Form
+
+ // Get all files from "documents" key:
+ files := form.File["documents"]
+ // => []*multipart.FileHeader
+
+ // Loop through files:
+ for _, file := range files {
+ fmt.Println(file.Filename, file.Size, file.Header["Content-Type"][0])
+ // => "tutorial.pdf" 360641 "application/pdf"
+
+ // Save the files to disk:
+ if err := c.SaveFile(file, fmt.Sprintf("./%s", file.Filename)); err != nil {
+ return err
+ }
+ }
+ return err
+ }
+})
+```
+
+## SaveFileToStorage
+
+Method is used to save **any** multipart file to an external storage system.
+
+```go title="Signature"
+func (c *Ctx) SaveFileToStorage(fileheader *multipart.FileHeader, path string, storage Storage) error
+```
+
+```go title="Example"
+storage := memory.New()
+
+app.Post("/", func(c *fiber.Ctx) error {
+ // Parse the multipart form:
+ if form, err := c.MultipartForm(); err == nil {
+ // => *multipart.Form
+
+ // Get all files from "documents" key:
+ files := form.File["documents"]
+ // => []*multipart.FileHeader
+
+ // Loop through files:
+ for _, file := range files {
+ fmt.Println(file.Filename, file.Size, file.Header["Content-Type"][0])
+ // => "tutorial.pdf" 360641 "application/pdf"
+
+ // Save the files to storage:
+ if err := c.SaveFileToStorage(file, fmt.Sprintf("./%s", file.Filename), storage); err != nil {
+ return err
+ }
+ }
+ return err
+ }
+})
+```
+
+## Secure
+
+A boolean property that is `true` , if a **TLS** connection is established.
+
+```go title="Signature"
+func (c *Ctx) Secure() bool
+```
+
+```go title="Example"
+// Secure() method is equivalent to:
+c.Protocol() == "https"
+```
+
+## Send
+
+Sets the HTTP response body.
+
+```go title="Signature"
+func (c *Ctx) Send(body []byte) error
+```
+
+```go title="Example"
+app.Get("/", func(c *fiber.Ctx) error {
+ return c.Send([]byte("Hello, World!")) // => "Hello, World!"
+})
+```
+
+Fiber also provides `SendString` and `SendStream` methods for raw inputs.
+
+:::tip
+Use this if you **don't need** type assertion, recommended for **faster** performance.
+:::
+
+```go title="Signature"
+func (c *Ctx) SendString(body string) error
+func (c *Ctx) SendStream(stream io.Reader, size ...int) error
+```
+
+```go title="Example"
+app.Get("/", func(c *fiber.Ctx) error {
+ return c.SendString("Hello, World!")
+ // => "Hello, World!"
+
+ return c.SendStream(bytes.NewReader([]byte("Hello, World!")))
+ // => "Hello, World!"
+})
+```
+
+## SendFile
+
+Transfers the file from the given path. Sets the [Content-Type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type) response HTTP header field based on the **filenames** extension.
+
+:::caution
+Method doesn´t use **gzipping** by default, set it to **true** to enable.
+:::
+
+```go title="Signature" title="Signature"
+func (c *Ctx) SendFile(file string, compress ...bool) error
+```
+
+```go title="Example"
+app.Get("/not-found", func(c *fiber.Ctx) error {
+ return c.SendFile("./public/404.html");
+
+ // Disable compression
+ return c.SendFile("./static/index.html", false);
+})
+```
+
+:::info
+If the file contains an url specific character you have to escape it before passing the file path into the `sendFile` function.
+:::
+
+```go title="Example"
+app.Get("/file-with-url-chars", func(c *fiber.Ctx) error {
+ return c.SendFile(url.PathEscape("hash_sign_#.txt"))
+})
+```
+
+## SendStatus
+
+Sets the status code and the correct status message in the body, if the response body is **empty**.
+
+:::tip
+You can find all used status codes and messages [here](https://github.com/gofiber/fiber/blob/dffab20bcdf4f3597d2c74633a7705a517d2c8c2/utils.go#L183-L244).
+:::
+
+```go title="Signature"
+func (c *Ctx) SendStatus(status int) error
+```
+
+```go title="Example"
+app.Get("/not-found", func(c *fiber.Ctx) error {
+ return c.SendStatus(415)
+ // => 415 "Unsupported Media Type"
+
+ c.SendString("Hello, World!")
+ return c.SendStatus(415)
+ // => 415 "Hello, World!"
+})
+```
+
+## Set
+
+Sets the response’s HTTP header field to the specified `key`, `value`.
+
+```go title="Signature"
+func (c *Ctx) Set(key string, val string)
+```
+
+```go title="Example"
+app.Get("/", func(c *fiber.Ctx) error {
+ c.Set("Content-Type", "text/plain")
+ // => "Content-type: text/plain"
+
+ // ...
+})
+```
+
+## SetParserDecoder
+
+Allow you to config BodyParser/QueryParser decoder, base on schema's options, providing possibility to add custom type for parsing.
+
+```go title="Signature"
+func SetParserDecoder(parserConfig fiber.ParserConfig{
+ IgnoreUnknownKeys bool,
+ ParserType []fiber.ParserType{
+ Customtype interface{},
+ Converter func(string) reflect.Value,
+ },
+ ZeroEmpty bool,
+ SetAliasTag string,
+})
+```
+
+```go title="Example"
+
+type CustomTime time.Time
+
+// String() returns the time in string
+func (ct *CustomTime) String() string {
+ t := time.Time(*ct).String()
+ return t
+}
+
+// Register the converter for CustomTime type format as 2006-01-02
+var timeConverter = func(value string) reflect.Value {
+ fmt.Println("timeConverter", value)
+ if v, err := time.Parse("2006-01-02", value); err == nil {
+ return reflect.ValueOf(v)
+ }
+ return reflect.Value{}
+}
+
+customTime := fiber.ParserType{
+ Customtype: CustomTime{},
+ Converter: timeConverter,
+}
+
+// Add setting to the Decoder
+fiber.SetParserDecoder(fiber.ParserConfig{
+ IgnoreUnknownKeys: true,
+ ParserType: []fiber.ParserType{customTime},
+ ZeroEmpty: true,
+})
+
+// Example to use CustomType, you pause custom time format not in RFC3339
+type Demo struct {
+ Date CustomTime `form:"date" query:"date"`
+ Title string `form:"title" query:"title"`
+ Body string `form:"body" query:"body"`
+}
+
+app.Post("/body", func(c *fiber.Ctx) error {
+ var d Demo
+ c.BodyParser(&d)
+ fmt.Println("d.Date", d.Date.String())
+ return c.JSON(d)
+})
+
+app.Get("/query", func(c *fiber.Ctx) error {
+ var d Demo
+ c.QueryParser(&d)
+ fmt.Println("d.Date", d.Date.String())
+ return c.JSON(d)
+})
+
+// curl -X POST -F title=title -F body=body -F date=2021-10-20 http://localhost:3000/body
+
+// curl -X GET "http://localhost:3000/query?title=title&body=body&date=2021-10-20"
+
+```
+
+
+## SetUserContext
+
+Sets the user specified implementation for context interface.
+
+```go title="Signature"
+func (c *Ctx) SetUserContext(ctx context.Context)
+```
+
+```go title="Example"
+app.Get("/", func(c *fiber.Ctx) error {
+ ctx := context.Background()
+ c.SetUserContext(ctx)
+ // Here ctx could be any context implementation
+
+ // ...
+})
+```
+
+## Stale
+
+[https://expressjs.com/en/4x/api.html\#req.stale](https://expressjs.com/en/4x/api.html#req.stale)
+
+```go title="Signature"
+func (c *Ctx) Stale() bool
+```
+
+## Status
+
+Sets the HTTP status for the response.
+
+:::info
+Method is a **chainable**.
+:::
+
+```go title="Signature"
+func (c *Ctx) Status(status int) *Ctx
+```
+
+```go title="Example"
+app.Get("/fiber", func(c *fiber.Ctx) error {
+ c.Status(fiber.StatusOK)
+ return nil
+}
+
+app.Get("/hello", func(c *fiber.Ctx) error {
+ return c.Status(fiber.StatusBadRequest).SendString("Bad Request")
+}
+
+app.Get("/world", func(c *fiber.Ctx) error {
+ return c.Status(fiber.StatusNotFound).SendFile("./public/gopher.png")
+})
+```
+
+## Subdomains
+
+Returns a string slice of subdomains in the domain name of the request.
+
+The application property subdomain offset, which defaults to `2`, is used for determining the beginning of the subdomain segments.
+
+```go title="Signature"
+func (c *Ctx) Subdomains(offset ...int) []string
+```
+
+```go title="Example"
+// Host: "tobi.ferrets.example.com"
+
+app.Get("/", func(c *fiber.Ctx) error {
+ c.Subdomains() // ["ferrets", "tobi"]
+ c.Subdomains(1) // ["tobi"]
+
+ // ...
+})
+```
+
+## Type
+
+Sets the [Content-Type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type) HTTP header to the MIME type listed [here](https://github.com/nginx/nginx/blob/master/conf/mime.types) specified by the file **extension**.
+
+```go title="Signature"
+func (c *Ctx) Type(ext string, charset ...string) *Ctx
+```
+
+```go title="Example"
+app.Get("/", func(c *fiber.Ctx) error {
+ c.Type(".html") // => "text/html"
+ c.Type("html") // => "text/html"
+ c.Type("png") // => "image/png"
+
+ c.Type("json", "utf-8") // => "application/json; charset=utf-8"
+
+ // ...
+})
+```
+
+## UserContext
+
+UserContext returns a context implementation that was set by user earlier
+or returns a non-nil, empty context, if it was not set earlier.
+
+```go title="Signature"
+func (c *Ctx) UserContext() context.Context
+```
+
+```go title="Example"
+app.Get("/", func(c *fiber.Ctx) error {
+ ctx := c.UserContext()
+ // ctx is context implementation set by user
+
+ // ...
+})
+```
+
+## Vary
+
+Adds the given header field to the [Vary](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Vary) response header. This will append the header, if not already listed, otherwise leaves it listed in the current location.
+
+:::info
+Multiple fields are **allowed**.
+:::
+
+```go title="Signature"
+func (c *Ctx) Vary(fields ...string)
+```
+
+```go title="Example"
+app.Get("/", func(c *fiber.Ctx) error {
+ c.Vary("Origin") // => Vary: Origin
+ c.Vary("User-Agent") // => Vary: Origin, User-Agent
+
+ // No duplicates
+ c.Vary("Origin") // => Vary: Origin, User-Agent
+
+ c.Vary("Accept-Encoding", "Accept")
+ // => Vary: Origin, User-Agent, Accept-Encoding, Accept
+
+ // ...
+})
+```
+
+## Write
+
+Write adopts the Writer interface
+
+```go title="Signature"
+func (c *Ctx) Write(p []byte) (n int, err error)
+```
+
+```go title="Example"
+app.Get("/", func(c *fiber.Ctx) error {
+ c.Write([]byte("Hello, World!")) // => "Hello, World!"
+
+ fmt.Fprintf(c, "%s\n", "Hello, World!") // "Hello, World!Hello, World!"
+})
+```
+
+## Writef
+
+Writef adopts the string with variables
+
+```go title="Signature"
+func (c *Ctx) Writef(f string, a ...interface{}) (n int, err error)
+```
+
+```go title="Example"
+app.Get("/", func(c *fiber.Ctx) error {
+ world := "World!"
+ c.Writef("Hello, %s", world) // => "Hello, World!"
+
+ fmt.Fprintf(c, "%s\n", "Hello, World!") // "Hello, World!Hello, World!"
+})
+```
+
+## WriteString
+
+WriteString adopts the string
+
+```go title="Signature"
+func (c *Ctx) WriteString(s string) (n int, err error)
+```
+
+```go title="Example"
+app.Get("/", func(c *fiber.Ctx) error {
+ c.WriteString("Hello, World!") // => "Hello, World!"
+
+ fmt.Fprintf(c, "%s\n", "Hello, World!") // "Hello, World!Hello, World!"
+})
+```
+
+## XHR
+
+A Boolean property, that is `true`, if the request’s [X-Requested-With](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers) header field is [XMLHttpRequest](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest), indicating that the request was issued by a client library \(such as [jQuery](https://api.jquery.com/jQuery.ajax/)\).
+
+```go title="Signature"
+func (c *Ctx) XHR() bool
+```
+
+```go title="Example"
+// X-Requested-With: XMLHttpRequest
+
+app.Get("/", func(c *fiber.Ctx) error {
+ c.XHR() // true
+
+ // ...
+})
+```
+
+## XML
+
+Converts any **interface** or **string** to XML using the standard `encoding/xml` package.
+
+:::info
+XML also sets the content header to **application/xml**.
+:::
+
+```go title="Signature"
+func (c *Ctx) XML(data interface{}) error
+```
+
+```go title="Example"
+type SomeStruct struct {
+ XMLName xml.Name `xml:"Fiber"`
+ Name string `xml:"Name"`
+ Age uint8 `xml:"Age"`
+}
+
+app.Get("/", func(c *fiber.Ctx) error {
+ // Create data struct:
+ data := SomeStruct{
+ Name: "Grame",
+ Age: 20,
+ }
+
+ return c.XML(data)
+ //
+ // Grame
+ // 20
+ //
+})
+```
diff --git a/docs/api/fiber.md b/docs/api/fiber.md
new file mode 100644
index 0000000000..fa0ad2412d
--- /dev/null
+++ b/docs/api/fiber.md
@@ -0,0 +1,119 @@
+---
+id: fiber
+title: 📦 Fiber
+description: Fiber represents the fiber package where you start to create an instance.
+sidebar_position: 1
+---
+
+## New
+
+This method creates a new **App** named instance. You can pass optional [config ](#config)when creating a new instance.
+
+```go title="Signature"
+func New(config ...Config) *App
+```
+
+```go title="Example"
+// Default config
+app := fiber.New()
+
+// ...
+```
+
+## Config
+
+You can pass an optional Config when creating a new Fiber instance.
+
+```go title="Example"
+// Custom config
+app := fiber.New(fiber.Config{
+ Prefork: true,
+ CaseSensitive: true,
+ StrictRouting: true,
+ ServerHeader: "Fiber",
+ AppName: "Test App v1.0.1",
+})
+
+// ...
+```
+
+**Config fields**
+
+| Property | Type | Description | Default |
+| ---------------------------- | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------- |
+| AppName | `string` | This allows to setup app name for the app | `""` |
+| BodyLimit | `int` | Sets the maximum allowed size for a request body, if the size exceeds the configured limit, it sends `413 - Request Entity Too Large` response. | `4 * 1024 * 1024` |
+| CaseSensitive | `bool` | When enabled, `/Foo` and `/foo` are different routes. When disabled, `/Foo`and `/foo` are treated the same. | `false` |
+| ColorScheme | [`Colors`](https://github.com/gofiber/fiber/blob/master/color.go) | You can define custom color scheme. They'll be used for startup message, route list and some middlewares. | [`DefaultColors`](https://github.com/gofiber/fiber/blob/master/color.go) |
+| CompressedFileSuffix | `string` | Adds a suffix to the original file name and tries saving the resulting compressed file under the new file name. | `".fiber.gz"` |
+| Concurrency | `int` | Maximum number of concurrent connections. | `256 * 1024` |
+| DisableDefaultContentType | `bool` | When set to true, causes the default Content-Type header to be excluded from the Response. | `false` |
+| DisableDefaultDate | `bool` | When set to true causes the default date header to be excluded from the response. | `false` |
+| DisableHeaderNormalizing | `bool` | By default all header names are normalized: conteNT-tYPE -> Content-Type | `false` |
+| DisableKeepalive | `bool` | Disable keep-alive connections, the server will close incoming connections after sending the first response to the client | `false` |
+| DisablePreParseMultipartForm | `bool` | Will not pre parse Multipart Form data if set to true. This option is useful for servers that desire to treat multipart form data as a binary blob, or choose when to parse the data. | `false` |
+| DisableStartupMessage | `bool` | When set to true, it will not print out debug information | `false` |
+| ETag | `bool` | Enable or disable ETag header generation, since both weak and strong etags are generated using the same hashing method \(CRC-32\). Weak ETags are the default when enabled. | `false` |
+| EnableIPValidation | `bool` | If set to true, `c.IP()` and `c.IPs()` will validate IP addresses before returning them. Also, `c.IP()` will return only the first valid IP rather than just the raw header value that may be a comma seperated string.
**WARNING:** There is a small performance cost to doing this validation. Keep disabled if speed is your only concern and your application is behind a trusted proxy that already validates this header. | `false` |
+| EnablePrintRoutes | `bool` | EnablePrintRoutes enables print all routes with their method, path, name and handler.. | `false` |
+| EnableTrustedProxyCheck | `bool` | When set to true, fiber will check whether proxy is trusted, using TrustedProxies list.
By default `c.Protocol()` will get value from X-Forwarded-Proto, X-Forwarded-Protocol, X-Forwarded-Ssl or X-Url-Scheme header, `c.IP()` will get value from `ProxyHeader` header, `c.Hostname()` will get value from X-Forwarded-Host header. If `EnableTrustedProxyCheck` is true, and `RemoteIP` is in the list of `TrustedProxies` `c.Protocol()`, `c.IP()`, and `c.Hostname()` will have the same behaviour when `EnableTrustedProxyCheck` disabled, if `RemoteIP` isn't in the list, `c.Protocol()` will return https in case when tls connection is handled by the app, or http otherwise, `c.IP()` will return RemoteIP() from fasthttp context, `c.Hostname()` will return `fasthttp.Request.URI().Host()` | `false` |
+| ErrorHandler | `ErrorHandler` | ErrorHandler is executed when an error is returned from fiber.Handler. Mounted fiber error handlers are retained by the top-level app and applied on prefix associated requests. | `DefaultErrorHandler` |
+| GETOnly | `bool` | Rejects all non-GET requests if set to true. This option is useful as anti-DoS protection for servers accepting only GET requests. The request size is limited by ReadBufferSize if GETOnly is set. | `false` |
+| IdleTimeout | `time.Duration` | The maximum amount of time to wait for the next request when keep-alive is enabled. If IdleTimeout is zero, the value of ReadTimeout is used. | `nil` |
+| Immutable | `bool` | When enabled, all values returned by context methods are immutable. By default, they are valid until you return from the handler; see issue [\#185](https://github.com/gofiber/fiber/issues/185). | `false` |
+| JSONDecoder | `utils.JSONUnmarshal` | Allowing for flexibility in using another json library for decoding. | `json.Unmarshal` |
+| JSONEncoder | `utils.JSONMarshal` | Allowing for flexibility in using another json library for encoding. | `json.Marshal` |
+| Network | `string` | Known networks are "tcp", "tcp4" (IPv4-only), "tcp6" (IPv6-only)
**WARNING:** When prefork is set to true, only "tcp4" and "tcp6" can be chosen. | `NetworkTCP4` |
+| PassLocalsToViews | `bool` | PassLocalsToViews Enables passing of the locals set on a fiber.Ctx to the template engine. See our **Template Middleware** for supported engines. | `false` |
+| Prefork | `bool` | Enables use of the[`SO_REUSEPORT`](https://lwn.net/Articles/542629/)socket option. This will spawn multiple Go processes listening on the same port. learn more about [socket sharding](https://www.nginx.com/blog/socket-sharding-nginx-release-1-9-1/). **NOTE: if enabled, the application will need to be ran through a shell because prefork mode sets environment variables. If you're using Docker, make sure the app is ran with `CMD ./app` or `CMD ["sh", "-c", "/app"]`. For more info, see** [**this**](https://github.com/gofiber/fiber/issues/1021#issuecomment-730537971) **issue comment.** | `false` |
+| ProxyHeader | `string` | This will enable `c.IP()` to return the value of the given header key. By default `c.IP()`will return the Remote IP from the TCP connection, this property can be useful if you are behind a load balancer e.g. _X-Forwarded-\*_. | `""` |
+| ReadBufferSize | `int` | per-connection buffer size for requests' reading. This also limits the maximum header size. Increase this buffer if your clients send multi-KB RequestURIs and/or multi-KB headers \(for example, BIG cookies\). | `4096` |
+| ReadTimeout | `time.Duration` | The amount of time allowed to read the full request, including the body. The default timeout is unlimited. | `nil` |
+| RequestMethods | `[]string` | RequestMethods provides customizibility for HTTP methods. You can add/remove methods as you wish. | `DefaultMethods` |
+| ServerHeader | `string` | Enables the `Server` HTTP header with the given value. | `""` |
+| StreamRequestBody | `bool` | StreamRequestBody enables request body streaming, and calls the handler sooner when given body is larger then the current limit. | `false` |
+| StrictRouting | `bool` | When enabled, the router treats `/foo` and `/foo/` as different. Otherwise, the router treats `/foo` and `/foo/` as the same. | `false` |
+| TrustedProxies | `[]string` | Contains the list of trusted proxy IP's. Look at `EnableTrustedProxyCheck` doc.
It can take IP or IP range addresses. If it gets IP range, it iterates all possible addresses. | `[]string*__*` |
+| UnescapePath | `bool` | Converts all encoded characters in the route back before setting the path for the context, so that the routing can also work with URL encoded special characters | `false` |
+| Views | `Views` | Views is the interface that wraps the Render function. See our **Template Middleware** for supported engines. | `nil` |
+| ViewsLayout | `string` | Views Layout is the global layout for all template render until override on Render function. See our **Template Middleware** for supported engines. | `""` |
+| WriteBufferSize | `int` | Per-connection buffer size for responses' writing. | `4096` |
+| WriteTimeout | `time.Duration` | The maximum duration before timing out writes of the response. The default timeout is unlimited. | `nil` |
+| XMLEncoder | `utils.XMLMarshal` | Allowing for flexibility in using another XML library for encoding. | `xml.Marshal` |
+
+## NewError
+
+NewError creates a new HTTPError instance with an optional message.
+
+```go title="Signature"
+func NewError(code int, message ...string) *Error
+```
+
+```go title="Example"
+app.Get("/", func(c *fiber.Ctx) error {
+ return fiber.NewError(782, "Custom error message")
+})
+```
+
+## IsChild
+
+IsChild determines if the current process is a result of Prefork.
+
+```go title="Signature"
+func IsChild() bool
+```
+
+```go title="Example"
+// Prefork will spawn child processes
+app := fiber.New(fiber.Config{
+ Prefork: true,
+})
+
+if !fiber.IsChild() {
+ fmt.Println("I'm the parent process")
+} else {
+ fmt.Println("I'm a child process")
+}
+
+// ...
+```
diff --git a/docs/api/log.md b/docs/api/log.md
new file mode 100644
index 0000000000..9b741b13f7
--- /dev/null
+++ b/docs/api/log.md
@@ -0,0 +1,155 @@
+---
+id: log
+title: 📃 Log
+description: Fiber's built-in log package
+sidebar_position: 6
+---
+
+We can use logs to observe program behavior, diagnose problems, or configure corresponding alarms.
+And defining a well structured log can improve search efficiency and facilitate handling of problems.
+
+Fiber provides a default way to print logs in the standard output.
+It also provides several global functions, such as `log.Info`, `log.Errorf`, `log.Warnw`, etc.
+
+## Log levels
+
+```go
+const (
+ LevelTrace Level = iota
+ LevelDebug
+ LevelInfo
+ LevelWarn
+ LevelError
+ LevelFatal
+ LevelPanic
+)
+```
+
+## Custom log
+
+Fiber provides the `AllLogger` interface for adapting the various log libraries.
+
+```go
+type CommonLogger interface {
+ Logger
+ FormatLogger
+ WithLogger
+}
+
+type AllLogger interface {
+ CommonLogger
+ ControlLogger
+ WithLogger
+}
+```
+
+## Print log
+Note: The method of calling the Fatal level will interrupt the program running after printing the log, please use it with caution.
+Directly print logs of different levels, which will be entered into messageKey, the default is msg.
+
+```go
+log.Info("Hello, World!")
+log.Debug("Are you OK?")
+log.Info("42 is the answer to life, the universe, and everything")
+log.Warn("We are under attack!")
+log.Error("Houston, we have a problem.")
+log.Fatal("So Long, and Thanks for All the Fislog.")
+log.Panic("The system is down.")
+```
+Format and print logs of different levels, all methods end with f
+
+```go
+log.Debugf("Hello %s", "boy")
+log.Infof("%d is the answer to life, the universe, and everything", 233)
+log.Warnf("We are under attack %s!", "boss")
+log.Errorf("%s, we have a problem.", "Master Shifu")
+log.Fatalf("So Long, and Thanks for All the %s.", "banana")
+```
+
+Print a message with the key and value, or `KEYVALS UNPAIRED` if the key and value are not a pair.
+
+```go
+log.Debugw("", "Hello", "boy")
+log.Infow("", "number", 233)
+log.Warnw("", "job", "boss")
+log.Errorw("", "name", "Master Shifu")
+log.Fatalw("", "fruit", "banana")
+```
+
+## Global log
+If you are in a project and just want to use a simple log function that can be printed at any time in the global, we provide a global log.
+
+```go
+import "github.com/gofiber/fiber/v2/log"
+
+log.Info("info")
+log.Warn("warn")
+```
+
+The above is using the default `log.DefaultLogger` standard output.
+You can also find an already implemented adaptation under contrib, or use your own implemented Logger and use `log.SetLogger` to set the global log logger.
+
+```go
+import (
+ "log"
+ fiberlog "github.com/gofiber/fiber/v2/log"
+)
+
+var _ log.AllLogger = (*customLogger)(nil)
+
+type customLogger struct {
+ stdlog *log.Logger
+}
+
+// ...
+// inject your custom logger
+fiberlog.SetLogger(customLogger)
+```
+
+## Set Level
+`log.SetLevel` sets the level of logs below which logs will not be output.
+The default logger is LevelTrace.
+
+Note that this method is not **concurrent-safe**.
+
+```go
+import "github.com/gofiber/fiber/v2/log"
+
+log.SetLevel(log.LevelInfo)
+```
+## Set output
+
+`log.SetOutput` sets the output destination of the logger. The default logger types the log in the console.
+
+```go
+var logger AllLogger = &defaultLogger{
+ stdlog: log.New(os.Stderr, "", log.LstdFlags|log.Lshortfile|log.Lmicroseconds),
+ depth: 4,
+}
+```
+
+Set the output destination to the file.
+
+```go
+// Output to ./test.log file
+f, err := os.OpenFile("test.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
+if err != nil {
+ return
+}
+log.SetOutput(f)
+```
+Set the output destination to the console and file.
+
+```go
+// Output to ./test.log file
+file, _ := os.OpenFile("test.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
+iw := io.MultiWriter(os.Stdout, file)
+log.SetOutput(iw)
+```
+## Bind context
+Set the context, using the following method will return a `CommonLogger` instance bound to the specified context
+```go
+commonLogger := log.WithContext(ctx)
+commonLogger.Info("info")
+```
+
diff --git a/docs/api/middleware/_category_.json b/docs/api/middleware/_category_.json
new file mode 100644
index 0000000000..133ac5147a
--- /dev/null
+++ b/docs/api/middleware/_category_.json
@@ -0,0 +1,9 @@
+{
+ "label": "🧬 Middleware",
+ "position": 7,
+ "collapsed": true,
+ "link": {
+ "type": "generated-index",
+ "description": "Middleware is a function chained in the HTTP request cycle with access to the Context which it uses to perform a specific action, for example, logging every request or enabling CORS."
+ }
+}
\ No newline at end of file
diff --git a/docs/api/middleware/adaptor.md b/docs/api/middleware/adaptor.md
new file mode 100644
index 0000000000..64df229ce2
--- /dev/null
+++ b/docs/api/middleware/adaptor.md
@@ -0,0 +1,169 @@
+---
+id: adaptor
+---
+
+# Adaptor
+
+Converter for net/http handlers to/from Fiber request handlers, special thanks to [@arsmn](https://github.com/arsmn)!
+
+## Signatures
+| Name | Signature | Description
+| :--- | :--- | :---
+| HTTPHandler | `HTTPHandler(h http.Handler) fiber.Handler` | http.Handler -> fiber.Handler
+| HTTPHandlerFunc | `HTTPHandlerFunc(h http.HandlerFunc) fiber.Handler` | http.HandlerFunc -> fiber.Handler
+| HTTPMiddleware | `HTTPHandlerFunc(mw func(http.Handler) http.Handler) fiber.Handler` | func(http.Handler) http.Handler -> fiber.Handler
+| FiberHandler | `FiberHandler(h fiber.Handler) http.Handler` | fiber.Handler -> http.Handler
+| FiberHandlerFunc | `FiberHandlerFunc(h fiber.Handler) http.HandlerFunc` | fiber.Handler -> http.HandlerFunc
+| FiberApp | `FiberApp(app *fiber.App) http.HandlerFunc` | Fiber app -> http.HandlerFunc
+| ConvertRequest | `ConvertRequest(c *fiber.Ctx, forServer bool) (*http.Request, error)` | fiber.Ctx -> http.Request
+| CopyContextToFiberContext | `CopyContextToFiberContext(context interface{}, requestContext *fasthttp.RequestCtx)` | context.Context -> fasthttp.RequestCtx
+
+## Examples
+
+### net/http to Fiber
+```go
+package main
+
+import (
+ "fmt"
+ "net/http"
+
+ "github.com/gofiber/fiber/v2"
+ "github.com/gofiber/fiber/v2/middleware/adaptor"
+)
+
+func main() {
+ // New fiber app
+ app := fiber.New()
+
+ // http.Handler -> fiber.Handler
+ app.Get("/", adaptor.HTTPHandler(handler(greet)))
+
+ // http.HandlerFunc -> fiber.Handler
+ app.Get("/func", adaptor.HTTPHandlerFunc(greet))
+
+ // Listen on port 3000
+ app.Listen(":3000")
+}
+
+func handler(f http.HandlerFunc) http.Handler {
+ return http.HandlerFunc(f)
+}
+
+func greet(w http.ResponseWriter, r *http.Request) {
+ fmt.Fprint(w, "Hello World!")
+}
+```
+
+### net/http middleware to Fiber
+```go
+package main
+
+import (
+ "log"
+ "net/http"
+
+ "github.com/gofiber/fiber/v2"
+ "github.com/gofiber/fiber/v2/middleware/adaptor"
+)
+
+func main() {
+ // New fiber app
+ app := fiber.New()
+
+ // http middleware -> fiber.Handler
+ app.Use(adaptor.HTTPMiddleware(logMiddleware))
+
+ // Listen on port 3000
+ app.Listen(":3000")
+}
+
+func logMiddleware(next http.Handler) http.Handler {
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ log.Println("log middleware")
+ next.ServeHTTP(w, r)
+ })
+}
+```
+
+### Fiber Handler to net/http
+```go
+package main
+
+import (
+ "net/http"
+
+ "github.com/gofiber/fiber/v2"
+ "github.com/gofiber/fiber/v2/middleware/adaptor"
+)
+
+func main() {
+ // fiber.Handler -> http.Handler
+ http.Handle("/", adaptor.FiberHandler(greet))
+
+ // fiber.Handler -> http.HandlerFunc
+ http.HandleFunc("/func", adaptor.FiberHandlerFunc(greet))
+
+ // Listen on port 3000
+ http.ListenAndServe(":3000", nil)
+}
+
+func greet(c *fiber.Ctx) error {
+ return c.SendString("Hello World!")
+}
+```
+
+### Fiber App to net/http
+```go
+package main
+
+import (
+ "net/http"
+
+ "github.com/gofiber/fiber/v2"
+ "github.com/gofiber/fiber/v2/middleware/adaptor"
+)
+
+func main() {
+ app := fiber.New()
+
+ app.Get("/greet", greet)
+
+ // Listen on port 3000
+ http.ListenAndServe(":3000", adaptor.FiberApp(app))
+}
+
+func greet(c *fiber.Ctx) error {
+ return c.SendString("Hello World!")
+}
+```
+
+### Fiber Context to (net/http).Request
+```go
+package main
+
+import (
+ "net/http"
+
+ "github.com/gofiber/fiber/v2"
+ "github.com/gofiber/fiber/v2/middleware/adaptor"
+)
+
+func main() {
+ app := fiber.New()
+
+ app.Get("/greet", greetWithHTTPReq)
+
+ // Listen on port 3000
+ http.ListenAndServe(":3000", adaptor.FiberApp(app))
+}
+
+func greetWithHTTPReq(c *fiber.Ctx) error {
+ httpReq, err := adaptor.ConvertRequest(c, false)
+ if err != nil {
+ return err
+ }
+
+ return c.SendString("Request URL: " + httpReq.URL.String())
+}
+```
diff --git a/docs/api/middleware/basicauth.md b/docs/api/middleware/basicauth.md
new file mode 100644
index 0000000000..0e90eafed0
--- /dev/null
+++ b/docs/api/middleware/basicauth.md
@@ -0,0 +1,85 @@
+---
+id: basicauth
+---
+
+# BasicAuth
+
+Basic Authentication middleware for [Fiber](https://github.com/gofiber/fiber) that provides an HTTP basic authentication. It calls the next handler for valid credentials and [401 Unauthorized](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/401) or a custom response for missing or invalid credentials.
+
+## Signatures
+
+```go
+func New(config Config) fiber.Handler
+```
+
+## Examples
+
+Import the middleware package that is part of the Fiber web framework
+
+```go
+import (
+ "github.com/gofiber/fiber/v2"
+ "github.com/gofiber/fiber/v2/middleware/basicauth"
+)
+```
+
+After you initiate your Fiber app, you can use the following possibilities:
+
+```go
+// Provide a minimal config
+app.Use(basicauth.New(basicauth.Config{
+ Users: map[string]string{
+ "john": "doe",
+ "admin": "123456",
+ },
+}))
+
+// Or extend your config for customization
+app.Use(basicauth.New(basicauth.Config{
+ Users: map[string]string{
+ "john": "doe",
+ "admin": "123456",
+ },
+ Realm: "Forbidden",
+ Authorizer: func(user, pass string) bool {
+ if user == "john" && pass == "doe" {
+ return true
+ }
+ if user == "admin" && pass == "123456" {
+ return true
+ }
+ return false
+ },
+ Unauthorized: func(c *fiber.Ctx) error {
+ return c.SendFile("./unauthorized.html")
+ },
+ ContextUsername: "_user",
+ ContextPassword: "_pass",
+}))
+```
+
+## Config
+
+| Property | Type | Description | Default |
+|:----------------|:----------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------------------|
+| Next | `func(*fiber.Ctx) bool` | Next defines a function to skip this middleware when returned true. | `nil` |
+| Users | `map[string]string` | Users defines the allowed credentials. | `map[string]string{}` |
+| Realm | `string` | Realm is a string to define the realm attribute of BasicAuth. The realm identifies the system to authenticate against and can be used by clients to save credentials. | `"Restricted"` |
+| Authorizer | `func(string, string) bool` | Authorizer defines a function to check the credentials. It will be called with a username and password and is expected to return true or false to indicate approval. | `nil` |
+| Unauthorized | `fiber.Handler` | Unauthorized defines the response body for unauthorized responses. | `nil` |
+| ContextUsername | `string` | ContextUsername is the key to store the username in Locals. | `"username"` |
+| ContextPassword | `string` | ContextPassword is the key to store the password in Locals. | `"password"` |
+
+## Default Config
+
+```go
+var ConfigDefault = Config{
+ Next: nil,
+ Users: map[string]string{},
+ Realm: "Restricted",
+ Authorizer: nil,
+ Unauthorized: nil,
+ ContextUsername: "username",
+ ContextPassword: "password",
+}
+```
diff --git a/docs/api/middleware/cache.md b/docs/api/middleware/cache.md
new file mode 100644
index 0000000000..3a87306d3b
--- /dev/null
+++ b/docs/api/middleware/cache.md
@@ -0,0 +1,99 @@
+---
+id: cache
+---
+
+# Cache
+
+Cache middleware for [Fiber](https://github.com/gofiber/fiber) designed to intercept responses and cache them. This middleware will cache the `Body`, `Content-Type` and `StatusCode` using the `c.Path()` as unique identifier. Special thanks to [@codemicro](https://github.com/codemicro/fiber-cache) for creating this middleware for Fiber core!
+
+Request Directives
+`Cache-Control: no-cache` will return the up-to-date response but still caches it. You will always get a `miss` cache status.
+`Cache-Control: no-store` will refrain from caching. You will always get the up-to-date response.
+
+## Signatures
+
+```go
+func New(config ...Config) fiber.Handler
+```
+
+## Examples
+
+Import the middleware package that is part of the Fiber web framework
+
+```go
+import (
+ "github.com/gofiber/fiber/v2"
+ "github.com/gofiber/fiber/v2/middleware/cache"
+)
+```
+
+After you initiate your Fiber app, you can use the following possibilities:
+
+```go
+// Initialize default config
+app.Use(cache.New())
+
+// Or extend your config for customization
+app.Use(cache.New(cache.Config{
+ Next: func(c *fiber.Ctx) bool {
+ return c.Query("refresh") == "true"
+ },
+ Expiration: 30 * time.Minute,
+ CacheControl: true,
+}))
+```
+
+Or you can custom key and expire time like this:
+
+```go
+app.Use(cache.New(cache.Config{
+ ExpirationGenerator: func(c *fiber.Ctx, cfg *cache.Config) time.Duration {
+ newCacheTime, _ := strconv.Atoi(c.GetRespHeader("Cache-Time", "600"))
+ return time.Second * time.Duration(newCacheTime)
+ },
+ KeyGenerator: func(c *fiber.Ctx) string {
+ return utils.CopyString(c.Path())
+ },
+}))
+
+app.Get("/", func(c *fiber.Ctx) error {
+ c.Response().Header.Add("Cache-Time", "6000")
+ return c.SendString("hi")
+})
+```
+
+## Config
+
+| Property | Type | Description | Default |
+|:---------------------|:------------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------|:------------------------------------------------------------------|
+| Next | `func(*fiber.Ctx) bool` | Next defines a function to skip this middleware when returned true. | `nil` |
+| Expiration | `time.Duration` | Expiration is the time that a cached response will live. | `1 * time.Minute` |
+| CacheHeader | `string` | CacheHeader is the header on the response header that indicates the cache status, with the possible return values "hit," "miss," or "unreachable." | `X-Cache` |
+| CacheControl | `bool` | CacheControl enables client-side caching if set to true. | `false` |
+| KeyGenerator | `func(*fiber.Ctx) string` | Key allows you to generate custom keys. | `func(c *fiber.Ctx) string { return utils.CopyString(c.Path()) }` |
+| ExpirationGenerator | `func(*fiber.Ctx, *cache.Config) time.Duration` | ExpirationGenerator allows you to generate custom expiration keys based on the request. | `nil` |
+| Storage | `fiber.Storage` | Store is used to store the state of the middleware. | In-memory store |
+| Store (Deprecated) | `fiber.Storage` | Deprecated: Use Storage instead. | In-memory store |
+| Key (Deprecated) | `func(*fiber.Ctx) string` | Deprecated: Use KeyGenerator instead. | `nil` |
+| StoreResponseHeaders | `bool` | StoreResponseHeaders allows you to store additional headers generated by next middlewares & handler. | `false` |
+| MaxBytes | `uint` | MaxBytes is the maximum number of bytes of response bodies simultaneously stored in cache. | `0` (No limit) |
+| Methods | `[]string` | Methods specifies the HTTP methods to cache. | `[]string{fiber.MethodGet, fiber.MethodHead}` |
+
+## Default Config
+
+```go
+var ConfigDefault = Config{
+ Next: nil,
+ Expiration: 1 * time.Minute,
+ CacheHeader: "X-Cache",
+ CacheControl: false,
+ KeyGenerator: func(c *fiber.Ctx) string {
+ return utils.CopyString(c.Path())
+ },
+ ExpirationGenerator: nil,
+ StoreResponseHeaders: false,
+ Storage: nil,
+ MaxBytes: 0,
+ Methods: []string{fiber.MethodGet, fiber.MethodHead},
+}
+```
diff --git a/docs/api/middleware/compress.md b/docs/api/middleware/compress.md
new file mode 100644
index 0000000000..f284f5e92c
--- /dev/null
+++ b/docs/api/middleware/compress.md
@@ -0,0 +1,81 @@
+---
+id: compress
+---
+
+# Compress
+
+Compression middleware for [Fiber](https://github.com/gofiber/fiber) that will compress the response using `gzip`, `deflate` and `brotli` compression depending on the [Accept-Encoding](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding) header.
+
+## Signatures
+
+```go
+func New(config ...Config) fiber.Handler
+```
+
+## Examples
+
+Import the middleware package that is part of the Fiber web framework
+
+```go
+import (
+ "github.com/gofiber/fiber/v2"
+ "github.com/gofiber/fiber/v2/middleware/compress"
+)
+```
+
+After you initiate your Fiber app, you can use the following possibilities:
+
+```go
+// Initialize default config
+app.Use(compress.New())
+
+// Or extend your config for customization
+app.Use(compress.New(compress.Config{
+ Level: compress.LevelBestSpeed, // 1
+}))
+
+// Skip middleware for specific routes
+app.Use(compress.New(compress.Config{
+ Next: func(c *fiber.Ctx) bool {
+ return c.Path() == "/dont_compress"
+ },
+ Level: compress.LevelBestSpeed, // 1
+}))
+```
+
+## Config
+
+### Config
+
+| Property | Type | Description | Default |
+|:---------|:------------------------|:--------------------------------------------------------------------|:-------------------|
+| Next | `func(*fiber.Ctx) bool` | Next defines a function to skip this middleware when returned true. | `nil` |
+| Level | `Level` | Level determines the compression algorithm. | `LevelDefault (0)` |
+
+Possible values for the "Level" field are:
+
+- `LevelDisabled (-1)`: Compression is disabled.
+- `LevelDefault (0)`: Default compression level.
+- `LevelBestSpeed (1)`: Best compression speed.
+- `LevelBestCompression (2)`: Best compression.
+
+## Default Config
+
+```go
+var ConfigDefault = Config{
+ Next: nil,
+ Level: LevelDefault,
+}
+```
+
+## Constants
+
+```go
+// Compression levels
+const (
+ LevelDisabled = -1
+ LevelDefault = 0
+ LevelBestSpeed = 1
+ LevelBestCompression = 2
+)
+```
diff --git a/docs/api/middleware/cors.md b/docs/api/middleware/cors.md
new file mode 100644
index 0000000000..af9b8c5f2b
--- /dev/null
+++ b/docs/api/middleware/cors.md
@@ -0,0 +1,88 @@
+---
+id: cors
+---
+
+# CORS
+
+CORS middleware for [Fiber](https://github.com/gofiber/fiber) that can be used to enable [Cross-Origin Resource Sharing](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) with various options.
+
+## Signatures
+
+```go
+func New(config ...Config) fiber.Handler
+```
+
+## Examples
+
+Import the middleware package that is part of the Fiber web framework
+
+```go
+import (
+ "github.com/gofiber/fiber/v2"
+ "github.com/gofiber/fiber/v2/middleware/cors"
+)
+```
+
+After you initiate your Fiber app, you can use the following possibilities:
+
+```go
+// Initialize default config
+app.Use(cors.New())
+
+// Or extend your config for customization
+app.Use(cors.New(cors.Config{
+ AllowOrigins: "https://gofiber.io, https://gofiber.net",
+ AllowHeaders: "Origin, Content-Type, Accept",
+}))
+```
+
+Using the `AllowOriginsFunc` function. In this example any origin will be allowed via CORS.
+
+For example, if a browser running on `http://localhost:3000` sends a request, this will be accepted and the `access-control-allow-origin` response header will be set to `http://localhost:3000`.
+
+**Note: Using this feature is discouraged in production and it's best practice to explicitly set CORS origins via `AllowOrigins`.**
+
+```go
+app.Use(cors.New())
+
+app.Use(cors.New(cors.Config{
+ AllowOriginsFunc: func(origin string) bool {
+ return os.Getenv("ENVIRONMENT") == "development"
+ },
+}))
+```
+
+## 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` |
+
+## Default Config
+
+```go
+var ConfigDefault = Config{
+ Next: nil,
+ AllowOriginsFunc: nil,
+ AllowOrigins: "*",
+ AllowMethods: strings.Join([]string{
+ fiber.MethodGet,
+ fiber.MethodPost,
+ fiber.MethodHead,
+ fiber.MethodPut,
+ fiber.MethodDelete,
+ fiber.MethodPatch,
+ }, ","),
+ AllowHeaders: "",
+ AllowCredentials: false,
+ ExposeHeaders: "",
+ MaxAge: 0,
+}
+```
diff --git a/docs/api/middleware/csrf.md b/docs/api/middleware/csrf.md
new file mode 100644
index 0000000000..dbbf6007d9
--- /dev/null
+++ b/docs/api/middleware/csrf.md
@@ -0,0 +1,111 @@
+---
+id: csrf
+---
+
+# CSRF
+
+CSRF middleware for [Fiber](https://github.com/gofiber/fiber) that provides [Cross-site request forgery](https://en.wikipedia.org/wiki/Cross-site_request_forgery) protection by passing a csrf token via cookies. This cookie value will be used to compare against the client csrf token on requests, other than those defined as "safe" by RFC7231 \(GET, HEAD, OPTIONS, or TRACE\). When the csrf token is invalid, this middleware will return the `fiber.ErrForbidden` error.
+
+CSRF Tokens are generated on GET requests. You can retrieve the CSRF token with `c.Locals(contextKey)`, where `contextKey` is the string you set in the config (see Custom Config below).
+
+When no `csrf_` cookie is set, or the token has expired, a new token will be generated and `csrf_` cookie set.
+
+:::note
+This middleware uses our [Storage](https://github.com/gofiber/storage) package to support various databases through a single interface. The default configuration for this middleware saves data to memory, see the examples below for other databases.
+:::
+
+## Signatures
+
+```go
+func New(config ...Config) fiber.Handler
+```
+
+## Examples
+
+Import the middleware package that is part of the Fiber web framework
+
+```go
+import (
+ "github.com/gofiber/fiber/v2"
+ "github.com/gofiber/fiber/v2/middleware/csrf"
+)
+```
+
+After you initiate your Fiber app, you can use the following possibilities:
+
+```go
+// Initialize default config
+app.Use(csrf.New())
+
+// Or extend your config for customization
+app.Use(csrf.New(csrf.Config{
+ KeyLookup: "header:X-Csrf-Token",
+ CookieName: "csrf_",
+ CookieSameSite: "Lax",
+ Expiration: 1 * time.Hour,
+ KeyGenerator: utils.UUID,
+ Extractor: func(c *fiber.Ctx) (string, error) { ... },
+}))
+```
+
+:::note
+KeyLookup will be ignored if Extractor is explicitly set.
+:::
+
+## Config
+
+### Config
+
+| Property | Type | Description | Default |
+|:------------------|:-----------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------------------------|
+| Next | `func(*fiber.Ctx) bool` | Next defines a function to skip this middleware when returned true. | `nil` |
+| KeyLookup | `string` | KeyLookup is a string in the form of "`