如何在所有处理程序之前运行一个函数?

huangapple go评论117阅读模式
英文:

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地址后调用另一个处理程序:

  1. type checker struct {
  2. h http.Handler
  3. }
  4. func (c checker) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  5. if blackListed(r.RemoteAddr) {
  6. http.Error(w, "not authorized", http.StatusForbidden)
  7. return
  8. }
  9. c.h.ServeHTTP(w, r)
  10. }

将此处理程序传递给ListenAndServe,而不是原始处理程序。例如,如果你有:

  1. err := http.ListenAndServe(addr, mux)

将代码更改为:

  1. err := http.ListenAndServe(addr, checker{mux})

这也适用于所有的ListenAndServe变体。它适用于http.ServeMux、Gorilla mux和其他路由器。

英文:

Create a handler that invokes another handler after checking the IP address:

  1. type checker struct {
  2. h http.Handler
  3. }
  4. func (c checker) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  5. if blackListed(r.RemoteAddr) {
  6. http.Error(w, "not authorized", http.StatusForbidden)
  7. return
  8. }
  9. c.h.ServeHTTP(w, r)
  10. }

Pass this handler to ListenAndServe instead of your original handler. For example, if you had:

  1. err := http.ListenAndServe(addr, mux)

change the code to

  1. 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。我创建了一个记录一些请求信息的函数(中间件)。

  1. func main() {
  2. r := mux.NewRouter()
  3. // 处理程序
  4. r.HandleFunc("/hello", helloWorldHandler)
  5. // 使用中间件记录所有请求
  6. r.Use(logMiddleware)
  7. http.ListenAndServe(":8080", r)
  8. }
  9. func logMiddleware(next http.Handler) http.Handler {
  10. return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  11. // 在这里添加你的中间件代码
  12. log.Printf("收到来自 %s 的请求 %s", r.RemoteAddr, r.URL.Path)
  13. // 调用链中的下一个处理程序
  14. next.ServeHTTP(w, r)
  15. })
  16. }
  17. func helloHandler(w http.ResponseWriter, r *http.Request) {
  18. fmt.Println("Hello world!")
  19. }

希望这可以帮助到你!

英文:

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

  1. func main() {
  2. r := mux.NewRouter()
  3. // Handlers
  4. r.HandleFunc("/hello", helloWorldHandler)
  5. // use middleware to log all requests
  6. r.Use(logMiddleware)
  7. http.ListenAndServe(":8080", r)
  8. }
  9. func logMiddleware(next http.Handler) http.Handler {
  10. return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  11. // add your middleware code here
  12. log.Printf("received request for %s from %s", r.URL.Path, r.RemoteAddr)
  13. // call the next handler in the chain
  14. next.ServeHTTP(w, r)
  15. })}
  16. func helloHandler(w http.ResponseWriter, r *http.Request) {
  17. fmt.Println("Hello world!")
  18. }

答案3

得分: -1

如果你想使用默认的复用器(muxer),我发现这是常见的,你可以创建一个中间件,像这样:

  1. func mustBeLoggedIn(handler func(http.ResponseWriter, *http.Request)) func(http.ResponseWriter, *http.Request) {
  2. return func(w http.ResponseWriter, r *http.Request) {
  3. // 我是否已登录?
  4. if ...未登录... {
  5. http.Error(w, err.Error(), http.StatusUnauthorized)
  6. return
  7. }
  8. // 传递给原始处理程序。
  9. handler(w, r)
  10. }
  11. }

使用方法如下:

  1. http.HandleFunc("/some/priveliged/action", mustBeLoggedIn(myVanillaHandler))
  2. http.ListenAndServe(":80", nil)
英文:

If you want to use the default muxer, which i find is common, you can create middleware like so:

  1. func mustBeLoggedIn(handler func(http.ResponseWriter, *http.Request)) func(http.ResponseWriter, *http.Request) {
  2. return func(w http.ResponseWriter, r *http.Request) {
  3. // Am i logged in?
  4. if ...not logged in... {
  5. http.Error(w, err.Error(), http.StatusUnauthorized)
  6. return
  7. }
  8. // Pass through to the original handler.
  9. handler(w, r)
  10. }
  11. }

Use it like so:

  1. http.HandleFunc("/some/priveliged/action", mustBeLoggedIn(myVanillaHandler))
  2. http.ListenAndServe(":80", nil)

huangapple
  • 本文由 发表于 2015年1月21日 23:30:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/28070923.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定