如果我要使用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))
}
看一下我为一个ServeHTTP
方法的不同示例编写的httpauth库。以上和ServeHTTP
在您的类型上显式创建方法都是有效的方法。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句