api_dataproxy.go 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. package api
  2. import (
  3. "net/http"
  4. "net/http/httputil"
  5. "net/url"
  6. "strings"
  7. "github.com/torkelo/grafana-pro/pkg/bus"
  8. "github.com/torkelo/grafana-pro/pkg/log"
  9. "github.com/torkelo/grafana-pro/pkg/middleware"
  10. m "github.com/torkelo/grafana-pro/pkg/models"
  11. )
  12. func singleJoiningSlash(a, b string) string {
  13. aslash := strings.HasSuffix(a, "/")
  14. bslash := strings.HasPrefix(b, "/")
  15. switch {
  16. case aslash && bslash:
  17. return a + b[1:]
  18. case !aslash && !bslash:
  19. return a + "/" + b
  20. }
  21. return a + b
  22. }
  23. func NewReverseProxy(target *url.URL, proxyPath string) *httputil.ReverseProxy {
  24. targetQuery := target.RawQuery
  25. director := func(req *http.Request) {
  26. req.URL.Scheme = target.Scheme
  27. req.URL.Host = target.Host
  28. req.URL.Path = singleJoiningSlash(target.Path, proxyPath)
  29. if targetQuery == "" || req.URL.RawQuery == "" {
  30. req.URL.RawQuery = targetQuery + req.URL.RawQuery
  31. } else {
  32. req.URL.RawQuery = targetQuery + "&" + req.URL.RawQuery
  33. }
  34. log.Info("Proxy: %v", req.URL.Path)
  35. }
  36. return &httputil.ReverseProxy{Director: director}
  37. }
  38. // TODO: need to cache datasources
  39. func ProxyDataSourceRequest(c *middleware.Context) {
  40. name := c.Params(":name")
  41. query := m.GetDataSourceByNameQuery{
  42. Name: name,
  43. AccountId: c.GetAccountId(),
  44. }
  45. err := bus.Dispatch(&query)
  46. if err != nil {
  47. c.JsonApiErr(500, "Unable to load datasource meta data", err)
  48. }
  49. proxyPath := c.Params("*")
  50. url, _ := url.Parse(query.Result.Url)
  51. proxy := NewReverseProxy(url, proxyPath)
  52. proxy.ServeHTTP(c.RW(), c.Req.Request)
  53. }