| 
									
										
										
										
											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-10-09 22:07:28 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/auth/identity" | 
					
						
							| 
									
										
										
										
											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 { | 
					
						
							| 
									
										
										
										
											2024-02-28 00:39:51 +08:00
										 |  |  | 		c.Handle(hs.Cfg, http.StatusBadRequest, "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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-26 20:27:34 +08:00
										 |  |  | 	width := c.QueryInt("width") | 
					
						
							|  |  |  | 	if width == 0 { | 
					
						
							|  |  |  | 		width = hs.Cfg.RendererDefaultImageWidth | 
					
						
							| 
									
										
										
										
											2018-05-24 21:26:27 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-26 20:27:34 +08:00
										 |  |  | 	height := c.QueryInt("height") | 
					
						
							|  |  |  | 	if height == 0 { | 
					
						
							|  |  |  | 		height = hs.Cfg.RendererDefaultImageHeight | 
					
						
							| 
									
										
										
										
											2018-05-24 21:26:27 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	timeout, err := strconv.Atoi(queryReader.Get("timeout", "60")) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2024-02-28 00:39:51 +08:00
										 |  |  | 		c.Handle(hs.Cfg, http.StatusBadRequest, "Render parameters error", fmt.Errorf("cannot parse timeout as int: %s", err)) | 
					
						
							| 
									
										
										
										
											2018-05-24 21:26:27 +08:00
										 |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-26 20:27:34 +08:00
										 |  |  | 	scale := c.QueryFloat64("scale") | 
					
						
							|  |  |  | 	if scale == 0 { | 
					
						
							|  |  |  | 		scale = hs.Cfg.RendererDefaultImageScale | 
					
						
							| 
									
										
										
										
											2020-04-21 22:16:41 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	headers := http.Header{} | 
					
						
							|  |  |  | 	acceptLanguageHeader := c.Req.Header.Values("Accept-Language") | 
					
						
							|  |  |  | 	if len(acceptLanguageHeader) > 0 { | 
					
						
							|  |  |  | 		headers["Accept-Language"] = acceptLanguageHeader | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-09 22:07:28 +08:00
										 |  |  | 	userID, errID := identity.UserIdentifier(c.SignedInUser.GetNamespacedID()) | 
					
						
							|  |  |  | 	if errID != nil { | 
					
						
							|  |  |  | 		hs.log.Error("Failed to parse user id", "err", errID) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-08 20:09:34 +08:00
										 |  |  | 	encoding := queryReader.Get("encoding", "") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	result, err := hs.RenderService.Render(c.Req.Context(), rendering.RenderPNG, rendering.Opts{ | 
					
						
							| 
									
										
										
										
											2022-01-27 06:02:19 +08:00
										 |  |  | 		TimeoutOpts: rendering.TimeoutOpts{ | 
					
						
							|  |  |  | 			Timeout: time.Duration(timeout) * time.Second, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		AuthOpts: rendering.AuthOpts{ | 
					
						
							| 
									
										
										
										
											2023-10-06 17:34:36 +08:00
										 |  |  | 			OrgID:   c.SignedInUser.GetOrgID(), | 
					
						
							| 
									
										
										
										
											2023-10-09 22:07:28 +08:00
										 |  |  | 			UserID:  userID, | 
					
						
							|  |  |  | 			OrgRole: c.SignedInUser.GetOrgRole(), | 
					
						
							| 
									
										
										
										
											2022-01-27 06:02:19 +08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											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", ""), | 
					
						
							| 
									
										
										
										
											2024-02-08 20:09:34 +08:00
										 |  |  | 		Encoding:          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) { | 
					
						
							| 
									
										
										
										
											2024-02-28 00:39:51 +08:00
										 |  |  | 			c.Handle(hs.Cfg, http.StatusInternalServerError, err.Error(), err) | 
					
						
							| 
									
										
										
										
											2020-11-19 20:34:28 +08:00
										 |  |  | 			return | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-06-07 21:15:13 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-28 00:39:51 +08:00
										 |  |  | 		c.Handle(hs.Cfg, http.StatusInternalServerError, "Rendering failed.", err) | 
					
						
							| 
									
										
										
										
											2015-02-05 19:23:24 +08:00
										 |  |  | 		return | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-08 20:09:34 +08:00
										 |  |  | 	if encoding == "pdf" { | 
					
						
							|  |  |  | 		c.Resp.Header().Set("Content-Type", "application/pdf") | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		c.Resp.Header().Set("Content-Type", "image/png") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-18 20:21:57 +08:00
										 |  |  | 	c.Resp.Header().Set("Cache-Control", "private") | 
					
						
							| 
									
										
										
										
											2021-09-01 17:18:30 +08:00
										 |  |  | 	http.ServeFile(c.Resp, c.Req, result.FilePath) | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | } |