33

我正在使用 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 包装您的处理程序,否则您将泄漏内存!一个简单的方法是在调用 http.ListenAndServe 时包装顶层多路复用器:

我怎样才能防止这种情况?

4

5 回答 5

67

只需创建一个包装器,这在 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))
}
于 2014-10-05T16:30:11.243 回答
15
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)
}

mux 网站上的官方文档

于 2019-09-09T20:15:40.483 回答
13

我不确定为什么@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)
})}
于 2015-10-28T23:17:28.733 回答
6

如果您想将中间件链应用于路由器或子路由器的所有路由,您可以使用 Gorilla mux 的分支https://github.com/bezrukovspb/mux

subRouter := router.PathPrefix("/use-a-b").Subrouter().Use(middlewareA, middlewareB)
subRouter.Path("/hello").HandlerFunc(requestHandlerFunc)
于 2016-04-16T19:12:38.350 回答
0

您可能会考虑使用中间件包,例如negroni

于 2014-10-05T16:16:08.463 回答