| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | package api | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2020-11-19 20:34:28 +08:00
										 |  |  | 	"errors" | 
					
						
							| 
									
										
										
										
											2015-01-29 19:10:34 +08:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | 	"net/http" | 
					
						
							| 
									
										
										
										
											2018-05-24 21:26:27 +08:00
										 |  |  | 	"strconv" | 
					
						
							|  |  |  | 	"time" | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-04 19:57:20 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/models" | 
					
						
							| 
									
										
										
										
											2023-01-27 15:50:36 +08:00
										 |  |  | 	contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model" | 
					
						
							| 
									
										
										
										
											2018-05-24 21:26:27 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/rendering" | 
					
						
							| 
									
										
										
										
											2015-02-05 17:37:13 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/util" | 
					
						
							| 
									
										
										
										
											2021-10-11 20:30:59 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/web" | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-27 15:50:36 +08:00
										 |  |  | func (hs *HTTPServer) RenderToPng(c *contextmodel.ReqContext) { | 
					
						
							| 
									
										
										
										
											2019-01-29 05:18:48 +08:00
										 |  |  | 	queryReader, err := util.NewURLQueryReader(c.Req.URL) | 
					
						
							| 
									
										
										
										
											2017-11-28 22:20:22 +08:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2020-12-16 02:09:04 +08:00
										 |  |  | 		c.Handle(hs.Cfg, 400, "Render parameters error", err) | 
					
						
							| 
									
										
										
										
											2017-11-28 22:20:22 +08:00
										 |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-05-24 21:26:27 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-21 07:14:13 +08:00
										 |  |  | 	queryParams := fmt.Sprintf("?%s", c.Req.URL.RawQuery) | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-24 21:26:27 +08:00
										 |  |  | 	width, err := strconv.Atoi(queryReader.Get("width", "800")) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2020-12-16 02:09:04 +08:00
										 |  |  | 		c.Handle(hs.Cfg, 400, "Render parameters error", fmt.Errorf("cannot parse width as int: %s", err)) | 
					
						
							| 
									
										
										
										
											2018-05-24 21:26:27 +08:00
										 |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	height, err := strconv.Atoi(queryReader.Get("height", "400")) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2020-12-16 02:09:04 +08:00
										 |  |  | 		c.Handle(hs.Cfg, 400, "Render parameters error", fmt.Errorf("cannot parse height as int: %s", err)) | 
					
						
							| 
									
										
										
										
											2018-05-24 21:26:27 +08:00
										 |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	timeout, err := strconv.Atoi(queryReader.Get("timeout", "60")) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2020-12-16 02:09:04 +08:00
										 |  |  | 		c.Handle(hs.Cfg, 400, "Render parameters error", fmt.Errorf("cannot parse timeout as int: %s", err)) | 
					
						
							| 
									
										
										
										
											2018-05-24 21:26:27 +08:00
										 |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-21 22:16:41 +08:00
										 |  |  | 	scale, err := strconv.ParseFloat(queryReader.Get("scale", "1"), 64) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2020-12-16 02:09:04 +08:00
										 |  |  | 		c.Handle(hs.Cfg, 400, "Render parameters error", fmt.Errorf("cannot parse scale as float: %s", err)) | 
					
						
							| 
									
										
										
										
											2020-04-21 22:16:41 +08:00
										 |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	headers := http.Header{} | 
					
						
							|  |  |  | 	acceptLanguageHeader := c.Req.Header.Values("Accept-Language") | 
					
						
							|  |  |  | 	if len(acceptLanguageHeader) > 0 { | 
					
						
							|  |  |  | 		headers["Accept-Language"] = acceptLanguageHeader | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-24 21:26:27 +08:00
										 |  |  | 	result, err := hs.RenderService.Render(c.Req.Context(), rendering.Opts{ | 
					
						
							| 
									
										
										
										
											2022-01-27 06:02:19 +08:00
										 |  |  | 		TimeoutOpts: rendering.TimeoutOpts{ | 
					
						
							|  |  |  | 			Timeout: time.Duration(timeout) * time.Second, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		AuthOpts: rendering.AuthOpts{ | 
					
						
							| 
									
										
										
										
											2022-08-11 19:28:55 +08:00
										 |  |  | 			OrgID:   c.OrgID, | 
					
						
							|  |  |  | 			UserID:  c.UserID, | 
					
						
							| 
									
										
										
										
											2022-01-27 06:02:19 +08:00
										 |  |  | 			OrgRole: c.OrgRole, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2020-04-21 22:16:41 +08:00
										 |  |  | 		Width:             width, | 
					
						
							|  |  |  | 		Height:            height, | 
					
						
							| 
									
										
										
										
											2021-10-11 20:30:59 +08:00
										 |  |  | 		Path:              web.Params(c.Req)["*"] + queryParams, | 
					
						
							| 
									
										
										
										
											2020-04-21 22:16:41 +08:00
										 |  |  | 		Timezone:          queryReader.Get("tz", ""), | 
					
						
							|  |  |  | 		Encoding:          queryReader.Get("encoding", ""), | 
					
						
							| 
									
										
										
										
											2020-04-27 23:25:08 +08:00
										 |  |  | 		ConcurrentLimit:   hs.Cfg.RendererConcurrentRequestLimit, | 
					
						
							| 
									
										
										
										
											2020-04-21 22:16:41 +08:00
										 |  |  | 		DeviceScaleFactor: scale, | 
					
						
							|  |  |  | 		Headers:           headers, | 
					
						
							| 
									
										
										
										
											2022-02-09 17:23:32 +08:00
										 |  |  | 		Theme:             models.ThemeDark, | 
					
						
							| 
									
										
										
										
											2022-01-27 06:02:19 +08:00
										 |  |  | 	}, nil) | 
					
						
							| 
									
										
										
										
											2020-11-19 20:34:28 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		if errors.Is(err, rendering.ErrTimeout) { | 
					
						
							| 
									
										
										
										
											2020-12-16 02:09:04 +08:00
										 |  |  | 			c.Handle(hs.Cfg, 500, err.Error(), err) | 
					
						
							| 
									
										
										
										
											2020-11-19 20:34:28 +08:00
										 |  |  | 			return | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-06-07 21:15:13 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-16 02:09:04 +08:00
										 |  |  | 		c.Handle(hs.Cfg, 500, "Rendering failed.", err) | 
					
						
							| 
									
										
										
										
											2015-02-05 19:23:24 +08:00
										 |  |  | 		return | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	c.Resp.Header().Set("Content-Type", "image/png") | 
					
						
							| 
									
										
										
										
											2021-09-01 17:18:30 +08:00
										 |  |  | 	http.ServeFile(c.Resp, c.Req, result.FilePath) | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | } |