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

时间:2015-09-01 11:44:46

标签: go

如果我使用DefaultServeMux(我通过将nil作为第二个参数传递给ListenAndServe来指定),那么我可以访问http.HandleFunc,您在下面的示例中使用了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) } 去维基:

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

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

http.HandleFunc

所以我没有内置http.HandleFunc。但是,我必须修改一些授权代码到我需要"/protected"之类的代码库。例如,如果我一直在使用DefaultServeMux,当我点击Protected路由时,我会想要转到h.AuthorizationHandlerFunc处理程序,但只有在经过这样的 h.AuthorizationHandlerFunc(Protected) 之后

Protected

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

问题:在这种情况下如何实现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") } (不使用DefaultServeMux)?

#pragma strict

public var myText : GameObject; // Assign the text to this in the inspector

function Start() {
yield WaitForSeconds (5);
myText.SetActive( true ); // Enable the text so it shows
yield WaitForSeconds (5);
myText.SetActive( false ); // Disable the text so it is hidden
}

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

1 个答案:

答案 0 :(得分:1)

将您的授权中间件重新实现为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 lib I wrote的其他示例。上述内容和在您的类型上明确创建ServeHTTP方法都是有效的方法。