// Creates a closure function that is used as an http handler for browsers to // subscribe to events via longpolling. // Notice how we're wrapping LongpollManager.SubscriptionHandler in order to // add our own logic and validation. func getEventSubscriptionHandler(manager *golongpoll.LongpollManager) func(w http.ResponseWriter, r *http.Request) { // Creates closure that captures the LongpollManager // Wraps the manager.SubscriptionHandler with a layer of dummy access control validation return func(w http.ResponseWriter, r *http.Request) { category := r.URL.Query().Get("category") user := r.URL.Query().Get("user") // NOTE: real user authentication should be used in the real world! // Dummy user access control in the event the client is requesting // a user's private activity stream: if category == "larry_actions" && user != "larry" { w.WriteHeader(http.StatusForbidden) w.Write([]byte("You're not Larry.")) return } if category == "moe_actions" && user != "moe" { w.WriteHeader(http.StatusForbidden) w.Write([]byte("You're not Moe.")) return } if category == "curly_actions" && user != "curly" { w.WriteHeader(http.StatusForbidden) w.Write([]byte("You're not Curly.")) return } // Only allow supported subscription categories: if category != "public_actions" && category != "larry_actions" && category != "moe_actions" && category != "curly_actions" { w.WriteHeader(http.StatusBadRequest) w.Write([]byte("Subscription channel does not exist.")) return } // Client is either requesting the public stream, or a private // stream that they're allowed to see. // Go ahead and let the subscription happen: manager.SubscriptionHandler(w, r) } }