gpt4 book ai didi

go - 如何在不使用 DefaultServeMux 的情况下实现 HandlerFunc

转载 作者:数据小太阳 更新时间:2023-10-29 03:16:35 26 4
gpt4 key购买 nike

如果我要使用 DefaultServeMux(我通过将 nil 作为第二个参数传递给 ListenAndServe 来指定),那么我可以访问 http.HandleFunc,您请参阅 Go wiki 中此示例中使用的以下内容:

func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:])
}

func main() {
http.HandleFunc("/", handler)
http.ListenAndServe(":8080", nil)
}

在我当前的代码中,我无法使用 DefaultServeMux,即我将自定义处理程序传递给 ListenAndServe

    h := &mypackage.Handler{
Database: mydb
}
http.ListenAndServe(":8080", h)

所以我没有得到内置的http.HandleFunc。但是,我必须使一些授权代码适应我的代码库,它需要像http.HandleFunc这样的东西.例如,如果我一直在使用 DefaultServeMux,当我点击 "/protected" 路由时,我想转到 Protected 处理程序,但只有在通过h.AuthorizationHandlerFunc 像这样

   h.AuthorizationHandlerFunc(Protected)

但是,由于我没有使用 DefaultServeMux,它无法正常工作,即我无法将 Protected 函数(并调用它)传递给 AuthorizationHandlerFunc .这是下面 AuthorizationHandlerFunc 的实现。您可以在下面看到 Protected 永远不会被调用。

问题:如何在这种情况下实现HandlerFunc(不使用DefaultServeMux)?

func (h *Handler) AuthorizationHandlerFunc(next http.HandlerFunc) http.Handler{
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request){
h.AuthorizationMiddleWare(w, r, next)
})
}

func (h *Handler) AuthorizationMiddleWare(w http.ResponseWriter, r *http.Request, next http.HandlerFunc){
//other stuff happens
log.Println("this is never getting called")
next(w,r)
}
func (h *Handler)Protected(w http.ResponseWriter, r *http.Request){

log.Println("this is never getting called")
}

更新ServeHTTP 在 mypackage.Handler 上实现。为什么 Protected 函数没有被调用,或者就此而言,AuthorizationMiddleWare 中的相关代码?

最佳答案

将您的授权中间件重新实现为 http.Handler:

type auth struct {
DB *sql.DB
UnauthorizedHandler http.Handler
}

func NewAuth(db *sql.DB, unauthorized http.Handler) *auth {
return auth{db, unauthorized}
}

func (a *auth) Protected(h http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
// Check whether the request is valid
// If it's invalid, call your error func and make sure to *return* early!
if !valid {
a.UnauthorizedHandler.ServeHTTP(w, r)
return
}
// Call the next handler on success
h.ServeHTTP(w, r)
return
}

return http.HandlerFunc(fn)
}

func someHandler(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "Hello!\n")
}

func main() {
auth := NewAuth(db, errorHandler)
r := http.NewServeMux()
// We have a http.Handler implementation that wraps a http.HandlerFunc
// ... so we call r.Handle on our ServeMux and type-cast the wrapped func
r.Handle("/protected", auth.Protected(http.HandlerFunc(someHandler)))
// Just a simple http.HandlerFunc here
r.HandleFunc("/public", someOtherHandler)

log.Fatal(http.ListenAndServe(":8000", r))
}

看看 httpauth lib I wrote对于使用 ServeHTTP 方法的不同示例。上述方法和在您的类型上显式创建 ServeHTTP 方法都是有效的方法。

关于go - 如何在不使用 DefaultServeMux 的情况下实现 HandlerFunc,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32330744/

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