dongpenggan6812 2019-01-30 14:54
浏览 93
已采纳

转到r.Use并返回错误的Gorilla Mux MiddlewareFunc

How do you set up Gorilla Mux r.Use to return errors down the middleware chain? https://godoc.org/github.com/gorilla/mux#Router.Use

Main.go

r := mux.NewRouter()

r.Use(LoggingFunc)
r.Use(AuthFunc)

Basic middleware

Starts with logging middleware which can catch and handle errors from further down the chain

type HandlerFunc func(w http.ResponseWriter, r *http.Request) error

func LoggingFunc(next HandlerFunc) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // Logging middleware

        defer func() {
            if err, ok := recover().(error); ok {
                w.WriteHeader(http.StatusInternalServerError)
            }
        }()

        err := next(w, r)
        if err != nil {
            // log error
        }
    })
}

The next middleware handles authentication and returns an error to the logging middleware.

func AuthFunc(next HandlerFunc) HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) error {

        if r.GET("JWT") == "" {
            return fmt.Errorf("No JWT")
        }

        return next(w, r)
    }
}

I keep getting errors like

  cannot use AuthFunc (type func(handlers.HandlerFunc) http.Handler) as type mux.MiddlewareFunc in argument to r.Use

Thanks

  • 写回答

1条回答 默认 最新

  • dqybjj3497 2019-01-30 17:00
    关注

    According to the mux.Use doc its argument type is MiddlewareFunc which return type is http.Handler not error type. You have to define which return type is http.HandlerFunc

    type Middleware func(http.HandlerFunc) http.HandlerFunc
    
    func main() {
        r := mux.NewRouter()
    
        //  execute middleware from right to left of the chain
        chain := Chain(SayHello, AuthFunc(), LoggingFunc())
        r.HandleFunc("/", chain)
    
        println("server listening :  8000")
        http.ListenAndServe(":8000", r)
    }
    
    // Chain applies middlewares to a http.HandlerFunc
    func Chain(f http.HandlerFunc, middlewares ...Middleware) http.HandlerFunc {
        for _, m := range middlewares {
            f = m(f)
        }
        return f
    }
    
    func LoggingFunc() Middleware {
        return func(next http.HandlerFunc) http.HandlerFunc {
            return func(w http.ResponseWriter, r *http.Request) {
                // Loggin middleware
    
                defer func() {
                    if _, ok := recover().(error); ok {
                        w.WriteHeader(http.StatusInternalServerError)
                    }
                }()
    
                // Call next middleware/handler in chain
                next(w, r)
            }
        }
    }
    
    func AuthFunc() Middleware {
        return func(next http.HandlerFunc) http.HandlerFunc {
            return func(w http.ResponseWriter, r *http.Request) {
    
                if r.Header.Get("JWT") == "" {
                    fmt.Errorf("No JWT")
                    return
                }
    
                next(w, r)
            }
        }
    
    }
    
    func SayHello(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintln(w, "Hello client")
    }
    

    It will execute the LogginFunc then AuthFunc and then SayHello method which is your desire method after passing all those middlewares.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 delta降尺度计算的一些细节,有偿
  • ¥15 Arduino红外遥控代码有问题
  • ¥15 数值计算离散正交多项式
  • ¥30 数值计算均差系数编程
  • ¥15 redis-full-check比较 两个集群的数据出错
  • ¥15 Matlab编程问题
  • ¥15 训练的多模态特征融合模型准确度很低怎么办
  • ¥15 kylin启动报错log4j类冲突
  • ¥15 超声波模块测距控制点灯,灯的闪烁很不稳定,经过调试发现测的距离偏大
  • ¥15 import arcpy出现importing _arcgisscripting 找不到相关程序