diff --git a/CHANGELOG.md b/CHANGELOG.md index aec8218657..4bcc1af782 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +## v1.3.1 [unreleased] + +### Bug Fixes + 1. [#1450](https://github.com/influxdata/chronograf/pull/1450): Fix infinite spinner when using "/chronograf" as a basepath + +### Features + +### UI Improvements + ## v1.3.0 [2017-05-09] ### Bug Fixes diff --git a/server/prefixing_redirector.go b/server/prefixing_redirector.go index eec4e9fd72..86f957efab 100644 --- a/server/prefixing_redirector.go +++ b/server/prefixing_redirector.go @@ -16,7 +16,8 @@ func (i *interceptingResponseWriter) WriteHeader(status int) { if status >= 300 && status < 400 { location := i.ResponseWriter.Header().Get("Location") if u, err := url.Parse(location); err == nil && !u.IsAbs() { - if !strings.HasPrefix(location, i.Prefix) { + hasPrefix := strings.HasPrefix(u.Path, i.Prefix) + if !hasPrefix || (hasPrefix && !strings.HasPrefix(u.Path[len(i.Prefix):], i.Prefix)) { i.ResponseWriter.Header().Set("Location", path.Join(i.Prefix, location)+"/") } } diff --git a/server/prefixing_redirector_test.go b/server/prefixing_redirector_test.go new file mode 100644 index 0000000000..728c906047 --- /dev/null +++ b/server/prefixing_redirector_test.go @@ -0,0 +1,87 @@ +package server + +import ( + "net/http" + "net/http/httptest" + "strings" + "testing" +) + +var prefixingRedirectTests = []struct { + CaseName string + RedirectTarget string + Prefix string + Expected string +}{ + { + "ChronografBasepath", + "/chronograf/v1/", + "/chronograf", + "/chronograf/chronograf/v1/", + }, + { + "DifferentBasepath", + "/chronograf/v1/", + "/delorean", + "/delorean/chronograf/v1/", + }, + { + "TrailingSlashPrefix", + "/chronograf/v1/", + "/delorean/", + "/delorean/chronograf/v1/", + }, + { + "NoPrefix", + "/chronograf/v1/", + "", + "/chronograf/v1/", + }, + { + "SlashPrefix", + "/chronograf/v1/", + "/", + "/chronograf/v1/", + }, + { + "AlreadyPrefixed", + "/chronograf/chronograf/v1/", + "/chronograf", + "/chronograf/chronograf/v1/", + }, +} + +func Test_PrefixingRedirector(t *testing.T) { + t.Parallel() + for _, p := range prefixingRedirectTests { + t.Run(p.CaseName, func(subt *testing.T) { + hf := http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { + rw.Header().Set("Location", p.RedirectTarget) + rw.WriteHeader(http.StatusTemporaryRedirect) + }) + pr := PrefixedRedirect(p.Prefix, hf) + + ts := httptest.NewServer(pr) + defer ts.Close() + + hc := http.Client{ + CheckRedirect: func(req *http.Request, via []*http.Request) error { + return http.ErrUseLastResponse + }, + } + + mockBody := strings.NewReader("") + req, _ := http.NewRequest("GET", ts.URL, mockBody) + + resp, err := hc.Do(req) + if err != nil { + subt.Fatal("Unexpected http err:", err) + } + + expected := p.Expected + if loc := resp.Header.Get("Location"); loc != expected { + subt.Fatal("Unexpected redirected location. Expected:", expected, "Actual:", loc) + } + }) + } +}