mirror of https://github.com/gofiber/fiber.git
📝 docs: automated synchronization with `gofiber/docs` (#2344)
Automated Synchronization with gofiber/docs repopull/2348/head
parent
af69fa5a56
commit
b3643198f8
|
@ -0,0 +1,38 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Some env variables
|
||||
BRANCH="master"
|
||||
MAJOR_VERSION="v2"
|
||||
REPO_URL="github.com/gofiber/docs.git"
|
||||
AUTHOR_EMAIL="github-actions[bot]@users.noreply.github.com"
|
||||
AUTHOR_USERNAME="github-actions[bot]"
|
||||
|
||||
# Set commit author
|
||||
git config --global user.email "${AUTHOR_EMAIL}"
|
||||
git config --global user.name "${AUTHOR_USERNAME}"
|
||||
|
||||
if [[ $EVENT == "push" ]]; then
|
||||
latest_commit=$(git rev-parse --short HEAD)
|
||||
log_output=$(git log --oneline ${BRANCH} HEAD~1..HEAD --name-status -- docs/)
|
||||
|
||||
if [[ $log_output != "" ]]; then
|
||||
git clone https://${TOKEN}@${REPO_URL} fiber-docs
|
||||
cp -a docs/* fiber-docs/docs
|
||||
|
||||
# Push changes for next docs
|
||||
cd fiber-docs/ || return
|
||||
git add .
|
||||
git commit -m "Add docs from https://github.com/gofiber/fiber/commit/${latest_commit}"
|
||||
git push https://${TOKEN}@${REPO_URL}
|
||||
fi
|
||||
elif [[ $EVENT == "release" ]]; then
|
||||
latest_tag=$(git describe --tags --abbrev=0)
|
||||
|
||||
# Push changes for stable docs
|
||||
git clone https://${TOKEN}@${REPO_URL} fiber-docs
|
||||
cd fiber-docs/ || return
|
||||
cp -a docs/* versioned_docs/version-${MAJOR_VERSION}.x
|
||||
git add .
|
||||
git commit -m "Sync docs for ${latest_tag} release"
|
||||
git push https://${TOKEN}@${REPO_URL}
|
||||
fi
|
|
@ -0,0 +1,25 @@
|
|||
name: 'Sync docs'
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- main
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
sync-docs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
fetch-depth: 2
|
||||
|
||||
- name: Sync docs
|
||||
run: ./.github/scripts/sync_docs.sh
|
||||
env:
|
||||
EVENT: ${{ github.event_name }}
|
||||
TOKEN: ${{ secrets.TOKEN }}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"label": "API",
|
||||
"position": 2,
|
||||
"link": {
|
||||
"type": "generated-index",
|
||||
"description": "API documentation for Fiber."
|
||||
}
|
||||
}
|
|
@ -0,0 +1,608 @@
|
|||
---
|
||||
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
|
||||
|
||||
<RoutingHandler />
|
||||
|
||||
## 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 := New()
|
||||
one := New()
|
||||
two := New()
|
||||
three := 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.
|
||||
|
||||
```go
|
||||
func (app *App) Shutdown() error
|
||||
func (app *App) ShutdownWithTimeout(timeout time.Duration) 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,
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
## 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,
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
## 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
|
||||
```
|
|
@ -0,0 +1,567 @@
|
|||
---
|
||||
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
|
||||
```
|
||||
|
||||
## ✨ 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"
|
||||
})
|
||||
// ...
|
||||
```
|
|
@ -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"
|
||||
)
|
||||
```
|
File diff suppressed because it is too large
Load Diff
|
@ -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` | You can define custom color scheme. They'll be used for startup message, route list and some middlewares. | `DefaultColors` |
|
||||
| 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.<br /><br />**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. <br /><br />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. <br /> 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)<br /><br />**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. <br /> <br /> 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")
|
||||
}
|
||||
|
||||
// ...
|
||||
```
|
|
@ -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."
|
||||
}
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
---
|
||||
id: basicauth
|
||||
title: 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
|
||||
|
||||
```go
|
||||
// Config defines the config for middleware.
|
||||
type Config struct {
|
||||
// Next defines a function to skip this middleware when returned true.
|
||||
//
|
||||
// Optional. Default: nil
|
||||
Next func(c *fiber.Ctx) bool
|
||||
|
||||
// Users defines the allowed credentials
|
||||
//
|
||||
// Required. Default: map[string]string{}
|
||||
Users map[string]string
|
||||
|
||||
// Realm is a string to define realm attribute of BasicAuth.
|
||||
// the realm identifies the system to authenticate against
|
||||
// and can be used by clients to save credentials
|
||||
//
|
||||
// Optional. Default: "Restricted".
|
||||
Realm string
|
||||
|
||||
// Authorizer defines a function you can pass
|
||||
// to check the credentials however you want.
|
||||
// It will be called with a username and password
|
||||
// and is expected to return true or false to indicate
|
||||
// that the credentials were approved or not.
|
||||
//
|
||||
// Optional. Default: nil.
|
||||
Authorizer func(string, string) bool
|
||||
|
||||
// Unauthorized defines the response body for unauthorized responses.
|
||||
// By default it will return with a 401 Unauthorized and the correct WWW-Auth header
|
||||
//
|
||||
// Optional. Default: nil
|
||||
Unauthorized fiber.Handler
|
||||
|
||||
// ContextUser is the key to store the username in Locals
|
||||
//
|
||||
// Optional. Default: "username"
|
||||
ContextUsername string
|
||||
|
||||
// ContextPass is the key to store the password in Locals
|
||||
//
|
||||
// Optional. Default: "password"
|
||||
ContextPassword string
|
||||
}
|
||||
```
|
||||
|
||||
## Default Config
|
||||
|
||||
```go
|
||||
var ConfigDefault = Config{
|
||||
Next: nil,
|
||||
Users: map[string]string{},
|
||||
Realm: "Restricted",
|
||||
Authorizer: nil,
|
||||
Unauthorized: nil,
|
||||
ContextUsername: "username",
|
||||
ContextPassword: "password",
|
||||
}
|
||||
```
|
|
@ -0,0 +1,138 @@
|
|||
---
|
||||
id: cache
|
||||
title: 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<br />
|
||||
`Cache-Control: no-cache` will return the up-to-date response but still caches it. You will always get a `miss` cache status.<br />
|
||||
`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(New(Config{
|
||||
ExpirationGenerator: func(c *fiber.Ctx, cfg *Config) time.Duration {
|
||||
newCacheTime, _ := strconv.Atoi(c.GetRespHeader("Cache-Time", "600"))
|
||||
return time.Second * time.Duration(newCacheTime)
|
||||
},
|
||||
KeyGenerator: func(c *fiber.Ctx) string {
|
||||
return c.Path()
|
||||
}
|
||||
}))
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) error {
|
||||
c.Response().Header.Add("Cache-Time", "6000")
|
||||
return c.SendString("hi")
|
||||
})
|
||||
```
|
||||
|
||||
## Config
|
||||
|
||||
```go
|
||||
// Config defines the config for middleware.
|
||||
type Config struct {
|
||||
// Next defines a function to skip this middleware when returned true.
|
||||
//
|
||||
// Optional. Default: nil
|
||||
Next func(c *fiber.Ctx) bool
|
||||
|
||||
// Expiration is the time that an cached response will live
|
||||
//
|
||||
// Optional. Default: 1 * time.Minute
|
||||
Expiration time.Duration
|
||||
|
||||
// CacheControl enables client side caching if set to true
|
||||
//
|
||||
// Optional. Default: false
|
||||
CacheControl bool
|
||||
|
||||
// Key allows you to generate custom keys, by default c.Path() is used
|
||||
//
|
||||
// Default: func(c *fiber.Ctx) string {
|
||||
// return utils.CopyString(c.Path())
|
||||
// }
|
||||
KeyGenerator func(*fiber.Ctx) string
|
||||
|
||||
// allows you to generate custom Expiration Key By Key, default is Expiration (Optional)
|
||||
//
|
||||
// Default: nil
|
||||
ExpirationGenerator func(*fiber.Ctx, *Config) time.Duration
|
||||
|
||||
// Store is used to store the state of the middleware
|
||||
//
|
||||
// Default: an in memory store for this process only
|
||||
Storage fiber.Storage
|
||||
|
||||
// allows you to store additional headers generated by next middlewares & handler
|
||||
//
|
||||
// Default: false
|
||||
StoreResponseHeaders bool
|
||||
|
||||
// Max number of bytes of response bodies simultaneously stored in cache. When limit is reached,
|
||||
// entries with the nearest expiration are deleted to make room for new.
|
||||
// 0 means no limit
|
||||
//
|
||||
// Default: 0
|
||||
MaxBytes uint
|
||||
|
||||
// You can specify HTTP methods to cache.
|
||||
// The middleware just caches the routes of its methods in this slice.
|
||||
//
|
||||
// Default: []string{fiber.MethodGet, fiber.MethodHead}
|
||||
Methods []string
|
||||
}
|
||||
```
|
||||
|
||||
## Default Config
|
||||
|
||||
```go
|
||||
// ConfigDefault is the default config
|
||||
var ConfigDefault = Config{
|
||||
Next: nil,
|
||||
Expiration: 1 * time.Minute,
|
||||
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},
|
||||
}
|
||||
```
|
|
@ -0,0 +1,85 @@
|
|||
---
|
||||
id: compress
|
||||
title: 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
|
||||
// Default middleware config
|
||||
app.Use(compress.New())
|
||||
|
||||
// Provide a custom compression level
|
||||
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
|
||||
|
||||
```go
|
||||
// Config defines the config for middleware.
|
||||
type Config struct {
|
||||
// Next defines a function to skip this middleware when returned true.
|
||||
//
|
||||
// Optional. Default: nil
|
||||
Next func(c *fiber.Ctx) bool
|
||||
|
||||
// CompressLevel determines the compression algoritm
|
||||
//
|
||||
// Optional. Default: LevelDefault
|
||||
// LevelDisabled: -1
|
||||
// LevelDefault: 0
|
||||
// LevelBestSpeed: 1
|
||||
// LevelBestCompression: 2
|
||||
Level int
|
||||
}
|
||||
```
|
||||
|
||||
## Default Config
|
||||
|
||||
```go
|
||||
var ConfigDefault = Config{
|
||||
Next: nil,
|
||||
Level: LevelDefault,
|
||||
}
|
||||
```
|
||||
|
||||
## Constants
|
||||
|
||||
```go
|
||||
// Compression levels
|
||||
const (
|
||||
LevelDisabled = -1
|
||||
LevelDefault = 0
|
||||
LevelBestSpeed = 1
|
||||
LevelBestCompression = 2
|
||||
)
|
||||
```
|
|
@ -0,0 +1,99 @@
|
|||
---
|
||||
id: cors
|
||||
title: 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
|
||||
// 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",
|
||||
}))
|
||||
```
|
||||
|
||||
## Config
|
||||
|
||||
```go
|
||||
// Config defines the config for middleware.
|
||||
type Config struct {
|
||||
// Next defines a function to skip this middleware when returned true.
|
||||
//
|
||||
// Optional. Default: nil
|
||||
Next func(c *fiber.Ctx) bool
|
||||
|
||||
// AllowOrigin defines a list of origins that may access the resource.
|
||||
//
|
||||
// Optional. Default value "*"
|
||||
AllowOrigins string
|
||||
|
||||
// AllowMethods defines a list of methods allowed when accessing the resource.
|
||||
// This is used in response to a preflight request.
|
||||
//
|
||||
// Optional. Default value "GET,POST,HEAD,PUT,DELETE,PATCH"
|
||||
AllowMethods 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.
|
||||
//
|
||||
// Optional. Default value "".
|
||||
AllowHeaders string
|
||||
|
||||
// AllowCredentials indicates whether or not the response to the request
|
||||
// can be exposed when the credentials flag is true. When used as part of
|
||||
// a response to a preflight request, this indicates whether or not the
|
||||
// actual request can be made using credentials.
|
||||
//
|
||||
// Optional. Default value false.
|
||||
AllowCredentials bool
|
||||
|
||||
// ExposeHeaders defines a whitelist headers that clients are allowed to
|
||||
// access.
|
||||
//
|
||||
// Optional. Default value "".
|
||||
ExposeHeaders string
|
||||
|
||||
// MaxAge indicates how long (in seconds) the results of a preflight request
|
||||
// can be cached.
|
||||
//
|
||||
// Optional. Default value 0.
|
||||
MaxAge int
|
||||
}
|
||||
```
|
||||
|
||||
## Default Config
|
||||
|
||||
```go
|
||||
var ConfigDefault = Config{
|
||||
Next: nil,
|
||||
AllowOrigins: "*",
|
||||
AllowMethods: "GET,POST,HEAD,PUT,DELETE,PATCH",
|
||||
AllowHeaders: "",
|
||||
AllowCredentials: false,
|
||||
ExposeHeaders: "",
|
||||
MaxAge: 0,
|
||||
}
|
||||
```
|
|
@ -0,0 +1,136 @@
|
|||
---
|
||||
id: csrf
|
||||
title: 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. When no `_csrf` cookie is set, or the token has expired, a new token will be generated and `_csrf` cookie set.
|
||||
|
||||
## 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: "Strict",
|
||||
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
|
||||
|
||||
```go
|
||||
// Config defines the config for middleware.
|
||||
type Config struct {
|
||||
// Next defines a function to skip this middleware when returned true.
|
||||
//
|
||||
// Optional. Default: nil
|
||||
Next func(c *fiber.Ctx) bool
|
||||
|
||||
// KeyLookup is a string in the form of "<source>:<key>" that is used
|
||||
// to create an Extractor that extracts the token from the request.
|
||||
// Possible values:
|
||||
// - "header:<name>"
|
||||
// - "query:<name>"
|
||||
// - "param:<name>"
|
||||
// - "form:<name>"
|
||||
// - "cookie:<name>"
|
||||
//
|
||||
// Ignored if an Extractor is explicitly set.
|
||||
//
|
||||
// Optional. Default: "header:X-CSRF-Token"
|
||||
KeyLookup string
|
||||
|
||||
// Name of the session cookie. This cookie will store session key.
|
||||
// Optional. Default value "_csrf".
|
||||
CookieName string
|
||||
|
||||
// Domain of the CSRF cookie.
|
||||
// Optional. Default value "".
|
||||
CookieDomain string
|
||||
|
||||
// Path of the CSRF cookie.
|
||||
// Optional. Default value "".
|
||||
CookiePath string
|
||||
|
||||
// Indicates if CSRF cookie is secure.
|
||||
// Optional. Default value false.
|
||||
CookieSecure bool
|
||||
|
||||
// Indicates if CSRF cookie is HTTP only.
|
||||
// Optional. Default value false.
|
||||
CookieHTTPOnly bool
|
||||
|
||||
// Indicates if CSRF cookie is requested by SameSite.
|
||||
// Optional. Default value "Lax".
|
||||
CookieSameSite string
|
||||
|
||||
// Decides whether cookie should last for only the browser sesison.
|
||||
// Ignores Expiration if set to true
|
||||
CookieSessionOnly bool
|
||||
|
||||
// Expiration is the duration before csrf token will expire
|
||||
//
|
||||
// Optional. Default: 1 * time.Hour
|
||||
Expiration time.Duration
|
||||
|
||||
// Store is used to store the state of the middleware
|
||||
//
|
||||
// Optional. Default: memory.New()
|
||||
Storage fiber.Storage
|
||||
|
||||
// Context key to store generated CSRF token into context.
|
||||
// If left empty, token will not be stored in context.
|
||||
//
|
||||
// Optional. Default: ""
|
||||
ContextKey string
|
||||
|
||||
// KeyGenerator creates a new CSRF token
|
||||
//
|
||||
// Optional. Default: utils.UUID
|
||||
KeyGenerator func() string
|
||||
|
||||
// Extractor returns the csrf token
|
||||
//
|
||||
// If set this will be used in place of an Extractor based on KeyLookup.
|
||||
//
|
||||
// Optional. Default will create an Extractor based on KeyLookup.
|
||||
Extractor func(c *fiber.Ctx) (string, error)
|
||||
}
|
||||
```
|
||||
|
||||
## Default Config
|
||||
|
||||
```go
|
||||
var ConfigDefault = Config{
|
||||
KeyLookup: "header:X-Csrf-Token",
|
||||
CookieName: "csrf_",
|
||||
CookieSameSite: "Lax",
|
||||
Expiration: 1 * time.Hour,
|
||||
KeyGenerator: utils.UUID,
|
||||
}
|
||||
```
|
|
@ -0,0 +1,93 @@
|
|||
---
|
||||
id: earlydata
|
||||
title: EarlyData
|
||||
---
|
||||
|
||||
The Early Data middleware for [Fiber](https://github.com/gofiber/fiber) adds support for TLS 1.3's early data ("0-RTT") feature.
|
||||
Citing [RFC 8446](https://datatracker.ietf.org/doc/html/rfc8446#section-2-3), when a client and server share a PSK, TLS 1.3 allows clients to send data on the first flight ("early data") to speed up the request, effectively reducing the regular 1-RTT request to a 0-RTT request.
|
||||
|
||||
Make sure to enable fiber's `EnableTrustedProxyCheck` config option before using this middleware in order to not trust bogus HTTP request headers of the client.
|
||||
|
||||
Also be aware that enabling support for early data in your reverse proxy (e.g. nginx, as done with a simple `ssl_early_data on;`) makes requests replayable. Refer to the following documents before continuing:
|
||||
|
||||
- https://datatracker.ietf.org/doc/html/rfc8446#section-8
|
||||
- https://blog.trailofbits.com/2019/03/25/what-application-developers-need-to-know-about-tls-early-data-0rtt/
|
||||
|
||||
By default, this middleware allows early data requests on safe HTTP request methods only and rejects the request otherwise, i.e. aborts the request before executing your handler. This behavior can be controlled by the `AllowEarlyData` config option.
|
||||
Safe HTTP methods — `GET`, `HEAD`, `OPTIONS` and `TRACE` — should not modify a state on the server.
|
||||
|
||||
## Signatures
|
||||
|
||||
```go
|
||||
func New(config ...Config) fiber.Handler
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
First import the middleware from Fiber,
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/middleware/earlydata"
|
||||
)
|
||||
```
|
||||
|
||||
Then create a Fiber app with `app := fiber.New()`.
|
||||
|
||||
### Default Config
|
||||
|
||||
```go
|
||||
app.Use(earlydata.New())
|
||||
```
|
||||
|
||||
### Custom Config
|
||||
|
||||
```go
|
||||
app.Use(earlydata.New(earlydata.Config{
|
||||
Error: fiber.ErrTooEarly,
|
||||
// ...
|
||||
}))
|
||||
```
|
||||
|
||||
### Config
|
||||
|
||||
```go
|
||||
type Config struct {
|
||||
// Next defines a function to skip this middleware when returned true.
|
||||
//
|
||||
// Optional. Default: nil
|
||||
Next func(c *fiber.Ctx) bool
|
||||
|
||||
// IsEarlyData returns whether the request is an early-data request.
|
||||
//
|
||||
// Optional. Default: a function which checks if the "Early-Data" request header equals "1".
|
||||
IsEarlyData func(c *fiber.Ctx) bool
|
||||
|
||||
// AllowEarlyData returns whether the early-data request should be allowed or rejected.
|
||||
//
|
||||
// Optional. Default: a function which rejects the request on unsafe and allows the request on safe HTTP request methods.
|
||||
AllowEarlyData func(c *fiber.Ctx) bool
|
||||
|
||||
// Error is returned in case an early-data request is rejected.
|
||||
//
|
||||
// Optional. Default: fiber.ErrTooEarly.
|
||||
Error error
|
||||
}
|
||||
```
|
||||
|
||||
### Default Config
|
||||
|
||||
```go
|
||||
var ConfigDefault = Config{
|
||||
IsEarlyData: func(c *fiber.Ctx) bool {
|
||||
return c.Get("Early-Data") == "1"
|
||||
},
|
||||
|
||||
AllowEarlyData: func(c *fiber.Ctx) bool {
|
||||
return fiber.IsMethodSafe(c.Method())
|
||||
},
|
||||
|
||||
Error: fiber.ErrTooEarly,
|
||||
}
|
||||
```
|
|
@ -0,0 +1,108 @@
|
|||
---
|
||||
id: encryptcookie
|
||||
title: Encrypt Cookie
|
||||
---
|
||||
|
||||
Encrypt middleware for [Fiber](https://github.com/gofiber/fiber) which encrypts cookie values. Note: this middleware does not encrypt cookie names.
|
||||
|
||||
## Signatures
|
||||
|
||||
```go
|
||||
// Intitializes the middleware
|
||||
func New(config ...Config) fiber.Handler
|
||||
|
||||
// Returns a random 32 character long string
|
||||
func GenerateKey() string
|
||||
```
|
||||
|
||||
## 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/encryptcookie"
|
||||
)
|
||||
```
|
||||
|
||||
After you initiate your Fiber app, you can use the following possibilities:
|
||||
|
||||
```go
|
||||
// Default middleware config
|
||||
app.Use(encryptcookie.New(encryptcookie.Config{
|
||||
Key: "secret-thirty-2-character-string",
|
||||
}))
|
||||
|
||||
// Get / reading out the encrypted cookie
|
||||
app.Get("/", func(c *fiber.Ctx) error {
|
||||
return c.SendString("value=" + c.Cookies("test"))
|
||||
})
|
||||
|
||||
// Post / create the encrypted cookie
|
||||
app.Post("/", func(c *fiber.Ctx) error {
|
||||
c.Cookie(&fiber.Cookie{
|
||||
Name: "test",
|
||||
Value: "SomeThing",
|
||||
})
|
||||
return nil
|
||||
})
|
||||
```
|
||||
|
||||
## Config
|
||||
|
||||
```go
|
||||
type Config struct {
|
||||
// Next defines a function to skip this middleware when returned true.
|
||||
//
|
||||
// Optional. Default: nil
|
||||
Next func(c *fiber.Ctx) bool
|
||||
|
||||
// Array of cookie keys that should not be encrypted.
|
||||
//
|
||||
// Optional. Default: ["csrf_"]
|
||||
Except []string
|
||||
|
||||
// Base64 encoded unique key to encode & decode cookies.
|
||||
//
|
||||
// Required. Key length should be 32 characters.
|
||||
// You may use `encryptcookie.GenerateKey()` to generate a new key.
|
||||
Key string
|
||||
|
||||
// Custom function to encrypt cookies.
|
||||
//
|
||||
// Optional. Default: EncryptCookie
|
||||
Encryptor func(decryptedString, key string) (string, error)
|
||||
|
||||
// Custom function to decrypt cookies.
|
||||
//
|
||||
// Optional. Default: DecryptCookie
|
||||
Decryptor func(encryptedString, key string) (string, error)
|
||||
}
|
||||
```
|
||||
|
||||
## Default Config
|
||||
|
||||
```go
|
||||
// `Key` must be a 32 character string. It's used to encrpyt the values, so make sure it is random and keep it secret.
|
||||
// You can call `encryptcookie.GenerateKey()` to create a random key for you.
|
||||
// Make sure not to set `Key` to `encryptcookie.GenerateKey()` because that will create a new key every run.
|
||||
app.Use(encryptcookie.New(encryptcookie.Config{
|
||||
Key: "secret-thirty-2-character-string",
|
||||
}))
|
||||
```
|
||||
|
||||
## Usage of CSRF and Encryptcookie Middlewares with Custom Cookie Names
|
||||
Normally, encryptcookie middleware skips `csrf_` cookies. However, it won't work when you use custom cookie names for CSRF. You should update `Except` config to avoid this problem. For example:
|
||||
|
||||
```go
|
||||
app.Use(encryptcookie.New(encryptcookie.Config{
|
||||
Key: "secret-thirty-2-character-string",
|
||||
Except: []string{"csrf_1"}, // exclude CSRF cookie
|
||||
}))
|
||||
app.Use(csrf.New(csrf.Config{
|
||||
KeyLookup: "form:test",
|
||||
CookieName: "csrf_1",
|
||||
CookieHTTPOnly: true,
|
||||
}))
|
||||
```
|
|
@ -0,0 +1,74 @@
|
|||
---
|
||||
id: envvar
|
||||
title: EnvVar
|
||||
---
|
||||
|
||||
EnvVar middleware for [Fiber](https://github.com/gofiber/fiber) that can be used to expose environment variables with various options.
|
||||
|
||||
## Signatures
|
||||
|
||||
```go
|
||||
func New(config ...Config) fiber.Handler
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
First import the middleware from Fiber,
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/middleware/envvar"
|
||||
)
|
||||
```
|
||||
|
||||
Then create a Fiber app with `app := fiber.New()`.
|
||||
|
||||
**Note**: You need to provide a path to use envvar middleware.
|
||||
|
||||
### Default Config
|
||||
|
||||
```go
|
||||
app.Use("/expose/envvars", envvar.New())
|
||||
```
|
||||
|
||||
### Custom Config
|
||||
|
||||
```go
|
||||
app.Use("/expose/envvars", envvar.New(envvar.Config{
|
||||
ExportVars: map[string]string{"testKey": "", "testDefaultKey": "testDefaultVal"},
|
||||
ExcludeVars: map[string]string{"excludeKey": ""}}
|
||||
}))
|
||||
```
|
||||
|
||||
### Response
|
||||
|
||||
Http response contract:
|
||||
```
|
||||
{
|
||||
"vars": {
|
||||
"someEnvVariable": "someValue",
|
||||
"anotherEnvVariable": "anotherValue",
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Config
|
||||
|
||||
```go
|
||||
// Config defines the config for middleware.
|
||||
type Config struct {
|
||||
// ExportVars specifies the environment variables that should export
|
||||
ExportVars map[string]string
|
||||
// ExcludeVars specifies the environment variables that should not export
|
||||
ExcludeVars map[string]string
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Default Config
|
||||
|
||||
```go
|
||||
Config{}
|
||||
```
|
|
@ -0,0 +1,80 @@
|
|||
---
|
||||
id: etag
|
||||
title: ETag
|
||||
---
|
||||
|
||||
ETag middleware for [Fiber](https://github.com/gofiber/fiber) that lets caches be more efficient and save bandwidth, as a web server does not need to resend a full response if the content has not changed.
|
||||
|
||||
## 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/etag"
|
||||
)
|
||||
```
|
||||
|
||||
After you initiate your Fiber app, you can use the following possibilities:
|
||||
|
||||
### Default Config
|
||||
|
||||
```go
|
||||
app.Use(etag.New())
|
||||
|
||||
// Get / receives Etag: "13-1831710635" in response header
|
||||
app.Get("/", func(c *fiber.Ctx) error {
|
||||
return c.SendString("Hello, World!")
|
||||
})
|
||||
```
|
||||
|
||||
### Custom Config
|
||||
|
||||
```go
|
||||
app.Use(etag.New(etag.Config{
|
||||
Weak: true,
|
||||
}))
|
||||
|
||||
// Get / receives Etag: "W/"13-1831710635" in response header
|
||||
app.Get("/", func(c *fiber.Ctx) error {
|
||||
return c.SendString("Hello, World!")
|
||||
})
|
||||
```
|
||||
|
||||
## Config
|
||||
|
||||
```go
|
||||
// Config defines the config for middleware.
|
||||
type Config struct {
|
||||
// Next defines a function to skip this middleware when returned true.
|
||||
//
|
||||
// Optional. Default: nil
|
||||
Next func(c *fiber.Ctx) bool
|
||||
|
||||
// Weak indicates that a weak validator is used. Weak etags are easy
|
||||
// to generate, but are far less useful for comparisons. Strong
|
||||
// validators are ideal for comparisons but can be very difficult
|
||||
// to generate efficiently. Weak ETag values of two representations
|
||||
// of the same resources might be semantically equivalent, but not
|
||||
// byte-for-byte identical. This means weak etags prevent caching
|
||||
// when byte range requests are used, but strong etags mean range
|
||||
// requests can still be cached.
|
||||
Weak bool
|
||||
}
|
||||
```
|
||||
|
||||
## Default Config
|
||||
|
||||
```go
|
||||
var ConfigDefault = Config{
|
||||
Next: nil,
|
||||
Weak: false,
|
||||
}
|
||||
```
|
|
@ -0,0 +1,84 @@
|
|||
---
|
||||
id: expvar
|
||||
title: ExpVar
|
||||
---
|
||||
|
||||
Expvar middleware for [Fiber](https://github.com/gofiber/fiber) that serves via its HTTP server runtime exposed variants in the JSON format. The package is typically only imported for the side effect of registering its HTTP handlers. The handled path is `/debug/vars`.
|
||||
|
||||
## Signatures
|
||||
|
||||
```go
|
||||
func New() fiber.Handler
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
Import the expvar package that is part of the Fiber web framework
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"expvar"
|
||||
"fmt"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
expvarmw "github.com/gofiber/fiber/v2/middleware/expvar"
|
||||
)
|
||||
|
||||
var count = expvar.NewInt("count")
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
app.Use(expvarmw.New())
|
||||
app.Get("/", func(c *fiber.Ctx) error {
|
||||
count.Add(1)
|
||||
|
||||
return c.SendString(fmt.Sprintf("hello expvar count %d", count.Value()))
|
||||
})
|
||||
|
||||
fmt.Println(app.Listen(":3000"))
|
||||
}
|
||||
```
|
||||
|
||||
Visit path `/debug/vars` to see all vars and use query `r=key` to filter exposed variables.
|
||||
|
||||
```bash
|
||||
curl 127.0.0.1:3000
|
||||
hello expvar count 1
|
||||
|
||||
curl 127.0.0.1:3000/debug/vars
|
||||
{
|
||||
"cmdline": ["xxx"],
|
||||
"count": 1,
|
||||
"expvarHandlerCalls": 33,
|
||||
"expvarRegexpErrors": 0,
|
||||
"memstats": {...}
|
||||
}
|
||||
|
||||
curl 127.0.0.1:3000/debug/vars?r=c
|
||||
{
|
||||
"cmdline": ["xxx"],
|
||||
"count": 1
|
||||
}
|
||||
```
|
||||
|
||||
## Config
|
||||
|
||||
```go
|
||||
// Config defines the config for middleware.
|
||||
type Config struct {
|
||||
// Next defines a function to skip this middleware when returned true.
|
||||
//
|
||||
// Optional. Default: nil
|
||||
Next func(c *fiber.Ctx) bool
|
||||
}
|
||||
```
|
||||
|
||||
## Default Config
|
||||
|
||||
```go
|
||||
var ConfigDefault = Config{
|
||||
Next: nil,
|
||||
}
|
||||
```
|
|
@ -0,0 +1,85 @@
|
|||
---
|
||||
id: favicon
|
||||
title: Favicon
|
||||
---
|
||||
|
||||
Favicon middleware for [Fiber](https://github.com/gofiber/fiber) that ignores favicon requests or caches a provided icon in memory to improve performance by skipping disk access. User agents request favicon.ico frequently and indiscriminately, so you may wish to exclude these requests from your logs by using this middleware before your logger middleware.
|
||||
|
||||
:::note
|
||||
This middleware is exclusively for serving the default, implicit favicon, which is GET /favicon.ico or [custom favicon URL](#config).
|
||||
:::
|
||||
|
||||
## 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/favicon"
|
||||
)
|
||||
```
|
||||
|
||||
After you initiate your Fiber app, you can use the following possibilities:
|
||||
|
||||
```go
|
||||
// Provide a minimal config
|
||||
app.Use(favicon.New())
|
||||
|
||||
// Or extend your config for customization
|
||||
app.Use(favicon.New(favicon.Config{
|
||||
File: "./favicon.ico",
|
||||
URL: "/favicon.ico",
|
||||
}))
|
||||
```
|
||||
|
||||
## Config
|
||||
|
||||
```go
|
||||
// Config defines the config for middleware.
|
||||
type Config struct {
|
||||
// Next defines a function to skip this middleware when returned true.
|
||||
//
|
||||
// Optional. Default: nil
|
||||
Next func(c *fiber.Ctx) bool
|
||||
|
||||
// File holds the path to an actual favicon that will be cached
|
||||
//
|
||||
// Optional. Default: ""
|
||||
File string
|
||||
|
||||
// URL for favicon handler
|
||||
//
|
||||
// Optional. Default: "/favicon.ico"
|
||||
URL string
|
||||
|
||||
// FileSystem is an optional alternate filesystem to search for the favicon in.
|
||||
// An example of this could be an embedded or network filesystem
|
||||
//
|
||||
// Optional. Default: nil
|
||||
FileSystem http.FileSystem
|
||||
|
||||
// CacheControl defines how the Cache-Control header in the response should be set
|
||||
//
|
||||
// Optional. Default: "public, max-age=31536000"
|
||||
CacheControl string
|
||||
}
|
||||
```
|
||||
|
||||
## Default Config
|
||||
|
||||
```go
|
||||
var ConfigDefault = Config{
|
||||
Next: nil,
|
||||
File: "",
|
||||
URL: "/favicon.ico",
|
||||
FileSystem: nil,
|
||||
CacheControl: "public, max-age=31536000",
|
||||
}
|
||||
```
|
|
@ -0,0 +1,237 @@
|
|||
---
|
||||
id: filesystem
|
||||
title: FileSystem
|
||||
---
|
||||
|
||||
Filesystem middleware for [Fiber](https://github.com/gofiber/fiber) that enables you to serve files from a directory.
|
||||
|
||||
:::caution
|
||||
**`:params` & `:optionals?` within the prefix path are not supported!**
|
||||
|
||||
**To handle paths with spaces (or other url encoded values) make sure to set `fiber.Config{ UnescapePath: true}`**
|
||||
:::
|
||||
|
||||
### Table of Contents
|
||||
|
||||
* [Signatures](filesystem.md#signatures)
|
||||
* [Examples](filesystem.md#examples)
|
||||
* [Config](filesystem.md#config)
|
||||
* [Default Config](filesystem.md#default-config)
|
||||
|
||||
### 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/filesystem"
|
||||
)
|
||||
```
|
||||
|
||||
After you initiate your Fiber app, you can use the following possibilities:
|
||||
|
||||
```go
|
||||
// Provide a minimal config
|
||||
app.Use(filesystem.New(filesystem.Config{
|
||||
Root: http.Dir("./assets")
|
||||
}))
|
||||
|
||||
// Or extend your config for customization
|
||||
app.Use(filesystem.New(filesystem.Config{
|
||||
Root: http.Dir("./assets"),
|
||||
Browse: true,
|
||||
Index: "index.html",
|
||||
NotFoundFile: "404.html",
|
||||
MaxAge: 3600,
|
||||
}))
|
||||
```
|
||||
|
||||
## pkger
|
||||
|
||||
[https://github.com/markbates/pkger](https://github.com/markbates/pkger)
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/middleware/filesystem"
|
||||
|
||||
"github.com/markbates/pkger"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use("/assets", filesystem.New(filesystem.Config{
|
||||
Root: pkger.Dir("/assets"),
|
||||
})
|
||||
|
||||
log.Fatal(app.Listen(":3000"))
|
||||
}
|
||||
```
|
||||
|
||||
## packr
|
||||
|
||||
[https://github.com/gobuffalo/packr](https://github.com/gobuffalo/packr)
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/middleware/filesystem"
|
||||
|
||||
"github.com/gobuffalo/packr/v2"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use("/assets", filesystem.New(filesystem.Config{
|
||||
Root: packr.New("Assets Box", "/assets"),
|
||||
})
|
||||
|
||||
log.Fatal(app.Listen(":3000"))
|
||||
}
|
||||
```
|
||||
|
||||
## go.rice
|
||||
|
||||
[https://github.com/GeertJohan/go.rice](https://github.com/GeertJohan/go.rice)
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/middleware/filesystem"
|
||||
|
||||
"github.com/GeertJohan/go.rice"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use("/assets", filesystem.New(filesystem.Config{
|
||||
Root: rice.MustFindBox("assets").HTTPBox(),
|
||||
})
|
||||
|
||||
log.Fatal(app.Listen(":3000"))
|
||||
}
|
||||
```
|
||||
|
||||
## fileb0x
|
||||
|
||||
[https://github.com/UnnoTed/fileb0x](https://github.com/UnnoTed/fileb0x)
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/middleware/filesystem"
|
||||
|
||||
"<Your go module>/myEmbeddedFiles"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use("/assets", filesystem.New(filesystem.Config{
|
||||
Root: myEmbeddedFiles.HTTP,
|
||||
})
|
||||
|
||||
log.Fatal(app.Listen(":3000"))
|
||||
}
|
||||
```
|
||||
|
||||
## statik
|
||||
|
||||
[https://github.com/rakyll/statik](https://github.com/rakyll/statik)
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/middleware/filesystem"
|
||||
|
||||
// Use blank to invoke init function and register data to statik
|
||||
_ "<Your go module>/statik"
|
||||
"github.com/rakyll/statik/fs"
|
||||
)
|
||||
|
||||
func main() {
|
||||
statikFS, err := fs.New()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
app := fiber.New()
|
||||
|
||||
app.Use("/", filesystem.New(filesystem.Config{
|
||||
Root: statikFS,
|
||||
}))
|
||||
|
||||
log.Fatal(app.Listen(":3000"))
|
||||
}
|
||||
```
|
||||
|
||||
### Config
|
||||
|
||||
```go
|
||||
// Config defines the config for middleware.
|
||||
type Config struct {
|
||||
// Next defines a function to skip this middleware when returned true.
|
||||
//
|
||||
// Optional. Default: nil
|
||||
Next func(c *fiber.Ctx) bool
|
||||
|
||||
// Root is a FileSystem that provides access
|
||||
// to a collection of files and directories.
|
||||
//
|
||||
// Required. Default: nil
|
||||
Root http.FileSystem `json:"-"`
|
||||
|
||||
// Enable directory browsing.
|
||||
//
|
||||
// Optional. Default: false
|
||||
Browse bool `json:"browse"`
|
||||
|
||||
// Index file for serving a directory.
|
||||
//
|
||||
// Optional. Default: "index.html"
|
||||
Index string `json:"index"`
|
||||
|
||||
// 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"`
|
||||
|
||||
// File to return if path is not found. Useful for SPA's.
|
||||
//
|
||||
// Optional. Default: ""
|
||||
NotFoundFile string `json:"not_found_file"`
|
||||
}
|
||||
```
|
||||
|
||||
### Default Config
|
||||
|
||||
```go
|
||||
var ConfigDefault = Config{
|
||||
Next: nil,
|
||||
Root: nil,
|
||||
Browse: false,
|
||||
Index: "/index.html",
|
||||
MaxAge: 0,
|
||||
}
|
||||
```
|
|
@ -0,0 +1,110 @@
|
|||
---
|
||||
id: idempotency
|
||||
title: Idempotency
|
||||
---
|
||||
|
||||
Idempotency middleware for [Fiber](https://github.com/gofiber/fiber) allows for fault-tolerant APIs where duplicate requests — for example due to networking issues on the client-side — do not erroneously cause the same action performed multiple times on the server-side.
|
||||
|
||||
Refer to https://datatracker.ietf.org/doc/html/draft-ietf-httpapi-idempotency-key-header-02 for a better understanding.
|
||||
|
||||
## Signatures
|
||||
|
||||
```go
|
||||
func New(config ...Config) fiber.Handler
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
First import the middleware from Fiber,
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/middleware/idempotency"
|
||||
)
|
||||
```
|
||||
|
||||
Then create a Fiber app with `app := fiber.New()`.
|
||||
|
||||
### Default Config
|
||||
|
||||
```go
|
||||
app.Use(idempotency.New())
|
||||
```
|
||||
|
||||
### Custom Config
|
||||
|
||||
```go
|
||||
app.Use(idempotency.New(idempotency.Config{
|
||||
Lifetime: 42 * time.Minute,
|
||||
// ...
|
||||
}))
|
||||
```
|
||||
|
||||
### Config
|
||||
|
||||
```go
|
||||
type Config struct {
|
||||
// Next defines a function to skip this middleware when returned true.
|
||||
//
|
||||
// Optional. Default: a function which skips the middleware on safe HTTP request method.
|
||||
Next func(c *fiber.Ctx) bool
|
||||
|
||||
// Lifetime is the maximum lifetime of an idempotency key.
|
||||
//
|
||||
// Optional. Default: 30 * time.Minute
|
||||
Lifetime time.Duration
|
||||
|
||||
// KeyHeader is the name of the header that contains the idempotency key.
|
||||
//
|
||||
// Optional. Default: X-Idempotency-Key
|
||||
KeyHeader string
|
||||
// KeyHeaderValidate defines a function to validate the syntax of the idempotency header.
|
||||
//
|
||||
// Optional. Default: a function which ensures the header is 36 characters long (the size of an UUID).
|
||||
KeyHeaderValidate func(string) error
|
||||
|
||||
// KeepResponseHeaders is a list of headers that should be kept from the original response.
|
||||
//
|
||||
// Optional. Default: nil (to keep all headers)
|
||||
KeepResponseHeaders []string
|
||||
|
||||
// Lock locks an idempotency key.
|
||||
//
|
||||
// Optional. Default: an in-memory locker for this process only.
|
||||
Lock Locker
|
||||
|
||||
// Storage stores response data by idempotency key.
|
||||
//
|
||||
// Optional. Default: an in-memory storage for this process only.
|
||||
Storage fiber.Storage
|
||||
}
|
||||
```
|
||||
|
||||
### Default Config
|
||||
|
||||
```go
|
||||
var ConfigDefault = Config{
|
||||
Next: func(c *fiber.Ctx) bool {
|
||||
// Skip middleware if the request was done using a safe HTTP method
|
||||
return fiber.IsMethodSafe(c.Method())
|
||||
},
|
||||
|
||||
Lifetime: 30 * time.Minute,
|
||||
|
||||
KeyHeader: "X-Idempotency-Key",
|
||||
KeyHeaderValidate: func(k string) error {
|
||||
if l, wl := len(k), 36; l != wl { // UUID length is 36 chars
|
||||
return fmt.Errorf("%w: invalid length: %d != %d", ErrInvalidIdempotencyKey, l, wl)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
|
||||
KeepResponseHeaders: nil,
|
||||
|
||||
Lock: nil, // Set in configDefault so we don't allocate data here.
|
||||
|
||||
Storage: nil, // Set in configDefault so we don't allocate data here.
|
||||
}
|
||||
```
|
|
@ -0,0 +1,146 @@
|
|||
---
|
||||
id: limiter
|
||||
title: Limiter
|
||||
---
|
||||
|
||||
Limiter middleware for [Fiber](https://github.com/gofiber/fiber) used to limit repeated requests to public APIs and/or endpoints such as password reset etc. Also useful for API clients, web crawling, or other tasks that need to be throttled.
|
||||
|
||||
:::note
|
||||
This module does not share state with other processes/servers by default.
|
||||
:::
|
||||
|
||||
## 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/limiter"
|
||||
)
|
||||
```
|
||||
|
||||
After you initiate your Fiber app, you can use the following possibilities:
|
||||
|
||||
```go
|
||||
// Default middleware config
|
||||
app.Use(limiter.New())
|
||||
|
||||
// Or extend your config for customization
|
||||
app.Use(limiter.New(limiter.Config{
|
||||
Next: func(c *fiber.Ctx) bool {
|
||||
return c.IP() == "127.0.0.1"
|
||||
},
|
||||
Max: 20,
|
||||
Expiration: 30 * time.Second,
|
||||
KeyGenerator: func(c *fiber.Ctx) string {
|
||||
return c.Get("x-forwarded-for")
|
||||
},
|
||||
LimitReached: func(c *fiber.Ctx) error {
|
||||
return c.SendFile("./toofast.html")
|
||||
},
|
||||
Storage: myCustomStorage{}
|
||||
}))
|
||||
```
|
||||
|
||||
## Sliding window
|
||||
|
||||
Instead of using the standard fixed window algorithm, you can enable the [sliding window](https://en.wikipedia.org/wiki/Sliding_window_protocol) algorithm.
|
||||
|
||||
A example of such configuration is:
|
||||
|
||||
```go
|
||||
app.Use(limiter.New(limiter.Config{
|
||||
Max: 20,
|
||||
Expiration: 30 * time.Second,
|
||||
LimiterMiddleware: limiter.SlidingWindow{}
|
||||
}))
|
||||
```
|
||||
|
||||
This means that every window will take into account the previous window(if there was any). The given formula for the rate is:
|
||||
```
|
||||
weightOfPreviousWindpw = previous window's amount request * (whenNewWindow / Expiration)
|
||||
rate = weightOfPreviousWindpw + current window's amount request.
|
||||
```
|
||||
|
||||
## Config
|
||||
|
||||
```go
|
||||
// Config defines the config for middleware.
|
||||
type Config struct {
|
||||
// Next defines a function to skip this middleware when returned true.
|
||||
//
|
||||
// Optional. Default: nil
|
||||
Next func(c *fiber.Ctx) bool
|
||||
|
||||
// Max number of recent connections during `Expiration` seconds before sending a 429 response
|
||||
//
|
||||
// Default: 5
|
||||
Max int
|
||||
|
||||
// KeyGenerator allows you to generate custom keys, by default c.IP() is used
|
||||
//
|
||||
// Default: func(c *fiber.Ctx) string {
|
||||
// return c.IP()
|
||||
// }
|
||||
KeyGenerator func(*fiber.Ctx) string
|
||||
|
||||
// Expiration is the time on how long to keep records of requests in memory
|
||||
//
|
||||
// Default: 1 * time.Minute
|
||||
Expiration time.Duration
|
||||
|
||||
// LimitReached is called when a request hits the limit
|
||||
//
|
||||
// Default: func(c *fiber.Ctx) error {
|
||||
// return c.SendStatus(fiber.StatusTooManyRequests)
|
||||
// }
|
||||
LimitReached fiber.Handler
|
||||
|
||||
// When set to true, requests with StatusCode >= 400 won't be counted.
|
||||
//
|
||||
// Default: false
|
||||
SkipFailedRequests bool
|
||||
|
||||
// When set to true, requests with StatusCode < 400 won't be counted.
|
||||
//
|
||||
// Default: false
|
||||
SkipSuccessfulRequests bool
|
||||
|
||||
// Store is used to store the state of the middleware
|
||||
//
|
||||
// Default: an in memory store for this process only
|
||||
Storage fiber.Storage
|
||||
|
||||
// LimiterMiddleware is the struct that implements limiter middleware.
|
||||
//
|
||||
// Default: a new Fixed Window Rate Limiter
|
||||
LimiterMiddleware LimiterHandler
|
||||
}
|
||||
```
|
||||
|
||||
A custom store can be used if it implements the `Storage` interface - more details and an example can be found in `store.go`.
|
||||
|
||||
## Default Config
|
||||
|
||||
```go
|
||||
var ConfigDefault = Config{
|
||||
Max: 5,
|
||||
Expiration: 1 * time.Minute,
|
||||
KeyGenerator: func(c *fiber.Ctx) string {
|
||||
return c.IP()
|
||||
},
|
||||
LimitReached: func(c *fiber.Ctx) error {
|
||||
return c.SendStatus(fiber.StatusTooManyRequests)
|
||||
},
|
||||
SkipFailedRequests: false,
|
||||
SkipSuccessfulRequests: false,
|
||||
LimiterMiddleware: FixedWindow{},
|
||||
}
|
||||
```
|
|
@ -0,0 +1,193 @@
|
|||
---
|
||||
id: logger
|
||||
title: Logger
|
||||
---
|
||||
|
||||
Logger middleware for [Fiber](https://github.com/gofiber/fiber) that logs HTTP request/response details.
|
||||
|
||||
## Signatures
|
||||
```go
|
||||
func New(config ...Config) fiber.Handler
|
||||
```
|
||||
## Examples
|
||||
First ensure the appropriate packages are imported
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/middleware/logger"
|
||||
)
|
||||
```
|
||||
|
||||
:::tip
|
||||
|
||||
The order of registration plays a role. Only all routes that are registered after this one will be logged.
|
||||
The middleware should therefore be one of the first to be registered.
|
||||
|
||||
:::
|
||||
|
||||
### Default Config
|
||||
```go
|
||||
// Default middleware config
|
||||
app.Use(logger.New())
|
||||
```
|
||||
### Logging remote IP and Port
|
||||
```go
|
||||
app.Use(logger.New(logger.Config{
|
||||
Format: "[${ip}]:${port} ${status} - ${method} ${path}\n",
|
||||
}))
|
||||
```
|
||||
|
||||
### Logging Request ID
|
||||
```go
|
||||
app.Use(requestid.New())
|
||||
app.Use(logger.New(logger.Config{
|
||||
// For more options, see the Config section
|
||||
Format: "${pid} ${locals:requestid} ${status} - ${method} ${path}\n",
|
||||
}))
|
||||
```
|
||||
|
||||
### Changing TimeZone & TimeFormat
|
||||
|
||||
```go
|
||||
app.Use(logger.New(logger.Config{
|
||||
Format: "${pid} ${status} - ${method} ${path}\n",
|
||||
TimeFormat: "02-Jan-2006",
|
||||
TimeZone: "America/New_York",
|
||||
}))
|
||||
```
|
||||
|
||||
### Custom File Writer
|
||||
```go
|
||||
file, err := os.OpenFile("./123.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
|
||||
if err != nil {
|
||||
log.Fatalf("error opening file: %v", err)
|
||||
}
|
||||
defer file.Close()
|
||||
app.Use(logger.New(logger.Config{
|
||||
Output: file,
|
||||
}))
|
||||
```
|
||||
### Add Custom Tags
|
||||
```go
|
||||
app.Use(logger.New(logger.Config{
|
||||
CustomTags: map[string]logger.LogFunc{
|
||||
"custom_tag": func(output logger.Buffer, c *fiber.Ctx, data *logger.Data, extraParam string) (int, error) {
|
||||
return output.WriteString("it is a custom tag")
|
||||
},
|
||||
},
|
||||
}))
|
||||
```
|
||||
|
||||
### Callback after log is written
|
||||
|
||||
```go
|
||||
app.Use(logger.New(logger.Config{
|
||||
TimeFormat: time.RFC3339Nano,
|
||||
TimeZone: "Asia/Shanghai",
|
||||
Done: func(c *fiber.Ctx, logString []byte) {
|
||||
if c.Response().StatusCode() != fiber.StatusOK {
|
||||
reporter.SendToSlack(logString)
|
||||
}
|
||||
},
|
||||
}))
|
||||
```
|
||||
|
||||
## Config
|
||||
```go
|
||||
// Config defines the config for middleware.
|
||||
type Config struct {
|
||||
// Next defines a function to skip this middleware when returned true.
|
||||
//
|
||||
// Optional. Default: nil
|
||||
Next func(c *fiber.Ctx) bool
|
||||
// Done is a function that is called after the log string for a request is written to Output,
|
||||
// and pass the log string as parameter.
|
||||
//
|
||||
// Optional. Default: nil
|
||||
Done func(c *fiber.Ctx, logString []byte)
|
||||
// tagFunctions defines the custom tag action
|
||||
//
|
||||
// Optional. Default: map[string]LogFunc
|
||||
CustomTags map[string]LogFunc
|
||||
// Format defines the logging tags
|
||||
//
|
||||
// Optional. Default: [${time}] ${status} - ${latency} ${method} ${path}\n
|
||||
Format string
|
||||
// TimeFormat https://programming.guide/go/format-parse-string-time-date-example.html
|
||||
//
|
||||
// Optional. Default: 15:04:05
|
||||
TimeFormat string
|
||||
// TimeZone can be specified, such as "UTC" and "America/New_York" and "Asia/Chongqing", etc
|
||||
//
|
||||
// Optional. Default: "Local"
|
||||
TimeZone string
|
||||
// TimeInterval is the delay before the timestamp is updated
|
||||
//
|
||||
// Optional. Default: 500 * time.Millisecond
|
||||
TimeInterval time.Duration
|
||||
// Output is a writer where logs are written
|
||||
//
|
||||
// Default: os.Stdout
|
||||
Output io.Writer
|
||||
}
|
||||
type LogFunc func(buf logger.Buffer, c *fiber.Ctx, data *logger.Data, extraParam string) (int, error)
|
||||
```
|
||||
## Default Config
|
||||
```go
|
||||
var ConfigDefault = Config{
|
||||
Next: nil,
|
||||
Done: nil,
|
||||
Format: "[${time}] ${status} - ${latency} ${method} ${path}\n",
|
||||
TimeFormat: "15:04:05",
|
||||
TimeZone: "Local",
|
||||
TimeInterval: 500 * time.Millisecond,
|
||||
Output: os.Stdout,
|
||||
}
|
||||
```
|
||||
|
||||
## Constants
|
||||
```go
|
||||
// Logger variables
|
||||
const (
|
||||
TagPid = "pid"
|
||||
TagTime = "time"
|
||||
TagReferer = "referer"
|
||||
TagProtocol = "protocol"
|
||||
TagPort = "port"
|
||||
TagIP = "ip"
|
||||
TagIPs = "ips"
|
||||
TagHost = "host"
|
||||
TagMethod = "method"
|
||||
TagPath = "path"
|
||||
TagURL = "url"
|
||||
TagUA = "ua"
|
||||
TagLatency = "latency"
|
||||
TagStatus = "status" // response status
|
||||
TagResBody = "resBody" // response body
|
||||
TagReqHeaders = "reqHeaders"
|
||||
TagQueryStringParams = "queryParams" // request query parameters
|
||||
TagBody = "body" // request body
|
||||
TagBytesSent = "bytesSent"
|
||||
TagBytesReceived = "bytesReceived"
|
||||
TagRoute = "route"
|
||||
TagError = "error"
|
||||
// DEPRECATED: Use TagReqHeader instead
|
||||
TagHeader = "header:" // request header
|
||||
TagReqHeader = "reqHeader:" // request header
|
||||
TagRespHeader = "respHeader:" // response header
|
||||
TagQuery = "query:" // request query
|
||||
TagForm = "form:" // request form
|
||||
TagCookie = "cookie:" // request cookie
|
||||
TagLocals = "locals:"
|
||||
// colors
|
||||
TagBlack = "black"
|
||||
TagRed = "red"
|
||||
TagGreen = "green"
|
||||
TagYellow = "yellow"
|
||||
TagBlue = "blue"
|
||||
TagMagenta = "magenta"
|
||||
TagCyan = "cyan"
|
||||
TagWhite = "white"
|
||||
TagReset = "reset"
|
||||
)
|
||||
```
|
|
@ -0,0 +1,104 @@
|
|||
---
|
||||
id: monitor
|
||||
title: Monitor
|
||||
---
|
||||
|
||||
Monitor middleware for [Fiber](https://github.com/gofiber/fiber) that reports server metrics, inspired by [express-status-monitor](https://github.com/RafalWilinski/express-status-monitor)
|
||||
|
||||
:::caution
|
||||
Monitor is still in beta, API might change in the future!
|
||||
:::
|
||||
|
||||

|
||||
|
||||
### Signatures
|
||||
```go
|
||||
func New() fiber.Handler
|
||||
```
|
||||
|
||||
### Examples
|
||||
Import the middleware package and assign it to a route.
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/middleware/monitor"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Get("/metrics", monitor.New(monitor.Config{Title: "MyService Metrics Page"}))
|
||||
|
||||
log.Fatal(app.Listen(":3000"))
|
||||
}
|
||||
```
|
||||
You can also access the API endpoint with
|
||||
`curl -X GET -H "Accept: application/json" http://localhost:3000/metrics` which returns:
|
||||
```json
|
||||
{"pid":{ "cpu":0.4568381746582226, "ram":20516864, "conns":3 },
|
||||
"os": { "cpu":8.759124087593099, "ram":3997155328, "conns":44,
|
||||
"total_ram":8245489664, "load_avg":0.51 }}
|
||||
```
|
||||
|
||||
## Config
|
||||
|
||||
```go
|
||||
// Config defines the config for middleware.
|
||||
type Config struct {
|
||||
// Metrics page title
|
||||
//
|
||||
// Optional. Default: "Fiber Monitor"
|
||||
Title string
|
||||
|
||||
// Refresh period
|
||||
//
|
||||
// Optional. Default: 3 seconds
|
||||
Refresh time.Duration
|
||||
|
||||
// Whether the service should expose only the monitoring API.
|
||||
//
|
||||
// Optional. Default: false
|
||||
APIOnly bool
|
||||
|
||||
// Next defines a function to skip this middleware when returned true.
|
||||
//
|
||||
// Optional. Default: nil
|
||||
Next func(c *fiber.Ctx) bool
|
||||
|
||||
// Custom HTML Code to Head Section(Before End)
|
||||
//
|
||||
// Optional. Default: empty
|
||||
CustomHead string
|
||||
|
||||
// FontURL for specify font resource path or URL . also you can use relative path
|
||||
//
|
||||
// Optional. Default: https://fonts.googleapis.com/css2?family=Roboto:wght@400;900&display=swap
|
||||
|
||||
FontURL string
|
||||
// ChartJsURL for specify ChartJS library path or URL . also you can use relative path
|
||||
//
|
||||
// Optional. Default: https://cdn.jsdelivr.net/npm/chart.js@2.9/dist/Chart.bundle.min.js
|
||||
|
||||
ChartJsURL string
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
## Default Config
|
||||
|
||||
```go
|
||||
var ConfigDefault = Config{
|
||||
Title: "Fiber Monitor",
|
||||
Refresh: 3 * time.Second,
|
||||
APIOnly: false,
|
||||
Next: nil,
|
||||
CustomHead:"",
|
||||
FontURL:"https://fonts.googleapis.com/css2?family=Roboto:wght@400;900&display=swap",
|
||||
ChartJsURL:"https://cdn.jsdelivr.net/npm/chart.js@2.9/dist/Chart.bundle.min.js"
|
||||
|
||||
}
|
||||
```
|
|
@ -0,0 +1,70 @@
|
|||
---
|
||||
id: pprof
|
||||
title: Pprof
|
||||
---
|
||||
|
||||
Pprof middleware for [Fiber](https://github.com/gofiber/fiber) that serves via its HTTP server runtime profiling data in the format expected by the pprof visualization tool. The package is typically only imported for the side effect of registering its HTTP handlers. The handled paths all begin with /debug/pprof/.
|
||||
|
||||
* [Signatures](pprof.md#signatures)
|
||||
* [Examples](pprof.md#examples)
|
||||
|
||||
## Signatures
|
||||
|
||||
```go
|
||||
func New() 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/pprof"
|
||||
)
|
||||
```
|
||||
|
||||
After you initiate your Fiber app, you can use the following possibilities:
|
||||
|
||||
```go
|
||||
// Default middleware
|
||||
app.Use(pprof.New())
|
||||
```
|
||||
|
||||
In systems where you have multiple ingress endpoints, it is common to add a URL prefix, like so:
|
||||
|
||||
```go
|
||||
// Default middleware
|
||||
app.Use(pprof.New(pprof.Config{Prefix: "/endpoint-prefix"}))
|
||||
```
|
||||
|
||||
This prefix will be added to the default path of "/debug/pprof/", for a resulting URL of:
|
||||
"/endpoint-prefix/debug/pprof/".
|
||||
|
||||
## Config
|
||||
|
||||
```go
|
||||
// Config defines the config for middleware.
|
||||
type Config struct {
|
||||
// Next defines a function to skip this middleware when returned true.
|
||||
//
|
||||
// Optional. Default: nil
|
||||
Next func(c *fiber.Ctx) bool
|
||||
|
||||
// Prefix defines a URL prefix added before "/debug/pprof".
|
||||
// Note that it should start with (but not end with) a slash.
|
||||
// Example: "/federated-fiber"
|
||||
//
|
||||
// Optional. Default: ""
|
||||
Prefix string
|
||||
}
|
||||
```
|
||||
|
||||
## Default Config
|
||||
|
||||
```go
|
||||
var ConfigDefault = Config{
|
||||
Next: nil,
|
||||
}
|
||||
```
|
|
@ -0,0 +1,150 @@
|
|||
---
|
||||
id: proxy
|
||||
title: Proxy
|
||||
---
|
||||
|
||||
Proxy middleware for [Fiber](https://github.com/gofiber/fiber) that allows you to proxy requests to multiple servers.
|
||||
|
||||
## Signatures
|
||||
|
||||
```go
|
||||
// Balancer create a load balancer among multiple upstrem servers.
|
||||
func Balancer(config Config) fiber.Handler
|
||||
// Forward performs the given http request and fills the given http response.
|
||||
func Forward(addr string, clients ...*fasthttp.Client) fiber.Handler
|
||||
// Do performs the given http request and fills the given http response.
|
||||
func Do(c *fiber.Ctx, addr string, clients ...*fasthttp.Client) error
|
||||
// DomainForward the given http request based on the given domain and fills the given http response
|
||||
func DomainForward(hostname string, addr string, clients ...*fasthttp.Client) fiber.Handler
|
||||
// BalancerForward performs the given http request based round robin balancer and fills the given http response
|
||||
func BalancerForward(servers []string, clients ...*fasthttp.Client) 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/proxy"
|
||||
)
|
||||
```
|
||||
|
||||
After you initiate your Fiber app, you can use the following possibilities:
|
||||
|
||||
```go
|
||||
// if target https site uses a self-signed certificate, you should
|
||||
// call WithTlsConfig before Do and Forward
|
||||
proxy.WithTlsConfig(&tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
})
|
||||
// if you need to use global self-custom client, you should use proxy.WithClient.
|
||||
proxy.WithClient(&fasthttp.Client{
|
||||
NoDefaultUserAgentHeader: true,
|
||||
DisablePathNormalizing: true,
|
||||
})
|
||||
|
||||
// Forward to url
|
||||
app.Get("/gif", proxy.Forward("https://i.imgur.com/IWaBepg.gif"))
|
||||
|
||||
// If you want to forward with a specific domain. You have to use proxy.DomainForward.
|
||||
app.Get("/payments", proxy.DomainForward("docs.gofiber.io", "http://localhost:8000"))
|
||||
|
||||
// Forward to url with local custom client
|
||||
app.Get("/gif", proxy.Forward("https://i.imgur.com/IWaBepg.gif", &fasthttp.Client{
|
||||
NoDefaultUserAgentHeader: true,
|
||||
DisablePathNormalizing: true,
|
||||
}))
|
||||
|
||||
// Make request within handler
|
||||
app.Get("/:id", func(c *fiber.Ctx) error {
|
||||
url := "https://i.imgur.com/"+c.Params("id")+".gif"
|
||||
if err := proxy.Do(c, url); err != nil {
|
||||
return err
|
||||
}
|
||||
// Remove Server header from response
|
||||
c.Response().Header.Del(fiber.HeaderServer)
|
||||
return nil
|
||||
})
|
||||
|
||||
// Minimal round robin balancer
|
||||
app.Use(proxy.Balancer(proxy.Config{
|
||||
Servers: []string{
|
||||
"http://localhost:3001",
|
||||
"http://localhost:3002",
|
||||
"http://localhost:3003",
|
||||
},
|
||||
}))
|
||||
|
||||
// Or extend your balancer for customization
|
||||
app.Use(proxy.Balancer(proxy.Config{
|
||||
Servers: []string{
|
||||
"http://localhost:3001",
|
||||
"http://localhost:3002",
|
||||
"http://localhost:3003",
|
||||
},
|
||||
ModifyRequest: func(c *fiber.Ctx) error {
|
||||
c.Request().Header.Add("X-Real-IP", c.IP())
|
||||
return nil
|
||||
},
|
||||
ModifyResponse: func(c *fiber.Ctx) error {
|
||||
c.Response().Header.Del(fiber.HeaderServer)
|
||||
return nil
|
||||
},
|
||||
}))
|
||||
|
||||
// Or this way if the balancer is using https and the destination server is only using http.
|
||||
app.Use(proxy.BalancerForward([]string{
|
||||
"http://localhost:3001",
|
||||
"http://localhost:3002",
|
||||
"http://localhost:3003",
|
||||
}))
|
||||
```
|
||||
|
||||
## Config
|
||||
|
||||
```go
|
||||
// Config defines the config for middleware.
|
||||
type Config struct {
|
||||
// Next defines a function to skip this middleware when returned true.
|
||||
//
|
||||
// Optional. Default: nil
|
||||
Next func(c *fiber.Ctx) bool
|
||||
|
||||
// Servers defines a list of <scheme>://<host> HTTP servers,
|
||||
//
|
||||
// which are used in a round-robin manner.
|
||||
// i.e.: "https://foobar.com, http://www.foobar.com"
|
||||
//
|
||||
// Required
|
||||
Servers []string
|
||||
|
||||
// ModifyRequest allows you to alter the request
|
||||
//
|
||||
// Optional. Default: nil
|
||||
ModifyRequest fiber.Handler
|
||||
|
||||
// ModifyResponse allows you to alter the response
|
||||
//
|
||||
// Optional. Default: nil
|
||||
ModifyResponse fiber.Handler
|
||||
|
||||
// tls config for the http client.
|
||||
TlsConfig *tls.Config
|
||||
|
||||
// Client is custom client when client config is complex.
|
||||
// Note that Servers, Timeout, WriteBufferSize, ReadBufferSize and TlsConfig
|
||||
// will not be used if the client are set.
|
||||
Client *fasthttp.LBClient
|
||||
}
|
||||
```
|
||||
|
||||
## Default Config
|
||||
|
||||
```go
|
||||
// ConfigDefault is the default config
|
||||
var ConfigDefault = Config{
|
||||
Next: nil,
|
||||
}
|
||||
```
|
|
@ -0,0 +1,67 @@
|
|||
---
|
||||
id: recover
|
||||
title: Recover
|
||||
---
|
||||
|
||||
Recover middleware for [Fiber](https://github.com/gofiber/fiber) that recovers from panics anywhere in the stack chain and handles the control to the centralized [ErrorHandler](https://docs.gofiber.io/error-handling).
|
||||
|
||||
## 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/recover"
|
||||
)
|
||||
```
|
||||
|
||||
After you initiate your Fiber app, you can use the following possibilities:
|
||||
|
||||
```go
|
||||
// Default middleware config
|
||||
app.Use(recover.New())
|
||||
|
||||
// This panic will be catch by the middleware
|
||||
app.Get("/", func(c *fiber.Ctx) error {
|
||||
panic("I'm an error")
|
||||
})
|
||||
```
|
||||
|
||||
## Config
|
||||
|
||||
```go
|
||||
// Config defines the config for middleware.
|
||||
type Config struct {
|
||||
// Next defines a function to skip this middleware when returned true.
|
||||
//
|
||||
// Optional. Default: nil
|
||||
Next func(c *fiber.Ctx) bool
|
||||
|
||||
// EnableStackTrace enables handling stack trace
|
||||
//
|
||||
// Optional. Default: false
|
||||
EnableStackTrace bool
|
||||
|
||||
// StackTraceHandler defines a function to handle stack trace
|
||||
//
|
||||
// Optional. Default: defaultStackTraceHandler
|
||||
StackTraceHandler func(c *fiber.Ctx, e interface{})
|
||||
}
|
||||
```
|
||||
|
||||
## Default Config
|
||||
|
||||
```go
|
||||
var ConfigDefault = Config{
|
||||
Next: nil,
|
||||
EnableStackTrace: false,
|
||||
StackTraceHandler: defaultStackTraceHandler,
|
||||
}
|
||||
```
|
|
@ -0,0 +1,79 @@
|
|||
---
|
||||
id: requestid
|
||||
title: RequestID
|
||||
---
|
||||
|
||||
RequestID middleware for [Fiber](https://github.com/gofiber/fiber) that adds an indentifier to the 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/requestid"
|
||||
)
|
||||
```
|
||||
|
||||
After you initiate your Fiber app, you can use the following possibilities:
|
||||
|
||||
```go
|
||||
// Default middleware config
|
||||
app.Use(requestid.New())
|
||||
|
||||
// Or extend your config for customization
|
||||
app.Use(requestid.New(requestid.Config{
|
||||
Header: "X-Custom-Header",
|
||||
Generator: func() string {
|
||||
return "static-id"
|
||||
},
|
||||
}))
|
||||
```
|
||||
|
||||
## Config
|
||||
|
||||
```go
|
||||
// Config defines the config for middleware.
|
||||
type Config struct {
|
||||
// Next defines a function to skip this middleware when returned true.
|
||||
//
|
||||
// Optional. Default: nil
|
||||
Next func(c *fiber.Ctx) bool
|
||||
|
||||
// Header is the header key where to get/set the unique request ID
|
||||
//
|
||||
// Optional. Default: "X-Request-ID"
|
||||
Header string
|
||||
|
||||
// Generator defines a function to generate the unique identifier.
|
||||
//
|
||||
// Optional. Default: utils.UUID
|
||||
Generator func() string
|
||||
|
||||
// ContextKey defines the key used when storing the request ID in
|
||||
// the locals for a specific request.
|
||||
//
|
||||
// Optional. Default: requestid
|
||||
ContextKey string
|
||||
}
|
||||
```
|
||||
|
||||
## Default Config
|
||||
|
||||
```go
|
||||
var ConfigDefault = Config{
|
||||
Next: nil,
|
||||
Header: fiber.HeaderXRequestID,
|
||||
Generator: func() string {
|
||||
return utils.UUID()
|
||||
},
|
||||
ContextKey: "requestid"
|
||||
}
|
||||
```
|
|
@ -0,0 +1,151 @@
|
|||
---
|
||||
id: session
|
||||
title: Session
|
||||
---
|
||||
|
||||
Session middleware for [Fiber](https://github.com/gofiber/fiber).
|
||||
|
||||
:::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) *Store
|
||||
func (s *Store) RegisterType(i interface{})
|
||||
func (s *Store) Get(c *fiber.Ctx) (*Session, error)
|
||||
func (s *Store) Reset() error
|
||||
|
||||
func (s *Session) Get(key string) interface{}
|
||||
func (s *Session) Set(key string, val interface{})
|
||||
func (s *Session) Delete(key string)
|
||||
func (s *Session) Destroy() error
|
||||
func (s *Session) Regenerate() error
|
||||
func (s *Session) Save() error
|
||||
func (s *Session) Fresh() bool
|
||||
func (s *Session) ID() string
|
||||
func (s *Session) Keys() []string
|
||||
```
|
||||
|
||||
:::caution
|
||||
Storing `interface{}` values are limited to built-ins Go types.
|
||||
:::
|
||||
|
||||
### 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/session"
|
||||
)
|
||||
```
|
||||
|
||||
Then create a Fiber app with `app := fiber.New()`.
|
||||
|
||||
### Default Configuration
|
||||
|
||||
```go
|
||||
// This stores all of your app's sessions
|
||||
// Default middleware config
|
||||
store := session.New()
|
||||
|
||||
// This panic will be caught by the middleware
|
||||
app.Get("/", func(c *fiber.Ctx) error {
|
||||
// Get session from storage
|
||||
sess, err := store.Get(c)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Get value
|
||||
name := sess.Get("name")
|
||||
|
||||
// Set key/value
|
||||
sess.Set("name", "john")
|
||||
|
||||
// Get all Keys
|
||||
keys := sess.Keys()
|
||||
|
||||
// Delete key
|
||||
sess.Delete("name")
|
||||
|
||||
// Destroy session
|
||||
if err := sess.Destroy(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Save session
|
||||
if err := sess.Save(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return c.SendString(fmt.Sprintf("Welcome %v", name))
|
||||
})
|
||||
```
|
||||
|
||||
### Custom Storage/Database
|
||||
|
||||
You can use any storage from our [storage](https://github.com/gofiber/storage/) package.
|
||||
|
||||
```go
|
||||
storage := sqlite3.New() // From github.com/gofiber/storage/sqlite3
|
||||
store := session.New(session.Config{
|
||||
Storage: storage,
|
||||
})
|
||||
```
|
||||
|
||||
To use the store, see the above example.
|
||||
|
||||
## Config
|
||||
|
||||
```go
|
||||
// Config defines the config for middleware.
|
||||
type Config struct {
|
||||
// Allowed session duration
|
||||
// Optional. Default value 24 * time.Hour
|
||||
Expiration time.Duration
|
||||
|
||||
// Storage interface to store the session data
|
||||
// Optional. Default value memory.New()
|
||||
Storage fiber.Storage
|
||||
|
||||
// Name of the session cookie. This cookie will store session key.
|
||||
// Optional. Default value "session_id".
|
||||
CookieName string
|
||||
|
||||
// Domain of the cookie.
|
||||
// Optional. Default value "".
|
||||
CookieDomain string
|
||||
|
||||
// Path of the cookie.
|
||||
// Optional. Default value "".
|
||||
CookiePath string
|
||||
|
||||
// Indicates if cookie is secure.
|
||||
// Optional. Default value false.
|
||||
CookieSecure bool
|
||||
|
||||
// Indicates if cookie is HTTP only.
|
||||
// Optional. Default value false.
|
||||
CookieHTTPOnly bool
|
||||
|
||||
// Sets the cookie SameSite attribute.
|
||||
// Optional. Default value "Lax".
|
||||
CookieSameSite string
|
||||
|
||||
// KeyGenerator generates the session key.
|
||||
// Optional. Default value utils.UUID
|
||||
KeyGenerator func() string
|
||||
}
|
||||
```
|
||||
|
||||
## Default Config
|
||||
|
||||
```go
|
||||
var ConfigDefault = Config{
|
||||
Expiration: 24 * time.Hour,
|
||||
CookieName: "session_id",
|
||||
KeyGenerator: utils.UUID,
|
||||
}
|
||||
```
|
|
@ -0,0 +1,25 @@
|
|||
---
|
||||
id: skip
|
||||
title: Skip
|
||||
---
|
||||
|
||||
Skip middleware for [Fiber](https://github.com/gofiber/fiber) that skips a wrapped handler if a predicate is true.
|
||||
|
||||
### Signatures
|
||||
```go
|
||||
func New(handler fiber.Handler, exclude func(c *fiber.Ctx) bool) 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/skip"
|
||||
)
|
||||
```
|
||||
|
||||
After you initiate your Fiber app, you can use the following possibilities:
|
||||
```go
|
||||
app.Use(skip.New(handler, func(ctx *fiber.Ctx) bool { return ctx.Method() == fiber.MethodOptions }))
|
||||
```
|
|
@ -0,0 +1,128 @@
|
|||
---
|
||||
id: timeout
|
||||
title: Timeout
|
||||
---
|
||||
|
||||
Timeout middleware for [Fiber](https://github.com/gofiber/fiber). As a `fiber.Handler` wrapper, it creates a context with `context.WithTimeout` and pass it in `UserContext`. If the context passed executions (eg. DB ops, Http calls) takes longer than the given duration to return, the timeout error is set and forwarded to the centralized `ErrorHandler`.
|
||||
|
||||
It does not cancel long running executions. Underlying executions must handle timeout by using `context.Context` parameter.
|
||||
|
||||
## Signatures
|
||||
|
||||
```go
|
||||
func New(handler fiber.Handler, timeout time.Duration, timeoutErrors ...error) 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/timeout"
|
||||
)
|
||||
```
|
||||
|
||||
Sample timeout middleware usage:
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
h := func(c *fiber.Ctx) error {
|
||||
sleepTime, _ := time.ParseDuration(c.Params("sleepTime") + "ms")
|
||||
if err := sleepWithContext(c.UserContext(), sleepTime); err != nil {
|
||||
return fmt.Errorf("%w: execution error", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
app.Get("/foo/:sleepTime", timeout.New(h, 2*time.Second))
|
||||
_ = app.Listen(":3000")
|
||||
}
|
||||
|
||||
func sleepWithContext(ctx context.Context, d time.Duration) error {
|
||||
timer := time.NewTimer(d)
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
if !timer.Stop() {
|
||||
<-timer.C
|
||||
}
|
||||
return context.DeadlineExceeded
|
||||
case <-timer.C:
|
||||
}
|
||||
return nil
|
||||
}
|
||||
```
|
||||
|
||||
Test http 200 with curl:
|
||||
|
||||
```bash
|
||||
curl --location -I --request GET 'http://localhost:3000/foo/1000'
|
||||
```
|
||||
|
||||
Test http 408 with curl:
|
||||
|
||||
```bash
|
||||
curl --location -I --request GET 'http://localhost:3000/foo/3000'
|
||||
```
|
||||
|
||||
Use with custom error:
|
||||
|
||||
```go
|
||||
var ErrFooTimeOut = errors.New("foo context canceled")
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
h := func(c *fiber.Ctx) error {
|
||||
sleepTime, _ := time.ParseDuration(c.Params("sleepTime") + "ms")
|
||||
if err := sleepWithContextWithCustomError(c.UserContext(), sleepTime); err != nil {
|
||||
return fmt.Errorf("%w: execution error", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
app.Get("/foo/:sleepTime", timeout.New(h, 2*time.Second, ErrFooTimeOut))
|
||||
_ = app.Listen(":3000")
|
||||
}
|
||||
|
||||
func sleepWithContextWithCustomError(ctx context.Context, d time.Duration) error {
|
||||
timer := time.NewTimer(d)
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
if !timer.Stop() {
|
||||
<-timer.C
|
||||
}
|
||||
return ErrFooTimeOut
|
||||
case <-timer.C:
|
||||
}
|
||||
return nil
|
||||
}
|
||||
```
|
||||
|
||||
Sample usage with a DB call:
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
db, _ := gorm.Open(postgres.Open("postgres://localhost/foodb"), &gorm.Config{})
|
||||
|
||||
handler := func(ctx *fiber.Ctx) error {
|
||||
tran := db.WithContext(ctx.UserContext()).Begin()
|
||||
|
||||
if tran = tran.Exec("SELECT pg_sleep(50)"); tran.Error != nil {
|
||||
return tran.Error
|
||||
}
|
||||
|
||||
if tran = tran.Commit(); tran.Error != nil {
|
||||
return tran.Error
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
app.Get("/foo", timeout.New(handler, 10*time.Second))
|
||||
app.Listen(":3000")
|
||||
}
|
||||
```
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"label": "Extra",
|
||||
"position": 4,
|
||||
"link": {
|
||||
"type": "generated-index",
|
||||
"description": "Extra contents for Fiber."
|
||||
}
|
||||
}
|
|
@ -0,0 +1,112 @@
|
|||
---
|
||||
id: benchmarks
|
||||
title: 📊 Benchmarks
|
||||
description: >-
|
||||
These benchmarks aim to compare the performance of Fiber and other web
|
||||
frameworks.
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
## TechEmpower
|
||||
|
||||
[TechEmpower](https://www.techempower.com/benchmarks/#section=data-r19&hw=ph&test=composite) provides a performance comparison of many web application frameworks executing fundamental tasks such as JSON serialization, database access, and server-side template composition.
|
||||
|
||||
Each framework is operating in a realistic production configuration. Results are captured on cloud instances and on physical hardware. The test implementations are largely community-contributed and all source is available at the [GitHub repository](https://github.com/TechEmpower/FrameworkBenchmarks).
|
||||
|
||||
* Fiber `v1.10.0`
|
||||
* 28 HT Cores Intel\(R\) Xeon\(R\) Gold 5120 CPU @ 2.20GHz
|
||||
* 32GB RAM
|
||||
* Ubuntu 18.04.3 4.15.0-88-generic
|
||||
* Dedicated Cisco 10-Gbit Ethernet switch.
|
||||
|
||||
### Plaintext
|
||||
|
||||
The Plaintext test is an exercise of the request-routing fundamentals only, designed to demonstrate the capacity of high-performance platforms in particular. Requests will be sent using HTTP pipelining. The response payload is still small, meaning good performance is still necessary in order to saturate the gigabit Ethernet of the test environment.
|
||||
|
||||
See [Plaintext requirements](https://github.com/TechEmpower/FrameworkBenchmarks/wiki/Project-Information-Framework-Tests-Overview#single-database-query)
|
||||
|
||||
**Fiber** - **6,162,556** responses per second with an average latency of **2.0** ms.
|
||||
**Express** - **367,069** responses per second with an average latency of **354.1** ms.
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
### Data Updates
|
||||
|
||||
**Fiber** handled **11,846** responses per second with an average latency of **42.8** ms.
|
||||
**Express** handled **2,066** responses per second with an average latency of **390.44** ms.
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
### Multiple Queries
|
||||
|
||||
**Fiber** handled **19,664** responses per second with an average latency of **25.7** ms.
|
||||
**Express** handled **4,302** responses per second with an average latency of **117.2** ms.
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
### Single Query
|
||||
|
||||
**Fiber** handled **368,647** responses per second with an average latency of **0.7** ms.
|
||||
**Express** handled **57,880** responses per second with an average latency of **4.4** ms.
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
### JSON Serialization
|
||||
|
||||
**Fiber** handled **1,146,667** responses per second with an average latency of **0.4** ms.
|
||||
**Express** handled **244,847** responses per second with an average latency of **1.1** ms.
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
## Go web framework benchmark
|
||||
|
||||
🔗 [https://github.com/smallnest/go-web-framework-benchmark](https://github.com/smallnest/go-web-framework-benchmark)
|
||||
|
||||
* **CPU** Intel\(R\) Xeon\(R\) Gold 6140 CPU @ 2.30GHz
|
||||
* **MEM** 4GB
|
||||
* **GO** go1.13.6 linux/amd64
|
||||
* **OS** Linux
|
||||
|
||||
The first test case is to mock **0 ms**, **10 ms**, **100 ms**, **500 ms** processing time in handlers.
|
||||
|
||||

|
||||
|
||||
The concurrency clients are **5000**.
|
||||
|
||||

|
||||
|
||||
Latency is the time of real processing time by web servers. _The smaller is the better._
|
||||
|
||||

|
||||
|
||||
Allocs is the heap allocations by web servers when test is running. The unit is MB. _The smaller is the better._
|
||||
|
||||
If we enable **http pipelining**, test result as below:
|
||||
|
||||

|
||||
|
||||
Concurrency test in **30 ms** processing time, the test result for **100**, **1000**, **5000** clients is:
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
If we enable **http pipelining**, test result as below:
|
||||
|
||||

|
||||
|
||||
Dependency graph for `v1.9.0`
|
||||
|
||||

|
|
@ -0,0 +1,67 @@
|
|||
---
|
||||
id: faq
|
||||
title: 🤔 FAQ
|
||||
description: >-
|
||||
List of frequently asked questions. Feel free to open an issue to add your
|
||||
question to this page.
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
## How should I structure my application?
|
||||
|
||||
There is no definitive answer to this question. The answer depends on the scale of your application and the team that is involved. To be as flexible as possible, Fiber makes no assumptions in terms of structure.
|
||||
|
||||
Routes and other application-specific logic can live in as many files as you wish, in any directory structure you prefer. View the following examples for inspiration:
|
||||
|
||||
* [gofiber/boilerplate](https://github.com/gofiber/boilerplate)
|
||||
* [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
|
||||
* [Youtube - Building a REST API using Gorm and Fiber](https://www.youtube.com/watch?v=Iq2qT0fRhAA)
|
||||
* [embedmode/fiberseed](https://github.com/embedmode/fiberseed)
|
||||
|
||||
## How do I handle custom 404 responses?
|
||||
|
||||
If you're using v2.32.0 or later, all you need to do is to implement a custom error handler. See below, or see a more detailed explanation at [Error Handling](../guide/error-handling.md#custom-error-handler).
|
||||
|
||||
If you're using v2.31.0 or earlier, the error handler will not capture 404 errors. Instead, you need to add a middleware function at the very bottom of the stack \(below all other functions\) to handle a 404 response:
|
||||
|
||||
```go title="Example"
|
||||
app.Use(func(c *fiber.Ctx) error {
|
||||
return c.Status(fiber.StatusNotFound).SendString("Sorry can't find that!")
|
||||
})
|
||||
```
|
||||
|
||||
## How do I set up an error handler?
|
||||
|
||||
To override the default error handler, you can override the default when providing a [Config](../api/fiber.md#config) when initiating a new [Fiber instance](../api/fiber.md#new).
|
||||
|
||||
```go title="Example"
|
||||
app := fiber.New(fiber.Config{
|
||||
ErrorHandler: func(c *fiber.Ctx, err error) error {
|
||||
return c.Status(fiber.StatusInternalServerError).SendString(err.Error())
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
We have a dedicated page explaining how error handling works in Fiber, see [Error Handling](../guide/error-handling.md).
|
||||
|
||||
## Which template engines does Fiber support?
|
||||
|
||||
Fiber currently supports 8 template engines in our [gofiber/template](https://github.com/gofiber/template) middleware:
|
||||
|
||||
* [Ace](https://github.com/yosssi/ace)
|
||||
* [Amber](https://github.com/eknkc/amber)
|
||||
* [Django](https://github.com/flosch/pongo2)
|
||||
* [Handlebars](https://github.com/aymerick/raymond)
|
||||
* [HTML](https://pkg.go.dev/html/template/)
|
||||
* [Jet](https://github.com/CloudyKit/jet)
|
||||
* [Mustache](https://github.com/cbroglie/mustache)
|
||||
* [Pug](https://github.com/Joker/jade)
|
||||
|
||||
To learn more about using Templates in Fiber, see [Templates](../guide/templates.md).
|
||||
|
||||
## Does Fiber have a community chat?
|
||||
|
||||
Yes, we have our own [Discord ](https://gofiber.io/discord)server, where we hang out. We have different rooms for every subject.
|
||||
If you have questions or just want to have a chat, feel free to join us via this **>** [**invite link**](https://gofiber.io/discord) **<**.
|
||||
|
||||

|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"label": "Guide",
|
||||
"position": 3,
|
||||
"link": {
|
||||
"type": "generated-index",
|
||||
"description": "Guides for Fiber."
|
||||
}
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
---
|
||||
id: error-handling
|
||||
title: 🐛 Error Handling
|
||||
description: >-
|
||||
Fiber supports centralized error handling by returning an error to the handler
|
||||
which allows you to log errors to external services or send a customized HTTP
|
||||
response to the client.
|
||||
sidebar_position: 4
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
## Catching Errors
|
||||
|
||||
It’s essential to ensure that Fiber catches all errors that occur while running route handlers and middleware. You must return them to the handler function, where Fiber will catch and process them.
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="example" label="Example">
|
||||
|
||||
```go
|
||||
app.Get("/", func(c *fiber.Ctx) error {
|
||||
// Pass error to Fiber
|
||||
return c.SendFile("file-does-not-exist")
|
||||
})
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Fiber does not handle [panics](https://go.dev/blog/defer-panic-and-recover) by default. To recover from a panic thrown by any handler in the stack, you need to include the `Recover` middleware below:
|
||||
|
||||
```go title="Example"
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"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("This panic is caught by fiber")
|
||||
})
|
||||
|
||||
log.Fatal(app.Listen(":3000"))
|
||||
}
|
||||
```
|
||||
|
||||
You could use Fiber's custom error struct to pass an additional `status code` using `fiber.NewError()`. It's optional to pass a message; if this is left empty, it will default to the status code message \(`404` equals `Not Found`\).
|
||||
|
||||
```go title="Example"
|
||||
app.Get("/", func(c *fiber.Ctx) error {
|
||||
// 503 Service Unavailable
|
||||
return fiber.ErrServiceUnavailable
|
||||
|
||||
// 503 On vacation!
|
||||
return fiber.NewError(fiber.StatusServiceUnavailable, "On vacation!")
|
||||
})
|
||||
```
|
||||
|
||||
## Default Error Handler
|
||||
|
||||
Fiber provides an error handler by default. For a standard error, the response is sent as **500 Internal Server Error**. If the error is of type [fiber.Error](https://godoc.org/github.com/gofiber/fiber#Error), the response is sent with the provided status code and message.
|
||||
|
||||
```go title="Example"
|
||||
// Default error handler
|
||||
var DefaultErrorHandler = func(c *fiber.Ctx, err error) error {
|
||||
// Status code defaults to 500
|
||||
code := fiber.StatusInternalServerError
|
||||
|
||||
// Retrieve the custom status code if it's a *fiber.Error
|
||||
var e *fiber.Error
|
||||
if errors.As(err, &e) {
|
||||
code = e.Code
|
||||
}
|
||||
|
||||
// Set Content-Type: text/plain; charset=utf-8
|
||||
c.Set(fiber.HeaderContentType, fiber.MIMETextPlainCharsetUTF8)
|
||||
|
||||
// Return status code with error message
|
||||
return c.Status(code).SendString(err.Error())
|
||||
}
|
||||
```
|
||||
|
||||
## Custom Error Handler
|
||||
|
||||
A custom error handler can be set using a [Config ](../api/fiber.md#config)when initializing a [Fiber instance](../api/fiber.md#new).
|
||||
|
||||
In most cases, the default error handler should be sufficient. However, a custom error handler can come in handy if you want to capture different types of errors and take action accordingly e.g., send a notification email or log an error to the centralized system. You can also send customized responses to the client e.g., error page or just a JSON response.
|
||||
|
||||
The following example shows how to display error pages for different types of errors.
|
||||
|
||||
```go title="Example"
|
||||
// Create a new fiber instance with custom config
|
||||
app := fiber.New(fiber.Config{
|
||||
// Override default error handler
|
||||
ErrorHandler: func(ctx *fiber.Ctx, err error) error {
|
||||
// Status code defaults to 500
|
||||
code := fiber.StatusInternalServerError
|
||||
|
||||
// Retrieve the custom status code if it's a *fiber.Error
|
||||
var e *fiber.Error
|
||||
if errors.As(err, &e) {
|
||||
code = e.Code
|
||||
}
|
||||
|
||||
// Send custom error page
|
||||
err = ctx.Status(code).SendFile(fmt.Sprintf("./%d.html", code))
|
||||
if err != nil {
|
||||
// In case the SendFile fails
|
||||
return ctx.Status(fiber.StatusInternalServerError).SendString("Internal Server Error")
|
||||
}
|
||||
|
||||
// Return from handler
|
||||
return nil
|
||||
},
|
||||
})
|
||||
|
||||
// ...
|
||||
```
|
||||
|
||||
> Special thanks to the [Echo](https://echo.labstack.com/) & [Express](https://expressjs.com/) framework for inspiration regarding error handling.
|
|
@ -0,0 +1,36 @@
|
|||
---
|
||||
id: faster-fiber
|
||||
title: ⚡ Make Fiber Faster
|
||||
sidebar_position: 7
|
||||
---
|
||||
|
||||
## Custom JSON Encoder/Decoder
|
||||
Since Fiber v2.32.0, we use **encoding/json** as default json library due to stability and producibility. However, the standard library is a bit slow compared to 3rd party libraries. If you're not happy with the performance of **encoding/json**, we recommend you to use these libraries:
|
||||
- [goccy/go-json](https://github.com/goccy/go-json)
|
||||
- [bytedance/sonic](https://github.com/bytedance/sonic)
|
||||
- [segmentio/encoding](https://github.com/segmentio/encoding)
|
||||
- [mailru/easyjson](https://github.com/mailru/easyjson)
|
||||
- [minio/simdjson-go](https://github.com/minio/simdjson-go)
|
||||
- [wI2L/jettison](https://github.com/wI2L/jettison)
|
||||
|
||||
```go title="Example"
|
||||
package main
|
||||
|
||||
import "github.com/gofiber/fiber/v2"
|
||||
import "github.com/goccy/go-json"
|
||||
|
||||
func main() {
|
||||
app := fiber.New(fiber.Config{
|
||||
JSONEncoder: json.Marshal,
|
||||
JSONDecoder: json.Unmarshal,
|
||||
})
|
||||
|
||||
# ...
|
||||
}
|
||||
```
|
||||
|
||||
### References
|
||||
- [Set custom JSON encoder for client](../api/client.md#jsonencoder)
|
||||
- [Set custom JSON decoder for client](../api/client.md#jsondecoder)
|
||||
- [Set custom JSON encoder for application](../api/fiber.md#config)
|
||||
- [Set custom JSON decoder for application](../api/fiber.md#config)
|
|
@ -0,0 +1,75 @@
|
|||
---
|
||||
id: grouping
|
||||
title: 🎭 Grouping
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
## Paths
|
||||
|
||||
Like **Routing**, groups can also have paths that belong to a cluster.
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
api := app.Group("/api", middleware) // /api
|
||||
|
||||
v1 := api.Group("/v1", middleware) // /api/v1
|
||||
v1.Get("/list", handler) // /api/v1/list
|
||||
v1.Get("/user", handler) // /api/v1/user
|
||||
|
||||
v2 := api.Group("/v2", middleware) // /api/v2
|
||||
v2.Get("/list", handler) // /api/v2/list
|
||||
v2.Get("/user", handler) // /api/v2/user
|
||||
|
||||
log.Fatal(app.Listen(":3000"))
|
||||
}
|
||||
```
|
||||
|
||||
A **Group** of paths can have an optional handler.
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
api := app.Group("/api") // /api
|
||||
|
||||
v1 := api.Group("/v1") // /api/v1
|
||||
v1.Get("/list", handler) // /api/v1/list
|
||||
v1.Get("/user", handler) // /api/v1/user
|
||||
|
||||
v2 := api.Group("/v2") // /api/v2
|
||||
v2.Get("/list", handler) // /api/v2/list
|
||||
v2.Get("/user", handler) // /api/v2/user
|
||||
|
||||
log.Fatal(app.Listen(":3000"))
|
||||
}
|
||||
```
|
||||
|
||||
:::caution
|
||||
Running **/api**, **/v1** or **/v2** will result in **404** error, make sure you have the errors set.
|
||||
:::
|
||||
|
||||
## Group Handlers
|
||||
|
||||
Group handlers can also be used as a routing path but they must have **Next** added to them so that the flow can continue.
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
handler := func(c *fiber.Ctx) error {
|
||||
return c.SendStatus(fiber.StatusOK)
|
||||
}
|
||||
api := app.Group("/api") // /api
|
||||
|
||||
v1 := api.Group("/v1", func(c *fiber.Ctx) error { // middleware for /api/v1
|
||||
c.Set("Version", "v1")
|
||||
return c.Next()
|
||||
})
|
||||
v1.Get("/list", handler) // /api/v1/list
|
||||
v1.Get("/user", handler) // /api/v1/user
|
||||
|
||||
log.Fatal(app.Listen(":3000"))
|
||||
}
|
||||
```
|
|
@ -0,0 +1,192 @@
|
|||
---
|
||||
id: hooks
|
||||
title: 🪝 Hooks
|
||||
sidebar_position: 6
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
With Fiber v2.30.0, you can execute custom user functions when to run some methods. Here is a list of this hooks:
|
||||
- [OnRoute](#onroute)
|
||||
- [OnName](#onname)
|
||||
- [OnGroup](#ongroup)
|
||||
- [OnGroupName](#ongroupname)
|
||||
- [OnListen](#onlisten)
|
||||
- [OnFork](#onfork)
|
||||
- [OnShutdown](#onshutdown)
|
||||
- [OnMount](#onmount)
|
||||
|
||||
## Constants
|
||||
```go
|
||||
// Handlers define a function to create hooks for Fiber.
|
||||
type OnRouteHandler = func(Route) error
|
||||
type OnNameHandler = OnRouteHandler
|
||||
type OnGroupHandler = func(Group) error
|
||||
type OnGroupNameHandler = OnGroupHandler
|
||||
type OnListenHandler = func() error
|
||||
type OnForkHandler = func(int) error
|
||||
type OnShutdownHandler = OnListenHandler
|
||||
type OnMountHandler = func(*App) error
|
||||
```
|
||||
|
||||
## OnRoute
|
||||
|
||||
OnRoute is a hook to execute user functions on each route registeration. Also you can get route properties by **route** parameter.
|
||||
|
||||
```go title="Signature"
|
||||
func (app *App) OnRoute(handler ...OnRouteHandler)
|
||||
```
|
||||
|
||||
## OnName
|
||||
|
||||
OnName is a hook to execute user functions on each route naming. Also you can get route properties by **route** parameter.
|
||||
|
||||
:::caution
|
||||
OnName only works with naming routes, not groups.
|
||||
:::
|
||||
|
||||
```go title="Signature"
|
||||
func (app *App) OnName(handler ...OnNameHandler)
|
||||
```
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="onname-example" label="OnName Example">
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) error {
|
||||
return c.SendString(c.Route().Name)
|
||||
}).Name("index")
|
||||
|
||||
app.Hooks().OnName(func(r fiber.Route) error {
|
||||
fmt.Print("Name: " + r.Name + ", ")
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
app.Hooks().OnName(func(r fiber.Route) error {
|
||||
fmt.Print("Method: " + r.Method + "\n")
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
app.Get("/add/user", func(c *fiber.Ctx) error {
|
||||
return c.SendString(c.Route().Name)
|
||||
}).Name("addUser")
|
||||
|
||||
app.Delete("/destroy/user", func(c *fiber.Ctx) error {
|
||||
return c.SendString(c.Route().Name)
|
||||
}).Name("destroyUser")
|
||||
|
||||
app.Listen(":5000")
|
||||
}
|
||||
|
||||
// Results:
|
||||
// Name: addUser, Method: GET
|
||||
// Name: destroyUser, Method: DELETE
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## OnGroup
|
||||
|
||||
OnGroup is a hook to execute user functions on each group registeration. Also you can get group properties by **group** parameter.
|
||||
|
||||
```go title="Signature"
|
||||
func (app *App) OnGroup(handler ...OnGroupHandler)
|
||||
```
|
||||
|
||||
## OnGroupName
|
||||
|
||||
OnGroupName is a hook to execute user functions on each group naming. Also you can get group properties by **group** parameter.
|
||||
|
||||
:::caution
|
||||
OnGroupName only works with naming groups, not routes.
|
||||
:::
|
||||
|
||||
```go title="Signature"
|
||||
func (app *App) OnGroupName(handler ...OnGroupNameHandler)
|
||||
```
|
||||
|
||||
## OnListen
|
||||
|
||||
OnListen is a hook to execute user functions on Listen, ListenTLS, Listener.
|
||||
|
||||
```go title="Signature"
|
||||
func (app *App) OnListen(handler ...OnListenHandler)
|
||||
```
|
||||
|
||||
## OnFork
|
||||
|
||||
OnFork is a hook to execute user functions on Fork.
|
||||
|
||||
```go title="Signature"
|
||||
func (app *App) OnFork(handler ...OnForkHandler)
|
||||
```
|
||||
|
||||
## OnShutdown
|
||||
|
||||
OnShutdown is a hook to execute user functions after Shutdown.
|
||||
|
||||
```go title="Signature"
|
||||
func (app *App) OnShutdown(handler ...OnShutdownHandler)
|
||||
```
|
||||
|
||||
## OnMount
|
||||
|
||||
OnMount is a hook to execute user function after mounting process. The mount event is fired when sub-app is mounted on a parent app. The parent app is passed as a parameter. It works for app and group mounting.
|
||||
|
||||
```go title="Signature"
|
||||
func (h *Hooks) OnMount(handler ...OnMountHandler)
|
||||
```
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="onmount-example" label="OnMount Example">
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := New()
|
||||
app.Get("/", testSimpleHandler).Name("x")
|
||||
|
||||
subApp := New()
|
||||
subApp.Get("/test", testSimpleHandler)
|
||||
|
||||
subApp.Hooks().OnMount(func(parent *fiber.App) error {
|
||||
fmt.Print("Mount path of parent app: "+parent.MountPath())
|
||||
// ...
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
app.Mount("/sub", subApp)
|
||||
}
|
||||
|
||||
// Result:
|
||||
// Mount path of parent app:
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
|
||||
:::caution
|
||||
OnName/OnRoute/OnGroup/OnGroupName hooks are mount-sensitive. If you use one of these routes on sub app and you mount it; paths of routes and groups will start with mount prefix.
|
|
@ -0,0 +1,285 @@
|
|||
---
|
||||
id: routing
|
||||
title: 🔌 Routing
|
||||
description: >-
|
||||
Routing refers to how an application's endpoints (URIs) respond to client
|
||||
requests.
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import RoutingHandler from './../partials/routing/handler.md';
|
||||
|
||||
## Handlers
|
||||
|
||||
<RoutingHandler />
|
||||
|
||||
## Paths
|
||||
|
||||
Route paths, combined with a request method, define the endpoints at which requests can be made. Route paths can be **strings** or **string patterns**.
|
||||
|
||||
**Examples of route paths based on strings**
|
||||
|
||||
```go
|
||||
// This route path will match requests to the root route, "/":
|
||||
app.Get("/", func(c *fiber.Ctx) error {
|
||||
return c.SendString("root")
|
||||
})
|
||||
|
||||
// This route path will match requests to "/about":
|
||||
app.Get("/about", func(c *fiber.Ctx) error {
|
||||
return c.SendString("about")
|
||||
})
|
||||
|
||||
// This route path will match requests to "/random.txt":
|
||||
app.Get("/random.txt", func(c *fiber.Ctx) error {
|
||||
return c.SendString("random.txt")
|
||||
})
|
||||
```
|
||||
|
||||
As with the expressJs framework, the order of the route declaration plays a role.
|
||||
When a request is received, the routes are checked in the order in which they are declared.
|
||||
|
||||
:::info
|
||||
So please be careful to write routes with variable parameters after the routes that contain fixed parts, so that these variable parts do not match instead and unexpected behavior occurs.
|
||||
:::
|
||||
|
||||
## Parameters
|
||||
|
||||
Route parameters are dynamic elements in the route, which are **named** or **not named segments**. This segments that are used to capture the values specified at their position in the URL. The obtained values can be retrieved using the [Params](https://fiber.wiki/context#params) function, with the name of the route parameter specified in the path as their respective keys or for unnamed parameters the character\(\*, +\) and the counter of this.
|
||||
|
||||
The characters :, +, and \* are characters that introduce a parameter.
|
||||
|
||||
Greedy parameters are indicated by wildcard\(\*\) or plus\(+\) signs.
|
||||
|
||||
The routing also offers the possibility to use optional parameters, for the named parameters these are marked with a final "?", unlike the plus sign which is not optional, you can use the wildcard character for a parameter range which is optional and greedy.
|
||||
|
||||
**Example of define routes with route parameters**
|
||||
|
||||
```go
|
||||
// Parameters
|
||||
app.Get("/user/:name/books/:title", func(c *fiber.Ctx) error {
|
||||
fmt.Fprintf(c, "%s\n", c.Params("name"))
|
||||
fmt.Fprintf(c, "%s\n", c.Params("title"))
|
||||
return nil
|
||||
})
|
||||
// Plus - greedy - not optional
|
||||
app.Get("/user/+", func(c *fiber.Ctx) error {
|
||||
return c.SendString(c.Params("+"))
|
||||
})
|
||||
|
||||
// Optional parameter
|
||||
app.Get("/user/:name?", func(c *fiber.Ctx) error {
|
||||
return c.SendString(c.Params("name"))
|
||||
})
|
||||
|
||||
// Wildcard - greedy - optional
|
||||
app.Get("/user/*", func(c *fiber.Ctx) error {
|
||||
return c.SendString(c.Params("*"))
|
||||
})
|
||||
|
||||
// This route path will match requests to "/v1/some/resource/name:customVerb", since the parameter character is escaped
|
||||
app.Get("/v1/some/resource/name\\:customVerb", func(c *fiber.Ctx) error {
|
||||
return c.SendString("Hello, Community")
|
||||
})
|
||||
```
|
||||
|
||||
:::info
|
||||
Since the hyphen \(`-`\) and the dot \(`.`\) are interpreted literally, they can be used along with route parameters for useful purposes.
|
||||
:::
|
||||
|
||||
:::info
|
||||
All special parameter characters can also be escaped with `"\\"` and lose their value, so you can use them in the route if you want, like in the custom methods of the [google api design guide](https://cloud.google.com/apis/design/custom_methods).
|
||||
:::
|
||||
|
||||
```go
|
||||
// http://localhost:3000/plantae/prunus.persica
|
||||
app.Get("/plantae/:genus.:species", func(c *fiber.Ctx) error {
|
||||
fmt.Fprintf(c, "%s.%s\n", c.Params("genus"), c.Params("species"))
|
||||
return nil // prunus.persica
|
||||
})
|
||||
```
|
||||
|
||||
```go
|
||||
// http://localhost:3000/flights/LAX-SFO
|
||||
app.Get("/flights/:from-:to", func(c *fiber.Ctx) error {
|
||||
fmt.Fprintf(c, "%s-%s\n", c.Params("from"), c.Params("to"))
|
||||
return nil // LAX-SFO
|
||||
})
|
||||
```
|
||||
|
||||
Our intelligent router recognizes that the introductory parameter characters should be part of the request route in this case and can process them as such.
|
||||
|
||||
```go
|
||||
// http://localhost:3000/shop/product/color:blue/size:xs
|
||||
app.Get("/shop/product/color::color/size::size", func(c *fiber.Ctx) error {
|
||||
fmt.Fprintf(c, "%s:%s\n", c.Params("color"), c.Params("size"))
|
||||
return nil // blue:xs
|
||||
})
|
||||
```
|
||||
|
||||
In addition, several parameters in a row and several unnamed parameter characters in the route, such as the wildcard or plus character, are possible, which greatly expands the possibilities of the router for the user.
|
||||
|
||||
```go
|
||||
// GET /@v1
|
||||
// Params: "sign" -> "@", "param" -> "v1"
|
||||
app.Get("/:sign:param", handler)
|
||||
|
||||
// GET /api-v1
|
||||
// Params: "name" -> "v1"
|
||||
app.Get("/api-:name", handler)
|
||||
|
||||
// GET /customer/v1/cart/proxy
|
||||
// Params: "*1" -> "customer/", "*2" -> "/cart"
|
||||
app.Get("/*v1*/proxy", handler)
|
||||
|
||||
// GET /v1/brand/4/shop/blue/xs
|
||||
// Params: "*1" -> "brand/4", "*2" -> "blue/xs"
|
||||
app.Get("/v1/*/shop/*", handler)
|
||||
```
|
||||
|
||||
We have adapted the routing strongly to the express routing, but currently without the possibility of the regular expressions, because they are quite slow. The possibilities can be tested with version 0.1.7 \(express 4\) in the online [Express route tester](http://forbeslindesay.github.io/express-route-tester/).
|
||||
|
||||
### Constraints
|
||||
Route constraints execute when a match has occurred to the incoming URL and the URL path is tokenized into route values by parameters. The feature was intorduced in `v2.37.0` and inspired by [.NET Core](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/routing?view=aspnetcore-6.0#route-constraints).
|
||||
|
||||
:::caution
|
||||
Constraints aren't validation for parameters. If constraint aren't valid for parameter value, Fiber returns **404 handler**.
|
||||
:::
|
||||
|
||||
| Constraint | Example | Example matches |
|
||||
| ----------------- | ------------------------------------ | ------------------------------------------------------------------------------------------- |
|
||||
| int | :id<int\> | 123456789, -123456789 |
|
||||
| bool | :active<bool\> | true,false |
|
||||
| guid | :id<guid\> | CD2C1638-1638-72D5-1638-DEADBEEF1638 |
|
||||
| float | :weight<float\> | 1.234, -1,001.01e8 |
|
||||
| minLen(value) | :username<minLen(4)\> | Test (must be at least 4 characters) |
|
||||
| maxLen(value) | :filename<maxLen(8)\> | MyFile (must be no more than 8 characters |
|
||||
| len(length) | :filename<len(12)\> | somefile.txt (exactly 12 characters) |
|
||||
| min(value) | :age<min(18)\> | 19 (Integer value must be at least 18) |
|
||||
| max(value) | :age<max(120)\> | 91 (Integer value must be no more than 120) |
|
||||
| range(min,max) | :age<range(18,120)\> | 91 (Integer value must be at least 18 but no more than 120) |
|
||||
| alpha | :name<alpha\> | Rick (String must consist of one or more alphabetical characters, a-z and case-insensitive) |
|
||||
| datetime | :dob<datetime(2006\\\\-01\\\\-02)\> | 2005-11-01 |
|
||||
| regex(expression) | :date<regex(\\d{4}-\\d{2}-\\d{2})}\> | 2022-08-27 (Must match regular expression) |
|
||||
|
||||
**Examples**
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="single-constraint" label="Single Constraint">
|
||||
|
||||
```go
|
||||
app.Get("/:test<min(5)>", func(c *fiber.Ctx) error {
|
||||
return c.SendString(c.Params("test"))
|
||||
})
|
||||
|
||||
// curl -X GET http://localhost:3000/12
|
||||
// 12
|
||||
|
||||
// curl -X GET http://localhost:3000/1
|
||||
// Cannot GET /1
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="multiple-constraints" label="Multiple Constraints">
|
||||
|
||||
You can use `;` for multiple constraints.
|
||||
```go
|
||||
app.Get("/:test<min(100);maxLen(5)>", func(c *fiber.Ctx) error {
|
||||
return c.SendString(c.Params("test"))
|
||||
})
|
||||
|
||||
// curl -X GET http://localhost:3000/120000
|
||||
// Cannot GET /120000
|
||||
|
||||
// curl -X GET http://localhost:3000/1
|
||||
// Cannot GET /1
|
||||
|
||||
// curl -X GET http://localhost:3000/250
|
||||
// 250
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="regex-constraint" label="Regex Constraint">
|
||||
|
||||
Fiber precompiles regex query when to register routes. So there're no performance overhead for regex constraint.
|
||||
```go
|
||||
app.Get("/:date<regex(\\d{4}-\\d{2}-\\d{2})}>", func(c *fiber.Ctx) error {
|
||||
return c.SendString(c.Params("date"))
|
||||
})
|
||||
|
||||
// curl -X GET http://localhost:3000/125
|
||||
// Cannot GET /125
|
||||
|
||||
// curl -X GET http://localhost:3000/test
|
||||
// Cannot GET /test
|
||||
|
||||
// curl -X GET http://localhost:3000/2022-08-27
|
||||
// 2022-08-27
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
:::caution
|
||||
You should use `\\` before routing-specific characters when to use datetime constraint (`*`, `+`, `?`, `:`, `/`, `<`, `>`, `;`, `(`, `)`), to avoid wrong parsing.
|
||||
:::
|
||||
|
||||
**Optional Parameter Example**
|
||||
|
||||
You can impose constraints on optional parameters as well.
|
||||
|
||||
```go
|
||||
app.Get("/:test<int>?", func(c *fiber.Ctx) error {
|
||||
return c.SendString(c.Params("test"))
|
||||
})
|
||||
// curl -X GET http://localhost:3000/42
|
||||
// 42
|
||||
// curl -X GET http://localhost:3000/
|
||||
//
|
||||
// curl -X GET http://localhost:3000/7.0
|
||||
// Cannot GET /7.0
|
||||
```
|
||||
|
||||
## Middleware
|
||||
|
||||
Functions that are designed to make changes to the request or response are called **middleware functions**. The [Next](../api/ctx.md#next) is a **Fiber** router function, when called, executes the **next** function that **matches** the current route.
|
||||
|
||||
**Example of a middleware function**
|
||||
|
||||
```go
|
||||
app.Use(func(c *fiber.Ctx) error {
|
||||
// Set a custom header on all responses:
|
||||
c.Set("X-Custom-Header", "Hello, World")
|
||||
|
||||
// Go to next middleware:
|
||||
return c.Next()
|
||||
})
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) error {
|
||||
return c.SendString("Hello, World!")
|
||||
})
|
||||
```
|
||||
|
||||
`Use` method path is a **mount**, or **prefix** path, and limits middleware to only apply to any paths requested that begin with it.
|
||||
|
||||
## Grouping
|
||||
|
||||
If you have many endpoints, you can organize your routes using `Group`.
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
api := app.Group("/api", middleware) // /api
|
||||
|
||||
v1 := api.Group("/v1", middleware) // /api/v1
|
||||
v1.Get("/list", handler) // /api/v1/list
|
||||
v1.Get("/user", handler) // /api/v1/user
|
||||
|
||||
v2 := api.Group("/v2", middleware) // /api/v2
|
||||
v2.Get("/list", handler) // /api/v2/list
|
||||
v2.Get("/user", handler) // /api/v2/user
|
||||
|
||||
log.Fatal(app.Listen(":3000"))
|
||||
}
|
||||
```
|
|
@ -0,0 +1,105 @@
|
|||
---
|
||||
id: templates
|
||||
title: 📝 Templates
|
||||
description: Fiber supports server-side template engines.
|
||||
sidebar_position: 3
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
## Template interfaces
|
||||
|
||||
Fiber provides a Views interface to provide your own template engine:
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="views" label="Views">
|
||||
|
||||
```go
|
||||
type Views interface {
|
||||
Load() error
|
||||
Render(io.Writer, string, interface{}, ...string) error
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
`Views` interface contains a `Load` and `Render` method, `Load` is executed by Fiber on app initialization to load/parse the templates.
|
||||
|
||||
```go
|
||||
// Pass engine to Fiber's Views Engine
|
||||
app := fiber.New(fiber.Config{
|
||||
Views: engine,
|
||||
// Views Layout is the global layout for all template render until override on Render function.
|
||||
ViewsLayout: "layouts/main"
|
||||
})
|
||||
```
|
||||
|
||||
The `Render` method is linked to the [**ctx.Render\(\)**](../api/ctx.md#render) function that accepts a template name and binding data. It will use global layout if layout is not being defined in `Render` function.
|
||||
If the Fiber config option `PassLocalsToViews` is enabled, then all locals set using `ctx.Locals(key, value)` will be passed to the template.
|
||||
|
||||
```go
|
||||
app.Get("/", func(c *fiber.Ctx) error {
|
||||
return c.Render("index", fiber.Map{
|
||||
"hello": "world",
|
||||
});
|
||||
})
|
||||
```
|
||||
|
||||
## Engines
|
||||
|
||||
Fiber team maintains [templates](https://github.com/gofiber/template) package that provides wrappers for multiple template engines:
|
||||
|
||||
* [html](https://github.com/gofiber/template/tree/master/html)
|
||||
* [ace](https://github.com/gofiber/template/tree/master/ace)
|
||||
* [amber](https://github.com/gofiber/template/tree/master/amber)
|
||||
* [django](https://github.com/gofiber/template/tree/master/django)
|
||||
* [handlebars](https://github.com/gofiber/template/tree/master/handlebars)
|
||||
* [jet](https://github.com/gofiber/template/tree/master/jet)
|
||||
* [mustache](https://github.com/gofiber/template/tree/master/mustache)
|
||||
* [pug](https://github.com/gofiber/template/tree/master/pug)
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="example" label="Example">
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/template/html"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Initialize standard Go html template engine
|
||||
engine := html.New("./views", ".html")
|
||||
// If you want other engine, just replace with following
|
||||
// Create a new engine with django
|
||||
// engine := django.New("./views", ".django")
|
||||
|
||||
app := fiber.New(fiber.Config{
|
||||
Views: engine,
|
||||
})
|
||||
app.Get("/", func(c *fiber.Ctx) error {
|
||||
// Render index template
|
||||
return c.Render("index", fiber.Map{
|
||||
"Title": "Hello, World!",
|
||||
})
|
||||
})
|
||||
|
||||
log.Fatal(app.Listen(":3000"))
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="index" label="views/index.html">
|
||||
|
||||
```markup
|
||||
<!DOCTYPE html>
|
||||
<body>
|
||||
<h1>{{.Title}}</h1>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
|
@ -0,0 +1,83 @@
|
|||
---
|
||||
id: validation
|
||||
title: 🔎 Validation
|
||||
sidebar_position: 5
|
||||
---
|
||||
|
||||
## Validator package
|
||||
|
||||
Fiber can make _great_ use of the validator package to ensure correct validation of data to store.
|
||||
|
||||
* [Official validator Github page \(Installation, use, examples..\).](https://github.com/go-playground/validator)
|
||||
|
||||
You can find the detailed descriptions of the _validations_ used in the fields contained on the structs below:
|
||||
|
||||
* [Detailed docs](https://pkg.go.dev/github.com/go-playground/validator?tab=doc)
|
||||
|
||||
```go title="Validation Example"
|
||||
type Job struct{
|
||||
Type string `validate:"required,min=3,max=32"`
|
||||
Salary int `validate:"required,number"`
|
||||
}
|
||||
|
||||
type User struct{
|
||||
Name string `validate:"required,min=3,max=32"`
|
||||
// use `*bool` here otherwise the validation will fail for `false` values
|
||||
// Ref: https://github.com/go-playground/validator/issues/319#issuecomment-339222389
|
||||
IsActive *bool `validate:"required"`
|
||||
Email string `validate:"required,email,min=6,max=32"`
|
||||
Job Job `validate:"dive"`
|
||||
}
|
||||
|
||||
type ErrorResponse struct {
|
||||
FailedField string
|
||||
Tag string
|
||||
Value string
|
||||
}
|
||||
|
||||
var validate = validator.New()
|
||||
func ValidateStruct(user User) []*ErrorResponse {
|
||||
var errors []*ErrorResponse
|
||||
err := validate.Struct(user)
|
||||
if err != nil {
|
||||
for _, err := range err.(validator.ValidationErrors) {
|
||||
var element ErrorResponse
|
||||
element.FailedField = err.StructNamespace()
|
||||
element.Tag = err.Tag()
|
||||
element.Value = err.Param()
|
||||
errors = append(errors, &element)
|
||||
}
|
||||
}
|
||||
return errors
|
||||
}
|
||||
|
||||
func AddUser(c *fiber.Ctx) error {
|
||||
//Connect to database
|
||||
|
||||
user := new(User)
|
||||
|
||||
if err := c.BodyParser(user); err != nil {
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
|
||||
"message": err.Error(),
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
errors := ValidateStruct(*user)
|
||||
if errors != nil {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(errors)
|
||||
|
||||
}
|
||||
|
||||
//Do something else here
|
||||
|
||||
//Return user
|
||||
return c.JSON(user)
|
||||
}
|
||||
|
||||
// Running a test with the following curl commands
|
||||
// curl -X POST -H "Content-Type: application/json" --data "{\"name\":\"john\",\"isactive\":\"True\"}" http://localhost:8080/register/user
|
||||
|
||||
// Results in
|
||||
// [{"FailedField":"User.Email","Tag":"required","Value":""},{"FailedField":"User.Job.Salary","Tag":"required","Value":""},{"FailedField":"User.Job.Type","Tag":"required","Value":""}]⏎
|
||||
```
|
|
@ -0,0 +1,196 @@
|
|||
---
|
||||
slug: /
|
||||
id: welcome
|
||||
title: 👋 Welcome
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
An online API documentation with examples so you can start building web apps with Fiber right away!
|
||||
|
||||
**Fiber** is an [Express](https://github.com/expressjs/express) inspired **web framework** built on top of [Fasthttp](https://github.com/valyala/fasthttp), the **fastest** HTTP engine for [Go](https://go.dev/doc/). Designed to **ease** things up for **fast** development with **zero memory allocation** and **performance** in mind.
|
||||
|
||||
These docs are for **Fiber v2**, which was released on **September 15th, 2020**.
|
||||
|
||||
### Installation
|
||||
|
||||
First of all, [download](https://go.dev/dl/) and install Go. `1.16` or higher is required.
|
||||
|
||||
Installation is done using the [`go get`](https://pkg.go.dev/cmd/go/#hdr-Add_dependencies_to_current_module_and_install_them) command:
|
||||
|
||||
```bash
|
||||
go get github.com/gofiber/fiber/v2
|
||||
```
|
||||
|
||||
### Zero Allocation
|
||||
Some values returned from \***fiber.Ctx** are **not** immutable by default.
|
||||
|
||||
Because fiber is optimized for **high-performance**, values returned from **fiber.Ctx** are **not** immutable by default and **will** be re-used across requests. As a rule of thumb, you **must** only use context values within the handler, and you **must not** keep any references. As soon as you return from the handler, any values you have obtained from the context will be re-used in future requests and will change below your feet. Here is an example:
|
||||
|
||||
```go
|
||||
func handler(c *fiber.Ctx) error {
|
||||
// Variable is only valid within this handler
|
||||
result := c.Params("foo")
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
If you need to persist such values outside the handler, make copies of their **underlying buffer** using the [copy](https://pkg.go.dev/builtin/#copy) builtin. Here is an example for persisting a string:
|
||||
|
||||
```go
|
||||
func handler(c *fiber.Ctx) error {
|
||||
// Variable is only valid within this handler
|
||||
result := c.Params("foo")
|
||||
|
||||
// Make a copy
|
||||
buffer := make([]byte, len(result))
|
||||
copy(buffer, result)
|
||||
resultCopy := string(buffer)
|
||||
// Variable is now valid forever
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
We created a custom `CopyString` function that does the above and is available under [gofiber/utils](https://github.com/gofiber/fiber/tree/master/utils).
|
||||
|
||||
```go
|
||||
app.Get("/:foo", func(c *fiber.Ctx) error {
|
||||
// Variable is now immutable
|
||||
result := utils.CopyString(c.Params("foo"))
|
||||
|
||||
// ...
|
||||
})
|
||||
```
|
||||
|
||||
Alternatively, you can also use the `Immutable` setting. It will make all values returned from the context immutable, allowing you to persist them anywhere. Of course, this comes at the cost of performance.
|
||||
|
||||
```go
|
||||
app := fiber.New(fiber.Config{
|
||||
Immutable: true,
|
||||
})
|
||||
```
|
||||
|
||||
For more information, please check [**\#426**](https://github.com/gofiber/fiber/issues/426) and [**\#185**](https://github.com/gofiber/fiber/issues/185).
|
||||
|
||||
### Hello, World!
|
||||
|
||||
Embedded below is essentially the most straightforward **Fiber** app you can create:
|
||||
|
||||
```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")
|
||||
}
|
||||
```
|
||||
|
||||
```text
|
||||
go run server.go
|
||||
```
|
||||
|
||||
Browse to `http://localhost:3000` and you should see `Hello, World!` on the page.
|
||||
|
||||
### Basic routing
|
||||
|
||||
Routing refers to determining how an application responds to a client request to a particular endpoint, which is a URI (or path) and a specific HTTP request method (`GET`, `PUT`, `POST`, etc.).
|
||||
|
||||
Each route can have **multiple handler functions** that are executed when the route is matched.
|
||||
|
||||
Route definition takes the following structures:
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
app.Method(path string, ...func(*fiber.Ctx) error)
|
||||
```
|
||||
|
||||
- `app` is an instance of **Fiber**
|
||||
- `Method` is an [HTTP request method](https://docs.gofiber.io/api/app#route-handlers): `GET`, `PUT`, `POST`, etc.
|
||||
- `path` is a virtual path on the server
|
||||
- `func(*fiber.Ctx) error` is a callback function containing the [Context](https://docs.gofiber.io/api/ctx) executed when the route is matched
|
||||
|
||||
**Simple route**
|
||||
|
||||
```go
|
||||
// Respond with "Hello, World!" on root path, "/"
|
||||
app.Get("/", func(c *fiber.Ctx) error {
|
||||
return c.SendString("Hello, World!")
|
||||
})
|
||||
```
|
||||
|
||||
**Parameters**
|
||||
|
||||
```go
|
||||
// GET http://localhost:8080/hello%20world
|
||||
|
||||
app.Get("/:value", func(c *fiber.Ctx) error {
|
||||
return c.SendString("value: " + c.Params("value"))
|
||||
// => Get request with value: hello world
|
||||
})
|
||||
```
|
||||
|
||||
**Optional parameter**
|
||||
|
||||
```go
|
||||
// GET http://localhost:3000/john
|
||||
|
||||
app.Get("/:name?", func(c *fiber.Ctx) error {
|
||||
if c.Params("name") != "" {
|
||||
return c.SendString("Hello " + c.Params("name"))
|
||||
// => Hello john
|
||||
}
|
||||
return c.SendString("Where is john?")
|
||||
})
|
||||
```
|
||||
|
||||
**Wildcards**
|
||||
|
||||
```go
|
||||
// GET http://localhost:3000/api/user/john
|
||||
|
||||
app.Get("/api/*", func(c *fiber.Ctx) error {
|
||||
return c.SendString("API path: " + c.Params("*"))
|
||||
// => API path: user/john
|
||||
})
|
||||
```
|
||||
|
||||
### Static files
|
||||
|
||||
To serve static files such as **images**, **CSS**, and **JavaScript** files, replace your function handler with a file or directory string.
|
||||
|
||||
Function signature:
|
||||
|
||||
```go
|
||||
app.Static(prefix, root string, config ...Static)
|
||||
```
|
||||
|
||||
Use the following code to serve files in a directory named `./public`:
|
||||
|
||||
```go
|
||||
app := fiber.New()
|
||||
|
||||
app.Static("/", "./public")
|
||||
|
||||
app.Listen(":3000")
|
||||
```
|
||||
|
||||
Now, you can load the files that are in the `./public` directory:
|
||||
|
||||
```bash
|
||||
http://localhost:8080/hello.html
|
||||
http://localhost:8080/js/jquery.js
|
||||
http://localhost:8080/css/style.css
|
||||
```
|
||||
|
||||
### Note
|
||||
|
||||
For more information on how to build APIs in Go with Fiber, please check out this excellent article
|
||||
[on building an express-style API in Go with Fiber](https://blog.logrocket.com/express-style-api-go-fiber/).
|
|
@ -0,0 +1,69 @@
|
|||
---
|
||||
id: route-handlers
|
||||
title: Route Handlers
|
||||
---
|
||||
|
||||
Registers a route bound to a specific [HTTP method](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods).
|
||||
|
||||
```go title="Signatures"
|
||||
// HTTP methods
|
||||
func (app *App) Get(path string, handlers ...Handler) Router
|
||||
func (app *App) Head(path string, handlers ...Handler) Router
|
||||
func (app *App) Post(path string, handlers ...Handler) Router
|
||||
func (app *App) Put(path string, handlers ...Handler) Router
|
||||
func (app *App) Delete(path string, handlers ...Handler) Router
|
||||
func (app *App) Connect(path string, handlers ...Handler) Router
|
||||
func (app *App) Options(path string, handlers ...Handler) Router
|
||||
func (app *App) Trace(path string, handlers ...Handler) Router
|
||||
func (app *App) Patch(path string, handlers ...Handler) Router
|
||||
|
||||
// Add allows you to specifiy a method as value
|
||||
func (app *App) Add(method, path string, handlers ...Handler) Router
|
||||
|
||||
// All will register the route on all HTTP methods
|
||||
// Almost the same as app.Use but not bound to prefixes
|
||||
func (app *App) All(path string, handlers ...Handler) Router
|
||||
```
|
||||
|
||||
```go title="Examples"
|
||||
// Simple GET handler
|
||||
app.Get("/api/list", func(c *fiber.Ctx)error{
|
||||
return c.SendString("I'm a GET request!")
|
||||
})
|
||||
|
||||
// Simple POST handler
|
||||
app.Post("/api/register", func(c *fiber.Ctx) error {
|
||||
return c.SendString("I'm a POST request!")
|
||||
})
|
||||
```
|
||||
|
||||
**Use** can be used for middleware packages and prefix catchers. These routes will only match the beginning of each path i.e. `/john` will match `/john/doe`, `/johnnnnn` etc
|
||||
|
||||
```go title="Signature"
|
||||
func (app *App) Use(args ...interface{}) Router
|
||||
```
|
||||
|
||||
```go title="Examples"
|
||||
// Match any request
|
||||
app.Use(func(c *fiber.Ctx) error {
|
||||
return c.Next()
|
||||
})
|
||||
|
||||
// Match request starting with /api
|
||||
app.Use("/api", func(c *fiber.Ctx) error {
|
||||
return c.Next()
|
||||
})
|
||||
|
||||
// Match requests starting with /api or /home (multiple-prefix support)
|
||||
app.Use([]string{"/api", "/home"}, func(c *fiber.Ctx) error {
|
||||
return c.Next()
|
||||
})
|
||||
|
||||
// Attach multiple handlers
|
||||
app.Use("/api",func(c *fiber.Ctx) error {
|
||||
c.Set("X-Custom-Header", random.String(32))
|
||||
return c.Next()
|
||||
}, func(c *fiber.Ctx) error {
|
||||
return c.Next()
|
||||
})
|
||||
```
|
Loading…
Reference in New Issue