replace zxq.co/ripple/hanayo
This commit is contained in:
106
vendor/zxq.co/ripple/rippleapi/app/router.go
vendored
Normal file
106
vendor/zxq.co/ripple/rippleapi/app/router.go
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/buaazp/fasthttprouter"
|
||||
"github.com/jmoiron/sqlx"
|
||||
"github.com/valyala/fasthttp"
|
||||
"zxq.co/ripple/rippleapi/common"
|
||||
)
|
||||
|
||||
type router struct {
|
||||
r *fasthttprouter.Router
|
||||
}
|
||||
|
||||
func (r router) Method(path string, f func(md common.MethodData) common.CodeMessager, privilegesNeeded ...int) {
|
||||
r.r.GET(path, wrap(Method(f, privilegesNeeded...)))
|
||||
}
|
||||
func (r router) POSTMethod(path string, f func(md common.MethodData) common.CodeMessager, privilegesNeeded ...int) {
|
||||
r.r.POST(path, wrap(Method(f, privilegesNeeded...)))
|
||||
}
|
||||
func (r router) Peppy(path string, a func(c *fasthttp.RequestCtx, db *sqlx.DB)) {
|
||||
r.r.GET(path, wrap(PeppyMethod(a)))
|
||||
}
|
||||
func (r router) GET(path string, handle fasthttp.RequestHandler) {
|
||||
r.r.GET(path, wrap(handle))
|
||||
}
|
||||
func (r router) PlainGET(path string, handle fasthttp.RequestHandler) {
|
||||
r.r.GET(path, handle)
|
||||
}
|
||||
|
||||
const (
|
||||
// \x1b is escape code for ESC
|
||||
// <ESC>[<n>m is escape sequence for a certain colour
|
||||
// no IP is written out because of the hundreds of possible ways to pass IPs
|
||||
// to a request when using a reverse proxy
|
||||
// this is partly inspired from gin, though made even more simplistic.
|
||||
fmtString = "%s | %15s |\x1b[%sm %3d \x1b[0m %-7s %s\n"
|
||||
// a kind of human readable RFC3339
|
||||
timeFormat = "2006-01-02 15:04:05"
|
||||
// color reference
|
||||
// http://misc.flogisoft.com/bash/tip_colors_and_formatting
|
||||
colorOk = "42" // green
|
||||
colorError = "41" // red
|
||||
)
|
||||
|
||||
// wrap returns a function that wraps around handle, providing middleware
|
||||
// functionality to apply to all API calls, which is to say:
|
||||
// - logging
|
||||
// - panic recovery (reporting to sentry)
|
||||
// - gzipping
|
||||
func wrap(handle fasthttp.RequestHandler) fasthttp.RequestHandler {
|
||||
return func(c *fasthttp.RequestCtx) {
|
||||
start := time.Now()
|
||||
|
||||
doggo.Incr("requests", nil, 1)
|
||||
|
||||
defer func() {
|
||||
if rval := recover(); rval != nil {
|
||||
var err error
|
||||
switch rval := rval.(type) {
|
||||
case string:
|
||||
err = errors.New(rval)
|
||||
case error:
|
||||
err = rval
|
||||
default:
|
||||
err = fmt.Errorf("%v - %#v", rval, rval)
|
||||
}
|
||||
common.Err(c, err)
|
||||
c.SetStatusCode(500)
|
||||
c.SetBodyString(`{ "code": 500, "message": "something really bad happened" }`)
|
||||
}
|
||||
|
||||
// switch color to colorError if statusCode is in [500;600)
|
||||
color := colorOk
|
||||
statusCode := c.Response.StatusCode()
|
||||
if statusCode >= 500 && statusCode < 600 {
|
||||
color = colorError
|
||||
}
|
||||
|
||||
if bytes.Contains(c.Request.Header.Peek("Accept-Encoding"), s2b("gzip")) {
|
||||
c.Response.Header.Add("Content-Encoding", "gzip")
|
||||
c.Response.Header.Add("Vary", "Accept-Encoding")
|
||||
b := c.Response.Body()
|
||||
c.Response.ResetBody()
|
||||
fasthttp.WriteGzip(c.Response.BodyWriter(), b)
|
||||
}
|
||||
|
||||
// print stuff
|
||||
fmt.Printf(
|
||||
fmtString,
|
||||
time.Now().Format(timeFormat),
|
||||
time.Since(start).String(),
|
||||
color,
|
||||
statusCode,
|
||||
c.Method(),
|
||||
c.Path(),
|
||||
)
|
||||
}()
|
||||
|
||||
handle(c)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user