responder.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. package frame
  2. import (
  3. "github.com/gin-gonic/gin"
  4. "reflect"
  5. "sync"
  6. )
  7. const RspBodyKey = "rsp_key"
  8. var responderList []Responder
  9. var once_resp_list sync.Once
  10. func get_responder_list() []Responder {
  11. once_resp_list.Do(func() {
  12. responderList = []Responder{(StringResponder)(nil),
  13. (JsonResponder)(nil),
  14. (VoidResponder)(nil),
  15. (XMLResponder)(nil),
  16. (FileResponder)(nil),
  17. }
  18. })
  19. return responderList
  20. }
  21. func Convert(handler interface{}) gin.HandlerFunc {
  22. h_ref := reflect.ValueOf(handler)
  23. for _, r := range get_responder_list() {
  24. r_ref := reflect.TypeOf(r)
  25. if h_ref.Type().ConvertibleTo(r_ref) {
  26. return h_ref.Convert(r_ref).Interface().(Responder).RespondTo()
  27. }
  28. }
  29. return nil
  30. }
  31. type Responder interface {
  32. RespondTo() gin.HandlerFunc
  33. }
  34. type VoidResponder func(*Context)
  35. func (s VoidResponder) RespondTo() gin.HandlerFunc {
  36. return func(c *gin.Context) {
  37. st := &Context{c}
  38. s(st)
  39. body := c.Writer.(*BodyLogWriter).Body
  40. cat := st.Writer.Header().Get("Content-Type")
  41. if body.String() == "" && cat != "application/octet-stream" {
  42. st.Ok(body)
  43. }
  44. }
  45. }
  46. type StringResponder func(*Context) string
  47. func (s StringResponder) RespondTo() gin.HandlerFunc {
  48. return func(c *gin.Context) {
  49. body := s(&Context{c})
  50. c.Set(RspBodyKey, body)
  51. c.String(200, body)
  52. }
  53. }
  54. type Json interface{}
  55. type JsonResponder func(*Context) Json
  56. func (j JsonResponder) RespondTo() gin.HandlerFunc {
  57. return func(c *gin.Context) {
  58. body := j(&Context{c})
  59. c.Set(RspBodyKey, body)
  60. c.JSON(200, body)
  61. }
  62. }
  63. type XML interface{}
  64. type XMLResponder func(*Context) XML
  65. func (s XMLResponder) RespondTo() gin.HandlerFunc {
  66. return func(c *gin.Context) {
  67. c.Writer.Header()["content-type"] = []string{"application/xml; charset=utf-8"}
  68. body := s(&Context{c}).(string)
  69. c.Set(RspBodyKey, body)
  70. c.String(200, body)
  71. }
  72. }
  73. type File struct {
  74. Data []byte
  75. ContentType string
  76. FileName string
  77. }
  78. type FileResponder func(*Context) File
  79. func (f FileResponder) RespondTo() gin.HandlerFunc {
  80. return func(c *gin.Context) {
  81. file := f(&Context{c})
  82. c.Header("Content-Disposition", "attachment; filename="+file.FileName)
  83. c.Header("Content-Transfer-Encoding", "binary")
  84. c.Data(200, file.ContentType, file.Data)
  85. }
  86. }