diff --git a/functional/Procfile b/functional/Procfile index 61ac41f..807bb49 100644 --- a/functional/Procfile +++ b/functional/Procfile @@ -1,2 +1,2 @@ client: go run client.go -server: go run ../main.go -config ./functional-config.json -logtostderr \ No newline at end of file +server: go run ../main.go -config ./functional-config.json -alsologtostderr \ No newline at end of file diff --git a/ipe/context.go b/ipe/context.go index 0ca02ab..bd98b0d 100644 --- a/ipe/context.go +++ b/ipe/context.go @@ -10,13 +10,20 @@ type applicationContext struct { DB db } +// url params +type params map[string]string + +func (p params) Get(key string) string { + return p[key] +} + // A handlerHTTPC responds to an HTTP request with custom application context. type handlerHTTPC interface { - ServeHTTPC(ctx *applicationContext, w http.ResponseWriter, r *http.Request) + ServeHTTPC(ctx *applicationContext, p params, w http.ResponseWriter, r *http.Request) } -type handlerHTTPCFunc func(ctx *applicationContext, w http.ResponseWriter, r *http.Request) +type handlerHTTPCFunc func(ctx *applicationContext, p params, w http.ResponseWriter, r *http.Request) -func (c handlerHTTPCFunc) ServeHTTPC(ctx *applicationContext, w http.ResponseWriter, r *http.Request) { - c(ctx, w, r) +func (c handlerHTTPCFunc) ServeHTTPC(ctx *applicationContext, p params, w http.ResponseWriter, r *http.Request) { + c(ctx, p, w, r) } diff --git a/ipe/handlers.go b/ipe/handlers.go index d18945a..b279e95 100644 --- a/ipe/handlers.go +++ b/ipe/handlers.go @@ -13,7 +13,6 @@ import ( "strings" log "github.com/golang/glog" - "github.com/gorilla/mux" "github.com/dimiro1/ipe/utils" ) @@ -48,9 +47,8 @@ func prepareQueryString(params url.Values) string { // * The query parameters sorted by key, with keys converted to lowercase, then joined as in the query string. // Note that the string must not be url escaped (e.g. given the keys auth_key: foo, Name: Something else, you get auth_key=foo&name=Something else) func restAuthenticationHandler(ctx *applicationContext, h handlerHTTPC) handlerHTTPC { - return handlerHTTPCFunc(func(ctx *applicationContext, w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - appID := vars["app_id"] + return handlerHTTPCFunc(func(ctx *applicationContext, p params, w http.ResponseWriter, r *http.Request) { + appID := p.Get("app_id") app, err := ctx.DB.GetAppByAppID(appID) @@ -60,17 +58,17 @@ func restAuthenticationHandler(ctx *applicationContext, h handlerHTTPC) handlerH return } - params := r.URL.Query() + query := r.URL.Query() - signature := params.Get("auth_signature") - params.Del("auth_signature") + signature := query.Get("auth_signature") + query.Del("auth_signature") - queryString := prepareQueryString(params) + queryString := prepareQueryString(query) toSign := strings.ToUpper(r.Method) + "\n" + r.URL.Path + "\n" + queryString if utils.HashMAC([]byte(toSign), []byte(app.Secret)) == signature { - h.ServeHTTPC(ctx, w, r) + h.ServeHTTPC(ctx, p, w, r) } else { log.Error("Not authorized") http.Error(w, "Not authorized", http.StatusUnauthorized) @@ -80,9 +78,8 @@ func restAuthenticationHandler(ctx *applicationContext, h handlerHTTPC) handlerH // Check if the application is disabled func restCheckAppDisabledHandler(ctx *applicationContext, h handlerHTTPC) handlerHTTPC { - return handlerHTTPCFunc(func(ctx *applicationContext, w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - appID := vars["app_id"] + return handlerHTTPCFunc(func(ctx *applicationContext, p params, w http.ResponseWriter, r *http.Request) { + appID := p.Get("app_id") currentApp, err := ctx.DB.GetAppByAppID(appID) @@ -96,7 +93,7 @@ func restCheckAppDisabledHandler(ctx *applicationContext, h handlerHTTPC) handle return } - h.ServeHTTPC(ctx, w, r) + h.ServeHTTPC(ctx, p, w, r) }) } @@ -120,9 +117,8 @@ func commonHandlers(ctx *applicationContext, h handlerHTTPCFunc) handlerHTTPC { // Response is an empty JSON hash. // // POST /apps/{app_id}/events -func postEvents(ctx *applicationContext, w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - appID := vars["app_id"] +func postEvents(ctx *applicationContext, p params, w http.ResponseWriter, r *http.Request) { + appID := p.Get("app_id") app, err := ctx.DB.GetAppByAppID(appID) @@ -186,13 +182,12 @@ func postEvents(ctx *applicationContext, w http.ResponseWriter, r *http.Request) // } // // GET /apps/{app_id}/channels -func getChannels(ctx *applicationContext, w http.ResponseWriter, r *http.Request) { - params := r.URL.Query() - vars := mux.Vars(r) +func getChannels(ctx *applicationContext, p params, w http.ResponseWriter, r *http.Request) { + query := r.URL.Query() - appID := vars["app_id"] - filter := params.Get("filter_by_prefix") - info := params.Get("info") + appID := p.Get("app_id") + filter := query.Get("filter_by_prefix") + info := query.Get("info") attributes := strings.Split(info, ",") @@ -267,20 +262,19 @@ func getChannels(ctx *applicationContext, w http.ResponseWriter, r *http.Request // } // // GET /apps/{app_id}/channels/{channel_name} -func getChannel(ctx *applicationContext, w http.ResponseWriter, r *http.Request) { +func getChannel(ctx *applicationContext, p params, w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json;charset=UTF-8") - params := r.URL.Query() - vars := mux.Vars(r) + query := r.URL.Query() - appID := vars["app_id"] + appID := p.Get("app_id") app, err := ctx.DB.GetAppByAppID(appID) if err != nil { http.Error(w, fmt.Sprintf("Could not found an app with app_id: %s", appID), http.StatusBadRequest) } - channelName := vars["channel_name"] + channelName := p.Get("channel_name") // Channel name could not be empty if strings.TrimSpace(channelName) == "" { @@ -288,7 +282,7 @@ func getChannel(ctx *applicationContext, w http.ResponseWriter, r *http.Request) return } - info := params.Get("info") + info := query.Get("info") attributes := strings.Split(info, ",") // Attributes requested @@ -357,11 +351,9 @@ func getChannel(ctx *applicationContext, w http.ResponseWriter, r *http.Request) // } // // GET /apps/{app_id}/channels/{channel_name}/users -func getChannelUsers(ctx *applicationContext, w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - - appID := vars["app_id"] - channelName := vars["channel_name"] +func getChannelUsers(ctx *applicationContext, p params, w http.ResponseWriter, r *http.Request) { + appID := p.Get("app_id") + channelName := p.Get("channel_name") isPresence := utils.IsPresenceChannel(channelName) diff --git a/ipe/router.go b/ipe/router.go index e553501..d39d4a3 100644 --- a/ipe/router.go +++ b/ipe/router.go @@ -24,14 +24,18 @@ func newRouter(ctx *applicationContext) *router { } func (a *router) GET(path string, handler handlerHTTPC) { - a.mux.Methods("GET").Path(path).HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - handler.ServeHTTPC(a.ctx, w, r) - }) + a.Handle("GET", path, handler) } func (a *router) POST(path string, handler handlerHTTPC) { - a.mux.Methods("POST").Path(path).HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - handler.ServeHTTPC(a.ctx, w, r) + a.Handle("POST", path, handler) +} + +func (a *router) Handle(method, path string, handler handlerHTTPC) { + a.mux.Methods(method).Path(path).HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + p := params(mux.Vars(r)) + + handler.ServeHTTPC(a.ctx, p, w, r) }) } diff --git a/ipe/websocket.go b/ipe/websocket.go index 5d57f33..4d8d429 100644 --- a/ipe/websocket.go +++ b/ipe/websocket.go @@ -13,7 +13,6 @@ import ( "strings" log "github.com/golang/glog" - "github.com/gorilla/mux" "github.com/gorilla/websocket" "github.com/dimiro1/ipe/utils" @@ -207,7 +206,7 @@ func onMessage(conn *websocket.Conn, w http.ResponseWriter, r *http.Request, ses } // Websocket GET /app/{key} -func wsHandler(ctx *applicationContext, w http.ResponseWriter, r *http.Request) { +func wsHandler(ctx *applicationContext, p params, w http.ResponseWriter, r *http.Request) { conn, err := upgrader.Upgrade(w, r, nil) defer func() { if conn != nil { @@ -220,8 +219,7 @@ func wsHandler(ctx *applicationContext, w http.ResponseWriter, r *http.Request) return } - vars := mux.Vars(r) - appKey := vars["key"] + appKey := p.Get("key") app, err := ctx.DB.GetAppByKey(appKey)