mirror of
https://github.com/gofiber/fiber.git
synced 2025-05-31 11:52:41 +00:00
commit
1ff27277c6
65
.github/README.md
vendored
65
.github/README.md
vendored
@ -215,8 +215,8 @@ func main() {
|
||||
c.Next()
|
||||
})
|
||||
|
||||
// POST /api/register
|
||||
app.Post("/api/register", func(c *fiber.Ctx) {
|
||||
// GET /api/register
|
||||
app.Get("/api/list", func(c *fiber.Ctx) {
|
||||
fmt.Println("Last middleware")
|
||||
c.Send("Hello, World!")
|
||||
})
|
||||
@ -311,22 +311,22 @@ Example:
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
"github.com/gofiber/logger"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// If you want to change default Logger config
|
||||
loggerConfig := middleware.LoggerConfig{
|
||||
// Optional logger config
|
||||
config := logger.LoggerConfig{
|
||||
Format: "${time} - ${method} ${path}\n",
|
||||
TimeFormat: "Mon, 2 Jan 2006 15:04:05 MST",
|
||||
}
|
||||
|
||||
// Middleware for Logger with config
|
||||
app.Use(middleware.Logger(loggerConfig))
|
||||
// Logger with config
|
||||
app.Use(logger.New(config))
|
||||
|
||||
// ...
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
@ -336,25 +336,19 @@ Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/middleware#cors
|
||||
|
||||
> [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) is a mechanism that uses additional HTTP headers to tell browsers to give a web application running at one origin, access to selected resources from a different origin. A web application executes a cross-origin HTTP request when it requests a resource that has a different origin (domain, protocol, or port) from its own.
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
"github.com/gofiber/cors"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Connect CORS for each route as middleware
|
||||
app.Use(middleware.CORS())
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
c.Send("CORS is enabled!")
|
||||
})
|
||||
// CORS with default config
|
||||
app.Use(cors.New())
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
@ -432,38 +426,41 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
### WebSocket support
|
||||
### WebSocket middleware
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/application#websocket
|
||||
- 📖 https://fiber.wiki/middleware#websocket
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/websocket"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.WebSocket("/ws", func(c *fiber.Conn) {
|
||||
app.Get("/ws", websocket.New(func(c *websocket.Conn) {
|
||||
for {
|
||||
mt, msg, err := c.ReadMessage()
|
||||
if err != nil {
|
||||
log.Println("read:", err)
|
||||
break
|
||||
}
|
||||
|
||||
log.Printf("recovery: %s", msg)
|
||||
|
||||
log.Printf("recv: %s", msg)
|
||||
err = c.WriteMessage(mt, msg)
|
||||
if err != nil {
|
||||
log.Println("write:", err)
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
}))
|
||||
|
||||
// Listen on ws://localhost:3000/ws
|
||||
app.Listen(3000)
|
||||
// ws://localhost:3000/ws
|
||||
}
|
||||
```
|
||||
|
||||
@ -478,20 +475,22 @@ Example:
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
"github.com/gofiber/recover"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(middleware.Recover(func(c *fiber.Ctx, err error) {
|
||||
log.Println(err) // "Something went wrong!"
|
||||
c.SendStatus(500) // Internal Server Error
|
||||
}))
|
||||
// Optional recover config
|
||||
config := recover.LoggerConfig{
|
||||
Handler: func(c *fiber.Ctx, err error) {
|
||||
c.SendString(err.Error())
|
||||
c.SendStatus(500)
|
||||
},
|
||||
}
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
panic("Something went wrong!")
|
||||
})
|
||||
// Logger with custom config
|
||||
app.Use(recover.New(config))
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
|
171
.github/README_de.md
vendored
171
.github/README_de.md
vendored
@ -207,16 +207,22 @@ func main() {
|
||||
<summary>📚 Show more code examples</summary>
|
||||
|
||||
### Template engines
|
||||
https://fiber.wiki/application#settings
|
||||
https://fiber.wiki/context#render
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/application#settings
|
||||
- 📖 https://fiber.wiki/context#render
|
||||
|
||||
Supported engines:
|
||||
|
||||
- [html](https://golang.org/pkg/html/template/)
|
||||
- [amber](https://github.com/eknkc/amber)
|
||||
- [handlebars](https://github.com/aymerick/raymond)
|
||||
- [mustache](https://github.com/cbroglie/mustache)
|
||||
- [pug](https://github.com/Joker/jade)
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
func main() {
|
||||
// You can setup template engine before initiation app:
|
||||
@ -244,7 +250,13 @@ func main() {
|
||||
```
|
||||
|
||||
### Grouping routes into chains
|
||||
https://fiber.wiki/application#group
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/application#group
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
@ -267,55 +279,60 @@ func main() {
|
||||
```
|
||||
|
||||
### Middleware logger
|
||||
https://fiber.wiki/middleware#logger
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/middleware#logger
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
"github.com/gofiber/logger"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// If you want to change default Logger config
|
||||
loggerConfig := middleware.LoggerConfig{
|
||||
|
||||
// Optional logger config
|
||||
config := logger.LoggerConfig{
|
||||
Format: "${time} - ${method} ${path}\n",
|
||||
TimeFormat: "Mon, 2 Jan 2006 15:04:05 MST",
|
||||
}
|
||||
|
||||
// Middleware for Logger with config
|
||||
app.Use(middleware.Logger(loggerConfig))
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Cross-Origin Resource Sharing (CORS)
|
||||
https://fiber.wiki/middleware#cors
|
||||
|
||||
[CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) is a mechanism that uses additional HTTP headers to tell browsers to give a web application running at one origin, access to selected resources from a different origin. A web application executes a cross-origin HTTP request when it requests a resource that has a different origin (domain, protocol, or port) from its own.
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Connect CORS for each route as middleware
|
||||
app.Use(middleware.CORS())
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
c.Send("CORS is enabled!")
|
||||
})
|
||||
// Logger with config
|
||||
app.Use(logger.New(config))
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
Check CORS by passing any domain in `Origin` header:
|
||||
### Cross-Origin Resource Sharing (CORS)
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/middleware#cors
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/cors"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// CORS with default config
|
||||
app.Use(cors.New())
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
Check CORS by passing any domain in `Origin` header:
|
||||
|
||||
```bash
|
||||
curl -H "Origin: http://example.com" --verbose http://localhost:3000
|
||||
@ -323,6 +340,12 @@ curl -H "Origin: http://example.com" --verbose http://localhost:3000
|
||||
|
||||
### Custom 404 response
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/application#http-methods
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
@ -339,7 +362,8 @@ func main() {
|
||||
|
||||
// Last middleware to match anything
|
||||
app.Use(func(c *fiber.Ctx) {
|
||||
c.SendStatus(404) // => 404 "Not Found"
|
||||
c.SendStatus(404)
|
||||
// => 404 "Not Found"
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
@ -347,7 +371,13 @@ func main() {
|
||||
```
|
||||
|
||||
### JSON Response
|
||||
https://fiber.wiki/context#json
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/context#json
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
type User struct {
|
||||
Name string `json:"name"`
|
||||
@ -359,71 +389,86 @@ func main() {
|
||||
|
||||
app.Get("/user", func(c *fiber.Ctx) {
|
||||
c.JSON(&User{"John", 20})
|
||||
// {"name":"John", "age":20}
|
||||
// => {"name":"John", "age":20}
|
||||
})
|
||||
|
||||
app.Get("/json", func(c *fiber.Ctx) {
|
||||
c.JSON(&fiber.Map{
|
||||
"success": true,
|
||||
"message": "Hi John!",
|
||||
c.JSON(fiber.Map{
|
||||
"success": true,
|
||||
"message": "Hi John!",
|
||||
})
|
||||
// {"success":true, "message":"Hi John!"}
|
||||
// => {"success":true, "message":"Hi John!"}
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
### WebSocket support
|
||||
https://fiber.wiki/application#websocket
|
||||
### WebSocket middleware
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/middleware#websocket
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/websocket"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.WebSocket("/ws", func(c *fiber.Conn) {
|
||||
app.Get("/ws", websocket.New(func(c *websocket.Conn) {
|
||||
for {
|
||||
mt, msg, err := c.ReadMessage()
|
||||
if err != nil {
|
||||
log.Println("read:", err)
|
||||
break
|
||||
}
|
||||
|
||||
log.Printf("recovery: %s", msg)
|
||||
|
||||
log.Printf("recv: %s", msg)
|
||||
err = c.WriteMessage(mt, msg)
|
||||
if err != nil {
|
||||
log.Println("write:", err)
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
}))
|
||||
|
||||
// Listen on ws://localhost:3000/ws
|
||||
app.Listen(3000)
|
||||
// ws://localhost:3000/ws
|
||||
}
|
||||
```
|
||||
|
||||
### Recover middleware
|
||||
https://fiber.wiki/middleware#recover
|
||||
```go
|
||||
package main
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/middleware#recover
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
"github.com/gofiber/recover"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(middleware.Recover(func(c *fiber.Ctx, err error) {
|
||||
log.Println(err) // "Something went wrong!"
|
||||
c.SendStatus(500) // Internal Server Error
|
||||
})))
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
panic("Something went wrong!")
|
||||
})
|
||||
// Optional recover config
|
||||
config := recover.LoggerConfig{
|
||||
Handler: func(c *fiber.Ctx, err error) {
|
||||
c.SendString(err.Error())
|
||||
c.SendStatus(500)
|
||||
},
|
||||
}
|
||||
|
||||
// Logger with custom config
|
||||
app.Use(recover.New(config))
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
|
171
.github/README_es.md
vendored
171
.github/README_es.md
vendored
@ -207,16 +207,22 @@ func main() {
|
||||
<summary>📚 Show more code examples</summary>
|
||||
|
||||
### Template engines
|
||||
https://fiber.wiki/application#settings
|
||||
https://fiber.wiki/context#render
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/application#settings
|
||||
- 📖 https://fiber.wiki/context#render
|
||||
|
||||
Supported engines:
|
||||
|
||||
- [html](https://golang.org/pkg/html/template/)
|
||||
- [amber](https://github.com/eknkc/amber)
|
||||
- [handlebars](https://github.com/aymerick/raymond)
|
||||
- [mustache](https://github.com/cbroglie/mustache)
|
||||
- [pug](https://github.com/Joker/jade)
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
func main() {
|
||||
// You can setup template engine before initiation app:
|
||||
@ -244,7 +250,13 @@ func main() {
|
||||
```
|
||||
|
||||
### Grouping routes into chains
|
||||
https://fiber.wiki/application#group
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/application#group
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
@ -267,55 +279,60 @@ func main() {
|
||||
```
|
||||
|
||||
### Middleware logger
|
||||
https://fiber.wiki/middleware#logger
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/middleware#logger
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
"github.com/gofiber/logger"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// If you want to change default Logger config
|
||||
loggerConfig := middleware.LoggerConfig{
|
||||
|
||||
// Optional logger config
|
||||
config := logger.LoggerConfig{
|
||||
Format: "${time} - ${method} ${path}\n",
|
||||
TimeFormat: "Mon, 2 Jan 2006 15:04:05 MST",
|
||||
}
|
||||
|
||||
// Middleware for Logger with config
|
||||
app.Use(middleware.Logger(loggerConfig))
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Cross-Origin Resource Sharing (CORS)
|
||||
https://fiber.wiki/middleware#cors
|
||||
|
||||
[CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) is a mechanism that uses additional HTTP headers to tell browsers to give a web application running at one origin, access to selected resources from a different origin. A web application executes a cross-origin HTTP request when it requests a resource that has a different origin (domain, protocol, or port) from its own.
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Connect CORS for each route as middleware
|
||||
app.Use(middleware.CORS())
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
c.Send("CORS is enabled!")
|
||||
})
|
||||
// Logger with config
|
||||
app.Use(logger.New(config))
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
Check CORS by passing any domain in `Origin` header:
|
||||
### Cross-Origin Resource Sharing (CORS)
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/middleware#cors
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/cors"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// CORS with default config
|
||||
app.Use(cors.New())
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
Check CORS by passing any domain in `Origin` header:
|
||||
|
||||
```bash
|
||||
curl -H "Origin: http://example.com" --verbose http://localhost:3000
|
||||
@ -323,6 +340,12 @@ curl -H "Origin: http://example.com" --verbose http://localhost:3000
|
||||
|
||||
### Custom 404 response
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/application#http-methods
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
@ -339,7 +362,8 @@ func main() {
|
||||
|
||||
// Last middleware to match anything
|
||||
app.Use(func(c *fiber.Ctx) {
|
||||
c.SendStatus(404) // => 404 "Not Found"
|
||||
c.SendStatus(404)
|
||||
// => 404 "Not Found"
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
@ -347,7 +371,13 @@ func main() {
|
||||
```
|
||||
|
||||
### JSON Response
|
||||
https://fiber.wiki/context#json
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/context#json
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
type User struct {
|
||||
Name string `json:"name"`
|
||||
@ -359,71 +389,86 @@ func main() {
|
||||
|
||||
app.Get("/user", func(c *fiber.Ctx) {
|
||||
c.JSON(&User{"John", 20})
|
||||
// {"name":"John", "age":20}
|
||||
// => {"name":"John", "age":20}
|
||||
})
|
||||
|
||||
app.Get("/json", func(c *fiber.Ctx) {
|
||||
c.JSON(&fiber.Map{
|
||||
"success": true,
|
||||
"message": "Hi John!",
|
||||
c.JSON(fiber.Map{
|
||||
"success": true,
|
||||
"message": "Hi John!",
|
||||
})
|
||||
// {"success":true, "message":"Hi John!"}
|
||||
// => {"success":true, "message":"Hi John!"}
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
### WebSocket support
|
||||
https://fiber.wiki/application#websocket
|
||||
### WebSocket middleware
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/middleware#websocket
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/websocket"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.WebSocket("/ws", func(c *fiber.Conn) {
|
||||
app.Get("/ws", websocket.New(func(c *websocket.Conn) {
|
||||
for {
|
||||
mt, msg, err := c.ReadMessage()
|
||||
if err != nil {
|
||||
log.Println("read:", err)
|
||||
break
|
||||
}
|
||||
|
||||
log.Printf("recovery: %s", msg)
|
||||
|
||||
log.Printf("recv: %s", msg)
|
||||
err = c.WriteMessage(mt, msg)
|
||||
if err != nil {
|
||||
log.Println("write:", err)
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
}))
|
||||
|
||||
// Listen on ws://localhost:3000/ws
|
||||
app.Listen(3000)
|
||||
// ws://localhost:3000/ws
|
||||
}
|
||||
```
|
||||
|
||||
### Recover middleware
|
||||
https://fiber.wiki/middleware#recover
|
||||
```go
|
||||
package main
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/middleware#recover
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
"github.com/gofiber/recover"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(middleware.Recover(func(c *fiber.Ctx, err error) {
|
||||
log.Println(err) // "Something went wrong!"
|
||||
c.SendStatus(500) // Internal Server Error
|
||||
})))
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
panic("Something went wrong!")
|
||||
})
|
||||
// Optional recover config
|
||||
config := recover.LoggerConfig{
|
||||
Handler: func(c *fiber.Ctx, err error) {
|
||||
c.SendString(err.Error())
|
||||
c.SendStatus(500)
|
||||
},
|
||||
}
|
||||
|
||||
// Logger with custom config
|
||||
app.Use(recover.New(config))
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
|
171
.github/README_fr.md
vendored
171
.github/README_fr.md
vendored
@ -207,16 +207,22 @@ func main() {
|
||||
<summary>📚 Show more code examples</summary>
|
||||
|
||||
### Template engines
|
||||
https://fiber.wiki/application#settings
|
||||
https://fiber.wiki/context#render
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/application#settings
|
||||
- 📖 https://fiber.wiki/context#render
|
||||
|
||||
Supported engines:
|
||||
|
||||
- [html](https://golang.org/pkg/html/template/)
|
||||
- [amber](https://github.com/eknkc/amber)
|
||||
- [handlebars](https://github.com/aymerick/raymond)
|
||||
- [mustache](https://github.com/cbroglie/mustache)
|
||||
- [pug](https://github.com/Joker/jade)
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
func main() {
|
||||
// You can setup template engine before initiation app:
|
||||
@ -244,7 +250,13 @@ func main() {
|
||||
```
|
||||
|
||||
### Grouping routes into chains
|
||||
https://fiber.wiki/application#group
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/application#group
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
@ -267,55 +279,60 @@ func main() {
|
||||
```
|
||||
|
||||
### Middleware logger
|
||||
https://fiber.wiki/middleware#logger
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/middleware#logger
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
"github.com/gofiber/logger"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// If you want to change default Logger config
|
||||
loggerConfig := middleware.LoggerConfig{
|
||||
|
||||
// Optional logger config
|
||||
config := logger.LoggerConfig{
|
||||
Format: "${time} - ${method} ${path}\n",
|
||||
TimeFormat: "Mon, 2 Jan 2006 15:04:05 MST",
|
||||
}
|
||||
|
||||
// Middleware for Logger with config
|
||||
app.Use(middleware.Logger(loggerConfig))
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Cross-Origin Resource Sharing (CORS)
|
||||
https://fiber.wiki/middleware#cors
|
||||
|
||||
[CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) is a mechanism that uses additional HTTP headers to tell browsers to give a web application running at one origin, access to selected resources from a different origin. A web application executes a cross-origin HTTP request when it requests a resource that has a different origin (domain, protocol, or port) from its own.
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Connect CORS for each route as middleware
|
||||
app.Use(middleware.CORS())
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
c.Send("CORS is enabled!")
|
||||
})
|
||||
// Logger with config
|
||||
app.Use(logger.New(config))
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
Check CORS by passing any domain in `Origin` header:
|
||||
### Cross-Origin Resource Sharing (CORS)
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/middleware#cors
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/cors"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// CORS with default config
|
||||
app.Use(cors.New())
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
Check CORS by passing any domain in `Origin` header:
|
||||
|
||||
```bash
|
||||
curl -H "Origin: http://example.com" --verbose http://localhost:3000
|
||||
@ -323,6 +340,12 @@ curl -H "Origin: http://example.com" --verbose http://localhost:3000
|
||||
|
||||
### Custom 404 response
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/application#http-methods
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
@ -339,7 +362,8 @@ func main() {
|
||||
|
||||
// Last middleware to match anything
|
||||
app.Use(func(c *fiber.Ctx) {
|
||||
c.SendStatus(404) // => 404 "Not Found"
|
||||
c.SendStatus(404)
|
||||
// => 404 "Not Found"
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
@ -347,7 +371,13 @@ func main() {
|
||||
```
|
||||
|
||||
### JSON Response
|
||||
https://fiber.wiki/context#json
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/context#json
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
type User struct {
|
||||
Name string `json:"name"`
|
||||
@ -359,71 +389,86 @@ func main() {
|
||||
|
||||
app.Get("/user", func(c *fiber.Ctx) {
|
||||
c.JSON(&User{"John", 20})
|
||||
// {"name":"John", "age":20}
|
||||
// => {"name":"John", "age":20}
|
||||
})
|
||||
|
||||
app.Get("/json", func(c *fiber.Ctx) {
|
||||
c.JSON(&fiber.Map{
|
||||
"success": true,
|
||||
"message": "Hi John!",
|
||||
c.JSON(fiber.Map{
|
||||
"success": true,
|
||||
"message": "Hi John!",
|
||||
})
|
||||
// {"success":true, "message":"Hi John!"}
|
||||
// => {"success":true, "message":"Hi John!"}
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
### WebSocket support
|
||||
https://fiber.wiki/application#websocket
|
||||
### WebSocket middleware
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/middleware#websocket
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/websocket"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.WebSocket("/ws", func(c *fiber.Conn) {
|
||||
app.Get("/ws", websocket.New(func(c *websocket.Conn) {
|
||||
for {
|
||||
mt, msg, err := c.ReadMessage()
|
||||
if err != nil {
|
||||
log.Println("read:", err)
|
||||
break
|
||||
}
|
||||
|
||||
log.Printf("recovery: %s", msg)
|
||||
|
||||
log.Printf("recv: %s", msg)
|
||||
err = c.WriteMessage(mt, msg)
|
||||
if err != nil {
|
||||
log.Println("write:", err)
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
}))
|
||||
|
||||
// Listen on ws://localhost:3000/ws
|
||||
app.Listen(3000)
|
||||
// ws://localhost:3000/ws
|
||||
}
|
||||
```
|
||||
|
||||
### Recover middleware
|
||||
https://fiber.wiki/middleware#recover
|
||||
```go
|
||||
package main
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/middleware#recover
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
"github.com/gofiber/recover"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(middleware.Recover(func(c *fiber.Ctx, err error) {
|
||||
log.Println(err) // "Something went wrong!"
|
||||
c.SendStatus(500) // Internal Server Error
|
||||
})))
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
panic("Something went wrong!")
|
||||
})
|
||||
// Optional recover config
|
||||
config := recover.LoggerConfig{
|
||||
Handler: func(c *fiber.Ctx, err error) {
|
||||
c.SendString(err.Error())
|
||||
c.SendStatus(500)
|
||||
},
|
||||
}
|
||||
|
||||
// Logger with custom config
|
||||
app.Use(recover.New(config))
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
|
181
.github/README_id.md
vendored
181
.github/README_id.md
vendored
@ -206,19 +206,25 @@ func main() {
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>📚 Perlihatkan contoh lainnya</summary>
|
||||
<summary>📚 Show more code examples</summary>
|
||||
|
||||
### Template engines
|
||||
https://fiber.wiki/application#settings
|
||||
https://fiber.wiki/context#render
|
||||
|
||||
Mendukung:
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/application#settings
|
||||
- 📖 https://fiber.wiki/context#render
|
||||
|
||||
Supported engines:
|
||||
|
||||
- [html](https://golang.org/pkg/html/template/)
|
||||
- [amber](https://github.com/eknkc/amber)
|
||||
- [handlebars](https://github.com/aymerick/raymond)
|
||||
- [mustache](https://github.com/cbroglie/mustache)
|
||||
- [pug](https://github.com/Joker/jade)
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
func main() {
|
||||
// You can setup template engine before initiation app:
|
||||
@ -245,8 +251,14 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
### Pengelompokan routes
|
||||
https://fiber.wiki/application#group
|
||||
### Grouping routes into chains
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/application#group
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
@ -269,61 +281,72 @@ func main() {
|
||||
```
|
||||
|
||||
### Middleware logger
|
||||
https://fiber.wiki/middleware#logger
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/middleware#logger
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
"github.com/gofiber/logger"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// If you want to change default Logger config
|
||||
loggerConfig := middleware.LoggerConfig{
|
||||
|
||||
// Optional logger config
|
||||
config := logger.LoggerConfig{
|
||||
Format: "${time} - ${method} ${path}\n",
|
||||
TimeFormat: "Mon, 2 Jan 2006 15:04:05 MST",
|
||||
}
|
||||
|
||||
// Middleware for Logger with config
|
||||
app.Use(middleware.Logger(loggerConfig))
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Cross-Origin Resource Sharing (CORS)
|
||||
https://fiber.wiki/middleware#cors
|
||||
|
||||
[CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) adalah mekanisme yang menggunakan HTTP headers tambahan untuk memberitahu browser bahwa aplikasi/data kita hanya bisa diakses dari sumber (origin) tertentu, atau bisa juga diakses dari sumber berbeda. Aplikasi web memproses cross-origin HTTP request ketika request-nya berasal dari sumber berbeda (domain, protokol dan port).
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Connect CORS for each route as middleware
|
||||
app.Use(middleware.CORS())
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
c.Send("CORS is enabled!")
|
||||
})
|
||||
// Logger with config
|
||||
app.Use(logger.New(config))
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
Setelah diaktifkan, bisa dicoba dengan cara memberi sumber/domain berbeda di header `Origin`:
|
||||
### Cross-Origin Resource Sharing (CORS)
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/middleware#cors
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/cors"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// CORS with default config
|
||||
app.Use(cors.New())
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
Check CORS by passing any domain in `Origin` header:
|
||||
|
||||
```bash
|
||||
curl -H "Origin: http://example.com" --verbose http://localhost:3000
|
||||
```
|
||||
|
||||
### Respon 404
|
||||
### Custom 404 response
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/application#http-methods
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
func main() {
|
||||
@ -341,15 +364,22 @@ func main() {
|
||||
|
||||
// Last middleware to match anything
|
||||
app.Use(func(c *fiber.Ctx) {
|
||||
c.SendStatus(404) // => 404 "Not Found"
|
||||
c.SendStatus(404)
|
||||
// => 404 "Not Found"
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
### Respon JSON
|
||||
https://fiber.wiki/context#json
|
||||
### JSON Response
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/context#json
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
type User struct {
|
||||
Name string `json:"name"`
|
||||
@ -361,71 +391,86 @@ func main() {
|
||||
|
||||
app.Get("/user", func(c *fiber.Ctx) {
|
||||
c.JSON(&User{"John", 20})
|
||||
// {"name":"John", "age":20}
|
||||
// => {"name":"John", "age":20}
|
||||
})
|
||||
|
||||
app.Get("/json", func(c *fiber.Ctx) {
|
||||
c.JSON(&fiber.Map{
|
||||
"success": true,
|
||||
"message": "Hi John!",
|
||||
c.JSON(fiber.Map{
|
||||
"success": true,
|
||||
"message": "Hi John!",
|
||||
})
|
||||
// {"success":true, "message":"Hi John!"}
|
||||
// => {"success":true, "message":"Hi John!"}
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
### Dukungan WebSocket
|
||||
https://fiber.wiki/application#websocket
|
||||
### WebSocket middleware
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/middleware#websocket
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/websocket"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.WebSocket("/ws", func(c *fiber.Conn) {
|
||||
app.Get("/ws", websocket.New(func(c *websocket.Conn) {
|
||||
for {
|
||||
mt, msg, err := c.ReadMessage()
|
||||
if err != nil {
|
||||
log.Println("read:", err)
|
||||
break
|
||||
}
|
||||
|
||||
log.Printf("recovery: %s", msg)
|
||||
|
||||
log.Printf("recv: %s", msg)
|
||||
err = c.WriteMessage(mt, msg)
|
||||
if err != nil {
|
||||
log.Println("write:", err)
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
}))
|
||||
|
||||
// Listen on ws://localhost:3000/ws
|
||||
app.Listen(3000)
|
||||
// ws://localhost:3000/ws
|
||||
}
|
||||
```
|
||||
|
||||
### Recover middleware
|
||||
https://fiber.wiki/middleware#recover
|
||||
```go
|
||||
package main
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/middleware#recover
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
"github.com/gofiber/recover"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(middleware.Recover(func(c *fiber.Ctx, err error) {
|
||||
log.Println(err) // "Something went wrong!"
|
||||
c.SendStatus(500) // Internal Server Error
|
||||
})))
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
panic("Something went wrong!")
|
||||
})
|
||||
// Optional recover config
|
||||
config := recover.LoggerConfig{
|
||||
Handler: func(c *fiber.Ctx, err error) {
|
||||
c.SendString(err.Error())
|
||||
c.SendStatus(500)
|
||||
},
|
||||
}
|
||||
|
||||
// Logger with custom config
|
||||
app.Use(recover.New(config))
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
|
171
.github/README_ja.md
vendored
171
.github/README_ja.md
vendored
@ -211,16 +211,22 @@ func main() {
|
||||
<summary>📚 Show more code examples</summary>
|
||||
|
||||
### Template engines
|
||||
https://fiber.wiki/application#settings
|
||||
https://fiber.wiki/context#render
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/application#settings
|
||||
- 📖 https://fiber.wiki/context#render
|
||||
|
||||
Supported engines:
|
||||
|
||||
- [html](https://golang.org/pkg/html/template/)
|
||||
- [amber](https://github.com/eknkc/amber)
|
||||
- [handlebars](https://github.com/aymerick/raymond)
|
||||
- [mustache](https://github.com/cbroglie/mustache)
|
||||
- [pug](https://github.com/Joker/jade)
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
func main() {
|
||||
// You can setup template engine before initiation app:
|
||||
@ -248,7 +254,13 @@ func main() {
|
||||
```
|
||||
|
||||
### Grouping routes into chains
|
||||
https://fiber.wiki/application#group
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/application#group
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
@ -271,55 +283,60 @@ func main() {
|
||||
```
|
||||
|
||||
### Middleware logger
|
||||
https://fiber.wiki/middleware#logger
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/middleware#logger
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
"github.com/gofiber/logger"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// If you want to change default Logger config
|
||||
loggerConfig := middleware.LoggerConfig{
|
||||
|
||||
// Optional logger config
|
||||
config := logger.LoggerConfig{
|
||||
Format: "${time} - ${method} ${path}\n",
|
||||
TimeFormat: "Mon, 2 Jan 2006 15:04:05 MST",
|
||||
}
|
||||
|
||||
// Middleware for Logger with config
|
||||
app.Use(middleware.Logger(loggerConfig))
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Cross-Origin Resource Sharing (CORS)
|
||||
https://fiber.wiki/middleware#cors
|
||||
|
||||
[CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) is a mechanism that uses additional HTTP headers to tell browsers to give a web application running at one origin, access to selected resources from a different origin. A web application executes a cross-origin HTTP request when it requests a resource that has a different origin (domain, protocol, or port) from its own.
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Connect CORS for each route as middleware
|
||||
app.Use(middleware.CORS())
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
c.Send("CORS is enabled!")
|
||||
})
|
||||
// Logger with config
|
||||
app.Use(logger.New(config))
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
Check CORS by passing any domain in `Origin` header:
|
||||
### Cross-Origin Resource Sharing (CORS)
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/middleware#cors
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/cors"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// CORS with default config
|
||||
app.Use(cors.New())
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
Check CORS by passing any domain in `Origin` header:
|
||||
|
||||
```bash
|
||||
curl -H "Origin: http://example.com" --verbose http://localhost:3000
|
||||
@ -327,6 +344,12 @@ curl -H "Origin: http://example.com" --verbose http://localhost:3000
|
||||
|
||||
### Custom 404 response
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/application#http-methods
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
@ -343,7 +366,8 @@ func main() {
|
||||
|
||||
// Last middleware to match anything
|
||||
app.Use(func(c *fiber.Ctx) {
|
||||
c.SendStatus(404) // => 404 "Not Found"
|
||||
c.SendStatus(404)
|
||||
// => 404 "Not Found"
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
@ -351,7 +375,13 @@ func main() {
|
||||
```
|
||||
|
||||
### JSON Response
|
||||
https://fiber.wiki/context#json
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/context#json
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
type User struct {
|
||||
Name string `json:"name"`
|
||||
@ -363,71 +393,86 @@ func main() {
|
||||
|
||||
app.Get("/user", func(c *fiber.Ctx) {
|
||||
c.JSON(&User{"John", 20})
|
||||
// {"name":"John", "age":20}
|
||||
// => {"name":"John", "age":20}
|
||||
})
|
||||
|
||||
app.Get("/json", func(c *fiber.Ctx) {
|
||||
c.JSON(&fiber.Map{
|
||||
"success": true,
|
||||
"message": "Hi John!",
|
||||
c.JSON(fiber.Map{
|
||||
"success": true,
|
||||
"message": "Hi John!",
|
||||
})
|
||||
// {"success":true, "message":"Hi John!"}
|
||||
// => {"success":true, "message":"Hi John!"}
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
### WebSocket support
|
||||
https://fiber.wiki/application#websocket
|
||||
### WebSocket middleware
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/middleware#websocket
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/websocket"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.WebSocket("/ws", func(c *fiber.Conn) {
|
||||
app.Get("/ws", websocket.New(func(c *websocket.Conn) {
|
||||
for {
|
||||
mt, msg, err := c.ReadMessage()
|
||||
if err != nil {
|
||||
log.Println("read:", err)
|
||||
break
|
||||
}
|
||||
|
||||
log.Printf("recovery: %s", msg)
|
||||
|
||||
log.Printf("recv: %s", msg)
|
||||
err = c.WriteMessage(mt, msg)
|
||||
if err != nil {
|
||||
log.Println("write:", err)
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
}))
|
||||
|
||||
// Listen on ws://localhost:3000/ws
|
||||
app.Listen(3000)
|
||||
// ws://localhost:3000/ws
|
||||
}
|
||||
```
|
||||
|
||||
### Recover middleware
|
||||
https://fiber.wiki/middleware#recover
|
||||
```go
|
||||
package main
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/middleware#recover
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
"github.com/gofiber/recover"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(middleware.Recover(func(c *fiber.Ctx, err error) {
|
||||
log.Println(err) // "Something went wrong!"
|
||||
c.SendStatus(500) // Internal Server Error
|
||||
})))
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
panic("Something went wrong!")
|
||||
})
|
||||
// Optional recover config
|
||||
config := recover.LoggerConfig{
|
||||
Handler: func(c *fiber.Ctx, err error) {
|
||||
c.SendString(err.Error())
|
||||
c.SendStatus(500)
|
||||
},
|
||||
}
|
||||
|
||||
// Logger with custom config
|
||||
app.Use(recover.New(config))
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
|
82
.github/README_ko.md
vendored
82
.github/README_ko.md
vendored
@ -233,6 +233,7 @@ Docs:
|
||||
- 📖 https://fiber.wiki/context#render
|
||||
|
||||
Supported engines:
|
||||
|
||||
- [html](https://golang.org/pkg/html/template/)
|
||||
- [amber](https://github.com/eknkc/amber)
|
||||
- [handlebars](https://github.com/aymerick/raymond)
|
||||
@ -305,22 +306,22 @@ Example:
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
"github.com/gofiber/logger"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// If you want to change default Logger config
|
||||
loggerConfig := middleware.LoggerConfig{
|
||||
|
||||
// Optional logger config
|
||||
config := logger.LoggerConfig{
|
||||
Format: "${time} - ${method} ${path}\n",
|
||||
TimeFormat: "Mon, 2 Jan 2006 15:04:05 MST",
|
||||
}
|
||||
|
||||
// Middleware for Logger with config
|
||||
app.Use(middleware.Logger(loggerConfig))
|
||||
// Logger with config
|
||||
app.Use(logger.New(config))
|
||||
|
||||
// ...
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
@ -329,30 +330,26 @@ Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/middleware#cors
|
||||
|
||||
> [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)은 추가적인 HTTP 헤더를 이용해 브라우저들이 한 출처에서 실행되는 웹 어플리케이션에게 다른 출처의 선택된 자원으로의 접근을 주도록 말해줍니다. 웹 어플리케이션은 자체와 다른 출처에 속해있는 자원(도메인, 프로토콜, 또는 포트)을 요청할때 cross-origin HTTP 요청을 실행합니다.
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
"github.com/gofiber/cors"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Connect CORS for each route as middleware
|
||||
app.Use(middleware.CORS())
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
c.Send("CORS is enabled!")
|
||||
})
|
||||
// CORS with default config
|
||||
app.Use(cors.New())
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
Check CORS by passing any domain in `Origin` header:
|
||||
`Origin` 헤더에 아무 도메인이나 넣어서 CORS를 확인해보세요:
|
||||
|
||||
```bash
|
||||
@ -383,7 +380,8 @@ func main() {
|
||||
|
||||
// Last middleware to match anything
|
||||
app.Use(func(c *fiber.Ctx) {
|
||||
c.SendStatus(404) // => 404 "Not Found"
|
||||
c.SendStatus(404)
|
||||
// => 404 "Not Found"
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
@ -408,52 +406,56 @@ func main() {
|
||||
|
||||
app.Get("/user", func(c *fiber.Ctx) {
|
||||
c.JSON(&User{"John", 20})
|
||||
// {"name":"John", "age":20}
|
||||
// => {"name":"John", "age":20}
|
||||
})
|
||||
|
||||
app.Get("/json", func(c *fiber.Ctx) {
|
||||
c.JSON(&fiber.Map{
|
||||
"success": true,
|
||||
"message": "Hi John!",
|
||||
c.JSON(fiber.Map{
|
||||
"success": true,
|
||||
"message": "Hi John!",
|
||||
})
|
||||
// {"success":true, "message":"Hi John!"}
|
||||
// => {"success":true, "message":"Hi John!"}
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
### WebSocket support
|
||||
### WebSocket middleware
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/application#websocket
|
||||
- 📖 https://fiber.wiki/middleware#websocket
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/websocket"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.WebSocket("/ws", func(c *fiber.Conn) {
|
||||
app.Get("/ws", websocket.New(func(c *websocket.Conn) {
|
||||
for {
|
||||
mt, msg, err := c.ReadMessage()
|
||||
if err != nil {
|
||||
log.Println("read:", err)
|
||||
break
|
||||
}
|
||||
|
||||
log.Printf("recovery: %s", msg)
|
||||
|
||||
log.Printf("recv: %s", msg)
|
||||
err = c.WriteMessage(mt, msg)
|
||||
if err != nil {
|
||||
log.Println("write:", err)
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
}))
|
||||
|
||||
// Listen on ws://localhost:3000/ws
|
||||
app.Listen(3000)
|
||||
// ws://localhost:3000/ws
|
||||
}
|
||||
```
|
||||
|
||||
@ -465,24 +467,24 @@ Docs:
|
||||
Example:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
"github.com/gofiber/recover"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(middleware.Recover(func(c *fiber.Ctx, err error) {
|
||||
log.Println(err) // "Something went wrong!"
|
||||
c.SendStatus(500) // Internal Server Error
|
||||
})))
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
panic("Something went wrong!")
|
||||
})
|
||||
// Optional recover config
|
||||
config := recover.LoggerConfig{
|
||||
Handler: func(c *fiber.Ctx, err error) {
|
||||
c.SendString(err.Error())
|
||||
c.SendStatus(500)
|
||||
},
|
||||
}
|
||||
|
||||
// Logger with custom config
|
||||
app.Use(recover.New(config))
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
|
171
.github/README_pt.md
vendored
171
.github/README_pt.md
vendored
@ -207,16 +207,22 @@ func main() {
|
||||
<summary>📚 Show more code examples</summary>
|
||||
|
||||
### Template engines
|
||||
https://fiber.wiki/application#settings
|
||||
https://fiber.wiki/context#render
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/application#settings
|
||||
- 📖 https://fiber.wiki/context#render
|
||||
|
||||
Supported engines:
|
||||
|
||||
- [html](https://golang.org/pkg/html/template/)
|
||||
- [amber](https://github.com/eknkc/amber)
|
||||
- [handlebars](https://github.com/aymerick/raymond)
|
||||
- [mustache](https://github.com/cbroglie/mustache)
|
||||
- [pug](https://github.com/Joker/jade)
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
func main() {
|
||||
// You can setup template engine before initiation app:
|
||||
@ -244,7 +250,13 @@ func main() {
|
||||
```
|
||||
|
||||
### Grouping routes into chains
|
||||
https://fiber.wiki/application#group
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/application#group
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
@ -267,55 +279,60 @@ func main() {
|
||||
```
|
||||
|
||||
### Middleware logger
|
||||
https://fiber.wiki/middleware#logger
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/middleware#logger
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
"github.com/gofiber/logger"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// If you want to change default Logger config
|
||||
loggerConfig := middleware.LoggerConfig{
|
||||
|
||||
// Optional logger config
|
||||
config := logger.LoggerConfig{
|
||||
Format: "${time} - ${method} ${path}\n",
|
||||
TimeFormat: "Mon, 2 Jan 2006 15:04:05 MST",
|
||||
}
|
||||
|
||||
// Middleware for Logger with config
|
||||
app.Use(middleware.Logger(loggerConfig))
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Cross-Origin Resource Sharing (CORS)
|
||||
https://fiber.wiki/middleware#cors
|
||||
|
||||
[CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) is a mechanism that uses additional HTTP headers to tell browsers to give a web application running at one origin, access to selected resources from a different origin. A web application executes a cross-origin HTTP request when it requests a resource that has a different origin (domain, protocol, or port) from its own.
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Connect CORS for each route as middleware
|
||||
app.Use(middleware.CORS())
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
c.Send("CORS is enabled!")
|
||||
})
|
||||
// Logger with config
|
||||
app.Use(logger.New(config))
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
Check CORS by passing any domain in `Origin` header:
|
||||
### Cross-Origin Resource Sharing (CORS)
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/middleware#cors
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/cors"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// CORS with default config
|
||||
app.Use(cors.New())
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
Check CORS by passing any domain in `Origin` header:
|
||||
|
||||
```bash
|
||||
curl -H "Origin: http://example.com" --verbose http://localhost:3000
|
||||
@ -323,6 +340,12 @@ curl -H "Origin: http://example.com" --verbose http://localhost:3000
|
||||
|
||||
### Custom 404 response
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/application#http-methods
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
@ -339,7 +362,8 @@ func main() {
|
||||
|
||||
// Last middleware to match anything
|
||||
app.Use(func(c *fiber.Ctx) {
|
||||
c.SendStatus(404) // => 404 "Not Found"
|
||||
c.SendStatus(404)
|
||||
// => 404 "Not Found"
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
@ -347,7 +371,13 @@ func main() {
|
||||
```
|
||||
|
||||
### JSON Response
|
||||
https://fiber.wiki/context#json
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/context#json
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
type User struct {
|
||||
Name string `json:"name"`
|
||||
@ -359,71 +389,86 @@ func main() {
|
||||
|
||||
app.Get("/user", func(c *fiber.Ctx) {
|
||||
c.JSON(&User{"John", 20})
|
||||
// {"name":"John", "age":20}
|
||||
// => {"name":"John", "age":20}
|
||||
})
|
||||
|
||||
app.Get("/json", func(c *fiber.Ctx) {
|
||||
c.JSON(&fiber.Map{
|
||||
"success": true,
|
||||
"message": "Hi John!",
|
||||
c.JSON(fiber.Map{
|
||||
"success": true,
|
||||
"message": "Hi John!",
|
||||
})
|
||||
// {"success":true, "message":"Hi John!"}
|
||||
// => {"success":true, "message":"Hi John!"}
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
### WebSocket support
|
||||
https://fiber.wiki/application#websocket
|
||||
### WebSocket middleware
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/middleware#websocket
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/websocket"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.WebSocket("/ws", func(c *fiber.Conn) {
|
||||
app.Get("/ws", websocket.New(func(c *websocket.Conn) {
|
||||
for {
|
||||
mt, msg, err := c.ReadMessage()
|
||||
if err != nil {
|
||||
log.Println("read:", err)
|
||||
break
|
||||
}
|
||||
|
||||
log.Printf("recovery: %s", msg)
|
||||
|
||||
log.Printf("recv: %s", msg)
|
||||
err = c.WriteMessage(mt, msg)
|
||||
if err != nil {
|
||||
log.Println("write:", err)
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
}))
|
||||
|
||||
// Listen on ws://localhost:3000/ws
|
||||
app.Listen(3000)
|
||||
// ws://localhost:3000/ws
|
||||
}
|
||||
```
|
||||
|
||||
### Recover middleware
|
||||
https://fiber.wiki/middleware#recover
|
||||
```go
|
||||
package main
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/middleware#recover
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
"github.com/gofiber/recover"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(middleware.Recover(func(c *fiber.Ctx, err error) {
|
||||
log.Println(err) // "Something went wrong!"
|
||||
c.SendStatus(500) // Internal Server Error
|
||||
})))
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
panic("Something went wrong!")
|
||||
})
|
||||
// Optional recover config
|
||||
config := recover.LoggerConfig{
|
||||
Handler: func(c *fiber.Ctx, err error) {
|
||||
c.SendString(err.Error())
|
||||
c.SendStatus(500)
|
||||
},
|
||||
}
|
||||
|
||||
// Logger with custom config
|
||||
app.Use(recover.New(config))
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
|
203
.github/README_ru.md
vendored
203
.github/README_ru.md
vendored
@ -224,16 +224,16 @@ func main() {
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>📚 Показать больше примеров кода</summary>
|
||||
<summary>📚 Show more code examples</summary>
|
||||
|
||||
### Работа с шаблонами
|
||||
### Template engines
|
||||
|
||||
Документация:
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/application#settings
|
||||
- 📖 https://fiber.wiki/context#render
|
||||
|
||||
Поддерживаемые движки шаблонов:
|
||||
Supported engines:
|
||||
|
||||
- [html](https://golang.org/pkg/html/template/)
|
||||
- [amber](https://github.com/eknkc/amber)
|
||||
@ -241,138 +241,130 @@ func main() {
|
||||
- [mustache](https://github.com/cbroglie/mustache)
|
||||
- [pug](https://github.com/Joker/jade)
|
||||
|
||||
Пример:
|
||||
Example:
|
||||
|
||||
```go
|
||||
func main() {
|
||||
// Вы можете настроить нужный движок для шаблонов
|
||||
// перед инициализацией приложения:
|
||||
// You can setup template engine before initiation app:
|
||||
app := fiber.New(&fiber.Settings{
|
||||
TemplateEngine: "mustache",
|
||||
TemplateFolder: "./views",
|
||||
TemplateExtension: ".tmpl",
|
||||
})
|
||||
|
||||
// ИЛИ уже после инициализации приложения,
|
||||
// в любом удобном месте:
|
||||
// OR after initiation app at any convenient location:
|
||||
app.Settings.TemplateEngine = "mustache"
|
||||
app.Settings.TemplateFolder = "./views"
|
||||
app.Settings.TemplateExtension = ".tmpl"
|
||||
|
||||
// Теперь, вы сможете вызывать шаблон `./views/home.tmpl` вот так:
|
||||
// And now, you can call template `./views/home.tmpl` like this:
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
c.Render("home", fiber.Map{
|
||||
"title": "Homepage",
|
||||
"year": 1999,
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Группировка роутов в цепочки
|
||||
### Grouping routes into chains
|
||||
|
||||
Документация:
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/application#group
|
||||
|
||||
Пример:
|
||||
Example:
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Корневой API роут
|
||||
|
||||
// Root API route
|
||||
api := app.Group("/api", cors()) // /api
|
||||
|
||||
// Роуты для API v1
|
||||
|
||||
// API v1 routes
|
||||
v1 := api.Group("/v1", mysql()) // /api/v1
|
||||
v1.Get("/list", handler) // /api/v1/list
|
||||
v1.Get("/user", handler) // /api/v1/user
|
||||
|
||||
// Роуты для API v2
|
||||
|
||||
// API v2 routes
|
||||
v2 := api.Group("/v2", mongodb()) // /api/v2
|
||||
v2.Get("/list", handler) // /api/v2/list
|
||||
v2.Get("/user", handler) // /api/v2/user
|
||||
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Встроенный логгер
|
||||
### Middleware logger
|
||||
|
||||
Документация:
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/middleware#logger
|
||||
|
||||
Пример:
|
||||
Example:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
"github.com/gofiber/logger"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Если вы хотите изменить конфигурацию логгера по умолчанию
|
||||
loggerConfig := middleware.LoggerConfig{
|
||||
|
||||
// Optional logger config
|
||||
config := logger.LoggerConfig{
|
||||
Format: "${time} - ${method} ${path}\n",
|
||||
TimeFormat: "Mon, 2 Jan 2006 15:04:05 MST",
|
||||
}
|
||||
|
||||
// Middleware для логгера с кастомным конфигом
|
||||
app.Use(middleware.Logger(loggerConfig))
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Cross-Origin Resource Sharing (CORS)
|
||||
|
||||
Документация:
|
||||
|
||||
- 📖 https://fiber.wiki/middleware#cors
|
||||
|
||||
> [CORS](https://developer.mozilla.org/ru/docs/Web/HTTP/CORS) — это механизм, использующий дополнительные HTTP-заголовки, чтобы дать возможность агенту пользователя получать разрешения на доступ к выбранным ресурсам с сервера на источнике (домене), отличном от того, что сайт использует в данный момент.
|
||||
|
||||
Пример:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Подключаем CORS для каждого роута в качестве middleware
|
||||
app.Use(middleware.CORS())
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
c.Send("CORS is enabled!")
|
||||
})
|
||||
// Logger with config
|
||||
app.Use(logger.New(config))
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
Проверьте работу CORS, передав любой домен в заголовке `Origin`:
|
||||
### Cross-Origin Resource Sharing (CORS)
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/middleware#cors
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/cors"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// CORS with default config
|
||||
app.Use(cors.New())
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
Check CORS by passing any domain in `Origin` header:
|
||||
|
||||
```bash
|
||||
curl -H "Origin: http://example.com" --verbose http://localhost:3000
|
||||
```
|
||||
|
||||
### Обработка 404 ошибки
|
||||
### Custom 404 response
|
||||
|
||||
Документация:
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/application#http-methods
|
||||
|
||||
Пример:
|
||||
Example:
|
||||
|
||||
```go
|
||||
func main() {
|
||||
@ -390,102 +382,117 @@ func main() {
|
||||
|
||||
// Last middleware to match anything
|
||||
app.Use(func(c *fiber.Ctx) {
|
||||
c.SendStatus(404) // => 404 "Not Found"
|
||||
c.SendStatus(404)
|
||||
// => 404 "Not Found"
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
### Ответ в формате JSON
|
||||
### JSON Response
|
||||
|
||||
Документация:
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/context#json
|
||||
|
||||
Пример:
|
||||
Example:
|
||||
|
||||
```go
|
||||
type User struct {
|
||||
Name string `json:"name"`
|
||||
Age int `json:"age"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
type User struct {
|
||||
Name string `json:"name"`
|
||||
Age int `json:"age"`
|
||||
}
|
||||
|
||||
// Serialize JSON
|
||||
app.Get("/json", func(c *fiber.Ctx) {
|
||||
app.Get("/user", func(c *fiber.Ctx) {
|
||||
c.JSON(&User{"John", 20})
|
||||
// => {"name":"John", "age":20}
|
||||
})
|
||||
|
||||
app.Get("/json", func(c *fiber.Ctx) {
|
||||
c.JSON(fiber.Map{
|
||||
"success": true,
|
||||
"message": "Hi John!",
|
||||
})
|
||||
// => {"success":true, "message":"Hi John!"}
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
### Поддержка WebSocket
|
||||
### WebSocket middleware
|
||||
|
||||
Документация:
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/application#websocket
|
||||
- 📖 https://fiber.wiki/middleware#websocket
|
||||
|
||||
Пример:
|
||||
Example:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/websocket"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.WebSocket("/ws/:name", func(c *fiber.Conn) {
|
||||
log.Println(c.Params("name"))
|
||||
|
||||
app.Get("/ws", websocket.New(func(c *websocket.Conn) {
|
||||
for {
|
||||
mt, msg, err := c.ReadMessage()
|
||||
if err != nil {
|
||||
log.Println("read:", err)
|
||||
break
|
||||
}
|
||||
|
||||
log.Printf("recovery: %s", msg)
|
||||
|
||||
log.Printf("recv: %s", msg)
|
||||
err = c.WriteMessage(mt, msg)
|
||||
if err != nil {
|
||||
log.Println("write:", err)
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
}))
|
||||
|
||||
// Слушаем вебсокет по адресу ws://localhost:3000/ws/john
|
||||
app.Listen(3000)
|
||||
// ws://localhost:3000/ws
|
||||
}
|
||||
```
|
||||
|
||||
### Восстановление работы после `panic`
|
||||
### Recover middleware
|
||||
|
||||
Документация:
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/middleware#recover
|
||||
|
||||
Пример:
|
||||
Example:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/recover"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
panic("Something went wrong!")
|
||||
})
|
||||
// Optional recover config
|
||||
config := recover.LoggerConfig{
|
||||
Handler: func(c *fiber.Ctx, err error) {
|
||||
c.SendString(err.Error())
|
||||
c.SendStatus(500)
|
||||
},
|
||||
}
|
||||
|
||||
app.Recover(func(c *fiber.Ctx) {
|
||||
c.Status(500).Send(c.Error())
|
||||
// => 500 "Something went wrong!"
|
||||
})
|
||||
// Logger with custom config
|
||||
app.Use(recover.New(config))
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## 🧬 Доступные Middleware
|
||||
|
171
.github/README_tr.md
vendored
171
.github/README_tr.md
vendored
@ -207,16 +207,22 @@ func main() {
|
||||
<summary>📚 Show more code examples</summary>
|
||||
|
||||
### Template engines
|
||||
https://fiber.wiki/application#settings
|
||||
https://fiber.wiki/context#render
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/application#settings
|
||||
- 📖 https://fiber.wiki/context#render
|
||||
|
||||
Supported engines:
|
||||
|
||||
- [html](https://golang.org/pkg/html/template/)
|
||||
- [amber](https://github.com/eknkc/amber)
|
||||
- [handlebars](https://github.com/aymerick/raymond)
|
||||
- [mustache](https://github.com/cbroglie/mustache)
|
||||
- [pug](https://github.com/Joker/jade)
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
func main() {
|
||||
// You can setup template engine before initiation app:
|
||||
@ -244,7 +250,13 @@ func main() {
|
||||
```
|
||||
|
||||
### Grouping routes into chains
|
||||
https://fiber.wiki/application#group
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/application#group
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
@ -267,55 +279,60 @@ func main() {
|
||||
```
|
||||
|
||||
### Middleware logger
|
||||
https://fiber.wiki/middleware#logger
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/middleware#logger
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
"github.com/gofiber/logger"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// If you want to change default Logger config
|
||||
loggerConfig := middleware.LoggerConfig{
|
||||
|
||||
// Optional logger config
|
||||
config := logger.LoggerConfig{
|
||||
Format: "${time} - ${method} ${path}\n",
|
||||
TimeFormat: "Mon, 2 Jan 2006 15:04:05 MST",
|
||||
}
|
||||
|
||||
// Middleware for Logger with config
|
||||
app.Use(middleware.Logger(loggerConfig))
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Cross-Origin Resource Sharing (CORS)
|
||||
https://fiber.wiki/middleware#cors
|
||||
|
||||
[CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) is a mechanism that uses additional HTTP headers to tell browsers to give a web application running at one origin, access to selected resources from a different origin. A web application executes a cross-origin HTTP request when it requests a resource that has a different origin (domain, protocol, or port) from its own.
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Connect CORS for each route as middleware
|
||||
app.Use(middleware.CORS())
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
c.Send("CORS is enabled!")
|
||||
})
|
||||
// Logger with config
|
||||
app.Use(logger.New(config))
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
Check CORS by passing any domain in `Origin` header:
|
||||
### Cross-Origin Resource Sharing (CORS)
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/middleware#cors
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/cors"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// CORS with default config
|
||||
app.Use(cors.New())
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
Check CORS by passing any domain in `Origin` header:
|
||||
|
||||
```bash
|
||||
curl -H "Origin: http://example.com" --verbose http://localhost:3000
|
||||
@ -323,6 +340,12 @@ curl -H "Origin: http://example.com" --verbose http://localhost:3000
|
||||
|
||||
### Custom 404 response
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/application#http-methods
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
@ -339,7 +362,8 @@ func main() {
|
||||
|
||||
// Last middleware to match anything
|
||||
app.Use(func(c *fiber.Ctx) {
|
||||
c.SendStatus(404) // => 404 "Not Found"
|
||||
c.SendStatus(404)
|
||||
// => 404 "Not Found"
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
@ -347,7 +371,13 @@ func main() {
|
||||
```
|
||||
|
||||
### JSON Response
|
||||
https://fiber.wiki/context#json
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/context#json
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
type User struct {
|
||||
Name string `json:"name"`
|
||||
@ -359,71 +389,86 @@ func main() {
|
||||
|
||||
app.Get("/user", func(c *fiber.Ctx) {
|
||||
c.JSON(&User{"John", 20})
|
||||
// {"name":"John", "age":20}
|
||||
// => {"name":"John", "age":20}
|
||||
})
|
||||
|
||||
app.Get("/json", func(c *fiber.Ctx) {
|
||||
c.JSON(&fiber.Map{
|
||||
"success": true,
|
||||
"message": "Hi John!",
|
||||
c.JSON(fiber.Map{
|
||||
"success": true,
|
||||
"message": "Hi John!",
|
||||
})
|
||||
// {"success":true, "message":"Hi John!"}
|
||||
// => {"success":true, "message":"Hi John!"}
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
### WebSocket support
|
||||
https://fiber.wiki/application#websocket
|
||||
### WebSocket middleware
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/middleware#websocket
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/websocket"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.WebSocket("/ws", func(c *fiber.Conn) {
|
||||
app.Get("/ws", websocket.New(func(c *websocket.Conn) {
|
||||
for {
|
||||
mt, msg, err := c.ReadMessage()
|
||||
if err != nil {
|
||||
log.Println("read:", err)
|
||||
break
|
||||
}
|
||||
|
||||
log.Printf("recovery: %s", msg)
|
||||
|
||||
log.Printf("recv: %s", msg)
|
||||
err = c.WriteMessage(mt, msg)
|
||||
if err != nil {
|
||||
log.Println("write:", err)
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
}))
|
||||
|
||||
// Listen on ws://localhost:3000/ws
|
||||
app.Listen(3000)
|
||||
// ws://localhost:3000/ws
|
||||
}
|
||||
```
|
||||
|
||||
### Recover middleware
|
||||
https://fiber.wiki/middleware#recover
|
||||
```go
|
||||
package main
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/middleware#recover
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
"github.com/gofiber/recover"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(middleware.Recover(func(c *fiber.Ctx, err error) {
|
||||
log.Println(err) // "Something went wrong!"
|
||||
c.SendStatus(500) // Internal Server Error
|
||||
})))
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
panic("Something went wrong!")
|
||||
})
|
||||
// Optional recover config
|
||||
config := recover.LoggerConfig{
|
||||
Handler: func(c *fiber.Ctx, err error) {
|
||||
c.SendString(err.Error())
|
||||
c.SendStatus(500)
|
||||
},
|
||||
}
|
||||
|
||||
// Logger with custom config
|
||||
app.Use(recover.New(config))
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
|
171
.github/README_zh-CN.md
vendored
171
.github/README_zh-CN.md
vendored
@ -207,16 +207,22 @@ func main() {
|
||||
<summary>📚 Show more code examples</summary>
|
||||
|
||||
### Template engines
|
||||
https://fiber.wiki/application#settings
|
||||
https://fiber.wiki/context#render
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/application#settings
|
||||
- 📖 https://fiber.wiki/context#render
|
||||
|
||||
Supported engines:
|
||||
|
||||
- [html](https://golang.org/pkg/html/template/)
|
||||
- [amber](https://github.com/eknkc/amber)
|
||||
- [handlebars](https://github.com/aymerick/raymond)
|
||||
- [mustache](https://github.com/cbroglie/mustache)
|
||||
- [pug](https://github.com/Joker/jade)
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
func main() {
|
||||
// You can setup template engine before initiation app:
|
||||
@ -244,7 +250,13 @@ func main() {
|
||||
```
|
||||
|
||||
### Grouping routes into chains
|
||||
https://fiber.wiki/application#group
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/application#group
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
@ -267,55 +279,60 @@ func main() {
|
||||
```
|
||||
|
||||
### Middleware logger
|
||||
https://fiber.wiki/middleware#logger
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/middleware#logger
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
"github.com/gofiber/logger"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// If you want to change default Logger config
|
||||
loggerConfig := middleware.LoggerConfig{
|
||||
|
||||
// Optional logger config
|
||||
config := logger.LoggerConfig{
|
||||
Format: "${time} - ${method} ${path}\n",
|
||||
TimeFormat: "Mon, 2 Jan 2006 15:04:05 MST",
|
||||
}
|
||||
|
||||
// Middleware for Logger with config
|
||||
app.Use(middleware.Logger(loggerConfig))
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Cross-Origin Resource Sharing (CORS)
|
||||
https://fiber.wiki/middleware#cors
|
||||
|
||||
[CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) is a mechanism that uses additional HTTP headers to tell browsers to give a web application running at one origin, access to selected resources from a different origin. A web application executes a cross-origin HTTP request when it requests a resource that has a different origin (domain, protocol, or port) from its own.
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Connect CORS for each route as middleware
|
||||
app.Use(middleware.CORS())
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
c.Send("CORS is enabled!")
|
||||
})
|
||||
// Logger with config
|
||||
app.Use(logger.New(config))
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
Check CORS by passing any domain in `Origin` header:
|
||||
### Cross-Origin Resource Sharing (CORS)
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/middleware#cors
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/cors"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// CORS with default config
|
||||
app.Use(cors.New())
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
Check CORS by passing any domain in `Origin` header:
|
||||
|
||||
```bash
|
||||
curl -H "Origin: http://example.com" --verbose http://localhost:3000
|
||||
@ -323,6 +340,12 @@ curl -H "Origin: http://example.com" --verbose http://localhost:3000
|
||||
|
||||
### Custom 404 response
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/application#http-methods
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
@ -339,7 +362,8 @@ func main() {
|
||||
|
||||
// Last middleware to match anything
|
||||
app.Use(func(c *fiber.Ctx) {
|
||||
c.SendStatus(404) // => 404 "Not Found"
|
||||
c.SendStatus(404)
|
||||
// => 404 "Not Found"
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
@ -347,7 +371,13 @@ func main() {
|
||||
```
|
||||
|
||||
### JSON Response
|
||||
https://fiber.wiki/context#json
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/context#json
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
type User struct {
|
||||
Name string `json:"name"`
|
||||
@ -359,71 +389,86 @@ func main() {
|
||||
|
||||
app.Get("/user", func(c *fiber.Ctx) {
|
||||
c.JSON(&User{"John", 20})
|
||||
// {"name":"John", "age":20}
|
||||
// => {"name":"John", "age":20}
|
||||
})
|
||||
|
||||
app.Get("/json", func(c *fiber.Ctx) {
|
||||
c.JSON(&fiber.Map{
|
||||
"success": true,
|
||||
"message": "Hi John!",
|
||||
c.JSON(fiber.Map{
|
||||
"success": true,
|
||||
"message": "Hi John!",
|
||||
})
|
||||
// {"success":true, "message":"Hi John!"}
|
||||
// => {"success":true, "message":"Hi John!"}
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
### WebSocket support
|
||||
https://fiber.wiki/application#websocket
|
||||
### WebSocket middleware
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/middleware#websocket
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/websocket"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.WebSocket("/ws", func(c *fiber.Conn) {
|
||||
app.Get("/ws", websocket.New(func(c *websocket.Conn) {
|
||||
for {
|
||||
mt, msg, err := c.ReadMessage()
|
||||
if err != nil {
|
||||
log.Println("read:", err)
|
||||
break
|
||||
}
|
||||
|
||||
log.Printf("recovery: %s", msg)
|
||||
|
||||
log.Printf("recv: %s", msg)
|
||||
err = c.WriteMessage(mt, msg)
|
||||
if err != nil {
|
||||
log.Println("write:", err)
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
}))
|
||||
|
||||
// Listen on ws://localhost:3000/ws
|
||||
app.Listen(3000)
|
||||
// ws://localhost:3000/ws
|
||||
}
|
||||
```
|
||||
|
||||
### Recover middleware
|
||||
https://fiber.wiki/middleware#recover
|
||||
```go
|
||||
package main
|
||||
|
||||
Docs:
|
||||
|
||||
- 📖 https://fiber.wiki/middleware#recover
|
||||
|
||||
Example:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
"github.com/gofiber/recover"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(middleware.Recover(func(c *fiber.Ctx, err error) {
|
||||
log.Println(err) // "Something went wrong!"
|
||||
c.SendStatus(500) // Internal Server Error
|
||||
})))
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
panic("Something went wrong!")
|
||||
})
|
||||
// Optional recover config
|
||||
config := recover.LoggerConfig{
|
||||
Handler: func(c *fiber.Ctx, err error) {
|
||||
c.SendString(err.Error())
|
||||
c.SendStatus(500)
|
||||
},
|
||||
}
|
||||
|
||||
// Logger with custom config
|
||||
app.Use(recover.New(config))
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
|
15
.travis.yml
15
.travis.yml
@ -1,4 +1,5 @@
|
||||
language: go
|
||||
sudo: false
|
||||
|
||||
os:
|
||||
- linux
|
||||
@ -6,9 +7,17 @@ os:
|
||||
- osx
|
||||
go:
|
||||
- 1.11.x
|
||||
- 1.12.x
|
||||
- 1.13.x
|
||||
- 1.14.x
|
||||
env:
|
||||
- GO111MODULE=on
|
||||
install:
|
||||
#- go get -v golang.org/x/lint/golint
|
||||
script:
|
||||
- go test
|
||||
# build test for supported platforms
|
||||
- GOOS=linux go build
|
||||
- GOOS=darwin go build
|
||||
- GOOS=freebsd go build
|
||||
- GOOS=windows go build
|
||||
- GOARCH=386 go build
|
||||
- go test -v
|
||||
- go test -race -v
|
||||
|
@ -8,7 +8,6 @@ import (
|
||||
"bufio"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
@ -25,7 +24,7 @@ import (
|
||||
)
|
||||
|
||||
// Version of Fiber
|
||||
const Version = "1.8.33"
|
||||
const Version = "1.8.4"
|
||||
|
||||
type (
|
||||
// App denotes the Fiber application.
|
||||
@ -33,7 +32,6 @@ type (
|
||||
server *fasthttp.Server // Fasthttp server settings
|
||||
routes []*Route // Route stack
|
||||
child bool // If current process is a child ( for prefork )
|
||||
recover func(*Ctx) // Deprecated, use middleware.Recover
|
||||
Settings *Settings // Fiber settings
|
||||
}
|
||||
// Map defines a generic map of type `map[string]interface{}`.
|
||||
@ -50,19 +48,23 @@ type (
|
||||
ServerHeader string `default:""`
|
||||
// Enables handler values to be immutable even if you return from handler
|
||||
Immutable bool `default:"false"`
|
||||
// Deprecated v1.8.2
|
||||
Compression bool `default:"false"`
|
||||
// Max body size that the server accepts
|
||||
BodyLimit int `default:"4 * 1024 * 1024"`
|
||||
// Folder containing template files
|
||||
TemplateFolder string `default:""`
|
||||
// Template engine: html, amber, handlebars , mustache or pug
|
||||
TemplateEngine string `default:""`
|
||||
TemplateEngine func(raw string, bind interface{}) (string, error) `default:""`
|
||||
// Extension for the template files
|
||||
TemplateExtension string `default:""`
|
||||
}
|
||||
)
|
||||
|
||||
// Group struct
|
||||
type Group struct {
|
||||
prefix string
|
||||
app *App
|
||||
}
|
||||
|
||||
// This method creates a new Fiber named instance.
|
||||
// You can pass optional settings when creating a new instance.
|
||||
//
|
||||
@ -99,11 +101,6 @@ func New(settings ...*Settings) *App {
|
||||
getBytes = func(s string) []byte { return []byte(s) }
|
||||
}
|
||||
}
|
||||
// This function is deprecated since v1.8.2!
|
||||
// Please us github.com/gofiber/compression
|
||||
if app.Settings.Compression {
|
||||
log.Println("Warning: Settings.Compression is deprecated since v1.8.2, please use github.com/gofiber/compression instead.")
|
||||
}
|
||||
return app
|
||||
}
|
||||
|
||||
@ -176,55 +173,55 @@ func (app *App) Use(args ...interface{}) *App {
|
||||
|
||||
// Connect : https://fiber.wiki/application#http-methods
|
||||
func (app *App) Connect(path string, handlers ...func(*Ctx)) *App {
|
||||
app.registerMethod(http.MethodConnect, path, handlers...)
|
||||
app.registerMethod(MethodConnect, path, handlers...)
|
||||
return app
|
||||
}
|
||||
|
||||
// Put : https://fiber.wiki/application#http-methods
|
||||
func (app *App) Put(path string, handlers ...func(*Ctx)) *App {
|
||||
app.registerMethod(http.MethodPut, path, handlers...)
|
||||
app.registerMethod(MethodPut, path, handlers...)
|
||||
return app
|
||||
}
|
||||
|
||||
// Post : https://fiber.wiki/application#http-methods
|
||||
func (app *App) Post(path string, handlers ...func(*Ctx)) *App {
|
||||
app.registerMethod(http.MethodPost, path, handlers...)
|
||||
app.registerMethod(MethodPost, path, handlers...)
|
||||
return app
|
||||
}
|
||||
|
||||
// Delete : https://fiber.wiki/application#http-methods
|
||||
func (app *App) Delete(path string, handlers ...func(*Ctx)) *App {
|
||||
app.registerMethod(http.MethodDelete, path, handlers...)
|
||||
app.registerMethod(MethodDelete, path, handlers...)
|
||||
return app
|
||||
}
|
||||
|
||||
// Head : https://fiber.wiki/application#http-methods
|
||||
func (app *App) Head(path string, handlers ...func(*Ctx)) *App {
|
||||
app.registerMethod(http.MethodHead, path, handlers...)
|
||||
app.registerMethod(MethodHead, path, handlers...)
|
||||
return app
|
||||
}
|
||||
|
||||
// Patch : https://fiber.wiki/application#http-methods
|
||||
func (app *App) Patch(path string, handlers ...func(*Ctx)) *App {
|
||||
app.registerMethod(http.MethodPatch, path, handlers...)
|
||||
app.registerMethod(MethodPatch, path, handlers...)
|
||||
return app
|
||||
}
|
||||
|
||||
// Options : https://fiber.wiki/application#http-methods
|
||||
func (app *App) Options(path string, handlers ...func(*Ctx)) *App {
|
||||
app.registerMethod(http.MethodOptions, path, handlers...)
|
||||
app.registerMethod(MethodOptions, path, handlers...)
|
||||
return app
|
||||
}
|
||||
|
||||
// Trace : https://fiber.wiki/application#http-methods
|
||||
func (app *App) Trace(path string, handlers ...func(*Ctx)) *App {
|
||||
app.registerMethod(http.MethodTrace, path, handlers...)
|
||||
app.registerMethod(MethodTrace, path, handlers...)
|
||||
return app
|
||||
}
|
||||
|
||||
// Get : https://fiber.wiki/application#http-methods
|
||||
func (app *App) Get(path string, handlers ...func(*Ctx)) *App {
|
||||
app.registerMethod(http.MethodGet, path, handlers...)
|
||||
app.registerMethod(MethodGet, path, handlers...)
|
||||
return app
|
||||
}
|
||||
|
||||
@ -240,19 +237,114 @@ func (app *App) All(path string, handlers ...func(*Ctx)) *App {
|
||||
return app
|
||||
}
|
||||
|
||||
// This function is deprecated since v1.8.2!
|
||||
// Please us github.com/gofiber/websocket
|
||||
func (app *App) WebSocket(path string, handle func(*Ctx)) *App {
|
||||
log.Println("Warning: app.WebSocket() is deprecated since v1.8.2, please use github.com/gofiber/websocket instead.")
|
||||
app.registerWebSocket(http.MethodGet, path, handle)
|
||||
return app
|
||||
// Group : https://fiber.wiki/application#group
|
||||
func (grp *Group) Group(prefix string, handlers ...func(*Ctx)) *Group {
|
||||
prefix = groupPaths(grp.prefix, prefix)
|
||||
if len(handlers) > 0 {
|
||||
grp.app.registerMethod("USE", prefix, handlers...)
|
||||
}
|
||||
return &Group{
|
||||
prefix: prefix,
|
||||
app: grp.app,
|
||||
}
|
||||
}
|
||||
|
||||
// This function is deprecated since v1.8.2!
|
||||
// Please us github.com/gofiber/recover
|
||||
func (app *App) Recover(handler func(*Ctx)) {
|
||||
log.Println("Warning: app.Recover() is deprecated since v1.8.2, please use github.com/gofiber/recover instead.")
|
||||
app.recover = handler
|
||||
// Static : https://fiber.wiki/application#static
|
||||
func (grp *Group) Static(prefix, root string, config ...Static) *Group {
|
||||
prefix = groupPaths(grp.prefix, prefix)
|
||||
grp.app.registerStatic(prefix, root, config...)
|
||||
return grp
|
||||
}
|
||||
|
||||
// Use only match requests starting with the specified prefix
|
||||
// It's optional to provide a prefix, default: "/"
|
||||
// Example: Use("/product", handler)
|
||||
// will match /product
|
||||
// will match /product/cool
|
||||
// will match /product/foo
|
||||
//
|
||||
// https://fiber.wiki/application#http-methods
|
||||
func (grp *Group) Use(args ...interface{}) *Group {
|
||||
var path = ""
|
||||
var handlers []func(*Ctx)
|
||||
for i := 0; i < len(args); i++ {
|
||||
switch arg := args[i].(type) {
|
||||
case string:
|
||||
path = arg
|
||||
case func(*Ctx):
|
||||
handlers = append(handlers, arg)
|
||||
default:
|
||||
log.Fatalf("Invalid Use() arguments, must be (prefix, handler) or (handler)")
|
||||
}
|
||||
}
|
||||
grp.app.registerMethod("USE", groupPaths(grp.prefix, path), handlers...)
|
||||
return grp
|
||||
}
|
||||
|
||||
// Connect : https://fiber.wiki/application#http-methods
|
||||
func (grp *Group) Connect(path string, handlers ...func(*Ctx)) *Group {
|
||||
grp.app.registerMethod(MethodConnect, groupPaths(grp.prefix, path), handlers...)
|
||||
return grp
|
||||
}
|
||||
|
||||
// Put : https://fiber.wiki/application#http-methods
|
||||
func (grp *Group) Put(path string, handlers ...func(*Ctx)) *Group {
|
||||
grp.app.registerMethod(MethodPut, groupPaths(grp.prefix, path), handlers...)
|
||||
return grp
|
||||
}
|
||||
|
||||
// Post : https://fiber.wiki/application#http-methods
|
||||
func (grp *Group) Post(path string, handlers ...func(*Ctx)) *Group {
|
||||
grp.app.registerMethod(MethodPost, groupPaths(grp.prefix, path), handlers...)
|
||||
return grp
|
||||
}
|
||||
|
||||
// Delete : https://fiber.wiki/application#http-methods
|
||||
func (grp *Group) Delete(path string, handlers ...func(*Ctx)) *Group {
|
||||
grp.app.registerMethod(MethodDelete, groupPaths(grp.prefix, path), handlers...)
|
||||
return grp
|
||||
}
|
||||
|
||||
// Head : https://fiber.wiki/application#http-methods
|
||||
func (grp *Group) Head(path string, handlers ...func(*Ctx)) *Group {
|
||||
grp.app.registerMethod(MethodHead, groupPaths(grp.prefix, path), handlers...)
|
||||
return grp
|
||||
}
|
||||
|
||||
// Patch : https://fiber.wiki/application#http-methods
|
||||
func (grp *Group) Patch(path string, handlers ...func(*Ctx)) *Group {
|
||||
grp.app.registerMethod(MethodPatch, groupPaths(grp.prefix, path), handlers...)
|
||||
return grp
|
||||
}
|
||||
|
||||
// Options : https://fiber.wiki/application#http-methods
|
||||
func (grp *Group) Options(path string, handlers ...func(*Ctx)) *Group {
|
||||
grp.app.registerMethod(MethodOptions, groupPaths(grp.prefix, path), handlers...)
|
||||
return grp
|
||||
}
|
||||
|
||||
// Trace : https://fiber.wiki/application#http-methods
|
||||
func (grp *Group) Trace(path string, handlers ...func(*Ctx)) *Group {
|
||||
grp.app.registerMethod(MethodTrace, groupPaths(grp.prefix, path), handlers...)
|
||||
return grp
|
||||
}
|
||||
|
||||
// Get : https://fiber.wiki/application#http-methods
|
||||
func (grp *Group) Get(path string, handlers ...func(*Ctx)) *Group {
|
||||
grp.app.registerMethod(MethodGet, groupPaths(grp.prefix, path), handlers...)
|
||||
return grp
|
||||
}
|
||||
|
||||
// All matches all HTTP methods and complete paths
|
||||
// Example: All("/product", handler)
|
||||
// will match /product
|
||||
// won't match /product/cool <-- important
|
||||
// won't match /product/foo <-- important
|
||||
//
|
||||
// https://fiber.wiki/application#http-methods
|
||||
func (grp *Group) All(path string, handlers ...func(*Ctx)) *Group {
|
||||
grp.app.registerMethod("ALL", groupPaths(grp.prefix, path), handlers...)
|
||||
return grp
|
||||
}
|
||||
|
||||
// Listen : https://fiber.wiki/application#listen
|
||||
@ -304,19 +396,22 @@ func (app *App) Shutdown() error {
|
||||
}
|
||||
|
||||
// Test : https://fiber.wiki/application#test
|
||||
func (app *App) Test(request *http.Request) (*http.Response, error) {
|
||||
// Get raw http request
|
||||
reqRaw, err := httputil.DumpRequest(request, true)
|
||||
func (app *App) Test(request *http.Request, msTimeout ...int) (*http.Response, error) {
|
||||
timeout := 200
|
||||
if len(msTimeout) > 0 {
|
||||
timeout = msTimeout[0]
|
||||
}
|
||||
// Dump raw http request
|
||||
dump, err := httputil.DumpRequest(request, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Setup a fiber server struct
|
||||
// Setup server
|
||||
app.server = app.newServer()
|
||||
// Create fake connection
|
||||
conn := &testConn{}
|
||||
// Pass HTTP request to conn
|
||||
_, err = conn.r.Write(reqRaw)
|
||||
if err != nil {
|
||||
// Create conn
|
||||
conn := new(testConn)
|
||||
// Write raw http request
|
||||
if _, err = conn.r.Write(dump); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Serve conn to server
|
||||
@ -324,25 +419,28 @@ func (app *App) Test(request *http.Request) (*http.Response, error) {
|
||||
go func() {
|
||||
channel <- app.server.ServeConn(conn)
|
||||
}()
|
||||
// Wait for callback
|
||||
select {
|
||||
case err := <-channel:
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if timeout < 0 {
|
||||
// Wait for callback
|
||||
select {
|
||||
case err := <-channel:
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Wait for callback
|
||||
select {
|
||||
case err := <-channel:
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case <-time.After(time.Duration(timeout) * time.Millisecond):
|
||||
return nil, fmt.Errorf("Timeout error")
|
||||
}
|
||||
// Throw timeout error after 200ms
|
||||
case <-time.After(200 * time.Millisecond):
|
||||
return nil, fmt.Errorf("timeout")
|
||||
}
|
||||
// Get raw HTTP response
|
||||
respRaw, err := ioutil.ReadAll(&conn.w)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Create buffer
|
||||
reader := strings.NewReader(getString(respRaw))
|
||||
buffer := bufio.NewReader(reader)
|
||||
// Convert raw HTTP response to http.Response
|
||||
// Read response
|
||||
buffer := bufio.NewReader(&conn.w)
|
||||
// Convert raw http response to *http.Response
|
||||
resp, err := http.ReadResponse(buffer, request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -393,9 +491,9 @@ func (app *App) prefork(address string) (ln net.Listener, err error) {
|
||||
return ln, err
|
||||
}
|
||||
|
||||
type disableLogger struct{}
|
||||
type customLogger struct{}
|
||||
|
||||
func (dl *disableLogger) Printf(format string, args ...interface{}) {
|
||||
func (cl *customLogger) Printf(format string, args ...interface{}) {
|
||||
// fmt.Println(fmt.Sprintf(format, args...))
|
||||
}
|
||||
|
||||
@ -405,7 +503,7 @@ func (app *App) newServer() *fasthttp.Server {
|
||||
Name: app.Settings.ServerHeader,
|
||||
MaxRequestBodySize: app.Settings.BodyLimit,
|
||||
NoDefaultServerHeader: app.Settings.ServerHeader == "",
|
||||
Logger: &disableLogger{},
|
||||
Logger: &customLogger{},
|
||||
LogAllErrors: false,
|
||||
ErrorHandler: func(ctx *fasthttp.RequestCtx, err error) {
|
||||
if err.Error() == "body size exceeds the given limit" {
|
103
context.go
103
context.go
@ -5,8 +5,10 @@
|
||||
package fiber
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"mime"
|
||||
@ -18,8 +20,6 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
websocket "github.com/fasthttp/websocket"
|
||||
template "github.com/gofiber/template"
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
fasthttp "github.com/valyala/fasthttp"
|
||||
)
|
||||
@ -34,7 +34,6 @@ type Ctx struct {
|
||||
method string // HTTP method
|
||||
path string // HTTP path
|
||||
values []string // Route parameter values
|
||||
compress bool // If the response needs to be compressed
|
||||
Fasthttp *fasthttp.RequestCtx // Reference to *fasthttp.RequestCtx
|
||||
err error // Contains error if catched
|
||||
}
|
||||
@ -57,6 +56,7 @@ type Cookie struct {
|
||||
Expires time.Time
|
||||
Secure bool
|
||||
HTTPOnly bool
|
||||
SameSite string
|
||||
}
|
||||
|
||||
// Ctx pool
|
||||
@ -80,37 +80,11 @@ func acquireCtx(fctx *fasthttp.RequestCtx) *Ctx {
|
||||
func releaseCtx(ctx *Ctx) {
|
||||
ctx.route = nil
|
||||
ctx.values = nil
|
||||
ctx.compress = false
|
||||
ctx.Fasthttp = nil
|
||||
ctx.err = nil
|
||||
poolCtx.Put(ctx)
|
||||
}
|
||||
|
||||
// Conn https://godoc.org/github.com/gorilla/websocket#pkg-index
|
||||
type Conn struct {
|
||||
*websocket.Conn
|
||||
}
|
||||
|
||||
// Conn pool
|
||||
var poolConn = sync.Pool{
|
||||
New: func() interface{} {
|
||||
return new(Conn)
|
||||
},
|
||||
}
|
||||
|
||||
// Acquire Conn from pool
|
||||
func acquireConn(fconn *websocket.Conn) *Conn {
|
||||
conn := poolConn.Get().(*Conn)
|
||||
conn.Conn = fconn
|
||||
return conn
|
||||
}
|
||||
|
||||
// Return Conn to pool
|
||||
func releaseConn(conn *Conn) {
|
||||
conn.Conn = nil
|
||||
poolConn.Put(conn)
|
||||
}
|
||||
|
||||
// Checks, if the specified extensions or content types are acceptable.
|
||||
//
|
||||
// https://fiber.wiki/context#accepts
|
||||
@ -125,7 +99,7 @@ func (ctx *Ctx) Accepts(offers ...string) (offer string) {
|
||||
|
||||
specs := strings.Split(h, ",")
|
||||
for _, value := range offers {
|
||||
mimetype := getType(value)
|
||||
mimetype := getMIME(value)
|
||||
// if mimetype != "" {
|
||||
// mimetype = strings.Split(mimetype, ";")[0]
|
||||
// } else {
|
||||
@ -343,16 +317,6 @@ func (ctx *Ctx) ClearCookie(key ...string) {
|
||||
})
|
||||
}
|
||||
|
||||
// This function is deprecated since v1.8.2!
|
||||
// Please us github.com/gofiber/compression
|
||||
func (ctx *Ctx) Compress(enable ...bool) {
|
||||
log.Println("Warning: c.Compress() is deprecated since v1.8.2, please use github.com/gofiber/compression instead.")
|
||||
ctx.compress = true
|
||||
if len(enable) > 0 {
|
||||
ctx.compress = enable[0]
|
||||
}
|
||||
}
|
||||
|
||||
// Set cookie by passing a cookie struct
|
||||
//
|
||||
// https://fiber.wiki/context#cookie
|
||||
@ -364,7 +328,23 @@ func (ctx *Ctx) Cookie(cookie *Cookie) {
|
||||
fcookie.SetDomain(cookie.Domain)
|
||||
fcookie.SetExpire(cookie.Expires)
|
||||
fcookie.SetSecure(cookie.Secure)
|
||||
if cookie.Secure {
|
||||
// Secure must be paired with SameSite=None
|
||||
fcookie.SetSameSite(fasthttp.CookieSameSiteNoneMode)
|
||||
}
|
||||
fcookie.SetHTTPOnly(cookie.HTTPOnly)
|
||||
switch strings.ToLower(cookie.SameSite) {
|
||||
case "lax":
|
||||
fcookie.SetSameSite(fasthttp.CookieSameSiteLaxMode)
|
||||
case "strict":
|
||||
fcookie.SetSameSite(fasthttp.CookieSameSiteStrictMode)
|
||||
case "none":
|
||||
fcookie.SetSameSite(fasthttp.CookieSameSiteNoneMode)
|
||||
// Secure must be paired with SameSite=None
|
||||
fcookie.SetSecure(true)
|
||||
default:
|
||||
fcookie.SetSameSite(fasthttp.CookieSameSiteDisabled)
|
||||
}
|
||||
ctx.Fasthttp.Response.Header.SetCookie(fcookie)
|
||||
}
|
||||
|
||||
@ -737,19 +717,11 @@ func (ctx *Ctx) Redirect(path string, status ...int) {
|
||||
// We support the following engines: html, amber, handlebars, mustache, pug
|
||||
//
|
||||
// https://fiber.wiki/context#render
|
||||
func (ctx *Ctx) Render(file string, bind interface{}, engine ...string) error {
|
||||
func (ctx *Ctx) Render(file string, bind interface{}) error {
|
||||
var err error
|
||||
var raw []byte
|
||||
var html string
|
||||
var e string
|
||||
|
||||
if len(engine) > 0 {
|
||||
e = engine[0]
|
||||
} else if ctx.app.Settings.TemplateEngine != "" {
|
||||
e = ctx.app.Settings.TemplateEngine
|
||||
} else {
|
||||
e = filepath.Ext(file)[1:]
|
||||
}
|
||||
if ctx.app.Settings.TemplateFolder != "" {
|
||||
file = filepath.Join(ctx.app.Settings.TemplateFolder, file)
|
||||
}
|
||||
@ -759,28 +731,25 @@ func (ctx *Ctx) Render(file string, bind interface{}, engine ...string) error {
|
||||
if raw, err = ioutil.ReadFile(filepath.Clean(file)); err != nil {
|
||||
return err
|
||||
}
|
||||
if ctx.app.Settings.TemplateEngine != nil {
|
||||
// Custom template engine
|
||||
// https://github.com/gofiber/template
|
||||
if html, err = ctx.app.Settings.TemplateEngine(getString(raw), bind); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
// Default template engine
|
||||
// https://golang.org/pkg/text/template/
|
||||
var buf bytes.Buffer
|
||||
var tmpl *template.Template
|
||||
|
||||
switch e {
|
||||
case "amber": // https://github.com/eknkc/amber
|
||||
if html, err = template.Amber(getString(raw), bind); err != nil {
|
||||
if tmpl, err = template.New("").Parse(getString(raw)); err != nil {
|
||||
return err
|
||||
}
|
||||
case "handlebars": // https://github.com/aymerick/raymond
|
||||
if html, err = template.Handlebars(getString(raw), bind); err != nil {
|
||||
return err
|
||||
}
|
||||
case "mustache": // https://github.com/cbroglie/mustache
|
||||
if html, err = template.Mustache(getString(raw), bind); err != nil {
|
||||
return err
|
||||
}
|
||||
case "pug": // https://github.com/Joker/jade
|
||||
if html, err = template.Pug(getString(raw), bind); err != nil {
|
||||
return err
|
||||
}
|
||||
default: // https://golang.org/pkg/text/template/
|
||||
if html, err = template.HTML(getString(raw), bind); err != nil {
|
||||
if err = tmpl.Execute(&buf, bind); err != nil {
|
||||
return err
|
||||
}
|
||||
html = buf.String()
|
||||
}
|
||||
ctx.Set("Content-Type", "text/html")
|
||||
ctx.SendString(html)
|
||||
@ -912,7 +881,7 @@ func (ctx *Ctx) Status(status int) *Ctx {
|
||||
//
|
||||
// https://fiber.wiki/context#type
|
||||
func (ctx *Ctx) Type(ext string) *Ctx {
|
||||
ctx.Fasthttp.Response.Header.SetContentType(getType(ext))
|
||||
ctx.Fasthttp.Response.Header.SetContentType(getMIME(ext))
|
||||
return ctx
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,6 @@ func Test_Accepts(t *testing.T) {
|
||||
}
|
||||
expect = ".xml"
|
||||
result = c.Accepts(expect)
|
||||
t.Log(result)
|
||||
if result != expect {
|
||||
t.Fatalf(`Expecting %s, got %s`, expect, result)
|
||||
}
|
||||
|
4
go.mod
4
go.mod
@ -3,11 +3,7 @@ module github.com/gofiber/fiber
|
||||
go 1.11
|
||||
|
||||
require (
|
||||
github.com/fasthttp/websocket v1.4.2
|
||||
github.com/gofiber/template v1.0.0
|
||||
github.com/google/uuid v1.1.1
|
||||
github.com/gorilla/schema v1.1.0
|
||||
github.com/json-iterator/go v1.1.9
|
||||
github.com/valyala/fasthttp v1.9.0
|
||||
github.com/valyala/fasttemplate v1.1.0
|
||||
)
|
||||
|
27
go.sum
Normal file
27
go.sum
Normal file
@ -0,0 +1,27 @@
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/gorilla/schema v1.1.0 h1:CamqUDOFUBqzrvxuz2vEwo8+SUdwsluFh7IlzJh30LY=
|
||||
github.com/gorilla/schema v1.1.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU=
|
||||
github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns=
|
||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/klauspost/compress v1.8.2 h1:Bx0qjetmNjdFXASH02NSAREKpiaDwkO1DRZ3dV2KCcs=
|
||||
github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
||||
github.com/klauspost/cpuid v1.2.1 h1:vJi+O/nMdFt0vqm8NZBI6wzALWdA2X+egi0ogNyrC/w=
|
||||
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasthttp v1.9.0 h1:hNpmUdy/+ZXYpGy0OBfm7K0UQTzb73W0T0U4iJIVrMw=
|
||||
github.com/valyala/fasthttp v1.9.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w=
|
||||
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
154
group.go
154
group.go
@ -1,154 +0,0 @@
|
||||
// 🚀 Fiber is an Express inspired web framework written in Go with 💖
|
||||
// 📌 API Documentation: https://fiber.wiki
|
||||
// 📝 Github Repository: https://github.com/gofiber/fiber
|
||||
|
||||
package fiber
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// Group ...
|
||||
type Group struct {
|
||||
prefix string
|
||||
app *App
|
||||
}
|
||||
|
||||
// Group : https://fiber.wiki/application#group
|
||||
func (grp *Group) Group(prefix string, handlers ...func(*Ctx)) *Group {
|
||||
prefix = groupPaths(grp.prefix, prefix)
|
||||
if len(handlers) > 0 {
|
||||
grp.app.registerMethod("USE", prefix, handlers...)
|
||||
}
|
||||
return &Group{
|
||||
prefix: prefix,
|
||||
app: grp.app,
|
||||
}
|
||||
}
|
||||
|
||||
// Static : https://fiber.wiki/application#static
|
||||
func (grp *Group) Static(prefix, root string, config ...Static) *Group {
|
||||
prefix = groupPaths(grp.prefix, prefix)
|
||||
grp.app.registerStatic(prefix, root, config...)
|
||||
return grp
|
||||
}
|
||||
|
||||
// Use only match requests starting with the specified prefix
|
||||
// It's optional to provide a prefix, default: "/"
|
||||
// Example: Use("/product", handler)
|
||||
// will match /product
|
||||
// will match /product/cool
|
||||
// will match /product/foo
|
||||
//
|
||||
// https://fiber.wiki/application#http-methods
|
||||
func (grp *Group) Use(args ...interface{}) *Group {
|
||||
var path = ""
|
||||
var handlers []func(*Ctx)
|
||||
for i := 0; i < len(args); i++ {
|
||||
switch arg := args[i].(type) {
|
||||
case string:
|
||||
path = arg
|
||||
case func(*Ctx):
|
||||
handlers = append(handlers, arg)
|
||||
default:
|
||||
log.Fatalf("Invalid handler: %v", reflect.TypeOf(arg))
|
||||
}
|
||||
}
|
||||
path = groupPaths(grp.prefix, path)
|
||||
grp.app.registerMethod("USE", path, handlers...)
|
||||
return grp
|
||||
}
|
||||
|
||||
// Connect : https://fiber.wiki/application#http-methods
|
||||
func (grp *Group) Connect(path string, handlers ...func(*Ctx)) *Group {
|
||||
path = groupPaths(grp.prefix, path)
|
||||
grp.app.registerMethod(http.MethodConnect, path, handlers...)
|
||||
return grp
|
||||
}
|
||||
|
||||
// Put : https://fiber.wiki/application#http-methods
|
||||
func (grp *Group) Put(path string, handlers ...func(*Ctx)) *Group {
|
||||
path = groupPaths(grp.prefix, path)
|
||||
grp.app.registerMethod(http.MethodPut, path, handlers...)
|
||||
return grp
|
||||
}
|
||||
|
||||
// Post : https://fiber.wiki/application#http-methods
|
||||
func (grp *Group) Post(path string, handlers ...func(*Ctx)) *Group {
|
||||
path = groupPaths(grp.prefix, path)
|
||||
grp.app.registerMethod(http.MethodPost, path, handlers...)
|
||||
return grp
|
||||
}
|
||||
|
||||
// Delete : https://fiber.wiki/application#http-methods
|
||||
func (grp *Group) Delete(path string, handlers ...func(*Ctx)) *Group {
|
||||
path = groupPaths(grp.prefix, path)
|
||||
grp.app.registerMethod(http.MethodDelete, path, handlers...)
|
||||
return grp
|
||||
}
|
||||
|
||||
// Head : https://fiber.wiki/application#http-methods
|
||||
func (grp *Group) Head(path string, handlers ...func(*Ctx)) *Group {
|
||||
path = groupPaths(grp.prefix, path)
|
||||
grp.app.registerMethod(http.MethodHead, path, handlers...)
|
||||
return grp
|
||||
}
|
||||
|
||||
// Patch : https://fiber.wiki/application#http-methods
|
||||
func (grp *Group) Patch(path string, handlers ...func(*Ctx)) *Group {
|
||||
path = groupPaths(grp.prefix, path)
|
||||
grp.app.registerMethod(http.MethodPatch, path, handlers...)
|
||||
return grp
|
||||
}
|
||||
|
||||
// Options : https://fiber.wiki/application#http-methods
|
||||
func (grp *Group) Options(path string, handlers ...func(*Ctx)) *Group {
|
||||
path = groupPaths(grp.prefix, path)
|
||||
grp.app.registerMethod(http.MethodOptions, path, handlers...)
|
||||
return grp
|
||||
}
|
||||
|
||||
// Trace : https://fiber.wiki/application#http-methods
|
||||
func (grp *Group) Trace(path string, handlers ...func(*Ctx)) *Group {
|
||||
path = groupPaths(grp.prefix, path)
|
||||
grp.app.registerMethod(http.MethodTrace, path, handlers...)
|
||||
return grp
|
||||
}
|
||||
|
||||
// Get : https://fiber.wiki/application#http-methods
|
||||
func (grp *Group) Get(path string, handlers ...func(*Ctx)) *Group {
|
||||
path = groupPaths(grp.prefix, path)
|
||||
grp.app.registerMethod(http.MethodGet, path, handlers...)
|
||||
return grp
|
||||
}
|
||||
|
||||
// All matches all HTTP methods and complete paths
|
||||
// Example: All("/product", handler)
|
||||
// will match /product
|
||||
// won't match /product/cool <-- important
|
||||
// won't match /product/foo <-- important
|
||||
//
|
||||
// https://fiber.wiki/application#http-methods
|
||||
func (grp *Group) All(path string, handlers ...func(*Ctx)) *Group {
|
||||
path = groupPaths(grp.prefix, path)
|
||||
grp.app.registerMethod("ALL", path, handlers...)
|
||||
return grp
|
||||
}
|
||||
|
||||
// This function is deprecated since v1.8.2!
|
||||
// Please us github.com/gofiber/websocket
|
||||
func (grp *Group) WebSocket(path string, handle func(*Ctx)) *Group {
|
||||
log.Println("Warning: app.WebSocket() is deprecated since v1.8.2, please use github.com/gofiber/websocket instead.")
|
||||
path = groupPaths(grp.prefix, path)
|
||||
grp.app.registerWebSocket(http.MethodGet, path, handle)
|
||||
return grp
|
||||
}
|
||||
|
||||
// This function is deprecated since v1.8.2!
|
||||
// Please us github.com/gofiber/recover
|
||||
func (grp *Group) Recover(handler func(*Ctx)) {
|
||||
log.Println("Warning: Recover() is deprecated since v1.8.2, please use github.com/gofiber/recover instead.")
|
||||
grp.app.recover = handler
|
||||
}
|
@ -1,80 +0,0 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
"github.com/gofiber/fiber"
|
||||
)
|
||||
|
||||
// BasicAuthConfig defines the config for BasicAuth middleware
|
||||
type BasicAuthConfig struct {
|
||||
// Skip defines a function to skip middleware.
|
||||
// Optional. Default: nil
|
||||
Skip func(*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.
|
||||
// Optional. Default: "Restricted".
|
||||
Realm string
|
||||
}
|
||||
|
||||
// BasicAuthConfigDefault is the default BasicAuth middleware config.
|
||||
var BasicAuthConfigDefault = BasicAuthConfig{
|
||||
Skip: nil,
|
||||
Users: map[string]string{},
|
||||
Realm: "Restricted",
|
||||
}
|
||||
|
||||
// BasicAuth ...
|
||||
func BasicAuth(config ...BasicAuthConfig) func(*fiber.Ctx) {
|
||||
log.Println("Warning: middleware.BasicAuth() is deprecated since v1.8.2, please use github.com/gofiber/basicauth")
|
||||
// Init config
|
||||
var cfg BasicAuthConfig
|
||||
if len(config) > 0 {
|
||||
cfg = config[0]
|
||||
}
|
||||
// Set config default values
|
||||
if cfg.Users == nil {
|
||||
cfg.Users = BasicAuthConfigDefault.Users
|
||||
}
|
||||
if cfg.Realm == "" {
|
||||
cfg.Realm = BasicAuthConfigDefault.Realm
|
||||
}
|
||||
// Return middleware handler
|
||||
return func(c *fiber.Ctx) {
|
||||
// Skip middleware if Skip returns true
|
||||
if cfg.Skip != nil && cfg.Skip(c) {
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
// Get authorization header
|
||||
auth := c.Get(fiber.HeaderAuthorization)
|
||||
// Check if characters are provided
|
||||
if len(auth) > 6 && strings.ToLower(auth[:5]) == "basic" {
|
||||
// Try to decode
|
||||
if raw, err := base64.StdEncoding.DecodeString(auth[6:]); err == nil {
|
||||
// Convert to string
|
||||
cred := string(raw)
|
||||
// Find semicolumn
|
||||
for i := 0; i < len(cred); i++ {
|
||||
if cred[i] == ':' {
|
||||
// Split into user & pass
|
||||
user := cred[:i]
|
||||
pass := cred[i+1:]
|
||||
// If exist & match in Users, we let him pass
|
||||
if cfg.Users[user] == pass {
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Authentication required
|
||||
c.Set(fiber.HeaderWWWAuthenticate, "basic realm="+cfg.Realm)
|
||||
c.SendStatus(401)
|
||||
}
|
||||
}
|
@ -1,174 +0,0 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/gofiber/fiber"
|
||||
)
|
||||
|
||||
// CORSConfig ...
|
||||
type CORSConfig struct {
|
||||
Skip func(*fiber.Ctx) bool
|
||||
// Optional. Default value []string{"*"}.
|
||||
AllowOrigins []string
|
||||
// Optional. Default value []string{"GET","POST","HEAD","PUT","DELETE","PATCH"}
|
||||
AllowMethods []string
|
||||
// Optional. Default value []string{}.
|
||||
AllowHeaders []string
|
||||
// Optional. Default value false.
|
||||
AllowCredentials bool
|
||||
// Optional. Default value []string{}.
|
||||
ExposeHeaders []string
|
||||
// Optional. Default value 0.
|
||||
MaxAge int
|
||||
}
|
||||
|
||||
// CorsConfigDefault is the defaul Cors middleware config.
|
||||
var CorsConfigDefault = CORSConfig{
|
||||
Skip: nil,
|
||||
AllowOrigins: []string{"*"},
|
||||
AllowMethods: []string{
|
||||
http.MethodGet,
|
||||
http.MethodPost,
|
||||
http.MethodHead,
|
||||
http.MethodPut,
|
||||
http.MethodDelete,
|
||||
http.MethodPatch,
|
||||
},
|
||||
}
|
||||
|
||||
// Cors ...
|
||||
func Cors(config ...CORSConfig) func(*fiber.Ctx) {
|
||||
log.Println("Warning: middleware.Cors() is deprecated since v1.8.2, please use github.com/gofiber/cors")
|
||||
// Init config
|
||||
var cfg CORSConfig
|
||||
// Set config if provided
|
||||
if len(config) > 0 {
|
||||
cfg = config[0]
|
||||
}
|
||||
// Set config default values
|
||||
if len(cfg.AllowOrigins) == 0 {
|
||||
cfg.AllowOrigins = CorsConfigDefault.AllowOrigins
|
||||
}
|
||||
if len(cfg.AllowMethods) == 0 {
|
||||
cfg.AllowMethods = CorsConfigDefault.AllowMethods
|
||||
}
|
||||
// Middleware settings
|
||||
allowMethods := strings.Join(cfg.AllowMethods, ",")
|
||||
allowHeaders := strings.Join(cfg.AllowHeaders, ",")
|
||||
exposeHeaders := strings.Join(cfg.ExposeHeaders, ",")
|
||||
maxAge := strconv.Itoa(cfg.MaxAge)
|
||||
// Middleware function
|
||||
return func(c *fiber.Ctx) {
|
||||
// Skip middleware if Skip returns true
|
||||
if cfg.Skip != nil && cfg.Skip(c) {
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
origin := c.Get(fiber.HeaderOrigin)
|
||||
allowOrigin := ""
|
||||
// Check allowed origins
|
||||
for _, o := range cfg.AllowOrigins {
|
||||
if o == "*" && cfg.AllowCredentials {
|
||||
allowOrigin = origin
|
||||
break
|
||||
}
|
||||
if o == "*" || o == origin {
|
||||
allowOrigin = o
|
||||
break
|
||||
}
|
||||
if matchSubdomain(origin, o) {
|
||||
allowOrigin = origin
|
||||
break
|
||||
}
|
||||
}
|
||||
// Simple request
|
||||
if c.Method() != http.MethodOptions {
|
||||
c.Vary(fiber.HeaderOrigin)
|
||||
c.Set(fiber.HeaderAccessControlAllowOrigin, allowOrigin)
|
||||
|
||||
if cfg.AllowCredentials {
|
||||
c.Set(fiber.HeaderAccessControlAllowCredentials, "true")
|
||||
}
|
||||
if exposeHeaders != "" {
|
||||
c.Set(fiber.HeaderAccessControlExposeHeaders, exposeHeaders)
|
||||
}
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
// Preflight request
|
||||
c.Vary(fiber.HeaderOrigin)
|
||||
c.Vary(fiber.HeaderAccessControlRequestMethod)
|
||||
c.Vary(fiber.HeaderAccessControlRequestHeaders)
|
||||
c.Set(fiber.HeaderAccessControlAllowOrigin, allowOrigin)
|
||||
c.Set(fiber.HeaderAccessControlAllowMethods, allowMethods)
|
||||
|
||||
if cfg.AllowCredentials {
|
||||
c.Set(fiber.HeaderAccessControlAllowCredentials, "true")
|
||||
}
|
||||
if allowHeaders != "" {
|
||||
c.Set(fiber.HeaderAccessControlAllowHeaders, allowHeaders)
|
||||
} else {
|
||||
h := c.Get(fiber.HeaderAccessControlRequestHeaders)
|
||||
if h != "" {
|
||||
c.Set(fiber.HeaderAccessControlAllowHeaders, h)
|
||||
}
|
||||
}
|
||||
if cfg.MaxAge > 0 {
|
||||
c.Set(fiber.HeaderAccessControlMaxAge, maxAge)
|
||||
}
|
||||
c.SendStatus(204) // No Content
|
||||
}
|
||||
}
|
||||
|
||||
func matchScheme(domain, pattern string) bool {
|
||||
didx := strings.Index(domain, ":")
|
||||
pidx := strings.Index(pattern, ":")
|
||||
return didx != -1 && pidx != -1 && domain[:didx] == pattern[:pidx]
|
||||
}
|
||||
|
||||
// matchSubdomain compares authority with wildcard
|
||||
func matchSubdomain(domain, pattern string) bool {
|
||||
if !matchScheme(domain, pattern) {
|
||||
return false
|
||||
}
|
||||
didx := strings.Index(domain, "://")
|
||||
pidx := strings.Index(pattern, "://")
|
||||
if didx == -1 || pidx == -1 {
|
||||
return false
|
||||
}
|
||||
domAuth := domain[didx+3:]
|
||||
// to avoid long loop by invalid long domain
|
||||
if len(domAuth) > 253 {
|
||||
return false
|
||||
}
|
||||
patAuth := pattern[pidx+3:]
|
||||
|
||||
domComp := strings.Split(domAuth, ".")
|
||||
patComp := strings.Split(patAuth, ".")
|
||||
for i := len(domComp)/2 - 1; i >= 0; i-- {
|
||||
opp := len(domComp) - 1 - i
|
||||
domComp[i], domComp[opp] = domComp[opp], domComp[i]
|
||||
}
|
||||
for i := len(patComp)/2 - 1; i >= 0; i-- {
|
||||
opp := len(patComp) - 1 - i
|
||||
patComp[i], patComp[opp] = patComp[opp], patComp[i]
|
||||
}
|
||||
|
||||
for i, v := range domComp {
|
||||
if len(patComp) <= i {
|
||||
return false
|
||||
}
|
||||
p := patComp[i]
|
||||
if p == "*" {
|
||||
return true
|
||||
}
|
||||
if p != v {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
@ -1,109 +0,0 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/gofiber/fiber"
|
||||
)
|
||||
|
||||
// HelmetConfig ...
|
||||
type HelmetConfig struct {
|
||||
// Skip defines a function to skip middleware.
|
||||
// Optional. Default: nil
|
||||
Skip func(*fiber.Ctx) bool
|
||||
// XSSProtection
|
||||
// Optional. Default value "1; mode=block".
|
||||
XSSProtection string
|
||||
// ContentTypeNosniff
|
||||
// Optional. Default value "nosniff".
|
||||
ContentTypeNosniff string
|
||||
// XFrameOptions
|
||||
// Optional. Default value "SAMEORIGIN".
|
||||
// Possible values: "SAMEORIGIN", "DENY", "ALLOW-FROM uri"
|
||||
XFrameOptions string
|
||||
// HSTSMaxAge
|
||||
// Optional. Default value 0.
|
||||
HSTSMaxAge int
|
||||
// HSTSExcludeSubdomains
|
||||
// Optional. Default value false.
|
||||
HSTSExcludeSubdomains bool
|
||||
// ContentSecurityPolicy
|
||||
// Optional. Default value "".
|
||||
ContentSecurityPolicy string
|
||||
// CSPReportOnly
|
||||
// Optional. Default value false.
|
||||
CSPReportOnly bool
|
||||
// HSTSPreloadEnabled
|
||||
// Optional. Default value false.
|
||||
HSTSPreloadEnabled bool
|
||||
// ReferrerPolicy
|
||||
// Optional. Default value "".
|
||||
ReferrerPolicy string
|
||||
}
|
||||
|
||||
// HelmetConfigDefault is the defaul Helmet middleware config.
|
||||
var HelmetConfigDefault = HelmetConfig{
|
||||
Skip: nil,
|
||||
XSSProtection: "1; mode=block",
|
||||
ContentTypeNosniff: "nosniff",
|
||||
XFrameOptions: "SAMEORIGIN",
|
||||
}
|
||||
|
||||
// Helmet ...
|
||||
func Helmet(config ...HelmetConfig) func(*fiber.Ctx) {
|
||||
log.Println("Warning: middleware.Helmet() is deprecated since v1.8.2, please use github.com/gofiber/helmet")
|
||||
// Init config
|
||||
var cfg HelmetConfig
|
||||
if len(config) > 0 {
|
||||
cfg = config[0]
|
||||
}
|
||||
// Set config default values
|
||||
if cfg.XSSProtection == "" {
|
||||
cfg.XSSProtection = HelmetConfigDefault.XSSProtection
|
||||
}
|
||||
if cfg.ContentTypeNosniff == "" {
|
||||
cfg.ContentTypeNosniff = HelmetConfigDefault.ContentTypeNosniff
|
||||
}
|
||||
if cfg.XFrameOptions == "" {
|
||||
cfg.XFrameOptions = HelmetConfigDefault.XFrameOptions
|
||||
}
|
||||
// Return middleware handler
|
||||
return func(c *fiber.Ctx) {
|
||||
// Skip middleware if Skip returns true
|
||||
if cfg.Skip != nil && cfg.Skip(c) {
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
if cfg.XSSProtection != "" {
|
||||
c.Set(fiber.HeaderXXSSProtection, cfg.XSSProtection)
|
||||
}
|
||||
if cfg.ContentTypeNosniff != "" {
|
||||
c.Set(fiber.HeaderXContentTypeOptions, cfg.ContentTypeNosniff)
|
||||
}
|
||||
if cfg.XFrameOptions != "" {
|
||||
c.Set(fiber.HeaderXFrameOptions, cfg.XFrameOptions)
|
||||
}
|
||||
if (c.Secure() || (c.Get(fiber.HeaderXForwardedProto) == "https")) && cfg.HSTSMaxAge != 0 {
|
||||
subdomains := ""
|
||||
if !cfg.HSTSExcludeSubdomains {
|
||||
subdomains = "; includeSubdomains"
|
||||
}
|
||||
if cfg.HSTSPreloadEnabled {
|
||||
subdomains = fmt.Sprintf("%s; preload", subdomains)
|
||||
}
|
||||
c.Set(fiber.HeaderStrictTransportSecurity, fmt.Sprintf("max-age=%d%s", cfg.HSTSMaxAge, subdomains))
|
||||
}
|
||||
if cfg.ContentSecurityPolicy != "" {
|
||||
if cfg.CSPReportOnly {
|
||||
c.Set(fiber.HeaderContentSecurityPolicyReportOnly, cfg.ContentSecurityPolicy)
|
||||
} else {
|
||||
c.Set(fiber.HeaderContentSecurityPolicy, cfg.ContentSecurityPolicy)
|
||||
}
|
||||
}
|
||||
if cfg.ReferrerPolicy != "" {
|
||||
c.Set(fiber.HeaderReferrerPolicy, cfg.ReferrerPolicy)
|
||||
}
|
||||
c.Next()
|
||||
}
|
||||
}
|
@ -1,143 +0,0 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"log"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/fiber"
|
||||
)
|
||||
|
||||
// LimiterConfig ...
|
||||
type LimiterConfig struct {
|
||||
Skip func(*fiber.Ctx) bool
|
||||
// Timeout in seconds on how long to keep records of requests in memory
|
||||
// Default: 60
|
||||
Timeout int
|
||||
// Max number of recent connections during `Timeout` seconds before sending a 429 response
|
||||
// Default: 10
|
||||
Max int
|
||||
// Message
|
||||
// default: "Too many requests, please try again later."
|
||||
Message string
|
||||
// StatusCode
|
||||
// Default: 429 Too Many Requests
|
||||
StatusCode int
|
||||
// Key allows to use a custom handler to create custom keys
|
||||
// Default: func(c *fiber.Ctx) string {
|
||||
// return c.IP()
|
||||
// }
|
||||
Key func(*fiber.Ctx) string
|
||||
// Handler is called when a request hits the limit
|
||||
// Default: func(c *fiber.Ctx) {
|
||||
// c.Status(cfg.StatusCode).SendString(cfg.Message)
|
||||
// }
|
||||
Handler func(*fiber.Ctx)
|
||||
}
|
||||
|
||||
// LimiterConfigDefault is the defaul Limiter middleware config.
|
||||
var LimiterConfigDefault = LimiterConfig{
|
||||
Skip: nil,
|
||||
Timeout: 60,
|
||||
Max: 10,
|
||||
Message: "Too many requests, please try again later.",
|
||||
StatusCode: 429,
|
||||
Key: func(c *fiber.Ctx) string {
|
||||
return c.IP()
|
||||
},
|
||||
}
|
||||
|
||||
// Limiter ...
|
||||
func Limiter(config ...LimiterConfig) func(*fiber.Ctx) {
|
||||
log.Println("Warning: middleware.Limiter() is deprecated since v1.8.2, please use github.com/gofiber/limiter")
|
||||
// Init config
|
||||
var cfg LimiterConfig
|
||||
// Set config if provided
|
||||
if len(config) > 0 {
|
||||
cfg = config[0]
|
||||
}
|
||||
// Set config default values
|
||||
if cfg.Timeout == 0 {
|
||||
cfg.Timeout = LimiterConfigDefault.Timeout
|
||||
}
|
||||
if cfg.Max == 0 {
|
||||
cfg.Max = LimiterConfigDefault.Max
|
||||
}
|
||||
if cfg.Message == "" {
|
||||
cfg.Message = LimiterConfigDefault.Message
|
||||
}
|
||||
if cfg.StatusCode == 0 {
|
||||
cfg.StatusCode = LimiterConfigDefault.StatusCode
|
||||
}
|
||||
if cfg.Key == nil {
|
||||
cfg.Key = LimiterConfigDefault.Key
|
||||
}
|
||||
if cfg.Handler == nil {
|
||||
cfg.Handler = func(c *fiber.Ctx) {
|
||||
c.Status(cfg.StatusCode).SendString(cfg.Message)
|
||||
}
|
||||
}
|
||||
// Limiter settings
|
||||
var hits = map[string]int{}
|
||||
var reset = map[string]int{}
|
||||
var timestamp = int(time.Now().Unix())
|
||||
// Update timestamp every second
|
||||
go func() {
|
||||
for {
|
||||
timestamp = int(time.Now().Unix())
|
||||
time.Sleep(1 * time.Second)
|
||||
}
|
||||
}()
|
||||
// Reset hits every cfg.Timeout
|
||||
go func() {
|
||||
for {
|
||||
// For every key in reset
|
||||
for key := range reset {
|
||||
// If resetTime exist and current time is equal or bigger
|
||||
if reset[key] != 0 && timestamp >= reset[key] {
|
||||
// Reset hits and resetTime
|
||||
hits[key] = 0
|
||||
reset[key] = 0
|
||||
}
|
||||
}
|
||||
// Wait cfg.Timeout
|
||||
time.Sleep(time.Duration(cfg.Timeout) * time.Second)
|
||||
}
|
||||
}()
|
||||
return func(c *fiber.Ctx) {
|
||||
// Skip middleware if Skip returns true
|
||||
if cfg.Skip != nil && cfg.Skip(c) {
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
// Get key (default is the remote IP)
|
||||
key := cfg.Key(c)
|
||||
// Increment key hits
|
||||
hits[key]++
|
||||
// Set unix timestamp if not exist
|
||||
if reset[key] == 0 {
|
||||
reset[key] = timestamp + cfg.Timeout
|
||||
}
|
||||
// Get current hits
|
||||
hitCount := hits[key]
|
||||
// Set how many hits we have left
|
||||
remaining := cfg.Max - hitCount
|
||||
// Calculate when it resets in seconds
|
||||
resetTime := reset[key] - timestamp
|
||||
// Check if hits exceed the cfg.Max
|
||||
if remaining < 1 {
|
||||
// Call Handler func
|
||||
cfg.Handler(c)
|
||||
// Return response with Retry-After header
|
||||
// https://tools.ietf.org/html/rfc6584
|
||||
c.Set("Retry-After", strconv.Itoa(resetTime))
|
||||
return
|
||||
}
|
||||
// We can continue, update RateLimit headers
|
||||
c.Set("X-RateLimit-Limit", strconv.Itoa(cfg.Max))
|
||||
c.Set("X-RateLimit-Remaining", strconv.Itoa(remaining))
|
||||
c.Set("X-RateLimit-Reset", strconv.Itoa(resetTime))
|
||||
// Bye!
|
||||
c.Next()
|
||||
}
|
||||
}
|
@ -1,140 +0,0 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/valyala/fasttemplate"
|
||||
)
|
||||
|
||||
// LoggerConfig ...
|
||||
type LoggerConfig struct {
|
||||
// Skip defines a function to skip middleware.
|
||||
// Optional. Default: nil
|
||||
Skip func(*fiber.Ctx) bool
|
||||
// Format defines the logging format with defined variables
|
||||
// Optional. Default: "${time} - ${ip} - ${method} ${path}\t${ua}\n"
|
||||
// Possible values: time, ip, url, host, method, path, protocol
|
||||
// referer, ua, header:<key>, query:<key>, formform:<key>, cookie:<key>
|
||||
Format string
|
||||
// TimeFormat https://programming.guide/go/format-parse-string-time-date-example.html
|
||||
// Optional. Default: 15:04:05
|
||||
TimeFormat string
|
||||
// Output is a writter where logs are written
|
||||
// Default: os.Stderr
|
||||
Output io.Writer
|
||||
}
|
||||
|
||||
// LoggerConfigDefault is the defaul Logger middleware config.
|
||||
var LoggerConfigDefault = LoggerConfig{
|
||||
Skip: nil,
|
||||
Format: "${time} ${method} ${path} - ${ip} - ${status} - ${latency}\n",
|
||||
TimeFormat: "15:04:05",
|
||||
Output: os.Stderr,
|
||||
}
|
||||
|
||||
// Logger ...
|
||||
func Logger(config ...LoggerConfig) func(*fiber.Ctx) {
|
||||
log.Println("Warning: middleware.Logger() is deprecated since v1.8.2, please use github.com/gofiber/logger")
|
||||
// Init config
|
||||
var cfg LoggerConfig
|
||||
// Set config if provided
|
||||
if len(config) > 0 {
|
||||
cfg = config[0]
|
||||
}
|
||||
// Set config default values
|
||||
if cfg.Format == "" {
|
||||
cfg.Format = LoggerConfigDefault.Format
|
||||
}
|
||||
if cfg.TimeFormat == "" {
|
||||
cfg.TimeFormat = LoggerConfigDefault.TimeFormat
|
||||
}
|
||||
if cfg.Output == nil {
|
||||
cfg.Output = LoggerConfigDefault.Output
|
||||
}
|
||||
// Middleware settings
|
||||
tmpl := fasttemplate.New(cfg.Format, "${", "}")
|
||||
pool := &sync.Pool{
|
||||
New: func() interface{} {
|
||||
return bytes.NewBuffer(make([]byte, 256))
|
||||
},
|
||||
}
|
||||
timestamp := time.Now().Format(cfg.TimeFormat)
|
||||
// Update date/time every second in a seperate go routine
|
||||
if strings.Contains(cfg.Format, "${time}") {
|
||||
go func() {
|
||||
for {
|
||||
timestamp = time.Now().Format(cfg.TimeFormat)
|
||||
time.Sleep(1 * time.Second)
|
||||
}
|
||||
}()
|
||||
}
|
||||
// Middleware function
|
||||
return func(c *fiber.Ctx) {
|
||||
// Skip middleware if Skip returns true
|
||||
if cfg.Skip != nil && cfg.Skip(c) {
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
start := time.Now()
|
||||
// handle request
|
||||
c.Next()
|
||||
// build log
|
||||
stop := time.Now()
|
||||
buf := pool.Get().(*bytes.Buffer)
|
||||
buf.Reset()
|
||||
defer pool.Put(buf)
|
||||
_, err := tmpl.ExecuteFunc(buf, func(w io.Writer, tag string) (int, error) {
|
||||
switch tag {
|
||||
case "time":
|
||||
return buf.WriteString(timestamp)
|
||||
case "referer":
|
||||
return buf.WriteString(c.Get(fiber.HeaderReferer))
|
||||
case "protocol":
|
||||
return buf.WriteString(c.Protocol())
|
||||
case "ip":
|
||||
return buf.WriteString(c.IP())
|
||||
case "host":
|
||||
return buf.WriteString(c.Hostname())
|
||||
case "method":
|
||||
return buf.WriteString(c.Method())
|
||||
case "path":
|
||||
return buf.WriteString(c.Path())
|
||||
case "url":
|
||||
return buf.WriteString(c.OriginalURL())
|
||||
case "ua":
|
||||
return buf.WriteString(c.Get(fiber.HeaderUserAgent))
|
||||
case "latency":
|
||||
return buf.WriteString(stop.Sub(start).String())
|
||||
case "status":
|
||||
return buf.WriteString(strconv.Itoa(c.Fasthttp.Response.StatusCode()))
|
||||
default:
|
||||
switch {
|
||||
case strings.HasPrefix(tag, "header:"):
|
||||
return buf.WriteString(c.Get(tag[7:]))
|
||||
case strings.HasPrefix(tag, "query:"):
|
||||
return buf.WriteString(c.Query(tag[6:]))
|
||||
case strings.HasPrefix(tag, "form:"):
|
||||
return buf.WriteString(c.FormValue(tag[5:]))
|
||||
case strings.HasPrefix(tag, "cookie:"):
|
||||
return buf.WriteString(c.Cookies(tag[7:]))
|
||||
}
|
||||
}
|
||||
return 0, nil
|
||||
})
|
||||
if err != nil {
|
||||
buf.WriteString(err.Error())
|
||||
}
|
||||
if _, err := cfg.Output.Write(buf.Bytes()); err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/gofiber/fiber"
|
||||
)
|
||||
|
||||
// Recover ...
|
||||
func Recover(handle ...func(*fiber.Ctx, error)) func(*fiber.Ctx) {
|
||||
log.Println("Warning: middleware.Recover() is deprecated since v1.8.2, please use github.com/gofiber/recover")
|
||||
h := func(c *fiber.Ctx, err error) {
|
||||
log.Println(err)
|
||||
c.SendStatus(500)
|
||||
}
|
||||
// Init custom error handler if exist
|
||||
if len(handle) > 0 {
|
||||
h = handle[0]
|
||||
}
|
||||
// Return middleware handle
|
||||
return func(c *fiber.Ctx) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
err, ok := r.(error)
|
||||
if !ok {
|
||||
err = fmt.Errorf("%v", r)
|
||||
}
|
||||
h(c, err)
|
||||
}
|
||||
}()
|
||||
c.Next()
|
||||
}
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// RequestIDConfig defines the config for RequestID middleware
|
||||
type RequestIDConfig struct {
|
||||
// Skip defines a function to skip middleware.
|
||||
// Optional. Default: nil
|
||||
Skip func(*fiber.Ctx) bool
|
||||
// Generator defines a function to generate an ID.
|
||||
// Optional. Default: func() string {
|
||||
// return uuid.New().String()
|
||||
// }
|
||||
Generator func() string
|
||||
}
|
||||
|
||||
// RequestIDConfigDefault is the default RequestID middleware config.
|
||||
var RequestIDConfigDefault = RequestIDConfig{
|
||||
Skip: nil,
|
||||
Generator: func() string {
|
||||
return uuid.New().String()
|
||||
},
|
||||
}
|
||||
|
||||
// RequestID adds an indentifier to the request using the `X-Request-ID` header
|
||||
func RequestID(config ...RequestIDConfig) func(*fiber.Ctx) {
|
||||
log.Println("Warning: middleware.RequestID() is deprecated since v1.8.2, please use github.com/gofiber/requestid")
|
||||
// Init config
|
||||
var cfg RequestIDConfig
|
||||
if len(config) > 0 {
|
||||
cfg = config[0]
|
||||
}
|
||||
// Set config default values
|
||||
if cfg.Skip == nil {
|
||||
cfg.Skip = RequestIDConfigDefault.Skip
|
||||
}
|
||||
if cfg.Generator == nil {
|
||||
cfg.Generator = RequestIDConfigDefault.Generator
|
||||
}
|
||||
// Return middleware handler
|
||||
return func(c *fiber.Ctx) {
|
||||
// Skip middleware if Skip returns true
|
||||
if cfg.Skip != nil && cfg.Skip(c) {
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
// Get value from RequestID
|
||||
rid := c.Get(fiber.HeaderXRequestID)
|
||||
fmt.Println(rid)
|
||||
// Create new ID
|
||||
if rid == "" {
|
||||
rid = cfg.Generator()
|
||||
}
|
||||
// Set X-Request-ID
|
||||
c.Set(fiber.HeaderXRequestID, rid)
|
||||
// Bye!
|
||||
c.Next()
|
||||
}
|
||||
}
|
82
router.go
82
router.go
@ -10,7 +10,6 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
websocket "github.com/fasthttp/websocket"
|
||||
fasthttp "github.com/valyala/fasthttp"
|
||||
)
|
||||
|
||||
@ -19,7 +18,6 @@ type Route struct {
|
||||
isGet bool // allows HEAD requests if GET
|
||||
|
||||
isMiddleware bool // is middleware route
|
||||
isWebSocket bool // is websocket route
|
||||
|
||||
isStar bool // path == '*'
|
||||
isSlash bool // path == '/'
|
||||
@ -30,9 +28,7 @@ type Route struct {
|
||||
Params []string // path params
|
||||
Regexp *regexp.Regexp // regexp matcher
|
||||
|
||||
HandleCtx func(*Ctx) // ctx handler
|
||||
HandleConn func(*Conn) // conn handler
|
||||
|
||||
Handler func(*Ctx) // ctx handler
|
||||
}
|
||||
|
||||
func (app *App) nextRoute(ctx *Ctx) {
|
||||
@ -45,19 +41,7 @@ func (app *App) nextRoute(ctx *Ctx) {
|
||||
if match {
|
||||
ctx.route = route
|
||||
ctx.values = values
|
||||
// Deprecated since v1.8.2
|
||||
// github.com/gofiber/websocket
|
||||
if route.isWebSocket {
|
||||
if err := websocketUpgrader.Upgrade(ctx.Fasthttp, func(fconn *websocket.Conn) {
|
||||
conn := acquireConn(fconn)
|
||||
defer releaseConn(conn)
|
||||
route.HandleConn(conn)
|
||||
}); err != nil { // Upgrading failed
|
||||
ctx.SendStatus(400)
|
||||
}
|
||||
} else {
|
||||
route.HandleCtx(ctx)
|
||||
}
|
||||
route.Handler(ctx)
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -123,7 +107,6 @@ func (app *App) handler(fctx *fasthttp.RequestCtx) {
|
||||
defer releaseCtx(ctx)
|
||||
// attach app poiner and compress settings
|
||||
ctx.app = app
|
||||
ctx.compress = app.Settings.Compression
|
||||
|
||||
// Case sensitive routing
|
||||
if !app.Settings.CaseSensitive {
|
||||
@ -133,12 +116,8 @@ func (app *App) handler(fctx *fasthttp.RequestCtx) {
|
||||
if !app.Settings.StrictRouting && len(ctx.path) > 1 {
|
||||
ctx.path = strings.TrimRight(ctx.path, "/")
|
||||
}
|
||||
|
||||
// Find route
|
||||
app.nextRoute(ctx)
|
||||
// Deprecated since v1.8.2 https://github.com/gofiber/compress
|
||||
if ctx.compress {
|
||||
compressResponse(fctx)
|
||||
}
|
||||
}
|
||||
|
||||
func (app *App) registerMethod(method, path string, handlers ...func(*Ctx)) {
|
||||
@ -201,62 +180,11 @@ func (app *App) registerMethod(method, path string, handlers ...func(*Ctx)) {
|
||||
Path: path,
|
||||
Params: Params,
|
||||
Regexp: Regexp,
|
||||
HandleCtx: handlers[i],
|
||||
Handler: handlers[i],
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (app *App) registerWebSocket(method, path string, handle func(*Ctx)) {
|
||||
// Cannot have an empty path
|
||||
if path == "" {
|
||||
path = "/"
|
||||
}
|
||||
// Path always start with a '/' or '*'
|
||||
if path[0] != '/' && path[0] != '*' {
|
||||
path = "/" + path
|
||||
}
|
||||
// Store original path to strip case sensitive params
|
||||
original := path
|
||||
// Case sensitive routing, all to lowercase
|
||||
if !app.Settings.CaseSensitive {
|
||||
path = strings.ToLower(path)
|
||||
}
|
||||
// Strict routing, remove last `/`
|
||||
if !app.Settings.StrictRouting && len(path) > 1 {
|
||||
path = strings.TrimRight(path, "/")
|
||||
}
|
||||
|
||||
var isWebSocket = true
|
||||
|
||||
var isStar = path == "*" || path == "/*"
|
||||
var isSlash = path == "/"
|
||||
var isRegex = false
|
||||
// Route properties
|
||||
var Params = getParams(original)
|
||||
var Regexp *regexp.Regexp
|
||||
// Params requires regex pattern
|
||||
if len(Params) > 0 {
|
||||
regex, err := getRegex(path)
|
||||
if err != nil {
|
||||
log.Fatal("Router: Invalid path pattern: " + path)
|
||||
}
|
||||
isRegex = true
|
||||
Regexp = regex
|
||||
}
|
||||
app.routes = append(app.routes, &Route{
|
||||
isWebSocket: isWebSocket,
|
||||
isStar: isStar,
|
||||
isSlash: isSlash,
|
||||
isRegex: isRegex,
|
||||
|
||||
Method: method,
|
||||
Path: path,
|
||||
Params: Params,
|
||||
Regexp: Regexp,
|
||||
HandleCtx: handle,
|
||||
})
|
||||
}
|
||||
|
||||
func (app *App) registerStatic(prefix, root string, config ...Static) {
|
||||
// Cannot have an empty prefix
|
||||
if prefix == "" {
|
||||
@ -324,7 +252,7 @@ func (app *App) registerStatic(prefix, root string, config ...Static) {
|
||||
isSlash: isSlash,
|
||||
Method: "*",
|
||||
Path: prefix,
|
||||
HandleCtx: func(c *Ctx) {
|
||||
Handler: func(c *Ctx) {
|
||||
// Only handle GET & HEAD methods
|
||||
if c.method == "GET" || c.method == "HEAD" {
|
||||
// Do stuff
|
||||
|
188
utils.go
188
utils.go
@ -15,20 +15,10 @@ import (
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
websocket "github.com/fasthttp/websocket"
|
||||
schema "github.com/gorilla/schema"
|
||||
fasthttp "github.com/valyala/fasthttp"
|
||||
)
|
||||
|
||||
var schemaDecoder = schema.NewDecoder()
|
||||
var compressResponse = fasthttp.CompressHandlerLevel(func(c *fasthttp.RequestCtx) {}, fasthttp.CompressDefaultCompression)
|
||||
var websocketUpgrader = websocket.FastHTTPUpgrader{
|
||||
ReadBufferSize: 1024,
|
||||
WriteBufferSize: 1024,
|
||||
CheckOrigin: func(fctx *fasthttp.RequestCtx) bool {
|
||||
return true
|
||||
},
|
||||
}
|
||||
|
||||
func groupPaths(prefix, path string) string {
|
||||
if path == "/" {
|
||||
@ -39,15 +29,6 @@ func groupPaths(prefix, path string) string {
|
||||
return path
|
||||
}
|
||||
|
||||
// BenchmarkDefault 322504144 18.6 ns/op // string == string
|
||||
// BenchmarkisEqual 353663168 17.0 ns/op // isEqual(string, string)
|
||||
// func isEqual(a, b string) bool {
|
||||
// if len(a) == len(b) {
|
||||
// return a == b
|
||||
// }
|
||||
// return false
|
||||
// }
|
||||
|
||||
func getParams(path string) (params []string) {
|
||||
if len(path) < 1 {
|
||||
return
|
||||
@ -107,15 +88,11 @@ func getFiles(root string) (files []string, dir bool, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func getType(ext string) (mime string) {
|
||||
if ext == "" {
|
||||
func getMIME(extension string) (mime string) {
|
||||
if extension == "" {
|
||||
return mime
|
||||
}
|
||||
if ext[0] == '.' {
|
||||
mime = extensionMIME[ext[1:]]
|
||||
} else {
|
||||
mime = extensionMIME[ext]
|
||||
}
|
||||
mime = extensionMIME[extension]
|
||||
if mime == "" {
|
||||
return MIMEOctetStream
|
||||
}
|
||||
@ -157,22 +134,7 @@ func (c *testConn) SetDeadline(t time.Time) error { return nil }
|
||||
func (c *testConn) SetReadDeadline(t time.Time) error { return nil }
|
||||
func (c *testConn) SetWriteDeadline(t time.Time) error { return nil }
|
||||
|
||||
// MIME types
|
||||
const (
|
||||
MIMEApplicationJSON = "application/json"
|
||||
MIMEApplicationJavaScript = "application/javascript"
|
||||
MIMEApplicationXML = "application/xml"
|
||||
MIMETextXML = "text/xml"
|
||||
MIMEApplicationForm = "application/x-www-form-urlencoded"
|
||||
MIMEApplicationProtobuf = "application/protobuf"
|
||||
MIMEApplicationMsgpack = "application/msgpack"
|
||||
MIMETextHTML = "text/html"
|
||||
MIMETextPlain = "text/plain"
|
||||
MIMEMultipartForm = "multipart/form-data"
|
||||
MIMEOctetStream = "application/octet-stream"
|
||||
)
|
||||
|
||||
// HTTP status codes with messages
|
||||
// HTTP status codes were copied from net/http.
|
||||
var statusMessages = map[int]string{
|
||||
100: "Continue",
|
||||
101: "Switching Protocols",
|
||||
@ -236,8 +198,25 @@ var statusMessages = map[int]string{
|
||||
511: "Network Authentication Required",
|
||||
}
|
||||
|
||||
// File extensions MIME types
|
||||
// MIME types were copied from labstack/echo
|
||||
const (
|
||||
MIMETextXML = "text/xml"
|
||||
MIMETextHTML = "text/html"
|
||||
MIMETextPlain = "text/plain"
|
||||
|
||||
MIMEApplicationJSON = "application/json"
|
||||
MIMEApplicationJavaScript = "application/javascript"
|
||||
MIMEApplicationXML = "application/xml"
|
||||
MIMEApplicationForm = "application/x-www-form-urlencoded"
|
||||
|
||||
MIMEMultipartForm = "multipart/form-data"
|
||||
|
||||
MIMEOctetStream = "application/octet-stream"
|
||||
)
|
||||
|
||||
// MIME types were copied from nginx/mime.types.
|
||||
var extensionMIME = map[string]string{
|
||||
// without dot
|
||||
"html": "text/html",
|
||||
"htm": "text/html",
|
||||
"shtml": "text/html",
|
||||
@ -343,9 +322,129 @@ var extensionMIME = map[string]string{
|
||||
"asf": "video/x-ms-asf",
|
||||
"wmv": "video/x-ms-wmv",
|
||||
"avi": "video/x-msvideo",
|
||||
|
||||
// with dot
|
||||
".html": "text/html",
|
||||
".htm": "text/html",
|
||||
".shtml": "text/html",
|
||||
".css": "text/css",
|
||||
".gif": "image/gif",
|
||||
".jpeg": "image/jpeg",
|
||||
".jpg": "image/jpeg",
|
||||
".xml": "application/xml",
|
||||
".js": "application/javascript",
|
||||
".atom": "application/atom+xml",
|
||||
".rss": "application/rss+xml",
|
||||
".mml": "text/mathml",
|
||||
".txt": "text/plain",
|
||||
".jad": "text/vnd.sun.j2me.app-descriptor",
|
||||
".wml": "text/vnd.wap.wml",
|
||||
".htc": "text/x-component",
|
||||
".png": "image/png",
|
||||
".svg": "image/svg+xml",
|
||||
".svgz": "image/svg+xml",
|
||||
".tif": "image/tiff",
|
||||
".tiff": "image/tiff",
|
||||
".wbmp": "image/vnd.wap.wbmp",
|
||||
".webp": "image/webp",
|
||||
".ico": "image/x-icon",
|
||||
".jng": "image/x-jng",
|
||||
".bmp": "image/x-ms-bmp",
|
||||
".woff": "font/woff",
|
||||
".woff2": "font/woff2",
|
||||
".jar": "application/java-archive",
|
||||
".war": "application/java-archive",
|
||||
".ear": "application/java-archive",
|
||||
".json": "application/json",
|
||||
".hqx": "application/mac-binhex40",
|
||||
".doc": "application/msword",
|
||||
".pdf": "application/pdf",
|
||||
".ps": "application/postscript",
|
||||
".eps": "application/postscript",
|
||||
".ai": "application/postscript",
|
||||
".rtf": "application/rtf",
|
||||
".m3u8": "application/vnd.apple.mpegurl",
|
||||
".kml": "application/vnd.google-earth.kml+xml",
|
||||
".kmz": "application/vnd.google-earth.kmz",
|
||||
".xls": "application/vnd.ms-excel",
|
||||
".eot": "application/vnd.ms-fontobject",
|
||||
".ppt": "application/vnd.ms-powerpoint",
|
||||
".odg": "application/vnd.oasis.opendocument.graphics",
|
||||
".odp": "application/vnd.oasis.opendocument.presentation",
|
||||
".ods": "application/vnd.oasis.opendocument.spreadsheet",
|
||||
".odt": "application/vnd.oasis.opendocument.text",
|
||||
".wmlc": "application/vnd.wap.wmlc",
|
||||
".7z": "application/x-7z-compressed",
|
||||
".cco": "application/x-cocoa",
|
||||
".jardiff": "application/x-java-archive-diff",
|
||||
".jnlp": "application/x-java-jnlp-file",
|
||||
".run": "application/x-makeself",
|
||||
".pl": "application/x-perl",
|
||||
".pm": "application/x-perl",
|
||||
".prc": "application/x-pilot",
|
||||
".pdb": "application/x-pilot",
|
||||
".rar": "application/x-rar-compressed",
|
||||
".rpm": "application/x-redhat-package-manager",
|
||||
".sea": "application/x-sea",
|
||||
".swf": "application/x-shockwave-flash",
|
||||
".sit": "application/x-stuffit",
|
||||
".tcl": "application/x-tcl",
|
||||
".tk": "application/x-tcl",
|
||||
".der": "application/x-x509-ca-cert",
|
||||
".pem": "application/x-x509-ca-cert",
|
||||
".crt": "application/x-x509-ca-cert",
|
||||
".xpi": "application/x-xpinstall",
|
||||
".xhtml": "application/xhtml+xml",
|
||||
".xspf": "application/xspf+xml",
|
||||
".zip": "application/zip",
|
||||
".bin": "application/octet-stream",
|
||||
".exe": "application/octet-stream",
|
||||
".dll": "application/octet-stream",
|
||||
".deb": "application/octet-stream",
|
||||
".dmg": "application/octet-stream",
|
||||
".iso": "application/octet-stream",
|
||||
".img": "application/octet-stream",
|
||||
".msi": "application/octet-stream",
|
||||
".msp": "application/octet-stream",
|
||||
".msm": "application/octet-stream",
|
||||
".mid": "audio/midi",
|
||||
".midi": "audio/midi",
|
||||
".kar": "audio/midi",
|
||||
".mp3": "audio/mpeg",
|
||||
".ogg": "audio/ogg",
|
||||
".m4a": "audio/x-m4a",
|
||||
".ra": "audio/x-realaudio",
|
||||
".3gpp": "video/3gpp",
|
||||
".3gp": "video/3gpp",
|
||||
".ts": "video/mp2t",
|
||||
".mp4": "video/mp4",
|
||||
".mpeg": "video/mpeg",
|
||||
".mpg": "video/mpeg",
|
||||
".mov": "video/quicktime",
|
||||
".webm": "video/webm",
|
||||
".flv": "video/x-flv",
|
||||
".m4v": "video/x-m4v",
|
||||
".mng": "video/x-mng",
|
||||
".asx": "video/x-ms-asf",
|
||||
".asf": "video/x-ms-asf",
|
||||
".wmv": "video/x-ms-wmv",
|
||||
".avi": "video/x-msvideo",
|
||||
}
|
||||
|
||||
// HTTP Headers
|
||||
// HTTP methods were copied from net/http.
|
||||
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
|
||||
)
|
||||
|
||||
// HTTP Headers were copied from net/http.
|
||||
const (
|
||||
// Authentication
|
||||
HeaderAuthorization = "Authorization"
|
||||
@ -509,6 +608,7 @@ const (
|
||||
HeaderXUACompatible = "X-UA-Compatible"
|
||||
)
|
||||
|
||||
// HTTP status codes were copied from net/http.
|
||||
const (
|
||||
StatusContinue = 100 // RFC 7231, 6.2.1
|
||||
StatusSwitchingProtocols = 101 // RFC 7231, 6.2.2
|
||||
|
Loading…
x
Reference in New Issue
Block a user