Gorilla mux 自定义中间件
Posted
技术标签:
【中文标题】Gorilla mux 自定义中间件【英文标题】:Gorilla mux custom middleware 【发布时间】:2014-11-30 00:28:01 【问题描述】:我正在使用 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 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)
每个传入的请求都应该通过中间件。如何在此处集成中间件?
更新
我会将它与 gorilla/sessions 结合使用,他们说:
重要提示:如果您不使用 gorilla/mux,则需要将您的 处理程序与 context.ClearHandler as 否则你会泄漏内存!一个 简单的方法是在调用时包装顶层多路复用器 http.ListenAndServe:
如何防止这种情况发生?
【问题讨论】:
对于那些登陆这里的人:gorilla/mux
现在有内置的中间件处理:github.com/gorilla/mux#middleware
【参考方案1】:
func Middleware(h http.Handler) http.Handler
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request)
// do stuff
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)
// 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)
the official doc on the mux website
【讨论】:
【参考方案2】:如果您想将中间件链应用于路由器或子路由器的所有路由,您可以使用 Gorilla mux 的 fork https://github.com/bezrukovspb/mux
subRouter := router.PathPrefix("/use-a-b").Subrouter().Use(middlewareA, middlewareB)
subRouter.Path("/hello").HandlerFunc(requestHandlerFunc)
【讨论】:
谢谢老兄!这种 express.js 中间件风格正是我想要的 gorilla mux 中内置了中间件使用 @ozy 你的意思是router.Use(),不过最好用一个子路由器,这样中间件可以应用到不同的地方。【参考方案3】:我不确定为什么@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)
)
【讨论】:
这种方法正是我想要的——带有中间件的嵌套Handle
。谢谢!
这和@OneOfOne 的回答差不多【参考方案4】:
只需创建一个包装器,在 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))
【讨论】:
谢谢你,h.ServeHTTP(w, r)
这部分是我所缺少的。他们并没有说得很清楚如何直接调用 Handler。
也可以使用r.Use(Middleware)
注册中间件。【参考方案5】:
您可以考虑使用中间件包,例如 negroni。
【讨论】:
当我使用gorilla/sessions时,它不会发生内存泄漏? 我无法编辑,因为Suggested edit queue is full
。 链接 不再存在。我想换一个新的negroni以上是关于Gorilla mux 自定义中间件的主要内容,如果未能解决你的问题,请参考以下文章