英文:
Gorilla mux custom middleware
问题
我正在使用gorilla mux来管理路由。我需要集成一个中间件来处理每个请求。
例如:
package main
import (
"fmt"
"github.com/gorilla/mux"
"log"
"net/http"
"strconv"
)
func HomeHandler(response http.ResponseWriter, request *http.Request) {
fmt.Fprintf(response, "Hello home")
}
func Middleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(response http.ResponseWriter, request *http.Request) {
// 在这里执行中间件逻辑
log.Println("Executing middleware")
next.ServeHTTP(response, request)
})
}
func main() {
port := 3000
portstring := strconv.Itoa(port)
r := mux.NewRouter()
r.HandleFunc("/", HomeHandler)
http.Handle("/", Middleware(r))
log.Print("Listening on port " + portstring + " ... ")
err := http.ListenAndServe(":"+portstring, nil)
if err != nil {
log.Fatal("ListenAndServe error: ", err)
}
}
每个传入的请求都会经过中间件。你可以通过创建一个中间件函数来实现。在这个函数中,你可以执行你想要的中间件逻辑,然后调用next.ServeHTTP(response, request)
来将请求传递给下一个处理程序。
更新
我将与gorilla/sessions一起使用,他们说:
重要提示:如果你不使用gorilla/mux,你需要使用context.ClearHandler来包装你的处理程序,否则会导致内存泄漏!在调用http.ListenAndServe时,一种简单的方法是包装顶级mux:
你可以使用context.ClearHandler
来解决这个问题。在调用http.ListenAndServe
时,将顶级mux包装在context.ClearHandler
中即可。
英文:
I am using gorilla mux for manage routing. What I am missing is to integrate a middleware between every request.
For example
package main
import (
"fmt"
"github.com/gorilla/mux"
"log"
"net/http"
"strconv"
)
func HomeHandler(response http.ResponseWriter, request *http.Request) {
fmt.Fprintf(response, "Hello home")
}
func main() {
port := 3000
portstring := strconv.Itoa(port)
r := mux.NewRouter()
r.HandleFunc("/", HomeHandler)
http.Handle("/", r)
log.Print("Listening on port " + portstring + " ... ")
err := http.ListenAndServe(":"+portstring, nil)
if err != nil {
log.Fatal("ListenAndServe error: ", err)
}
}
Every incoming request should pass through the middleware. How can I integrate here a midleware?
Update
I will use it in combination with gorilla/sessions, and they say:
> Important Note: If you aren't using gorilla/mux, you need to wrap your
> handlers with context.ClearHandler as or else you will leak memory! An
> easy way to do this is to wrap the top-level mux when calling
> http.ListenAndServe:
How can I prevent this scenario?
答案1
得分: 74
只需在Go中创建一个包装器即可,非常简单:
func HomeHandler(response http.ResponseWriter, request *http.Request) {
fmt.Fprintf(response, "Hello home")
}
func Middleware(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log.Println("middleware", r.URL)
h.ServeHTTP(w, r)
})
}
func main() {
r := mux.NewRouter()
r.HandleFunc("/", HomeHandler)
http.Handle("/", Middleware(r))
}
这段代码创建了一个名为HomeHandler
的函数,用于处理主页请求。Middleware
函数是一个中间件,用于在处理请求之前和之后执行一些操作。main
函数是程序的入口点,它创建了一个路由器r
,并将HomeHandler
函数与根路径"/"进行绑定。然后,通过Middleware
函数将路由器作为参数传递给http.Handle
函数,以便在处理请求时应用中间件。
英文:
Just create a wrapper, it's rather easy in Go:
func HomeHandler(response http.ResponseWriter, request *http.Request) {
fmt.Fprintf(response, "Hello home")
}
func Middleware(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log.Println("middleware", r.URL)
h.ServeHTTP(w, r)
})
}
func main() {
r := mux.NewRouter()
r.HandleFunc("/", HomeHandler)
http.Handle("/", Middleware(r))
}
答案2
得分: 25
Mux有一种官方的方法来实现中间件,可以参考以下示例代码:
// 一个普通的中间件
func Middleware(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// 在处理程序之前做一些事情
h.ServeHTTP(w, r)
// 在处理程序之后做一些事情
})
}
// 如果你想将数据传递给中间件
func Middleware2(s string) mux.MiddlewareFunc {
return func(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// 做一些事情
fmt.Println(s)
h.ServeHTTP(w, r)
})
}
}
func main() {
router := mux.NewRouter()
router.Use(Middleware)
// 你也可以将中间件应用于子路由器
subRouter := router.PathPrefix("/sub_router/").Subrouter()
subRouter.Use(Middleware2("somePrams"))
// 如果需要,可以添加更多的中间件,再次调用 router.Use
router.Use(Middleware3, Middleware4, Middleware5)
_ = http.ListenAndServe(":80", router)
}
你可以在 mux官方文档 上找到更多关于中间件的信息。
英文:
Mux has an official way of doing it
look on this example
// a regular middleware
func Middleware(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// do stuff before the handlers
h.ServeHTTP(w, r)
// do stuff after the hadlers
})
}
// if you want to pass data into the middleware
func Middleware2(s string) mux.MiddlewareFunc {
return func(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// do stuff
fmt.Println(s)
h.ServeHTTP(w, r)
})
}
}
func main() {
router := mux.NewRouter()
router.Use(Middleware)
//you can apply it to a sub-router too
subRouter := router.PathPrefix("/sub_router/").Subrouter()
subRouter.Use(Middleware2("somePrams"))
// Add more middleware if you need, call router.Use Again
router.Use(Middleware3, Middleware4, Middleware5)
_ = http.ListenAndServe(":80", router)
}
答案3
得分: 13
我不确定为什么@OneOfOne选择将路由器链接到中间件中,我认为这是一个稍微更好的方法:
func main() {
r.Handle("/", Middleware(http.HandlerFunc(homeHandler)))
http.Handle("/", r)
}
func Middleware(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
h.ServeHTTP(w, r)
})
}
英文:
I'm not sure why @OneOfOne chose to chain router into the Middleware, I think this is slight better approach:
func main() {
r.Handle("/",Middleware(http.HandlerFunc(homeHandler)))
http.Handle("/", r)
}
func Middleware(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
h.ServeHTTP(w, r)
})}
答案4
得分: 6
如果你想将中间件链应用于路由器或子路由器的所有路由,你可以使用Gorilla mux的一个分支 https://github.com/bezrukovspb/mux
subRouter := router.PathPrefix("/use-a-b").Subrouter().Use(middlewareA, middlewareB)
subRouter.Path("/hello").HandlerFunc(requestHandlerFunc)
英文:
If you want to apply a middleware chain to all routes of a router or subrouter you can use a fork of Gorilla mux https://github.com/bezrukovspb/mux
subRouter := router.PathPrefix("/use-a-b").Subrouter().Use(middlewareA, middlewareB)
subRouter.Path("/hello").HandlerFunc(requestHandlerFunc)
答案5
得分: 0
你可以考虑使用一个中间件包,比如negroni。
英文:
You might consider a middleware package such as negroni.
1: http://negroni.codegangsta.io/ "negroni"
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论