common.go 2.2 KB

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