Merge pull request #235 from Fenny/master

v1.8.4
This commit is contained in:
Fenny 2020-03-23 03:50:20 +01:00 committed by GitHub
commit 1ff27277c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 1430 additions and 1835 deletions

65
.github/README.md vendored
View File

@ -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
View File

@ -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
View File

@ -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
View File

@ -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
View File

@ -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
View File

@ -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
View File

@ -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
View File

@ -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
View File

@ -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
View File

@ -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)
}

View File

@ -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)
}

View File

@ -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

View File

@ -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" {

View File

@ -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
}

View File

@ -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
View File

@ -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
View 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
View File

@ -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
}

View File

@ -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)
}
}

View File

@ -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
}

View File

@ -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()
}
}

View File

@ -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()
}
}

View File

@ -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)
}
}
}

View File

@ -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()
}
}

View File

@ -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()
}
}

View File

@ -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
View File

@ -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