Removed GoJi in favor of Pressly Chi

This commit is contained in:
claudemiro
2016-08-22 23:06:15 -03:00
parent 4c5d5302ec
commit 4a305b32a6
6 changed files with 108 additions and 149 deletions
Generated
+5 -13
View File
@@ -1,20 +1,12 @@
hash: 0a451841a1f9493d419d658fab8da6863ef5df0645ddea506a225865078c9dcb
updated: 2016-08-10T22:23:10.989237578-03:00
hash: ee2de935e70f2a39cbfd2dd16add0736c698b32f5c02409d0c25844d883c91a1
updated: 2016-08-22T22:55:07.279113421-03:00
imports:
- name: github.com/golang/glog
version: 23def4e6c14b4da8ac2ed8007337bc5eb5007998
- name: github.com/gorilla/websocket
version: a69d25be2fe2923a97c2af6849b2f52426f68fc0
- name: github.com/pusher/pusher-http-go
version: 2bba5f217f6f0f4f0c0a9bb11b945b206b32bec5
- name: goji.io
version: e355964ac565b94cf0fc7f218346626529125086
- name: github.com/pressly/chi
version: 12aad88c7d86de2affe686f855b6ed94a07cba9c
subpackages:
- pat
- pattern
- internal
- name: golang.org/x/net
version: 075e191f18186a8ff2becaf64478e30f4545cdad
subpackages:
- context
- middleware
testImports: []
+3 -7
View File
@@ -2,10 +2,6 @@ package: github.com/dimiro1/ipe
import:
- package: github.com/golang/glog
- package: github.com/gorilla/websocket
- package: github.com/pusher/pusher-http-go
- package: goji.io
subpackages:
- pat
- package: golang.org/x/net
subpackages:
- context
- package: github.com/pressly/chi
excludeDirs:
- functional
+54 -85
View File
@@ -12,12 +12,8 @@ import (
"sort"
"strings"
goji "goji.io"
"goji.io/pat"
log "github.com/golang/glog"
"golang.org/x/net/context"
"github.com/pressly/chi"
"github.com/dimiro1/ipe/utils"
)
@@ -51,79 +47,64 @@ func prepareQueryString(params url.Values) string {
// * The request path (e.g. /some/resource)
// * 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(DB db, next goji.Handler) goji.HandlerFunc {
return func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
appID := pat.Param(ctx, "app_id")
func authenticationHandler(DB db) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
appID := chi.URLParam(r, "app_id")
app, err := DB.GetAppByAppID(appID)
app, err := DB.GetAppByAppID(appID)
if err != nil {
log.Error(err)
http.Error(w, "Not authorized", http.StatusUnauthorized)
return
if err != nil {
log.Error(err)
http.Error(w, "Not authorized", http.StatusUnauthorized)
return
}
query := r.URL.Query()
signature := query.Get("auth_signature")
query.Del("auth_signature")
queryString := prepareQueryString(query)
toSign := strings.ToUpper(r.Method) + "\n" + r.URL.Path + "\n" + queryString
if utils.HashMAC([]byte(toSign), []byte(app.Secret)) == signature {
next.ServeHTTP(w, r)
} else {
log.Error("Not authorized")
http.Error(w, "Not authorized", http.StatusUnauthorized)
}
}
query := r.URL.Query()
signature := query.Get("auth_signature")
query.Del("auth_signature")
queryString := prepareQueryString(query)
toSign := strings.ToUpper(r.Method) + "\n" + r.URL.Path + "\n" + queryString
if utils.HashMAC([]byte(toSign), []byte(app.Secret)) == signature {
next.ServeHTTPC(ctx, w, r)
} else {
log.Error("Not authorized")
http.Error(w, "Not authorized", http.StatusUnauthorized)
}
return http.HandlerFunc(fn)
}
}
// Check if the application is disabled
func restCheckAppDisabledHandler(DB db, next goji.Handler) goji.HandlerFunc {
return func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
appID := pat.Param(ctx, "app_id")
func checkAppDisabled(DB db) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
appID := chi.URLParam(r, "app_id")
currentApp, err := DB.GetAppByAppID(appID)
currentApp, err := DB.GetAppByAppID(appID)
if err != nil {
http.Error(w, fmt.Sprintf("Could not found an app with app_id: %s", appID), http.StatusForbidden)
return
}
if currentApp.ApplicationDisabled {
http.Error(w, "Application disabled", http.StatusForbidden)
return
}
next.ServeHTTPC(ctx, w, r)
}
}
func recoverHandler(next goji.Handler) goji.HandlerFunc {
return func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
defer func() {
if r := recover(); r != nil {
log.Errorf("Please verify the url parameters error was: %s", r)
http.Error(w, "Not authorized", http.StatusUnauthorized)
if err != nil {
http.Error(w, fmt.Sprintf("Could not found an app with app_id: %s", appID), http.StatusForbidden)
return
}
}()
next.ServeHTTPC(ctx, w, r)
if currentApp.ApplicationDisabled {
http.Error(w, "Application disabled", http.StatusForbidden)
return
}
next.ServeHTTP(w, r)
}
return http.HandlerFunc(fn)
}
}
// commonHandlers combine restCheckAppDisabledHandler and restAuthenticationHandler handlers
func commonHandlers(DB db, next goji.Handler) goji.HandlerFunc {
return recoverHandler(restCheckAppDisabledHandler(DB, restAuthenticationHandler(DB, next)))
}
func newPostEventsHandler(DB db) goji.HandlerFunc {
return commonHandlers(DB, &postEventsHandler{DB})
}
type postEventsHandler struct{ DB db }
// ServeHTTPC An event consists of a name and data (typically JSON) which may be sent to all subscribers to a particular channel or channels.
@@ -141,8 +122,8 @@ type postEventsHandler struct{ DB db }
// Response is an empty JSON hash.
//
// POST /apps/{app_id}/events
func (h *postEventsHandler) ServeHTTPC(ctx context.Context, w http.ResponseWriter, r *http.Request) {
appID := pat.Param(ctx, "app_id")
func (h *postEventsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
appID := chi.URLParam(r, "app_id")
app, err := h.DB.GetAppByAppID(appID)
@@ -187,10 +168,6 @@ func (h *postEventsHandler) ServeHTTPC(ctx context.Context, w http.ResponseWrite
w.Write([]byte("{}"))
}
func newGetChannelsHandler(DB db) goji.HandlerFunc {
return commonHandlers(DB, &getChannelsHandler{DB})
}
type getChannelsHandler struct{ DB db }
// Allows fetching a hash of occupied channels (optionally filtered by prefix),
@@ -212,10 +189,10 @@ type getChannelsHandler struct{ DB db }
// }
//
// GET /apps/{app_id}/channels
func (h *getChannelsHandler) ServeHTTPC(ctx context.Context, w http.ResponseWriter, r *http.Request) {
func (h *getChannelsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
query := r.URL.Query()
appID := pat.Param(ctx, "app_id")
appID := chi.URLParam(r, "app_id")
filter := query.Get("filter_by_prefix")
info := query.Get("info")
@@ -282,10 +259,6 @@ func (h *getChannelsHandler) ServeHTTPC(ctx context.Context, w http.ResponseWrit
}
}
func newGetChannelHandler(DB db) goji.HandlerFunc {
return commonHandlers(DB, &getChannelHandler{DB})
}
type getChannelHandler struct{ DB db }
// Fetch info for one channel
@@ -298,19 +271,19 @@ type getChannelHandler struct{ DB db }
// }
//
// GET /apps/{app_id}/channels/{channel_name}
func (h *getChannelHandler) ServeHTTPC(ctx context.Context, w http.ResponseWriter, r *http.Request) {
func (h *getChannelHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json;charset=UTF-8")
query := r.URL.Query()
appID := pat.Param(ctx, "app_id")
appID := chi.URLParam(r, "app_id")
app, err := h.DB.GetAppByAppID(appID)
if err != nil {
http.Error(w, fmt.Sprintf("Could not found an app with app_id: %s", appID), http.StatusBadRequest)
}
channelName := pat.Param(ctx, "channel_name")
channelName := chi.URLParam(r, "channel_name")
// Channel name could not be empty
if strings.TrimSpace(channelName) == "" {
@@ -376,10 +349,6 @@ func (h *getChannelHandler) ServeHTTPC(ctx context.Context, w http.ResponseWrite
}
}
func newGetChannelUsersHandler(DB db) goji.HandlerFunc {
return commonHandlers(DB, &getChannelUsersHandler{DB})
}
type getChannelUsersHandler struct{ DB db }
// Allowed only for presence-channels
@@ -393,9 +362,9 @@ type getChannelUsersHandler struct{ DB db }
// }
//
// GET /apps/{app_id}/channels/{channel_name}/users
func (h *getChannelUsersHandler) ServeHTTPC(ctx context.Context, w http.ResponseWriter, r *http.Request) {
appID := pat.Param(ctx, "app_id")
channelName := pat.Param(ctx, "channel_name")
func (h *getChannelUsersHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
appID := chi.URLParam(r, "app_id")
channelName := chi.URLParam(r, "channel_name")
isPresence := utils.IsPresenceChannel(channelName)
+26 -21
View File
@@ -1,15 +1,14 @@
package ipe
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/http/httptest"
"testing"
"goji.io/pattern"
"golang.org/x/net/context"
"github.com/pressly/chi"
)
var (
@@ -41,14 +40,15 @@ func init() {
func Test_getChannels_all(t *testing.T) {
appID := testApp.AppID
ctx := context.Background()
ctx = context.WithValue(ctx, pattern.Variable("app_id"), appID)
rctx := chi.NewRouteContext()
rctx.URLParams.Add("app_id", appID)
r, _ := http.NewRequest("GET", fmt.Sprintf("/apps/%s/channels", appID), nil)
r = r.WithContext(context.WithValue(context.Background(), chi.RouteCtxKey, rctx))
w := httptest.NewRecorder()
handler := &getChannelsHandler{database}
handler.ServeHTTPC(ctx, w, r)
handler.ServeHTTP(w, r)
if w.Code != http.StatusOK {
t.Errorf("w.Code == %d, wants %d", w.Code, http.StatusOK)
@@ -67,14 +67,15 @@ func Test_getChannels_all(t *testing.T) {
func Test_getChannels_filter_by_presence_prefix(t *testing.T) {
appID := testApp.AppID
ctx := context.Background()
ctx = context.WithValue(ctx, pattern.Variable("app_id"), appID)
rctx := chi.NewRouteContext()
rctx.URLParams.Add("app_id", appID)
r, _ := http.NewRequest("GET", fmt.Sprintf("/apps/%s/channels?filter_by_prefix=presence-", appID), nil)
r = r.WithContext(context.WithValue(context.Background(), chi.RouteCtxKey, rctx))
w := httptest.NewRecorder()
handler := &getChannelsHandler{database}
handler.ServeHTTPC(ctx, w, r)
handler.ServeHTTP(w, r)
if w.Code != http.StatusOK {
t.Errorf("w.Code == %d, wants %d", w.Code, http.StatusOK)
@@ -94,14 +95,15 @@ func Test_getChannels_filter_by_presence_prefix(t *testing.T) {
func Test_getChannels_filter_by_presence_prefix_and_user_count(t *testing.T) {
appID := testApp.AppID
ctx := context.Background()
ctx = context.WithValue(ctx, pattern.Variable("app_id"), appID)
rctx := chi.NewRouteContext()
rctx.URLParams.Add("app_id", appID)
r, _ := http.NewRequest("GET", fmt.Sprintf("/apps/%s/channels?filter_by_prefix=presence-&info=user_count", appID), nil)
r = r.WithContext(context.WithValue(context.Background(), chi.RouteCtxKey, rctx))
w := httptest.NewRecorder()
handler := &getChannelsHandler{database}
handler.ServeHTTPC(ctx, w, r)
handler.ServeHTTP(w, r)
if w.Code != http.StatusOK {
t.Errorf("w.Code == %d, wants %d", w.Code, http.StatusOK)
@@ -133,14 +135,15 @@ func Test_getChannels_filter_by_presence_prefix_and_user_count(t *testing.T) {
func Test_getChannels_filter_by_private_prefix_and_info_user_count(t *testing.T) {
appID := testApp.AppID
ctx := context.Background()
ctx = context.WithValue(ctx, pattern.Variable("app_id"), appID)
rctx := chi.NewRouteContext()
rctx.URLParams.Add("app_id", appID)
r, _ := http.NewRequest("GET", fmt.Sprintf("/apps/%s/channels?filter_by_prefix=private-&info=user_count", appID), nil)
r = r.WithContext(context.WithValue(context.Background(), chi.RouteCtxKey, rctx))
w := httptest.NewRecorder()
handler := &getChannelsHandler{database}
handler.ServeHTTPC(ctx, w, r)
handler.ServeHTTP(w, r)
if w.Code != http.StatusBadRequest {
t.Errorf("w.Code == %d, wants %d", w.Code, http.StatusBadRequest)
@@ -150,14 +153,15 @@ func Test_getChannels_filter_by_private_prefix_and_info_user_count(t *testing.T)
func Test_getChannels_filter_by_public_prefix(t *testing.T) {
appID := testApp.AppID
ctx := context.Background()
ctx = context.WithValue(ctx, pattern.Variable("app_id"), appID)
rctx := chi.NewRouteContext()
rctx.URLParams.Add("app_id", appID)
r, _ := http.NewRequest("GET", fmt.Sprintf("/apps/%s/channels?filter_by_prefix=public-", appID), nil)
r = r.WithContext(context.WithValue(context.Background(), chi.RouteCtxKey, rctx))
w := httptest.NewRecorder()
handler := &getChannelsHandler{database}
handler.ServeHTTPC(ctx, w, r)
handler.ServeHTTP(w, r)
if w.Code != http.StatusOK {
t.Errorf("w.Code == %d, wants %d", w.Code, http.StatusOK)
@@ -183,14 +187,15 @@ func Test_getChannels_filter_by_public_prefix(t *testing.T) {
func Test_getChannels_filter_by_private_prefix(t *testing.T) {
appID := testApp.AppID
ctx := context.Background()
ctx = context.WithValue(ctx, pattern.Variable("app_id"), appID)
rctx := chi.NewRouteContext()
rctx.URLParams.Add("app_id", appID)
r, _ := http.NewRequest("GET", fmt.Sprintf("/apps/%s/channels?filter_by_prefix=private-", appID), nil)
r = r.WithContext(context.WithValue(context.Background(), chi.RouteCtxKey, rctx))
w := httptest.NewRecorder()
handler := &getChannelsHandler{database}
handler.ServeHTTPC(ctx, w, r)
handler.ServeHTTP(w, r)
if w.Code != http.StatusOK {
t.Errorf("w.Code == %d, wants %d", w.Code, http.StatusOK)
+17 -12
View File
@@ -11,11 +11,9 @@ import (
"os"
"time"
"goji.io/pat"
goji "goji.io"
log "github.com/golang/glog"
"github.com/pressly/chi"
"github.com/pressly/chi/middleware"
)
// Start Parse the configuration file and starts the ipe server
@@ -47,20 +45,27 @@ func Start(filename string) {
db.AddApp(newAppFromConfig(a))
}
router := goji.NewMux()
router.HandleFuncC(pat.Post("/apps/:app_id/events"), newPostEventsHandler(db))
router.HandleFuncC(pat.Get("/apps/:app_id/channels"), newGetChannelsHandler(db))
router.HandleFuncC(pat.Get("/apps/:app_id/channels/:channel_name"), newGetChannelHandler(db))
router.HandleFuncC(pat.Get("/apps/:app_id/channels/:channel_name/users"), newGetChannelUsersHandler(db))
router.HandleC(pat.Get("/app/:key"), newWebsocketHandler(db))
r := chi.NewRouter()
r.Use(middleware.Recoverer)
r.Handle("/app/:key", &websocketHandler{db})
r.Group(func(r chi.Router) {
r.Use(checkAppDisabled(db))
r.Use(authenticationHandler(db))
r.Handle("/apps/:app_id/events", &postEventsHandler{db})
r.Handle("/apps/:app_id/channels", &getChannelsHandler{db})
r.Handle("/apps/:app_id/channels/:channel_name", &getChannelHandler{db})
r.Handle("/apps/:app_id/channels/:channel_name/users", &getChannelUsersHandler{db})
})
if conf.SSL {
go func() {
log.Infof("Starting HTTPS service on %s ...", conf.SSLHost)
log.Fatal(http.ListenAndServeTLS(conf.SSLHost, conf.SSLCertFile, conf.SSLKeyFile, router))
log.Fatal(http.ListenAndServeTLS(conf.SSLHost, conf.SSLCertFile, conf.SSLKeyFile, r))
}()
}
log.Infof("Starting HTTP service on %s ...", conf.Host)
log.Fatal(http.ListenAndServe(conf.Host, router))
log.Fatal(http.ListenAndServe(conf.Host, r))
}
+3 -11
View File
@@ -12,13 +12,9 @@ import (
"strconv"
"strings"
goji "goji.io"
"goji.io/pat"
log "github.com/golang/glog"
"github.com/gorilla/websocket"
"golang.org/x/net/context"
"github.com/pressly/chi"
"github.com/dimiro1/ipe/utils"
)
@@ -245,16 +241,12 @@ func emitWSError(err error, conn *websocket.Conn) {
}
}
func newWebsocketHandler(DB db) goji.Handler {
return &websocketHandler{DB}
}
type websocketHandler struct {
DB db
}
// Websocket GET /app/{key}
func (h *websocketHandler) ServeHTTPC(ctx context.Context, w http.ResponseWriter, r *http.Request) {
func (h *websocketHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
conn, err := upgrader.Upgrade(w, r, nil)
defer func() {
if conn != nil {
@@ -267,7 +259,7 @@ func (h *websocketHandler) ServeHTTPC(ctx context.Context, w http.ResponseWriter
return
}
appKey := pat.Param(ctx, "key")
appKey := chi.URLParam(r, "key")
app, err := h.DB.GetAppByKey(appKey)