From b5a4d0797a0efa0387798743853b12c40652f7e0 Mon Sep 17 00:00:00 2001 From: Radoslaw Wesolowski Date: Mon, 7 Jan 2019 17:56:04 +0100 Subject: [PATCH] Redirection status codes for methods different than GET --- docs/configuration/ping.md | 2 +- middlewares/redirect/redirect.go | 7 +++++++ middlewares/redirect/redirect_test.go | 25 ++++++++++++++++++++++++- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/docs/configuration/ping.md b/docs/configuration/ping.md index 7ec13d7f3..c36ceb24c 100644 --- a/docs/configuration/ping.md +++ b/docs/configuration/ping.md @@ -27,7 +27,7 @@ The `/ping` health-check URL is enabled with the command-line `--ping` or config Thus, if you have a regular path for `/foo` and an entrypoint on `:80`, you would access them as follows: * Regular path: `http://hostname:80/foo` -* Dashboard: `http://hostname:8080/` +* Admin panel: `http://hostname:8080/` * Ping URL: `http://hostname:8080/ping` However, for security reasons, you may want to be able to expose the `/ping` health-check URL to outside health-checkers, e.g. an Internet service or cloud load-balancer, _without_ exposing your dashboard's port. diff --git a/middlewares/redirect/redirect.go b/middlewares/redirect/redirect.go index 506d7db3f..5508669e7 100644 --- a/middlewares/redirect/redirect.go +++ b/middlewares/redirect/redirect.go @@ -125,8 +125,15 @@ type moveHandler struct { func (m *moveHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) { rw.Header().Set("Location", m.location.String()) status := http.StatusFound + if req.Method != http.MethodGet { + status = http.StatusTemporaryRedirect + } + if m.permanent { status = http.StatusMovedPermanently + if req.Method != http.MethodGet { + status = http.StatusPermanentRedirect + } } rw.WriteHeader(status) rw.Write([]byte(http.StatusText(status))) diff --git a/middlewares/redirect/redirect_test.go b/middlewares/redirect/redirect_test.go index ab190daca..d7b61e4cc 100644 --- a/middlewares/redirect/redirect_test.go +++ b/middlewares/redirect/redirect_test.go @@ -17,6 +17,7 @@ func TestNewEntryPointHandler(t *testing.T) { desc string entryPoint *configuration.EntryPoint permanent bool + method string url string expectedURL string expectedStatus int @@ -59,6 +60,24 @@ func TestNewEntryPointHandler(t *testing.T) { expectedURL: "http://foo:80", expectedStatus: http.StatusMovedPermanently, }, + { + desc: "HTTP to HTTP POST", + entryPoint: &configuration.EntryPoint{Address: ":80"}, + permanent: false, + url: "http://foo:90", + method: http.MethodPost, + expectedURL: "http://foo:80", + expectedStatus: http.StatusTemporaryRedirect, + }, + { + desc: "HTTP to HTTP POST permanent", + entryPoint: &configuration.EntryPoint{Address: ":80"}, + permanent: true, + url: "http://foo:90", + method: http.MethodPost, + expectedURL: "http://foo:80", + expectedStatus: http.StatusPermanentRedirect, + }, { desc: "invalid address", entryPoint: &configuration.EntryPoint{Address: ":foo", TLS: &tls.TLS{}}, @@ -80,7 +99,11 @@ func TestNewEntryPointHandler(t *testing.T) { require.NoError(t, err) recorder := httptest.NewRecorder() - r := testhelpers.MustNewRequest(http.MethodGet, test.url, nil) + method := http.MethodGet + if test.method != "" { + method = test.method + } + r := testhelpers.MustNewRequest(method, test.url, nil) handler.ServeHTTP(recorder, r, nil) location, err := recorder.Result().Location()