| 
									
										
										
										
											2015-05-18 23:28:15 +08:00
										 |  |  | package api | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"encoding/json" | 
					
						
							|  |  |  | 	"net/http" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/grafana/grafana/pkg/middleware" | 
					
						
							|  |  |  | 	"github.com/grafana/grafana/pkg/setting" | 
					
						
							| 
									
										
										
										
											2016-01-13 22:38:54 +08:00
										 |  |  | 	"gopkg.in/macaron.v1" | 
					
						
							| 
									
										
										
										
											2015-05-18 23:28:15 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var ( | 
					
						
							| 
									
										
										
										
											2016-06-03 18:50:51 +08:00
										 |  |  | 	NotFound = func() Response { | 
					
						
							|  |  |  | 		return ApiError(404, "Not found", nil) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-06-03 22:15:36 +08:00
										 |  |  | 	ServerError = func(err error) Response { | 
					
						
							|  |  |  | 		return ApiError(500, "Server error", err) | 
					
						
							| 
									
										
										
										
											2016-06-03 18:50:51 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-05-18 23:28:15 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type Response interface { | 
					
						
							| 
									
										
										
										
											2016-06-11 18:16:33 +08:00
										 |  |  | 	WriteTo(ctx *middleware.Context) | 
					
						
							| 
									
										
										
										
											2015-05-18 23:28:15 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type NormalResponse struct { | 
					
						
							| 
									
										
										
										
											2016-06-11 18:16:33 +08:00
										 |  |  | 	status     int | 
					
						
							|  |  |  | 	body       []byte | 
					
						
							|  |  |  | 	header     http.Header | 
					
						
							|  |  |  | 	errMessage string | 
					
						
							|  |  |  | 	err        error | 
					
						
							| 
									
										
										
										
											2015-05-18 23:28:15 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-19 01:06:19 +08:00
										 |  |  | func wrap(action interface{}) macaron.Handler { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-18 23:28:15 +08:00
										 |  |  | 	return func(c *middleware.Context) { | 
					
						
							| 
									
										
										
										
											2015-05-19 01:06:19 +08:00
										 |  |  | 		var res Response | 
					
						
							|  |  |  | 		val, err := c.Invoke(action) | 
					
						
							|  |  |  | 		if err == nil && val != nil && len(val) > 0 { | 
					
						
							|  |  |  | 			res = val[0].Interface().(Response) | 
					
						
							|  |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2016-06-03 22:15:36 +08:00
										 |  |  | 			res = ServerError(err) | 
					
						
							| 
									
										
										
										
											2015-05-18 23:28:15 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-05-19 01:06:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-11 18:16:33 +08:00
										 |  |  | 		res.WriteTo(c) | 
					
						
							| 
									
										
										
										
											2015-05-18 23:28:15 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-11 18:16:33 +08:00
										 |  |  | func (r *NormalResponse) WriteTo(ctx *middleware.Context) { | 
					
						
							|  |  |  | 	if r.err != nil { | 
					
						
							|  |  |  | 		ctx.Logger.Error(r.errMessage, "error", r.err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	header := ctx.Resp.Header() | 
					
						
							| 
									
										
										
										
											2015-05-18 23:28:15 +08:00
										 |  |  | 	for k, v := range r.header { | 
					
						
							|  |  |  | 		header[k] = v | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-06-11 18:16:33 +08:00
										 |  |  | 	ctx.Resp.WriteHeader(r.status) | 
					
						
							|  |  |  | 	ctx.Resp.Write(r.body) | 
					
						
							| 
									
										
										
										
											2015-05-18 23:28:15 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (r *NormalResponse) Cache(ttl string) *NormalResponse { | 
					
						
							|  |  |  | 	return r.Header("Cache-Control", "public,max-age="+ttl) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (r *NormalResponse) Header(key, value string) *NormalResponse { | 
					
						
							|  |  |  | 	r.header.Set(key, value) | 
					
						
							|  |  |  | 	return r | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // functions to create responses
 | 
					
						
							|  |  |  | func Empty(status int) *NormalResponse { | 
					
						
							|  |  |  | 	return Respond(status, nil) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func Json(status int, body interface{}) *NormalResponse { | 
					
						
							|  |  |  | 	return Respond(status, body).Header("Content-Type", "application/json") | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-19 01:06:19 +08:00
										 |  |  | func ApiSuccess(message string) *NormalResponse { | 
					
						
							|  |  |  | 	resp := make(map[string]interface{}) | 
					
						
							|  |  |  | 	resp["message"] = message | 
					
						
							| 
									
										
										
										
											2016-10-01 22:52:35 +08:00
										 |  |  | 	return Json(200, resp) | 
					
						
							| 
									
										
										
										
											2015-05-19 01:06:19 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-18 23:28:15 +08:00
										 |  |  | func ApiError(status int, message string, err error) *NormalResponse { | 
					
						
							| 
									
										
										
										
											2016-06-11 18:16:33 +08:00
										 |  |  | 	data := make(map[string]interface{}) | 
					
						
							| 
									
										
										
										
											2015-05-18 23:28:15 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	switch status { | 
					
						
							|  |  |  | 	case 404: | 
					
						
							| 
									
										
										
										
											2016-06-11 18:16:33 +08:00
										 |  |  | 		data["message"] = "Not Found" | 
					
						
							| 
									
										
										
										
											2015-05-18 23:28:15 +08:00
										 |  |  | 	case 500: | 
					
						
							| 
									
										
										
										
											2016-06-11 18:16:33 +08:00
										 |  |  | 		data["message"] = "Internal Server Error" | 
					
						
							| 
									
										
										
										
											2015-05-18 23:28:15 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if message != "" { | 
					
						
							| 
									
										
										
										
											2016-06-11 18:16:33 +08:00
										 |  |  | 		data["message"] = message | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		if setting.Env != setting.PROD { | 
					
						
							|  |  |  | 			data["error"] = err.Error() | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	resp := Json(status, data) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		resp.errMessage = message | 
					
						
							|  |  |  | 		resp.err = err | 
					
						
							| 
									
										
										
										
											2015-05-18 23:28:15 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-11 18:16:33 +08:00
										 |  |  | 	return resp | 
					
						
							| 
									
										
										
										
											2015-05-18 23:28:15 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func Respond(status int, body interface{}) *NormalResponse { | 
					
						
							|  |  |  | 	var b []byte | 
					
						
							|  |  |  | 	var err error | 
					
						
							|  |  |  | 	switch t := body.(type) { | 
					
						
							|  |  |  | 	case []byte: | 
					
						
							|  |  |  | 		b = t | 
					
						
							|  |  |  | 	case string: | 
					
						
							|  |  |  | 		b = []byte(t) | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		if b, err = json.Marshal(body); err != nil { | 
					
						
							|  |  |  | 			return ApiError(500, "body json marshal", err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return &NormalResponse{ | 
					
						
							|  |  |  | 		body:   b, | 
					
						
							|  |  |  | 		status: status, | 
					
						
							|  |  |  | 		header: make(http.Header), | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } |