mirror of https://github.com/gofiber/fiber.git
Add sjson
parent
a146f71f01
commit
5fa195bd4e
|
@ -15,7 +15,7 @@ import (
|
|||
|
||||
const (
|
||||
// Version for debugging
|
||||
Version = "1.1.0"
|
||||
Version = "1.2.0"
|
||||
// https://play.golang.org/p/r6GNeV1gbH
|
||||
banner = "" +
|
||||
" \x1b[1;32m _____ _ _\n" +
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
<script>
|
||||
window.$docsify = {
|
||||
name: 'Fiber v1.1.0',
|
||||
name: 'Fiber v1.2.0',
|
||||
repo: 'gofiber/fiber',
|
||||
loadSidebar: "sidebar.md",
|
||||
homepage: 'getting_started.md',
|
||||
|
|
2
go.mod
2
go.mod
|
@ -4,5 +4,7 @@ go 1.13
|
|||
|
||||
require (
|
||||
github.com/json-iterator/go v1.1.9
|
||||
github.com/tidwall/gjson v1.4.0 // indirect
|
||||
github.com/tidwall/sjson v1.0.4
|
||||
github.com/valyala/fasthttp v1.8.0
|
||||
)
|
||||
|
|
8
go.sum
8
go.sum
|
@ -14,6 +14,14 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN
|
|||
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/tidwall/gjson v1.4.0 h1:w6iOJZt9BJOzz4VD9CSnRCX/oleCsAZWi+1FFzZA+SA=
|
||||
github.com/tidwall/gjson v1.4.0/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls=
|
||||
github.com/tidwall/match v1.0.1 h1:PnKP62LPNxHKTwvHHZZzdOAOCtsJTjo6dZLCwpKm5xc=
|
||||
github.com/tidwall/match v1.0.1/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E=
|
||||
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
|
||||
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
github.com/tidwall/sjson v1.0.4 h1:UcdIRXff12Lpnu3OLtZvnc03g4vH2suXDXhBwBqmzYg=
|
||||
github.com/tidwall/sjson v1.0.4/go.mod h1:bURseu1nuBkFpIES5cz6zBtjmYeOQmEESshn7VpF15Y=
|
||||
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=
|
||||
|
|
30
request.go
30
request.go
|
@ -143,7 +143,7 @@ func (ctx *Ctx) BasicAuth() (user, pass string, ok bool) {
|
|||
if err != nil {
|
||||
return
|
||||
}
|
||||
cs := b2s(c)
|
||||
cs := B2S(c)
|
||||
s := strings.IndexByte(cs, ':')
|
||||
if s < 0 {
|
||||
return
|
||||
|
@ -158,18 +158,18 @@ func (ctx *Ctx) BasicAuth() (user, pass string, ok bool) {
|
|||
// -d john=doe
|
||||
func (ctx *Ctx) Body(args ...interface{}) string {
|
||||
if len(args) == 0 {
|
||||
return b2s(ctx.Fasthttp.Request.Body())
|
||||
return B2S(ctx.Fasthttp.Request.Body())
|
||||
}
|
||||
if len(args) == 1 {
|
||||
switch arg := args[0].(type) {
|
||||
case string:
|
||||
return b2s(ctx.Fasthttp.Request.PostArgs().Peek(arg))
|
||||
return B2S(ctx.Fasthttp.Request.PostArgs().Peek(arg))
|
||||
case func(string, string):
|
||||
ctx.Fasthttp.Request.PostArgs().VisitAll(func(k []byte, v []byte) {
|
||||
arg(b2s(k), b2s(v))
|
||||
arg(B2S(k), B2S(v))
|
||||
})
|
||||
default:
|
||||
return b2s(ctx.Fasthttp.Request.Body())
|
||||
return B2S(ctx.Fasthttp.Request.Body())
|
||||
}
|
||||
}
|
||||
return ""
|
||||
|
@ -178,15 +178,15 @@ func (ctx *Ctx) Body(args ...interface{}) string {
|
|||
// Cookies : https://gofiber.github.io/fiber/#/context?id=cookies
|
||||
func (ctx *Ctx) Cookies(args ...interface{}) string {
|
||||
if len(args) == 0 {
|
||||
//return b2s(ctx.Fasthttp.Response.Header.Peek("Cookie"))
|
||||
//return B2S(ctx.Fasthttp.Response.Header.Peek("Cookie"))
|
||||
return ctx.Get("Cookie")
|
||||
}
|
||||
switch arg := args[0].(type) {
|
||||
case string:
|
||||
return b2s(ctx.Fasthttp.Request.Header.Cookie(arg))
|
||||
return B2S(ctx.Fasthttp.Request.Header.Cookie(arg))
|
||||
case func(string, string):
|
||||
ctx.Fasthttp.Request.Header.VisitAllCookie(func(k, v []byte) {
|
||||
arg(b2s(k), b2s(v))
|
||||
arg(B2S(k), B2S(v))
|
||||
})
|
||||
default:
|
||||
panic("Argument must be a string or func(string, string)")
|
||||
|
@ -201,7 +201,7 @@ func (ctx *Ctx) FormFile(key string) (*multipart.FileHeader, error) {
|
|||
|
||||
// FormValue : https://gofiber.github.io/fiber/#/context?id=formvalue
|
||||
func (ctx *Ctx) FormValue(key string) string {
|
||||
return b2s(ctx.Fasthttp.FormValue(key))
|
||||
return B2S(ctx.Fasthttp.FormValue(key))
|
||||
}
|
||||
|
||||
// Fresh : https://gofiber.github.io/fiber/#/context?id=fresh
|
||||
|
@ -215,12 +215,12 @@ func (ctx *Ctx) Get(key string) string {
|
|||
if key == "referrer" {
|
||||
key = "referer"
|
||||
}
|
||||
return b2s(ctx.Fasthttp.Request.Header.Peek(key))
|
||||
return B2S(ctx.Fasthttp.Request.Header.Peek(key))
|
||||
}
|
||||
|
||||
// Hostname : https://gofiber.github.io/fiber/#/context?id=hostname
|
||||
func (ctx *Ctx) Hostname() string {
|
||||
return b2s(ctx.Fasthttp.URI().Host())
|
||||
return B2S(ctx.Fasthttp.URI().Host())
|
||||
}
|
||||
|
||||
// Ip : https://gofiber.github.io/fiber/#/context?id=Ip
|
||||
|
@ -265,7 +265,7 @@ func (ctx *Ctx) Locals(key string, val ...interface{}) interface{} {
|
|||
|
||||
// Method : https://gofiber.github.io/fiber/#/context?id=method
|
||||
func (ctx *Ctx) Method() string {
|
||||
return b2s(ctx.Fasthttp.Request.Header.Method())
|
||||
return B2S(ctx.Fasthttp.Request.Header.Method())
|
||||
}
|
||||
|
||||
// MultipartForm : https://gofiber.github.io/fiber/#/context?id=multipartform
|
||||
|
@ -275,7 +275,7 @@ func (ctx *Ctx) MultipartForm() (*multipart.Form, error) {
|
|||
|
||||
// OriginalUrl : https://gofiber.github.io/fiber/#/context?id=originalurl
|
||||
func (ctx *Ctx) OriginalUrl() string {
|
||||
return b2s(ctx.Fasthttp.Request.Header.RequestURI())
|
||||
return B2S(ctx.Fasthttp.Request.Header.RequestURI())
|
||||
}
|
||||
|
||||
// Params : https://gofiber.github.io/fiber/#/context?id=params
|
||||
|
@ -293,7 +293,7 @@ func (ctx *Ctx) Params(key string) string {
|
|||
|
||||
// Path : https://gofiber.github.io/fiber/#/context?id=path
|
||||
func (ctx *Ctx) Path() string {
|
||||
return b2s(ctx.Fasthttp.URI().Path())
|
||||
return B2S(ctx.Fasthttp.URI().Path())
|
||||
}
|
||||
|
||||
// Protocol : https://gofiber.github.io/fiber/#/context?id=protocol
|
||||
|
@ -306,7 +306,7 @@ func (ctx *Ctx) Protocol() string {
|
|||
|
||||
// Query : https://gofiber.github.io/fiber/#/context?id=query
|
||||
func (ctx *Ctx) Query(key string) string {
|
||||
return b2s(ctx.Fasthttp.QueryArgs().Peek(key))
|
||||
return B2S(ctx.Fasthttp.QueryArgs().Peek(key))
|
||||
}
|
||||
|
||||
// Range : https://gofiber.github.io/fiber/#/context?id=range
|
||||
|
|
45
response.go
45
response.go
|
@ -15,6 +15,7 @@ import (
|
|||
"time"
|
||||
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
"github.com/tidwall/sjson"
|
||||
"github.com/valyala/fasthttp"
|
||||
)
|
||||
|
||||
|
@ -49,7 +50,7 @@ func (ctx *Ctx) ClearCookie(name ...string) {
|
|||
return
|
||||
}
|
||||
ctx.Fasthttp.Request.Header.VisitAllCookie(func(k, v []byte) {
|
||||
ctx.Fasthttp.Response.Header.DelClientCookie(b2s(k))
|
||||
ctx.Fasthttp.Response.Header.DelClientCookie(B2S(k))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -124,7 +125,7 @@ func (ctx *Ctx) Format(args ...interface{}) {
|
|||
case string:
|
||||
body = b
|
||||
case []byte:
|
||||
body = b2s(b)
|
||||
body = B2S(b)
|
||||
default:
|
||||
panic("Body must be a string or []byte")
|
||||
}
|
||||
|
@ -151,7 +152,7 @@ func (ctx *Ctx) Json(v interface{}) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ctx.Set("Content-Type", "application/json")
|
||||
ctx.Fasthttp.Response.Header.SetContentTypeBytes(applicationjson)
|
||||
ctx.Fasthttp.Response.SetBodyString(raw)
|
||||
return nil
|
||||
}
|
||||
|
@ -165,7 +166,7 @@ func (ctx *Ctx) Jsonp(v interface{}, cb ...string) error {
|
|||
|
||||
var builder strings.Builder
|
||||
if len(cb) > 0 {
|
||||
builder.Write(s2b(cb[0]))
|
||||
builder.Write(S2B(cb[0]))
|
||||
} else {
|
||||
builder.Write([]byte("callback"))
|
||||
}
|
||||
|
@ -231,11 +232,11 @@ func (ctx *Ctx) Send(args ...interface{}) {
|
|||
}
|
||||
switch body := args[0].(type) {
|
||||
case string:
|
||||
//ctx.Fasthttp.Response.SetBodyRaw(s2b(body))
|
||||
//ctx.Fasthttp.Response.SetBodyRaw(S2B(body))
|
||||
ctx.Fasthttp.Response.SetBodyString(body)
|
||||
case []byte:
|
||||
//ctx.Fasthttp.Response.SetBodyRaw(body)
|
||||
ctx.Fasthttp.Response.SetBodyString(b2s(body))
|
||||
ctx.Fasthttp.Response.SetBodyString(B2S(body))
|
||||
default:
|
||||
panic("body must be a string or []byte")
|
||||
}
|
||||
|
@ -243,7 +244,7 @@ func (ctx *Ctx) Send(args ...interface{}) {
|
|||
|
||||
// SendBytes : https://gofiber.github.io/fiber/#/context?id=sendbytes
|
||||
func (ctx *Ctx) SendBytes(body []byte) {
|
||||
ctx.Fasthttp.Response.SetBodyString(b2s(body))
|
||||
ctx.Fasthttp.Response.SetBodyString(B2S(body))
|
||||
}
|
||||
|
||||
// SendFile : https://gofiber.github.io/fiber/#/context?id=sendfile
|
||||
|
@ -277,7 +278,33 @@ func (ctx *Ctx) SendString(body string) {
|
|||
|
||||
// Set : https://gofiber.github.io/fiber/#/context?id=set
|
||||
func (ctx *Ctx) Set(key string, val string) {
|
||||
ctx.Fasthttp.Response.Header.SetCanonical(s2b(key), s2b(val))
|
||||
ctx.Fasthttp.Response.Header.SetCanonical(S2B(key), S2B(val))
|
||||
}
|
||||
|
||||
// Sjson : https://github.com/tidwall/sjson
|
||||
func (ctx *Ctx) Sjson(json, path string, value interface{}) error {
|
||||
raw, err := sjson.SetBytesOptions(S2B(json), path, value, &sjson.Options{
|
||||
Optimistic: true,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ctx.Fasthttp.Response.Header.SetContentTypeBytes(applicationjson)
|
||||
ctx.Fasthttp.Response.SetBodyString(B2S(raw))
|
||||
return nil
|
||||
}
|
||||
|
||||
// SjsonString : https://github.com/tidwall/sjson
|
||||
func (ctx *Ctx) SjsonStr(json, path, value string) error {
|
||||
raw, err := sjson.SetBytesOptions(S2B(json), path, S2B(value), &sjson.Options{
|
||||
Optimistic: true,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ctx.Fasthttp.Response.Header.SetContentTypeBytes(applicationjson)
|
||||
ctx.Fasthttp.Response.SetBodyString(B2S(raw))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Status : https://gofiber.github.io/fiber/#/context?id=status
|
||||
|
@ -318,7 +345,7 @@ func (ctx *Ctx) Write(args ...interface{}) {
|
|||
case string:
|
||||
ctx.Fasthttp.Response.SetBodyString(body)
|
||||
case []byte:
|
||||
ctx.Fasthttp.Response.AppendBodyString(b2s(body))
|
||||
ctx.Fasthttp.Response.AppendBodyString(B2S(body))
|
||||
default:
|
||||
panic("body must be a string or []byte")
|
||||
}
|
||||
|
|
35
utils.go
35
utils.go
|
@ -10,12 +10,15 @@ package fiber
|
|||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strings"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var (
|
||||
applicationjson = []byte("application/json")
|
||||
)
|
||||
|
||||
var replacer = strings.NewReplacer(":", "", "?", "")
|
||||
|
||||
func getParams(path string) (params []string) {
|
||||
|
@ -73,33 +76,11 @@ func walkDir(root string) (files []string, isDir bool, err error) {
|
|||
return files, isDir, err
|
||||
}
|
||||
|
||||
// b2s converts byte slice to a string without memory allocation.
|
||||
// See https://groups.google.com/forum/#!msg/Golang-Nuts/ENgbUzYvCuU/90yGx7GUAgAJ .
|
||||
//
|
||||
// Note it may break if string and/or slice header will change
|
||||
// in the future go versions.
|
||||
func b2s(b []byte) string {
|
||||
sh := (*reflect.StringHeader)(unsafe.Pointer(&b))
|
||||
bh := reflect.SliceHeader{
|
||||
Data: sh.Data,
|
||||
Len: sh.Len,
|
||||
Cap: sh.Len,
|
||||
}
|
||||
return *(*string)(unsafe.Pointer(&bh))
|
||||
func B2S(b []byte) string {
|
||||
return *(*string)(unsafe.Pointer(&b))
|
||||
}
|
||||
|
||||
// s2b converts string to a byte slice without memory allocation.
|
||||
//
|
||||
// Note it may break if string and/or slice header will change
|
||||
// in the future go versions.
|
||||
func s2b(s string) []byte {
|
||||
sh := (*reflect.StringHeader)(unsafe.Pointer(&s))
|
||||
bh := reflect.SliceHeader{
|
||||
Data: sh.Data,
|
||||
Len: sh.Len,
|
||||
Cap: sh.Len,
|
||||
}
|
||||
return *(*[]byte)(unsafe.Pointer(&bh))
|
||||
func S2B(s string) []byte {
|
||||
return *(*[]byte)(unsafe.Pointer(&s))
|
||||
}
|
||||
|
||||
// NoCopy embed this type into a struct, which mustn't be copied,
|
||||
|
|
Loading…
Reference in New Issue