gpt4 book ai didi

go - Negroni 在请求完成后继续调用其他处理程序

转载 作者:IT王子 更新时间:2023-10-29 02:09:53 26 4
gpt4 key购买 nike

我的 Go 网络应用程序(使用 Gorilla muxnegroni)有大约 20 个处理程序,根据应应用的中间件功能分为三组。具体来说:

  • 第 1 组:静态请求(根本没有中间件)

    GET   /favicon.ico
    GET /files
    GET /files/index.html
    GET /files/favicon.ico
  • 第 2 组:应该只有 CORS 中间件的请求,没有身份验证:

    GET   /
    GET /login
    POST /login
    GET /auth-configuration
    GET /service-status
  • 第 3 组:应同时应用 CORS 和身份验证中间件的请求:

    GET   /articles
    POST /articles
    PUT /articles/etc
    PATCH /articles/etc

这是我设置 HTTP 服务器的代码:

func run() {

negroniStack := setUpNegroni()

bindAddr := // ...

http.ListenAndServe(bindAddr, negroniStack)
}

func setUpNegroni() negroni.Negroni {

negroniStack := negroni.Negroni{}

staticNegroni := setUpRoutesAndMiddlewareForStaticRequests()
loginNegroni := setUpRoutesAndMiddlewareForLogin()
serviceNegroni = setUpRoutesAndMiddlewareForService()

negroniStack.UseHandler(&staticNegroni)
negroniStack.UseHandler(&loginNegroni)
negroniStack.UseHandler(&serviceNegroni)

return negroniStack
}

func setUpRoutesAndMiddlewareForStaticRequests() negroni.Negroni {

staticNegroni := negroni.Negroni{}
staticRouter := mux.NewRouter()

staticRouter.PathPrefix("/files").HandlerFunc(staticHandler)
staticRouter.Path("/favicon.ico").HandlerFunc(staticHandler)

staticNegroni.UseHandler(staticRouter)
return staticNegroni
}

func setUpRoutesAndMiddlewareForLogin() negroni.Negroni {

authNegroni := negroni.Negroni{}

corsMiddleware := cors.New(cors.Options{
AllowedMethods: []string{"GET", "HEAD", "POST", "PUT", "PATCH", "DELETE"},
AllowCredentials: true,
OptionsPassthrough: false,
})

authNegroni.Use(corsMiddleware)

authRouter := mux.NewRouter()

authRouter.HandleFunc("/login", HandlePostAuth).Methods("POST")
authRouter.HandleFunc("/login", HandleGetAuth) // GET

authNegroni.UseHandler(authRouter)

return authNegroni
}

func setUpRoutesAndMiddlewareForService() negroni.Negroni {

serviceNegroni := negroni.Negroni{}

corsMiddleware := cors.New(cors.Options{
AllowedMethods: []string{"GET", "HEAD", "POST", "PUT", "PATCH", "DELETE"},
AllowCredentials: true,
OptionsPassthrough: false,
})
serviceNegroni.Use(corsMiddleware)

serviceNegroni.UseFunc(jwtMiddleware)

serviceRouter := mux.NewRouter()
serviceRouter.HandleFunc("/articles", HandleGetArticles).Methods("GET")
serviceRouter.HandleFunc("/articles", HandlePostArticles).Methods("POST")
// etc

serviceNegroni.UseHandler(serviceRouter)

return serviceNegroni
}

根据 Negroni's documentation 中的“特定于路由的中间件”部分,我认为这是正确的它说:

If you have a route group of routes that need specific middleware to be executed, you can simply create a new Negroni instance and use it as your route handler.

但是,当我发出请求并使用调试器时,我看到 (*Negroni).ServeHTTP 被多次调用。例如,如果我请求 GET/favicon.ico 然后 staticHandler 函数被正确调用并调用 WriteHeader(200),但在那之后它然后调用下一个 mux.Router,它调用 WriteHeader(404),它在终端中打印出一条警告,因为 header 被写入了两次(http: multiple response .WriteHeader 调用)

如果它用于不存在的路由,则 Gorilla 默认 NotFoundHandler 被调用 3 次(每个 mux.Router 一次)。

如何让 Negroni 在请求完成后停止调用其他处理程序?

...如果我错误配置了我的 Negroni 实例,为什么它不在初始化期间执行检查以警告我配置无效?

我的理解是 negroni.UseUseFunc 是设置中间件(每个请求都会调用),而 UseHandler 用于设置终端处理程序(每个请求仅调用 1 个,或回退到 404)。如果我正确理解了这种情况,那么出于某种原因它将我的终端处理程序视为中间件。

最佳答案

来自UseHandler文档 ( https://godoc.org/github.com/urfave/negroni#Negroni.UseHandler )

UseHandler adds a http.Handler onto the middleware stack. Handlers are invoked in the order they are added to a Negroni.

所以您在这里看到的似乎是预期的行为。

您基本上是在创建不同的 negroni 实例并将它们链接起来,因此您的最终 negroniStack本身就是一个中间件,它将执行您添加的其他中间件。

我相信您想要做的是使用实际路由器创建路由,然后将适当的中间件(使用 negroni)添加到每个路由。

如果您查看从文档中链接的示例,就会发现他们在该部分 (https://github.com/urfave/negroni#route-specific-middleware) 中所做的事情。

router.PathPrefix("/admin").Handler(negroni.New(
Middleware1,
Middleware2,
negroni.Wrap(adminRoutes),
))

看到它们不是嵌套 negroni 实例,而是只创建一个应用于所需路线的实例。

关于go - Negroni 在请求完成后继续调用其他处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50145256/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com