Merge pull request #1203 from influxdata/feature/meta-redirect
Add meta redirect for Influx Enterprise similar to meta client.pull/1202/head^2
commit
c9f1f3a660
|
@ -17,6 +17,7 @@
|
|||
1. [#1179](https://github.com/influxdata/chronograf/pull/1179): Admin Databases Page will render a database without retention policies
|
||||
1. [#1128](https://github.com/influxdata/chronograf/pull/1128): No more ghost dashboards 👻
|
||||
1. [#1189](https://github.com/influxdata/chronograf/pull/1189): Clicking inside the graph header edit box will no longer blur the field. Use the Escape key for that behavior instead.
|
||||
1. [#1195](https://github.com/influxdata/chronograf/issues/1195): Chronograf was not redirecting with authentiation for Influx Enterprise Meta service
|
||||
1. [#1095](https://github.com/influxdata/chronograf/pull/1095): Make logout button display again
|
||||
1. [#1209](https://github.com/influxdata/chronograf/pull/1209): HipChat Kapacitor config now uses only the subdomain instead of asking for the entire HipChat URL.
|
||||
|
||||
|
|
|
@ -384,7 +384,12 @@ func (d *defaultClient) Do(URL *url.URL, path, method string, params map[string]
|
|||
req.Header.Set("Content-Type", "application/json")
|
||||
}
|
||||
|
||||
res, err := http.DefaultClient.Do(req)
|
||||
// Meta servers will redirect (307) to leader. We need
|
||||
// special handling to preserve authentication headers.
|
||||
client := &http.Client{
|
||||
CheckRedirect: AuthedCheckRedirect,
|
||||
}
|
||||
res, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -404,6 +409,21 @@ func (d *defaultClient) Do(URL *url.URL, path, method string, params map[string]
|
|||
|
||||
}
|
||||
|
||||
// AuthedCheckRedirect tries to follow the Influx Enterprise pattern of
|
||||
// redirecting to the leader but preserving authentication headers.
|
||||
func AuthedCheckRedirect(req *http.Request, via []*http.Request) error {
|
||||
if len(via) >= 10 {
|
||||
return errors.New("too many redirects")
|
||||
} else if len(via) == 0 {
|
||||
return nil
|
||||
}
|
||||
preserve := "Authorization"
|
||||
if auth, ok := via[0].Header[preserve]; ok {
|
||||
req.Header[preserve] = auth
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Do is a cancelable function to interface with Influx Enterprise's Meta API
|
||||
func (m *MetaClient) Do(ctx context.Context, method, path string, params map[string]string, body io.Reader) (*http.Response, error) {
|
||||
type result struct {
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
@ -1396,3 +1397,59 @@ func (c *MockClient) Do(URL *url.URL, path, method string, params map[string]str
|
|||
Body: ioutil.NopCloser(bytes.NewReader(c.Body)),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func Test_AuthedCheckRedirect_Do(t *testing.T) {
|
||||
var ts2URL string
|
||||
ts1 := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
want := http.Header{
|
||||
"Referer": []string{ts2URL},
|
||||
"Accept-Encoding": []string{"gzip"},
|
||||
"Authorization": []string{"hunter2"},
|
||||
}
|
||||
for k, v := range want {
|
||||
if !reflect.DeepEqual(r.Header[k], v) {
|
||||
t.Errorf("Request.Header = %#v; want %#v", r.Header[k], v)
|
||||
}
|
||||
}
|
||||
if t.Failed() {
|
||||
w.Header().Set("Result", "got errors")
|
||||
} else {
|
||||
w.Header().Set("Result", "ok")
|
||||
}
|
||||
}))
|
||||
defer ts1.Close()
|
||||
|
||||
ts2 := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
http.Redirect(w, r, ts1.URL, http.StatusFound)
|
||||
}))
|
||||
defer ts2.Close()
|
||||
ts2URL = ts2.URL
|
||||
|
||||
tr := &http.Transport{}
|
||||
defer tr.CloseIdleConnections()
|
||||
|
||||
c := &http.Client{
|
||||
Transport: tr,
|
||||
CheckRedirect: AuthedCheckRedirect,
|
||||
}
|
||||
|
||||
req, _ := http.NewRequest("GET", ts2.URL, nil)
|
||||
req.Header.Add("Cookie", "foo=bar")
|
||||
req.Header.Add("Authorization", "hunter2")
|
||||
req.Header.Add("Howdy", "doody")
|
||||
req.Header.Set("User-Agent", "Darth Vader, an extraterrestrial from the Planet Vulcan")
|
||||
|
||||
res, err := c.Do(req)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
defer res.Body.Close()
|
||||
if res.StatusCode != 200 {
|
||||
t.Fatal(res.Status)
|
||||
}
|
||||
|
||||
if got := res.Header.Get("Result"); got != "ok" {
|
||||
t.Errorf("result = %q; want ok", got)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue