英文:
How to run a function before all handlers?
问题
在使用net/http包或gorilla库时,是否可以在Web应用程序的任何处理程序之前执行一个函数?
这将非常有用,例如,在继续实际请求处理程序之前,可以检查传入请求是否来自黑名单IP地址。
英文:
Is it possible to execute a function before any handlers in a web application using the net/http package or any of the gorilla libraries?
This would be useful, for instance, to check if the incoming request is from a blacklisted IP address before proceeding to the actual request handlers.
答案1
得分: 6
创建一个处理程序,在检查IP地址后调用另一个处理程序:
type checker struct {
h http.Handler
}
func (c checker) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if blackListed(r.RemoteAddr) {
http.Error(w, "not authorized", http.StatusForbidden)
return
}
c.h.ServeHTTP(w, r)
}
将此处理程序传递给ListenAndServe,而不是原始处理程序。例如,如果你有:
err := http.ListenAndServe(addr, mux)
将代码更改为:
err := http.ListenAndServe(addr, checker{mux})
这也适用于所有的ListenAndServe变体。它适用于http.ServeMux、Gorilla mux和其他路由器。
英文:
Create a handler that invokes another handler after checking the IP address:
type checker struct {
h http.Handler
}
func (c checker) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if blackListed(r.RemoteAddr) {
http.Error(w, "not authorized", http.StatusForbidden)
return
}
c.h.ServeHTTP(w, r)
}
Pass this handler to ListenAndServe instead of your original handler. For example, if you had:
err := http.ListenAndServe(addr, mux)
change the code to
err := http.ListenAndServe(addr, checker{mux})
This also applies to all the variations of ListenAndServe. It works with http.ServeMux, Gorilla mux and other routers.
答案2
得分: 0
在每个处理程序之前运行一个函数(中间件),我将在这个示例中使用gorilla/mux。我创建了一个记录一些请求信息的函数(中间件)。
func main() {
r := mux.NewRouter()
// 处理程序
r.HandleFunc("/hello", helloWorldHandler)
// 使用中间件记录所有请求
r.Use(logMiddleware)
http.ListenAndServe(":8080", r)
}
func logMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// 在这里添加你的中间件代码
log.Printf("收到来自 %s 的请求 %s", r.RemoteAddr, r.URL.Path)
// 调用链中的下一个处理程序
next.ServeHTTP(w, r)
})
}
func helloHandler(w http.ResponseWriter, r *http.Request) {
fmt.Println("Hello world!")
}
希望这可以帮助到你!
英文:
To run a function (middleware) before each handler, i will use in this example gorilla/mux.
I created a function (middleware) that logs some of the request infos
func main() {
r := mux.NewRouter()
// Handlers
r.HandleFunc("/hello", helloWorldHandler)
// use middleware to log all requests
r.Use(logMiddleware)
http.ListenAndServe(":8080", r)
}
func logMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// add your middleware code here
log.Printf("received request for %s from %s", r.URL.Path, r.RemoteAddr)
// call the next handler in the chain
next.ServeHTTP(w, r)
})}
func helloHandler(w http.ResponseWriter, r *http.Request) {
fmt.Println("Hello world!")
}
答案3
得分: -1
如果你想使用默认的复用器(muxer),我发现这是常见的,你可以创建一个中间件,像这样:
func mustBeLoggedIn(handler func(http.ResponseWriter, *http.Request)) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
// 我是否已登录?
if ...未登录... {
http.Error(w, err.Error(), http.StatusUnauthorized)
return
}
// 传递给原始处理程序。
handler(w, r)
}
}
使用方法如下:
http.HandleFunc("/some/priveliged/action", mustBeLoggedIn(myVanillaHandler))
http.ListenAndServe(":80", nil)
英文:
If you want to use the default muxer, which i find is common, you can create middleware like so:
func mustBeLoggedIn(handler func(http.ResponseWriter, *http.Request)) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
// Am i logged in?
if ...not logged in... {
http.Error(w, err.Error(), http.StatusUnauthorized)
return
}
// Pass through to the original handler.
handler(w, r)
}
}
Use it like so:
http.HandleFunc("/some/priveliged/action", mustBeLoggedIn(myVanillaHandler))
http.ListenAndServe(":80", nil)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论