Skip to content

Instantly share code, notes, and snippets.

@guillermo
Last active December 12, 2016 10:32
Show Gist options
  • Save guillermo/0eb7e53fa687acbf05ea to your computer and use it in GitHub Desktop.
Save guillermo/0eb7e53fa687acbf05ea to your computer and use it in GitHub Desktop.
Package verbs provides a simple method to filter request method with the net/http ServeMux
// Copyright 2015 Guillermo Alvarez. All rights reserved.
// Use of this source code is governed by standard BSD license.
/*
Package verbs provides a simple method to filter request method with the net/http ServeMux
func createUser(w http.ResponseWriter, r *http.Request) {
...
}
mux := http.NewServeMux()
mux.Handle("/users", Verbs{Post: createUser})
*/
package verbs
import "net/http"
type Verbs struct {
Get http.HandlerFunc
Post http.HandlerFunc
Put http.HandlerFunc
Delete http.HandlerFunc
Patch http.HandlerFunc
Head http.HandlerFunc
}
func (v Verbs) ServeHTTP(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case "GET":
if v.Get != nil {
v.Get(w, r)
return
}
case "POST":
if v.Post != nil {
v.Post(w, r)
return
}
case "PUT":
if v.Put != nil {
v.Put(w, r)
return
}
case "DELETE":
if v.Delete != nil {
v.Delete(w, r)
return
}
case "PATCH":
if v.Patch != nil {
v.Patch(w, r)
return
}
case "HEAD":
if v.Head != nil {
v.Head(w, r)
return
}
}
http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
}
@tbroyer
Copy link

tbroyer commented Dec 12, 2016

The origin server MUST generate an
Allow header field in a 405 response containing a list of the target
resource's currently supported methods.
— Source: https://tools.ietf.org/html/rfc7231#section-6.5.5

So the last line should actually read something like:

var allow []string
if v.Get != nil {
	allow = append(allow, "GET")
}
if v.Post != nil {
	allow = append(allow, "POST")
}
if v.Put != nil {
	allow = append(allow, "PUT")
}
if v.Delete != nil {
	allow = append(allow, "DELETE")
}
if v.Patch != nil {
	allow = append(allow, "PATCH")
}
if v.Head != nil {
	allow = append(allow, "HEAD")
}
w.Header().Set("Allow", strings.Join(allow, ",")) // technically could also w.Header()["Allow"] = allow, more verbose on the wire though
w.WriteHeader(http.StatusMethodNotAllowed) // or use http.Error here

(ouch! much less readable)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment