97 lines
2.0 KiB
Go
97 lines
2.0 KiB
Go
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()
|
|
}
|
|
}
|