mirror of https://github.com/gofiber/fiber.git
Huge refactoring, Add dummy CORS middleware
parent
825f4936f7
commit
18e7fcfc35
36
README.md
36
README.md
|
@ -4,11 +4,11 @@
|
|||
|
||||
<img align="right" height="180px" src="docs/static/logo_320px_trans.png" alt="Fiber logo" />
|
||||
|
||||
**[Fiber](https://github.com/gofiber/fiber)** is an [Express](https://expressjs.com/en/4x/api.html)-styled HTTP web framework implementation running on [Fasthttp](https://github.com/valyala/fasthttp), the **fastest** HTTP engine for Go (Golang). The package make use of **similar framework convention** as they are in Express.
|
||||
**[Fiber](https://github.com/gofiber/fiber)** is an [Express](https://expressjs.com/en/4x/api.html)-styled HTTP web framework implementation running on [Fasthttp](https://github.com/valyala/fasthttp), the **fastest** HTTP engine for Go (Golang). The package make use of **similar framework convention** as they are in Express.
|
||||
|
||||
People switching from [Node.js](https://nodejs.org/en/about/) to [Go](https://golang.org/doc/) often end up in a bad learning curve to start building their webapps, this project is meant to **ease** things up for **fast** development, but with **zero memory allocation** and **performance** in mind.
|
||||
|
||||
**In other languages:** <a href="README_RU.md"><img width="20px" src="docs/static/ru.svg" alt="ru"/></a>
|
||||
**In other languages:** <a href="README_RU.md"><img width="20px" src="docs/static/flags/ru.svg" alt="ru"/></a>
|
||||
|
||||
## API Documentation
|
||||
|
||||
|
@ -22,13 +22,13 @@ People switching from [Node.js](https://nodejs.org/en/about/) to [Go](https://go
|
|||
|
||||
## Features
|
||||
|
||||
* Optimized for speed and low memory usage
|
||||
* Rapid Server-Side Programming
|
||||
* Easy routing with parameters
|
||||
* Static files with custom prefix
|
||||
* Middleware with Next support
|
||||
* Express API endpoints
|
||||
* [Extended documentation](https://gofiber.github.io/fiber/)
|
||||
- Optimized for speed and low memory usage
|
||||
- Rapid Server-Side Programming
|
||||
- Easy routing with parameters
|
||||
- Static files with custom prefix
|
||||
- Middleware with Next support
|
||||
- Express API endpoints
|
||||
- [Extended documentation](https://gofiber.github.io/fiber/)
|
||||
|
||||
## Installing
|
||||
|
||||
|
@ -37,7 +37,7 @@ Assuming you’ve already installed Go `1.11+` 😉
|
|||
Install the [Fiber](https://github.com/gofiber/fiber) package by calling the following command:
|
||||
|
||||
```console
|
||||
$ go get -u github.com/gofiber/fiber
|
||||
go get -u github.com/gofiber/fiber
|
||||
```
|
||||
|
||||
## Hello, world!
|
||||
|
@ -59,7 +59,7 @@ func main() {
|
|||
app.Get("/", func(c *fiber.Ctx) {
|
||||
c.Send("Hello, World!")
|
||||
})
|
||||
|
||||
|
||||
// Start server on http://localhost:8080
|
||||
app.Listen(8080)
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ func main() {
|
|||
Go to console and run:
|
||||
|
||||
```console
|
||||
$ go run server.go
|
||||
go run server.go
|
||||
```
|
||||
|
||||
And now, browse to `http://localhost:8080` and you should see `Hello, World!` on the page! 🎉
|
||||
|
@ -85,10 +85,10 @@ import "github.com/gofiber/fiber"
|
|||
func main() {
|
||||
// Create new Fiber instance
|
||||
app := fiber.New()
|
||||
|
||||
|
||||
// Serve all static files on ./public folder
|
||||
app.Static("./public")
|
||||
|
||||
|
||||
// Start server on http://localhost:8080
|
||||
app.Listen(8080)
|
||||
}
|
||||
|
@ -116,21 +116,21 @@ func main() {
|
|||
app := fiber.New()
|
||||
|
||||
// Define all used middlewares in Use()
|
||||
|
||||
|
||||
app.Use(func(c *fiber.Ctx) {
|
||||
c.Write("Match anything!\n")
|
||||
c.Next()
|
||||
})
|
||||
|
||||
|
||||
app.Use("/api", func(c *fiber.Ctx) {
|
||||
c.Write("Match starting with /api\n")
|
||||
c.Next()
|
||||
})
|
||||
|
||||
|
||||
app.Get("/api/user", func(c *fiber.Ctx) {
|
||||
c.Write("Match exact path /api/user\n")
|
||||
})
|
||||
|
||||
|
||||
// Start server on http://localhost:8080
|
||||
app.Listen(8080)
|
||||
}
|
||||
|
|
40
README_RU.md
40
README_RU.md
|
@ -4,11 +4,11 @@
|
|||
|
||||
<img align="right" height="180px" src="docs/static/logo_320px_trans.png" alt="Fiber logo" />
|
||||
|
||||
**[Fiber](https://github.com/gofiber/fiber)** — это [Express](https://expressjs.com/en/4x/api.html)-подобный HTTP веб фреймворк, использующий всю мощь [Fasthttp](https://github.com/valyala/fasthttp), самого **быстрого** HTTP движка для Go (Golang). Мы используем **аналогичную** схему именования методов, как и у Express.
|
||||
**[Fiber](https://github.com/gofiber/fiber)** — это [Express](https://expressjs.com/en/4x/api.html)-подобный HTTP веб фреймворк, использующий всю мощь [Fasthttp](https://github.com/valyala/fasthttp), самого **быстрого** HTTP движка для Go (Golang). Мы используем **аналогичную** схему именования методов, как и у Express.
|
||||
|
||||
Разработчики, пришедшие из [Node.js](https://nodejs.org/en/about/) в [Go](https://golang.org/doc/) очень часто испытывают трудности при созданиии своих первых веб-приложений. Данный проект призван, в том числе, **облегчить** процесс перехода для таких разработчиков.
|
||||
Разработчики, пришедшие из [Node.js](https://nodejs.org/en/about/) в [Go](https://golang.org/doc/) очень часто испытывают трудности при создании своих первых веб-приложений. Данный проект призван, в том числе, **облегчить** процесс перехода для таких разработчиков.
|
||||
|
||||
**На других языках:** <a href="README.md"><img width="20px" src="docs/static/en.svg" alt="en"/></a>
|
||||
**На других языках:** <a href="README.md"><img width="20px" src="docs/static/flags/en.svg" alt="en"/></a>
|
||||
|
||||
## Документация по API
|
||||
|
||||
|
@ -22,13 +22,13 @@
|
|||
|
||||
## Особенности
|
||||
|
||||
* Оптимизирован для скорости и низкого использования памяти
|
||||
* Быстрое Server-Side программирование
|
||||
* Простая маршрутизация с параметрами
|
||||
* Статические файлы с пользовательским префиксом
|
||||
* Middleware с поддержкой `Next()`
|
||||
* Endpoints, как у API Express
|
||||
* [Расширенная документация](https://gofiber.github.io/fiber/)
|
||||
- Оптимизирован для скорости и низкого использования памяти
|
||||
- Быстрое Server-Side программирование
|
||||
- Простая маршрутизация с параметрами
|
||||
- Статические файлы с пользовательским префиксом
|
||||
- Middleware с поддержкой `Next()`
|
||||
- Endpoints, как у API Express
|
||||
- [Расширенная документация](https://gofiber.github.io/fiber/)
|
||||
|
||||
## Установка
|
||||
|
||||
|
@ -37,7 +37,7 @@
|
|||
Установит пакет [Fiber](https://github.com/gofiber/fiber) с помощью следующей команды в консоле:
|
||||
|
||||
```console
|
||||
$ go get -u github.com/gofiber/fiber
|
||||
go get -u github.com/gofiber/fiber
|
||||
```
|
||||
|
||||
## Hello, world!
|
||||
|
@ -55,11 +55,11 @@ func main() {
|
|||
// Создание нового инстанса Fiber
|
||||
app := fiber.New()
|
||||
|
||||
// Создание маршрута с GET
|
||||
// Создание маршрута с GET
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
c.Send("Hello, World!")
|
||||
})
|
||||
|
||||
|
||||
// Старт сервера на http://localhost:8080
|
||||
app.Listen(8080)
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ func main() {
|
|||
Перейдите в консоль и запустите:
|
||||
|
||||
```console
|
||||
$ go run server.go
|
||||
go run server.go
|
||||
```
|
||||
|
||||
А теперь, откройте в браузере адрес `http://localhost:8080`. Вы должы увидеть надпись `Hello, World!`! 🎉
|
||||
|
@ -85,10 +85,10 @@ import "github.com/gofiber/fiber"
|
|||
func main() {
|
||||
// Создание нового инстанса Fiber
|
||||
app := fiber.New()
|
||||
|
||||
|
||||
// Включение всех файлов в папке ./public для работы
|
||||
app.Static("./public")
|
||||
|
||||
|
||||
// Старт сервера на http://localhost:8080
|
||||
app.Listen(8080)
|
||||
}
|
||||
|
@ -117,21 +117,21 @@ func main() {
|
|||
|
||||
// Определяем все необходимые middlewares
|
||||
// с помощью метода Use()
|
||||
|
||||
|
||||
app.Use(func(c *fiber.Ctx) {
|
||||
c.Write("Match anything!\n")
|
||||
c.Next()
|
||||
})
|
||||
|
||||
|
||||
app.Use("/api", func(c *fiber.Ctx) {
|
||||
c.Write("Match starting with /api\n")
|
||||
c.Next()
|
||||
})
|
||||
|
||||
|
||||
app.Get("/api/user", func(c *fiber.Ctx) {
|
||||
c.Write("Match exact path /api/user\n")
|
||||
})
|
||||
|
||||
|
||||
// Старт сервера на http://localhost:8080
|
||||
app.Listen(8080)
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// 🔌 Fiber is an Expressjs inspired web framework build on 🚀 Fasthttp.
|
||||
// 🔌 Fiber is an Express.js inspired web framework build on 🚀 Fasthttp.
|
||||
// 📌 Please open an issue if you got suggestions or found a bug!
|
||||
// 🖥 https://github.com/gofiber/fiber
|
||||
|
||||
|
@ -13,6 +13,7 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
// Version : Fiber version
|
||||
Version = "1.2.3"
|
||||
// https://play.golang.org/p/r6GNeV1gbH
|
||||
banner = "" +
|
||||
|
@ -40,7 +41,7 @@ type Fiber struct {
|
|||
Prefork bool
|
||||
child bool
|
||||
// Stores all routes
|
||||
routes []*route
|
||||
routes []*Route
|
||||
}
|
||||
|
||||
// Fasthttp settings
|
||||
|
|
10
context.go
10
context.go
|
@ -1,4 +1,4 @@
|
|||
// 🔌 Fiber is an Expressjs inspired web framework build on 🚀 Fasthttp.
|
||||
// 🔌 Fiber is an Express.js inspired web framework build on 🚀 Fasthttp.
|
||||
// 📌 Please open an issue if you got suggestions or found a bug!
|
||||
// 🖥 https://github.com/gofiber/fiber
|
||||
|
||||
|
@ -13,23 +13,23 @@ import (
|
|||
"github.com/valyala/fasthttp"
|
||||
)
|
||||
|
||||
// Ctx struct
|
||||
// Ctx : struct
|
||||
type Ctx struct {
|
||||
route *route
|
||||
route *Route
|
||||
next bool
|
||||
params *[]string
|
||||
values []string
|
||||
Fasthttp *fasthttp.RequestCtx
|
||||
}
|
||||
|
||||
// Cookie :
|
||||
// Cookie : struct
|
||||
type Cookie struct {
|
||||
Expire int // time.Unix(1578981376, 0)
|
||||
MaxAge int
|
||||
Domain string
|
||||
Path string
|
||||
|
||||
HttpOnly bool
|
||||
HTTPOnly bool
|
||||
Secure bool
|
||||
SameSite string
|
||||
}
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
# Application
|
||||
|
||||
The app instance conventionally denotes the Fiber application.
|
||||
|
||||
#### New
|
||||
|
||||
Creates an new Fiber instance that we named "**app**".
|
||||
|
||||
```go
|
||||
app := fiber.New()
|
||||
// ...
|
||||
|
@ -12,7 +15,9 @@ app.Listen(8080)
|
|||
```
|
||||
|
||||
#### Server
|
||||
|
||||
Fiber by default does not send a [server header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Server), but you can enable this by changing the server value.
|
||||
|
||||
```go
|
||||
app := fiber.New()
|
||||
|
||||
|
@ -23,7 +28,8 @@ app.Listen(8080)
|
|||
```
|
||||
|
||||
#### Banner
|
||||
When you launch your Fiber application, the console will print a banner containing the package version and listening port. This is enabled by default, disable it by setting the Banner value to false.
|
||||
|
||||
When you launch your Fiber application, the console will print a banner containing the package version and listening port. This is enabled by default, disable it by setting the Banner value to false.
|
||||
|
||||

|
||||
|
||||
|
@ -36,10 +42,12 @@ app.Listen(8080)
|
|||
```
|
||||
|
||||
#### Engine
|
||||
|
||||
You can edit some of the Fasthttp server settings via the Fiber instance.
|
||||
Make sure that you set these settings before calling the [Listen](#listen) method. You can find the description of each value in [Fasthttp server settings](https://github.com/valyala/fasthttp/blob/master/server.go#L150)
|
||||
|
||||
**Only change these settings if you know what you are doing.**
|
||||
|
||||
```go
|
||||
app := fiber.New()
|
||||
|
||||
|
@ -68,13 +76,14 @@ app.Listen(8080)
|
|||
```
|
||||
|
||||
#### Prefork
|
||||
|
||||
Prefork enables use of the **[SO_REUSEPORT](https://lwn.net/Articles/542629/)** socket option, which is available in newer versions of many operating systems, including DragonFly BSD and Linux (kernel version 3.9 and later). This will spawn multiple go processes listening on the same port.
|
||||
|
||||
NGINX has a great article about [Socket Sharding](https://www.nginx.com/blog/socket-sharding-nginx-release-1-9-1/), these pictures are taken from the same article.
|
||||
|
||||
<img src="https://cdn.wp.nginx.com/wp-content/uploads/2015/05/Slack-for-iOS-Upload-1-e1432652484191.png" style="width: 50%;float: left;"/>
|
||||
<img src="https://cdn.wp.nginx.com/wp-content/uploads/2015/05/Slack-for-iOS-Upload-e1432652376641.png" style="width: 50%;float: left;"/>
|
||||
<div style="clear:both"></div>
|
||||
<div style="clear:both"></div>
|
||||
|
||||
You can enable the **prefork** feature by adding the **-prefork** flag.
|
||||
|
||||
|
@ -83,6 +92,7 @@ You can enable the **prefork** feature by adding the **-prefork** flag.
|
|||
```
|
||||
|
||||
Or enable the **Prefork** option in your app.
|
||||
|
||||
```go
|
||||
app := fiber.New()
|
||||
|
||||
|
@ -99,7 +109,9 @@ app.Listen(8080)
|
|||
```
|
||||
|
||||
#### Methods
|
||||
|
||||
Routes an HTTP request, where METHOD is the [HTTP method](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods) of the request, such as GET, PUT, POST, and so on capitalized. Thus, the actual methods are **app.Get()**, **app.Post()**, **app.Put()**, and so on.
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
app.Get(handler func(*Ctx))
|
||||
|
@ -123,36 +135,47 @@ app.Use(...) // Will only see wheter url starts with specified path without :par
|
|||
```
|
||||
|
||||
#### Static
|
||||
|
||||
To serve static files such as images, CSS files, and JavaScript files, replace your function handler with a file or directory string.
|
||||
By default this method will send `index.html` files in response to a request on a directory.
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
app.Static(root string)
|
||||
app.Static(prefix, root string)
|
||||
```
|
||||
|
||||
For example, use the following code to serve images, CSS files, and JavaScript files in a directory named public:
|
||||
|
||||
```go
|
||||
app.Static("./public")
|
||||
```
|
||||
|
||||
Now, you can load the files that are in the public directory:
|
||||
|
||||
```shell
|
||||
http://localhost:8080/hello.html
|
||||
http://localhost:8080/js/jquery.js
|
||||
http://localhost:8080/css/style.css
|
||||
```
|
||||
|
||||
To use multiple static assets directories, call the Static function multiple times:
|
||||
|
||||
```go
|
||||
app.Static("./public")
|
||||
app.Static("./files")
|
||||
```
|
||||
?>For best results, use a reverse proxy cache like [NGINX](https://www.nginx.com/resources/wiki/start/topics/examples/reverseproxycachingexample/) to improve performance of serving static assets.
|
||||
|
||||
?>For best results, use a reverse proxy cache like [NGINX](https://www.nginx.com/resources/wiki/start/topics/examples/reverseproxycachingexample/) to improve performance of serving static assets.
|
||||
|
||||
To create a virtual path prefix (where the path does not actually exist in the file system) for files that are served by the express.static function, specify a mount path for the static directory, as shown below:
|
||||
|
||||
```go
|
||||
app.Static("/static", "./public")
|
||||
```
|
||||
|
||||
Now, you can load the files that are in the public directory from the /static path prefix.
|
||||
|
||||
```shell
|
||||
http://localhost:8080/static/hello.html
|
||||
http://localhost:8080/static/js/jquery.js
|
||||
|
@ -160,7 +183,9 @@ http://localhost:8080/static/css/style.css
|
|||
```
|
||||
|
||||
#### Listen
|
||||
|
||||
Binds and listens for connections on the specified address. This can be a **INT** for port or **STRING** for address. To enable **TLS/HTTPS** you can append your **cert** and **key** path.
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
app.Listen(address interface{}, tls ...string)
|
||||
|
@ -175,5 +200,4 @@ app.Listen("127.0.0.1:8080")
|
|||
app.Listen(443, "server.crt", "server.key")
|
||||
```
|
||||
|
||||
|
||||
*Caught a mistake? [Edit this page on GitHub!](https://github.com/gofiber/fiber/blob/master/docs/application.md)*
|
||||
_Caught a mistake? [Edit this page on GitHub!](https://github.com/gofiber/fiber/blob/master/docs/application.md)_
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
# Benchmarks
|
||||
|
||||
#### TechEmpower
|
||||
* **CPU** Intel Xeon Gold 5120
|
||||
* **MEM** 32GB
|
||||
* **GO** go1.13.6 linux/amd64
|
||||
* **OS** Linux
|
||||
* **NET** Dedicated Cisco 10-gigabit Ethernet switch.
|
||||
|
||||
- **CPU** Intel Xeon Gold 5120
|
||||
- **MEM** 32GB
|
||||
- **GO** go1.13.6 linux/amd64
|
||||
- **OS** Linux
|
||||
- **NET** Dedicated Cisco 10-gigabit Ethernet switch.
|
||||
|
||||
Below you can see the results of tested go frameworks responding in plaintext.
|
||||
To view the list yourself, [Plaintext Go Results](https://www.techempower.com/benchmarks/#section=test&runid=350f0783-cc9b-4259-9831-28987799782a&hw=ph&test=plaintext&l=zijocf-1r).
|
||||
To see all language frameworks, [Plaintext All Results](https://www.techempower.com/benchmarks/#section=test&runid=350f0783-cc9b-4259-9831-28987799782a&hw=ph&test=plaintext).
|
||||
To see all language frameworks, [Plaintext All Results](https://www.techempower.com/benchmarks/#section=test&runid=350f0783-cc9b-4259-9831-28987799782a&hw=ph&test=plaintext).
|
||||
|
||||
Plaintext
|
||||
[](https://www.techempower.com/benchmarks/#section=test&runid=350f0783-cc9b-4259-9831-28987799782a&hw=ph&test=plaintext&l=zijocf-1r)
|
||||
|
@ -31,14 +31,15 @@ Data updates
|
|||
[](https://www.techempower.com/benchmarks/#section=test&runid=350f0783-cc9b-4259-9831-28987799782a&hw=ph&test=update&l=zijocf-1r)
|
||||
|
||||
#### Go-Web
|
||||
|
||||
[go-web-framework-benchmark](https://github.com/smallnest/go-web-framework-benchmark)
|
||||
|
||||
* **CPU** Intel(R) Xeon(R) Gold 6140 CPU @ 2.30GHz
|
||||
* **MEM** 4GB
|
||||
* **GO** go1.13.6 linux/amd64
|
||||
* **OS** Linux
|
||||
- **CPU** Intel(R) Xeon(R) Gold 6140 CPU @ 2.30GHz
|
||||
- **MEM** 4GB
|
||||
- **GO** go1.13.6 linux/amd64
|
||||
- **OS** Linux
|
||||
|
||||
The first test case is to mock 0 ms, 10 ms, 100 ms, 500 ms processing time in handlers.
|
||||
The first test case is to mock 0 ms, 10 ms, 100 ms, 500 ms processing time in handlers.
|
||||
|
||||

|
||||
|
||||
|
@ -68,8 +69,8 @@ If we enable http pipelining, test result as below:
|
|||
|
||||

|
||||
|
||||
<!-- CPU-Bound Test
|
||||
<!-- CPU-Bound Test
|
||||
This benchmark is outdated
|
||||
 -->
|
||||
|
||||
*Caught a mistake? [Edit this page on GitHub!](https://github.com/Fenny/fiber/blob/master/docs/benchmarks.md)*
|
||||
_Caught a mistake? [Edit this page on GitHub!](https://github.com/Fenny/fiber/blob/master/docs/benchmarks.md)_
|
||||
|
|
132
docs/context.md
132
docs/context.md
|
@ -1,8 +1,11 @@
|
|||
# Context
|
||||
|
||||
The ctx object represents the HTTP request and response and has methods for the request query string, parameters, body, HTTP headers, and so on. In this documentation and by convention, the context is always referred to as c but its actual name is determined by the parameters to the callback function in which you’re working.
|
||||
|
||||
#### Accepts
|
||||
|
||||
Checks if the specified content types are acceptable, based on the request’s Accept HTTP header field. You can use an extention or content-type format
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.Accepts(types ...string) string
|
||||
|
@ -31,7 +34,9 @@ app.Get("/", func(c *fiber.Ctx) {
|
|||
```
|
||||
|
||||
#### AcceptsCharsets
|
||||
|
||||
Returns the first accepted charset of the specified character sets, based on the request’s Accept-Charset HTTP header field
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.AcceptsCharsets(charsets ...string) string
|
||||
|
@ -50,9 +55,10 @@ app.Get("/", func(c *fiber.Ctx) {
|
|||
})
|
||||
```
|
||||
|
||||
|
||||
#### AcceptsEncodings
|
||||
|
||||
Returns the first accepted encoding of the specified encodings, based on the request’s Accept-Encoding HTTP header field.
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.AcceptsEncodings(encodings ...string) string
|
||||
|
@ -72,7 +78,9 @@ app.Get("/", func(c *fiber.Ctx) {
|
|||
```
|
||||
|
||||
#### AcceptsLanguages
|
||||
|
||||
Returns the first accepted language of the specified languages, based on the request’s Accept-Language HTTP header field.
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.AcceptsLanguages(languages ...string) string
|
||||
|
@ -92,7 +100,9 @@ app.Get("/", func(c *fiber.Ctx) {
|
|||
```
|
||||
|
||||
#### Append
|
||||
|
||||
Appends the specified value to the HTTP response header field. If the header is not already set, it creates the header with the specified value. The value parameter must be a string.
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.Append(field, values ...string)
|
||||
|
@ -113,7 +123,9 @@ app.Get("/", func(c *fiber.Ctx) {
|
|||
```
|
||||
|
||||
#### Attachment
|
||||
Sets the HTTP response [Content-Disposition](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition) header field to “attachment”. If a filename is given, then it sets the Content-Type based on the extension name via (Type)[#type], and sets the Content-Disposition “filename=” parameter.
|
||||
|
||||
Sets the HTTP response [Content-Disposition](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition) header field to “attachment”. If a filename is given, then it sets the Content-Type based on the extension name via [Type](#type), and sets the Content-Disposition “filename=” parameter.
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.Attachment(file ...string)
|
||||
|
@ -132,7 +144,9 @@ app.Get("/", func(c *fiber.Ctx) {
|
|||
#### BaseUrl
|
||||
|
||||
#### AcceptsLanguages
|
||||
|
||||
Returns the base URL, protocol and hostname combined.
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.BaseUrl() bool
|
||||
|
@ -146,7 +160,9 @@ app.Get("/", func(c *fiber.Ctx) {
|
|||
```
|
||||
|
||||
#### BasicAuth
|
||||
|
||||
BasicAuth returns the username and password provided in the request's Authorization header, if the request uses [HTTP Basic Authentication](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication).
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.BasicAuth() (user, pass string, ok bool)
|
||||
|
@ -167,10 +183,12 @@ app.Get("/", func(c *fiber.Ctx) {
|
|||
```
|
||||
|
||||
#### Body
|
||||
|
||||
Contains the raw post body submitted in the request.
|
||||
Calling a key in body returns a string value if exist or you loop trough the body params using a key value function callback.
|
||||
|
||||
The following example shows how to use the body function.
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.Body() string
|
||||
|
@ -190,14 +208,16 @@ app.Post("/", func(c *fiber.Ctx) {
|
|||
|
||||
// Loop trough all body params
|
||||
c.Body(func(key string, val string) {
|
||||
fmt.Printl(key, val)
|
||||
fmt.Printl(key, val)
|
||||
// => "user" "john"
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
#### ClearCookie
|
||||
|
||||
Clears all client cookies or a specific cookie by name by setting the expire date in the past.
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.ClearCookie()
|
||||
|
@ -217,7 +237,9 @@ app.Get("/", func(c *fiber.Ctx) {
|
|||
```
|
||||
|
||||
#### Cookie
|
||||
|
||||
Sets cookie name to value, the third options parameter is not implemented yet.
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.Cookie(name, value string)
|
||||
|
@ -259,7 +281,9 @@ app.Get("/", func(c *fiber.Ctx) {
|
|||
```
|
||||
|
||||
#### Cookies
|
||||
|
||||
Get cookies
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.Cookies() string
|
||||
|
@ -287,7 +311,9 @@ app.Get("/", func(c *fiber.Ctx) {
|
|||
```
|
||||
|
||||
#### Download
|
||||
|
||||
Transfers the file at path as an “attachment”. Typically, browsers will prompt the user for download. By default, the Content-Disposition header “filename=” parameter is path (this typically appears in the browser dialog). Override this default with the filename parameter.
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.Download(path string)
|
||||
|
@ -304,11 +330,14 @@ app.Get("/", func(c *fiber.Ctx) {
|
|||
```
|
||||
|
||||
#### !End
|
||||
|
||||
!> Planned for v2.0.0
|
||||
|
||||
#### Fasthttp
|
||||
|
||||
You can still access and use all Fasthttp methods and properties.
|
||||
Please read the [Fasthttp Documentation](https://godoc.org/github.com/valyala/fasthttp) for more information
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.Fasthttp...
|
||||
|
@ -324,6 +353,7 @@ app.Get("/", func(c *fiber.Ctx) {
|
|||
```
|
||||
|
||||
#### Format
|
||||
|
||||
Performs content-negotiation on the Accept HTTP header. It uses [Accepts](#accepts) to select a proper format. If the header is not specified or there is no proper format, text/plain is used.
|
||||
|
||||
```go
|
||||
|
@ -348,7 +378,9 @@ app.Get("/", func(c *fiber.Ctx) {
|
|||
```
|
||||
|
||||
#### FormFile
|
||||
|
||||
MultipartForm files can be retrieved by name, the first file from the given key is returned.
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.FormFile(name string) (*multipart.FileHeader, error)
|
||||
|
@ -367,7 +399,9 @@ app.Post("/", func(c *fiber.Ctx) {
|
|||
```
|
||||
|
||||
#### FormValue
|
||||
|
||||
MultipartForm values can be retrieved by name, the first value from the given key is returned.
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.FormValue(name string) string
|
||||
|
@ -381,10 +415,13 @@ app.Post("/", func(c *fiber.Ctx) {
|
|||
```
|
||||
|
||||
#### !Fresh
|
||||
|
||||
!> Planned for v2.0.0
|
||||
|
||||
#### Get
|
||||
|
||||
Returns the HTTP response header specified by field. The match is case-insensitive.
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.Get(field string) string
|
||||
|
@ -403,10 +440,13 @@ app.Get("/", func(c *fiber.Ctx) {
|
|||
```
|
||||
|
||||
#### !HeadersSent
|
||||
|
||||
!> Planned for v2.0.0
|
||||
|
||||
#### Hostname
|
||||
|
||||
Contains the hostname derived from the Host HTTP header.
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.Hostname() string
|
||||
|
@ -420,7 +460,9 @@ app.Get("/", func(c *fiber.Ctx) {
|
|||
```
|
||||
|
||||
#### Ip
|
||||
|
||||
Contains the remote IP address of the request.
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.Ip() string
|
||||
|
@ -433,7 +475,9 @@ app.Get("/", func(c *fiber.Ctx) {
|
|||
```
|
||||
|
||||
#### Ips
|
||||
|
||||
contains an array of IP addresses specified in the X-Forwarded-For request header.
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.Ips() []string
|
||||
|
@ -447,7 +491,9 @@ app.Get("/", func(c *fiber.Ctx) {
|
|||
```
|
||||
|
||||
#### Is
|
||||
|
||||
Returns the matching content type if the incoming request’s “Content-Type” HTTP header field matches the MIME type specified by the type parameter. If the request has no body, returns false.
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.Is(typ string) bool
|
||||
|
@ -455,19 +501,21 @@ c.Is(typ string) bool
|
|||
// Example
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
// Content-Type: text/html; charset=utf-8
|
||||
c.Is("html")
|
||||
c.Is("html")
|
||||
// => true
|
||||
|
||||
c.Is(".html")
|
||||
// => true
|
||||
|
||||
c.Is("json")
|
||||
c.Is("json")
|
||||
// => false
|
||||
})
|
||||
```
|
||||
|
||||
#### Json
|
||||
|
||||
Converts any interface or string to json using [Jsoniter](https://github.com/json-iterator/go), this function also sets the content header to application/json.
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.Json(v interface{}) error
|
||||
|
@ -494,6 +542,7 @@ app.Listen(8080)
|
|||
```
|
||||
|
||||
Or with error checking
|
||||
|
||||
```go
|
||||
app.Get("/json", func(c *fiber.Ctx) {
|
||||
data := SomeStruct{
|
||||
|
@ -508,7 +557,9 @@ app.Get("/json", func(c *fiber.Ctx) {
|
|||
```
|
||||
|
||||
#### JsonBytes
|
||||
|
||||
This function accepts raw []byte bodies and sets the content header to application/json. This function is used if you do not need type assertion.
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.Json(json []byte)
|
||||
|
@ -521,11 +572,12 @@ app.Get("/json", func(c *fiber.Ctx) {
|
|||
app.Listen(8080)
|
||||
```
|
||||
|
||||
|
||||
#### Jsonp
|
||||
|
||||
Sends a JSON response with JSONP support. This method is identical to [Json()](#json), except that it opts-in to JSONP callback support.
|
||||
|
||||
By default, the JSONP callback name is simply callback. Override this by passing a named string in the function.
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.Jsonp(v interface{}) error
|
||||
|
@ -553,7 +605,9 @@ app.Listen(8080)
|
|||
```
|
||||
|
||||
#### JsonString
|
||||
|
||||
This function accepts raw string body and sets the content header to application/json. This function is used if you do not need type assertion.
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.Json(json string)
|
||||
|
@ -567,7 +621,9 @@ app.Listen(8080)
|
|||
```
|
||||
|
||||
#### Links
|
||||
|
||||
Joins the links followed by the propery to populate the response’s Link HTTP header field.
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.Links(link ...string)
|
||||
|
@ -584,9 +640,11 @@ app.Get("/", func(c *fiber.Ctx) {
|
|||
```
|
||||
|
||||
#### Locals
|
||||
A function that stores string variables scoped to the request, and therefore available only to the routes that match the request.
|
||||
|
||||
A function that stores string variables scoped to the request, and therefore available only to the routes that match the request.
|
||||
|
||||
This is usefull if you want to pass some specific values to the next middleware.
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.Locals(key string)
|
||||
|
@ -608,6 +666,7 @@ app.Get("/", func(c *fiber.Ctx) {
|
|||
```
|
||||
|
||||
You can put any type inside the locals, don't forget to convert it back when you are using the variable
|
||||
|
||||
```go
|
||||
type JSON struct {
|
||||
Message string `json:"message"`
|
||||
|
@ -627,7 +686,9 @@ app.Get("/", func(c *fiber.Ctx) {
|
|||
```
|
||||
|
||||
#### Location
|
||||
|
||||
Sets the response Location HTTP header to the specified path parameter.
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.Location(path string)
|
||||
|
@ -640,7 +701,9 @@ app.Post("/", func(c *fiber.Ctx) {
|
|||
```
|
||||
|
||||
#### Method
|
||||
|
||||
Contains a string corresponding to the HTTP method of the request: GET, POST, PUT, and so on.
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.Method() string
|
||||
|
@ -653,9 +716,11 @@ app.Post("/", func(c *fiber.Ctx) {
|
|||
```
|
||||
|
||||
#### MultipartForm
|
||||
|
||||
To access multipart form entries, you can parse the binary with .MultipartForm().
|
||||
This returns a map[string][]string, so given a key the value will be a string slice.
|
||||
So accepting multiple files or values is easy, as shown below!
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.MultipartForm() (*multipart.Form, error)
|
||||
|
@ -688,7 +753,9 @@ app.Post("/", func(c *fiber.Ctx) {
|
|||
```
|
||||
|
||||
#### Next
|
||||
|
||||
When Next() is called, it executes the next function in the stack that matches the current route.
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.Next()
|
||||
|
@ -709,7 +776,9 @@ app.Get("/", func(c *fiber.Ctx) {
|
|||
```
|
||||
|
||||
#### OriginalUrl
|
||||
|
||||
Contains the original request URL.
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.OriginalUrl() string
|
||||
|
@ -723,7 +792,9 @@ app.Get("/", func(c *fiber.Ctx) {
|
|||
```
|
||||
|
||||
#### Params
|
||||
|
||||
This method can be used to get the route parameters. For example, if you have the route /user/:name, then the “name” property is available as c.Params("name"). This method defaults "".
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.Params(param string) string
|
||||
|
@ -737,7 +808,9 @@ app.Get("/user/:name", func(c *fiber.Ctx) {
|
|||
```
|
||||
|
||||
#### Path
|
||||
|
||||
Contains the path part of the request URL.
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.Path() string
|
||||
|
@ -751,6 +824,7 @@ app.Get("/users", func(c *fiber.Ctx) {
|
|||
```
|
||||
|
||||
#### Protocol
|
||||
|
||||
Contains the request protocol string: either http or (for TLS requests) https.
|
||||
|
||||
```go
|
||||
|
@ -763,8 +837,11 @@ app.Get("/", func(c *fiber.Ctx) {
|
|||
// => "http"
|
||||
})
|
||||
```
|
||||
|
||||
#### Query
|
||||
|
||||
This property is an object containing a property for each query string parameter in the route. If there is no query string, it returns an empty string
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.Query(parameter string) string
|
||||
|
@ -782,10 +859,13 @@ app.Get("/", func(c *fiber.Ctx) {
|
|||
```
|
||||
|
||||
#### !Range
|
||||
|
||||
!> Planned for v2.0.0
|
||||
|
||||
#### Redirect
|
||||
|
||||
Redirects to the URL derived from the specified path, with specified status, a positive integer that corresponds to an HTTP status code . If not specified, status defaults to “302 “Found”.
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.Redirect(path string)
|
||||
|
@ -801,11 +881,14 @@ app.Get("/", func(c *fiber.Ctx) {
|
|||
```
|
||||
|
||||
#### !Render
|
||||
|
||||
!> Planned for v2.0.0
|
||||
|
||||
#### Route
|
||||
|
||||
Contains the currently-matched route struct, **only use this for debugging**.
|
||||
It returns an anonymous struct as shown below.
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.Route() struct {
|
||||
|
@ -830,8 +913,8 @@ app.Post("/:api?", func(c *fiber.Ctx) {
|
|||
})
|
||||
```
|
||||
|
||||
|
||||
#### SaveFile
|
||||
|
||||
This function is used to save any multipart file to disk.
|
||||
You can see a working example here: [Multiple file upload](#multipartform)
|
||||
|
||||
|
@ -841,6 +924,7 @@ c.SaveFile(fh *multipart.FileHeader, path string)
|
|||
```
|
||||
|
||||
#### Secure
|
||||
|
||||
A Boolean property that is true if a TLS connection is established.
|
||||
|
||||
```go
|
||||
|
@ -852,9 +936,11 @@ c.Protocol() == "https"
|
|||
```
|
||||
|
||||
#### Send
|
||||
|
||||
Sends the HTTP response.
|
||||
|
||||
The Send parameters can be of any type
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.Send(body ...interface{})
|
||||
|
@ -873,8 +959,10 @@ app.Get("/", func(c *fiber.Ctx) {
|
|||
```
|
||||
|
||||
#### SendBytes
|
||||
|
||||
Same as Send() but without type assertion.
|
||||
I suggest using this in production for optimal performance.
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.SendBytes(body []byte)
|
||||
|
@ -886,7 +974,9 @@ app.Get("/", func(c *fiber.Ctx) {
|
|||
```
|
||||
|
||||
#### SendFile
|
||||
Transfers the file at the given path. Sets the Content-Type response HTTP header field based on the filename’s extension.
|
||||
|
||||
Transfers the file at the given path. Sets the Content-Type response HTTP header field based on the filename’s extension.
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.SendFile(path string)
|
||||
|
@ -902,7 +992,9 @@ app.Get("/not-found", func(c *fiber.Ctx) {
|
|||
```
|
||||
|
||||
#### SendStatus
|
||||
|
||||
Sets the status code, but also the correct status message in the body if the response body is still empty. You can find all status codes and messages in [status.go](https://github.com/gofiber/fiber/blob/master/status.go)
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.SendStatus(status int)
|
||||
|
@ -921,8 +1013,10 @@ app.Get("/not-found", func(c *fiber.Ctx) {
|
|||
```
|
||||
|
||||
#### SendString
|
||||
|
||||
Same as Send() but without type assertion.
|
||||
I suggest using this in production for optimal performance.
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.SendString(body string)
|
||||
|
@ -934,7 +1028,9 @@ app.Get("/", func(c *fiber.Ctx) {
|
|||
```
|
||||
|
||||
#### Set
|
||||
|
||||
Sets the response’s HTTP header field to value. To set multiple fields at once, pass an object as the parameter.
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.Set(key, value string)
|
||||
|
@ -947,13 +1043,17 @@ app.Get("/", func(c *fiber.Ctx) {
|
|||
```
|
||||
|
||||
#### !SignedCookies
|
||||
|
||||
!> Planned for v2.0.0
|
||||
|
||||
#### !Stale
|
||||
|
||||
!> Planned for v2.0.0
|
||||
|
||||
#### Status
|
||||
|
||||
Sets the HTTP status for the response. It is a chainable alias of Node’s response.statusCode.
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.Status(status int)
|
||||
|
@ -967,8 +1067,10 @@ app.Get("/", func(c *fiber.Ctx) {
|
|||
```
|
||||
|
||||
#### Subdomains
|
||||
|
||||
An array of subdomains in the domain name of the request.
|
||||
The application property subdomain offset, which defaults to 2, is used for determining the beginning of the subdomain segments.
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.Subdomains() []string
|
||||
|
@ -982,7 +1084,9 @@ app.Get("/", func(c *fiber.Ctx) {
|
|||
```
|
||||
|
||||
#### Type
|
||||
|
||||
Sets the Content-Type HTTP header to the MIME type listed [here](https://github.com/nginx/nginx/blob/master/conf/mime.types) specified by the file extension.
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.Type(typ string) string
|
||||
|
@ -1004,9 +1108,11 @@ app.Get("/", func(c *fiber.Ctx) {
|
|||
```
|
||||
|
||||
#### Vary
|
||||
|
||||
Adds the given header field to the Vary response header of res. This can be a single field, or multiple fields.
|
||||
|
||||
This will append the header if not already listed, otherwise leaves it listed in the current location.
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.Vary(field ...string)
|
||||
|
@ -1033,9 +1139,11 @@ app.Get("/", func(c *fiber.Ctx) {
|
|||
```
|
||||
|
||||
#### Write
|
||||
|
||||
Appends to the HTTP response.
|
||||
|
||||
The Write parameter can be any type
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.Write(bodies ...interface{})
|
||||
|
@ -1057,7 +1165,9 @@ app.Get("/", func(c *fiber.Ctx) {
|
|||
```
|
||||
|
||||
#### Xhr
|
||||
|
||||
A Boolean property that is true if the request’s **X-Requested-With** header field is **XMLHttpRequest**, indicating that the request was issued by a client library such as [jQuery](https://api.jquery.com/jQuery.ajax/).
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.Xhr() bool
|
||||
|
@ -1070,7 +1180,9 @@ app.Get("/", func(c *fiber.Ctx) {
|
|||
```
|
||||
|
||||
#### Xml
|
||||
|
||||
Xml sets the header to "application/xml" and marshals your interface to xml.
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
c.Xml(xml interface{}) error
|
||||
|
@ -1092,4 +1204,4 @@ app.Listen(8080)
|
|||
|
||||
```
|
||||
|
||||
*Caught a mistake? [Edit this page on GitHub!](https://github.com/Fenny/fiber/blob/master/docs/context.md)*
|
||||
_Caught a mistake? [Edit this page on GitHub!](https://github.com/Fenny/fiber/blob/master/docs/context.md)_
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
# Examples
|
||||
|
||||
#### Multiple File Upload
|
||||
```go
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import "github.com/fenny/fiber"
|
||||
|
@ -25,7 +25,9 @@ func main() {
|
|||
app.Listen(8080)
|
||||
}
|
||||
```
|
||||
|
||||
#### 404 Handling
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
|
@ -43,7 +45,9 @@ func main() {
|
|||
app.Listen(8080)
|
||||
}
|
||||
```
|
||||
|
||||
#### Static Caching
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
|
@ -61,7 +65,9 @@ func main() {
|
|||
app.Listen(8080)
|
||||
}
|
||||
```
|
||||
|
||||
#### Enable CORS
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
|
@ -82,7 +88,9 @@ func main() {
|
|||
app.Listen(8080)
|
||||
}
|
||||
```
|
||||
|
||||
#### Returning JSON
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
|
@ -110,7 +118,9 @@ func main() {
|
|||
app.Listen(8080)
|
||||
}
|
||||
```
|
||||
|
||||
#### TLS/HTTPS
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
|
@ -127,4 +137,4 @@ func main() {
|
|||
}
|
||||
```
|
||||
|
||||
*Caught a mistake? [Edit this page on GitHub!](https://github.com/Fenny/fiber/blob/master/docs/examples.md)*
|
||||
_Caught a mistake? [Edit this page on GitHub!](https://github.com/Fenny/fiber/blob/master/docs/examples.md)_
|
||||
|
|
|
@ -4,7 +4,7 @@ AcceptsEncodings
|
|||
AcceptsLanguages
|
||||
Append
|
||||
Attachment
|
||||
BaseUrl
|
||||
BaseURL
|
||||
BasicAuth
|
||||
Body
|
||||
ClearCookie
|
||||
|
@ -19,10 +19,10 @@ Fresh
|
|||
Get
|
||||
HeadersSent
|
||||
Hostname
|
||||
Ip
|
||||
IP
|
||||
Ips
|
||||
Is
|
||||
Json
|
||||
JSON
|
||||
Jsonp
|
||||
Links
|
||||
Locals
|
||||
|
@ -55,4 +55,4 @@ Subdomains
|
|||
Type
|
||||
Vary
|
||||
Xhr
|
||||
Xml
|
||||
XML
|
||||
|
|
|
@ -1,27 +1,35 @@
|
|||
<img src="static/logo.jpg" width="150" alt="accessibility text"><br><br>
|
||||
|
||||
[](https://github.com/gofiber/fiber/releases/latest)
|
||||
[](http://godoc.org/github.com/gofiber/fiber)
|
||||
[](https://goreportcard.com/report/github.com/gofiber/fiber)
|
||||
[](https://github.com/gofiber/fiber/blob/master/LICENSE)
|
||||
[](https://gitter.im/FiberGo/community)
|
||||
<br>
|
||||
|
||||
# Getting started
|
||||
!>**IMPORTANT: Always use versioning control using [go.mod](https://blog.golang.org/using-go-modules) to avoid breaking API changes!**
|
||||
|
||||
!>**IMPORTANT: Always use versioning control using [go.mod](https://blog.golang.org/using-go-modules) to avoid breaking API changes!**
|
||||
|
||||
**[Fiber](https://github.com/gofiber/fiber)** is a router framework build on top of [FastHTTP](https://github.com/valyala/fasthttp), the fastest HTTP package for **[Go](https://golang.org/doc/)**.<br>
|
||||
This library is inspired by [Express](https://expressjs.com/en/4x/api.html), one of the most populair and well known web framework for **[Nodejs](https://nodejs.org/en/about/)**.
|
||||
|
||||
#### Installing
|
||||
|
||||
Assuming you’ve already installed [Go](https://golang.org/doc/), install the [Fiber](https://github.com/gofiber/fiber) package by calling the following command:
|
||||
|
||||
```shell
|
||||
$ go get -u github.com/gofiber/fiber
|
||||
go get -u github.com/gofiber/fiber
|
||||
```
|
||||
|
||||
#### Hello world
|
||||
|
||||
Embedded below is essentially the simplest Fiber app you can create.
|
||||
|
||||
```shell
|
||||
$ create server.go
|
||||
create server.go
|
||||
```
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
|
@ -37,12 +45,15 @@ func main() {
|
|||
app.Listen(8080)
|
||||
}
|
||||
```
|
||||
|
||||
```shell
|
||||
$ go run server.go
|
||||
go run server.go
|
||||
```
|
||||
|
||||
Browse to http://localhost:8080 and you should see Hello, World! on the page.
|
||||
|
||||
#### Basic routing
|
||||
|
||||
Routing refers to determining how an application responds to a client request to a particular endpoint, which is a URI (or path) and a specific HTTP request method (GET, POST, and so on).
|
||||
|
||||
Each route can have one handler function, that is executed when the route is matched.
|
||||
|
@ -55,14 +66,15 @@ app.Method(func(*fiber.Ctx))
|
|||
app.Method(path string, func(*fiber.Ctx))
|
||||
```
|
||||
|
||||
* **app** is an instance of **[Fiber](#hello-world)**.
|
||||
* **Method** is an [HTTP request method](application?id=methods), in capitalization: Get, Put, Post etc
|
||||
* **path string** is a path on the server.
|
||||
* **func(*fiber.Ctx)** is a function containing the [Context](/context) executed when the route is matched.
|
||||
- **app** is an instance of **[Fiber](#hello-world)**.
|
||||
- **Method** is an [HTTP request method](application?id=methods), in capitalization: Get, Put, Post etc
|
||||
- **path string** is a path on the server.
|
||||
- **func(\*fiber.Ctx)** is a function containing the [Context](/context) executed when the route is matched.
|
||||
|
||||
This tutorial assumes that an instance of fiber named app is created and the server is running. If you are not familiar with creating an app and starting it, see the [Hello world](#hello-world) example.
|
||||
|
||||
The following examples illustrate defining simple routes.
|
||||
The following examples illustrate defining simple routes.
|
||||
|
||||
```go
|
||||
// Respond with Hello, World! on the homepage:
|
||||
app.Get("/", func(c *fiber.Ctx) {
|
||||
|
@ -95,22 +107,27 @@ app.Get("/api/*", func(c *fiber.Ctx) {
|
|||
```
|
||||
|
||||
#### Static files
|
||||
|
||||
To serve static files such as images, CSS files, and JavaScript files, replace your function handler with a file or directory string.
|
||||
|
||||
```go
|
||||
// Function signature
|
||||
app.Static(root string)
|
||||
app.Static(prefix, root string)
|
||||
```
|
||||
|
||||
For example, use the following code to serve images, CSS files, and JavaScript files in a directory named public:
|
||||
|
||||
```go
|
||||
app.Static("./public")
|
||||
```
|
||||
|
||||
Now, you can load the files that are in the public directory:
|
||||
|
||||
```shell
|
||||
http://localhost:8080/hello.html
|
||||
http://localhost:8080/js/jquery.js
|
||||
http://localhost:8080/css/style.css
|
||||
```
|
||||
|
||||
*Caught a mistake? [Edit this page on GitHub!](https://github.com/gofiber/fiber/blob/master/docs/getting_started.md)*
|
||||
_Caught a mistake? [Edit this page on GitHub!](https://github.com/gofiber/fiber/blob/master/docs/getting_started.md)_
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
# License & Thanks
|
||||
Special thanks to some amazing people and organizations:
|
||||
|
||||
Special thanks to some amazing people and organizations:
|
||||
|
||||
[@fenny](https://github.com/fenny) / [Fiber](https://github.com/gofiber/fiber/blob/master/LICENSE)
|
||||
[@valyala](https://github.com/valyala) / [Fasthttp](https://github.com/valyala/fasthttp/blob/master/LICENSE)
|
||||
|
@ -8,7 +9,6 @@ Special thanks to some amazing people and organizations:
|
|||
[@vincentLiuxiang](https://github.com/vincentLiuxiang) / [Lu](https://github.com/vincentLiuxiang/lu/blob/master/LICENSE)
|
||||
[@tj](https://github.com/tj) / [Expressjs](https://github.com/expressjs/express)
|
||||
[@pillarjs](https://github.com/pillarjs) / [Path-to-regexp](https://github.com/pillarjs/path-to-regexp/blob/master/LICENSE)
|
||||
[@techempower](https://github.com/TechEmpower) / [FrameworkBenchmarks](https://github.com/TechEmpower/FrameworkBenchmarks)
|
||||
[@techempower](https://github.com/TechEmpower) / [FrameworkBenchmarks](https://github.com/TechEmpower/FrameworkBenchmarks)
|
||||
|
||||
|
||||
*Caught a mistake? [Edit this page on GitHub!](https://github.com/Fenny/fiber/blob/master/docs/license.md)*
|
||||
_Caught a mistake? [Edit this page on GitHub!](https://github.com/Fenny/fiber/blob/master/docs/license.md)_
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# Routing
|
||||
|
||||
|
||||
#### Paths
|
||||
|
||||
Route paths, in combination with a request method, define the endpoints at which requests can be made. Route paths can be strings, string patterns, or regular expressions.
|
||||
|
||||
The characters ?, +, "8", and () are subsets of their regular expression counterparts. The hyphen (-) and the dot (.) are interpreted literally by string-based paths.
|
||||
|
@ -24,7 +24,9 @@ app.Get("/random.text", func(c *fiber.Ctx) {
|
|||
c.Send("random.text")
|
||||
})
|
||||
```
|
||||
|
||||
Here are some examples of route paths based on string patterns.
|
||||
|
||||
```go
|
||||
// This route path will match acd and abcd.
|
||||
app.Get("/ab?cd", func(c *fiber.Ctx) {
|
||||
|
@ -48,6 +50,7 @@ app.Get("/ab(cd)?e", func(c *fiber.Ctx) {
|
|||
```
|
||||
|
||||
#### Parameters
|
||||
|
||||
Route parameters are named URL segments that are used to capture the values specified at their position in the URL. The captured values can be retrieved using the [Params](context#params) function, with the name of the route parameter specified in the path as their respective keys.
|
||||
|
||||
To define routes with route parameters, simply specify the route parameters in the path of the route as shown below.
|
||||
|
@ -66,11 +69,13 @@ app.Get("/user/:name?", func(c *fiber.Ctx) {
|
|||
c.Send(c.Params("name"))
|
||||
})
|
||||
```
|
||||
|
||||
?>The name of route parameters must be made up of “word characters” ([A-Za-z0-9_]).
|
||||
|
||||
!> The hyphen (-) and the dot (.) are not interpreted literally yet, planned for V2
|
||||
|
||||
#### Middleware
|
||||
|
||||
The [Next](context#next) function is a function in the [Fiber](https://github.com/fenny/fiber) router which, when called, executes the next function that matches the current route.
|
||||
|
||||
Functions that are designed to make changes to the request or response are called middleware functions.
|
||||
|
@ -99,4 +104,4 @@ app.Get("/", func(c *fiber.Ctx) {
|
|||
app.Listen(8080)
|
||||
```
|
||||
|
||||
*Caught a mistake? [Edit this page on GitHub!](https://github.com/Fenny/fiber/blob/master/docs/routing.md)*
|
||||
_Caught a mistake? [Edit this page on GitHub!](https://github.com/Fenny/fiber/blob/master/docs/routing.md)_
|
||||
|
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 863 B After Width: | Height: | Size: 863 B |
26
go.sum
26
go.sum
|
@ -1,26 +0,0 @@
|
|||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns=
|
||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/klauspost/compress v1.8.2 h1:Bx0qjetmNjdFXASH02NSAREKpiaDwkO1DRZ3dV2KCcs=
|
||||
github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
||||
github.com/klauspost/cpuid v1.2.1 h1:vJi+O/nMdFt0vqm8NZBI6wzALWdA2X+egi0ogNyrC/w=
|
||||
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasthttp v1.8.0 h1:actnGGBYtGQmxVaZxyZpp57Vcc2NhcO7mMN0IMwCC0w=
|
||||
github.com/valyala/fasthttp v1.8.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w=
|
||||
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a h1:0R4NLDRDZX6JcmhJgXi5E4b8Wg84ihbmUKp/GvSPEzc=
|
||||
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
13
listen.go
13
listen.go
|
@ -1,4 +1,4 @@
|
|||
// 🔌 Fiber is an Expressjs inspired web framework build on 🚀 Fasthttp.
|
||||
// 🔌 Fiber is an Express.js inspired web framework build on 🚀 Fasthttp.
|
||||
// 📌 Please open an issue if you got suggestions or found a bug!
|
||||
// 🖥 https://github.com/gofiber/fiber
|
||||
|
||||
|
@ -67,20 +67,24 @@ func (r *Fiber) Listen(address interface{}, tls ...string) {
|
|||
}
|
||||
r.prefork(server, host, tls...)
|
||||
}
|
||||
|
||||
// Prefork disabled
|
||||
if r.Banner {
|
||||
fmt.Printf(banner, Version, "", "Express on steriods", host)
|
||||
}
|
||||
|
||||
ln, err := net.Listen("tcp4", host)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// enable TLS/HTTPS
|
||||
if len(tls) > 1 {
|
||||
if err := server.ServeTLS(ln, tls[0], tls[1]); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := server.Serve(ln); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@ -92,6 +96,7 @@ func (r *Fiber) prefork(server *fasthttp.Server, host string, tls ...string) {
|
|||
if !r.child {
|
||||
// Create babies
|
||||
childs := make([]*exec.Cmd, runtime.NumCPU())
|
||||
|
||||
for i := range childs {
|
||||
childs[i] = exec.Command(os.Args[0], "-prefork", "-child")
|
||||
childs[i].Stdout = os.Stdout
|
||||
|
@ -100,26 +105,32 @@ func (r *Fiber) prefork(server *fasthttp.Server, host string, tls ...string) {
|
|||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
for _, child := range childs {
|
||||
if err := child.Wait(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
// Child proc
|
||||
runtime.GOMAXPROCS(1)
|
||||
|
||||
ln, err := reuseport.Listen("tcp4", host)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// enable TLS/HTTPS
|
||||
if len(tls) > 1 {
|
||||
if err := server.ServeTLS(ln, tls[0], tls[1]); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := server.Serve(ln); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// 🔌 Fiber is an Expressjs inspired web framework build on 🚀 Fasthttp.
|
||||
// 🔌 Fiber is an Express.js inspired web framework build on 🚀 Fasthttp.
|
||||
// 📌 Please open an issue if you got suggestions or found a bug!
|
||||
// 🖥 https://github.com/gofiber/fiber
|
||||
|
||||
|
|
|
@ -1,13 +1,9 @@
|
|||
package middleware
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/gofiber/fiber"
|
||||
)
|
||||
import "github.com/gofiber/fiber"
|
||||
|
||||
// Cors : Enable cross-origin resource sharing (CORS) with various options.
|
||||
func Cors(c *fiber.Ctx) {
|
||||
fmt.Println("Cors is still under development, disable until v1.0.0")
|
||||
func Cors(c *fiber.Ctx, d string) {
|
||||
c.Set("Access-Control-Allow-Origin", d)
|
||||
c.Next()
|
||||
}
|
||||
|
|
40
request.go
40
request.go
|
@ -1,4 +1,4 @@
|
|||
// 🔌 Fiber is an Expressjs inspired web framework build on 🚀 Fasthttp.
|
||||
// 🔌 Fiber is an Express.js inspired web framework build on 🚀 Fasthttp.
|
||||
// 📌 Please open an issue if you got suggestions or found a bug!
|
||||
// 🖥 https://github.com/gofiber/fiber
|
||||
|
||||
|
@ -21,10 +21,12 @@ func (ctx *Ctx) Accepts(offers ...string) string {
|
|||
if len(offers) == 0 {
|
||||
panic("You must provide atleast one content type string")
|
||||
}
|
||||
|
||||
h := ctx.Get(fasthttp.HeaderAccept)
|
||||
if h == "" {
|
||||
return offers[0]
|
||||
}
|
||||
|
||||
specs := strings.Split(h, ",")
|
||||
for _, offer := range offers {
|
||||
mimetype := getType(offer)
|
||||
|
@ -38,9 +40,11 @@ func (ctx *Ctx) Accepts(offers ...string) string {
|
|||
if strings.HasPrefix(spec, "*/*") {
|
||||
return offer
|
||||
}
|
||||
|
||||
if strings.HasPrefix(spec, mimetype) {
|
||||
return offer
|
||||
}
|
||||
|
||||
if strings.Contains(spec, "/*") {
|
||||
if strings.HasPrefix(spec, strings.Split(mimetype, "/")[0]) {
|
||||
return offer
|
||||
|
@ -56,10 +60,12 @@ func (ctx *Ctx) AcceptsCharsets(offers ...string) string {
|
|||
if len(offers) == 0 {
|
||||
panic("You must provide atleast one content type string")
|
||||
}
|
||||
|
||||
h := ctx.Get(fasthttp.HeaderAcceptCharset)
|
||||
if h == "" {
|
||||
return offers[0]
|
||||
}
|
||||
|
||||
specs := strings.Split(h, ",")
|
||||
for _, offer := range offers {
|
||||
for _, spec := range specs {
|
||||
|
@ -80,10 +86,12 @@ func (ctx *Ctx) AcceptsEncodings(offers ...string) string {
|
|||
if len(offers) == 0 {
|
||||
panic("You must provide atleast one content type string")
|
||||
}
|
||||
|
||||
h := ctx.Get(fasthttp.HeaderAcceptEncoding)
|
||||
if h == "" {
|
||||
return offers[0]
|
||||
}
|
||||
|
||||
specs := strings.Split(h, ",")
|
||||
for _, offer := range offers {
|
||||
for _, spec := range specs {
|
||||
|
@ -104,10 +112,12 @@ func (ctx *Ctx) AcceptsLanguages(offers ...string) string {
|
|||
if len(offers) == 0 {
|
||||
panic("You must provide atleast one content type string")
|
||||
}
|
||||
|
||||
h := ctx.Get(fasthttp.HeaderAcceptLanguage)
|
||||
if h == "" {
|
||||
return offers[0]
|
||||
}
|
||||
|
||||
specs := strings.Split(h, ",")
|
||||
for _, offer := range offers {
|
||||
for _, spec := range specs {
|
||||
|
@ -123,8 +133,8 @@ func (ctx *Ctx) AcceptsLanguages(offers ...string) string {
|
|||
return ""
|
||||
}
|
||||
|
||||
// BaseUrl : https://gofiber.github.io/fiber/#/context?id=baseurl
|
||||
func (ctx *Ctx) BaseUrl() string {
|
||||
// BaseURL : https://gofiber.github.io/fiber/#/context?id=baseurl
|
||||
func (ctx *Ctx) BaseURL() string {
|
||||
return ctx.Protocol() + "://" + ctx.Hostname()
|
||||
}
|
||||
|
||||
|
@ -134,20 +144,25 @@ func (ctx *Ctx) BasicAuth() (user, pass string, ok bool) {
|
|||
if auth == "" {
|
||||
return
|
||||
}
|
||||
|
||||
const prefix = "Basic "
|
||||
|
||||
// Case insensitive prefix match.
|
||||
if len(auth) < len(prefix) || !strings.EqualFold(auth[:len(prefix)], prefix) {
|
||||
return
|
||||
}
|
||||
|
||||
c, err := base64.StdEncoding.DecodeString(auth[len(prefix):])
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
cs := getString(c)
|
||||
s := strings.IndexByte(cs, ':')
|
||||
if s < 0 {
|
||||
return
|
||||
}
|
||||
|
||||
return cs[:s], cs[s+1:], true
|
||||
}
|
||||
|
||||
|
@ -156,6 +171,7 @@ func (ctx *Ctx) Body(args ...interface{}) string {
|
|||
if len(args) == 0 {
|
||||
return getString(ctx.Fasthttp.Request.Body())
|
||||
}
|
||||
|
||||
if len(args) == 1 {
|
||||
switch arg := args[0].(type) {
|
||||
case string:
|
||||
|
@ -176,6 +192,7 @@ func (ctx *Ctx) Cookies(args ...interface{}) string {
|
|||
if len(args) == 0 {
|
||||
return ctx.Get(fasthttp.HeaderCookie)
|
||||
}
|
||||
|
||||
switch arg := args[0].(type) {
|
||||
case string:
|
||||
return getString(ctx.Fasthttp.Request.Header.Cookie(arg))
|
||||
|
@ -188,6 +205,7 @@ func (ctx *Ctx) Cookies(args ...interface{}) string {
|
|||
default:
|
||||
return ctx.Get(fasthttp.HeaderCookie)
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
|
@ -220,8 +238,8 @@ func (ctx *Ctx) Hostname() string {
|
|||
return getString(ctx.Fasthttp.URI().Host())
|
||||
}
|
||||
|
||||
// Ip : https://gofiber.github.io/fiber/#/context?id=Ip
|
||||
func (ctx *Ctx) Ip() string {
|
||||
// IP : https://gofiber.github.io/fiber/#/context?id=Ip
|
||||
func (ctx *Ctx) IP() string {
|
||||
return ctx.Fasthttp.RemoteIP().String()
|
||||
}
|
||||
|
||||
|
@ -239,6 +257,7 @@ func (ctx *Ctx) Is(ext string) bool {
|
|||
if ext[0] != '.' {
|
||||
ext = "." + ext
|
||||
}
|
||||
|
||||
exts, _ := mime.ExtensionsByType(ctx.Get(fasthttp.HeaderContentType))
|
||||
if len(exts) > 0 {
|
||||
for _, item := range exts {
|
||||
|
@ -254,9 +273,9 @@ func (ctx *Ctx) Is(ext string) bool {
|
|||
func (ctx *Ctx) Locals(key string, val ...interface{}) interface{} {
|
||||
if len(val) == 0 {
|
||||
return ctx.Fasthttp.UserValue(key)
|
||||
} else {
|
||||
ctx.Fasthttp.SetUserValue(key, val[0])
|
||||
}
|
||||
|
||||
ctx.Fasthttp.SetUserValue(key, val[0])
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -270,8 +289,8 @@ func (ctx *Ctx) MultipartForm() (*multipart.Form, error) {
|
|||
return ctx.Fasthttp.MultipartForm()
|
||||
}
|
||||
|
||||
// OriginalUrl : https://gofiber.github.io/fiber/#/context?id=originalurl
|
||||
func (ctx *Ctx) OriginalUrl() string {
|
||||
// OriginalURL : https://gofiber.github.io/fiber/#/context?id=originalurl
|
||||
func (ctx *Ctx) OriginalURL() string {
|
||||
return getString(ctx.Fasthttp.Request.Header.RequestURI())
|
||||
}
|
||||
|
||||
|
@ -280,6 +299,7 @@ func (ctx *Ctx) Params(key string) string {
|
|||
if ctx.params == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
for i := 0; i < len(*ctx.params); i++ {
|
||||
if (*ctx.params)[i] == key {
|
||||
return ctx.values[i]
|
||||
|
@ -312,7 +332,7 @@ func (ctx *Ctx) Range() {
|
|||
}
|
||||
|
||||
// Route : https://gofiber.github.io/fiber/#/context?id=route
|
||||
func (ctx *Ctx) Route() *route {
|
||||
func (ctx *Ctx) Route() *Route {
|
||||
return ctx.route
|
||||
}
|
||||
|
||||
|
|
55
response.go
55
response.go
|
@ -1,9 +1,10 @@
|
|||
// 🔌 Fiber is an Expressjs inspired web framework build on 🚀 Fasthttp.
|
||||
// 🔌 Fiber is an Express.js inspired web framework build on 🚀 Fasthttp.
|
||||
// 📌 Please open an issue if you got suggestions or found a bug!
|
||||
// 🖥 https://github.com/gofiber/fiber
|
||||
|
||||
// 🦸 Not all heroes wear capes, thank you to some amazing people
|
||||
// 💖 @valyala, @dgrr, @erikdubbelboer, @savsgio, @julienschmidt
|
||||
|
||||
package fiber
|
||||
|
||||
import (
|
||||
|
@ -22,6 +23,7 @@ func (ctx *Ctx) Append(field string, values ...string) {
|
|||
if len(values) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
h := ctx.Get(field)
|
||||
for i := range values {
|
||||
h += h + "," + values[i]
|
||||
|
@ -48,6 +50,7 @@ func (ctx *Ctx) ClearCookie(name ...string) {
|
|||
}
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Fasthttp.Request.Header.VisitAllCookie(func(k, v []byte) {
|
||||
ctx.Fasthttp.Response.Header.DelClientCookie(getString(k))
|
||||
})
|
||||
|
@ -56,8 +59,10 @@ func (ctx *Ctx) ClearCookie(name ...string) {
|
|||
// Cookie : https://gofiber.github.io/fiber/#/context?id=cookie
|
||||
func (ctx *Ctx) Cookie(key, value string, options ...interface{}) {
|
||||
cook := &fasthttp.Cookie{}
|
||||
|
||||
cook.SetKey(key)
|
||||
cook.SetValue(value)
|
||||
|
||||
if len(options) > 0 {
|
||||
switch opt := options[0].(type) {
|
||||
case *Cookie:
|
||||
|
@ -73,8 +78,8 @@ func (ctx *Ctx) Cookie(key, value string, options ...interface{}) {
|
|||
if opt.Path != "" {
|
||||
cook.SetPath(opt.Path)
|
||||
}
|
||||
if opt.HttpOnly {
|
||||
cook.SetHTTPOnly(opt.HttpOnly)
|
||||
if opt.HTTPOnly {
|
||||
cook.SetHTTPOnly(opt.HTTPOnly)
|
||||
}
|
||||
if opt.Secure {
|
||||
cook.SetSecure(opt.Secure)
|
||||
|
@ -96,15 +101,18 @@ func (ctx *Ctx) Cookie(key, value string, options ...interface{}) {
|
|||
panic("Invalid cookie options")
|
||||
}
|
||||
}
|
||||
|
||||
ctx.Fasthttp.Response.Header.SetCookie(cook)
|
||||
}
|
||||
|
||||
// Download : https://gofiber.github.io/fiber/#/context?id=download
|
||||
func (ctx *Ctx) Download(file string, name ...string) {
|
||||
filename := filepath.Base(file)
|
||||
|
||||
if len(name) > 0 {
|
||||
filename = name[0]
|
||||
}
|
||||
|
||||
ctx.Set(fasthttp.HeaderContentDisposition, "attachment; filename="+filename)
|
||||
ctx.SendFile(file)
|
||||
}
|
||||
|
@ -117,7 +125,9 @@ func (ctx *Ctx) End() {
|
|||
// Format : https://gofiber.github.io/fiber/#/context?id=format
|
||||
func (ctx *Ctx) Format(args ...interface{}) {
|
||||
var body string
|
||||
|
||||
accept := ctx.Accepts("html", "json")
|
||||
|
||||
for i := range args {
|
||||
switch arg := args[i].(type) {
|
||||
case string:
|
||||
|
@ -131,7 +141,7 @@ func (ctx *Ctx) Format(args ...interface{}) {
|
|||
case "html":
|
||||
ctx.SendString("<p>" + body + "</p>")
|
||||
case "json":
|
||||
ctx.Json(body)
|
||||
ctx.JSON(body)
|
||||
default:
|
||||
ctx.SendString(body)
|
||||
}
|
||||
|
@ -143,20 +153,22 @@ func (ctx *Ctx) HeadersSent() {
|
|||
|
||||
}
|
||||
|
||||
// Json : https://gofiber.github.io/fiber/#/context?id=json
|
||||
func (ctx *Ctx) Json(v interface{}) error {
|
||||
// JSON : https://gofiber.github.io/fiber/#/context?id=json
|
||||
func (ctx *Ctx) JSON(v interface{}) error {
|
||||
raw, err := jsoniter.Marshal(&v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ctx.Fasthttp.Response.Header.SetContentType(contentTypeJson)
|
||||
|
||||
ctx.Fasthttp.Response.Header.SetContentType(contentTypeJSON)
|
||||
ctx.Fasthttp.Response.SetBodyString(getString(raw))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// JsonBytes : https://gofiber.github.io/fiber/#/context?id=jsonbytes
|
||||
func (ctx *Ctx) JsonBytes(raw []byte) {
|
||||
ctx.Fasthttp.Response.Header.SetContentType(contentTypeJson)
|
||||
// JSONBytes : https://gofiber.github.io/fiber/#/context?id=jsonbytes
|
||||
func (ctx *Ctx) JSONBytes(raw []byte) {
|
||||
ctx.Fasthttp.Response.Header.SetContentType(contentTypeJSON)
|
||||
ctx.Fasthttp.Response.SetBodyString(getString(raw))
|
||||
}
|
||||
|
||||
|
@ -166,6 +178,7 @@ func (ctx *Ctx) Jsonp(v interface{}, cb ...string) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
str := "callback("
|
||||
if len(cb) > 0 {
|
||||
str = cb[0] + "("
|
||||
|
@ -175,12 +188,13 @@ func (ctx *Ctx) Jsonp(v interface{}, cb ...string) error {
|
|||
ctx.Set(fasthttp.HeaderXContentTypeOptions, "nosniff")
|
||||
ctx.Fasthttp.Response.Header.SetContentType(contentTypeJs)
|
||||
ctx.Fasthttp.Response.SetBodyString(str)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// JsonString : https://gofiber.github.io/fiber/#/context?id=jsonstring
|
||||
func (ctx *Ctx) JsonString(raw string) {
|
||||
ctx.Fasthttp.Response.Header.SetContentType(contentTypeJson)
|
||||
// JSONString : https://gofiber.github.io/fiber/#/context?id=jsonstring
|
||||
func (ctx *Ctx) JSONString(raw string) {
|
||||
ctx.Fasthttp.Response.Header.SetContentType(contentTypeJSON)
|
||||
ctx.Fasthttp.Response.SetBodyString(raw)
|
||||
}
|
||||
|
||||
|
@ -194,6 +208,7 @@ func (ctx *Ctx) Links(link ...string) {
|
|||
h += `; rel="` + l + `",`
|
||||
}
|
||||
}
|
||||
|
||||
if len(link) > 0 {
|
||||
h = strings.TrimSuffix(h, ",")
|
||||
ctx.Set(fasthttp.HeaderLink, h)
|
||||
|
@ -219,6 +234,7 @@ func (ctx *Ctx) Redirect(path string, status ...int) {
|
|||
if len(status) > 0 {
|
||||
code = status[0]
|
||||
}
|
||||
|
||||
ctx.Set(fasthttp.HeaderLocation, path)
|
||||
ctx.Fasthttp.Response.SetStatusCode(code)
|
||||
}
|
||||
|
@ -233,6 +249,7 @@ func (ctx *Ctx) Send(args ...interface{}) {
|
|||
if len(args) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
switch body := args[0].(type) {
|
||||
case string:
|
||||
ctx.Fasthttp.Response.SetBodyString(body)
|
||||
|
@ -255,6 +272,7 @@ func (ctx *Ctx) SendFile(file string, gzip ...bool) {
|
|||
fasthttp.ServeFileUncompressed(ctx.Fasthttp, file)
|
||||
return
|
||||
}
|
||||
|
||||
fasthttp.ServeFile(ctx.Fasthttp, file)
|
||||
// https://github.com/valyala/fasthttp/blob/master/fs.go#L81
|
||||
//ctx.Type(filepath.Ext(path))
|
||||
|
@ -264,6 +282,7 @@ func (ctx *Ctx) SendFile(file string, gzip ...bool) {
|
|||
// SendStatus : https://gofiber.github.io/fiber/#/context?id=sendstatus
|
||||
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 {
|
||||
msg := getStatus(status)
|
||||
|
@ -300,12 +319,14 @@ func (ctx *Ctx) Vary(fields ...string) {
|
|||
if len(fields) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
vary := ctx.Get(fasthttp.HeaderVary)
|
||||
for _, field := range fields {
|
||||
if !strings.Contains(vary, field) {
|
||||
vary += ", " + field
|
||||
}
|
||||
}
|
||||
|
||||
ctx.Set(fasthttp.HeaderVary, vary)
|
||||
}
|
||||
|
||||
|
@ -323,13 +344,15 @@ func (ctx *Ctx) Write(args ...interface{}) {
|
|||
}
|
||||
}
|
||||
|
||||
// Xml : https://gofiber.github.io/fiber/#/context?id=xml
|
||||
func (ctx *Ctx) Xml(v interface{}) error {
|
||||
// XML : https://gofiber.github.io/fiber/#/context?id=xml
|
||||
func (ctx *Ctx) XML(v interface{}) error {
|
||||
raw, err := xml.Marshal(v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ctx.Fasthttp.Response.Header.SetContentType(contentTypeXml)
|
||||
|
||||
ctx.Fasthttp.Response.Header.SetContentType(contentTypeXML)
|
||||
ctx.Fasthttp.Response.SetBody(raw)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
51
router.go
51
router.go
|
@ -1,4 +1,4 @@
|
|||
// 🔌 Fiber is an Expressjs inspired web framework build on 🚀 Fasthttp.
|
||||
// 🔌 Fiber is an Express.js inspired web framework build on 🚀 Fasthttp.
|
||||
// 📌 Please open an issue if you got suggestions or found a bug!
|
||||
// 🖥 https://github.com/gofiber/fiber
|
||||
|
||||
|
@ -14,10 +14,11 @@ import (
|
|||
"github.com/valyala/fasthttp"
|
||||
)
|
||||
|
||||
type route struct {
|
||||
// Route : struct
|
||||
type Route struct {
|
||||
// HTTP method in uppercase, can be a * for Use() & All()
|
||||
Method string
|
||||
// Stores the orignal path
|
||||
// Stores the original path
|
||||
Path string
|
||||
// Bool that defines if the route is a Use() middleware
|
||||
Midware bool
|
||||
|
@ -35,13 +36,16 @@ type route struct {
|
|||
func (r *Fiber) register(method string, args ...interface{}) {
|
||||
// Set if method is Use() midware
|
||||
var midware = method == "MIDWARE"
|
||||
|
||||
// Match any method
|
||||
if method == "ALL" || midware {
|
||||
method = "*"
|
||||
}
|
||||
|
||||
// Prepare possible variables
|
||||
var path string // We could have a path/prefix
|
||||
var handler func(*Ctx) // We could have a ctx handler
|
||||
|
||||
// Only 1 argument, so no path/prefix
|
||||
if len(args) == 1 {
|
||||
handler = args[0].(func(*Ctx))
|
||||
|
@ -52,49 +56,59 @@ func (r *Fiber) register(method string, args ...interface{}) {
|
|||
panic("Invalid path, must begin with slash '/' or wildcard '*'")
|
||||
}
|
||||
}
|
||||
|
||||
if midware && strings.Contains(path, "/:") {
|
||||
panic("You cannot use :params in Use()")
|
||||
}
|
||||
|
||||
// If Use() path == "/", match anything aka *
|
||||
if midware && path == "/" {
|
||||
path = "*"
|
||||
}
|
||||
|
||||
// If the route needs to match any path
|
||||
if path == "" || path == "*" || path == "/*" {
|
||||
r.routes = append(r.routes, &route{method, path, midware, true, nil, nil, handler})
|
||||
return
|
||||
}
|
||||
// Get params from path
|
||||
params := getParams(path)
|
||||
// If path has no params (simple path), we dont need regex (also for use())
|
||||
if midware || len(params) == 0 {
|
||||
r.routes = append(r.routes, &route{method, path, midware, false, nil, nil, handler})
|
||||
r.routes = append(r.routes, &Route{method, path, midware, true, nil, nil, handler})
|
||||
return
|
||||
}
|
||||
|
||||
// We have parametes, so we need to compile regix from the path
|
||||
// Get params from path
|
||||
params := getParams(path)
|
||||
|
||||
// If path has no params (simple path), we don't need regex (also for use())
|
||||
if midware || len(params) == 0 {
|
||||
r.routes = append(r.routes, &Route{method, path, midware, false, nil, nil, handler})
|
||||
return
|
||||
}
|
||||
|
||||
// We have parametes, so we need to compile regex from the path
|
||||
regex, err := getRegex(path)
|
||||
if err != nil {
|
||||
panic("Invalid url pattern: " + path)
|
||||
}
|
||||
|
||||
// Add regex + params to route
|
||||
r.routes = append(r.routes, &route{method, path, midware, false, regex, params, handler})
|
||||
r.routes = append(r.routes, &Route{method, path, midware, false, regex, params, handler})
|
||||
}
|
||||
|
||||
// then try to match a route as efficient as possible.
|
||||
func (r *Fiber) handler(fctx *fasthttp.RequestCtx) {
|
||||
found := false
|
||||
|
||||
// get custom context from sync pool
|
||||
ctx := acquireCtx(fctx)
|
||||
|
||||
// get path and method from main context
|
||||
path := ctx.Path()
|
||||
method := ctx.Method()
|
||||
|
||||
// loop trough routes
|
||||
for _, route := range r.routes {
|
||||
// Skip route if method is not allowed
|
||||
if route.Method != "*" && route.Method != method {
|
||||
continue
|
||||
}
|
||||
|
||||
// First check if we match a wildcard or static path
|
||||
if route.Wildcard || route.Path == path {
|
||||
// if route.wildcard || (route.path == path && route.params == nil) {
|
||||
|
@ -117,6 +131,7 @@ func (r *Fiber) handler(fctx *fasthttp.RequestCtx) {
|
|||
// continue to go to the next route
|
||||
continue
|
||||
}
|
||||
|
||||
// If route is Use() and path starts with route.path
|
||||
// aka strings.HasPrefix(route.path, path)
|
||||
if route.Midware && strings.HasPrefix(path, route.Path) {
|
||||
|
@ -129,14 +144,17 @@ func (r *Fiber) handler(fctx *fasthttp.RequestCtx) {
|
|||
ctx.next = false
|
||||
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)
|
||||
|
@ -146,23 +164,30 @@ func (r *Fiber) handler(fctx *fasthttp.RequestCtx) {
|
|||
ctx.values = matches[0][1:len(matches[0])]
|
||||
}
|
||||
}
|
||||
|
||||
found = true
|
||||
|
||||
// Set route pointer if user wants to call .Route()
|
||||
ctx.route = route
|
||||
|
||||
// Execute handler with context
|
||||
route.Handler(ctx)
|
||||
|
||||
// if next is not set, leave loop and release ctx
|
||||
if !ctx.next {
|
||||
break
|
||||
}
|
||||
|
||||
// set next to false for next iteration
|
||||
ctx.next = false
|
||||
}
|
||||
|
||||
// No routes found
|
||||
if !found {
|
||||
// Custom 404 handler?
|
||||
ctx.Status(404).Send("Not Found")
|
||||
}
|
||||
|
||||
// release context back into sync pool
|
||||
releaseCtx(ctx)
|
||||
}
|
||||
|
|
15
static.go
15
static.go
|
@ -1,4 +1,4 @@
|
|||
// 🔌 Fiber is an Expressjs inspired web framework build on 🚀 Fasthttp.
|
||||
// 🔌 Fiber is an Express.js inspired web framework build on 🚀 Fasthttp.
|
||||
// 📌 Please open an issue if you got suggestions or found a bug!
|
||||
// 🖥 https://github.com/gofiber/fiber
|
||||
|
||||
|
@ -19,6 +19,7 @@ func (r *Fiber) Static(args ...string) {
|
|||
wildcard := false
|
||||
// enable / disable gzipping somewhere?
|
||||
gzip := true
|
||||
|
||||
if len(args) == 1 {
|
||||
root = args[0]
|
||||
} else if len(args) == 2 {
|
||||
|
@ -28,36 +29,44 @@ func (r *Fiber) Static(args ...string) {
|
|||
prefix = "/" + prefix
|
||||
}
|
||||
}
|
||||
|
||||
// Check if wildcard for single files
|
||||
if prefix == "*" || prefix == "/*" {
|
||||
wildcard = true
|
||||
}
|
||||
|
||||
// Lets get all files from root
|
||||
files, _, err := getFiles(root)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// ./static/compiled => static/compiled
|
||||
mount := filepath.Clean(root)
|
||||
|
||||
// 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))
|
||||
|
||||
// Store original file path to use in ctx handler
|
||||
filePath := file
|
||||
|
||||
// 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" {
|
||||
r.routes = append(r.routes, &route{"GET", prefix, wildcard, false, nil, nil, func(c *Ctx) {
|
||||
r.routes = append(r.routes, &Route{"GET", prefix, wildcard, false, nil, nil, func(c *Ctx) {
|
||||
c.SendFile(filePath, gzip)
|
||||
}})
|
||||
}
|
||||
|
||||
// Add the route + SendFile(filepath) to routes
|
||||
r.routes = append(r.routes, &route{"GET", path, wildcard, false, nil, nil, func(c *Ctx) {
|
||||
r.routes = append(r.routes, &Route{"GET", path, wildcard, false, nil, nil, func(c *Ctx) {
|
||||
c.SendFile(filePath, gzip)
|
||||
}})
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// 🔌 Fiber is an Expressjs inspired web framework build on 🚀 Fasthttp.
|
||||
// 🔌 Fiber is an Express.js inspired web framework build on 🚀 Fasthttp.
|
||||
// 📌 Please open an issue if you got suggestions or found a bug!
|
||||
// 🖥 https://github.com/gofiber/fiber
|
||||
|
||||
|
|
6
types.go
6
types.go
|
@ -1,4 +1,4 @@
|
|||
// 🔌 Fiber is an Expressjs inspired web framework build on 🚀 Fasthttp.
|
||||
// 🔌 Fiber is an Express.js inspired web framework build on 🚀 Fasthttp.
|
||||
// 📌 Please open an issue if you got suggestions or found a bug!
|
||||
// 🖥 https://github.com/gofiber/fiber
|
||||
|
||||
|
@ -9,9 +9,9 @@ package fiber
|
|||
|
||||
// common content types
|
||||
const (
|
||||
contentTypeJson = "application/json"
|
||||
contentTypeJSON = "application/json"
|
||||
contentTypeJs = "application/javascript"
|
||||
contentTypeXml = "application/xml"
|
||||
contentTypeXML = "application/xml"
|
||||
contentTypeOctetStream = "application/octet-stream"
|
||||
)
|
||||
|
||||
|
|
8
utils.go
8
utils.go
|
@ -1,4 +1,4 @@
|
|||
// 🔌 Fiber is an Expressjs inspired web framework build on 🚀 Fasthttp.
|
||||
// 🔌 Fiber is an Express.js inspired web framework build on 🚀 Fasthttp.
|
||||
// 📌 Please open an issue if you got suggestions or found a bug!
|
||||
// 🖥 https://github.com/gofiber/fiber
|
||||
|
||||
|
@ -29,6 +29,7 @@ func getParams(path string) (params []string) {
|
|||
}
|
||||
return params
|
||||
}
|
||||
|
||||
func getRegex(path string) (*regexp.Regexp, error) {
|
||||
pattern := "^"
|
||||
segments := strings.Split(path, "/")
|
||||
|
@ -49,6 +50,7 @@ func getRegex(path string) (*regexp.Regexp, error) {
|
|||
regex, err := regexp.Compile(pattern)
|
||||
return regex, err
|
||||
}
|
||||
|
||||
func getFiles(root string) (files []string, isDir bool, err error) {
|
||||
err = filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
|
||||
if !info.IsDir() {
|
||||
|
@ -60,6 +62,7 @@ func getFiles(root string) (files []string, isDir bool, err error) {
|
|||
})
|
||||
return files, isDir, err
|
||||
}
|
||||
|
||||
func getType(ext string) (mime string) {
|
||||
if ext[0] == '.' {
|
||||
ext = ext[1:]
|
||||
|
@ -70,12 +73,15 @@ func getType(ext string) (mime string) {
|
|||
}
|
||||
return mime
|
||||
}
|
||||
|
||||
func getStatus(status int) (msg string) {
|
||||
return statusMessages[status]
|
||||
}
|
||||
|
||||
func getString(b []byte) string {
|
||||
return *(*string)(unsafe.Pointer(&b))
|
||||
}
|
||||
|
||||
func getBytes(s string) []byte {
|
||||
return *(*[]byte)(unsafe.Pointer(&s))
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue