Skip to content
Snippets Groups Projects
Commit 5b7dab93 authored by Will McCutchen's avatar Will McCutchen
Browse files

Add /absolute-redirect/:n handler

parent a2db30b1
No related branches found
No related tags found
No related merge requests found
......@@ -44,7 +44,7 @@ func (h *HTTPBin) Get(w http.ResponseWriter, r *http.Request) {
Args: args,
Headers: r.Header,
Origin: getOrigin(r),
URL: getURL(r),
URL: getURL(r).String(),
}
body, _ := json.Marshal(resp)
writeJSON(w, body, http.StatusOK)
......@@ -62,7 +62,7 @@ func (h *HTTPBin) RequestWithBody(w http.ResponseWriter, r *http.Request) {
Args: args,
Headers: r.Header,
Origin: getOrigin(r),
URL: getURL(r),
URL: getURL(r).String(),
}
err = parseBody(w, r, resp, h.options.MaxMemory)
......@@ -197,8 +197,30 @@ func (h *HTTPBin) ResponseHeaders(w http.ResponseWriter, r *http.Request) {
w.Write(body)
}
// RelativeRedirect responds with an HTTP 302 redirect a given number of times
func (h *HTTPBin) RelativeRedirect(w http.ResponseWriter, r *http.Request) {
func redirectLocation(r *http.Request, relative bool, n int) string {
var location string
var path string
if n < 1 {
path = "/get"
} else if relative {
path = fmt.Sprintf("/relative-redirect/%d", n)
} else {
path = fmt.Sprintf("/absolute-redirect/%d", n)
}
if relative {
location = path
} else {
u := getURL(r)
u.Path = path
location = u.String()
}
return location
}
func doRedirect(w http.ResponseWriter, r *http.Request, relative bool) {
parts := strings.Split(r.URL.Path, "/")
if len(parts) != 3 {
http.Error(w, "Not found", http.StatusNotFound)
......@@ -209,11 +231,16 @@ func (h *HTTPBin) RelativeRedirect(w http.ResponseWriter, r *http.Request) {
http.Error(w, "Invalid redirect", http.StatusBadRequest)
}
location := fmt.Sprintf("/relative-redirect/%d", n-1)
if n == 1 {
location = "/get"
}
w.Header().Set("Location", location)
w.Header().Set("Location", redirectLocation(r, relative, n-1))
w.WriteHeader(http.StatusFound)
}
// RelativeRedirect responds with an HTTP 302 redirect a given number of times
func (h *HTTPBin) RelativeRedirect(w http.ResponseWriter, r *http.Request) {
doRedirect(w, r, true)
}
// AbsoluteRedirect responds with an HTTP 302 redirect a given number of times
func (h *HTTPBin) AbsoluteRedirect(w http.ResponseWriter, r *http.Request) {
doRedirect(w, r, false)
}
......@@ -750,18 +750,30 @@ func TestResponseHeaders__InvalidQuery(t *testing.T) {
assertStatusCode(t, w, http.StatusBadRequest)
}
func TestRelativeRedirect__OK(t *testing.T) {
func TestRedirects__OK(t *testing.T) {
var tests = []struct {
relative bool
n int
location string
}{
{1, "/get"},
{2, "/relative-redirect/1"},
{100, "/relative-redirect/99"},
{true, 1, "/get"},
{true, 2, "/relative-redirect/1"},
{true, 100, "/relative-redirect/99"},
{false, 1, "http://host/get"},
{false, 2, "http://host/absolute-redirect/1"},
{false, 100, "http://host/absolute-redirect/99"},
}
for _, test := range tests {
r, _ := http.NewRequest("GET", fmt.Sprintf("/relative-redirect/%d", test.n), nil)
var urlTemplate string
if test.relative {
urlTemplate = "/relative-redirect/%d"
} else {
urlTemplate = "/absolute-redirect/%d"
}
r, _ := http.NewRequest("GET", fmt.Sprintf(urlTemplate, test.n), nil)
r.Host = "host"
w := httptest.NewRecorder()
handler.ServeHTTP(w, r)
......@@ -770,20 +782,33 @@ func TestRelativeRedirect__OK(t *testing.T) {
}
}
func TestRelativeRedirect__Errors(t *testing.T) {
func TestRedirects__Errors(t *testing.T) {
var tests = []struct {
given interface{}
status int
relative bool
given interface{}
status int
}{
{3.14, http.StatusBadRequest},
{-1, http.StatusBadRequest},
{"", http.StatusBadRequest},
{"foo", http.StatusBadRequest},
{"10/bar", http.StatusNotFound},
{true, 3.14, http.StatusBadRequest},
{true, -1, http.StatusBadRequest},
{true, "", http.StatusBadRequest},
{true, "foo", http.StatusBadRequest},
{true, "10/bar", http.StatusNotFound},
{false, 3.14, http.StatusBadRequest},
{false, -1, http.StatusBadRequest},
{false, "", http.StatusBadRequest},
{false, "foo", http.StatusBadRequest},
{false, "10/bar", http.StatusNotFound},
}
for _, test := range tests {
r, _ := http.NewRequest("GET", fmt.Sprintf("/relative-redirect/%v", test.given), nil)
var urlTemplate string
if test.relative {
urlTemplate = "/relative-redirect/%v"
} else {
urlTemplate = "/absolute-redirect/%v"
}
r, _ := http.NewRequest("GET", fmt.Sprintf(urlTemplate, test.given), nil)
w := httptest.NewRecorder()
handler.ServeHTTP(w, r)
......
......@@ -16,7 +16,7 @@ func getOrigin(r *http.Request) string {
return origin
}
func getURL(r *http.Request) string {
func getURL(r *http.Request) *url.URL {
scheme := r.Header.Get("X-Forwarded-Proto")
if scheme == "" {
scheme = r.Header.Get("X-Forwarded-Protocol")
......@@ -33,7 +33,7 @@ func getURL(r *http.Request) string {
host = r.Host
}
u := &url.URL{
return &url.URL{
Scheme: scheme,
Opaque: r.URL.Opaque,
User: r.URL.User,
......@@ -44,7 +44,6 @@ func getURL(r *http.Request) string {
RawQuery: r.URL.RawQuery,
Fragment: r.URL.Fragment,
}
return u.String()
}
func writeJSON(w http.ResponseWriter, body []byte, status int) {
......
......@@ -68,6 +68,7 @@ func (h *HTTPBin) Handler() http.Handler {
mux.HandleFunc("/response-headers", h.ResponseHeaders)
mux.HandleFunc("/relative-redirect/", h.RelativeRedirect)
mux.HandleFunc("/absolute-redirect/", h.AbsoluteRedirect)
return logger(cors(mux))
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment