I'm trying to implement two routes using the Chi router. One should be invoked only if the "host" header is set to example.com. But only the lastly added route is invoked.
r := chi.NewRouter()
r.Use(middleware.Logger)
middlewareHeader := middleware.RouteHeaders().Route("Host", "example.com", middleware.New(r)).Handler
r.With(middlewareHeader).MethodFunc("get", "/", func(w http.ResponseWriter, r *http.Request) {
log.Println("Host: example.com")
echo(w, r)
})
middlewareNone := middleware.RouteHeaders().Handler
r.With(middlewareNone).MethodFunc("get", "/", func(w http.ResponseWriter, r *http.Request) {
echo(w, r)
})
srv := &http.Server{
Handler: r,
Addr: "127.0.0.1:8080",
WriteTimeout: 15 * time.Second,
ReadTimeout: 15 * time.Second,
}
log.Fatal(srv.ListenAndServe())
As mentioned on comment: you cannot assign multiple handlers to one route.
RouteHeaders is a neat little header-based router that allows you to direct the flow of a request through a middleware stack based on a request header.
RouteHeaders
is used to put your request through specific middleware stack, not to change routes. You can still use it but middleware has to redirect to other route.
func redirectOnHeader(header, value string) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Header.Get(header) == value {
http.Redirect(w, r, "/with-header", http.StatusMovedPermanently)
return
}
next.ServeHTTP(w, r)
})
}
}
then call the middleware on desired route
r := chi.NewRouter()
r.With(redirectOnHeader("Host", "example.com")).Get("/", func(w http.ResponseWriter, r *http.Request) {
echo(w, r)
})
r.Get("/with-headers", func(w http.ResponseWriter, r *http.Request) {
echo(w, r)
})
RouteHeaders
As in example in docs.
Note that you need 2 routers on order to have 2 "/"
routes.
r := chi.NewRouter()
anotherR := chi.NewRouter()
r.Use(middleware.RouteHeaders().
Route("Host", "example.com", middleware.New(r)).
RouteDefault(middleware.New(anotherR)).
Handler)
r.Get("/", func(w http.ResponseWriter, r *http.Request) {
echo(w, r)
})
anotherR.Get("/", func(w http.ResponseWriter, r *http.Request) {
echo(w, r)
})
func(w http.ResponseWriter, r *http.Request) {
if r.Header.Get(header) == value {
// do something
return
}
// do something else
})