1
0

Move the crudhandler to own repo (#27)

This commit is contained in:
konrad
2018-11-30 23:26:56 +00:00
committed by Gitea
parent d9304f6996
commit ce2cae9430
228 changed files with 13281 additions and 3292 deletions

View File

@ -2,7 +2,6 @@ language: go
go:
- 1.9.x
- 1.10.x
- 1.11.x
- tip
install:
- make dependency

View File

@ -2,113 +2,74 @@
[[projects]]
digest = "1:ffe9824d294da03b391f44e1ae8281281b4afc1bdaa9588c9097785e3af10cec"
name = "github.com/davecgh/go-spew"
packages = ["spew"]
pruneopts = "UT"
revision = "8991bc29aa16c548c550c7ff78260e27b9ab7c73"
version = "v1.1.1"
revision = "346938d642f2ec3594ed81d874461961cd0faa76"
version = "v1.1.0"
[[projects]]
digest = "1:76dc72490af7174349349838f2fe118996381b31ea83243812a97e5a0fd5ed55"
name = "github.com/dgrijalva/jwt-go"
packages = ["."]
pruneopts = "UT"
revision = "06ea1031745cb8b3dab3f6a236daf2b0aa468b7e"
version = "v3.2.0"
[[projects]]
digest = "1:568171fc14a3d819b112c3e219d351ea7b05e8dad7935c4168c6b3373244a686"
name = "github.com/labstack/gommon"
packages = [
"bytes",
"color",
"log",
"random",
]
pruneopts = "UT"
revision = "2a618302b929cc20862dda3aa6f02f64dbe740dd"
version = "v0.2.7"
packages = ["bytes","color","log","random"]
revision = "6fe1405d73ec4bd4cd8a4ac8e2a2b2bf95d03954"
version = "0.2.4"
[[projects]]
digest = "1:c658e84ad3916da105a761660dcaeb01e63416c8ec7bc62256a9b411a05fcd67"
name = "github.com/mattn/go-colorable"
packages = ["."]
pruneopts = "UT"
revision = "167de6bfdfba052fa6b2d3664c8f5272e23c9072"
version = "v0.0.9"
[[projects]]
digest = "1:0981502f9816113c9c8c4ac301583841855c8cf4da8c72f696b3ebedf6d0e4e5"
name = "github.com/mattn/go-isatty"
packages = ["."]
pruneopts = "UT"
revision = "6ca4dbf54d38eea1a992b3c722a76a5d1c4cb25c"
version = "v0.0.4"
revision = "0360b2af4f38e8d38c7fce2a9f4e702702d73a39"
version = "v0.0.3"
[[projects]]
digest = "1:0028cb19b2e4c3112225cd871870f2d9cf49b9b4276531f03438a88e94be86fe"
name = "github.com/pmezard/go-difflib"
packages = ["difflib"]
pruneopts = "UT"
revision = "792786c7400a136282c1664665ae0a8db921c6c2"
version = "v1.0.0"
[[projects]]
digest = "1:18752d0b95816a1b777505a97f71c7467a8445b8ffb55631a7bf779f6ba4fa83"
name = "github.com/stretchr/testify"
packages = ["assert"]
pruneopts = "UT"
revision = "f35b8ab0b5a2cef36673838d662e249dd9c94686"
version = "v1.2.2"
[[projects]]
digest = "1:c468422f334a6b46a19448ad59aaffdfc0a36b08fdcc1c749a0b29b6453d7e59"
name = "github.com/valyala/bytebufferpool"
packages = ["."]
pruneopts = "UT"
revision = "e746df99fe4a3986f4d4f79e13c1e0117ce9c2f7"
version = "v1.0.0"
revision = "12b6f73e6084dad08a7c6e575284b177ecafbc71"
version = "v1.2.1"
[[projects]]
branch = "master"
name = "github.com/valyala/bytebufferpool"
packages = ["."]
revision = "e746df99fe4a3986f4d4f79e13c1e0117ce9c2f7"
[[projects]]
branch = "master"
digest = "1:268b8bce0064e8c057d7b913605459f9a26dcab864c0886a56d196540fbf003f"
name = "github.com/valyala/fasttemplate"
packages = ["."]
pruneopts = "UT"
revision = "dcecefd839c4193db0d35b88ec65b4c12d360ab0"
[[projects]]
branch = "master"
digest = "1:dedf20eb0d3e8d6aa8a4d3d2fae248222b688ed528201995e152cc497899123c"
name = "golang.org/x/crypto"
packages = [
"acme",
"acme/autocert",
]
pruneopts = "UT"
revision = "0e37d006457bf46f9e6692014ba72ef82c33022c"
packages = ["acme","acme/autocert"]
revision = "182114d582623c1caa54f73de9c7224e23a48487"
[[projects]]
branch = "master"
digest = "1:6eb2645d74b43d9c87b51947df39f7c668a4f422cd512053f7f6f75bfaad0197"
name = "golang.org/x/sys"
packages = ["unix"]
pruneopts = "UT"
revision = "d0be0721c37eeb5299f245a996a483160fc36940"
revision = "c28acc882ebcbfbe8ce9f0f14b9ac26ee138dd51"
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
input-imports = [
"github.com/dgrijalva/jwt-go",
"github.com/labstack/gommon/bytes",
"github.com/labstack/gommon/color",
"github.com/labstack/gommon/log",
"github.com/labstack/gommon/random",
"github.com/stretchr/testify/assert",
"github.com/valyala/fasttemplate",
"golang.org/x/crypto/acme/autocert",
]
inputs-digest = "9c7b45e80fe353405800cf01f429b3a203cfb8d4468a04c64a908e11a98ea764"
solver-name = "gps-cdcl"
solver-version = 1

View File

@ -1,6 +1,7 @@
# Gopkg.toml example
#
# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
# for detailed Gopkg.toml documentation.
#
# required = ["github.com/user/thing/cmd/thing"]
@ -16,13 +17,8 @@
# source = "github.com/myfork/project2"
#
# [[override]]
# name = "github.com/x/y"
# version = "2.4.0"
#
# [prune]
# non-go = false
# go-tests = true
# unused-packages = true
# name = "github.com/x/y"
# version = "2.4.0"
[[constraint]]
@ -31,11 +27,11 @@
[[constraint]]
name = "github.com/labstack/gommon"
version = "0.2.7"
version = "0.2.4"
[[constraint]]
name = "github.com/stretchr/testify"
version = "1.2.2"
version = "1.2.1"
[[constraint]]
branch = "master"
@ -43,8 +39,4 @@
[[constraint]]
branch = "master"
name = "golang.org/x/crypto"
[prune]
go-tests = true
unused-packages = true
name = "golang.org/x/crypto"

View File

@ -32,7 +32,7 @@ Date: 2018/03/15<br>
Source: https://github.com/vishr/web-framework-benchmark<br>
Lower is better!
<img src="https://i.imgur.com/I32VdMJ.png">
<img src="https://api.labstack.com/chart/bar?values=37223,55382,2985,5265|42013,59865,3350,6424&labels=Static,GitHub%20API,Parse%20API,Gplus%20API&titles=Echo,Gin&colors=lightseagreen,goldenrod&x_title=Routes&y_title=ns/op">
## [Guide](https://echo.labstack.com/guide)

View File

@ -44,11 +44,12 @@ func (b *DefaultBinder) Bind(i interface{}, c Context) (err error) {
case strings.HasPrefix(ctype, MIMEApplicationJSON):
if err = json.NewDecoder(req.Body).Decode(i); err != nil {
if ute, ok := err.(*json.UnmarshalTypeError); ok {
return NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Unmarshal type error: expected=%v, got=%v, field=%v, offset=%v", ute.Type, ute.Value, ute.Field, ute.Offset))
return NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Unmarshal type error: expected=%v, got=%v, offset=%v", ute.Type, ute.Value, ute.Offset))
} else if se, ok := err.(*json.SyntaxError); ok {
return NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Syntax error: offset=%v, error=%v", se.Offset, se.Error()))
} else {
return NewHTTPError(http.StatusBadRequest, err.Error())
}
return NewHTTPError(http.StatusBadRequest, err.Error())
}
case strings.HasPrefix(ctype, MIMEApplicationXML), strings.HasPrefix(ctype, MIMETextXML):
if err = xml.NewDecoder(req.Body).Decode(i); err != nil {
@ -56,8 +57,9 @@ func (b *DefaultBinder) Bind(i interface{}, c Context) (err error) {
return NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Unsupported type error: type=%v, error=%v", ute.Type, ute.Error()))
} else if se, ok := err.(*xml.SyntaxError); ok {
return NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Syntax error: line=%v, error=%v", se.Line, se.Error()))
} else {
return NewHTTPError(http.StatusBadRequest, err.Error())
}
return NewHTTPError(http.StatusBadRequest, err.Error())
}
case strings.HasPrefix(ctype, MIMEApplicationForm), strings.HasPrefix(ctype, MIMEMultipartForm):
params, err := c.FormParams()
@ -94,29 +96,14 @@ func (b *DefaultBinder) bindData(ptr interface{}, data map[string][]string, tag
inputFieldName = typeField.Name
// If tag is nil, we inspect if the field is a struct.
if _, ok := bindUnmarshaler(structField); !ok && structFieldKind == reflect.Struct {
if err := b.bindData(structField.Addr().Interface(), data, tag); err != nil {
err := b.bindData(structField.Addr().Interface(), data, tag)
if err != nil {
return err
}
continue
}
}
inputValue, exists := data[inputFieldName]
if !exists {
// Go json.Unmarshal supports case insensitive binding. However the
// url params are bound case sensitive which is inconsistent. To
// fix this we must check all of the map values in a
// case-insensitive search.
inputFieldName = strings.ToLower(inputFieldName)
for k, v := range data {
if strings.ToLower(k) == inputFieldName {
inputValue = v
exists = true
break
}
}
}
if !exists {
continue
}
@ -139,9 +126,10 @@ func (b *DefaultBinder) bindData(ptr interface{}, data map[string][]string, tag
}
}
val.Field(i).Set(slice)
} else if err := setWithProperType(typeField.Type.Kind(), inputValue[0], structField); err != nil {
return err
} else {
if err := setWithProperType(typeField.Type.Kind(), inputValue[0], structField); err != nil {
return err
}
}
}
return nil

View File

@ -103,7 +103,7 @@ type (
// MiddlewareFunc defines a function to process middleware.
MiddlewareFunc func(HandlerFunc) HandlerFunc
// HandlerFunc defines a function to serve HTTP requests.
// HandlerFunc defines a function to server HTTP requests.
HandlerFunc func(Context) error
// HTTPErrorHandler is a centralized HTTP error handler.
@ -217,7 +217,7 @@ const (
)
const (
Version = "3.3.6"
Version = "3.3.5"
website = "https://echo.labstack.com"
// http://patorjk.com/software/taag/#p=display&f=Small%20Slant&t=Echo
banner = `
@ -326,7 +326,7 @@ func (e *Echo) DefaultHTTPErrorHandler(err error, c Context) {
code = he.Code
msg = he.Message
if he.Internal != nil {
err = fmt.Errorf("%v, %v", err, he.Internal)
msg = fmt.Sprintf("%v, %v", err, he.Internal)
}
} else if e.Debug {
msg = err.Error()
@ -337,6 +337,8 @@ func (e *Echo) DefaultHTTPErrorHandler(err error, c Context) {
msg = Map{"message": msg}
}
e.Logger.Error(err)
// Send response
if !c.Response().Committed {
if c.Request().Method == HEAD { // Issue #608
@ -460,11 +462,11 @@ func static(i i, prefix, root string) *Route {
return i.GET(prefix+"/*", h)
}
// File registers a new route with path to serve a static file with optional route-level middleware.
func (e *Echo) File(path, file string, m ...MiddlewareFunc) *Route {
// File registers a new route with path to serve a static file.
func (e *Echo) File(path, file string) *Route {
return e.GET(path, func(c Context) error {
return c.File(file)
}, m...)
})
}
// Add registers a new route for an HTTP method and path with matching handler
@ -557,17 +559,26 @@ func (e *Echo) ServeHTTP(w http.ResponseWriter, r *http.Request) {
c := e.pool.Get().(*context)
c.Reset(r, w)
m := r.Method
h := NotFoundHandler
if e.premiddleware == nil {
e.router.Find(r.Method, getPath(r), c)
path := r.URL.RawPath
if path == "" {
path = r.URL.Path
}
e.router.Find(m, getPath(r), c)
h = c.Handler()
for i := len(e.middleware) - 1; i >= 0; i-- {
h = e.middleware[i](h)
}
} else {
h = func(c Context) error {
e.router.Find(r.Method, getPath(r), c)
path := r.URL.RawPath
if path == "" {
path = r.URL.Path
}
e.router.Find(m, getPath(r), c)
h := c.Handler()
for i := len(e.middleware) - 1; i >= 0; i-- {
h = e.middleware[i](h)

View File

@ -1,15 +0,0 @@
module github.com/labstack/echo
require (
github.com/davecgh/go-spew v1.1.0 // indirect
github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/labstack/gommon v0.0.0-20180312174116-6fe1405d73ec
github.com/mattn/go-colorable v0.0.9 // indirect
github.com/mattn/go-isatty v0.0.3 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/stretchr/testify v1.2.1
github.com/valyala/bytebufferpool v0.0.0-20160817181652-e746df99fe4a // indirect
github.com/valyala/fasttemplate v0.0.0-20170224212429-dcecefd839c4
golang.org/x/crypto v0.0.0-20180312195533-182114d58262
golang.org/x/sys v0.0.0-20180312081825-c28acc882ebc // indirect
)

View File

@ -1,22 +0,0 @@
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/labstack/gommon v0.0.0-20180312174116-6fe1405d73ec h1:aYKwS4iCpqxskMuvI8+Byq0CxnnWHO/xuLk2pZJ96tY=
github.com/labstack/gommon v0.0.0-20180312174116-6fe1405d73ec/go.mod h1:/tj9csK2iPSBvn+3NLM9e52usepMtrd5ilFYA+wQNJ4=
github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-isatty v0.0.3 h1:ns/ykhmWi7G9O+8a448SecJU3nSMBXJfqQkl0upE1jI=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.2.1 h1:52QO5WkIUcHGIR7EnGagH88x1bUzqGXTC5/1bDTUQ7U=
github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/valyala/bytebufferpool v0.0.0-20160817181652-e746df99fe4a h1:AOcehBWpFhYPYw0ioDTppQzgI8pAAahVCiMSKTp9rbo=
github.com/valyala/bytebufferpool v0.0.0-20160817181652-e746df99fe4a/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasttemplate v0.0.0-20170224212429-dcecefd839c4 h1:gKMu1Bf6QINDnvyZuTaACm9ofY+PRh+5vFz4oxBZeF8=
github.com/valyala/fasttemplate v0.0.0-20170224212429-dcecefd839c4/go.mod h1:50wTf68f99/Zt14pr046Tgt3Lp2vLyFZKzbFXTOabXw=
golang.org/x/crypto v0.0.0-20180312195533-182114d58262 h1:1NLVUmR8SQ7cNNA5Vo7ronpXbR+5A+9IwIC/bLE7D8Y=
golang.org/x/crypto v0.0.0-20180312195533-182114d58262/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/sys v0.0.0-20180312081825-c28acc882ebc h1:eCzBKjjvhDDXMoH5l7eA+YK1PEtyJ2QLj3f4IArr+zg=
golang.org/x/sys v0.0.0-20180312081825-c28acc882ebc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=

View File

@ -94,10 +94,6 @@ func CORSWithConfig(config CORSConfig) echo.MiddlewareFunc {
// Check allowed origins
for _, o := range config.AllowOrigins {
if o == "*" && config.AllowCredentials {
allowOrigin = origin
break
}
if o == "*" || o == origin {
allowOrigin = o
break

View File

@ -16,16 +16,6 @@ type (
// Skipper defines a function to skip middleware.
Skipper Skipper
// BeforeFunc defines a function which is executed just before the middleware.
BeforeFunc BeforeFunc
// SuccessHandler defines a function which is executed for a valid token.
SuccessHandler JWTSuccessHandler
// ErrorHandler defines a function which is executed for an invalid token.
// It may be used to define a custom JWT error.
ErrorHandler JWTErrorHandler
// Signing key to validate token.
// Required.
SigningKey interface{}
@ -58,12 +48,6 @@ type (
keyFunc jwt.Keyfunc
}
// JWTSuccessHandler defines a function which is executed for a valid token.
JWTSuccessHandler func(echo.Context)
// JWTErrorHandler defines a function which is executed for an invalid token.
JWTErrorHandler func(error) error
jwtExtractor func(echo.Context) (string, error)
)
@ -75,6 +59,7 @@ const (
// Errors
var (
ErrJWTMissing = echo.NewHTTPError(http.StatusBadRequest, "missing or malformed jwt")
ErrJWTInvalid = echo.NewHTTPError(http.StatusUnauthorized, "invalid or expired jwt")
)
var (
@ -152,15 +137,8 @@ func JWTWithConfig(config JWTConfig) echo.MiddlewareFunc {
return next(c)
}
if config.BeforeFunc != nil {
config.BeforeFunc(c)
}
auth, err := extractor(c)
if err != nil {
if config.ErrorHandler != nil {
return config.ErrorHandler(err)
}
return err
}
token := new(jwt.Token)
@ -175,17 +153,11 @@ func JWTWithConfig(config JWTConfig) echo.MiddlewareFunc {
if err == nil && token.Valid {
// Store user information from token into context.
c.Set(config.ContextKey, token)
if config.SuccessHandler != nil {
config.SuccessHandler(c)
}
return next(c)
}
if config.ErrorHandler != nil {
return config.ErrorHandler(err)
}
return &echo.HTTPError{
Code: http.StatusUnauthorized,
Message: "invalid or expired jwt",
Code: ErrJWTInvalid.Code,
Message: ErrJWTInvalid.Message,
Internal: err,
}
}

View File

@ -33,11 +33,9 @@ type (
// - host
// - method
// - path
// - protocol
// - referer
// - user_agent
// - status
// - error
// - latency (In nanoseconds)
// - latency_human (Human readable)
// - bytes_in (Bytes received)
@ -69,7 +67,7 @@ var (
DefaultLoggerConfig = LoggerConfig{
Skipper: DefaultSkipper,
Format: `{"time":"${time_rfc3339_nano}","id":"${id}","remote_ip":"${remote_ip}","host":"${host}",` +
`"method":"${method}","uri":"${uri}","status":${status},"error":"${error}","latency":${latency},` +
`"method":"${method}","uri":"${uri}","status":${status}, "latency":${latency},` +
`"latency_human":"${latency_human}","bytes_in":${bytes_in},` +
`"bytes_out":${bytes_out}}` + "\n",
CustomTimeFormat: "2006-01-02 15:04:05.00000",
@ -155,8 +153,6 @@ func LoggerWithConfig(config LoggerConfig) echo.MiddlewareFunc {
p = "/"
}
return buf.WriteString(p)
case "protocol":
return buf.WriteString(req.Proto)
case "referer":
return buf.WriteString(req.Referer())
case "user_agent":
@ -173,10 +169,6 @@ func LoggerWithConfig(config LoggerConfig) echo.MiddlewareFunc {
s = config.colorer.Cyan(n)
}
return buf.WriteString(s)
case "error":
if err != nil {
return buf.WriteString(err.Error())
}
case "latency":
l := stop.Sub(start)
return buf.WriteString(strconv.FormatInt(int64(l), 10))

View File

@ -11,10 +11,7 @@ import (
type (
// Skipper defines a function to skip middleware. Returning true skips processing
// the middleware.
Skipper func(echo.Context) bool
// BeforeFunc defines a function which is executed just before the middleware.
BeforeFunc func(echo.Context)
Skipper func(c echo.Context) bool
)
func captureTokens(pattern *regexp.Regexp, input string) *strings.Replacer {

View File

@ -57,8 +57,7 @@ func RewriteWithConfig(config RewriteConfig) echo.MiddlewareFunc {
// Initialize
for k, v := range config.Rules {
k = strings.Replace(k, "*", "(.*)", -1)
k = k + "$"
k = strings.Replace(k, "*", "(\\S*)", -1)
config.rulesRegex[regexp.MustCompile(k)] = v
}
@ -75,9 +74,9 @@ func RewriteWithConfig(config RewriteConfig) echo.MiddlewareFunc {
replacer := captureTokens(k, req.URL.Path)
if replacer != nil {
req.URL.Path = replacer.Replace(v)
break
}
}
return next(c)
}
}