Redirection status codes for methods different than GET

This commit is contained in:
Radoslaw Wesolowski 2019-01-07 17:56:04 +01:00 committed by Traefiker Bot
parent 099bbb8be7
commit d7bd69714d
3 changed files with 44 additions and 7 deletions

View file

@ -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.

View file

@ -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)))

View file

@ -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)
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)
}