Merge pull request #54 from rogpeppe/001-custom-method-not-allowed
add support for custom MethodNotAllowed function
diff --git a/router.go b/router.go
index 4893950..8c9550f 100644
--- a/router.go
+++ b/router.go
@@ -142,6 +142,11 @@
// found. If it is not set, http.NotFound is used.
NotFound http.HandlerFunc
+ // Configurable http.HandlerFunc which is called when a request
+ // cannot be routed and HandleMethodNotAllowed is true.
+ // If it is not set, http.Error with http.StatusMethodNotAllowed is used.
+ MethodNotAllowed http.HandlerFunc
+
// Function to handle panics recovered from http handlers.
// It should be used to generate a error page and return the http error code
// 500 (Internal Server Error).
@@ -335,10 +340,14 @@
handle, _, _ := r.trees[method].getValue(req.URL.Path)
if handle != nil {
- http.Error(w,
- http.StatusText(http.StatusMethodNotAllowed),
- http.StatusMethodNotAllowed,
- )
+ if r.MethodNotAllowed != nil {
+ r.MethodNotAllowed(w, req)
+ } else {
+ http.Error(w,
+ http.StatusText(http.StatusMethodNotAllowed),
+ http.StatusMethodNotAllowed,
+ )
+ }
return
}
}
diff --git a/router_test.go b/router_test.go
index 7b07dfb..75d2dfc 100644
--- a/router_test.go
+++ b/router_test.go
@@ -178,6 +178,20 @@
if !(w.Code == http.StatusMethodNotAllowed) {
t.Errorf("NotAllowed handling failed: Code=%d, Header=%v", w.Code, w.Header())
}
+
+ w = httptest.NewRecorder()
+ responseText := "custom method"
+ router.MethodNotAllowed = func(w http.ResponseWriter, req *http.Request) {
+ w.WriteHeader(http.StatusTeapot)
+ w.Write([]byte(responseText))
+ }
+ router.ServeHTTP(w, r)
+ if got := w.Body.String(); !(got == responseText) {
+ t.Errorf("unexpected response got %q want %q", got, responseText)
+ }
+ if w.Code != http.StatusTeapot {
+ t.Errorf("unexpected response code %d want %d", w.Code, http.StatusTeapot)
+ }
}
func TestRouterNotFound(t *testing.T) {