common.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. package api
  2. import (
  3. "encoding/json"
  4. "net/http"
  5. "github.com/grafana/grafana/pkg/metrics"
  6. "github.com/grafana/grafana/pkg/middleware"
  7. "github.com/grafana/grafana/pkg/setting"
  8. "gopkg.in/macaron.v1"
  9. )
  10. var (
  11. NotFound = func() Response {
  12. return ApiError(404, "Not found", nil)
  13. }
  14. ServerError = func(err error) Response {
  15. return ApiError(500, "Server error", err)
  16. }
  17. )
  18. type Response interface {
  19. WriteTo(ctx *middleware.Context)
  20. }
  21. type NormalResponse struct {
  22. status int
  23. body []byte
  24. header http.Header
  25. errMessage string
  26. err error
  27. }
  28. func wrap(action interface{}) macaron.Handler {
  29. return func(c *middleware.Context) {
  30. var res Response
  31. val, err := c.Invoke(action)
  32. if err == nil && val != nil && len(val) > 0 {
  33. res = val[0].Interface().(Response)
  34. } else {
  35. res = ServerError(err)
  36. }
  37. res.WriteTo(c)
  38. }
  39. }
  40. func (r *NormalResponse) WriteTo(ctx *middleware.Context) {
  41. if r.err != nil {
  42. ctx.Logger.Error(r.errMessage, "error", r.err)
  43. }
  44. header := ctx.Resp.Header()
  45. for k, v := range r.header {
  46. header[k] = v
  47. }
  48. ctx.Resp.WriteHeader(r.status)
  49. ctx.Resp.Write(r.body)
  50. }
  51. func (r *NormalResponse) Cache(ttl string) *NormalResponse {
  52. return r.Header("Cache-Control", "public,max-age="+ttl)
  53. }
  54. func (r *NormalResponse) Header(key, value string) *NormalResponse {
  55. r.header.Set(key, value)
  56. return r
  57. }
  58. // functions to create responses
  59. func Empty(status int) *NormalResponse {
  60. return Respond(status, nil)
  61. }
  62. func Json(status int, body interface{}) *NormalResponse {
  63. return Respond(status, body).Header("Content-Type", "application/json")
  64. }
  65. func ApiSuccess(message string) *NormalResponse {
  66. resp := make(map[string]interface{})
  67. resp["message"] = message
  68. return Respond(200, resp)
  69. }
  70. func ApiError(status int, message string, err error) *NormalResponse {
  71. data := make(map[string]interface{})
  72. switch status {
  73. case 404:
  74. metrics.M_Api_Status_404.Inc(1)
  75. data["message"] = "Not Found"
  76. case 500:
  77. metrics.M_Api_Status_500.Inc(1)
  78. data["message"] = "Internal Server Error"
  79. }
  80. if message != "" {
  81. data["message"] = message
  82. }
  83. if err != nil {
  84. if setting.Env != setting.PROD {
  85. data["error"] = err.Error()
  86. }
  87. }
  88. resp := Json(status, data)
  89. if err != nil {
  90. resp.errMessage = message
  91. resp.err = err
  92. }
  93. return resp
  94. }
  95. func Respond(status int, body interface{}) *NormalResponse {
  96. var b []byte
  97. var err error
  98. switch t := body.(type) {
  99. case []byte:
  100. b = t
  101. case string:
  102. b = []byte(t)
  103. default:
  104. if b, err = json.Marshal(body); err != nil {
  105. return ApiError(500, "body json marshal", err)
  106. }
  107. }
  108. return &NormalResponse{
  109. body: b,
  110. status: status,
  111. header: make(http.Header),
  112. }
  113. }