adopt for rest errors and revendor go-pkgz

This commit is contained in:
Umputun
2019-01-13 23:27:15 -06:00
parent 492f92e660
commit 8c8f13fd73
19 changed files with 116 additions and 85 deletions
+9 -9
View File
@@ -112,7 +112,7 @@
version = "v1.0.0"
[[projects]]
digest = "1:94bd00c67ee734ccdafa8c29a3dec31a71e1c0906d12136d50b59af98f0f2a9c"
digest = "1:1e397244efaf3322184d8fe59caa62dae159d925aa74a5efafa670964d860d67"
name = "github.com/go-pkgz/auth"
packages = [
".",
@@ -122,16 +122,16 @@
"token",
]
pruneopts = "UT"
revision = "720bf3c94e674562c17355923524c067e43b6078"
version = "v0.3.1"
revision = "06e223a293c64ebcaaccda26edfeaf7fba1b8746"
version = "v0.3.2"
[[projects]]
digest = "1:479ca4406d1521b92615374d807581ccfdb1b971abc3bac7e29c1fc83c988745"
digest = "1:779380833dce298899504f0b78ce961339cd5b5facb43f41208d2120d22306f5"
name = "github.com/go-pkgz/lgr"
packages = ["."]
pruneopts = "UT"
revision = "07dcefe903e40f6c93674e1b85f84764552665b0"
version = "v0.2.0"
revision = "dbe2f3c6c85e69d224b1dc5ea48d65521827ee8c"
version = "v0.2.1"
[[projects]]
digest = "1:1212e114344a5cdcc834ea69e19d456eef230f9784659080fee67e02ba2cb574"
@@ -153,7 +153,7 @@
version = "v1.0.0"
[[projects]]
digest = "1:f90abdc7788e4c799b440eba9ba2c0da647b734d4bd7c0d6a66b8af74d836e67"
digest = "1:9aba5c95373481f118e57e9740d9e82f86802d86849809ab89324bcb4f236451"
name = "github.com/go-pkgz/rest"
packages = [
".",
@@ -161,8 +161,8 @@
"logger",
]
pruneopts = "UT"
revision = "8fbfa5089252d9c40ed780e00e97763c28764e67"
version = "v1.1.6"
revision = "e7d08d0194d613b8854de2e487bf7732500fa153"
version = "v1.2.0"
[[projects]]
digest = "1:ffc060c551980d37ee9e428ef528ee2813137249ccebb0bfc412ef83071cac91"
+1 -1
View File
@@ -155,7 +155,7 @@ func (s *Rest) makeHTTPServer(port int, router http.Handler) *http.Server {
func (s *Rest) routes() chi.Router {
router := chi.NewRouter()
router.Use(middleware.RealIP, R.Recoverer)
router.Use(middleware.RealIP, R.Recoverer(log.Default()))
router.Use(middleware.Throttle(1000), middleware.Timeout(60*time.Second))
router.Use(R.AppInfo("remark42", "umputun", s.Version), R.Ping)
+2 -2
View File
@@ -43,7 +43,7 @@ type SSLConfig struct {
func (s *Rest) httpToHTTPSRouter() chi.Router {
log.Printf("[DEBUG] create https-to-http redirect routes")
router := chi.NewRouter()
router.Use(middleware.RealIP, R.Recoverer)
router.Use(middleware.RealIP, R.Recoverer(log.Default()))
router.Use(middleware.Throttle(1000), middleware.Timeout(60*time.Second))
router.Handle("/*", s.redirectHandler())
@@ -57,7 +57,7 @@ func (s *Rest) httpToHTTPSRouter() chi.Router {
func (s *Rest) httpChallengeRouter(m *autocert.Manager) chi.Router {
log.Printf("[DEBUG] create http-challenge routes")
router := chi.NewRouter()
router.Use(middleware.RealIP, R.Recoverer)
router.Use(middleware.RealIP, R.Recoverer(log.Default()))
router.Use(middleware.Throttle(1000), middleware.Timeout(60*time.Second))
router.Handle("/*", m.HTTPHandler(s.redirectHandler()))
+1 -1
View File
@@ -78,7 +78,7 @@ func NewService(opts Opts) (res *Service) {
}
if opts.Logger == nil {
res.logger = lgr.Func(func(fmt string, args ...interface{}) {}) // do-nothing logger
res.logger = lgr.NoOp
}
jwtService := token.NewService(token.Opts{
+1 -1
View File
@@ -92,7 +92,7 @@ func (p *Proxy) Handler(w http.ResponseWriter, r *http.Request) {
avReader, size, err := p.Store.Get(avatarID)
if err != nil {
rest.SendErrorJSON(w, r, http.StatusBadRequest, err, "can't load avatar")
rest.SendErrorJSON(w, r, p.L, http.StatusBadRequest, err, "can't load avatar")
return
}
+4 -4
View File
@@ -5,13 +5,13 @@ require (
github.com/coreos/bbolt v1.3.0
github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8
github.com/go-pkgz/lgr v0.1.0 // indirect
github.com/go-pkgz/lgr v0.1.4
github.com/go-pkgz/mongo v1.0.0
github.com/go-pkgz/rest v1.1.5
github.com/go-pkgz/rest v1.2.0
github.com/nullrocks/identicon v0.0.0-20180626043057-7875f45b0022
github.com/pkg/errors v0.8.0
github.com/pkg/errors v0.8.1
github.com/stretchr/objx v0.1.1 // indirect
golang.org/x/image v0.0.0-20181116024801-cd38e8056d9b
golang.org/x/net v0.0.0-20181220203305-927f97764cc3 // indirect
golang.org/x/net v0.0.0-20190107210223-45ffb0cd1ba0 // indirect
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890
)
+13
View File
@@ -13,6 +13,10 @@ github.com/go-pkgz/lgr v0.0.0-20190107224007-7d791fb529cb h1:HBzmL2t7mb8A14Vc1uM
github.com/go-pkgz/lgr v0.0.0-20190107224007-7d791fb529cb/go.mod h1:hBM1NM/SoYdlrykgdgJWGrZ/TM/XaZIjRbJfx7NkMm8=
github.com/go-pkgz/lgr v0.1.0 h1:JzSBxyNW9gli9PMVGI8IUhmFsQZaK2usJ62pmUGj0BY=
github.com/go-pkgz/lgr v0.1.0/go.mod h1:hBM1NM/SoYdlrykgdgJWGrZ/TM/XaZIjRbJfx7NkMm8=
github.com/go-pkgz/lgr v0.1.3 h1:jGPFbzfXWSt3r8qyjXnuKFNM6J10bs3YnD8wPSGdsww=
github.com/go-pkgz/lgr v0.1.3/go.mod h1:hBM1NM/SoYdlrykgdgJWGrZ/TM/XaZIjRbJfx7NkMm8=
github.com/go-pkgz/lgr v0.1.4 h1:mOV129LVgHLq65kYs1Abz0dSk3Sba6PuuJ/S+x2yDaw=
github.com/go-pkgz/lgr v0.1.4/go.mod h1:hBM1NM/SoYdlrykgdgJWGrZ/TM/XaZIjRbJfx7NkMm8=
github.com/go-pkgz/mongo v1.0.0 h1:9jijAK7prCRMetiyTu3c1rv/2lMypzuf2DWcVpTlwzw=
github.com/go-pkgz/mongo v1.0.0/go.mod h1:R9si/F2aJsjz4MUxhzuppIHY8yLV3YCeuCpgcI50cu4=
github.com/go-pkgz/rest v1.1.3 h1:rMf+xJn8i1Ip9OKohusZsRxwntM0BwYu8OX8BuEwN80=
@@ -21,22 +25,31 @@ github.com/go-pkgz/rest v1.1.4 h1:/Lrg9kBWBjNah7nmCDHLszRAfVVBIy5ajf0vVgpHPi0=
github.com/go-pkgz/rest v1.1.4/go.mod h1:DIxxm3vSt6e+IY+UQUOFsfB2YaHLmGoOfPLWN5pxQSA=
github.com/go-pkgz/rest v1.1.5 h1:5br4mnscfLb27yxv5hJFLBVmAt09PrmIBP+meA3CfHc=
github.com/go-pkgz/rest v1.1.5/go.mod h1:DIxxm3vSt6e+IY+UQUOFsfB2YaHLmGoOfPLWN5pxQSA=
github.com/go-pkgz/rest v1.1.6 h1:Sqm7uW0X29iEmt4S/vJ82bslQXa6jMMNTaRvHzjTcjo=
github.com/go-pkgz/rest v1.1.6/go.mod h1:fFcrWsYgEp5Xx6HxRFzfV6zTiytCeYv1Jceg8TxorOs=
github.com/go-pkgz/rest v1.2.0 h1:75GVv25NmkV2l4dBr/io/ZApJ6zWQu5aZ4wFJA6QQCw=
github.com/go-pkgz/rest v1.2.0/go.mod h1:COazNj35u3RXAgQNBr6neR599tYP3URiOpsu9p0rOtk=
github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/nullrocks/identicon v0.0.0-20180626043057-7875f45b0022 h1:Ys0rDzh8s4UMlGaDa1UTA0sfKgvF0hQZzTYX8ktjiDc=
github.com/nullrocks/identicon v0.0.0-20180626043057-7875f45b0022/go.mod h1:x4NsS+uc7ecH/Cbm9xKQ6XzmJM57rWTkjywjfB2yQ18=
github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
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/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
golang.org/x/image v0.0.0-20181116024801-cd38e8056d9b h1:VHyIDlv3XkfCa5/a81uzaoDkHH4rr81Z62g+xlnO8uM=
golang.org/x/image v0.0.0-20181116024801-cd38e8056d9b/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3 h1:eH6Eip3UpmR+yM/qI9Ijluzb1bNv/cAU/n+6l8tRSis=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190107210223-45ffb0cd1ba0 h1:1DW40AJQ7AP4nY6ORUGUdkpXyEC9W2GAXcOPaMZK0K8=
golang.org/x/net v0.0.0-20190107210223-45ffb0cd1ba0/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890 h1:uESlIz09WIHT2I+pasSXcpLYqYK8wHcdCetU3VuMBJE=
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
+4 -4
View File
@@ -44,16 +44,16 @@ func (p DirectHandler) LoginHandler(w http.ResponseWriter, r *http.Request) {
aud := r.URL.Query().Get("aud")
sessOnly := r.URL.Query().Get("sess") == "1"
if p.CredChecker == nil {
rest.SendErrorJSON(w, r, http.StatusInternalServerError, errors.New("empty credential store"), "no credential store")
rest.SendErrorJSON(w, r, p.L, http.StatusInternalServerError, errors.New("empty credential store"), "no credential store")
return
}
ok, err := p.CredChecker.Check(user, password)
if err != nil {
rest.SendErrorJSON(w, r, http.StatusInternalServerError, err, "failed to access creds store")
rest.SendErrorJSON(w, r, p.L, http.StatusInternalServerError, err, "failed to access creds store")
return
}
if !ok {
rest.SendErrorJSON(w, r, http.StatusForbidden, nil, "incorrect user or password")
rest.SendErrorJSON(w, r, p.L, http.StatusForbidden, nil, "incorrect user or password")
return
}
claims := token.Claims{
@@ -66,7 +66,7 @@ func (p DirectHandler) LoginHandler(w http.ResponseWriter, r *http.Request) {
}
if err = p.TokenService.Set(w, claims); err != nil {
rest.SendErrorJSON(w, r, http.StatusInternalServerError, err, "failed to set token")
rest.SendErrorJSON(w, r, p.L, http.StatusInternalServerError, err, "failed to set token")
return
}
rest.RenderJSON(w, r, claims.User)
+13 -13
View File
@@ -81,13 +81,13 @@ func (p Oauth2Handler) LoginHandler(w http.ResponseWriter, r *http.Request) {
// make state (random) and store in session
state, err := randToken()
if err != nil {
rest.SendErrorJSON(w, r, http.StatusInternalServerError, err, "failed to make oauth2 state")
rest.SendErrorJSON(w, r, p.L, http.StatusInternalServerError, err, "failed to make oauth2 state")
return
}
cid, err := randToken()
if err != nil {
rest.SendErrorJSON(w, r, http.StatusInternalServerError, err, "failed to make claim's id")
rest.SendErrorJSON(w, r, p.L, http.StatusInternalServerError, err, "failed to make claim's id")
return
}
@@ -106,7 +106,7 @@ func (p Oauth2Handler) LoginHandler(w http.ResponseWriter, r *http.Request) {
}
if err := p.JwtService.Set(w, claims); err != nil {
rest.SendErrorJSON(w, r, http.StatusInternalServerError, err, "failed to set token")
rest.SendErrorJSON(w, r, p.L, http.StatusInternalServerError, err, "failed to set token")
return
}
@@ -122,32 +122,32 @@ func (p Oauth2Handler) LoginHandler(w http.ResponseWriter, r *http.Request) {
func (p Oauth2Handler) AuthHandler(w http.ResponseWriter, r *http.Request) {
oauthClaims, _, err := p.JwtService.Get(r)
if err != nil {
rest.SendErrorJSON(w, r, http.StatusInternalServerError, err, "failed to get token")
rest.SendErrorJSON(w, r, p.L, http.StatusInternalServerError, err, "failed to get token")
return
}
if oauthClaims.Handshake == nil {
rest.SendErrorJSON(w, r, http.StatusForbidden, nil, "invalid handshake token")
rest.SendErrorJSON(w, r, p.L, http.StatusForbidden, nil, "invalid handshake token")
return
}
retrievedState := oauthClaims.Handshake.State
if retrievedState == "" || retrievedState != r.URL.Query().Get("state") {
rest.SendErrorJSON(w, r, http.StatusForbidden, nil, "unexpected state")
rest.SendErrorJSON(w, r, p.L, http.StatusForbidden, nil, "unexpected state")
return
}
p.Logf("[DEBUG] token with state %s", retrievedState)
tok, err := p.conf.Exchange(context.Background(), r.URL.Query().Get("code"))
if err != nil {
rest.SendErrorJSON(w, r, http.StatusInternalServerError, err, "exchange failed")
rest.SendErrorJSON(w, r, p.L, http.StatusInternalServerError, err, "exchange failed")
return
}
client := p.conf.Client(context.Background(), tok)
uinfo, err := client.Get(p.infoURL)
if err != nil {
rest.SendErrorJSON(w, r, http.StatusServiceUnavailable, err, "failed to get client info")
rest.SendErrorJSON(w, r, p.L, http.StatusServiceUnavailable, err, "failed to get client info")
return
}
@@ -159,13 +159,13 @@ func (p Oauth2Handler) AuthHandler(w http.ResponseWriter, r *http.Request) {
data, err := ioutil.ReadAll(uinfo.Body)
if err != nil {
rest.SendErrorJSON(w, r, http.StatusInternalServerError, err, "failed to read user info")
rest.SendErrorJSON(w, r, p.L, http.StatusInternalServerError, err, "failed to read user info")
return
}
jData := map[string]interface{}{}
if e := json.Unmarshal(data, &jData); e != nil {
rest.SendErrorJSON(w, r, http.StatusInternalServerError, err, "failed to unmarshal user info")
rest.SendErrorJSON(w, r, p.L, http.StatusInternalServerError, err, "failed to unmarshal user info")
return
}
p.Logf("[DEBUG] got raw user info %+v", jData)
@@ -173,13 +173,13 @@ func (p Oauth2Handler) AuthHandler(w http.ResponseWriter, r *http.Request) {
u := p.mapUser(jData, data)
u, err = setAvatar(p.AvatarSaver, u)
if err != nil {
rest.SendErrorJSON(w, r, http.StatusInternalServerError, err, "failed to save avatar to proxy")
rest.SendErrorJSON(w, r, p.L, http.StatusInternalServerError, err, "failed to save avatar to proxy")
return
}
cid, err := randToken()
if err != nil {
rest.SendErrorJSON(w, r, http.StatusInternalServerError, err, "failed to make claim's id")
rest.SendErrorJSON(w, r, p.L, http.StatusInternalServerError, err, "failed to make claim's id")
return
}
claims := token.Claims{
@@ -193,7 +193,7 @@ func (p Oauth2Handler) AuthHandler(w http.ResponseWriter, r *http.Request) {
}
if err = p.JwtService.Set(w, claims); err != nil {
rest.SendErrorJSON(w, r, http.StatusInternalServerError, err, "failed to set token")
rest.SendErrorJSON(w, r, p.L, http.StatusInternalServerError, err, "failed to set token")
return
}
+1 -1
View File
@@ -46,5 +46,5 @@ func Setup(opts ...Option) {
def.skipCallers = 2
}
// Default returns pre-constructed def logger (debug on, callers disabled)
// Default returns pre-constructed def logger (debug off, callers disabled)
func Default() L { return def }
+23 -16
View File
@@ -53,18 +53,19 @@ func (l *Logger) Logf(format string, args ...interface{}) {
// format timestamp with or without msecs
ts := func() (res string) {
if l.msec {
return l.now().Format("2006/01/02 15:04:05.000 ")
return l.now().Format("2006/01/02 15:04:05.000")
}
return l.now().Format("2006/01/02 15:04:05 ")
return l.now().Format("2006/01/02 15:04:05")
}
lv, msg := l.extractLevel(fmt.Sprintf(format, args...))
if lv == "DEBUG " && !l.dbg {
if lv == "DEBUG" && !l.dbg {
return
}
var bld strings.Builder
bld.WriteString(ts())
bld.WriteString(lv)
bld.WriteString(l.formatLevel(lv))
bld.WriteString(" ")
if l.dbg && (l.callerFile || l.callerFunc) {
if pc, file, line, ok := runtime.Caller(l.skipCallers); ok {
@@ -95,18 +96,19 @@ func (l *Logger) Logf(format string, args ...interface{}) {
l.stdout.Write(msgb) //nolint
switch lv {
case "PANIC ", "FATAL ":
case "PANIC", "FATAL":
l.stderr.Write(msgb) //nolint
bld.WriteString("\n") //nolint
l.stderr.Write(getDump()) //nolint
l.fatal()
case "ERROR ":
case "ERROR":
l.stderr.Write(msgb) //nolint
}
l.lock.Unlock()
}
func (l *Logger) extractLevel(line string) (level, msg string) {
func (l *Logger) formatLevel(lv string) string {
brace := func(b string) string {
if l.levelBraces {
@@ -115,19 +117,24 @@ func (l *Logger) extractLevel(line string) (level, msg string) {
return ""
}
spaces := " "
if lv == "" {
return ""
}
spaces := ""
if len(lv) == 4 {
spaces = " "
}
return " " + brace("[") + lv + brace("]") + spaces
}
func (l *Logger) extractLevel(line string) (level, msg string) {
for _, lv := range levels {
if strings.HasPrefix(line, lv) {
if len(lv) == 4 {
spaces = " "
}
return brace("[") + lv + brace("]") + spaces, line[len(lv)+1:]
return lv, line[len(lv)+1:]
}
if strings.HasPrefix(line, "["+lv+"]") {
if len(lv) == 4 {
spaces = " "
}
return brace("[") + lv + brace("]") + spaces, line[len(lv)+3:]
return lv, line[len(lv)+3:]
}
}
return "", line
+6 -5
View File
@@ -6,13 +6,14 @@ go:
install: true
before_install:
- export TZ=America/Chicago
- curl -L https://git.io/vp6lP | sh
- go get github.com/mattn/goveralls
- go get gopkg.in/alecthomas/gometalinter.v2
- $GOPATH/bin/gometalinter.v2 --install
- export PATH=$(pwd)/bin:$PATH
script:
- GO111MODULE=on go get ./...
- GO111MODULE=on go mod vendor
- GO111MODULE=on go test -v -mod=vendor ./...
- $GOPATH/bin/gometalinter.v2 --exclude=test --exclude=mock --exclude=vendor ./...
- $GOPATH/bin/goveralls -service=travis-ci
- GO111MODULE=on go test -v -mod=vendor -covermode=count -coverprofile=profile.cov ./... || travis_terminate 1
- ./bin/gometalinter --deadline=120s --exclude=test --exclude=mock --exclude=vendor --exclude=_example --disable-all --enable=errcheck --enable=vet --enable=vetshadow --enable=megacheck --enable=ineffassign --enable=varcheck --enable=unconvert --enable=deadcode --enable=interfacer --enable=gotype ./... || travis_terminate 1;
- $GOPATH/bin/goveralls -coverprofile=profile.cov -service=travis-ci
-1
View File
@@ -2,7 +2,6 @@ module github.com/go-pkgz/rest
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-pkgz/lgr v0.1.3
github.com/hashicorp/golang-lru v0.5.0
github.com/pkg/errors v0.8.0
github.com/stretchr/testify v1.3.0
-2
View File
@@ -1,8 +1,6 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-pkgz/lgr v0.1.3 h1:jGPFbzfXWSt3r8qyjXnuKFNM6J10bs3YnD8wPSGdsww=
github.com/go-pkgz/lgr v0.1.3/go.mod h1:hBM1NM/SoYdlrykgdgJWGrZ/TM/XaZIjRbJfx7NkMm8=
github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
+6 -3
View File
@@ -3,16 +3,19 @@ package rest
import (
"errors"
"fmt"
"log"
"net/http"
"net/url"
"runtime"
"strings"
"github.com/go-pkgz/rest/logger"
)
// SendErrorJSON sends {error: msg} with error code and logging error and caller
func SendErrorJSON(w http.ResponseWriter, r *http.Request, code int, err error, msg string) {
log.Printf("[DEBUG] %s", errDetailsMsg(r, code, err, msg))
func SendErrorJSON(w http.ResponseWriter, r *http.Request, l logger.Backend, code int, err error, msg string) {
if l != nil {
l.Logf("%s", errDetailsMsg(r, code, err, msg))
}
w.WriteHeader(code)
RenderJSON(w, r, JSON{"error": msg})
}
+16 -6
View File
@@ -5,14 +5,13 @@ import (
"bytes"
"fmt"
"io/ioutil"
"log"
"net"
"net/http"
"net/url"
"regexp"
"strings"
"time"
"github.com/go-pkgz/lgr"
)
var reMultWhtsp = regexp.MustCompile(`[\s\p{Zs}]{2,}`)
@@ -24,7 +23,7 @@ type Middleware struct {
flags []Flag
ipFn func(ip string) string
userFn func(r *http.Request) (string, error)
log lgr.L
log Backend
}
// Flag type
@@ -38,9 +37,20 @@ const (
None
)
// Logger returns default logger middleware
// Backend is logging backend
type Backend interface {
Logf(format string, args ...interface{})
}
type stdBackend struct{}
func (s stdBackend) Logf(format string, args ...interface{}) {
log.Printf(format, args...)
}
// Logger returns default logger middleware with REST prefix
func Logger(next http.Handler) http.Handler {
l := New(Flags(All), Prefix("REST"))
l := New(Prefix("REST"))
return l.Handler(next)
}
@@ -51,7 +61,7 @@ func New(options ...Option) *Middleware {
prefix: "",
maxBodySize: 1024,
flags: []Flag{All},
log: lgr.Default(),
log: stdBackend{},
}
for _, opt := range options {
opt(&res)
+1 -3
View File
@@ -2,8 +2,6 @@ package logger
import (
"net/http"
"github.com/go-pkgz/lgr"
)
// Option func type
@@ -47,7 +45,7 @@ func UserFn(userFn func(r *http.Request) (string, error)) Option {
}
// Log functional option defines loging backend.
func Log(log lgr.L) Option {
func Log(log Backend) Option {
return func(l *Middleware) {
l.log = log
}
+14 -12
View File
@@ -6,7 +6,7 @@ import (
"runtime/debug"
"strings"
log "github.com/go-pkgz/lgr"
"github.com/go-pkgz/rest/logger"
)
// AppInfo adds custom app-info to the response header
@@ -42,16 +42,18 @@ func Ping(next http.Handler) http.Handler {
}
// Recoverer is a middleware that recovers from panics, logs the panic and returns a HTTP 500 status if possible.
func Recoverer(next http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
defer func() {
if rvr := recover(); rvr != nil {
log.Printf("[WARN] request panic, %v", rvr)
log.Print(string(debug.Stack()))
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
}
}()
next.ServeHTTP(w, r)
func Recoverer(l logger.Backend) func(http.Handler) http.Handler {
return func(h http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
defer func() {
if rvr := recover(); rvr != nil {
l.Logf("request panic, %v", rvr)
l.Logf(string(debug.Stack()))
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
}
}()
h.ServeHTTP(w, r)
}
return http.HandlerFunc(fn)
}
return http.HandlerFunc(fn)
}
+1 -1
View File
@@ -48,7 +48,7 @@ func RenderJSONWithHTML(w http.ResponseWriter, r *http.Request, v interface{}) e
data, err := encodeJSONWithHTML(v)
if err != nil {
return errors.Wrap(err, "json encoding failed")
return err
}
return RenderJSONFromBytes(w, r, data)
}