mirror of
https://github.com/gofiber/fiber.git
synced 2025-02-21 07:52:53 +00:00
Merge pull request #3 from gofiber/master
Accumulative update @ 07 Mar 2020
This commit is contained in:
commit
778953db3c
104
.github/README.md
vendored
104
.github/README.md
vendored
@ -33,6 +33,9 @@
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_tr.md">
|
||||
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/tr.svg">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_id.md">
|
||||
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/id.svg">
|
||||
</a>
|
||||
<br><br>
|
||||
<a href="https://github.com/gofiber/fiber/releases">
|
||||
<img src="https://img.shields.io/github/release/gofiber/fiber?style=flat-square">
|
||||
@ -60,7 +63,7 @@
|
||||
</a>
|
||||
</p>
|
||||
<p align="center">
|
||||
<b>Fiber</b> is an <a href="https://github.com/expressjs/express">Express</a> inspired <b>web framework</b> build on top of <a href="https://github.com/valyala/fasthttp">Fasthttp</a>, the <b>fastest</b> HTTP engine for <a href="https://golang.org/doc/">Go</a>. Designed to <b>ease</b> things up for <b>fast</b> development with <b>zero memory allocation</b> and <b>performance</b> in mind.
|
||||
<b>Fiber</b> is an <a href="https://github.com/expressjs/express">Express</a> inspired <b>web framework</b> built on top of <a href="https://github.com/valyala/fasthttp">Fasthttp</a>, the <b>fastest</b> HTTP engine for <a href="https://golang.org/doc/">Go</a>. Designed to <b>ease</b> things up for <b>fast</b> development with <b>zero memory allocation</b> and <b>performance</b> in mind.
|
||||
</p>
|
||||
|
||||
## ⚡️ Quickstart
|
||||
@ -109,16 +112,16 @@ These tests are performed by [TechEmpower](https://github.com/TechEmpower/Framew
|
||||
- [API endpoints](https://fiber.wiki/context)
|
||||
- Middleware & [Next](https://fiber.wiki/context#next) support
|
||||
- [Rapid](https://dev.to/koddr/welcome-to-fiber-an-express-js-styled-fastest-web-framework-written-with-on-golang-497) server-side programming
|
||||
- Available in 9 other languages
|
||||
- Available in 10 other languages
|
||||
- And much more, [explore Fiber](https://fiber.wiki/)
|
||||
|
||||
## 💡 Philosophy
|
||||
|
||||
New gophers that make the switch from [Node.js](https://nodejs.org/en/about/) to [Go](https://golang.org/doc/) are dealing with a learning curve before they can start building their web applications or microservices. Fiber, as a **web framework**, was created with the idea of **minimalism** and follow **UNIX way**, so that new gophers can quickly enter the world of Go with a warm and trusted welcome.
|
||||
New gophers that make the switch from [Node.js](https://nodejs.org/en/about/) to [Go](https://golang.org/doc/) are dealing with a learning curve before they can start building their web applications or microservices. Fiber, as a **web framework**, was created with the idea of **minimalism** and follows the **UNIX way**, so that new gophers can quickly enter the world of Go with a warm and trusted welcome.
|
||||
|
||||
Fiber is **inspired** by Express, the most popular web framework on the Internet. We combined the **ease** of Express and **raw performance** of Go. If you have ever implemented a web application on Node.js (_using Express or similar_), then many methods and principles will seem **very common** to you.
|
||||
Fiber is **inspired** by Express, the most popular web framework on the Internet. We combined the **ease** of Express and **raw performance** of Go. If you have ever implemented a web application in Node.js (_using Express or similar_), then many methods and principles will seem **very common** to you.
|
||||
|
||||
We **listen** to our users in [issues](https://github.com/gofiber/fiber/issues) (_and all over the Internet_) to create a **fast**, **flexible** and **friendly** Go web framework for **any** tasks, **deadlines** and developer **skills**! Just like Express does in the JavaScript world.
|
||||
We **listen** to our users in [issues](https://github.com/gofiber/fiber/issues) (_and all over the Internet_) to create a **fast**, **flexible** and **friendly** Go web framework for **any** task, **deadline** and developer **skill**! Just like Express does in the JavaScript world.
|
||||
|
||||
## 👀 Examples
|
||||
|
||||
@ -153,12 +156,12 @@ func main() {
|
||||
```
|
||||
|
||||
### Serve static files
|
||||
|
||||
https://fiber.wiki/application#static
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Static("/public")
|
||||
app.Static("/", "/public")
|
||||
// => http://localhost:3000/js/script.js
|
||||
// => http://localhost:3000/css/style.css
|
||||
|
||||
@ -174,7 +177,8 @@ func main() {
|
||||
```
|
||||
|
||||
### Middleware & Next
|
||||
|
||||
https://fiber.wiki/routing#middleware
|
||||
https://fiber.wiki/context#next
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
@ -205,9 +209,10 @@ func main() {
|
||||
<summary>📚 Show more code examples</summary>
|
||||
|
||||
### Template engines
|
||||
https://fiber.wiki/application#settings
|
||||
https://fiber.wiki/context#render
|
||||
|
||||
Already supports:
|
||||
|
||||
Supported engines:
|
||||
- [html](https://golang.org/pkg/html/template/)
|
||||
- [amber](https://github.com/eknkc/amber)
|
||||
- [handlebars](https://github.com/aymerick/raymond)
|
||||
@ -241,7 +246,7 @@ func main() {
|
||||
```
|
||||
|
||||
### Grouping routes into chains
|
||||
|
||||
https://fiber.wiki/application#group
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
@ -263,8 +268,8 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
### Built-in logger
|
||||
|
||||
### Middleware logger
|
||||
https://fiber.wiki/middleware#logger
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
@ -273,7 +278,7 @@ import (
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
|
||||
// If you want to change default Logger config
|
||||
loggerConfig := middleware.LoggerConfig{
|
||||
Format: "${time} - ${method} ${path}\n",
|
||||
@ -288,6 +293,7 @@ func main() {
|
||||
```
|
||||
|
||||
### 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.
|
||||
|
||||
@ -311,7 +317,7 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
Check CORS by passing any domain in `Origin` header:
|
||||
Check CORS by passing any domain in `Origin` header:
|
||||
|
||||
```bash
|
||||
curl -H "Origin: http://example.com" --verbose http://localhost:3000
|
||||
@ -343,20 +349,27 @@ func main() {
|
||||
```
|
||||
|
||||
### JSON Response
|
||||
|
||||
https://fiber.wiki/context#json
|
||||
```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}
|
||||
// {"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)
|
||||
@ -364,14 +377,12 @@ func main() {
|
||||
```
|
||||
|
||||
### WebSocket support
|
||||
|
||||
https://fiber.wiki/application#websocket
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.WebSocket("/ws/:name", func(c *fiber.Conn) {
|
||||
log.Println(c.Params("name"))
|
||||
|
||||
app.WebSocket("/ws", func(c *fiber.Conn) {
|
||||
for {
|
||||
mt, msg, err := c.ReadMessage()
|
||||
if err != nil {
|
||||
@ -389,26 +400,33 @@ func main() {
|
||||
}
|
||||
})
|
||||
|
||||
// Listen on ws://localhost:3000/ws/john
|
||||
// Listen on ws://localhost:3000/ws
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
### Recover from `panic`
|
||||
|
||||
### Recover middleware
|
||||
https://fiber.wiki/middleware#recover
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
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!")
|
||||
})
|
||||
|
||||
app.Recover(func(c *fiber.Ctx) {
|
||||
c.Status(500).Send(c.Error())
|
||||
// => 500 "Something went wrong!"
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
@ -437,6 +455,12 @@ If you want to say **thank you** and/or support the active development of `Fiber
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/gofiber/fiber">
|
||||
<img src="https://i.stack.imgur.com/frlIf.png" width="100px"></br>
|
||||
<sub><b>JustDave</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/bihe">
|
||||
<img src="https://avatars1.githubusercontent.com/u/635852?s=460&v=4" width="100px"></br>
|
||||
@ -471,3 +495,11 @@ If you want to say **thank you** and/or support the active development of `Fiber
|
||||
## ⚠️ License
|
||||
|
||||
`Fiber` is free and open-source software licensed under the [MIT License](https://github.com/gofiber/fiber/blob/master/LICENSE).
|
||||
|
||||
[](https://sourcerer.io/fame/Fenny/gofiber/fiber/links/0)
|
||||
[](https://sourcerer.io/fame/Fenny/gofiber/fiber/links/1)
|
||||
[](https://sourcerer.io/fame/Fenny/gofiber/fiber/links/2)
|
||||
[](https://sourcerer.io/fame/Fenny/gofiber/fiber/links/3)
|
||||
[](https://sourcerer.io/fame/Fenny/gofiber/fiber/links/4)
|
||||
[](https://sourcerer.io/fame/Fenny/gofiber/fiber/links/5)
|
||||
[](https://sourcerer.io/fame/Fenny/gofiber/fiber/links/6)
|
||||
|
251
.github/README_de.md
vendored
251
.github/README_de.md
vendored
@ -33,6 +33,9 @@
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_tr.md">
|
||||
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/tr.svg">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_id.md">
|
||||
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/id.svg">
|
||||
</a>
|
||||
<br><br>
|
||||
<a href="https://github.com/gofiber/fiber/releases">
|
||||
<img src="https://img.shields.io/github/release/gofiber/fiber?style=flat-square">
|
||||
@ -122,27 +125,6 @@ Fiber ist **inspiriert** von Expressjs, dem beliebtesten Web-Framework im Intern
|
||||
|
||||
Nachfolgend sind einige der gängigen Beispiele aufgeführt. Wenn du weitere Codebeispiele sehen möchten, besuche bitte unser ["Recipes Repository"](https://github.com/gofiber/recipes) oder besuche unsere [API Dokumentation](https://fiber.wiki).
|
||||
|
||||
### Serve static files
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Static("/public")
|
||||
// => http://localhost:3000/js/script.js
|
||||
// => http://localhost:3000/css/style.css
|
||||
|
||||
app.Static("/prefix", "/public")
|
||||
// => http://localhost:3000/prefix/js/script.js
|
||||
// => http://localhost:3000/prefix/css/style.css
|
||||
|
||||
app.Static("*", "/public/index.html")
|
||||
// => http://localhost:3000/any/path/shows/index/html
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
### Routing
|
||||
|
||||
```go
|
||||
@ -171,8 +153,30 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
### Middleware & Next
|
||||
### Serve static files
|
||||
https://fiber.wiki/application#static
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Static("/", "/public")
|
||||
// => http://localhost:3000/js/script.js
|
||||
// => http://localhost:3000/css/style.css
|
||||
|
||||
app.Static("/prefix", "/public")
|
||||
// => http://localhost:3000/prefix/js/script.js
|
||||
// => http://localhost:3000/prefix/css/style.css
|
||||
|
||||
app.Static("*", "/public/index.html")
|
||||
// => http://localhost:3000/any/path/shows/index/html
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
### Middleware & Next
|
||||
https://fiber.wiki/routing#middleware
|
||||
https://fiber.wiki/context#next
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
@ -200,7 +204,122 @@ func main() {
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>📜 Show more code examples</summary>
|
||||
<summary>📚 Show more code examples</summary>
|
||||
|
||||
### Template engines
|
||||
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)
|
||||
|
||||
```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"
|
||||
|
||||
// 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
|
||||
https://fiber.wiki/application#group
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Root API route
|
||||
api := app.Group("/api", cors()) // /api
|
||||
|
||||
// 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 routes
|
||||
v2 := api.Group("/v2", mongodb()) // /api/v2
|
||||
v2.Get("/list", handler) // /api/v2/list
|
||||
v2.Get("/user", handler) // /api/v2/user
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Middleware logger
|
||||
https://fiber.wiki/middleware#logger
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// If you want to change default Logger config
|
||||
loggerConfig := middleware.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!")
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
Check CORS by passing any domain in `Origin` header:
|
||||
|
||||
```bash
|
||||
curl -H "Origin: http://example.com" --verbose http://localhost:3000
|
||||
```
|
||||
|
||||
### Custom 404 response
|
||||
|
||||
@ -209,9 +328,11 @@ func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Static("/public")
|
||||
|
||||
app.Get("/demo", func(c *fiber.Ctx) {
|
||||
c.Send("This is a demo!")
|
||||
})
|
||||
|
||||
app.Post("/register", func(c *fiber.Ctx) {
|
||||
c.Send("Welcome!")
|
||||
})
|
||||
@ -226,40 +347,82 @@ func main() {
|
||||
```
|
||||
|
||||
### JSON Response
|
||||
|
||||
https://fiber.wiki/context#json
|
||||
```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}
|
||||
// {"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)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### Recover from panic
|
||||
|
||||
### WebSocket support
|
||||
https://fiber.wiki/application#websocket
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
panic("Something went wrong!")
|
||||
app.WebSocket("/ws", func(c *fiber.Conn) {
|
||||
for {
|
||||
mt, msg, err := c.ReadMessage()
|
||||
if err != nil {
|
||||
log.Println("read:", err)
|
||||
break
|
||||
}
|
||||
|
||||
log.Printf("recovery: %s", msg)
|
||||
|
||||
err = c.WriteMessage(mt, msg)
|
||||
if err != nil {
|
||||
log.Println("write:", err)
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
app.Recover(func(c *fiber.Ctx) {
|
||||
c.Status(500).Send(c.Error())
|
||||
// => 500 "Something went wrong!"
|
||||
// Listen on ws://localhost:3000/ws
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
### Recover middleware
|
||||
https://fiber.wiki/middleware#recover
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
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!")
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
@ -287,6 +450,12 @@ Falls du **danke** sagen möchtest und/oder aktiv die Entwicklung von `fiber` f
|
||||
</a>
|
||||
<table>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/gofiber/fiber">
|
||||
<img src="https://i.stack.imgur.com/frlIf.png" width="100px"></br>
|
||||
<sub><b>JustDave</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/bihe">
|
||||
<img src="https://avatars1.githubusercontent.com/u/635852?s=460&v=4" width="100px"></br>
|
||||
@ -296,7 +465,7 @@ Falls du **danke** sagen möchtest und/oder aktiv die Entwicklung von `fiber` f
|
||||
<td align="center">
|
||||
<a href="https://github.com/koddr">
|
||||
<img src="https://avatars0.githubusercontent.com/u/11155743?s=460&v=4" width="100px"></br>
|
||||
<sub><b>koddr</b></sub>
|
||||
<sub><b>Vic Shóstak</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
|
253
.github/README_es.md
vendored
253
.github/README_es.md
vendored
@ -33,6 +33,9 @@
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_tr.md">
|
||||
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/tr.svg">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_id.md">
|
||||
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/id.svg">
|
||||
</a>
|
||||
<br><br>
|
||||
<a href="https://github.com/gofiber/fiber/releases">
|
||||
<img src="https://img.shields.io/github/release/gofiber/fiber?style=flat-square">
|
||||
@ -88,7 +91,7 @@ En primer lugar, [descargue](https://golang.org/dl/) e instale Go. Se requiere `
|
||||
La instalación se realiza con el comando [`go get`](https://golang.org/cmd/go/#hdr-Add_dependencies_to_current_module_and_install_them) :
|
||||
|
||||
```bash
|
||||
go get github.com/gofiber/fiber
|
||||
go get github.com/gofiber/fiber/...
|
||||
```
|
||||
|
||||
## 🤖 Puntos de referencia
|
||||
@ -122,27 +125,6 @@ Fiber está **inspirado** en Expressjs, el framework web más popular en Interne
|
||||
|
||||
A continuación se enumeran algunos de los ejemplos comunes. Si desea ver más ejemplos de código, visite nuestro [repositorio de Recetas](https://github.com/gofiber/recipes) o nuestra [documentación de API](https://fiber.wiki) .
|
||||
|
||||
### Serve static files
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Static("/public")
|
||||
// => http://localhost:3000/js/script.js
|
||||
// => http://localhost:3000/css/style.css
|
||||
|
||||
app.Static("/prefix", "/public")
|
||||
// => http://localhost:3000/prefix/js/script.js
|
||||
// => http://localhost:3000/prefix/css/style.css
|
||||
|
||||
app.Static("*", "/public/index.html")
|
||||
// => http://localhost:3000/any/path/shows/index/html
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
### Routing
|
||||
|
||||
```go
|
||||
@ -171,8 +153,30 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
### Middleware & Next
|
||||
### Serve static files
|
||||
https://fiber.wiki/application#static
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Static("/", "/public")
|
||||
// => http://localhost:3000/js/script.js
|
||||
// => http://localhost:3000/css/style.css
|
||||
|
||||
app.Static("/prefix", "/public")
|
||||
// => http://localhost:3000/prefix/js/script.js
|
||||
// => http://localhost:3000/prefix/css/style.css
|
||||
|
||||
app.Static("*", "/public/index.html")
|
||||
// => http://localhost:3000/any/path/shows/index/html
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
### Middleware & Next
|
||||
https://fiber.wiki/routing#middleware
|
||||
https://fiber.wiki/context#next
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
@ -200,7 +204,122 @@ func main() {
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>📜 Show more code examples</summary>
|
||||
<summary>📚 Show more code examples</summary>
|
||||
|
||||
### Template engines
|
||||
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)
|
||||
|
||||
```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"
|
||||
|
||||
// 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
|
||||
https://fiber.wiki/application#group
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Root API route
|
||||
api := app.Group("/api", cors()) // /api
|
||||
|
||||
// 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 routes
|
||||
v2 := api.Group("/v2", mongodb()) // /api/v2
|
||||
v2.Get("/list", handler) // /api/v2/list
|
||||
v2.Get("/user", handler) // /api/v2/user
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Middleware logger
|
||||
https://fiber.wiki/middleware#logger
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// If you want to change default Logger config
|
||||
loggerConfig := middleware.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!")
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
Check CORS by passing any domain in `Origin` header:
|
||||
|
||||
```bash
|
||||
curl -H "Origin: http://example.com" --verbose http://localhost:3000
|
||||
```
|
||||
|
||||
### Custom 404 response
|
||||
|
||||
@ -209,9 +328,11 @@ func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Static("/public")
|
||||
|
||||
app.Get("/demo", func(c *fiber.Ctx) {
|
||||
c.Send("This is a demo!")
|
||||
})
|
||||
|
||||
app.Post("/register", func(c *fiber.Ctx) {
|
||||
c.Send("Welcome!")
|
||||
})
|
||||
@ -226,40 +347,82 @@ func main() {
|
||||
```
|
||||
|
||||
### JSON Response
|
||||
|
||||
https://fiber.wiki/context#json
|
||||
```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}
|
||||
// {"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)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### Recover from panic
|
||||
|
||||
### WebSocket support
|
||||
https://fiber.wiki/application#websocket
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
panic("Something went wrong!")
|
||||
app.WebSocket("/ws", func(c *fiber.Conn) {
|
||||
for {
|
||||
mt, msg, err := c.ReadMessage()
|
||||
if err != nil {
|
||||
log.Println("read:", err)
|
||||
break
|
||||
}
|
||||
|
||||
log.Printf("recovery: %s", msg)
|
||||
|
||||
err = c.WriteMessage(mt, msg)
|
||||
if err != nil {
|
||||
log.Println("write:", err)
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
app.Recover(func(c *fiber.Ctx) {
|
||||
c.Status(500).Send(c.Error())
|
||||
// => 500 "Something went wrong!"
|
||||
// Listen on ws://localhost:3000/ws
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
### Recover middleware
|
||||
https://fiber.wiki/middleware#recover
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
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!")
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
@ -287,6 +450,12 @@ Si quiere **agradecer** y/o apoyar el desarrollo activo de la `Fiber`:
|
||||
</a>
|
||||
<table>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/gofiber/fiber">
|
||||
<img src="https://i.stack.imgur.com/frlIf.png" width="100px"></br>
|
||||
<sub><b>JustDave</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/bihe">
|
||||
<img src="https://avatars1.githubusercontent.com/u/635852?s=460&v=4" width="100px"></br>
|
||||
@ -296,7 +465,7 @@ Si quiere **agradecer** y/o apoyar el desarrollo activo de la `Fiber`:
|
||||
<td align="center">
|
||||
<a href="https://github.com/koddr">
|
||||
<img src="https://avatars0.githubusercontent.com/u/11155743?s=460&v=4" width="100px"></br>
|
||||
<sub><b>koddr</b></sub>
|
||||
<sub><b>Vic Shóstak</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
|
251
.github/README_fr.md
vendored
251
.github/README_fr.md
vendored
@ -33,6 +33,9 @@
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_tr.md">
|
||||
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/tr.svg">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_id.md">
|
||||
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/id.svg">
|
||||
</a>
|
||||
<br><br>
|
||||
<a href="https://github.com/gofiber/fiber/releases">
|
||||
<img src="https://img.shields.io/github/release/gofiber/fiber?style=flat-square">
|
||||
@ -122,27 +125,6 @@ Fiber est **inspiré** par Express, le framework web le plus populaire d'Interne
|
||||
|
||||
Ci-dessous quelques exemples courants. Si vous voulez voir plus d'exemples, rendez-vous sur notre ["Recipes repository"](https://github.com/gofiber/recipes) ou visitez notre [documentation API](https://fiber.wiki).
|
||||
|
||||
### Serve static files
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Static("/public")
|
||||
// => http://localhost:3000/js/script.js
|
||||
// => http://localhost:3000/css/style.css
|
||||
|
||||
app.Static("/prefix", "/public")
|
||||
// => http://localhost:3000/prefix/js/script.js
|
||||
// => http://localhost:3000/prefix/css/style.css
|
||||
|
||||
app.Static("*", "/public/index.html")
|
||||
// => http://localhost:3000/any/path/shows/index/html
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
### Routing
|
||||
|
||||
```go
|
||||
@ -171,8 +153,30 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
### Middleware & Next
|
||||
### Serve static files
|
||||
https://fiber.wiki/application#static
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Static("/", "/public")
|
||||
// => http://localhost:3000/js/script.js
|
||||
// => http://localhost:3000/css/style.css
|
||||
|
||||
app.Static("/prefix", "/public")
|
||||
// => http://localhost:3000/prefix/js/script.js
|
||||
// => http://localhost:3000/prefix/css/style.css
|
||||
|
||||
app.Static("*", "/public/index.html")
|
||||
// => http://localhost:3000/any/path/shows/index/html
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
### Middleware & Next
|
||||
https://fiber.wiki/routing#middleware
|
||||
https://fiber.wiki/context#next
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
@ -200,7 +204,122 @@ func main() {
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>📜 Voir plus d'exemples de code</summary>
|
||||
<summary>📚 Show more code examples</summary>
|
||||
|
||||
### Template engines
|
||||
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)
|
||||
|
||||
```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"
|
||||
|
||||
// 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
|
||||
https://fiber.wiki/application#group
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Root API route
|
||||
api := app.Group("/api", cors()) // /api
|
||||
|
||||
// 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 routes
|
||||
v2 := api.Group("/v2", mongodb()) // /api/v2
|
||||
v2.Get("/list", handler) // /api/v2/list
|
||||
v2.Get("/user", handler) // /api/v2/user
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Middleware logger
|
||||
https://fiber.wiki/middleware#logger
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// If you want to change default Logger config
|
||||
loggerConfig := middleware.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!")
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
Check CORS by passing any domain in `Origin` header:
|
||||
|
||||
```bash
|
||||
curl -H "Origin: http://example.com" --verbose http://localhost:3000
|
||||
```
|
||||
|
||||
### Custom 404 response
|
||||
|
||||
@ -209,9 +328,11 @@ func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Static("/public")
|
||||
|
||||
app.Get("/demo", func(c *fiber.Ctx) {
|
||||
c.Send("This is a demo!")
|
||||
})
|
||||
|
||||
app.Post("/register", func(c *fiber.Ctx) {
|
||||
c.Send("Welcome!")
|
||||
})
|
||||
@ -226,40 +347,82 @@ func main() {
|
||||
```
|
||||
|
||||
### JSON Response
|
||||
|
||||
https://fiber.wiki/context#json
|
||||
```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}
|
||||
// {"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)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### Recover from panic
|
||||
|
||||
### WebSocket support
|
||||
https://fiber.wiki/application#websocket
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
panic("Something went wrong!")
|
||||
app.WebSocket("/ws", func(c *fiber.Conn) {
|
||||
for {
|
||||
mt, msg, err := c.ReadMessage()
|
||||
if err != nil {
|
||||
log.Println("read:", err)
|
||||
break
|
||||
}
|
||||
|
||||
log.Printf("recovery: %s", msg)
|
||||
|
||||
err = c.WriteMessage(mt, msg)
|
||||
if err != nil {
|
||||
log.Println("write:", err)
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
app.Recover(func(c *fiber.Ctx) {
|
||||
c.Status(500).Send(c.Error())
|
||||
// => 500 "Something went wrong!"
|
||||
// Listen on ws://localhost:3000/ws
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
### Recover middleware
|
||||
https://fiber.wiki/middleware#recover
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
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!")
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
@ -287,6 +450,12 @@ Si vous voulez nous remercier et/ou soutenir le développement actif de `Fiber`:
|
||||
</a>
|
||||
<table>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/gofiber/fiber">
|
||||
<img src="https://i.stack.imgur.com/frlIf.png" width="100px"></br>
|
||||
<sub><b>JustDave</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/bihe">
|
||||
<img src="https://avatars1.githubusercontent.com/u/635852?s=460&v=4" width="100px"></br>
|
||||
@ -296,7 +465,7 @@ Si vous voulez nous remercier et/ou soutenir le développement actif de `Fiber`:
|
||||
<td align="center">
|
||||
<a href="https://github.com/koddr">
|
||||
<img src="https://avatars0.githubusercontent.com/u/11155743?s=460&v=4" width="100px"></br>
|
||||
<sub><b>koddr</b></sub>
|
||||
<sub><b>Vic Shóstak</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
|
499
.github/README_id.md
vendored
Normal file
499
.github/README_id.md
vendored
Normal file
@ -0,0 +1,499 @@
|
||||
<p align="center">
|
||||
<a href="https://fiber.wiki">
|
||||
<img alt="Fiber" height="125" src="https://github.com/gofiber/docs/blob/master/static/fiber_v2_logo.svg">
|
||||
</a>
|
||||
<br>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README.md">
|
||||
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/gb.svg">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ru.md">
|
||||
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/ru.svg">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_es.md">
|
||||
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/es.svg">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ja.md">
|
||||
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/jp.svg">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_pt.md">
|
||||
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/pt.svg">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_zh-CN.md">
|
||||
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/cn.svg">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_de.md">
|
||||
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/de.svg">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_ko.md">
|
||||
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/kr.svg">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_fr.md">
|
||||
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/fr.svg">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_tr.md">
|
||||
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/tr.svg">
|
||||
</a>
|
||||
<!-- <a href="https://github.com/gofiber/fiber/blob/master/.github/README_id.md">
|
||||
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/id.svg">
|
||||
</a> -->
|
||||
<br><br>
|
||||
<a href="https://github.com/gofiber/fiber/releases">
|
||||
<img src="https://img.shields.io/github/release/gofiber/fiber?style=flat-square">
|
||||
</a>
|
||||
<a href="https://fiber.wiki">
|
||||
<img src="https://img.shields.io/badge/api-documentation-blue?style=flat-square">
|
||||
</a>
|
||||
<a href="https://pkg.go.dev/github.com/gofiber/fiber?tab=doc">
|
||||
<img src="https://img.shields.io/badge/go.dev-reference-007d9c?logo=go&logoColor=white&style=flat-square">
|
||||
</a>
|
||||
<a href="#">
|
||||
<img src="https://img.shields.io/badge/goreport-A%2B-brightgreen?style=flat-square">
|
||||
</a>
|
||||
<a href="https://gocover.io/github.com/gofiber/fiber">
|
||||
<img src="https://img.shields.io/badge/coverage-91%25-brightgreen?style=flat-square">
|
||||
</a>
|
||||
<a href="https://travis-ci.org/gofiber/fiber">
|
||||
<img src="https://img.shields.io/travis/gofiber/fiber/master.svg?label=linux&style=flat-square">
|
||||
</a>
|
||||
<a href="https://travis-ci.org/gofiber/fiber">
|
||||
<img src="https://img.shields.io/travis/gofiber/fiber/master.svg?label=windows&style=flat-square">
|
||||
</a>
|
||||
<a href="https://travis-ci.org/gofiber/fiber">
|
||||
<img src="https://img.shields.io/travis/gofiber/fiber/master.svg?label=osx&style=flat-square">
|
||||
</a>
|
||||
</p>
|
||||
<p align="center">
|
||||
<b>Fiber</b> adalah <b>web framework</b> yang terinspirasi dari <a href="https://github.com/expressjs/express">Express</a> yang berbasiskan <a href="https://github.com/valyala/fasthttp">Fasthttp</a>, HTTP engine paling <b>cepat</b> untuk <a href="https://golang.org/doc/">Go</a>. Dirancang untuk <b>mempermudah</b>, <b>mempercepat</b> pengembangan aplikasi dengan <b>alokasi memori nol-nya</b> serta <b>kinerja</b> yang selalu diperhatikan.
|
||||
</p>
|
||||
|
||||
## ⚡️ Cara Mulai
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import "github.com/gofiber/fiber"
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
c.Send("Hello, World!")
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
## ⚙️ Instalasi
|
||||
|
||||
Pertama, [unduh](https://golang.org/dl/) dan instal Go di komputer anda. Versi `1.11` atau yang lebih tinggi diperlukan.
|
||||
|
||||
Instalasi dilakukkan dengan perintah [`go get`](https://golang.org/cmd/go/#hdr-Add_dependencies_to_current_module_and_install_them):
|
||||
|
||||
```bash
|
||||
go get -u github.com/gofiber/fiber/...
|
||||
```
|
||||
|
||||
## 🤖 Pengukuran Kinerja
|
||||
|
||||
Pengukuran ini dilakukan oleh [TechEmpower](https://github.com/TechEmpower/FrameworkBenchmarks) dan [Go Web](https://github.com/smallnest/go-web-framework-benchmark). Apabila anda ingin melihat hasil lengkapnya, silahkan kunjungi halaman [Wiki](https://fiber.wiki/benchmarks) kami.
|
||||
|
||||
<p float="left" align="middle">
|
||||
<img src="https://github.com/gofiber/docs/blob/master/.gitbook/assets//benchmark-pipeline.png" width="49%">
|
||||
<img src="https://github.com/gofiber/docs/blob/master/.gitbook/assets//benchmark_alloc.png" width="49%">
|
||||
</p>
|
||||
|
||||
## 🎯 Fitur
|
||||
|
||||
- Sistem [Routing](https://fiber.wiki/routing) yang solid
|
||||
- Serve [file statis](https://fiber.wiki/application#static)
|
||||
- [Kinerja](https://fiber.wiki/benchmarks) ekstrim
|
||||
- [Penggunaan memori](https://fiber.wiki/benchmarks) yang kecil
|
||||
- Cocok untuk [API](https://fiber.wiki/context)
|
||||
- Mendukung Middleware & [Next](https://fiber.wiki/context#next) seperti Express
|
||||
- Kembangkan aplikasi dengan [Cepat](https://dev.to/koddr/welcome-to-fiber-an-express-js-styled-fastest-web-framework-written-with-on-golang-497)
|
||||
- Tersedia di 10 bahasa lainnya
|
||||
- Dan masih banyak lagi, [kunjungi Fiber](https://fiber.wiki/)
|
||||
|
||||
## 💡 Filosofi
|
||||
|
||||
Bagi yang baru yang beralih dari [Node.js](https://nodejs.org/en/about/) ke [Go](https://golang.org/doc/) terkadang perlu waktu yang cukup lama sebelum mereka mampu membuat aplikasi web dengan Go. Fiber, sebagai **web framework** dirancang secara **minimalis** dan mengikuti filosofi dari **UNIX**, sehingga pengguna baru dengan cepat memasuki dunia Go dengan sambutan yang hangat dan dapat diandalkan.
|
||||
|
||||
Fiber terinspirasi dari Express, salah satu web framework paling terkenal di Internet. Kami menggabungkan **kemudahan** dari Express dan **kinerja luar biasa** dari Go. Apabila anda pernah membuat aplikasi dengan Node.js (_dengan Express atau yang lainnya_), maka banyak metode dan prinsip yang akan terasa **sangat umum** bagi anda.
|
||||
|
||||
Kami **mendengarkan** para pengguna di [GitHub Issues](https://github.com/gofiber/fiber/issues) (_dan berbagai platform lainnya_) untuk menciptakan web framework yang **cepat**, **fleksibel** dan **bersahabat** untuk berbagai macam keperluan, **tenggat waktu** dan **keahlian** para pengguna! Sama halnya seperti yang dilakukkan Express di dunia JavaScript.
|
||||
|
||||
## 👀 Contoh
|
||||
|
||||
Dibawah ini terdapat beberapa contoh penggunaan. Jika anda ingin contoh lainnya, silahkan kunjungi [Gudang resep](https://github.com/gofiber/recipes) atau kunjungi [Dokumentasi API](https://fiber.wiki) kami.
|
||||
|
||||
### Routing
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// GET /john
|
||||
app.Get("/:name", func(c *fiber.Ctx) {
|
||||
fmt.Printf("Hello %s!", c.Params("name"))
|
||||
// => Hello john!
|
||||
})
|
||||
|
||||
// GET /john
|
||||
app.Get("/:name/:age?", func(c *fiber.Ctx) {
|
||||
fmt.Printf("Name: %s, Age: %s", c.Params("name"), c.Params("age"))
|
||||
// => Name: john, Age:
|
||||
})
|
||||
|
||||
// GET /api/register
|
||||
app.Get("/api*", func(c *fiber.Ctx) {
|
||||
fmt.Printf("/api%s", c.Params("*"))
|
||||
// => /api/register
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
### Menyajikan file statis
|
||||
https://fiber.wiki/application#static
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Static("/", "/public")
|
||||
// => http://localhost:3000/js/script.js
|
||||
// => http://localhost:3000/css/style.css
|
||||
|
||||
app.Static("/prefix", "/public")
|
||||
// => http://localhost:3000/prefix/js/script.js
|
||||
// => http://localhost:3000/prefix/css/style.css
|
||||
|
||||
app.Static("*", "/public/index.html")
|
||||
// => http://localhost:3000/any/path/shows/index/html
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
### Middleware & Next
|
||||
https://fiber.wiki/routing#middleware
|
||||
https://fiber.wiki/context#next
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Match any route
|
||||
app.Use(func(c *fiber.Ctx) {
|
||||
fmt.Println("First middleware")
|
||||
c.Next()
|
||||
})
|
||||
|
||||
// Match all routes starting with /api
|
||||
app.Use("/api", func(c *fiber.Ctx) {
|
||||
fmt.Println("Second middleware")
|
||||
c.Next()
|
||||
})
|
||||
|
||||
// POST /api/register
|
||||
app.Post("/api/register", func(c *fiber.Ctx) {
|
||||
fmt.Println("Last middleware")
|
||||
c.Send("Hello, World!")
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>📚 Perlihatkan contoh lainnya</summary>
|
||||
|
||||
### Template engines
|
||||
https://fiber.wiki/application#settings
|
||||
https://fiber.wiki/context#render
|
||||
|
||||
Mendukung:
|
||||
- [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)
|
||||
|
||||
```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"
|
||||
|
||||
// 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,
|
||||
})
|
||||
})
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Pengelompokan routes
|
||||
https://fiber.wiki/application#group
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Root API route
|
||||
api := app.Group("/api", cors()) // /api
|
||||
|
||||
// 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 routes
|
||||
v2 := api.Group("/v2", mongodb()) // /api/v2
|
||||
v2.Get("/list", handler) // /api/v2/list
|
||||
v2.Get("/user", handler) // /api/v2/user
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Middleware logger
|
||||
https://fiber.wiki/middleware#logger
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// If you want to change default Logger config
|
||||
loggerConfig := middleware.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!")
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
Setelah diaktifkan, bisa dicoba dengan cara memberi sumber/domain berbeda di header `Origin`:
|
||||
|
||||
```bash
|
||||
curl -H "Origin: http://example.com" --verbose http://localhost:3000
|
||||
```
|
||||
|
||||
### Respon 404
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Static("/public")
|
||||
|
||||
app.Get("/demo", func(c *fiber.Ctx) {
|
||||
c.Send("This is a demo!")
|
||||
})
|
||||
|
||||
app.Post("/register", func(c *fiber.Ctx) {
|
||||
c.Send("Welcome!")
|
||||
})
|
||||
|
||||
// Last middleware to match anything
|
||||
app.Use(func(c *fiber.Ctx) {
|
||||
c.SendStatus(404) // => 404 "Not Found"
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
### Respon JSON
|
||||
https://fiber.wiki/context#json
|
||||
```go
|
||||
type User struct {
|
||||
Name string `json:"name"`
|
||||
Age int `json:"age"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Get("/user", func(c *fiber.Ctx) {
|
||||
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)
|
||||
}
|
||||
```
|
||||
|
||||
### Dukungan WebSocket
|
||||
https://fiber.wiki/application#websocket
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.WebSocket("/ws", func(c *fiber.Conn) {
|
||||
for {
|
||||
mt, msg, err := c.ReadMessage()
|
||||
if err != nil {
|
||||
log.Println("read:", err)
|
||||
break
|
||||
}
|
||||
|
||||
log.Printf("recovery: %s", msg)
|
||||
|
||||
err = c.WriteMessage(mt, msg)
|
||||
if err != nil {
|
||||
log.Println("write:", err)
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// Listen on ws://localhost:3000/ws
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
### Recover middleware
|
||||
https://fiber.wiki/middleware#recover
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
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!")
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
</details>
|
||||
|
||||
## 💬 Media
|
||||
|
||||
- [Welcome to Fiber — an Express.js styled web framework written in Go with ❤️](https://dev.to/koddr/welcome-to-fiber-an-express-js-styled-fastest-web-framework-written-with-on-golang-497) (_by [Vic Shóstak](https://github.com/koddr), 03 Feb 2020_)
|
||||
- [Fiber release v1.7 is out now! 🎉 What's new and is he still fast, flexible and friendly?](https://dev.to/koddr/fiber-v2-is-out-now-what-s-new-and-is-he-still-fast-flexible-and-friendly-3ipf) (_by [Vic Shóstak](https://github.com/koddr), 21 Feb 2020_)
|
||||
|
||||
## 👍 Berkontribusi
|
||||
|
||||
Apabila anda ingin mengucapkan **terima kasih** dan/atau mendukung pengembangan `Fiber`:
|
||||
|
||||
1. Berikan bintang atau [GitHub Star](https://github.com/gofiber/fiber/stargazers) ke proyek ini.
|
||||
2. Bagikan [di Twitter anda](https://twitter.com/intent/tweet?text=%F0%9F%9A%80%20Fiber%20%E2%80%94%20is%20an%20Express.js%20inspired%20web%20framework%20build%20on%20Fasthttp%20for%20%23Go%20https%3A%2F%2Fgithub.com%2Fgofiber%2Ffiber).
|
||||
3. Buat ulasan atau tutorial di [Medium](https://medium.com/), [Dev.to](https://dev.to/) atau blog pribadi anda.
|
||||
4. Bantu kami menerjemahkan `README` ini ke bahasa lainnya.
|
||||
|
||||
|
||||
## ☕ Para Pendukung
|
||||
|
||||
<a href="https://www.buymeacoffee.com/fenny" target="_blank">
|
||||
<img src="https://github.com/gofiber/docs/blob/master/static/buy-morning-coffee-3x.gif" alt="Buy Me A Coffee" height="100" >
|
||||
</a>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/gofiber/fiber">
|
||||
<img src="https://i.stack.imgur.com/frlIf.png" width="100px"></br>
|
||||
<sub><b>JustDave</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/bihe">
|
||||
<img src="https://avatars1.githubusercontent.com/u/635852?s=460&v=4" width="100px"></br>
|
||||
<sub><b>HenrikBinggl</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/koddr">
|
||||
<img src="https://avatars0.githubusercontent.com/u/11155743?s=460&v=4" width="100px"></br>
|
||||
<sub><b>Vic Shóstak</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/MarvinJWendt">
|
||||
<img src="https://avatars1.githubusercontent.com/u/31022056?s=460&v=4" width="100px"></br>
|
||||
<sub><b>MarvinJWendt</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/toishy">
|
||||
<img src="https://avatars1.githubusercontent.com/u/31921460?s=460&v=4" width="100px"></br>
|
||||
<sub><b>ToishY</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
## ⭐️ Bintang
|
||||
|
||||
<a href="https://starchart.cc/gofiber/fiber" rel="nofollow"><img src="https://starchart.cc/gofiber/fiber.svg" alt="Stars over time" style="max-width:100%;"></a>
|
||||
|
||||
## ⚠️ Lisensi
|
||||
|
||||
`Fiber` adalah perangkat lunak gratis dengan sumber terbuka berlisensi [MIT License](https://github.com/gofiber/fiber/blob/master/LICENSE).
|
||||
|
||||
[](https://sourcerer.io/fame/Fenny/gofiber/fiber/links/0)[](https://sourcerer.io/fame/Fenny/gofiber/fiber/links/1)[](https://sourcerer.io/fame/Fenny/gofiber/fiber/links/2)[](https://sourcerer.io/fame/Fenny/gofiber/fiber/links/3)[](https://sourcerer.io/fame/Fenny/gofiber/fiber/links/4)[](https://sourcerer.io/fame/Fenny/gofiber/fiber/links/5)[](https://sourcerer.io/fame/Fenny/gofiber/fiber/links/6)[](https://sourcerer.io/fame/Fenny/gofiber/fiber/links/7)
|
252
.github/README_ja.md
vendored
252
.github/README_ja.md
vendored
@ -33,6 +33,9 @@
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_tr.md">
|
||||
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/tr.svg">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_id.md">
|
||||
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/id.svg">
|
||||
</a>
|
||||
<br><br>
|
||||
<a href="https://github.com/gofiber/fiber/releases">
|
||||
<img src="https://img.shields.io/github/release/gofiber/fiber?style=flat-square">
|
||||
@ -126,27 +129,6 @@ Fiberは人気の高いWebフレームワークであるExpressjsに**インス
|
||||
|
||||
以下に一般的な例をいくつか示します。他のコード例をご覧になりたい場合は、 [Recipesリポジトリ](https://github.com/gofiber/recipes)または[APIドキュメント](https://fiber.wiki)にアクセスしてください。
|
||||
|
||||
### Serve static files
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Static("/public")
|
||||
// => http://localhost:3000/js/script.js
|
||||
// => http://localhost:3000/css/style.css
|
||||
|
||||
app.Static("/prefix", "/public")
|
||||
// => http://localhost:3000/prefix/js/script.js
|
||||
// => http://localhost:3000/prefix/css/style.css
|
||||
|
||||
app.Static("*", "/public/index.html")
|
||||
// => http://localhost:3000/any/path/shows/index/html
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
### Routing
|
||||
|
||||
```go
|
||||
@ -175,8 +157,30 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
### Middleware & Next
|
||||
### Serve static files
|
||||
https://fiber.wiki/application#static
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Static("/", "/public")
|
||||
// => http://localhost:3000/js/script.js
|
||||
// => http://localhost:3000/css/style.css
|
||||
|
||||
app.Static("/prefix", "/public")
|
||||
// => http://localhost:3000/prefix/js/script.js
|
||||
// => http://localhost:3000/prefix/css/style.css
|
||||
|
||||
app.Static("*", "/public/index.html")
|
||||
// => http://localhost:3000/any/path/shows/index/html
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
### Middleware & Next
|
||||
https://fiber.wiki/routing#middleware
|
||||
https://fiber.wiki/context#next
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
@ -204,7 +208,122 @@ func main() {
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>📜 Show more code examples</summary>
|
||||
<summary>📚 Show more code examples</summary>
|
||||
|
||||
### Template engines
|
||||
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)
|
||||
|
||||
```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"
|
||||
|
||||
// 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
|
||||
https://fiber.wiki/application#group
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Root API route
|
||||
api := app.Group("/api", cors()) // /api
|
||||
|
||||
// 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 routes
|
||||
v2 := api.Group("/v2", mongodb()) // /api/v2
|
||||
v2.Get("/list", handler) // /api/v2/list
|
||||
v2.Get("/user", handler) // /api/v2/user
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Middleware logger
|
||||
https://fiber.wiki/middleware#logger
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// If you want to change default Logger config
|
||||
loggerConfig := middleware.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!")
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
Check CORS by passing any domain in `Origin` header:
|
||||
|
||||
```bash
|
||||
curl -H "Origin: http://example.com" --verbose http://localhost:3000
|
||||
```
|
||||
|
||||
### Custom 404 response
|
||||
|
||||
@ -213,9 +332,11 @@ func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Static("/public")
|
||||
|
||||
app.Get("/demo", func(c *fiber.Ctx) {
|
||||
c.Send("This is a demo!")
|
||||
})
|
||||
|
||||
app.Post("/register", func(c *fiber.Ctx) {
|
||||
c.Send("Welcome!")
|
||||
})
|
||||
@ -230,46 +351,89 @@ func main() {
|
||||
```
|
||||
|
||||
### JSON Response
|
||||
|
||||
https://fiber.wiki/context#json
|
||||
```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}
|
||||
// {"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)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### Recover from panic
|
||||
|
||||
### WebSocket support
|
||||
https://fiber.wiki/application#websocket
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
panic("Something went wrong!")
|
||||
app.WebSocket("/ws", func(c *fiber.Conn) {
|
||||
for {
|
||||
mt, msg, err := c.ReadMessage()
|
||||
if err != nil {
|
||||
log.Println("read:", err)
|
||||
break
|
||||
}
|
||||
|
||||
log.Printf("recovery: %s", msg)
|
||||
|
||||
err = c.WriteMessage(mt, msg)
|
||||
if err != nil {
|
||||
log.Println("write:", err)
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
app.Recover(func(c *fiber.Ctx) {
|
||||
c.Status(500).Send(c.Error())
|
||||
// => 500 "Something went wrong!"
|
||||
// Listen on ws://localhost:3000/ws
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
### Recover middleware
|
||||
https://fiber.wiki/middleware#recover
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
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!")
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
</details>
|
||||
|
||||
## 💬 メディア
|
||||
|
||||
- [ファイバーへようこそ— Go with❤️で記述されたExpress.jsスタイルのWebフレームワーク](https://dev.to/koddr/welcome-to-fiber-an-express-js-styled-fastest-web-framework-written-with-on-golang-497) *[ヴィック・ショースタク](https://github.com/koddr) 、2020年2月3日*
|
||||
@ -292,6 +456,12 @@ func main() {
|
||||
</a>
|
||||
<table>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/gofiber/fiber">
|
||||
<img src="https://i.stack.imgur.com/frlIf.png" width="100px"></br>
|
||||
<sub><b>JustDave</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/bihe">
|
||||
<img src="https://avatars1.githubusercontent.com/u/635852?s=460&v=4" width="100px"></br>
|
||||
@ -301,7 +471,7 @@ func main() {
|
||||
<td align="center">
|
||||
<a href="https://github.com/koddr">
|
||||
<img src="https://avatars0.githubusercontent.com/u/11155743?s=460&v=4" width="100px"></br>
|
||||
<sub><b>koddr</b></sub>
|
||||
<sub><b>Vic Shóstak</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
|
251
.github/README_ko.md
vendored
251
.github/README_ko.md
vendored
@ -33,6 +33,9 @@
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_tr.md">
|
||||
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/tr.svg">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_id.md">
|
||||
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/id.svg">
|
||||
</a>
|
||||
<br><br>
|
||||
<a href="https://github.com/gofiber/fiber/releases">
|
||||
<img src="https://img.shields.io/github/release/gofiber/fiber?style=flat-square">
|
||||
@ -122,27 +125,6 @@ Fiber는 인터넷에서 가장 인기있는 웹 프레임워크인 Express에
|
||||
|
||||
다음은 일반적인 예제들 입니다. 더 많은 코드 예제를 보고 싶다면, [Recipes 저장소](https://github.com/gofiber/recipes) 또는 [API 문서](https://fiber.wiki)를 방문하세요.
|
||||
|
||||
### Serve static files
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Static("/public")
|
||||
// => http://localhost:3000/js/script.js
|
||||
// => http://localhost:3000/css/style.css
|
||||
|
||||
app.Static("/prefix", "/public")
|
||||
// => http://localhost:3000/prefix/js/script.js
|
||||
// => http://localhost:3000/prefix/css/style.css
|
||||
|
||||
app.Static("*", "./public/index.html")
|
||||
// => http://localhost:3000/anything/returns/the/index/file
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
### Routing
|
||||
|
||||
```go
|
||||
@ -171,8 +153,30 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
### Middleware & Next
|
||||
### Serve static files
|
||||
https://fiber.wiki/application#static
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Static("/", "/public")
|
||||
// => http://localhost:3000/js/script.js
|
||||
// => http://localhost:3000/css/style.css
|
||||
|
||||
app.Static("/prefix", "/public")
|
||||
// => http://localhost:3000/prefix/js/script.js
|
||||
// => http://localhost:3000/prefix/css/style.css
|
||||
|
||||
app.Static("*", "/public/index.html")
|
||||
// => http://localhost:3000/any/path/shows/index/html
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
### Middleware & Next
|
||||
https://fiber.wiki/routing#middleware
|
||||
https://fiber.wiki/context#next
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
@ -200,7 +204,122 @@ func main() {
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>📜 Show more code examples</summary>
|
||||
<summary>📚 Show more code examples</summary>
|
||||
|
||||
### Template engines
|
||||
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)
|
||||
|
||||
```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"
|
||||
|
||||
// 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
|
||||
https://fiber.wiki/application#group
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Root API route
|
||||
api := app.Group("/api", cors()) // /api
|
||||
|
||||
// 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 routes
|
||||
v2 := api.Group("/v2", mongodb()) // /api/v2
|
||||
v2.Get("/list", handler) // /api/v2/list
|
||||
v2.Get("/user", handler) // /api/v2/user
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Middleware logger
|
||||
https://fiber.wiki/middleware#logger
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// If you want to change default Logger config
|
||||
loggerConfig := middleware.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!")
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
Check CORS by passing any domain in `Origin` header:
|
||||
|
||||
```bash
|
||||
curl -H "Origin: http://example.com" --verbose http://localhost:3000
|
||||
```
|
||||
|
||||
### Custom 404 response
|
||||
|
||||
@ -209,9 +328,11 @@ func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Static("/public")
|
||||
|
||||
app.Get("/demo", func(c *fiber.Ctx) {
|
||||
c.Send("This is a demo!")
|
||||
})
|
||||
|
||||
app.Post("/register", func(c *fiber.Ctx) {
|
||||
c.Send("Welcome!")
|
||||
})
|
||||
@ -226,40 +347,82 @@ func main() {
|
||||
```
|
||||
|
||||
### JSON Response
|
||||
|
||||
https://fiber.wiki/context#json
|
||||
```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}
|
||||
// {"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)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### Recover from panic
|
||||
|
||||
### WebSocket support
|
||||
https://fiber.wiki/application#websocket
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
panic("Something went wrong!")
|
||||
app.WebSocket("/ws", func(c *fiber.Conn) {
|
||||
for {
|
||||
mt, msg, err := c.ReadMessage()
|
||||
if err != nil {
|
||||
log.Println("read:", err)
|
||||
break
|
||||
}
|
||||
|
||||
log.Printf("recovery: %s", msg)
|
||||
|
||||
err = c.WriteMessage(mt, msg)
|
||||
if err != nil {
|
||||
log.Println("write:", err)
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
app.Recover(func(c *fiber.Ctx) {
|
||||
c.Status(500).Send(c.Error())
|
||||
// => 500 "Something went wrong!"
|
||||
// Listen on ws://localhost:3000/ws
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
### Recover middleware
|
||||
https://fiber.wiki/middleware#recover
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
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!")
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
@ -287,6 +450,12 @@ func main() {
|
||||
</a>
|
||||
<table>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/gofiber/fiber">
|
||||
<img src="https://i.stack.imgur.com/frlIf.png" width="100px"></br>
|
||||
<sub><b>JustDave</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/bihe">
|
||||
<img src="https://avatars1.githubusercontent.com/u/635852?s=460&v=4" width="100px"></br>
|
||||
@ -296,7 +465,7 @@ func main() {
|
||||
<td align="center">
|
||||
<a href="https://github.com/koddr">
|
||||
<img src="https://avatars0.githubusercontent.com/u/11155743?s=460&v=4" width="100px"></br>
|
||||
<sub><b>koddr</b></sub>
|
||||
<sub><b>Vic Shóstak</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
|
251
.github/README_pt.md
vendored
251
.github/README_pt.md
vendored
@ -33,6 +33,9 @@
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_tr.md">
|
||||
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/tr.svg">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_id.md">
|
||||
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/id.svg">
|
||||
</a>
|
||||
<br><br>
|
||||
<a href="https://github.com/gofiber/fiber/releases">
|
||||
<img src="https://img.shields.io/github/release/gofiber/fiber?style=flat-square">
|
||||
@ -122,27 +125,6 @@ O Fiber é **inspirado** no Express, o framework web mais popular da Internet. C
|
||||
|
||||
Listados abaixo estão alguns exemplos comuns. Se você quiser ver mais exemplos de código, visite nosso [repositório de receitas](https://github.com/gofiber/recipes) ou a [documentação da API](https://fiber.wiki).
|
||||
|
||||
### Serve static files
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Static("/public")
|
||||
// => http://localhost:3000/js/script.js
|
||||
// => http://localhost:3000/css/style.css
|
||||
|
||||
app.Static("/prefix", "/public")
|
||||
// => http://localhost:3000/prefix/js/script.js
|
||||
// => http://localhost:3000/prefix/css/style.css
|
||||
|
||||
app.Static("*", "/public/index.html")
|
||||
// => http://localhost:3000/any/path/shows/index/html
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
### Routing
|
||||
|
||||
```go
|
||||
@ -171,8 +153,30 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
### Middleware & Next
|
||||
### Serve static files
|
||||
https://fiber.wiki/application#static
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Static("/", "/public")
|
||||
// => http://localhost:3000/js/script.js
|
||||
// => http://localhost:3000/css/style.css
|
||||
|
||||
app.Static("/prefix", "/public")
|
||||
// => http://localhost:3000/prefix/js/script.js
|
||||
// => http://localhost:3000/prefix/css/style.css
|
||||
|
||||
app.Static("*", "/public/index.html")
|
||||
// => http://localhost:3000/any/path/shows/index/html
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
### Middleware & Next
|
||||
https://fiber.wiki/routing#middleware
|
||||
https://fiber.wiki/context#next
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
@ -200,7 +204,122 @@ func main() {
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>📜 Show more code examples</summary>
|
||||
<summary>📚 Show more code examples</summary>
|
||||
|
||||
### Template engines
|
||||
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)
|
||||
|
||||
```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"
|
||||
|
||||
// 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
|
||||
https://fiber.wiki/application#group
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Root API route
|
||||
api := app.Group("/api", cors()) // /api
|
||||
|
||||
// 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 routes
|
||||
v2 := api.Group("/v2", mongodb()) // /api/v2
|
||||
v2.Get("/list", handler) // /api/v2/list
|
||||
v2.Get("/user", handler) // /api/v2/user
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Middleware logger
|
||||
https://fiber.wiki/middleware#logger
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// If you want to change default Logger config
|
||||
loggerConfig := middleware.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!")
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
Check CORS by passing any domain in `Origin` header:
|
||||
|
||||
```bash
|
||||
curl -H "Origin: http://example.com" --verbose http://localhost:3000
|
||||
```
|
||||
|
||||
### Custom 404 response
|
||||
|
||||
@ -209,9 +328,11 @@ func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Static("/public")
|
||||
|
||||
app.Get("/demo", func(c *fiber.Ctx) {
|
||||
c.Send("This is a demo!")
|
||||
})
|
||||
|
||||
app.Post("/register", func(c *fiber.Ctx) {
|
||||
c.Send("Welcome!")
|
||||
})
|
||||
@ -226,40 +347,82 @@ func main() {
|
||||
```
|
||||
|
||||
### JSON Response
|
||||
|
||||
https://fiber.wiki/context#json
|
||||
```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}
|
||||
// {"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)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### Recover from panic
|
||||
|
||||
### WebSocket support
|
||||
https://fiber.wiki/application#websocket
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
panic("Something went wrong!")
|
||||
app.WebSocket("/ws", func(c *fiber.Conn) {
|
||||
for {
|
||||
mt, msg, err := c.ReadMessage()
|
||||
if err != nil {
|
||||
log.Println("read:", err)
|
||||
break
|
||||
}
|
||||
|
||||
log.Printf("recovery: %s", msg)
|
||||
|
||||
err = c.WriteMessage(mt, msg)
|
||||
if err != nil {
|
||||
log.Println("write:", err)
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
app.Recover(func(c *fiber.Ctx) {
|
||||
c.Status(500).Send(c.Error())
|
||||
// => 500 "Something went wrong!"
|
||||
// Listen on ws://localhost:3000/ws
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
### Recover middleware
|
||||
https://fiber.wiki/middleware#recover
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
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!")
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
@ -287,6 +450,12 @@ Se você quer **agradecer** e/ou apoiar o desenvolvimento ativo do `Fiber`:
|
||||
</a>
|
||||
<table>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/gofiber/fiber">
|
||||
<img src="https://i.stack.imgur.com/frlIf.png" width="100px"></br>
|
||||
<sub><b>JustDave</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/bihe">
|
||||
<img src="https://avatars1.githubusercontent.com/u/635852?s=460&v=4" width="100px"></br>
|
||||
@ -296,7 +465,7 @@ Se você quer **agradecer** e/ou apoiar o desenvolvimento ativo do `Fiber`:
|
||||
<td align="center">
|
||||
<a href="https://github.com/koddr">
|
||||
<img src="https://avatars0.githubusercontent.com/u/11155743?s=460&v=4" width="100px"></br>
|
||||
<sub><b>koddr</b></sub>
|
||||
<sub><b>Vic Shóstak</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
|
9
.github/README_ru.md
vendored
9
.github/README_ru.md
vendored
@ -33,6 +33,9 @@
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_tr.md">
|
||||
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/tr.svg">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_id.md">
|
||||
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/id.svg">
|
||||
</a>
|
||||
<br><br>
|
||||
<a href="https://github.com/gofiber/fiber/releases">
|
||||
<img src="https://img.shields.io/github/release/gofiber/fiber?style=flat-square">
|
||||
@ -438,6 +441,12 @@ func main() {
|
||||
</a>
|
||||
<table>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/gofiber/fiber">
|
||||
<img src="https://i.stack.imgur.com/frlIf.png" width="100px"></br>
|
||||
<sub><b>JustDave</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/bihe">
|
||||
<img src="https://avatars1.githubusercontent.com/u/635852?s=460&v=4" width="100px"></br>
|
||||
|
223
.github/README_tr.md
vendored
223
.github/README_tr.md
vendored
@ -30,6 +30,9 @@
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_fr.md">
|
||||
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/fr.svg">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_id.md">
|
||||
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/id.svg">
|
||||
</a>
|
||||
<br><br>
|
||||
<a href="https://github.com/gofiber/fiber/releases">
|
||||
<img src="https://img.shields.io/github/release/gofiber/fiber?style=flat-square">
|
||||
@ -119,7 +122,7 @@ Fiber internet üzerinde en popüler olan Express web çatısından **esinlenmi
|
||||
|
||||
Aşağıda yaygın örneklerden bazıları listelenmiştir. Daha fazla kod örneği görmek için, lütfen [Kod depomuzu](https://github.com/gofiber/recipes) veya [API dökümantasyonunu](https://fiber.wiki) ziyaret ediniz.
|
||||
|
||||
### Rotalar
|
||||
### Routing
|
||||
|
||||
```go
|
||||
func main() {
|
||||
@ -147,13 +150,13 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
### Statik dosya yönetimi
|
||||
|
||||
### Serve static files
|
||||
https://fiber.wiki/application#static
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Static("/public")
|
||||
app.Static("/", "/public")
|
||||
// => http://localhost:3000/js/script.js
|
||||
// => http://localhost:3000/css/style.css
|
||||
|
||||
@ -168,8 +171,9 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
### Ara Katman & Sonraki
|
||||
|
||||
### Middleware & Next
|
||||
https://fiber.wiki/routing#middleware
|
||||
https://fiber.wiki/context#next
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
@ -197,18 +201,135 @@ func main() {
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>📚 Daha fazla kod örneği görüntüle</summary>
|
||||
<summary>📚 Show more code examples</summary>
|
||||
|
||||
### Özel 404 Cevabı
|
||||
### Template engines
|
||||
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)
|
||||
|
||||
```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"
|
||||
|
||||
// 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
|
||||
https://fiber.wiki/application#group
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Root API route
|
||||
api := app.Group("/api", cors()) // /api
|
||||
|
||||
// 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 routes
|
||||
v2 := api.Group("/v2", mongodb()) // /api/v2
|
||||
v2.Get("/list", handler) // /api/v2/list
|
||||
v2.Get("/user", handler) // /api/v2/user
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Middleware logger
|
||||
https://fiber.wiki/middleware#logger
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// If you want to change default Logger config
|
||||
loggerConfig := middleware.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!")
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
Check CORS by passing any domain in `Origin` header:
|
||||
|
||||
```bash
|
||||
curl -H "Origin: http://example.com" --verbose http://localhost:3000
|
||||
```
|
||||
|
||||
### Custom 404 response
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Static("/public")
|
||||
|
||||
app.Get("/demo", func(c *fiber.Ctx) {
|
||||
c.Send("This is a demo!")
|
||||
})
|
||||
|
||||
app.Post("/register", func(c *fiber.Ctx) {
|
||||
c.Send("Welcome!")
|
||||
})
|
||||
@ -222,41 +343,83 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
### JSON Cevabı
|
||||
|
||||
### JSON Response
|
||||
https://fiber.wiki/context#json
|
||||
```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}
|
||||
// {"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)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### Panikten Kurtarma
|
||||
|
||||
### WebSocket support
|
||||
https://fiber.wiki/application#websocket
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
panic("Something went wrong!")
|
||||
app.WebSocket("/ws", func(c *fiber.Conn) {
|
||||
for {
|
||||
mt, msg, err := c.ReadMessage()
|
||||
if err != nil {
|
||||
log.Println("read:", err)
|
||||
break
|
||||
}
|
||||
|
||||
log.Printf("recovery: %s", msg)
|
||||
|
||||
err = c.WriteMessage(mt, msg)
|
||||
if err != nil {
|
||||
log.Println("write:", err)
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
app.Recover(func(c *fiber.Ctx) {
|
||||
c.Status(500).Send(c.Error())
|
||||
// => 500 "Something went wrong!"
|
||||
// Listen on ws://localhost:3000/ws
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
### Recover middleware
|
||||
https://fiber.wiki/middleware#recover
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
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!")
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
@ -286,6 +449,12 @@ Eğer **teşekkür etmek** ve/veya `Fiber` ın aktif geliştirilmesini destekle
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/gofiber/fiber">
|
||||
<img src="https://i.stack.imgur.com/frlIf.png" width="100px"></br>
|
||||
<sub><b>JustDave</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/bihe">
|
||||
<img src="https://avatars1.githubusercontent.com/u/635852?s=460&v=4" width="100px"></br>
|
||||
@ -295,7 +464,7 @@ Eğer **teşekkür etmek** ve/veya `Fiber` ın aktif geliştirilmesini destekle
|
||||
<td align="center">
|
||||
<a href="https://github.com/koddr">
|
||||
<img src="https://avatars0.githubusercontent.com/u/11155743?s=460&v=4" width="100px"></br>
|
||||
<sub><b>Vic Shóstak</b></sub>
|
||||
<sub><b>Vic Shóstak</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
|
154
.github/README_zh-CN.md
vendored
154
.github/README_zh-CN.md
vendored
@ -30,6 +30,9 @@
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_fr.md">
|
||||
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/fr.svg">
|
||||
</a>
|
||||
<a href="https://github.com/gofiber/fiber/blob/master/.github/README_id.md">
|
||||
<img height="20px" src="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.6/flags/4x3/id.svg">
|
||||
</a>
|
||||
<br><br>
|
||||
<a href="https://github.com/gofiber/fiber/releases">
|
||||
<img src="https://img.shields.io/github/release/gofiber/fiber?style=flat-square">
|
||||
@ -118,7 +121,7 @@ Fiber **受** Internet上最流行的Web框架Expressjs的**启发** 。我们
|
||||
|
||||
下面列出了一些常见示例。如果您想查看更多代码示例,请访问我们的[Recipes存储库](https://github.com/gofiber/recipes)或访问我们的[API文档](https://fiber.wiki) 。
|
||||
|
||||
### 路由
|
||||
### Routing
|
||||
|
||||
```go
|
||||
func main() {
|
||||
@ -146,13 +149,13 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
### 静态文件
|
||||
|
||||
### Serve static files
|
||||
https://fiber.wiki/application#static
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Static("/public")
|
||||
app.Static("/", "/public")
|
||||
// => http://localhost:3000/js/script.js
|
||||
// => http://localhost:3000/css/style.css
|
||||
|
||||
@ -167,8 +170,9 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
### 中间件
|
||||
|
||||
### Middleware & Next
|
||||
https://fiber.wiki/routing#middleware
|
||||
https://fiber.wiki/context#next
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
@ -196,12 +200,13 @@ func main() {
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>📚 显示更多代码示例</summary>
|
||||
<summary>📚 Show more code examples</summary>
|
||||
|
||||
### 模板引擎
|
||||
|
||||
已经支持的:
|
||||
### Template engines
|
||||
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)
|
||||
@ -234,8 +239,8 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
### 组路由
|
||||
|
||||
### Grouping routes into chains
|
||||
https://fiber.wiki/application#group
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
@ -257,16 +262,73 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
### 自定义 404 响应
|
||||
### Middleware logger
|
||||
https://fiber.wiki/middleware#logger
|
||||
```go
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// If you want to change default Logger config
|
||||
loggerConfig := middleware.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!")
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
Check CORS by passing any domain in `Origin` header:
|
||||
|
||||
```bash
|
||||
curl -H "Origin: http://example.com" --verbose http://localhost:3000
|
||||
```
|
||||
|
||||
### Custom 404 response
|
||||
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Static("/public")
|
||||
|
||||
app.Get("/demo", func(c *fiber.Ctx) {
|
||||
c.Send("This is a demo!")
|
||||
})
|
||||
|
||||
app.Post("/register", func(c *fiber.Ctx) {
|
||||
c.Send("Welcome!")
|
||||
})
|
||||
@ -280,36 +342,41 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
### JSON
|
||||
|
||||
### JSON Response
|
||||
https://fiber.wiki/context#json
|
||||
```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}
|
||||
// {"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 support
|
||||
https://fiber.wiki/application#websocket
|
||||
```go
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.WebSocket("/ws/:name", func(c *fiber.Conn) {
|
||||
log.Println(c.Params("name"))
|
||||
|
||||
app.WebSocket("/ws", func(c *fiber.Conn) {
|
||||
for {
|
||||
mt, msg, err := c.ReadMessage()
|
||||
if err != nil {
|
||||
@ -327,26 +394,33 @@ func main() {
|
||||
}
|
||||
})
|
||||
|
||||
// Listen on ws://localhost:3000/ws/john
|
||||
// Listen on ws://localhost:3000/ws
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
|
||||
### 从 panic 中恢复
|
||||
|
||||
### Recover middleware
|
||||
https://fiber.wiki/middleware#recover
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber"
|
||||
"github.com/gofiber/fiber/middleware"
|
||||
)
|
||||
|
||||
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!")
|
||||
})
|
||||
|
||||
app.Recover(func(c *fiber.Ctx) {
|
||||
c.Status(500).Send(c.Error())
|
||||
// => 500 "Something went wrong!"
|
||||
})
|
||||
|
||||
app.Listen(3000)
|
||||
}
|
||||
```
|
||||
@ -374,6 +448,12 @@ func main() {
|
||||
</a>
|
||||
<table>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/gofiber/fiber">
|
||||
<img src="https://i.stack.imgur.com/frlIf.png" width="100px"></br>
|
||||
<sub><b>JustDave</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/bihe">
|
||||
<img src="https://avatars1.githubusercontent.com/u/635852?s=460&v=4" width="100px"></br>
|
||||
@ -383,7 +463,7 @@ func main() {
|
||||
<td align="center">
|
||||
<a href="https://github.com/koddr">
|
||||
<img src="https://avatars0.githubusercontent.com/u/11155743?s=460&v=4" width="100px"></br>
|
||||
<sub><b>koddr</b></sub>
|
||||
<sub><b>Vic Shóstak</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
|
170
app.go
170
app.go
@ -6,6 +6,7 @@ package fiber
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"crypto/tls"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
@ -25,26 +26,26 @@ import (
|
||||
)
|
||||
|
||||
// Version of Fiber
|
||||
const Version = "1.8.0"
|
||||
const Version = "1.8.2"
|
||||
|
||||
type (
|
||||
// App denotes the Fiber application.
|
||||
App struct {
|
||||
server *fasthttp.Server
|
||||
routes []*Route
|
||||
child bool
|
||||
recover func(*Ctx)
|
||||
Settings *Settings
|
||||
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{}`.
|
||||
Map map[string]interface{}
|
||||
// Settings is a struct holding the server settings
|
||||
Settings struct {
|
||||
// fiber settings
|
||||
// This will spawn multiple Go processes listening on the same port
|
||||
Prefork bool `default:"false"`
|
||||
// Enable strict routing. When enabled, the router treats "/foo" and "/foo/" as different. Otherwise, the router treats "/foo" and "/foo/" as the same.
|
||||
// Enable strict routing. When enabled, the router treats "/foo" and "/foo/" as different.
|
||||
StrictRouting bool `default:"false"`
|
||||
// Enable case sensitivity. When enabled, "/Foo" and "/foo" are different routes. When disabled, "/Foo" and "/foo" are treated the same.
|
||||
// Enable case sensitivity. When enabled, "/Foo" and "/foo" are different routes.
|
||||
CaseSensitive bool `default:"false"`
|
||||
// Enables the "Server: value" HTTP header.
|
||||
ServerHeader string `default:""`
|
||||
@ -52,28 +53,13 @@ type (
|
||||
Immutable bool `default:"false"`
|
||||
// Enables GZip / Deflate compression for all responses
|
||||
Compression bool `default:"false"`
|
||||
// CompressionLevel int `default:"1"`
|
||||
// fasthttp settings
|
||||
// GETOnly bool `default:"false"`
|
||||
// IdleTimeout time.Duration `default:"0"`
|
||||
// Concurrency int `default:"256 * 1024"`
|
||||
// ReadTimeout time.Duration `default:"0"`
|
||||
// WriteTimeout time.Duration `default:"0"`
|
||||
// TCPKeepalive bool `default:"false"`
|
||||
// MaxConnsPerIP int `default:"0"`
|
||||
// ReadBufferSize int `default:"4096"`
|
||||
// WriteBufferSize int `default:"4096"`
|
||||
// ConcurrencySleep time.Duration `default:"0"`
|
||||
// DisableKeepAlive bool `default:"false"`
|
||||
// ReduceMemoryUsage bool `default:"false"`
|
||||
// MaxRequestsPerConn int `default:"0"`
|
||||
// TCPKeepalivePeriod time.Duration `default:"0"`
|
||||
// Max body size that the server accepts
|
||||
BodyLimit int `default:"4 * 1024 * 1024"`
|
||||
// NoHeaderNormalizing bool `default:"false"`
|
||||
// NoDefaultContentType bool `default:"false"`
|
||||
// template settings
|
||||
TemplateFolder string `default:""`
|
||||
TemplateEngine string `default:""`
|
||||
// Folder containing template files
|
||||
TemplateFolder string `default:""`
|
||||
// Template engine: html, amber, handlebars , mustache or pug
|
||||
TemplateEngine string `default:""`
|
||||
// Extension for the template files
|
||||
TemplateExtension string `default:""`
|
||||
}
|
||||
)
|
||||
@ -84,61 +70,45 @@ func init() {
|
||||
}
|
||||
|
||||
// New : https://fiber.wiki/application#new
|
||||
func New(settings ...*Settings) (app *App) {
|
||||
var prefork bool
|
||||
var child bool
|
||||
for _, arg := range os.Args[1:] {
|
||||
if arg == "-prefork" {
|
||||
func New(settings ...*Settings) *App {
|
||||
var prefork, child bool
|
||||
// Loop trought args without using flag.Parse()
|
||||
for i := range os.Args[1:] {
|
||||
if os.Args[i] == "-prefork" {
|
||||
prefork = true
|
||||
} else if arg == "-child" {
|
||||
} else if os.Args[i] == "-child" {
|
||||
child = true
|
||||
}
|
||||
}
|
||||
app = &App{
|
||||
// Create default app
|
||||
app := &App{
|
||||
child: child,
|
||||
Settings: &Settings{
|
||||
Prefork: prefork,
|
||||
BodyLimit: 4 * 1024 * 1024,
|
||||
},
|
||||
}
|
||||
// If settings exist, set some defaults
|
||||
if len(settings) > 0 {
|
||||
opt := settings[0]
|
||||
if !opt.Prefork {
|
||||
opt.Prefork = prefork
|
||||
if !settings[0].Prefork { // Default to -prefork flag if false
|
||||
settings[0].Prefork = prefork
|
||||
}
|
||||
if opt.Immutable {
|
||||
getString = func(b []byte) string {
|
||||
return string(b)
|
||||
}
|
||||
if settings[0].BodyLimit == 0 { // Default MaxRequestBodySize
|
||||
settings[0].BodyLimit = 4 * 1024 * 1024
|
||||
}
|
||||
// if opt.Concurrency == 0 {
|
||||
// opt.Concurrency = 256 * 1024
|
||||
// }
|
||||
// if opt.ReadBufferSize == 0 {
|
||||
// opt.ReadBufferSize = 4096
|
||||
// }
|
||||
// if opt.WriteBufferSize == 0 {
|
||||
// opt.WriteBufferSize = 4096
|
||||
// }
|
||||
if opt.BodyLimit == 0 {
|
||||
opt.BodyLimit = 4 * 1024 * 1024
|
||||
if settings[0].Immutable { // Replace unsafe conversion funcs
|
||||
getString = func(b []byte) string { return string(b) }
|
||||
getBytes = func(s string) []byte { return []byte(s) }
|
||||
}
|
||||
// if opt.CompressionLevel == 0 {
|
||||
// opt.CompressionLevel = 1
|
||||
// }
|
||||
app.Settings = opt
|
||||
return
|
||||
app.Settings = settings[0] // Set custom settings
|
||||
}
|
||||
app.Settings = &Settings{
|
||||
Prefork: prefork,
|
||||
// Concurrency: 256 * 1024,
|
||||
// ReadBufferSize: 4096,
|
||||
// WriteBufferSize: 4096,
|
||||
BodyLimit: 4 * 1024 * 1024,
|
||||
}
|
||||
return
|
||||
return app
|
||||
}
|
||||
|
||||
// Group : https://fiber.wiki/application#group
|
||||
func (app *App) Group(prefix string, handlers ...func(*Ctx)) *Group {
|
||||
if len(handlers) > 0 {
|
||||
app.registerMethod("USE", prefix, "", handlers...)
|
||||
app.registerMethod("USE", prefix, handlers...)
|
||||
}
|
||||
return &Group{
|
||||
prefix: prefix,
|
||||
@ -147,8 +117,8 @@ func (app *App) Group(prefix string, handlers ...func(*Ctx)) *Group {
|
||||
}
|
||||
|
||||
// Static : https://fiber.wiki/application#static
|
||||
func (app *App) Static(args ...string) *App {
|
||||
app.registerStatic("/", args...)
|
||||
func (app *App) Static(prefix, root string) *App {
|
||||
app.registerStatic(prefix, root)
|
||||
return app
|
||||
}
|
||||
|
||||
@ -166,83 +136,84 @@ func (app *App) Use(args ...interface{}) *App {
|
||||
log.Fatalf("Invalid handler: %v", reflect.TypeOf(arg))
|
||||
}
|
||||
}
|
||||
app.registerMethod("USE", "", path, handlers...)
|
||||
app.registerMethod("USE", path, handlers...)
|
||||
return 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(http.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(http.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(http.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(http.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(http.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(http.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(http.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(http.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(http.MethodGet, path, handlers...)
|
||||
return app
|
||||
}
|
||||
|
||||
// All : https://fiber.wiki/application#http-methods
|
||||
func (app *App) All(path string, handlers ...func(*Ctx)) *App {
|
||||
app.registerMethod("ALL", "", path, handlers...)
|
||||
app.registerMethod("ALL", path, handlers...)
|
||||
return app
|
||||
}
|
||||
|
||||
// WebSocket : https://fiber.wiki/application#websocket
|
||||
func (app *App) WebSocket(path string, handler func(*Conn)) *App {
|
||||
app.registerWebSocket(http.MethodGet, "", path, handler)
|
||||
func (app *App) WebSocket(path string, handle func(*Conn)) *App {
|
||||
app.registerWebSocket(http.MethodGet, path, handle)
|
||||
return app
|
||||
}
|
||||
|
||||
// Recover : https://fiber.wiki/application#recover
|
||||
func (app *App) Recover(handler func(*Ctx)) {
|
||||
log.Println("Warning: Recover(handler) is deprecated since v1.8.2, please use middleware.Recover(handler, error) instead.")
|
||||
app.recover = handler
|
||||
}
|
||||
|
||||
// Listen : https://fiber.wiki/application#listen
|
||||
func (app *App) Listen(address interface{}, tls ...string) error {
|
||||
func (app *App) Listen(address interface{}, tlsconfig ...*tls.Config) error {
|
||||
addr, ok := address.(string)
|
||||
if !ok {
|
||||
port, ok := address.(int)
|
||||
@ -273,9 +244,9 @@ func (app *App) Listen(address interface{}, tls ...string) error {
|
||||
}
|
||||
}
|
||||
|
||||
// enable TLS/HTTPS
|
||||
if len(tls) > 1 {
|
||||
return app.server.ServeTLS(ln, tls[0], tls[1])
|
||||
// TLS config
|
||||
if len(tlsconfig) > 0 {
|
||||
ln = tls.NewListener(ln, tlsconfig[0])
|
||||
}
|
||||
return app.server.Serve(ln)
|
||||
}
|
||||
@ -387,26 +358,11 @@ func (dl *disableLogger) Printf(format string, args ...interface{}) {
|
||||
|
||||
func (app *App) newServer() *fasthttp.Server {
|
||||
return &fasthttp.Server{
|
||||
Handler: app.handler,
|
||||
Name: app.Settings.ServerHeader,
|
||||
// Concurrency: app.Settings.Concurrency,
|
||||
// SleepWhenConcurrencyLimitsExceeded: app.Settings.ConcurrencySleep,
|
||||
// DisableKeepalive: app.Settings.DisableKeepAlive,
|
||||
// ReadBufferSize: app.Settings.ReadBufferSize,
|
||||
// WriteBufferSize: app.Settings.WriteBufferSize,
|
||||
// ReadTimeout: app.Settings.ReadTimeout,
|
||||
// WriteTimeout: app.Settings.WriteTimeout,
|
||||
// IdleTimeout: app.Settings.IdleTimeout,
|
||||
// MaxConnsPerIP: app.Settings.MaxConnsPerIP,
|
||||
// MaxRequestsPerConn: app.Settings.MaxRequestsPerConn,
|
||||
// TCPKeepalive: app.Settings.TCPKeepalive,
|
||||
// TCPKeepalivePeriod: app.Settings.TCPKeepalivePeriod,
|
||||
MaxRequestBodySize: app.Settings.BodyLimit,
|
||||
// ReduceMemoryUsage: app.Settings.ReduceMemoryUsage,
|
||||
// GetOnly: app.Settings.GETOnly,
|
||||
// DisableHeaderNamesNormalizing: app.Settings.NoHeaderNormalizing,
|
||||
Handler: app.handler,
|
||||
Name: app.Settings.ServerHeader,
|
||||
MaxRequestBodySize: app.Settings.BodyLimit,
|
||||
NoDefaultServerHeader: app.Settings.ServerHeader == "",
|
||||
// NoDefaultContentType: app.Settings.NoDefaultContentType,
|
||||
|
||||
Logger: &disableLogger{},
|
||||
LogAllErrors: false,
|
||||
ErrorHandler: func(ctx *fasthttp.RequestCtx, err error) {
|
||||
|
@ -70,10 +70,9 @@ func Test_Static(t *testing.T) {
|
||||
app := New()
|
||||
grp := app.Group("/v1")
|
||||
grp.Static("/v2", ".travis.yml")
|
||||
app.Static("/yesyes*", ".github/FUNDING.yml")
|
||||
app.Static("./.github")
|
||||
app.Static("/*", ".github/FUNDING.yml")
|
||||
app.Static("/john", "./.github")
|
||||
req, _ := http.NewRequest("GET", "/stale.yml", nil)
|
||||
req, _ := http.NewRequest("GET", "/john/stale.yml", nil)
|
||||
resp, err := app.Test(req)
|
||||
if err != nil {
|
||||
t.Fatalf(`%s: %s`, t.Name(), err)
|
||||
|
68
context.go
68
context.go
@ -28,17 +28,19 @@ import (
|
||||
// It has methods for the request query string, parameters, body, HTTP headers and so on.
|
||||
// For more information please visit our documentation: https://fiber.wiki/context
|
||||
type Ctx struct {
|
||||
app *App
|
||||
route *Route
|
||||
next bool
|
||||
error error
|
||||
params *[]string
|
||||
values []string
|
||||
compress bool
|
||||
Fasthttp *fasthttp.RequestCtx
|
||||
app *App // Reference to *App
|
||||
route *Route // Reference to *Route
|
||||
index int // Index of the current stack
|
||||
matched bool // If the context found a match in stack
|
||||
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
|
||||
}
|
||||
|
||||
// Range info of range header
|
||||
// Range struct
|
||||
type Range struct {
|
||||
Type string
|
||||
Ranges []struct {
|
||||
@ -47,6 +49,17 @@ type Range struct {
|
||||
}
|
||||
}
|
||||
|
||||
// Cookie struct
|
||||
type Cookie struct {
|
||||
Name string
|
||||
Value string
|
||||
Path string
|
||||
Domain string
|
||||
Expires time.Time
|
||||
Secure bool
|
||||
HTTPOnly bool
|
||||
}
|
||||
|
||||
// Ctx pool
|
||||
var poolCtx = sync.Pool{
|
||||
New: func() interface{} {
|
||||
@ -55,20 +68,23 @@ var poolCtx = sync.Pool{
|
||||
}
|
||||
|
||||
// Acquire Ctx from pool
|
||||
func acquireCtx() *Ctx {
|
||||
func acquireCtx(fctx *fasthttp.RequestCtx) *Ctx {
|
||||
ctx := poolCtx.Get().(*Ctx)
|
||||
ctx.index = -1
|
||||
ctx.path = getString(fctx.URI().Path())
|
||||
ctx.method = getString(fctx.Request.Header.Method())
|
||||
ctx.Fasthttp = fctx
|
||||
return ctx
|
||||
}
|
||||
|
||||
// Return Ctx to pool
|
||||
func releaseCtx(ctx *Ctx) {
|
||||
ctx.route = nil
|
||||
ctx.next = false
|
||||
ctx.error = nil
|
||||
ctx.params = nil
|
||||
ctx.values = nil
|
||||
ctx.compress = false
|
||||
ctx.matched = false
|
||||
ctx.Fasthttp = nil
|
||||
ctx.err = nil
|
||||
poolCtx.Put(ctx)
|
||||
}
|
||||
|
||||
@ -97,17 +113,6 @@ func releaseConn(conn *Conn) {
|
||||
poolConn.Put(conn)
|
||||
}
|
||||
|
||||
// Cookie : struct
|
||||
type Cookie struct {
|
||||
Name string
|
||||
Value string
|
||||
Path string
|
||||
Domain string
|
||||
Expires time.Time
|
||||
Secure bool
|
||||
HTTPOnly bool
|
||||
}
|
||||
|
||||
// Accepts : https://fiber.wiki/context#accepts
|
||||
func (ctx *Ctx) Accepts(offers ...string) (offer string) {
|
||||
if len(offers) == 0 {
|
||||
@ -358,7 +363,7 @@ func (ctx *Ctx) Download(file string, name ...string) {
|
||||
|
||||
// Error returns err that is passed via Next(err)
|
||||
func (ctx *Ctx) Error() error {
|
||||
return ctx.error
|
||||
return ctx.err
|
||||
}
|
||||
|
||||
// Format : https://fiber.wiki/context#format
|
||||
@ -522,12 +527,11 @@ func (ctx *Ctx) MultipartForm() (*multipart.Form, error) {
|
||||
// Next : https://fiber.wiki/context#next
|
||||
func (ctx *Ctx) Next(err ...error) {
|
||||
ctx.route = nil
|
||||
ctx.next = true
|
||||
ctx.params = nil
|
||||
ctx.values = nil
|
||||
if len(err) > 0 {
|
||||
ctx.error = err[0]
|
||||
ctx.err = err[0]
|
||||
}
|
||||
ctx.app.nextRoute(ctx)
|
||||
}
|
||||
|
||||
// OriginalURL : https://fiber.wiki/context#originalurl
|
||||
@ -537,11 +541,11 @@ func (ctx *Ctx) OriginalURL() string {
|
||||
|
||||
// Params : https://fiber.wiki/context#params
|
||||
func (ctx *Ctx) Params(key string) (value string) {
|
||||
if ctx.params == nil {
|
||||
if ctx.route.Params == nil {
|
||||
return
|
||||
}
|
||||
for i := 0; i < len(*ctx.params); i++ {
|
||||
if (*ctx.params)[i] == key {
|
||||
for i := 0; i < len(ctx.route.Params); i++ {
|
||||
if (ctx.route.Params)[i] == key {
|
||||
return ctx.values[i]
|
||||
}
|
||||
}
|
||||
@ -725,7 +729,7 @@ func (ctx *Ctx) SendStatus(status int) {
|
||||
ctx.Fasthttp.Response.SetStatusCode(status)
|
||||
// Only set status body when there is no response body
|
||||
if len(ctx.Fasthttp.Response.Body()) == 0 {
|
||||
ctx.Fasthttp.Response.SetBodyString(getStatus(status))
|
||||
ctx.Fasthttp.Response.SetBodyString(statusMessages[status])
|
||||
}
|
||||
}
|
||||
|
||||
|
61
group.go
61
group.go
@ -8,7 +8,6 @@ import (
|
||||
"log"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Group ...
|
||||
@ -19,19 +18,9 @@ type Group struct {
|
||||
|
||||
// Group : https://fiber.wiki/application#group
|
||||
func (grp *Group) Group(prefix string, handlers ...func(*Ctx)) *Group {
|
||||
if len(prefix) > 0 && prefix[0] != '/' && prefix[0] != '*' {
|
||||
prefix = "/" + prefix
|
||||
}
|
||||
// When grouping, always remove single slash
|
||||
if len(grp.prefix) > 0 && prefix == "/" {
|
||||
prefix = ""
|
||||
}
|
||||
// Prepent group prefix if exist
|
||||
prefix = grp.prefix + prefix
|
||||
// Clean path by removing double "//" => "/"
|
||||
prefix = strings.Replace(prefix, "//", "/", -1)
|
||||
prefix = groupPaths(grp.prefix, prefix)
|
||||
if len(handlers) > 0 {
|
||||
grp.app.registerMethod("USE", prefix, "", handlers...)
|
||||
grp.app.registerMethod("USE", prefix, handlers...)
|
||||
}
|
||||
return &Group{
|
||||
prefix: prefix,
|
||||
@ -40,8 +29,9 @@ func (grp *Group) Group(prefix string, handlers ...func(*Ctx)) *Group {
|
||||
}
|
||||
|
||||
// Static : https://fiber.wiki/application#static
|
||||
func (grp *Group) Static(args ...string) *Group {
|
||||
grp.app.registerStatic(grp.prefix, args...)
|
||||
func (grp *Group) Static(prefix, root string) *Group {
|
||||
prefix = groupPaths(grp.prefix, prefix)
|
||||
grp.app.registerStatic(prefix, root)
|
||||
return grp
|
||||
}
|
||||
|
||||
@ -56,80 +46,93 @@ func (grp *Group) Use(args ...interface{}) *Group {
|
||||
case func(*Ctx):
|
||||
handlers = append(handlers, arg)
|
||||
default:
|
||||
log.Fatalf("Invalid handlerrrr: %v", reflect.TypeOf(arg))
|
||||
log.Fatalf("Invalid handler: %v", reflect.TypeOf(arg))
|
||||
}
|
||||
}
|
||||
grp.app.registerMethod("USE", grp.prefix, path, handlers...)
|
||||
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 {
|
||||
grp.app.registerMethod(http.MethodConnect, grp.prefix, path, handlers...)
|
||||
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 {
|
||||
grp.app.registerMethod(http.MethodPut, grp.prefix, path, handlers...)
|
||||
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 {
|
||||
grp.app.registerMethod(http.MethodPost, grp.prefix, path, handlers...)
|
||||
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 {
|
||||
grp.app.registerMethod(http.MethodDelete, grp.prefix, path, handlers...)
|
||||
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 {
|
||||
grp.app.registerMethod(http.MethodHead, grp.prefix, path, handlers...)
|
||||
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 {
|
||||
grp.app.registerMethod(http.MethodPatch, grp.prefix, path, handlers...)
|
||||
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 {
|
||||
grp.app.registerMethod(http.MethodOptions, grp.prefix, path, handlers...)
|
||||
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 {
|
||||
grp.app.registerMethod(http.MethodTrace, grp.prefix, path, handlers...)
|
||||
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 {
|
||||
grp.app.registerMethod(http.MethodGet, grp.prefix, path, handlers...)
|
||||
path = groupPaths(grp.prefix, path)
|
||||
grp.app.registerMethod(http.MethodGet, path, handlers...)
|
||||
return grp
|
||||
}
|
||||
|
||||
// All : https://fiber.wiki/application#http-methods
|
||||
func (grp *Group) All(path string, handlers ...func(*Ctx)) *Group {
|
||||
grp.app.registerMethod("ALL", grp.prefix, path, handlers...)
|
||||
path = groupPaths(grp.prefix, path)
|
||||
grp.app.registerMethod("ALL", path, handlers...)
|
||||
return grp
|
||||
}
|
||||
|
||||
// WebSocket : https://fiber.wiki/application#websocket
|
||||
func (grp *Group) WebSocket(path string, handler func(*Conn)) *Group {
|
||||
grp.app.registerWebSocket(http.MethodGet, grp.prefix, path, handler)
|
||||
func (grp *Group) WebSocket(path string, handle func(*Conn)) *Group {
|
||||
path = groupPaths(grp.prefix, path)
|
||||
grp.app.registerWebSocket(http.MethodGet, path, handle)
|
||||
return grp
|
||||
}
|
||||
|
||||
// Recover : https://fiber.wiki/application#recover
|
||||
func (grp *Group) Recover(handler func(*Ctx)) {
|
||||
log.Println("Warning: Recover(handler) is deprecated since v1.8.2, please use middleware.Recover(handler, error) instead.")
|
||||
grp.app.recover = handler
|
||||
}
|
||||
|
@ -49,8 +49,8 @@ var HelmetConfigDefault = HelmetConfig{
|
||||
XFrameOptions: "SAMEORIGIN",
|
||||
}
|
||||
|
||||
// Secure ...
|
||||
func Secure(config ...HelmetConfig) func(*fiber.Ctx) {
|
||||
// Helmet ...
|
||||
func Helmet(config ...HelmetConfig) func(*fiber.Ctx) {
|
||||
// Init config
|
||||
var cfg HelmetConfig
|
||||
if len(config) > 0 {
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
@ -34,7 +35,7 @@ type LoggerConfig struct {
|
||||
// LoggerConfigDefault is the defaul Logger middleware config.
|
||||
var LoggerConfigDefault = LoggerConfig{
|
||||
Skip: nil,
|
||||
Format: "${time} - ${ip} - ${method} ${path}\t${ua}\n",
|
||||
Format: "${time} ${method} ${path} - ${ip} - ${status} - ${latency}ms\n",
|
||||
TimeFormat: "15:04:05",
|
||||
Output: os.Stderr,
|
||||
}
|
||||
@ -81,6 +82,11 @@ func Logger(config ...LoggerConfig) func(*fiber.Ctx) {
|
||||
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)
|
||||
@ -104,6 +110,10 @@ func Logger(config ...LoggerConfig) func(*fiber.Ctx) {
|
||||
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:"):
|
||||
@ -124,6 +134,5 @@ func Logger(config ...LoggerConfig) func(*fiber.Ctx) {
|
||||
if _, err := cfg.Output.Write(buf.Bytes()); err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
33
middleware/recover.go
Normal file
33
middleware/recover.go
Normal file
@ -0,0 +1,33 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/gofiber/fiber"
|
||||
)
|
||||
|
||||
// Recover ...
|
||||
func Recover(handle ...func(*fiber.Ctx, error)) func(*fiber.Ctx) {
|
||||
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()
|
||||
}
|
||||
}
|
682
router.go
682
router.go
@ -5,8 +5,8 @@
|
||||
package fiber
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
@ -17,403 +17,311 @@ import (
|
||||
|
||||
// Route struct
|
||||
type Route struct {
|
||||
// HTTP method in uppercase, can be a * for "Use" & "All" routes
|
||||
Method string
|
||||
// Stores the original path
|
||||
Path string
|
||||
// Prefix is for ending wildcards or middleware
|
||||
Prefix string
|
||||
// Stores regex for complex paths
|
||||
Regex *regexp.Regexp
|
||||
// Stores params keys for :params / :optional? / *
|
||||
Params []string
|
||||
// Handler for context
|
||||
HandlerCtx func(*Ctx)
|
||||
// Handler for websockets
|
||||
HandlerConn func(*Conn)
|
||||
isMiddleware bool // is middleware route
|
||||
isWebSocket bool // is websocket route
|
||||
|
||||
isStar bool // path == '*'
|
||||
isSlash bool // path == '/'
|
||||
isRegex bool // needs regex parsing
|
||||
|
||||
Method string // http method
|
||||
Path string // orginal path
|
||||
Params []string // path params
|
||||
Regexp *regexp.Regexp // regexp matcher
|
||||
|
||||
HandleCtx func(*Ctx) // ctx handler
|
||||
HandleConn func(*Conn) // conn handler
|
||||
|
||||
}
|
||||
|
||||
func (app *App) registerStatic(grpPrefix string, args ...string) {
|
||||
var prefix = "/"
|
||||
var root = "./"
|
||||
// enable / disable gzipping somewhere?
|
||||
// todo v2.0.0
|
||||
gzip := true
|
||||
|
||||
if len(args) == 1 {
|
||||
root = args[0]
|
||||
}
|
||||
if len(args) == 2 {
|
||||
prefix = args[0]
|
||||
root = args[1]
|
||||
}
|
||||
|
||||
// A non wildcard path must start with a '/'
|
||||
if prefix != "*" && len(prefix) > 0 && prefix[0] != '/' {
|
||||
prefix = "/" + prefix
|
||||
}
|
||||
// Prepend group prefix
|
||||
if len(grpPrefix) > 0 {
|
||||
// `/v1`+`/` => `/v1`+``
|
||||
if prefix == "/" {
|
||||
prefix = grpPrefix
|
||||
} else {
|
||||
prefix = grpPrefix + prefix
|
||||
}
|
||||
// Remove duplicate slashes `//`
|
||||
prefix = strings.Replace(prefix, "//", "/", -1)
|
||||
}
|
||||
// Empty or '/*' path equals "match anything"
|
||||
// TODO fix * for paths with grpprefix
|
||||
if prefix == "/*" {
|
||||
prefix = "*"
|
||||
}
|
||||
// Lets get all files from root
|
||||
files, _, err := getFiles(root)
|
||||
if err != nil {
|
||||
log.Fatal("Static: ", err)
|
||||
}
|
||||
// ./static/compiled => static/compiled
|
||||
mount := filepath.Clean(root)
|
||||
|
||||
if !app.Settings.CaseSensitive {
|
||||
prefix = strings.ToLower(prefix)
|
||||
}
|
||||
if !app.Settings.StrictRouting && len(prefix) > 1 {
|
||||
prefix = strings.TrimRight(prefix, "/")
|
||||
}
|
||||
|
||||
// Loop over all files
|
||||
for _, file := range files {
|
||||
// Ignore the .gzipped files by fasthttp
|
||||
if strings.Contains(file, ".fasthttp.gz") {
|
||||
continue
|
||||
}
|
||||
// Time to create a fake path for the route match
|
||||
// static/index.html => /index.html
|
||||
path := filepath.Join(prefix, strings.Replace(file, mount, "", 1))
|
||||
// for windows: static\index.html => /index.html
|
||||
path = filepath.ToSlash(path)
|
||||
// Store file path to use in ctx handler
|
||||
filePath := file
|
||||
|
||||
if len(prefix) > 1 && strings.Contains(prefix, "*") {
|
||||
app.routes = append(app.routes, &Route{
|
||||
Method: "GET",
|
||||
Path: path,
|
||||
Prefix: strings.Split(prefix, "*")[0],
|
||||
HandlerCtx: func(c *Ctx) {
|
||||
c.SendFile(filePath, gzip)
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
// If the file is an index.html, bind the prefix to index.html directly
|
||||
if filepath.Base(filePath) == "index.html" || filepath.Base(filePath) == "index.htm" {
|
||||
app.routes = append(app.routes, &Route{
|
||||
Method: "GET",
|
||||
Path: prefix,
|
||||
HandlerCtx: func(c *Ctx) {
|
||||
c.SendFile(filePath, gzip)
|
||||
},
|
||||
})
|
||||
}
|
||||
if !app.Settings.CaseSensitive {
|
||||
path = strings.ToLower(path)
|
||||
}
|
||||
if !app.Settings.StrictRouting && len(prefix) > 1 {
|
||||
path = strings.TrimRight(path, "/")
|
||||
}
|
||||
// Add the route + SendFile(filepath) to routes
|
||||
app.routes = append(app.routes, &Route{
|
||||
Method: "GET",
|
||||
Path: path,
|
||||
HandlerCtx: func(c *Ctx) {
|
||||
c.SendFile(filePath, gzip)
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
func (app *App) registerWebSocket(method, group, path string, handler func(*Conn)) {
|
||||
if len(path) > 0 && path[0] != '/' {
|
||||
path = "/" + path
|
||||
}
|
||||
if len(group) > 0 {
|
||||
// `/v1`+`/` => `/v1`+``
|
||||
if path == "/" {
|
||||
path = group
|
||||
} else {
|
||||
path = group + path
|
||||
}
|
||||
// Remove duplicate slashes `//`
|
||||
path = strings.Replace(path, "//", "/", -1)
|
||||
}
|
||||
// Routes are case insensitive by default
|
||||
if !app.Settings.CaseSensitive {
|
||||
path = strings.ToLower(path)
|
||||
}
|
||||
if !app.Settings.StrictRouting && len(path) > 1 {
|
||||
path = strings.TrimRight(path, "/")
|
||||
}
|
||||
// Get ':param' & ':optional?' & '*' from path
|
||||
params := getParams(path)
|
||||
if len(params) > 0 {
|
||||
log.Fatal("WebSocket routes do not support path parameters: `:param, :optional?, *`")
|
||||
}
|
||||
app.routes = append(app.routes, &Route{
|
||||
Method: method, Path: path, HandlerConn: handler,
|
||||
})
|
||||
}
|
||||
func (app *App) registerMethod(method, group, path string, handlers ...func(*Ctx)) {
|
||||
// No special paths for websockets
|
||||
if len(handlers) == 0 {
|
||||
log.Fatalf("Missing handler in route")
|
||||
}
|
||||
// Set variables
|
||||
var prefix string
|
||||
var middleware = method == "USE"
|
||||
// A non wildcard path must start with a '/'
|
||||
if path != "*" && len(path) > 0 && path[0] != '/' {
|
||||
path = "/" + path
|
||||
}
|
||||
// Prepend group prefix
|
||||
if len(group) > 0 {
|
||||
// `/v1`+`/` => `/v1`+``
|
||||
if path == "/" {
|
||||
path = group
|
||||
} else {
|
||||
path = group + path
|
||||
}
|
||||
// Remove duplicate slashes `//`
|
||||
path = strings.Replace(path, "//", "/", -1)
|
||||
}
|
||||
// Empty or '/*' path equals "match anything"
|
||||
// TODO fix * for paths with grpprefix
|
||||
if path == "/*" || (middleware && path == "") {
|
||||
path = "*"
|
||||
}
|
||||
if method == "ALL" || middleware {
|
||||
method = "*"
|
||||
}
|
||||
// Routes are case insensitive by default
|
||||
if !app.Settings.CaseSensitive {
|
||||
path = strings.ToLower(path)
|
||||
}
|
||||
if !app.Settings.StrictRouting && len(path) > 1 {
|
||||
path = strings.TrimRight(path, "/")
|
||||
}
|
||||
// If the route can match anything
|
||||
if path == "*" {
|
||||
for i := range handlers {
|
||||
app.routes = append(app.routes, &Route{
|
||||
Method: method, Path: path, HandlerCtx: handlers[i],
|
||||
})
|
||||
}
|
||||
return
|
||||
}
|
||||
// Get ':param' & ':optional?' & '*' from path
|
||||
params := getParams(path)
|
||||
// Enable prefix for midware
|
||||
if len(params) == 0 && middleware {
|
||||
prefix = path
|
||||
}
|
||||
|
||||
// If path has no params (simple path)
|
||||
if len(params) == 0 {
|
||||
for i := range handlers {
|
||||
app.routes = append(app.routes, &Route{
|
||||
Method: method, Path: path, Prefix: prefix, HandlerCtx: handlers[i],
|
||||
})
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// If path only contains 1 wildcard, we can create a prefix
|
||||
// If its a middleware, we also create a prefix
|
||||
if len(params) == 1 && params[0] == "*" {
|
||||
prefix = strings.Split(path, "*")[0]
|
||||
for i := range handlers {
|
||||
app.routes = append(app.routes, &Route{
|
||||
Method: method, Path: path, Prefix: prefix,
|
||||
Params: params, HandlerCtx: handlers[i],
|
||||
})
|
||||
}
|
||||
return
|
||||
}
|
||||
// We have an :param or :optional? and need to compile a regex struct
|
||||
regex, err := getRegex(path)
|
||||
if err != nil {
|
||||
log.Fatal("Router: Invalid path pattern: " + path)
|
||||
}
|
||||
// Add route with regex
|
||||
for i := range handlers {
|
||||
app.routes = append(app.routes, &Route{
|
||||
Method: method, Path: path, Regex: regex,
|
||||
Params: params, HandlerCtx: handlers[i],
|
||||
})
|
||||
}
|
||||
}
|
||||
func (app *App) handler(fctx *fasthttp.RequestCtx) {
|
||||
// Use this boolean to perform 404 not found at the end
|
||||
var match = false
|
||||
// get custom context from sync pool
|
||||
ctx := acquireCtx()
|
||||
defer releaseCtx(ctx)
|
||||
ctx.app = app
|
||||
ctx.compress = app.Settings.Compression
|
||||
ctx.Fasthttp = fctx
|
||||
// get path and method
|
||||
path := ctx.Path()
|
||||
if !app.Settings.CaseSensitive {
|
||||
path = strings.ToLower(path)
|
||||
}
|
||||
if !app.Settings.StrictRouting && len(path) > 1 {
|
||||
path = strings.TrimRight(path, "/")
|
||||
}
|
||||
method := ctx.Method()
|
||||
// enable recovery
|
||||
if app.recover != nil {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
err, ok := r.(error)
|
||||
if !ok {
|
||||
err = fmt.Errorf("%v", r)
|
||||
}
|
||||
ctx.error = err
|
||||
app.recover(ctx)
|
||||
func (app *App) nextRoute(ctx *Ctx) {
|
||||
lenr := len(app.routes) - 1
|
||||
for ctx.index < lenr {
|
||||
ctx.index++
|
||||
route := app.routes[ctx.index]
|
||||
match, values := route.matchRoute(ctx.method, ctx.path)
|
||||
if match {
|
||||
ctx.route = route
|
||||
if !ctx.matched {
|
||||
ctx.matched = true
|
||||
}
|
||||
}()
|
||||
}
|
||||
// loop trough routes
|
||||
for _, route := range app.routes {
|
||||
// Skip route if method does not match
|
||||
if route.Method != "*" && route.Method != method {
|
||||
continue
|
||||
}
|
||||
// Set route pointer if user wants to call .Route()
|
||||
ctx.route = route
|
||||
// wilcard or exact same path
|
||||
// TODO v2: enable or disable case insensitive match
|
||||
if route.Path == "*" || route.Path == path {
|
||||
// if * always set the path to the wildcard parameter
|
||||
if route.Path == "*" {
|
||||
ctx.params = &[]string{"*"}
|
||||
ctx.values = []string{path}
|
||||
if len(values) > 0 {
|
||||
ctx.values = values
|
||||
}
|
||||
// ctx.Fasthttp.Request.Header.ConnectionUpgrade()
|
||||
// Websocket request
|
||||
if route.HandlerConn != nil && websocket.FastHTTPIsWebSocketUpgrade(fctx) {
|
||||
// Try to upgrade
|
||||
err := socketUpgrade.Upgrade(ctx.Fasthttp, func(fconn *websocket.Conn) {
|
||||
if route.isWebSocket {
|
||||
if err := websocketUpgrader.Upgrade(ctx.Fasthttp, func(fconn *websocket.Conn) {
|
||||
conn := acquireConn(fconn)
|
||||
defer releaseConn(conn)
|
||||
route.HandlerConn(conn)
|
||||
})
|
||||
// Upgrading failed
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to upgrade websocket connection")
|
||||
route.HandleConn(conn)
|
||||
}); err != nil { // Upgrading failed
|
||||
ctx.SendStatus(400)
|
||||
}
|
||||
return
|
||||
}
|
||||
// No handler for HTTP nor websocket
|
||||
if route.HandlerCtx == nil {
|
||||
continue
|
||||
}
|
||||
// Match found, 404 not needed
|
||||
match = true
|
||||
route.HandlerCtx(ctx)
|
||||
// if next is not set, leave loop and release ctx
|
||||
if !ctx.next {
|
||||
break
|
||||
} else {
|
||||
// reset match to false
|
||||
match = false
|
||||
route.HandleCtx(ctx)
|
||||
}
|
||||
// set next to false for next iteration
|
||||
ctx.next = false
|
||||
// continue to go to the next route
|
||||
continue
|
||||
return
|
||||
}
|
||||
if route.Prefix != "" && strings.HasPrefix(path, route.Prefix) {
|
||||
ctx.route = route
|
||||
if strings.Contains(route.Path, "*") {
|
||||
ctx.params = &[]string{"*"}
|
||||
// ctx.values = matches[0][1:len(matches[0])]
|
||||
// parse query source
|
||||
ctx.values = []string{strings.Replace(path, route.Prefix, "", 1)}
|
||||
}
|
||||
// No handler for HTTP nor websocket
|
||||
if route.HandlerCtx == nil {
|
||||
continue
|
||||
}
|
||||
// Match found, 404 not needed
|
||||
match = true
|
||||
route.HandlerCtx(ctx)
|
||||
// if next is not set, leave loop and release ctx
|
||||
if !ctx.next {
|
||||
break
|
||||
} else {
|
||||
// reset match to false
|
||||
match = false
|
||||
}
|
||||
// set next to false for next iteration
|
||||
ctx.next = false
|
||||
// continue to go to the next route
|
||||
continue
|
||||
}
|
||||
|
||||
// Skip route if regex does not exist
|
||||
if route.Regex == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// Skip route if regex does not match
|
||||
if !route.Regex.MatchString(path) {
|
||||
continue
|
||||
}
|
||||
|
||||
// If we have parameters, lets find the matches
|
||||
if len(route.Params) > 0 {
|
||||
matches := route.Regex.FindAllStringSubmatch(path, -1)
|
||||
// If we have matches, add params and values to context
|
||||
if len(matches) > 0 && len(matches[0]) > 1 {
|
||||
ctx.params = &route.Params
|
||||
ctx.values = matches[0][1:len(matches[0])]
|
||||
}
|
||||
}
|
||||
// No handler for HTTP nor websocket
|
||||
if route.HandlerCtx == nil {
|
||||
continue
|
||||
}
|
||||
// Match found, 404 not needed
|
||||
match = true
|
||||
route.HandlerCtx(ctx)
|
||||
// if next is not set, leave loop and release ctx
|
||||
if !ctx.next {
|
||||
break
|
||||
} else {
|
||||
// reset match to false
|
||||
match = false
|
||||
}
|
||||
// set next to false for next iteration
|
||||
ctx.next = false
|
||||
}
|
||||
// Do we need to compress?
|
||||
if ctx.compress {
|
||||
compressDefaultCompression(fctx)
|
||||
// switch app.Settings.CompressionLevel {
|
||||
// case 2:
|
||||
// compressBestSpeed(fctx)
|
||||
// case 3:
|
||||
// compressBestCompression(fctx)
|
||||
// case 4:
|
||||
// compressHuffmanOnly(fctx)
|
||||
// default: // 1
|
||||
// compressDefaultCompression(fctx)
|
||||
// }
|
||||
}
|
||||
// No match, send default 404 Not Found
|
||||
if !match {
|
||||
if !ctx.matched {
|
||||
ctx.SendStatus(404)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Route) matchRoute(method, path string) (match bool, values []string) {
|
||||
// is route middleware? matches all http methods
|
||||
if r.isMiddleware {
|
||||
// '*' or '/' means its a valid match
|
||||
if r.isStar || r.isSlash {
|
||||
return true, nil
|
||||
}
|
||||
// if midware path starts with req.path
|
||||
if strings.HasPrefix(path, r.Path) {
|
||||
return true, nil
|
||||
}
|
||||
// middlewares dont support regex so bye!
|
||||
return false, nil
|
||||
}
|
||||
// non-middleware route, http method must match!
|
||||
// the wildcard method is for .All() method
|
||||
if r.Method != method && r.Method[0] != '*' {
|
||||
return false, nil
|
||||
}
|
||||
// '*' means we match anything
|
||||
if r.isStar {
|
||||
return true, nil
|
||||
}
|
||||
// simple '/' bool, so you avoid unnecessary comparison for long paths
|
||||
if r.isSlash && path == "/" {
|
||||
return true, nil
|
||||
}
|
||||
// does this route need regex matching?
|
||||
if r.isRegex {
|
||||
// req.path match regex pattern
|
||||
if r.Regexp.MatchString(path) {
|
||||
// do we have parameters
|
||||
if len(r.Params) > 0 {
|
||||
// get values for parameters
|
||||
matches := r.Regexp.FindAllStringSubmatch(path, -1)
|
||||
// did we get the values?
|
||||
if len(matches) > 0 && len(matches[0]) > 1 {
|
||||
values = matches[0][1:len(matches[0])]
|
||||
return true, values
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
// last thing to do is to check for a simple path match
|
||||
if r.Path == path {
|
||||
return true, nil
|
||||
}
|
||||
// Nothing match
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (app *App) handler(fctx *fasthttp.RequestCtx) {
|
||||
// get fiber context from sync pool
|
||||
ctx := acquireCtx(fctx)
|
||||
defer releaseCtx(ctx)
|
||||
|
||||
// attach app poiner and compress settings
|
||||
ctx.app = app
|
||||
ctx.compress = app.Settings.Compression
|
||||
|
||||
// Case sensitive routing
|
||||
if !app.Settings.CaseSensitive {
|
||||
ctx.path = strings.ToLower(ctx.path)
|
||||
}
|
||||
// Strict routing
|
||||
if !app.Settings.StrictRouting && len(ctx.path) > 1 {
|
||||
ctx.path = strings.TrimRight(ctx.path, "/")
|
||||
}
|
||||
|
||||
app.nextRoute(ctx)
|
||||
|
||||
if ctx.compress {
|
||||
compressResponse(fctx)
|
||||
}
|
||||
}
|
||||
|
||||
func (app *App) registerMethod(method, path string, handlers ...func(*Ctx)) {
|
||||
// Route requires atleast one handler
|
||||
if len(handlers) == 0 {
|
||||
log.Fatalf("Missing handler in route")
|
||||
}
|
||||
// Cannot have an empty path
|
||||
if path == "" {
|
||||
path = "/"
|
||||
}
|
||||
// Path always start with a '/' or '*'
|
||||
if path[0] != '/' && path[0] != '*' {
|
||||
path = "/" + 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, "/")
|
||||
}
|
||||
|
||||
// Set route booleans
|
||||
var isMiddleware = method == "USE"
|
||||
// Middleware / All allows all HTTP methods
|
||||
if isMiddleware || method == "ALL" {
|
||||
method = "*"
|
||||
}
|
||||
var isStar = path == "*" || path == "/*"
|
||||
// Middleware containing only a `/` equals wildcard
|
||||
if isMiddleware && path == "/" {
|
||||
isStar = true
|
||||
}
|
||||
var isSlash = path == "/"
|
||||
var isRegex = false
|
||||
// Route properties
|
||||
var Params = getParams(path)
|
||||
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
|
||||
}
|
||||
for i := range handlers {
|
||||
app.routes = append(app.routes, &Route{
|
||||
isMiddleware: isMiddleware,
|
||||
isStar: isStar,
|
||||
isSlash: isSlash,
|
||||
isRegex: isRegex,
|
||||
Method: method,
|
||||
Path: path,
|
||||
Params: Params,
|
||||
Regexp: Regexp,
|
||||
HandleCtx: handlers[i],
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (app *App) registerWebSocket(method, path string, handle func(*Conn)) {
|
||||
// Cannot have an empty path
|
||||
if path == "" {
|
||||
path = "/"
|
||||
}
|
||||
// Path always start with a '/' or '*'
|
||||
if path[0] != '/' && path[0] != '*' {
|
||||
path = "/" + 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(path)
|
||||
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,
|
||||
HandleConn: handle,
|
||||
})
|
||||
}
|
||||
|
||||
func (app *App) registerStatic(prefix, root string) {
|
||||
// Cannot have an empty prefix
|
||||
if prefix == "" {
|
||||
prefix = "/"
|
||||
}
|
||||
// prefix always start with a '/' or '*'
|
||||
if prefix[0] != '/' && prefix[0] != '*' {
|
||||
prefix = "/" + prefix
|
||||
}
|
||||
// Case sensitive routing, all to lowercase
|
||||
if !app.Settings.CaseSensitive {
|
||||
prefix = strings.ToLower(prefix)
|
||||
}
|
||||
|
||||
var isStar = prefix == "*" || prefix == "/*"
|
||||
|
||||
files := map[string]string{}
|
||||
// Clean root path
|
||||
root = filepath.Clean(root)
|
||||
// Check if root exist and is accessible
|
||||
if _, err := os.Stat(root); err != nil {
|
||||
log.Fatalf("%s", err)
|
||||
}
|
||||
// Store path url and file paths in map
|
||||
if err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
|
||||
if !info.IsDir() {
|
||||
url := "*"
|
||||
if !isStar {
|
||||
// /css/style.css: static/css/style.css
|
||||
url = filepath.Join(prefix, strings.Replace(path, root, "", 1))
|
||||
}
|
||||
// \static\css: /static/css
|
||||
url = filepath.ToSlash(url)
|
||||
files[url] = path
|
||||
if filepath.Base(path) == "index.html" {
|
||||
files[url] = path
|
||||
}
|
||||
}
|
||||
return err
|
||||
}); err != nil {
|
||||
log.Fatalf("%s", err)
|
||||
}
|
||||
compress := app.Settings.Compression
|
||||
app.routes = append(app.routes, &Route{
|
||||
isMiddleware: true,
|
||||
isStar: isStar,
|
||||
Method: "*",
|
||||
Path: prefix,
|
||||
HandleCtx: func(c *Ctx) {
|
||||
// Only allow GET & HEAD methods
|
||||
if c.method == "GET" || c.method == "HEAD" {
|
||||
path := "*"
|
||||
if !isStar {
|
||||
path = c.path
|
||||
}
|
||||
file := files[path]
|
||||
if file != "" {
|
||||
c.SendFile(file, compress)
|
||||
return
|
||||
}
|
||||
}
|
||||
c.matched = false
|
||||
c.Next()
|
||||
},
|
||||
})
|
||||
}
|
||||
|
27
utils.go
27
utils.go
@ -20,13 +20,9 @@ import (
|
||||
fasthttp "github.com/valyala/fasthttp"
|
||||
)
|
||||
|
||||
var compressDefaultCompression = fasthttp.CompressHandlerLevel(func(c *fasthttp.RequestCtx) {}, fasthttp.CompressDefaultCompression)
|
||||
|
||||
// var compressBestSpeed = fasthttp.CompressHandlerLevel(func(c *fasthttp.RequestCtx) {}, fasthttp.CompressBestSpeed)
|
||||
// var compressBestCompression = fasthttp.CompressHandlerLevel(func(c *fasthttp.RequestCtx) {}, fasthttp.CompressBestCompression)
|
||||
// var compressHuffmanOnly = fasthttp.CompressHandlerLevel(func(c *fasthttp.RequestCtx) {}, fasthttp.CompressHuffmanOnly)
|
||||
var schemaDecoder = schema.NewDecoder()
|
||||
var socketUpgrade = websocket.FastHTTPUpgrader{
|
||||
var compressResponse = fasthttp.CompressHandlerLevel(func(c *fasthttp.RequestCtx) {}, fasthttp.CompressDefaultCompression)
|
||||
var websocketUpgrader = websocket.FastHTTPUpgrader{
|
||||
ReadBufferSize: 1024,
|
||||
WriteBufferSize: 1024,
|
||||
CheckOrigin: func(fctx *fasthttp.RequestCtx) bool {
|
||||
@ -34,6 +30,15 @@ var socketUpgrade = websocket.FastHTTPUpgrader{
|
||||
},
|
||||
}
|
||||
|
||||
func groupPaths(prefix, path string) string {
|
||||
if path == "/" {
|
||||
path = ""
|
||||
}
|
||||
path = prefix + path
|
||||
path = strings.Replace(path, "//", "/", -1)
|
||||
return path
|
||||
}
|
||||
|
||||
func getParams(path string) (params []string) {
|
||||
if len(path) < 1 {
|
||||
return
|
||||
@ -108,10 +113,6 @@ func getType(ext string) (mime string) {
|
||||
return mime
|
||||
}
|
||||
|
||||
func getStatus(status int) (msg string) {
|
||||
return statusMessage[status]
|
||||
}
|
||||
|
||||
// #nosec G103
|
||||
// getString converts byte slice to a string without memory allocation.
|
||||
// See https://groups.google.com/forum/#!msg/Golang-Nuts/ENgbUzYvCuU/90yGx7GUAgAJ .
|
||||
@ -122,7 +123,7 @@ var getString = func(b []byte) string {
|
||||
// #nosec G103
|
||||
// getBytes converts string to a byte slice without memory allocation.
|
||||
// See https://groups.google.com/forum/#!msg/Golang-Nuts/ENgbUzYvCuU/90yGx7GUAgAJ .
|
||||
func getBytes(s string) (b []byte) {
|
||||
var getBytes = func(s string) (b []byte) {
|
||||
return *(*[]byte)(unsafe.Pointer(&s))
|
||||
}
|
||||
|
||||
@ -162,8 +163,8 @@ const (
|
||||
MIMEOctetStream = "application/octet-stream"
|
||||
)
|
||||
|
||||
// HTTP status codes
|
||||
var statusMessage = map[int]string{
|
||||
// HTTP status codes with messages
|
||||
var statusMessages = map[int]string{
|
||||
100: "Continue",
|
||||
101: "Switching Protocols",
|
||||
102: "Processing",
|
||||
|
Loading…
x
Reference in New Issue
Block a user