husobee / vestigo

Echo Inspired Stand Alone URL Router
MIT License
268 stars 32 forks source link

In presence of multiple routes, HEAD results in 405 #47

Open drdaeman opened 7 years ago

drdaeman commented 7 years ago

I have a very simple code, like this:

router := vestigo.NewRouter()
// Also tried router.HandleFunc instead of router.Get
router.Get("/ping", func(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "text/plain; charset=utf-8")
    w.WriteHeader(http.StatusOK)
    io.WriteString(w, "PONG")
})
router.Get("/test", func(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "text/plain; charset=utf-8")
    w.WriteHeader(http.StatusOK)
    io.WriteString(w, "TEST")
})
// After this, I create &http.Server{Handler: router, ...} and start it.

Whenever I have any other HandleFunc on the router (e.g. /test in the example above), HEAD /ping results in HTTP/1.1 405 Method Not Allowed despite what the Allow response header says:

$ http head http://localhost:8000/ping
HTTP/1.1 405 Method Not Allowed
Allow: GET, HEAD
Content-Length: 18
Content-Type: text/plain; charset=utf-8
Date: Fri, 23 Dec 2016 01:27:54 GMT

I've even tried to be really explicit and tried the following, but it hadn't any visible effect:

router.Add("HEAD", "/ping", func(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "text/plain; charset=utf-8")
    w.WriteHeader(http.StatusOK)
})

If I remove /test handler, I start getting 200 OK for /ping, just as expected.

Oh, and HEAD /test results in 200 OK, so I suppose HEAD is broken for all but the last route registered. Or, maybe, it's more complicated than this - I haven't tested any other scenarios.

Except for this HEAD issue, routing seem to work okay. Well, at least GETs are handled just fine.

What could be possibly wrong here? Tested on Go 1.7 and 1.8b2, amd64, GNU/Linux and Windows builds all exhibit the same behavior.

husobee commented 7 years ago

Investigating, thanks for the report.