package frame import ( "github.com/gin-gonic/gin" "reflect" "sync" ) const RspBodyKey = "rsp_key" var responderList []Responder var once_resp_list sync.Once func get_responder_list() []Responder { once_resp_list.Do(func() { responderList = []Responder{(StringResponder)(nil), (JsonResponder)(nil), (VoidResponder)(nil), (XMLResponder)(nil), (FileResponder)(nil), } }) return responderList } func Convert(handler interface{}) gin.HandlerFunc { h_ref := reflect.ValueOf(handler) for _, r := range get_responder_list() { r_ref := reflect.TypeOf(r) if h_ref.Type().ConvertibleTo(r_ref) { return h_ref.Convert(r_ref).Interface().(Responder).RespondTo() } } return nil } type Responder interface { RespondTo() gin.HandlerFunc } type VoidResponder func(*Context) func (s VoidResponder) RespondTo() gin.HandlerFunc { return func(c *gin.Context) { st := &Context{c} s(st) body := c.Writer.(*BodyLogWriter).Body cat := st.Writer.Header().Get("Content-Type") if body.String() == "" && cat != "application/octet-stream" { st.Ok(body) } } } type StringResponder func(*Context) string func (s StringResponder) RespondTo() gin.HandlerFunc { return func(c *gin.Context) { body := s(&Context{c}) c.Set(RspBodyKey, body) c.String(200, body) } } type Json interface{} type JsonResponder func(*Context) Json func (j JsonResponder) RespondTo() gin.HandlerFunc { return func(c *gin.Context) { body := j(&Context{c}) c.Set(RspBodyKey, body) c.JSON(200, body) } } type XML interface{} type XMLResponder func(*Context) XML func (s XMLResponder) RespondTo() gin.HandlerFunc { return func(c *gin.Context) { c.Writer.Header()["content-type"] = []string{"application/xml; charset=utf-8"} body := s(&Context{c}).(string) c.Set(RspBodyKey, body) c.String(200, body) } } type File struct { Data []byte ContentType string FileName string } type FileResponder func(*Context) File func (f FileResponder) RespondTo() gin.HandlerFunc { return func(c *gin.Context) { file := f(&Context{c}) c.Header("Content-Disposition", "attachment; filename="+file.FileName) c.Header("Content-Transfer-Encoding", "binary") c.Data(200, file.ContentType, file.Data) } }