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() } }