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 46de16fa3..d9fdb584b 100644 --- a/middlewares/redirect/redirect.go +++ b/middlewares/redirect/redirect.go @@ -103,8 +103,15 @@ 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) _, err := rw.Write([]byte(http.StatusText(status))) diff --git a/middlewares/redirect/redirect_test.go b/middlewares/redirect/redirect_test.go index cee75670b..592c64488 100644 --- a/middlewares/redirect/redirect_test.go +++ b/middlewares/redirect/redirect_test.go @@ -17,11 +17,12 @@ func TestNewRegexHandler(t *testing.T) { testCases := []struct { desc string config config.Redirect + method string url string + secured bool expectedURL string expectedStatus int errorExpected bool - secured bool }{ { desc: "simple redirection", @@ -124,6 +125,29 @@ func TestNewRegexHandler(t *testing.T) { expectedURL: "http://foo:88", expectedStatus: http.StatusFound, }, + { + desc: "HTTP to HTTP POST", + config: config.Redirect{ + Regex: `^http://`, + Replacement: "https://$1", + }, + url: "http://foo", + method: http.MethodPost, + expectedURL: "https://foo", + expectedStatus: http.StatusTemporaryRedirect, + }, + { + desc: "HTTP to HTTP POST permanent", + config: config.Redirect{ + Regex: `^http://`, + Replacement: "https://$1", + Permanent: true, + }, + url: "http://foo", + method: http.MethodPost, + expectedURL: "https://foo", + expectedStatus: http.StatusPermanentRedirect, + }, } for _, test := range testCases { @@ -142,23 +166,29 @@ func TestNewRegexHandler(t *testing.T) { require.NotNil(t, handler) 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) if test.secured { r.TLS = &tls.ConnectionState{} } r.Header.Set("X-Foo", "bar") handler.ServeHTTP(recorder, r) - if test.expectedStatus == http.StatusMovedPermanently || test.expectedStatus == http.StatusFound { - assert.Equal(t, test.expectedStatus, recorder.Code) + assert.Equal(t, test.expectedStatus, recorder.Code) + if test.expectedStatus == http.StatusMovedPermanently || + test.expectedStatus == http.StatusFound || + test.expectedStatus == http.StatusTemporaryRedirect || + test.expectedStatus == http.StatusPermanentRedirect { location, err := recorder.Result().Location() require.NoError(t, err) assert.Equal(t, test.expectedURL, location.String()) } else { - assert.Equal(t, test.expectedStatus, recorder.Code) - location, err := recorder.Result().Location() require.Errorf(t, err, "Location %v", location) }