You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
OneAuth/libs/base/api_handler.go

92 lines
1.9 KiB
Go

package base
import (
"errors"
"github.com/json-iterator/go"
"github.com/veypi/OneAuth/libs/oerr"
"github.com/veypi/OneAuth/libs/tools"
"github.com/veypi/OneBD"
"github.com/veypi/OneBD/rfc"
"github.com/veypi/utils/log"
"gorm.io/gorm"
"strconv"
"sync"
"time"
)
var json = jsoniter.ConfigFastest
func JSONResponse(m OneBD.Meta, data interface{}, err error) {
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
err = oerr.ResourceNotExist
}
}
if m.Method() == rfc.MethodHead {
if err != nil {
m.SetHeader("status", "0")
m.SetHeader("code", strconv.Itoa(int(oerr.OfType(err.Error()))))
m.SetHeader("err", err.Error())
} else {
m.SetHeader("status", "1")
}
return
}
res := map[string]interface{}{
"status": 1,
}
if err != nil {
res["status"] = 0
res["code"] = oerr.OfType(err.Error())
res["err"] = err.Error()
} else {
res["status"] = 1
res["content"] = data
}
p, err := json.Marshal(res)
if err != nil {
log.Warn().Err(err).Msg("encode json data error")
return
}
_, _ = m.Write(p)
}
type ApiHandler struct {
OneBD.BaseHandler
UserHandler
}
func (h *ApiHandler) Init(m OneBD.Meta) error {
return tools.MultiIniter(m, &h.BaseHandler, &h.UserHandler)
}
func (h *ApiHandler) OnResponse(data interface{}) {
JSONResponse(h.Meta(), data, nil)
}
func (h *ApiHandler) OnError(err error) {
log.WithNoCaller.Warn().Err(err).Msg(h.Meta().RequestPath())
JSONResponse(h.Meta(), nil, err)
}
var ioNumLimit = make(map[string]time.Time)
var limitLocker = sync.RWMutex{}
func (h *ApiHandler) SetAccessDelta(d time.Duration) error {
// 尽量对写操作加频率限制
now := time.Now()
limitLocker.Lock()
label := h.Meta().RemoteAddr() + h.Meta().RequestPath()
last, ok := ioNumLimit[label]
defer func() {
ioNumLimit[label] = now
limitLocker.Unlock()
}()
if !ok {
return nil
} else if now.Sub(last) >= d {
return nil
}
return oerr.AccessTooFast
}