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

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

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)

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:

确定