使用 Golang Gorilla 包设置回调

Setting callback with Golang Gorilla package

是否有一种简单的方法来设置在对 gorilla/mux HTTP 网络服务器发出的每个 HTTP 请求时调用的回调函数?他们似乎没有在他们的文档中设置回调函数的概念。

我想检查 headers 之一以获取有关每次调用我的服务器的一些信息。

gorilla/mux 本身只是一个路由器和调度程序,虽然从技术上讲可以满足您的要求,但实际上并不是它的设计目的。

"idiomatic" 方法是用中间件包装您的处理程序,中间件用任何附加功能装饰您的处理程序,例如检查 headers 每次调用的一些信息。

在 gorilla/mux full example 上展开,您可以执行以下操作:

package main

import (
        "log"
        "net/http"

        "github.com/gorilla/mux"
)

func HeaderCheckWrapper(requiredHeader string, original func(http.ResponseWriter, *http.Request)) func(http.ResponseWriter, *http.Request) {
        return func(w http.ResponseWriter, r *http.Request) {
                if foo, ok := r.Header[requiredHeader]; ok {
                        // do whatever with the header value, and then call the original:
                        log.Printf("Found header %q, with value %q", requiredHeader, foo)
                        original(w, r)
                        return
                }
                // otherwise reject the request
                w.WriteHeader(http.StatusPreconditionFailed)
                w.Write([]byte("missing expected header " + requiredHeader))
        }
}

func YourHandler(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("Gorilla!\n"))
}

func main() {
        r := mux.NewRouter()
        // Routes consist of a path and a handler function.
        r.HandleFunc("/", HeaderCheckWrapper("X-Foo-Header", YourHandler))

        // Bind to a port and pass our router in
        log.Fatal(http.ListenAndServe(":8000", r))
}

如果您想要一个可以接收路由器中所有请求的处理程序,您可以使用 alice 将您的处理程序链接在一起。

这是一种处理所有传入请求的简单方法。

这是一个例子:

package main

import (
    "net/http"

    "github.com/gorilla/mux"
    "github.com/justinas/alice"
)

func MyMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        if len(r.URL.Path) > 1 {
            http.Error(w, "please only call index because this is a lame example", http.StatusNotFound)
            return
        }
        next.ServeHTTP(w, r)
    })
}

func Handler(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("Hello"))
}

func main() {
    r := mux.NewRouter()

    r.HandleFunc("/", Handler)
    r.HandleFunc("/fail", Handler)

    chain := alice.New(MyMiddleware).Then(r)

    http.ListenAndServe(":8080", chain)
}