mirror of https://github.com/gofiber/fiber.git
v1.8.0
parent
63353cac7b
commit
2eeb40273c
122
app.go
122
app.go
|
@ -23,7 +23,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// Version of Fiber
|
// Version of Fiber
|
||||||
const Version = "1.7.1"
|
const Version = "1.8.0"
|
||||||
|
|
||||||
type (
|
type (
|
||||||
// App denotes the Fiber application.
|
// App denotes the Fiber application.
|
||||||
|
@ -46,6 +46,8 @@ type (
|
||||||
CaseSensitive bool `default:"false"`
|
CaseSensitive bool `default:"false"`
|
||||||
// Enables the "Server: value" HTTP header.
|
// Enables the "Server: value" HTTP header.
|
||||||
ServerHeader string `default:""`
|
ServerHeader string `default:""`
|
||||||
|
// Enables handler values to be immutable even if you return from handler
|
||||||
|
Immutable bool `default:"false"`
|
||||||
// fasthttp settings
|
// fasthttp settings
|
||||||
GETOnly bool `default:"false"`
|
GETOnly bool `default:"false"`
|
||||||
IdleTimeout time.Duration `default:"0"`
|
IdleTimeout time.Duration `default:"0"`
|
||||||
|
@ -72,19 +74,34 @@ type (
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
var prefork = flag.Bool("fiber-prefork", false, "use prefork")
|
func init() {
|
||||||
var child = flag.Bool("fiber-child", false, "is child process")
|
flag.Bool("prefork", false, "Use prefork")
|
||||||
|
flag.Bool("child", false, "Is a child process")
|
||||||
|
}
|
||||||
|
|
||||||
// New ...
|
// New : https://fiber.wiki/application#new
|
||||||
func New(settings ...*Settings) (app *App) {
|
func New(settings ...*Settings) (app *App) {
|
||||||
flag.Parse()
|
var prefork bool
|
||||||
|
var child bool
|
||||||
|
for _, arg := range os.Args[1:] {
|
||||||
|
if arg == "-prefork" {
|
||||||
|
prefork = true
|
||||||
|
} else if arg == "-child" {
|
||||||
|
child = true
|
||||||
|
}
|
||||||
|
}
|
||||||
app = &App{
|
app = &App{
|
||||||
child: *child,
|
child: child,
|
||||||
}
|
}
|
||||||
if len(settings) > 0 {
|
if len(settings) > 0 {
|
||||||
opt := settings[0]
|
opt := settings[0]
|
||||||
if !opt.Prefork {
|
if !opt.Prefork {
|
||||||
opt.Prefork = *prefork
|
opt.Prefork = prefork
|
||||||
|
}
|
||||||
|
if opt.Immutable {
|
||||||
|
getString = func(b []byte) string {
|
||||||
|
return string(b)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if opt.Concurrency == 0 {
|
if opt.Concurrency == 0 {
|
||||||
opt.Concurrency = 256 * 1024
|
opt.Concurrency = 256 * 1024
|
||||||
|
@ -102,7 +119,7 @@ func New(settings ...*Settings) (app *App) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
app.Settings = &Settings{
|
app.Settings = &Settings{
|
||||||
Prefork: *prefork,
|
Prefork: prefork,
|
||||||
Concurrency: 256 * 1024,
|
Concurrency: 256 * 1024,
|
||||||
ReadBufferSize: 4096,
|
ReadBufferSize: 4096,
|
||||||
WriteBufferSize: 4096,
|
WriteBufferSize: 4096,
|
||||||
|
@ -111,89 +128,89 @@ func New(settings ...*Settings) (app *App) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recover
|
// Recover : https://fiber.wiki/application#recover
|
||||||
func (app *App) Recover(cb func(*Ctx)) {
|
func (app *App) Recover(callback func(*Ctx)) {
|
||||||
app.recover = cb
|
app.recover = callback
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recover
|
// Recover : https://fiber.wiki/application#recover
|
||||||
func (grp *Group) Recover(cb func(*Ctx)) {
|
func (grp *Group) Recover(callback func(*Ctx)) {
|
||||||
grp.app.recover = cb
|
grp.app.recover = callback
|
||||||
}
|
}
|
||||||
|
|
||||||
// Static ...
|
// Static : https://fiber.wiki/application#static
|
||||||
func (app *App) Static(args ...string) *App {
|
func (app *App) Static(args ...string) *App {
|
||||||
app.registerStatic("/", args...)
|
app.registerStatic("/", args...)
|
||||||
return app
|
return app
|
||||||
}
|
}
|
||||||
|
|
||||||
// WebSocket ...
|
// WebSocket : https://fiber.wiki/application#websocket
|
||||||
func (app *App) WebSocket(args ...interface{}) *App {
|
func (app *App) WebSocket(args ...interface{}) *App {
|
||||||
app.register("GET", "", args...)
|
app.register(http.MethodGet, "", args...)
|
||||||
return app
|
return app
|
||||||
}
|
}
|
||||||
|
|
||||||
// Connect ...
|
// Connect : https://fiber.wiki/application#http-methods
|
||||||
func (app *App) Connect(args ...interface{}) *App {
|
func (app *App) Connect(args ...interface{}) *App {
|
||||||
app.register("CONNECT", "", args...)
|
app.register(http.MethodConnect, "", args...)
|
||||||
return app
|
return app
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put ...
|
// Put : https://fiber.wiki/application#http-methods
|
||||||
func (app *App) Put(args ...interface{}) *App {
|
func (app *App) Put(args ...interface{}) *App {
|
||||||
app.register("PUT", "", args...)
|
app.register(http.MethodPut, "", args...)
|
||||||
return app
|
return app
|
||||||
}
|
}
|
||||||
|
|
||||||
// Post ...
|
// Post : https://fiber.wiki/application#http-methods
|
||||||
func (app *App) Post(args ...interface{}) *App {
|
func (app *App) Post(args ...interface{}) *App {
|
||||||
app.register("POST", "", args...)
|
app.register(http.MethodPost, "", args...)
|
||||||
return app
|
return app
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete ...
|
// Delete : https://fiber.wiki/application#http-methods
|
||||||
func (app *App) Delete(args ...interface{}) *App {
|
func (app *App) Delete(args ...interface{}) *App {
|
||||||
app.register("DELETE", "", args...)
|
app.register(http.MethodDelete, "", args...)
|
||||||
return app
|
return app
|
||||||
}
|
}
|
||||||
|
|
||||||
// Head ...
|
// Head : https://fiber.wiki/application#http-methods
|
||||||
func (app *App) Head(args ...interface{}) *App {
|
func (app *App) Head(args ...interface{}) *App {
|
||||||
app.register("HEAD", "", args...)
|
app.register(http.MethodHead, "", args...)
|
||||||
return app
|
return app
|
||||||
}
|
}
|
||||||
|
|
||||||
// Patch ...
|
// Patch : https://fiber.wiki/application#http-methods
|
||||||
func (app *App) Patch(args ...interface{}) *App {
|
func (app *App) Patch(args ...interface{}) *App {
|
||||||
app.register("PATCH", "", args...)
|
app.register(http.MethodPatch, "", args...)
|
||||||
return app
|
return app
|
||||||
}
|
}
|
||||||
|
|
||||||
// Options ...
|
// Options : https://fiber.wiki/application#http-methods
|
||||||
func (app *App) Options(args ...interface{}) *App {
|
func (app *App) Options(args ...interface{}) *App {
|
||||||
app.register("OPTIONS", "", args...)
|
app.register(http.MethodOptions, "", args...)
|
||||||
return app
|
return app
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trace ...
|
// Trace : https://fiber.wiki/application#http-methods
|
||||||
func (app *App) Trace(args ...interface{}) *App {
|
func (app *App) Trace(args ...interface{}) *App {
|
||||||
app.register("TRACE", "", args...)
|
app.register(http.MethodOptions, "", args...)
|
||||||
return app
|
return app
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get ...
|
// Get : https://fiber.wiki/application#http-methods
|
||||||
func (app *App) Get(args ...interface{}) *App {
|
func (app *App) Get(args ...interface{}) *App {
|
||||||
app.register("GET", "", args...)
|
app.register(http.MethodGet, "", args...)
|
||||||
return app
|
return app
|
||||||
}
|
}
|
||||||
|
|
||||||
// All ...
|
// All : https://fiber.wiki/application#http-methods
|
||||||
func (app *App) All(args ...interface{}) *App {
|
func (app *App) All(args ...interface{}) *App {
|
||||||
app.register("ALL", "", args...)
|
app.register("ALL", "", args...)
|
||||||
return app
|
return app
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use ...
|
// Use : https://fiber.wiki/application#http-methods
|
||||||
func (app *App) Use(args ...interface{}) *App {
|
func (app *App) Use(args ...interface{}) *App {
|
||||||
app.register("USE", "", args...)
|
app.register("USE", "", args...)
|
||||||
return app
|
return app
|
||||||
|
@ -214,10 +231,10 @@ func (app *App) Listen(address interface{}, tls ...string) error {
|
||||||
}
|
}
|
||||||
// Create fasthttp server
|
// Create fasthttp server
|
||||||
app.server = app.newServer()
|
app.server = app.newServer()
|
||||||
// Print banner
|
// Print listening message
|
||||||
// if app.Settings.Banner && !app.child {
|
if !app.child {
|
||||||
// fmt.Printf("Fiber-%s is listening on %s\n", Version, addr)
|
fmt.Printf("Fiber v%s listening on %s\n", Version, addr)
|
||||||
// }
|
}
|
||||||
var ln net.Listener
|
var ln net.Listener
|
||||||
var err error
|
var err error
|
||||||
// Prefork enabled
|
// Prefork enabled
|
||||||
|
@ -238,7 +255,8 @@ func (app *App) Listen(address interface{}, tls ...string) error {
|
||||||
return app.server.Serve(ln)
|
return app.server.Serve(ln)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shutdown server gracefully
|
// Shutdown : TODO: Docs
|
||||||
|
// Shutsdown the server gracefully
|
||||||
func (app *App) Shutdown() error {
|
func (app *App) Shutdown() error {
|
||||||
if app.server == nil {
|
if app.server == nil {
|
||||||
return fmt.Errorf("Server is not running")
|
return fmt.Errorf("Server is not running")
|
||||||
|
@ -246,11 +264,10 @@ func (app *App) Shutdown() error {
|
||||||
return app.server.Shutdown()
|
return app.server.Shutdown()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test takes a http.Request and execute a fake connection to the application
|
// Test : https://fiber.wiki/application#test
|
||||||
// It returns a http.Response when the connection was successful
|
func (app *App) Test(request *http.Request) (*http.Response, error) {
|
||||||
func (app *App) Test(req *http.Request) (*http.Response, error) {
|
|
||||||
// Get raw http request
|
// Get raw http request
|
||||||
reqRaw, err := httputil.DumpRequest(req, true)
|
reqRaw, err := httputil.DumpRequest(request, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -287,7 +304,7 @@ func (app *App) Test(req *http.Request) (*http.Response, error) {
|
||||||
reader := strings.NewReader(getString(respRaw))
|
reader := strings.NewReader(getString(respRaw))
|
||||||
buffer := bufio.NewReader(reader)
|
buffer := bufio.NewReader(reader)
|
||||||
// Convert raw HTTP response to http.Response
|
// Convert raw HTTP response to http.Response
|
||||||
resp, err := http.ReadResponse(buffer, req)
|
resp, err := http.ReadResponse(buffer, request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -299,11 +316,11 @@ func (app *App) Test(req *http.Request) (*http.Response, error) {
|
||||||
func (app *App) prefork(address string) (ln net.Listener, err error) {
|
func (app *App) prefork(address string) (ln net.Listener, err error) {
|
||||||
// Master proc
|
// Master proc
|
||||||
if !app.child {
|
if !app.child {
|
||||||
addr, err := net.ResolveTCPAddr("tcp", address)
|
addr, err := net.ResolveTCPAddr("tcp4", address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ln, err
|
return ln, err
|
||||||
}
|
}
|
||||||
tcplistener, err := net.ListenTCP("tcp", addr)
|
tcplistener, err := net.ListenTCP("tcp4", addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ln, err
|
return ln, err
|
||||||
}
|
}
|
||||||
|
@ -311,14 +328,14 @@ func (app *App) prefork(address string) (ln net.Listener, err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ln, err
|
return ln, err
|
||||||
}
|
}
|
||||||
|
files := []*os.File{fl}
|
||||||
childs := make([]*exec.Cmd, runtime.NumCPU()/2)
|
childs := make([]*exec.Cmd, runtime.NumCPU()/2)
|
||||||
|
|
||||||
// #nosec G204
|
// #nosec G204
|
||||||
for i := range childs {
|
for i := range childs {
|
||||||
childs[i] = exec.Command(os.Args[0], "-fiber-prefork", "-fiber-child")
|
childs[i] = exec.Command(os.Args[0], append(os.Args[1:], "-prefork", "-child")...)
|
||||||
childs[i].Stdout = os.Stdout
|
childs[i].Stdout = os.Stdout
|
||||||
childs[i].Stderr = os.Stderr
|
childs[i].Stderr = os.Stderr
|
||||||
childs[i].ExtraFiles = []*os.File{fl}
|
childs[i].ExtraFiles = files
|
||||||
if err := childs[i].Start(); err != nil {
|
if err := childs[i].Start(); err != nil {
|
||||||
return ln, err
|
return ln, err
|
||||||
}
|
}
|
||||||
|
@ -331,6 +348,7 @@ func (app *App) prefork(address string) (ln net.Listener, err error) {
|
||||||
}
|
}
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
} else {
|
} else {
|
||||||
|
runtime.GOMAXPROCS(1)
|
||||||
ln, err = net.FileListener(os.NewFile(3, ""))
|
ln, err = net.FileListener(os.NewFile(3, ""))
|
||||||
}
|
}
|
||||||
return ln, err
|
return ln, err
|
||||||
|
|
368
context.go
368
context.go
|
@ -5,10 +5,8 @@
|
||||||
package fiber
|
package fiber
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
"fmt"
|
"fmt"
|
||||||
"html/template"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"mime"
|
"mime"
|
||||||
|
@ -19,14 +17,8 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
// templates
|
|
||||||
pug "github.com/Joker/jade"
|
|
||||||
handlebars "github.com/aymerick/raymond"
|
|
||||||
mustache "github.com/cbroglie/mustache"
|
|
||||||
amber "github.com/eknkc/amber"
|
|
||||||
|
|
||||||
// core
|
|
||||||
websocket "github.com/fasthttp/websocket"
|
websocket "github.com/fasthttp/websocket"
|
||||||
|
template "github.com/gofiber/template"
|
||||||
jsoniter "github.com/json-iterator/go"
|
jsoniter "github.com/json-iterator/go"
|
||||||
fasthttp "github.com/valyala/fasthttp"
|
fasthttp "github.com/valyala/fasthttp"
|
||||||
)
|
)
|
||||||
|
@ -42,7 +34,6 @@ type Ctx struct {
|
||||||
params *[]string
|
params *[]string
|
||||||
values []string
|
values []string
|
||||||
Fasthttp *fasthttp.RequestCtx
|
Fasthttp *fasthttp.RequestCtx
|
||||||
Socket *websocket.Conn
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ctx pool
|
// Ctx pool
|
||||||
|
@ -67,7 +58,6 @@ func releaseCtx(ctx *Ctx) {
|
||||||
ctx.params = nil
|
ctx.params = nil
|
||||||
ctx.values = nil
|
ctx.values = nil
|
||||||
ctx.Fasthttp = nil
|
ctx.Fasthttp = nil
|
||||||
ctx.Socket = nil
|
|
||||||
poolCtx.Put(ctx)
|
poolCtx.Put(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,18 +105,17 @@ func releaseConn(conn *Conn) {
|
||||||
|
|
||||||
// Cookie : struct
|
// Cookie : struct
|
||||||
type Cookie struct {
|
type Cookie struct {
|
||||||
Expire int // time.Unix(1578981376, 0)
|
Name string
|
||||||
MaxAge int
|
Value string
|
||||||
Domain string
|
Path string
|
||||||
Path string
|
Domain string
|
||||||
|
Expires time.Time
|
||||||
HTTPOnly bool
|
|
||||||
Secure bool
|
Secure bool
|
||||||
SameSite string
|
HTTPOnly bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Accepts : https://fiber.wiki/context#accepts
|
// Accepts : https://fiber.wiki/context#accepts
|
||||||
func (ctx *Ctx) Accepts(offers ...string) string {
|
func (ctx *Ctx) Accepts(offers ...string) (offer string) {
|
||||||
if len(offers) == 0 {
|
if len(offers) == 0 {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
@ -136,8 +125,8 @@ func (ctx *Ctx) Accepts(offers ...string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
specs := strings.Split(h, ",")
|
specs := strings.Split(h, ",")
|
||||||
for _, offer := range offers {
|
for _, value := range offers {
|
||||||
mimetype := getType(offer)
|
mimetype := getType(value)
|
||||||
// if mimetype != "" {
|
// if mimetype != "" {
|
||||||
// mimetype = strings.Split(mimetype, ";")[0]
|
// mimetype = strings.Split(mimetype, ";")[0]
|
||||||
// } else {
|
// } else {
|
||||||
|
@ -146,16 +135,16 @@ func (ctx *Ctx) Accepts(offers ...string) string {
|
||||||
for _, spec := range specs {
|
for _, spec := range specs {
|
||||||
spec = strings.TrimSpace(spec)
|
spec = strings.TrimSpace(spec)
|
||||||
if strings.HasPrefix(spec, "*/*") {
|
if strings.HasPrefix(spec, "*/*") {
|
||||||
return offer
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.HasPrefix(spec, mimetype) {
|
if strings.HasPrefix(spec, mimetype) {
|
||||||
return offer
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.Contains(spec, "/*") {
|
if strings.Contains(spec, "/*") {
|
||||||
if strings.HasPrefix(spec, strings.Split(mimetype, "/")[0]) {
|
if strings.HasPrefix(spec, strings.Split(mimetype, "/")[0]) {
|
||||||
return offer
|
return value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -164,7 +153,7 @@ func (ctx *Ctx) Accepts(offers ...string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// AcceptsCharsets : https://fiber.wiki/context#acceptscharsets
|
// AcceptsCharsets : https://fiber.wiki/context#acceptscharsets
|
||||||
func (ctx *Ctx) AcceptsCharsets(offers ...string) string {
|
func (ctx *Ctx) AcceptsCharsets(offers ...string) (offer string) {
|
||||||
if len(offers) == 0 {
|
if len(offers) == 0 {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
@ -175,14 +164,14 @@ func (ctx *Ctx) AcceptsCharsets(offers ...string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
specs := strings.Split(h, ",")
|
specs := strings.Split(h, ",")
|
||||||
for _, offer := range offers {
|
for _, value := range offers {
|
||||||
for _, spec := range specs {
|
for _, spec := range specs {
|
||||||
spec = strings.TrimSpace(spec)
|
spec = strings.TrimSpace(spec)
|
||||||
if strings.HasPrefix(spec, "*") {
|
if strings.HasPrefix(spec, "*") {
|
||||||
return offer
|
return value
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(spec, offer) {
|
if strings.HasPrefix(spec, value) {
|
||||||
return offer
|
return value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -190,7 +179,7 @@ func (ctx *Ctx) AcceptsCharsets(offers ...string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// AcceptsEncodings : https://fiber.wiki/context#acceptsencodings
|
// AcceptsEncodings : https://fiber.wiki/context#acceptsencodings
|
||||||
func (ctx *Ctx) AcceptsEncodings(offers ...string) string {
|
func (ctx *Ctx) AcceptsEncodings(offers ...string) (offer string) {
|
||||||
if len(offers) == 0 {
|
if len(offers) == 0 {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
@ -201,14 +190,14 @@ func (ctx *Ctx) AcceptsEncodings(offers ...string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
specs := strings.Split(h, ",")
|
specs := strings.Split(h, ",")
|
||||||
for _, offer := range offers {
|
for _, value := range offers {
|
||||||
for _, spec := range specs {
|
for _, spec := range specs {
|
||||||
spec = strings.TrimSpace(spec)
|
spec = strings.TrimSpace(spec)
|
||||||
if strings.HasPrefix(spec, "*") {
|
if strings.HasPrefix(spec, "*") {
|
||||||
return offer
|
return value
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(spec, offer) {
|
if strings.HasPrefix(spec, value) {
|
||||||
return offer
|
return value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -216,7 +205,7 @@ func (ctx *Ctx) AcceptsEncodings(offers ...string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// AcceptsLanguages : https://fiber.wiki/context#acceptslanguages
|
// AcceptsLanguages : https://fiber.wiki/context#acceptslanguages
|
||||||
func (ctx *Ctx) AcceptsLanguages(offers ...string) string {
|
func (ctx *Ctx) AcceptsLanguages(offers ...string) (offer string) {
|
||||||
if len(offers) == 0 {
|
if len(offers) == 0 {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
@ -226,14 +215,14 @@ func (ctx *Ctx) AcceptsLanguages(offers ...string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
specs := strings.Split(h, ",")
|
specs := strings.Split(h, ",")
|
||||||
for _, offer := range offers {
|
for _, value := range offers {
|
||||||
for _, spec := range specs {
|
for _, spec := range specs {
|
||||||
spec = strings.TrimSpace(spec)
|
spec = strings.TrimSpace(spec)
|
||||||
if strings.HasPrefix(spec, "*") {
|
if strings.HasPrefix(spec, "*") {
|
||||||
return offer
|
return value
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(spec, offer) {
|
if strings.HasPrefix(spec, value) {
|
||||||
return offer
|
return value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -273,38 +262,29 @@ func (ctx *Ctx) BaseURL() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Body : https://fiber.wiki/context#body
|
// Body : https://fiber.wiki/context#body
|
||||||
func (ctx *Ctx) Body(args ...interface{}) string {
|
func (ctx *Ctx) Body(key ...string) string {
|
||||||
if len(args) == 0 {
|
// Return request body
|
||||||
|
if len(key) == 0 {
|
||||||
return getString(ctx.Fasthttp.Request.Body())
|
return getString(ctx.Fasthttp.Request.Body())
|
||||||
}
|
}
|
||||||
|
// Return post value by key
|
||||||
if len(args) == 1 {
|
if len(key) > 0 {
|
||||||
switch arg := args[0].(type) {
|
return getString(ctx.Fasthttp.Request.PostArgs().Peek(key[0]))
|
||||||
case string:
|
|
||||||
return getString(ctx.Fasthttp.Request.PostArgs().Peek(arg))
|
|
||||||
case []byte:
|
|
||||||
return getString(ctx.Fasthttp.Request.PostArgs().PeekBytes(arg))
|
|
||||||
case func(string, string):
|
|
||||||
ctx.Fasthttp.Request.PostArgs().VisitAll(func(k []byte, v []byte) {
|
|
||||||
arg(getString(k), getString(v))
|
|
||||||
})
|
|
||||||
default:
|
|
||||||
return getString(ctx.Fasthttp.Request.Body())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// BodyParser : https://fiber.wiki/context#bodyparser
|
// BodyParser : https://fiber.wiki/context#bodyparser
|
||||||
func (ctx *Ctx) BodyParser(v interface{}) error {
|
func (ctx *Ctx) BodyParser(out interface{}) error {
|
||||||
|
// TODO : Query Params
|
||||||
ctype := getString(ctx.Fasthttp.Request.Header.ContentType())
|
ctype := getString(ctx.Fasthttp.Request.Header.ContentType())
|
||||||
// application/json
|
// application/json
|
||||||
if strings.HasPrefix(ctype, MIMEApplicationJSON) {
|
if strings.HasPrefix(ctype, MIMEApplicationJSON) {
|
||||||
return jsoniter.Unmarshal(ctx.Fasthttp.Request.Body(), v)
|
return jsoniter.Unmarshal(ctx.Fasthttp.Request.Body(), out)
|
||||||
}
|
}
|
||||||
// application/xml text/xml
|
// application/xml text/xml
|
||||||
if strings.HasPrefix(ctype, MIMEApplicationXML) || strings.HasPrefix(ctype, MIMETextXML) {
|
if strings.HasPrefix(ctype, MIMEApplicationXML) || strings.HasPrefix(ctype, MIMETextXML) {
|
||||||
return xml.Unmarshal(ctx.Fasthttp.Request.Body(), v)
|
return xml.Unmarshal(ctx.Fasthttp.Request.Body(), out)
|
||||||
}
|
}
|
||||||
// application/x-www-form-urlencoded
|
// application/x-www-form-urlencoded
|
||||||
if strings.HasPrefix(ctype, MIMEApplicationForm) {
|
if strings.HasPrefix(ctype, MIMEApplicationForm) {
|
||||||
|
@ -312,7 +292,7 @@ func (ctx *Ctx) BodyParser(v interface{}) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return schemaDecoder.Decode(v, data)
|
return schemaDecoder.Decode(out, data)
|
||||||
}
|
}
|
||||||
// multipart/form-data
|
// multipart/form-data
|
||||||
if strings.HasPrefix(ctype, MIMEMultipartForm) {
|
if strings.HasPrefix(ctype, MIMEMultipartForm) {
|
||||||
|
@ -320,18 +300,18 @@ func (ctx *Ctx) BodyParser(v interface{}) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return schemaDecoder.Decode(v, data.Value)
|
return schemaDecoder.Decode(out, data.Value)
|
||||||
|
|
||||||
}
|
}
|
||||||
return fmt.Errorf("cannot parse content-type: %v", ctype)
|
return fmt.Errorf("BodyParser: cannot parse content-type: %v", ctype)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClearCookie : https://fiber.wiki/context#clearcookie
|
// ClearCookie : https://fiber.wiki/context#clearcookie
|
||||||
func (ctx *Ctx) ClearCookie(name ...string) {
|
func (ctx *Ctx) ClearCookie(key ...string) {
|
||||||
if len(name) > 0 {
|
if len(key) > 0 {
|
||||||
for i := range name {
|
for i := range key {
|
||||||
//ctx.Fasthttp.Request.Header.DelAllCookies()
|
//ctx.Fasthttp.Request.Header.DelAllCookies()
|
||||||
ctx.Fasthttp.Response.Header.DelClientCookie(name[i])
|
ctx.Fasthttp.Response.Header.DelClientCookie(key[i])
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -342,75 +322,24 @@ func (ctx *Ctx) ClearCookie(name ...string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cookie : https://fiber.wiki/context#cookie
|
// Cookie : https://fiber.wiki/context#cookie
|
||||||
func (ctx *Ctx) Cookie(key, value string, options ...interface{}) {
|
func (ctx *Ctx) Cookie(cookie *Cookie) {
|
||||||
cook := &fasthttp.Cookie{}
|
fcookie := &fasthttp.Cookie{}
|
||||||
|
fcookie.SetKey(cookie.Name)
|
||||||
cook.SetKey(key)
|
fcookie.SetValue(cookie.Value)
|
||||||
cook.SetValue(value)
|
fcookie.SetPath(cookie.Path)
|
||||||
|
fcookie.SetDomain(cookie.Domain)
|
||||||
if len(options) > 0 {
|
fcookie.SetExpire(cookie.Expires)
|
||||||
switch opt := options[0].(type) {
|
fcookie.SetSecure(cookie.Secure)
|
||||||
case *Cookie:
|
fcookie.SetHTTPOnly(cookie.HTTPOnly)
|
||||||
if opt.Expire > 0 {
|
ctx.Fasthttp.Response.Header.SetCookie(fcookie)
|
||||||
cook.SetExpire(time.Unix(int64(opt.Expire), 0))
|
|
||||||
}
|
|
||||||
if opt.MaxAge > 0 {
|
|
||||||
cook.SetMaxAge(opt.MaxAge)
|
|
||||||
}
|
|
||||||
if opt.Domain != "" {
|
|
||||||
cook.SetDomain(opt.Domain)
|
|
||||||
}
|
|
||||||
if opt.Path != "" {
|
|
||||||
cook.SetPath(opt.Path)
|
|
||||||
}
|
|
||||||
if opt.HTTPOnly {
|
|
||||||
cook.SetHTTPOnly(opt.HTTPOnly)
|
|
||||||
}
|
|
||||||
if opt.Secure {
|
|
||||||
cook.SetSecure(opt.Secure)
|
|
||||||
}
|
|
||||||
if opt.SameSite != "" {
|
|
||||||
sameSite := fasthttp.CookieSameSiteDefaultMode
|
|
||||||
if strings.EqualFold(opt.SameSite, "lax") {
|
|
||||||
sameSite = fasthttp.CookieSameSiteLaxMode
|
|
||||||
} else if strings.EqualFold(opt.SameSite, "strict") {
|
|
||||||
sameSite = fasthttp.CookieSameSiteStrictMode
|
|
||||||
} else if strings.EqualFold(opt.SameSite, "none") {
|
|
||||||
sameSite = fasthttp.CookieSameSiteNoneMode
|
|
||||||
}
|
|
||||||
// } else {
|
|
||||||
// sameSite = fasthttp.CookieSameSiteDisabled
|
|
||||||
// }
|
|
||||||
cook.SetSameSite(sameSite)
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
log.Println("Cookie: Invalid &Cookie{} struct")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.Fasthttp.Response.Header.SetCookie(cook)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cookies : https://fiber.wiki/context#cookies
|
// Cookies : https://fiber.wiki/context#cookies
|
||||||
func (ctx *Ctx) Cookies(args ...interface{}) string {
|
func (ctx *Ctx) Cookies(key ...string) (value string) {
|
||||||
if len(args) == 0 {
|
if len(key) == 0 {
|
||||||
return ctx.Get(fasthttp.HeaderCookie)
|
return ctx.Get(fasthttp.HeaderCookie)
|
||||||
}
|
}
|
||||||
|
return getString(ctx.Fasthttp.Request.Header.Cookie(key[0]))
|
||||||
switch arg := args[0].(type) {
|
|
||||||
case string:
|
|
||||||
return getString(ctx.Fasthttp.Request.Header.Cookie(arg))
|
|
||||||
case []byte:
|
|
||||||
return getString(ctx.Fasthttp.Request.Header.CookieBytes(arg))
|
|
||||||
case func(string, string):
|
|
||||||
ctx.Fasthttp.Request.Header.VisitAllCookie(func(k, v []byte) {
|
|
||||||
arg(getString(k), getString(v))
|
|
||||||
})
|
|
||||||
default:
|
|
||||||
return ctx.Get(fasthttp.HeaderCookie)
|
|
||||||
}
|
|
||||||
|
|
||||||
return ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Download : https://fiber.wiki/context#download
|
// Download : https://fiber.wiki/context#download
|
||||||
|
@ -431,30 +360,27 @@ func (ctx *Ctx) Error() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Format : https://fiber.wiki/context#format
|
// Format : https://fiber.wiki/context#format
|
||||||
func (ctx *Ctx) Format(args ...interface{}) {
|
func (ctx *Ctx) Format(body interface{}) {
|
||||||
var body string
|
var b string
|
||||||
|
|
||||||
accept := ctx.Accepts("html", "json")
|
accept := ctx.Accepts("html", "json")
|
||||||
|
|
||||||
for i := range args {
|
switch val := body.(type) {
|
||||||
switch arg := args[i].(type) {
|
case string:
|
||||||
case string:
|
b = val
|
||||||
body = arg
|
case []byte:
|
||||||
case []byte:
|
b = getString(val)
|
||||||
body = getString(arg)
|
default:
|
||||||
default:
|
b = fmt.Sprintf("%v", val)
|
||||||
body = fmt.Sprintf("%v", arg)
|
}
|
||||||
}
|
switch accept {
|
||||||
switch accept {
|
case "html":
|
||||||
case "html":
|
ctx.SendString("<p>" + b + "</p>")
|
||||||
ctx.SendString("<p>" + body + "</p>")
|
case "json":
|
||||||
case "json":
|
if err := ctx.JSON(body); err != nil {
|
||||||
if err := ctx.JSON(body); err != nil {
|
log.Println("Format: error serializing json ", err)
|
||||||
log.Println("Format: error serializing json ", err)
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
ctx.SendString(body)
|
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
ctx.SendString(b)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -464,7 +390,7 @@ func (ctx *Ctx) FormFile(key string) (*multipart.FileHeader, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// FormValue : https://fiber.wiki/context#formvalue
|
// FormValue : https://fiber.wiki/context#formvalue
|
||||||
func (ctx *Ctx) FormValue(key string) string {
|
func (ctx *Ctx) FormValue(key string) (value string) {
|
||||||
return getString(ctx.Fasthttp.FormValue(key))
|
return getString(ctx.Fasthttp.FormValue(key))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -474,7 +400,7 @@ func (ctx *Ctx) Fresh() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get : https://fiber.wiki/context#get
|
// Get : https://fiber.wiki/context#get
|
||||||
func (ctx *Ctx) Get(key string) string {
|
func (ctx *Ctx) Get(key string) (value string) {
|
||||||
if key == "referrer" {
|
if key == "referrer" {
|
||||||
key = "referer"
|
key = "referer"
|
||||||
}
|
}
|
||||||
|
@ -501,26 +427,26 @@ func (ctx *Ctx) IPs() []string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is : https://fiber.wiki/context#is
|
// Is : https://fiber.wiki/context#is
|
||||||
func (ctx *Ctx) Is(ext string) bool {
|
func (ctx *Ctx) Is(extension string) (match bool) {
|
||||||
if ext[0] != '.' {
|
if extension[0] != '.' {
|
||||||
ext = "." + ext
|
extension = "." + extension
|
||||||
}
|
}
|
||||||
|
|
||||||
exts, _ := mime.ExtensionsByType(ctx.Get(fasthttp.HeaderContentType))
|
exts, _ := mime.ExtensionsByType(ctx.Get(fasthttp.HeaderContentType))
|
||||||
if len(exts) > 0 {
|
if len(exts) > 0 {
|
||||||
for _, item := range exts {
|
for _, item := range exts {
|
||||||
if item == ext {
|
if item == extension {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// JSON : https://fiber.wiki/context#json
|
// JSON : https://fiber.wiki/context#json
|
||||||
func (ctx *Ctx) JSON(v interface{}) error {
|
func (ctx *Ctx) JSON(json interface{}) error {
|
||||||
ctx.Fasthttp.Response.Header.SetContentType(MIMEApplicationJSON)
|
ctx.Fasthttp.Response.Header.SetContentType(MIMEApplicationJSON)
|
||||||
raw, err := jsoniter.Marshal(&v)
|
raw, err := jsoniter.Marshal(&json)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Fasthttp.Response.SetBodyString("")
|
ctx.Fasthttp.Response.SetBodyString("")
|
||||||
return err
|
return err
|
||||||
|
@ -531,15 +457,15 @@ func (ctx *Ctx) JSON(v interface{}) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// JSONP : https://fiber.wiki/context#jsonp
|
// JSONP : https://fiber.wiki/context#jsonp
|
||||||
func (ctx *Ctx) JSONP(v interface{}, cb ...string) error {
|
func (ctx *Ctx) JSONP(json interface{}, callback ...string) error {
|
||||||
raw, err := jsoniter.Marshal(&v)
|
raw, err := jsoniter.Marshal(&json)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
str := "callback("
|
str := "callback("
|
||||||
if len(cb) > 0 {
|
if len(callback) > 0 {
|
||||||
str = cb[0] + "("
|
str = callback[0] + "("
|
||||||
}
|
}
|
||||||
str += getString(raw) + ");"
|
str += getString(raw) + ");"
|
||||||
|
|
||||||
|
@ -568,12 +494,12 @@ func (ctx *Ctx) Links(link ...string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Locals : https://fiber.wiki/context#locals
|
// Locals : https://fiber.wiki/context#locals
|
||||||
func (ctx *Ctx) Locals(key string, val ...interface{}) interface{} {
|
func (ctx *Ctx) Locals(key string, value ...interface{}) (val interface{}) {
|
||||||
if len(val) == 0 {
|
if len(value) == 0 {
|
||||||
return ctx.Fasthttp.UserValue(key)
|
return ctx.Fasthttp.UserValue(key)
|
||||||
}
|
}
|
||||||
ctx.Fasthttp.SetUserValue(key, val[0])
|
ctx.Fasthttp.SetUserValue(key, value[0])
|
||||||
return nil
|
return value[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Location : https://fiber.wiki/context#location
|
// Location : https://fiber.wiki/context#location
|
||||||
|
@ -608,16 +534,16 @@ func (ctx *Ctx) OriginalURL() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Params : https://fiber.wiki/context#params
|
// Params : https://fiber.wiki/context#params
|
||||||
func (ctx *Ctx) Params(key string) string {
|
func (ctx *Ctx) Params(key string) (value string) {
|
||||||
if ctx.params == nil {
|
if ctx.params == nil {
|
||||||
return ""
|
return
|
||||||
}
|
}
|
||||||
for i := 0; i < len(*ctx.params); i++ {
|
for i := 0; i < len(*ctx.params); i++ {
|
||||||
if (*ctx.params)[i] == key {
|
if (*ctx.params)[i] == key {
|
||||||
return ctx.values[i]
|
return ctx.values[i]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ""
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Path : https://fiber.wiki/context#path
|
// Path : https://fiber.wiki/context#path
|
||||||
|
@ -634,7 +560,7 @@ func (ctx *Ctx) Protocol() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Query : https://fiber.wiki/context#query
|
// Query : https://fiber.wiki/context#query
|
||||||
func (ctx *Ctx) Query(key string) string {
|
func (ctx *Ctx) Query(key string) (value string) {
|
||||||
return getString(ctx.Fasthttp.QueryArgs().Peek(key))
|
return getString(ctx.Fasthttp.QueryArgs().Peek(key))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -642,7 +568,7 @@ func (ctx *Ctx) Query(key string) string {
|
||||||
func (ctx *Ctx) Range() {
|
func (ctx *Ctx) Range() {
|
||||||
// https://expressjs.com/en/api.html#req.range
|
// https://expressjs.com/en/api.html#req.range
|
||||||
// https://github.com/jshttp/range-parser/blob/master/index.js
|
// https://github.com/jshttp/range-parser/blob/master/index.js
|
||||||
// r := ctx.Fasthttp.Request.Header.Peek(fasthttp.HeaderRange)
|
// r := ctx.Fasthttp.Request.Header.Peek(HeaderRange)
|
||||||
// *magic*
|
// *magic*
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -658,18 +584,18 @@ func (ctx *Ctx) Redirect(path string, status ...int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render : https://fiber.wiki/context#render
|
// Render : https://fiber.wiki/context#render
|
||||||
func (ctx *Ctx) Render(file string, data interface{}, e ...string) error {
|
func (ctx *Ctx) Render(file string, bind interface{}, engine ...string) error {
|
||||||
var err error
|
var err error
|
||||||
var raw []byte
|
var raw []byte
|
||||||
var html string
|
var html string
|
||||||
var engine string
|
var e string
|
||||||
|
|
||||||
if len(e) > 0 {
|
if len(engine) > 0 {
|
||||||
engine = e[0]
|
e = engine[0]
|
||||||
} else if ctx.app.Settings.ViewEngine != "" {
|
} else if ctx.app.Settings.ViewEngine != "" {
|
||||||
engine = ctx.app.Settings.ViewEngine
|
e = ctx.app.Settings.ViewEngine
|
||||||
} else {
|
} else {
|
||||||
engine = filepath.Ext(file)[1:]
|
e = filepath.Ext(file)[1:]
|
||||||
}
|
}
|
||||||
if ctx.app.Settings.ViewFolder != "" {
|
if ctx.app.Settings.ViewFolder != "" {
|
||||||
file = filepath.Join(ctx.app.Settings.ViewFolder, file)
|
file = filepath.Join(ctx.app.Settings.ViewFolder, file)
|
||||||
|
@ -681,53 +607,27 @@ func (ctx *Ctx) Render(file string, data interface{}, e ...string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
switch engine {
|
switch e {
|
||||||
case "amber": // https://github.com/eknkc/amber
|
case "amber": // https://github.com/eknkc/amber
|
||||||
var buf bytes.Buffer
|
if html, err = template.Amber(getString(raw), bind); err != nil {
|
||||||
var tmpl *template.Template
|
|
||||||
|
|
||||||
if tmpl, err = amber.Compile(getString(raw), amber.DefaultOptions); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err = tmpl.Execute(&buf, data); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
html = buf.String()
|
|
||||||
|
|
||||||
case "handlebars": // https://github.com/aymerick/raymond
|
case "handlebars": // https://github.com/aymerick/raymond
|
||||||
if html, err = handlebars.Render(getString(raw), data); err != nil {
|
if html, err = template.Handlebars(getString(raw), bind); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
case "mustache": // https://github.com/cbroglie/mustache
|
case "mustache": // https://github.com/cbroglie/mustache
|
||||||
if html, err = mustache.Render(getString(raw), data); err != nil {
|
if html, err = template.Mustache(getString(raw), bind); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
case "pug": // https://github.com/Joker/jade
|
case "pug": // https://github.com/Joker/jade
|
||||||
var parsed string
|
if html, err = template.Pug(getString(raw), bind); err != nil {
|
||||||
var buf bytes.Buffer
|
|
||||||
var tmpl *template.Template
|
|
||||||
if parsed, err = pug.Parse("", raw); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if tmpl, err = template.New("").Parse(parsed); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err = tmpl.Execute(&buf, data); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
html = buf.String()
|
|
||||||
|
|
||||||
default: // https://golang.org/pkg/text/template/
|
default: // https://golang.org/pkg/text/template/
|
||||||
var buf bytes.Buffer
|
if html, err = template.HTML(getString(raw), bind); err != nil {
|
||||||
var tmpl *template.Template
|
|
||||||
|
|
||||||
if tmpl, err = template.New("").Parse(getString(raw)); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err = tmpl.Execute(&buf, data); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
html = buf.String()
|
|
||||||
}
|
}
|
||||||
ctx.Set("Content-Type", "text/html")
|
ctx.Set("Content-Type", "text/html")
|
||||||
ctx.SendString(html)
|
ctx.SendString(html)
|
||||||
|
@ -740,8 +640,8 @@ func (ctx *Ctx) Route() *Route {
|
||||||
}
|
}
|
||||||
|
|
||||||
// SaveFile : https://fiber.wiki/context#secure
|
// SaveFile : https://fiber.wiki/context#secure
|
||||||
func (ctx *Ctx) SaveFile(fh *multipart.FileHeader, path string) error {
|
func (ctx *Ctx) SaveFile(fileheader *multipart.FileHeader, path string) error {
|
||||||
return fasthttp.SaveMultipartFile(fh, path)
|
return fasthttp.SaveMultipartFile(fileheader, path)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Secure : https://fiber.wiki/context#secure
|
// Secure : https://fiber.wiki/context#secure
|
||||||
|
@ -750,18 +650,19 @@ func (ctx *Ctx) Secure() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send : https://fiber.wiki/context#send
|
// Send : https://fiber.wiki/context#send
|
||||||
func (ctx *Ctx) Send(args ...interface{}) {
|
func (ctx *Ctx) Send(bodies ...interface{}) {
|
||||||
if len(args) == 0 {
|
// if len(bodies) > 0 {
|
||||||
return
|
// ctx.Fasthttp.Response.SetBodyString("")
|
||||||
}
|
// }
|
||||||
|
for i := range bodies {
|
||||||
switch body := args[0].(type) {
|
switch body := bodies[i].(type) {
|
||||||
case string:
|
case string:
|
||||||
ctx.Fasthttp.Response.SetBodyString(body)
|
ctx.Fasthttp.Response.AppendBodyString(body)
|
||||||
case []byte:
|
case []byte:
|
||||||
ctx.Fasthttp.Response.SetBodyString(getString(body))
|
ctx.Fasthttp.Response.AppendBodyString(getString(body))
|
||||||
default:
|
default:
|
||||||
ctx.Fasthttp.Response.SetBodyString(fmt.Sprintf("%v", body))
|
ctx.Fasthttp.Response.AppendBodyString(fmt.Sprintf("%v", body))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -803,19 +704,14 @@ func (ctx *Ctx) Set(key string, val string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Subdomains : https://fiber.wiki/context#subdomains
|
// Subdomains : https://fiber.wiki/context#subdomains
|
||||||
func (ctx *Ctx) Subdomains(offset ...int) (subs []string) {
|
func (ctx *Ctx) Subdomains(offset ...int) []string {
|
||||||
o := 2
|
o := 2
|
||||||
if len(offset) > 0 {
|
if len(offset) > 0 {
|
||||||
o = offset[0]
|
o = offset[0]
|
||||||
}
|
}
|
||||||
subs = strings.Split(ctx.Hostname(), ".")
|
subdomains := strings.Split(ctx.Hostname(), ".")
|
||||||
subs = subs[:len(subs)-o]
|
subdomains = subdomains[:len(subdomains)-o]
|
||||||
return subs
|
return subdomains
|
||||||
}
|
|
||||||
|
|
||||||
// SignedCookies : https://fiber.wiki/context#signedcookies
|
|
||||||
func (ctx *Ctx) SignedCookies() {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stale : https://fiber.wiki/context#stale
|
// Stale : https://fiber.wiki/context#stale
|
||||||
|
@ -854,9 +750,9 @@ func (ctx *Ctx) Vary(fields ...string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write : https://fiber.wiki/context#write
|
// Write : https://fiber.wiki/context#write
|
||||||
func (ctx *Ctx) Write(args ...interface{}) {
|
func (ctx *Ctx) Write(bodies ...interface{}) {
|
||||||
for i := range args {
|
for i := range bodies {
|
||||||
switch body := args[i].(type) {
|
switch body := bodies[i].(type) {
|
||||||
case string:
|
case string:
|
||||||
ctx.Fasthttp.Response.AppendBodyString(body)
|
ctx.Fasthttp.Response.AppendBodyString(body)
|
||||||
case []byte:
|
case []byte:
|
||||||
|
|
|
@ -15,6 +15,7 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_Accepts(t *testing.T) {
|
func Test_Accepts(t *testing.T) {
|
||||||
|
@ -129,7 +130,6 @@ func Test_BaseURL(t *testing.T) {
|
||||||
func Test_Body(t *testing.T) {
|
func Test_Body(t *testing.T) {
|
||||||
app := New()
|
app := New()
|
||||||
app.Post("/test", func(c *Ctx) {
|
app.Post("/test", func(c *Ctx) {
|
||||||
c.Body(1)
|
|
||||||
expect := "john=doe"
|
expect := "john=doe"
|
||||||
result := c.Body()
|
result := c.Body()
|
||||||
if result != expect {
|
if result != expect {
|
||||||
|
@ -140,21 +140,6 @@ func Test_Body(t *testing.T) {
|
||||||
if result != expect {
|
if result != expect {
|
||||||
t.Fatalf(`%s: Expecting %s, got %s`, t.Name(), expect, result)
|
t.Fatalf(`%s: Expecting %s, got %s`, t.Name(), expect, result)
|
||||||
}
|
}
|
||||||
expect = "doe"
|
|
||||||
result = c.Body([]byte("john"))
|
|
||||||
if result != expect {
|
|
||||||
t.Fatalf(`%s: Expecting %s, got %s`, t.Name(), expect, result)
|
|
||||||
}
|
|
||||||
c.Body(func(k, v string) {
|
|
||||||
expect = "john"
|
|
||||||
if k != "john" {
|
|
||||||
t.Fatalf(`%s: Expecting %s, got %s`, t.Name(), expect, k)
|
|
||||||
}
|
|
||||||
expect = "doe"
|
|
||||||
if v != "doe" {
|
|
||||||
t.Fatalf(`%s: Expecting %s, got %s`, t.Name(), expect, v)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
data := url.Values{}
|
data := url.Values{}
|
||||||
data.Set("john", "doe")
|
data.Set("john", "doe")
|
||||||
|
@ -196,7 +181,6 @@ func Test_BodyParser(t *testing.T) {
|
||||||
func Test_Cookies(t *testing.T) {
|
func Test_Cookies(t *testing.T) {
|
||||||
app := New()
|
app := New()
|
||||||
app.Get("/test", func(c *Ctx) {
|
app.Get("/test", func(c *Ctx) {
|
||||||
c.Cookies(1)
|
|
||||||
expect := "john=doe"
|
expect := "john=doe"
|
||||||
result := c.Cookies()
|
result := c.Cookies()
|
||||||
if result != expect {
|
if result != expect {
|
||||||
|
@ -207,21 +191,6 @@ func Test_Cookies(t *testing.T) {
|
||||||
if result != expect {
|
if result != expect {
|
||||||
t.Fatalf(`%s: Expecting %s, got %s`, t.Name(), expect, result)
|
t.Fatalf(`%s: Expecting %s, got %s`, t.Name(), expect, result)
|
||||||
}
|
}
|
||||||
expect = "doe"
|
|
||||||
result = c.Cookies([]byte("john"))
|
|
||||||
if result != expect {
|
|
||||||
t.Fatalf(`%s: Expecting %s, got %s`, t.Name(), expect, result)
|
|
||||||
}
|
|
||||||
c.Cookies(func(k, v string) {
|
|
||||||
expect = "john"
|
|
||||||
if k != "john" {
|
|
||||||
t.Fatalf(`%s: Expecting %s, got %s`, t.Name(), expect, k)
|
|
||||||
}
|
|
||||||
expect = "doe"
|
|
||||||
if v != "doe" {
|
|
||||||
t.Fatalf(`%s: Expecting %s, got %s`, t.Name(), expect, v)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
req, _ := http.NewRequest("GET", "/test", nil)
|
req, _ := http.NewRequest("GET", "/test", nil)
|
||||||
|
@ -621,20 +590,6 @@ func Test_Secure(t *testing.T) {
|
||||||
t.Fatalf(`%s: StatusCode %v`, t.Name(), resp.StatusCode)
|
t.Fatalf(`%s: StatusCode %v`, t.Name(), resp.StatusCode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func Test_SignedCookies(t *testing.T) {
|
|
||||||
app := New()
|
|
||||||
app.Get("/test", func(c *Ctx) {
|
|
||||||
c.SignedCookies()
|
|
||||||
})
|
|
||||||
req, _ := http.NewRequest("GET", "/test", nil)
|
|
||||||
resp, err := app.Test(req)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf(`%s: %s`, t.Name(), err)
|
|
||||||
}
|
|
||||||
if resp.StatusCode != 200 {
|
|
||||||
t.Fatalf(`%s: StatusCode %v`, t.Name(), resp.StatusCode)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
func Test_Stale(t *testing.T) {
|
func Test_Stale(t *testing.T) {
|
||||||
app := New()
|
app := New()
|
||||||
app.Get("/test", func(c *Ctx) {
|
app.Get("/test", func(c *Ctx) {
|
||||||
|
@ -758,16 +713,16 @@ func Test_ClearCookie(t *testing.T) {
|
||||||
}
|
}
|
||||||
func Test_Cookie(t *testing.T) {
|
func Test_Cookie(t *testing.T) {
|
||||||
app := New()
|
app := New()
|
||||||
|
expire := time.Now().Add(24 * time.Hour)
|
||||||
|
var dst []byte
|
||||||
|
dst = expire.In(time.UTC).AppendFormat(dst, time.RFC1123)
|
||||||
|
httpdate := strings.Replace(string(dst), "UTC", "GMT", -1)
|
||||||
app.Get("/test", func(c *Ctx) {
|
app.Get("/test", func(c *Ctx) {
|
||||||
options := &Cookie{
|
cookie := new(Cookie)
|
||||||
MaxAge: 60,
|
cookie.Name = "username"
|
||||||
Domain: "example.com",
|
cookie.Value = "jon"
|
||||||
Path: "/",
|
cookie.Expires = expire
|
||||||
HTTPOnly: true,
|
c.Cookie(cookie)
|
||||||
Secure: false,
|
|
||||||
SameSite: "lax",
|
|
||||||
}
|
|
||||||
c.Cookie("name", "john", options)
|
|
||||||
})
|
})
|
||||||
req, _ := http.NewRequest("GET", "http://example.com/test", nil)
|
req, _ := http.NewRequest("GET", "http://example.com/test", nil)
|
||||||
resp, err := app.Test(req)
|
resp, err := app.Test(req)
|
||||||
|
@ -777,8 +732,8 @@ func Test_Cookie(t *testing.T) {
|
||||||
if resp.StatusCode != 200 {
|
if resp.StatusCode != 200 {
|
||||||
t.Fatalf(`%s: StatusCode %v`, t.Name(), resp.StatusCode)
|
t.Fatalf(`%s: StatusCode %v`, t.Name(), resp.StatusCode)
|
||||||
}
|
}
|
||||||
if !strings.Contains(resp.Header.Get("Set-Cookie"), "name=john; max-age=60; domain=example.com; path=/; HttpOnly; SameSite=Lax") {
|
if !strings.Contains(resp.Header.Get("Set-Cookie"), "username=jon; expires="+string(httpdate)+"; path=/") {
|
||||||
t.Fatalf(`%s: Expecting %s`, t.Name(), "name=john; max-age=60; domain=example.com; path=/; HttpOnly; SameSite=Lax")
|
t.Fatalf(`%s: Expecting %s`, t.Name(), "username=jon; expires="+string(httpdate)+"; path=/")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func Test_Download(t *testing.T) {
|
func Test_Download(t *testing.T) {
|
||||||
|
|
3
go.mod
3
go.mod
|
@ -3,8 +3,9 @@ module github.com/gofiber/fiber
|
||||||
go 1.11
|
go 1.11
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/fasthttp/websocket v1.4.1
|
|
||||||
github.com/gorilla/schema v1.1.0
|
github.com/gorilla/schema v1.1.0
|
||||||
|
github.com/gofiber/template v1.0.0
|
||||||
github.com/json-iterator/go v1.1.9
|
github.com/json-iterator/go v1.1.9
|
||||||
github.com/valyala/fasthttp v1.9.0
|
github.com/valyala/fasthttp v1.9.0
|
||||||
|
github.com/fasthttp/websocket v1.4.2
|
||||||
)
|
)
|
||||||
|
|
15
go.sum
15
go.sum
|
@ -1,7 +1,6 @@
|
||||||
github.com/Joker/hpp v0.0.0-20180418125244-6893e659854a/go.mod h1:MzD2WMdSxvbHw5fM/OXOFily/lipJWRc9C1px0Mt0ZE=
|
github.com/Joker/hpp v0.0.0-20180418125244-6893e659854a/go.mod h1:MzD2WMdSxvbHw5fM/OXOFily/lipJWRc9C1px0Mt0ZE=
|
||||||
github.com/Joker/jade v1.0.0 h1:lOCEPvTAtWfLpSZYMOv/g44MGQFAolbKh2khHHGu0Kc=
|
github.com/Joker/jade v1.0.0 h1:lOCEPvTAtWfLpSZYMOv/g44MGQFAolbKh2khHHGu0Kc=
|
||||||
github.com/Joker/jade v1.0.0/go.mod h1:efZIdO0py/LtcJRSa/j2WEklMSAw84WV0zZVMxNToB8=
|
github.com/Joker/jade v1.0.0/go.mod h1:efZIdO0py/LtcJRSa/j2WEklMSAw84WV0zZVMxNToB8=
|
||||||
github.com/aymerick/raymond v1.1.0 h1:phuNN2s67eI/HtO8CrvqFcdR2JP+BtkGJZ9n692Hr2Y=
|
|
||||||
github.com/aymerick/raymond v2.0.2+incompatible h1:VEp3GpgdAnv9B2GFyTvqgcKvY+mfKMjPOA3SbKLtnU0=
|
github.com/aymerick/raymond v2.0.2+incompatible h1:VEp3GpgdAnv9B2GFyTvqgcKvY+mfKMjPOA3SbKLtnU0=
|
||||||
github.com/aymerick/raymond v2.0.2+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g=
|
github.com/aymerick/raymond v2.0.2+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g=
|
||||||
github.com/cbroglie/mustache v1.0.1 h1:ivMg8MguXq/rrz2eu3tw6g3b16+PQhoTn6EZAhst2mw=
|
github.com/cbroglie/mustache v1.0.1 h1:ivMg8MguXq/rrz2eu3tw6g3b16+PQhoTn6EZAhst2mw=
|
||||||
|
@ -10,17 +9,17 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385 h1:clC1lXBpe2kTj2VHdaIu9ajZQe4kcEY9j0NsnDDBZ3o=
|
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385 h1:clC1lXBpe2kTj2VHdaIu9ajZQe4kcEY9j0NsnDDBZ3o=
|
||||||
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM=
|
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM=
|
||||||
github.com/fasthttp/websocket v1.4.1 h1:fisgNMCNCbIPM5GRRRTAckRrynbSzf76fevcJYJYnSM=
|
github.com/fasthttp/websocket v1.4.2 h1:AU/zSiIIAuJjBMf5o+vO0syGOnEfvZRu40xIhW/3RuM=
|
||||||
github.com/fasthttp/websocket v1.4.1/go.mod h1:toetUvZ3KISxtZERe0wzPPpnaN8GZCKHCowWctwA50o=
|
github.com/fasthttp/websocket v1.4.2/go.mod h1:smsv/h4PBEBaU0XDTY5UwJTpZv69fQ0FfcLJr21mA6Y=
|
||||||
|
github.com/gofiber/template v1.0.0 h1:Vf4Fby9zUWVQyY2y69KKyRHsEYlIE+Pxb25M+jiaEL0=
|
||||||
|
github.com/gofiber/template v1.0.0/go.mod h1:+bij+R0NI6urTg2jtQvPj5wb2uWMxW9eYGsAN3QhnP0=
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/gorilla/schema v1.1.0 h1:CamqUDOFUBqzrvxuz2vEwo8+SUdwsluFh7IlzJh30LY=
|
github.com/gorilla/schema v1.1.0 h1:CamqUDOFUBqzrvxuz2vEwo8+SUdwsluFh7IlzJh30LY=
|
||||||
github.com/gorilla/schema v1.1.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU=
|
github.com/gorilla/schema v1.1.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU=
|
||||||
github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns=
|
github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns=
|
||||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||||
github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
|
||||||
github.com/klauspost/compress v1.8.2 h1:Bx0qjetmNjdFXASH02NSAREKpiaDwkO1DRZ3dV2KCcs=
|
github.com/klauspost/compress v1.8.2 h1:Bx0qjetmNjdFXASH02NSAREKpiaDwkO1DRZ3dV2KCcs=
|
||||||
github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
||||||
github.com/klauspost/cpuid v0.0.0-20180405133222-e7e905edc00e/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
|
||||||
github.com/klauspost/cpuid v1.2.1 h1:vJi+O/nMdFt0vqm8NZBI6wzALWdA2X+egi0ogNyrC/w=
|
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/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 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
|
||||||
|
@ -28,18 +27,16 @@ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJ
|
||||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg=
|
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/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/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/savsgio/gotils v0.0.0-20190714152828-365999d0a274 h1:F52t1X2ziOrMcQMVHo8ZxwOrDTMAq6MrlKtL1Atu2wU=
|
github.com/savsgio/gotils v0.0.0-20200117113501-90175b0fbe3f h1:PgA+Olipyj258EIEYnpFFONrrCcAIWNUNoFhUfMqAGY=
|
||||||
github.com/savsgio/gotils v0.0.0-20190714152828-365999d0a274/go.mod h1:w803/Fg1m0hrp1ZT9KNfQe4E4+WOMMFLcgzPvOcye10=
|
github.com/savsgio/gotils v0.0.0-20200117113501-90175b0fbe3f/go.mod h1:lHhJedqxCoHN+zMtwGNTXWmF0u9Jt363FYRhV6g0CdY=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
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/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 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||||
github.com/valyala/fasthttp v1.4.0/go.mod h1:4vX61m6KN+xDduDNwXrhIAVZaZaZiQ1luJk8LWSxF3s=
|
|
||||||
github.com/valyala/fasthttp v1.9.0 h1:hNpmUdy/+ZXYpGy0OBfm7K0UQTzb73W0T0U4iJIVrMw=
|
github.com/valyala/fasthttp v1.9.0 h1:hNpmUdy/+ZXYpGy0OBfm7K0UQTzb73W0T0U4iJIVrMw=
|
||||||
github.com/valyala/fasthttp v1.9.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w=
|
github.com/valyala/fasthttp v1.9.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w=
|
||||||
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
|
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/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/net v0.0.0-20180911220305-26e67e76b6c3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
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/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
|
83
group.go
83
group.go
|
@ -4,7 +4,10 @@
|
||||||
|
|
||||||
package fiber
|
package fiber
|
||||||
|
|
||||||
import "strings"
|
import (
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
// Group ...
|
// Group ...
|
||||||
type Group struct {
|
type Group struct {
|
||||||
|
@ -12,10 +15,10 @@ type Group struct {
|
||||||
app *App
|
app *App
|
||||||
}
|
}
|
||||||
|
|
||||||
// Group ...
|
// Group : https://fiber.wiki/application#group
|
||||||
func (app *App) Group(prefix string, args ...interface{}) *Group {
|
func (app *App) Group(prefix string, handlers ...interface{}) *Group {
|
||||||
if len(args) > 0 {
|
if len(handlers) > 0 {
|
||||||
app.register("USE", prefix, args...)
|
app.register("USE", prefix, handlers...)
|
||||||
}
|
}
|
||||||
return &Group{
|
return &Group{
|
||||||
prefix: prefix,
|
prefix: prefix,
|
||||||
|
@ -23,102 +26,102 @@ func (app *App) Group(prefix string, args ...interface{}) *Group {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Group ...
|
// Group : https://fiber.wiki/application#group
|
||||||
func (grp *Group) Group(newPrfx string, args ...interface{}) *Group {
|
func (grp *Group) Group(prefix string, handlers ...interface{}) *Group {
|
||||||
var prefix = grp.prefix
|
var oldPrefix = grp.prefix
|
||||||
if len(newPrfx) > 0 && newPrfx[0] != '/' && newPrfx[0] != '*' {
|
if len(prefix) > 0 && prefix[0] != '/' && prefix[0] != '*' {
|
||||||
newPrfx = "/" + newPrfx
|
prefix = "/" + prefix
|
||||||
}
|
}
|
||||||
// When grouping, always remove single slash
|
// When grouping, always remove single slash
|
||||||
if len(prefix) > 0 && newPrfx == "/" {
|
if len(oldPrefix) > 0 && prefix == "/" {
|
||||||
newPrfx = ""
|
prefix = ""
|
||||||
}
|
}
|
||||||
// Prepent group prefix if exist
|
// Prepent group prefix if exist
|
||||||
prefix = prefix + newPrfx
|
newPrefix := oldPrefix + prefix
|
||||||
// Clean path by removing double "//" => "/"
|
// Clean path by removing double "//" => "/"
|
||||||
prefix = strings.Replace(prefix, "//", "/", -1)
|
newPrefix = strings.Replace(newPrefix, "//", "/", -1)
|
||||||
if len(args) > 0 {
|
if len(handlers) > 0 {
|
||||||
grp.app.register("USE", prefix, args...)
|
grp.app.register("USE", newPrefix, handlers...)
|
||||||
}
|
}
|
||||||
return &Group{
|
return &Group{
|
||||||
prefix: prefix,
|
prefix: newPrefix,
|
||||||
app: grp.app,
|
app: grp.app,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Static ...
|
// Static : https://fiber.wiki/application#static
|
||||||
func (grp *Group) Static(args ...string) *Group {
|
func (grp *Group) Static(args ...string) *Group {
|
||||||
grp.app.registerStatic(grp.prefix, args...)
|
grp.app.registerStatic(grp.prefix, args...)
|
||||||
return grp
|
return grp
|
||||||
}
|
}
|
||||||
|
|
||||||
// WebSocket ...
|
// WebSocket : https://fiber.wiki/application#websocket
|
||||||
func (grp *Group) WebSocket(args ...interface{}) *Group {
|
func (grp *Group) WebSocket(args ...interface{}) *Group {
|
||||||
grp.app.register("GET", grp.prefix, args...)
|
grp.app.register(http.MethodGet, grp.prefix, args...)
|
||||||
return grp
|
return grp
|
||||||
}
|
}
|
||||||
|
|
||||||
// Connect ...
|
// Connect : https://fiber.wiki/application#http-methods
|
||||||
func (grp *Group) Connect(args ...interface{}) *Group {
|
func (grp *Group) Connect(args ...interface{}) *Group {
|
||||||
grp.app.register("CONNECT", grp.prefix, args...)
|
grp.app.register(http.MethodConnect, grp.prefix, args...)
|
||||||
return grp
|
return grp
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put ...
|
// Put : https://fiber.wiki/application#http-methods
|
||||||
func (grp *Group) Put(args ...interface{}) *Group {
|
func (grp *Group) Put(args ...interface{}) *Group {
|
||||||
grp.app.register("PUT", grp.prefix, args...)
|
grp.app.register(http.MethodPut, grp.prefix, args...)
|
||||||
return grp
|
return grp
|
||||||
}
|
}
|
||||||
|
|
||||||
// Post ...
|
// Post : https://fiber.wiki/application#http-methods
|
||||||
func (grp *Group) Post(args ...interface{}) *Group {
|
func (grp *Group) Post(args ...interface{}) *Group {
|
||||||
grp.app.register("POST", grp.prefix, args...)
|
grp.app.register(http.MethodPost, grp.prefix, args...)
|
||||||
return grp
|
return grp
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete ...
|
// Delete : https://fiber.wiki/application#http-methods
|
||||||
func (grp *Group) Delete(args ...interface{}) *Group {
|
func (grp *Group) Delete(args ...interface{}) *Group {
|
||||||
grp.app.register("DELETE", grp.prefix, args...)
|
grp.app.register(http.MethodDelete, grp.prefix, args...)
|
||||||
return grp
|
return grp
|
||||||
}
|
}
|
||||||
|
|
||||||
// Head ...
|
// Head : https://fiber.wiki/application#http-methods
|
||||||
func (grp *Group) Head(args ...interface{}) *Group {
|
func (grp *Group) Head(args ...interface{}) *Group {
|
||||||
grp.app.register("HEAD", grp.prefix, args...)
|
grp.app.register(http.MethodHead, grp.prefix, args...)
|
||||||
return grp
|
return grp
|
||||||
}
|
}
|
||||||
|
|
||||||
// Patch ...
|
// Patch : https://fiber.wiki/application#http-methods
|
||||||
func (grp *Group) Patch(args ...interface{}) *Group {
|
func (grp *Group) Patch(args ...interface{}) *Group {
|
||||||
grp.app.register("PATCH", grp.prefix, args...)
|
grp.app.register(http.MethodPatch, grp.prefix, args...)
|
||||||
return grp
|
return grp
|
||||||
}
|
}
|
||||||
|
|
||||||
// Options ...
|
// Options : https://fiber.wiki/application#http-methods
|
||||||
func (grp *Group) Options(args ...interface{}) *Group {
|
func (grp *Group) Options(args ...interface{}) *Group {
|
||||||
grp.app.register("OPTIONS", grp.prefix, args...)
|
grp.app.register(http.MethodOptions, grp.prefix, args...)
|
||||||
return grp
|
return grp
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trace ...
|
// Trace : https://fiber.wiki/application#http-methods
|
||||||
func (grp *Group) Trace(args ...interface{}) *Group {
|
func (grp *Group) Trace(args ...interface{}) *Group {
|
||||||
grp.app.register("TRACE", grp.prefix, args...)
|
grp.app.register(http.MethodTrace, grp.prefix, args...)
|
||||||
return grp
|
return grp
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get ...
|
// Get : https://fiber.wiki/application#http-methods
|
||||||
func (grp *Group) Get(args ...interface{}) *Group {
|
func (grp *Group) Get(args ...interface{}) *Group {
|
||||||
grp.app.register("GET", grp.prefix, args...)
|
grp.app.register(http.MethodGet, grp.prefix, args...)
|
||||||
return grp
|
return grp
|
||||||
}
|
}
|
||||||
|
|
||||||
// All ...
|
// All : https://fiber.wiki/application#http-methods
|
||||||
func (grp *Group) All(args ...interface{}) *Group {
|
func (grp *Group) All(args ...interface{}) *Group {
|
||||||
grp.app.register("ALL", grp.prefix, args...)
|
grp.app.register("ALL", grp.prefix, args...)
|
||||||
return grp
|
return grp
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use ...
|
// Use : https://fiber.wiki/application#http-methods
|
||||||
func (grp *Group) Use(args ...interface{}) *Group {
|
func (grp *Group) Use(args ...interface{}) *Group {
|
||||||
grp.app.register("USE", grp.prefix, args...)
|
grp.app.register("USE", grp.prefix, args...)
|
||||||
return grp
|
return grp
|
||||||
|
|
|
@ -278,7 +278,11 @@ func (app *App) handler(fctx *fasthttp.RequestCtx) {
|
||||||
if app.recover != nil {
|
if app.recover != nil {
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
ctx.error = fmt.Errorf("panic: %v", r)
|
err, ok := r.(error)
|
||||||
|
if !ok {
|
||||||
|
err = fmt.Errorf("%v", r)
|
||||||
|
}
|
||||||
|
ctx.error = err
|
||||||
app.recover(ctx)
|
app.recover(ctx)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
34
utils.go
34
utils.go
|
@ -29,21 +29,6 @@ var socketUpgrade = websocket.FastHTTPUpgrader{
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// MIME types
|
|
||||||
const (
|
|
||||||
MIMEApplicationJSON = "application/json"
|
|
||||||
MIMEApplicationJavaScript = "application/javascript"
|
|
||||||
MIMEApplicationXML = "application/xml"
|
|
||||||
MIMETextXML = "text/xml"
|
|
||||||
MIMEApplicationForm = "application/x-www-form-urlencoded"
|
|
||||||
MIMEApplicationProtobuf = "application/protobuf"
|
|
||||||
MIMEApplicationMsgpack = "application/msgpack"
|
|
||||||
MIMETextHTML = "text/html"
|
|
||||||
MIMETextPlain = "text/plain"
|
|
||||||
MIMEMultipartForm = "multipart/form-data"
|
|
||||||
MIMEOctetStream = "application/octet-stream"
|
|
||||||
)
|
|
||||||
|
|
||||||
func getParams(path string) (params []string) {
|
func getParams(path string) (params []string) {
|
||||||
if len(path) < 1 {
|
if len(path) < 1 {
|
||||||
return
|
return
|
||||||
|
@ -125,7 +110,7 @@ func getStatus(status int) (msg string) {
|
||||||
// #nosec G103
|
// #nosec G103
|
||||||
// getString converts byte slice to a string without memory allocation.
|
// getString converts byte slice to a string without memory allocation.
|
||||||
// See https://groups.google.com/forum/#!msg/Golang-Nuts/ENgbUzYvCuU/90yGx7GUAgAJ .
|
// See https://groups.google.com/forum/#!msg/Golang-Nuts/ENgbUzYvCuU/90yGx7GUAgAJ .
|
||||||
func getString(b []byte) string {
|
var getString = func(b []byte) string {
|
||||||
return *(*string)(unsafe.Pointer(&b))
|
return *(*string)(unsafe.Pointer(&b))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,6 +142,21 @@ func (c *testConn) SetDeadline(t time.Time) error { return nil }
|
||||||
func (c *testConn) SetReadDeadline(t time.Time) error { return nil }
|
func (c *testConn) SetReadDeadline(t time.Time) error { return nil }
|
||||||
func (c *testConn) SetWriteDeadline(t time.Time) error { return nil }
|
func (c *testConn) SetWriteDeadline(t time.Time) error { return nil }
|
||||||
|
|
||||||
|
// MIME types
|
||||||
|
const (
|
||||||
|
MIMEApplicationJSON = "application/json"
|
||||||
|
MIMEApplicationJavaScript = "application/javascript"
|
||||||
|
MIMEApplicationXML = "application/xml"
|
||||||
|
MIMETextXML = "text/xml"
|
||||||
|
MIMEApplicationForm = "application/x-www-form-urlencoded"
|
||||||
|
MIMEApplicationProtobuf = "application/protobuf"
|
||||||
|
MIMEApplicationMsgpack = "application/msgpack"
|
||||||
|
MIMETextHTML = "text/html"
|
||||||
|
MIMETextPlain = "text/plain"
|
||||||
|
MIMEMultipartForm = "multipart/form-data"
|
||||||
|
MIMEOctetStream = "application/octet-stream"
|
||||||
|
)
|
||||||
|
|
||||||
// HTTP status codes
|
// HTTP status codes
|
||||||
var statusMessage = map[int]string{
|
var statusMessage = map[int]string{
|
||||||
100: "Continue",
|
100: "Continue",
|
||||||
|
@ -221,7 +221,7 @@ var statusMessage = map[int]string{
|
||||||
511: "Network Authentication Required",
|
511: "Network Authentication Required",
|
||||||
}
|
}
|
||||||
|
|
||||||
// MIME types for file extensions
|
// File extensions MIME types
|
||||||
var extensionMIME = map[string]string{
|
var extensionMIME = map[string]string{
|
||||||
"html": "text/html",
|
"html": "text/html",
|
||||||
"htm": "text/html",
|
"htm": "text/html",
|
||||||
|
|
Loading…
Reference in New Issue