Send an Allow header whenever we send 405
This commit is contained in:
parent
32531c7f24
commit
d398bd962a
|
@ -113,6 +113,8 @@ func (wfe *WebFrontEndImpl) HandlePaths() {
|
|||
// Method implementations
|
||||
|
||||
func (wfe *WebFrontEndImpl) Index(response http.ResponseWriter, request *http.Request) {
|
||||
wfe.sendNonce(response)
|
||||
|
||||
// http://golang.org/pkg/net/http/#example_ServeMux_Handle
|
||||
// The "/" pattern matches everything, so we need to check
|
||||
// that we're at the root here.
|
||||
|
@ -121,6 +123,11 @@ func (wfe *WebFrontEndImpl) Index(response http.ResponseWriter, request *http.Re
|
|||
return
|
||||
}
|
||||
|
||||
if request.Method != "GET" {
|
||||
sendAllow(response, "GET")
|
||||
wfe.sendError(response, "Method not allowed", request.Method, http.StatusMethodNotAllowed)
|
||||
}
|
||||
|
||||
tmpl := template.Must(template.New("body").Parse(`<html>
|
||||
<body>
|
||||
This is an <a href="https://github.com/letsencrypt/acme-spec/">ACME</a>
|
||||
|
@ -155,6 +162,10 @@ const (
|
|||
ServerInternalProblem = ProblemType("urn:acme:error:serverInternal")
|
||||
)
|
||||
|
||||
func sendAllow(response http.ResponseWriter, methods ...string) {
|
||||
response.Header().Set("Allow", strings.Join(methods, ", "))
|
||||
}
|
||||
|
||||
func (wfe *WebFrontEndImpl) sendNonce(response http.ResponseWriter) {
|
||||
response.Header().Set("Replay-Nonce", wfe.nonceService.Nonce())
|
||||
}
|
||||
|
@ -269,6 +280,7 @@ func (wfe *WebFrontEndImpl) NewRegistration(response http.ResponseWriter, reques
|
|||
wfe.sendNonce(response)
|
||||
|
||||
if request.Method != "POST" {
|
||||
sendAllow(response, "POST")
|
||||
wfe.sendError(response, "Method not allowed", "", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
|
@ -330,6 +342,7 @@ func (wfe *WebFrontEndImpl) NewAuthorization(response http.ResponseWriter, reque
|
|||
wfe.sendNonce(response)
|
||||
|
||||
if request.Method != "POST" {
|
||||
sendAllow(response, "POST")
|
||||
wfe.sendError(response, "Method not allowed", request.Method, http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
|
@ -389,6 +402,7 @@ func (wfe *WebFrontEndImpl) RevokeCertificate(response http.ResponseWriter, requ
|
|||
wfe.sendNonce(response)
|
||||
|
||||
if request.Method != "POST" {
|
||||
sendAllow(response, "POST")
|
||||
wfe.sendError(response, "Method not allowed", request.Method, http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
|
@ -466,6 +480,7 @@ func (wfe *WebFrontEndImpl) NewCertificate(response http.ResponseWriter, request
|
|||
wfe.sendNonce(response)
|
||||
|
||||
if request.Method != "POST" {
|
||||
sendAllow(response, "POST")
|
||||
wfe.sendError(response, "Method not allowed", request.Method, http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
|
@ -539,6 +554,7 @@ func (wfe *WebFrontEndImpl) Challenge(authz core.Authorization, response http.Re
|
|||
wfe.sendNonce(response)
|
||||
|
||||
if request.Method != "GET" && request.Method != "POST" {
|
||||
sendAllow(response, "GET", "POST")
|
||||
wfe.sendError(response, "Method not allowed", request.Method, http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
|
@ -562,6 +578,7 @@ func (wfe *WebFrontEndImpl) Challenge(authz core.Authorization, response http.Re
|
|||
|
||||
switch request.Method {
|
||||
default:
|
||||
sendAllow(response, "GET", "POST")
|
||||
wfe.sendError(response, "Method not allowed", "", http.StatusMethodNotAllowed)
|
||||
return
|
||||
|
||||
|
@ -648,6 +665,7 @@ func (wfe *WebFrontEndImpl) Registration(response http.ResponseWriter, request *
|
|||
wfe.sendNonce(response)
|
||||
|
||||
if request.Method != "POST" {
|
||||
sendAllow(response, "POST")
|
||||
wfe.sendError(response, "Method not allowed", request.Method, http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
|
@ -721,6 +739,7 @@ func (wfe *WebFrontEndImpl) Authorization(response http.ResponseWriter, request
|
|||
wfe.sendNonce(response)
|
||||
|
||||
if request.Method != "GET" && request.Method != "POST" {
|
||||
sendAllow(response, "GET", "POST")
|
||||
wfe.sendError(response, "Method not allowed", request.Method, http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
|
@ -743,6 +762,7 @@ func (wfe *WebFrontEndImpl) Authorization(response http.ResponseWriter, request
|
|||
|
||||
switch request.Method {
|
||||
default:
|
||||
sendAllow(response, "GET", "POST")
|
||||
wfe.sendError(response, "Method not allowed", request.Method, http.StatusMethodNotAllowed)
|
||||
return
|
||||
|
||||
|
@ -771,6 +791,7 @@ func (wfe *WebFrontEndImpl) Certificate(response http.ResponseWriter, request *h
|
|||
wfe.sendNonce(response)
|
||||
|
||||
if request.Method != "GET" && request.Method != "POST" {
|
||||
sendAllow(response, "GET", "POST")
|
||||
wfe.sendError(response, "Method not allowed", request.Method, http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
|
@ -778,6 +799,7 @@ func (wfe *WebFrontEndImpl) Certificate(response http.ResponseWriter, request *h
|
|||
path := request.URL.Path
|
||||
switch request.Method {
|
||||
default:
|
||||
sendAllow(response, "GET", "POST")
|
||||
wfe.sendError(response, "Method not allowed", request.Method, http.StatusMethodNotAllowed)
|
||||
return
|
||||
|
||||
|
@ -819,6 +841,7 @@ func (wfe *WebFrontEndImpl) Terms(response http.ResponseWriter, request *http.Re
|
|||
wfe.sendNonce(response)
|
||||
|
||||
if request.Method != "GET" {
|
||||
sendAllow(response, "GET")
|
||||
wfe.sendError(response, "Method not allowed", request.Method, http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
|
@ -830,6 +853,7 @@ func (wfe *WebFrontEndImpl) Issuer(response http.ResponseWriter, request *http.R
|
|||
wfe.sendNonce(response)
|
||||
|
||||
if request.Method != "GET" {
|
||||
sendAllow(response, "GET")
|
||||
wfe.sendError(response, "Method not allowed", request.Method, http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
|
@ -847,6 +871,7 @@ func (wfe *WebFrontEndImpl) BuildID(response http.ResponseWriter, request *http.
|
|||
wfe.sendNonce(response)
|
||||
|
||||
if request.Method != "GET" {
|
||||
sendAllow(response, "GET")
|
||||
wfe.sendError(response, "Method not allowed", request.Method, http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -298,6 +298,39 @@ func setupWFE() WebFrontEndImpl {
|
|||
return wfe
|
||||
}
|
||||
|
||||
func TestMethodNotAllowed(t *testing.T) {
|
||||
wfe := setupWFE()
|
||||
|
||||
cases := []struct {
|
||||
path string
|
||||
handler func(http.ResponseWriter, *http.Request)
|
||||
allowed []string
|
||||
}{
|
||||
{"/", wfe.Index, []string{"GET"}},
|
||||
{wfe.NewReg, wfe.NewRegistration, []string{"POST"}},
|
||||
{wfe.RegBase, wfe.Registration, []string{"POST"}},
|
||||
{wfe.NewAuthz, wfe.NewAuthorization, []string{"POST"}},
|
||||
{wfe.AuthzBase, wfe.Authorization, []string{"GET", "POST"}},
|
||||
{wfe.NewCert, wfe.NewCertificate, []string{"POST"}},
|
||||
{wfe.CertBase, wfe.Certificate, []string{"GET", "POST"}},
|
||||
{wfe.SubscriberAgreementURL, wfe.Terms, []string{"GET"}},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
responseWriter := httptest.NewRecorder()
|
||||
url, _ := url.Parse(c.path)
|
||||
c.handler(responseWriter, &http.Request{
|
||||
Method: "BOGUS",
|
||||
URL: url,
|
||||
})
|
||||
nonce := responseWriter.Header().Get("Replay-Nonce")
|
||||
allow := responseWriter.Header().Get("Allow")
|
||||
test.Assert(t, responseWriter.Code == http.StatusMethodNotAllowed, "Bogus method allowed")
|
||||
test.Assert(t, len(nonce) > 0, "Bad Replay-Nonce header")
|
||||
test.Assert(t, len(allow) > 0 && allow == strings.Join(c.allowed, ", "), "Bad Allow header")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIndex(t *testing.T) {
|
||||
wfe := setupWFE()
|
||||
|
||||
|
@ -305,7 +338,8 @@ func TestIndex(t *testing.T) {
|
|||
|
||||
url, _ := url.Parse("/")
|
||||
wfe.Index(responseWriter, &http.Request{
|
||||
URL: url,
|
||||
Method: "GET",
|
||||
URL: url,
|
||||
})
|
||||
test.AssertEquals(t, responseWriter.Code, http.StatusOK)
|
||||
test.AssertNotEquals(t, responseWriter.Body.String(), "404 page not found\n")
|
||||
|
|
Loading…
Reference in New Issue