Comments (9)
Excuse me @julienschmidt , but I can't replicate that bad behaviour, even changing the order of the handlers. Here is my code:
package main
import (
"fmt"
"github.com/julienschmidt/httprouter"
"log"
"net/http"
)
func Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
fmt.Fprint(w, "Welcome!\n")
}
func Hello(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
fmt.Fprintf(w, "hello, %s!\n", ps.ByName("name"))
}
func main() {
router := httprouter.New()
router.Handle("OPTIONS", "/*name", Hello)
router.Handle("GET", "/v1/search", Index)
log.Fatal(http.ListenAndServe(":8080", router))
}
And here the request I made to try it:
$ curl -X OPTIONS localhost:8080/mynameisjavier
hello, /mynameisjavier!
$ curl localhost:8080/mynameisjavier
405 method not allowed
$ curl localhost:8080/v1/search
Welcome!
$ curl -X OPTIONS localhost:8080/v1/search
hello, /v1/search!
$ curl -X POST localhost:8080/v1/search
405 method not allowed
Thank you in advance for your response.
from httprouter.
Morning... I'll send an example (or a test) that illustrates the bug.
Randy
On Jan 6, 2015, at 3:39 AM, Javier Provecho Fernandez [email protected] wrote:
Excuse me @julienschmidt , but I can't replicate that bad behaviour, even changing the order of the handlers. Here is my code:
package main
import (
"fmt"
"github.com/julienschmidt/httprouter"
"log"
"net/http"
)func Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
fmt.Fprint(w, "Welcome!\n")
}func Hello(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
fmt.Fprintf(w, "hello, %s!\n", ps.ByName("name"))
}func main() {
router := httprouter.New()
router.Handle("OPTIONS", "/*name", Hello)
router.Handle("GET", "/v1/search", Index)
log.Fatal(http.ListenAndServe(":8080", router))
}
And here the request I made to try it:$ curl -X OPTIONS localhost:8080/mynameisjavier
hello, /mynameisjavier!$ curl localhost:8080/mynameisjavier
405 method not allowed$ curl localhost:8080/v1/search
Welcome!$ curl -X OPTIONS localhost:8080/v1/search
hello, /v1/search!$ curl -X POST localhost:8080/v1/search
405 method not allowed
Thank you in advance for your response.�
Reply to this email directly or view it on GitHub.
from httprouter.
@javierprovecho you have to test against another route (that should 404 or 200). The test below should pass, but fails with the 405 code:
func TestRouterNotAllowed(t *testing.T) {
handlerFunc := func(_ http.ResponseWriter, _ *http.Request, _ Params) {}
router := New()
router.GET("/handler", handlerFunc)
router.Handle("OPTIONS", "/*path", handlerFunc)
router.NotFound = func(_ http.ResponseWriter, _ *http.Request) {}
testRoutes := []struct {
method string
route string
code int
}{
{"GET", "/handler", 200},
{"POST", "/handler", 405},
{"OPTIONS", "/other", 200},
{"GET", "/", 404}, // This test fails
}
for _, tr := range testRoutes {
r, _ := http.NewRequest(tr.method, tr.route, nil)
w := httptest.NewRecorder()
router.ServeHTTP(w, r)
if !(w.Code == tr.code) {
t.Errorf("Handling %s %s failed. Want=%d Got=%d", tr.method, tr.route, tr.code, w.Code)
}
}
}
from httprouter.
For a bit more context, we chain multiple routers (Hitch
instances, actually) together with different middleware. Router A’s NotFound
handler is Router B:
apis := hitch.New()
apis.Use(httpgzip.Handler, AuthenticateClient, geoIP)
apis.Get("/v1/search", http.HandlerFunc(V1Search))
apis.Get("/v1/info", http.HandlerFunc(V1Info))
// Base handler
h := hitch.New()
h.Use(logger)
h.Get("/", http.RedirectHandler(apiDocsURL, 301))
h.Get("/favicon.ico", http.NotFoundHandler())
h.Options("/*path", http.HandlerFunc(CORSPreflight))
h.Next(apis.Handler())
return h.Handler()
from httprouter.
@ydnar we are probably discovering a new bug, because that test also fails with previous commit.
--- FAIL: TestRouterNotAllowedYDNAR (0.00s)
...
notallowedYDNAR_test.go:33: Handling GET / failed. Want=404 Got=200
...
And the router is right, as said in README.md
, https://github.com/julienschmidt/httprouter#catch-all-parameters, a route like router.Handle("OPTIONS", "/*path", handlerFunc)
will even match, so if you request it with a different method, it should return 405. I would like both yours and @julienschmidt opinion on this.
Thank you @ydnar for both examples.
from httprouter.
I can think of two ways to solve this (there are probably more):
- Skip wildcard routes when detecting
MethodNotAllowed
. - Treat OPTIONS requests as a special case. They should only exist for existing other routes (GET, POST, etc.). Browsers issue OPTIONS requests during the CORS preflight process.
The wildcard route we used in the example above is symptomatic of our desire to not repeat our routes. We could solve this with an OptionsHandler
, similar to NotFound
, or a helper func that automatically generates handlers for OPTIONS requests for other methods.
from httprouter.
... or just add an option to turn the 405 handling off.
The abuse of the NotFound handler to chain the router is not really intended and probably not a really common use case. But of course it is not my intention to make this use-case impossible.
from httprouter.
No comments?
I'd like to reintroduce the 405 support soon again.
from httprouter.
No comments from me actually because I had two hard weeks at university.
Your solution of turning on/off 405 method looks nice.
I'll try to push a new pull request soon.
As always, I'm reading your mails, but sometimes I'm not able to respond quickly.
—
Enviado desde Mailbox
On Tue, Jan 13, 2015 at 3:43 PM, Julien Schmidt [email protected]
wrote:
No comments?
I'd like to reintroduce the 405 support soon again.
Reply to this email directly or view it on GitHub:
#52 (comment)
from httprouter.
Related Issues (20)
- Run into 404 instead of graphql playground when using gqlgen with httprouter HOT 1
- How to use this custom middleware HOT 1
- Matching multiple named parameters HOT 1
- ServeFiles not able to serve static files HOT 2
- How can I receive multiple parameters in GET request? HOT 3
- Is it possible to bind one router to some path in another router? HOT 2
- is it possible to get the registered path? HOT 7
- panic: '/hello/:name' in new path '/hello/:name' conflicts with existing wildcar
- Why make catchAll form so special HOT 2
- httprouter.ParamsWithContext(r.Context()) is returning []
- Question: will re-registering a handler work properly?
- Fails with "embed" package HOT 1
- Dump all registered routes HOT 3
- Improve longestCommonPrefix and add unit tests HOT 1
- Question: How can I embed swagger UI? HOT 2
- Feature Request: Support multi-wildcard names for same tree branch HOT 1
- panic: path must begin with '/' in path 'GET'
- List all registered endpoint httprouter
- what is the empty path node used for? HOT 1
- Unable to load jsx files because "file.jsx was blocked because of a disallowed MIME type text/plain" HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from httprouter.