first version
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
cc "rpirelay/internal/context"
|
||||
apierr "rpirelay/internal/errors"
|
||||
"rpirelay/internal/response"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func Initialize(secret string) *Middleware {
|
||||
return &Middleware{secret: secret}
|
||||
}
|
||||
|
||||
type Middleware struct {
|
||||
secret string
|
||||
}
|
||||
|
||||
func (m *Middleware) APIPanicCatch() cc.CustomHandler {
|
||||
return func(c *cc.C) {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
// build error
|
||||
// *****
|
||||
builder := new(strings.Builder)
|
||||
builder.WriteString("[API Error Catch]\n")
|
||||
|
||||
pc := make([]uintptr, 10)
|
||||
n := runtime.Callers(1, pc)
|
||||
frames := runtime.CallersFrames(pc[:n])
|
||||
|
||||
builder.WriteString("\n[Stack]\n")
|
||||
for {
|
||||
frame, more := frames.Next()
|
||||
builder.WriteString(fmt.Sprintf("%s\n\t%s:%d\n", frame.Func.Name(), frame.File, frame.Line))
|
||||
if !more {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
builder.WriteString("\n[Error]\n")
|
||||
builder.WriteString(fmt.Sprintf("%v\n", err))
|
||||
|
||||
fmt.Printf("%s\n", builder.String())
|
||||
// *****
|
||||
var e *apierr.APIError
|
||||
if converted, ok := err.(*apierr.APIError); ok {
|
||||
e = converted
|
||||
} else {
|
||||
e = apierr.ErrInternalError
|
||||
}
|
||||
|
||||
code := make([]response.MessageCode, 0)
|
||||
if c := e.Code(); c != nil {
|
||||
code = append(code, *c)
|
||||
}
|
||||
resp := response.Get(e.Status(), code...)
|
||||
|
||||
c.AbortWithStatusJSON(resp.Status, resp.Body)
|
||||
}
|
||||
}()
|
||||
|
||||
// 是json body 才做複製
|
||||
if c.GetHeader("content-type") == "application/json" {
|
||||
data, err := c.GetRawData()
|
||||
if err != nil {
|
||||
panic(apierr.ErrInternalError.SetErr(err))
|
||||
}
|
||||
|
||||
c.Request.Body = io.NopCloser(bytes.NewBuffer(data))
|
||||
c.Set("_RawBody", data)
|
||||
}
|
||||
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Middleware) Authorization() cc.CustomHandler {
|
||||
return func(c *cc.C) {
|
||||
auth := c.GetHeader("x-lawsnote-key")
|
||||
if auth == "" {
|
||||
panic(apierr.ErrUnauthorized.SetErr(errors.New("no lawsnote header found")))
|
||||
}
|
||||
|
||||
if auth != m.secret {
|
||||
panic(apierr.ErrForbidden.SetErr(errors.New("secret not match")))
|
||||
}
|
||||
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user