| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | package api | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2015-06-01 17:00:05 +08:00
										 |  |  | 	"crypto/tls" | 
					
						
							|  |  |  | 	"net" | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | 	"net/http" | 
					
						
							|  |  |  | 	"net/http/httputil" | 
					
						
							|  |  |  | 	"net/url" | 
					
						
							| 
									
										
										
										
											2015-06-01 17:00:05 +08:00
										 |  |  | 	"time" | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-05 17:37:13 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/bus" | 
					
						
							|  |  |  | 	"github.com/grafana/grafana/pkg/middleware" | 
					
						
							|  |  |  | 	m "github.com/grafana/grafana/pkg/models" | 
					
						
							|  |  |  | 	"github.com/grafana/grafana/pkg/util" | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-01 17:00:05 +08:00
										 |  |  | var dataProxyTransport = &http.Transport{ | 
					
						
							|  |  |  | 	TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, | 
					
						
							|  |  |  | 	Proxy:           http.ProxyFromEnvironment, | 
					
						
							|  |  |  | 	Dial: (&net.Dialer{ | 
					
						
							|  |  |  | 		Timeout:   30 * time.Second, | 
					
						
							|  |  |  | 		KeepAlive: 30 * time.Second, | 
					
						
							|  |  |  | 	}).Dial, | 
					
						
							|  |  |  | 	TLSHandshakeTimeout: 10 * time.Second, | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | func NewReverseProxy(ds *m.DataSource, proxyPath string) *httputil.ReverseProxy { | 
					
						
							|  |  |  | 	target, _ := url.Parse(ds.Url) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	director := func(req *http.Request) { | 
					
						
							|  |  |  | 		req.URL.Scheme = target.Scheme | 
					
						
							|  |  |  | 		req.URL.Host = target.Host | 
					
						
							| 
									
										
										
										
											2015-02-13 14:26:33 +08:00
										 |  |  | 		req.Host = target.Host | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		reqQueryVals := req.URL.Query() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-28 15:25:13 +08:00
										 |  |  | 		if ds.Type == m.DS_INFLUXDB_08 { | 
					
						
							| 
									
										
										
										
											2015-01-08 16:00:00 +08:00
										 |  |  | 			req.URL.Path = util.JoinUrlFragments(target.Path, "db/"+ds.Database+"/"+proxyPath) | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | 			reqQueryVals.Add("u", ds.User) | 
					
						
							|  |  |  | 			reqQueryVals.Add("p", ds.Password) | 
					
						
							|  |  |  | 			req.URL.RawQuery = reqQueryVals.Encode() | 
					
						
							| 
									
										
										
										
											2015-02-28 15:25:13 +08:00
										 |  |  | 		} else if ds.Type == m.DS_INFLUXDB { | 
					
						
							| 
									
										
										
										
											2015-02-26 01:43:44 +08:00
										 |  |  | 			req.URL.Path = util.JoinUrlFragments(target.Path, proxyPath) | 
					
						
							|  |  |  | 			reqQueryVals.Add("db", ds.Database) | 
					
						
							|  |  |  | 			req.URL.RawQuery = reqQueryVals.Encode() | 
					
						
							| 
									
										
										
										
											2015-08-07 17:01:59 +08:00
										 |  |  | 			if !ds.BasicAuth { | 
					
						
							|  |  |  | 				req.Header.Add("Authorization", util.GetBasicAuthHeader(ds.User, ds.Password)) | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2015-01-08 16:00:00 +08:00
										 |  |  | 			req.URL.Path = util.JoinUrlFragments(target.Path, proxyPath) | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-03-02 16:58:35 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if ds.BasicAuth { | 
					
						
							|  |  |  | 			req.Header.Add("Authorization", util.GetBasicAuthHeader(ds.BasicAuthUser, ds.BasicAuthPassword)) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-08-10 18:11:18 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// clear cookie headers
 | 
					
						
							|  |  |  | 		req.Header.Del("Cookie") | 
					
						
							|  |  |  | 		req.Header.Del("Set-Cookie") | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return &httputil.ReverseProxy{Director: director} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-15 03:29:41 +08:00
										 |  |  | //ProxyDataSourceRequest TODO need to cache datasources
 | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | func ProxyDataSourceRequest(c *middleware.Context) { | 
					
						
							|  |  |  | 	id := c.ParamsInt64(":id") | 
					
						
							| 
									
										
										
										
											2015-03-12 00:34:11 +08:00
										 |  |  | 	query := m.GetDataSourceByIdQuery{Id: id, OrgId: c.OrgId} | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-12 00:34:11 +08:00
										 |  |  | 	if err := bus.Dispatch(&query); err != nil { | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | 		c.JsonApiErr(500, "Unable to load datasource meta data", err) | 
					
						
							| 
									
										
										
										
											2015-03-12 00:34:11 +08:00
										 |  |  | 		return | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	proxyPath := c.Params("*") | 
					
						
							|  |  |  | 	proxy := NewReverseProxy(&query.Result, proxyPath) | 
					
						
							| 
									
										
										
										
											2015-06-01 17:00:05 +08:00
										 |  |  | 	proxy.Transport = dataProxyTransport | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | 	proxy.ServeHTTP(c.RW(), c.Req.Request) | 
					
						
							|  |  |  | } |