package query import ( "net/http" "strings" "github.com/grafana/grafana/pkg/services/ngalert/models" queryService "github.com/grafana/grafana/pkg/services/query" ) // Set of headers that we want to forward to the datasource api servers. Those are used i.e. for // cache control or identifying the source of the request. // // The headers related to grafana alerting (x-rule-*), should match the list at // https://github.com/grafana/grafana/blob/f8ae71e4583499dd461ebaed31451966be04220b/pkg/services/pluginsintegration/clientmiddleware/usealertingheaders_middleware.go#L23 // // The headers related to grafana query should match the list at // https://github.com/grafana/grafana/blob/f8ae71e4583499dd461ebaed31451966be04220b/pkg/services/pluginsintegration/clientmiddleware/tracing_header_middleware.go#L36 // // The usage of strings.ToLower is because the server would convert `FromAlert` to `Fromalert`. So the make matching // easier, we just match all headers in lower case. // // the headers X-Real-IP and X-Forwarded-For are used by the HostedGrafanaACHeaderMiddleware at // https://github.com/grafana/grafana/blob/f191acf8114ab79609fc631e0f01fe2b47371188/pkg/services/pluginsintegration/clientmiddleware/grafana_request_id_header_middleware.go#L107 // // the Cookie header is used by the CookiesMiddleware at // https://github.com/grafana/grafana/blob/326d374266077fbacc28c740f276748c636774f5/pkg/services/pluginsintegration/clientmiddleware/cookies_middleware.go#L60 var expectedHeaders = map[string]string{ strings.ToLower(models.FromAlertHeaderName): models.FromAlertHeaderName, strings.ToLower(models.CacheSkipHeaderName): models.CacheSkipHeaderName, strings.ToLower("X-Rule-Name"): "X-Rule-Name", strings.ToLower("X-Rule-Uid"): "X-Rule-Uid", strings.ToLower("X-Rule-Folder"): "X-Rule-Folder", strings.ToLower("X-Rule-Source"): "X-Rule-Source", strings.ToLower("X-Rule-Type"): "X-Rule-Type", strings.ToLower("X-Rule-Version"): "X-Rule-Version", strings.ToLower("X-Grafana-Org-Id"): "X-Grafana-Org-Id", strings.ToLower(queryService.HeaderQueryGroupID): queryService.HeaderQueryGroupID, strings.ToLower(queryService.HeaderPanelID): queryService.HeaderPanelID, strings.ToLower(queryService.HeaderDashboardUID): queryService.HeaderDashboardUID, strings.ToLower(queryService.HeaderDatasourceUID): queryService.HeaderDatasourceUID, strings.ToLower(queryService.HeaderFromExpression): queryService.HeaderFromExpression, strings.ToLower(queryService.HeaderPanelPluginId): queryService.HeaderPanelPluginId, strings.ToLower(queryService.HeaderDashboardTitle): queryService.HeaderDashboardTitle, strings.ToLower(queryService.HeaderPanelTitle): queryService.HeaderPanelTitle, strings.ToLower("X-Real-IP"): "X-Real-IP", strings.ToLower("X-Forwarded-For"): "X-Forwarded-For", strings.ToLower("Cookie"): "Cookie", } func ExtractKnownHeaders(header http.Header) map[string]string { extractedHeaders := make(map[string]string) for k, v := range header { if headerName, exists := expectedHeaders[strings.ToLower(k)]; exists { extractedHeaders[headerName] = v[0] } } return extractedHeaders }