func main() { stderrBackend := logging.NewLogBackend(os.Stderr, "", 0) stderrFormatter := logging.NewBackendFormatter(stderrBackend, stdout_log_format) logging.SetBackend(stderrFormatter) logging.SetFormatter(stdout_log_format) log.Info("Starting app") log.Debugf("version: %s", version) if !strings.ContainsRune(version, '-') { log.Warning("once you tag your commit with name your version number will be prettier") } log.Error("now add some code!") renderer, err := web.New() if err != nil { log.Errorf("Renderer failed with: %s", err) } mux := goji.NewMux() mux.Handle(pat.Get("/static/*"), http.StripPrefix("/static", http.FileServer(http.Dir(`public/static`)))) mux.Handle(pat.Get("/apidoc/*"), http.StripPrefix("/apidoc", http.FileServer(http.Dir(`public/apidoc`)))) mux.HandleFunc(pat.Get("/"), renderer.HandleRoot) mux.HandleFunc(pat.Get("/status"), renderer.HandleStatus) log.Warningf("listening on %s", listenAddr) log.Errorf("failed on %s", http.ListenAndServe(listenAddr, mux)) }
// test really long resource paths (limit to what securecookie can encode) func TestInvalidStates(t *testing.T) { // resource path respath := "/" + strings.Repeat("x", 4096) // setup oauthmw sess := newSession() prov := newProvider() prov.Path = "/" prov.Configs = map[string]*oauth2.Config{ "google": newGoogleEndpoint(""), } // setup mux and middleware m0 := goji.NewMux() m0.UseC(sess.Handler) m0.UseC(prov.RequireLogin(nil)) m0.HandleFuncC(pat.Get("/*"), okHandler) r0, _ := get(m0, respath, nil, t) checkError(500, "could not encode state for google", r0, t) //-------------------------------------- // repeat above test, but with multiple providers prov.Configs["facebook"] = newFacebookEndpoint("") // setup mux and middleware m1 := goji.NewMux() m1.UseC(sess.Handler) m1.UseC(prov.RequireLogin(nil)) m1.HandleFuncC(pat.Get("/*"), okHandler) r1, _ := get(m1, respath, nil, t) checkError(500, "could not encode state for facebook (2)", r1, t) }
func main() { mux := goji.NewMux() mux.HandleFuncC(pat.Get("/hello/:name"), hello) mux.HandleFuncC(pat.Get("/goodbye/:name"), goodbye) http.ListenAndServe(":8000", mux) }
func main() { mux := goji.NewMux() mux.HandleFuncC(pat.Get("/books"), allBooks) mux.HandleFuncC(pat.Get("/books/:isbn"), bookByISBN) mux.UseC(logging) http.ListenAndServe("localhost:8080", mux) }
func main() { router := goji.NewMux() router.HandleFunc(pat.Get("/"), index) router.HandleFuncC(pat.Get("/hello/:name"), hello) log.Println("Starting server on port 9090") log.Fatal(http.ListenAndServe(":9090", router)) }
func Web() *goji.Mux { mux := goji.SubMux() mux.HandleFuncC(pat.Get("/people"), frontend.ListPeople) mux.HandleFuncC(pat.Get("/people/:person"), frontend.GetPerson) return mux }
func Listen() { mux := goji.NewMux() mux.HandleFunc(pat.Post("/reset.json"), reset) mux.HandleFuncC(pat.Get("/:name.json"), show) mux.HandleFunc(pat.Get("/"), index) bind := fmt.Sprintf(":%s", getBindPort()) log.Fatal(http.ListenAndServe(bind, mux)) }
func init() { mux := goji.NewMux() mux.HandleFuncC(pat.Get("/"), index) mux.HandleFuncC(pat.Get("/hello/:name"), hello) mux.HandleFuncC(pat.Get("/article"), article) http.Handle("/", mux) }
func TestRequireLoginAutoRedirect(t *testing.T) { // setup mux's m0 := goji.NewMux() m1 := goji.NewMux() m1Sub := goji.NewMux() m1.HandleC(pat.Get("/p/*"), m1Sub) m2 := goji.NewMux() m2Sub := goji.NewMux() m2.HandleC(pat.Get("/p/*"), m2Sub) tests := []struct { mux *goji.Mux addToMux *goji.Mux path string redir string }{ {m0, m0, "/", "/oauth-redirect-google?state="}, {m1, m1, "/", "/oauth-redirect-google?state="}, /*{m1, m1Sub, "/p/", "/p/oauth-redirect-google?state="}, {m2, m2, "/p/", "/p/oauth-redirect-google?state="}, {m2, m2Sub, "/p/", "/p/oauth-redirect-google?state="},*/ } for i, test := range tests { // setup middleware sess := newSession() prov := newProvider() prov.Path = test.path prov.Configs = map[string]*oauth2.Config{ "google": newGoogleEndpoint(""), } // enable subrouter test for m2Sub /*if test.addToMux == m2Sub { prov.SubRouter = true }*/ // add middleware to mux sessmw := sess.Handler rlmw := prov.RequireLogin(nil) test.addToMux.UseC(sessmw) test.addToMux.UseC(rlmw) // check for redirect r0, l0 := get(test.mux, test.path, nil, t) check(302, r0, t) if !strings.HasPrefix(l0, test.redir) { t.Errorf("test %d invalid redirect %s", i, l0) } // remove middleware from mux so they can be reused //test.addToMux.Abandon(rlmw) //test.addToMux.Abandon(sessmw) } }
func Listen() { mux := goji.NewMux() mux.HandleFuncC(pat.Get("/:name.json"), show) mux.HandleFunc(pat.Get("/"), index) bind := ":" if port := os.Getenv("PORT"); port != "" { bind += port } else { bind += "8000" } log.Fatal(http.ListenAndServe(bind, mux)) }
func TestLogin(t *testing.T) { // setup oauthmw sess := newSession() prov := newProvider() prov.Path = "/" prov.Configs = map[string]*oauth2.Config{ "google": newGoogleEndpoint(""), "facebook": newFacebookEndpoint(""), } prov.checkDefaults() // setup mux and middleware m0 := goji.NewMux() m0.UseC(sess.Handler) m0.UseC(prov.Login(nil)) m0.HandleFuncC(pat.Get("/ok"), okHandler) // do initial request to establish session r0, _ := get(m0, "/ok", nil, t) checkOK(r0, t) cookie := getCookie(r0, t) // verify 404 if no/bad state provided r1, _ := get(m0, "/oauth-redirect-google", cookie, t) check(404, r1, t) // verify redirect when correct state provided s2 := encodeState(&prov, getSid(sess.Store, &prov, t), "google", "/resource", t) r2, l2 := get(m0, "/oauth-redirect-google?state="+s2, cookie, t) check(302, r2, t) if !strings.HasPrefix(l2, "https://accounts.google.com/o/oauth2/auth?client_id=") { t.Errorf("redirect should be to google, got: %s", l2) } }
func runAPI(wg *sync.WaitGroup) { mux := goji.NewMux() // List all webhooks mux.HandleFuncC( pat.Get("/webhooks"), func(ctx context.Context, w http.ResponseWriter, r *http.Request) { ui := uhttp.UI{ctx, r, w} kase := usecase.ListWebhooks{ DB: &drivers.DB, Out: &ui, } if err := kase.Exec(); err != nil { fail(err) } }, ) // Create a new webhook mux.HandleFuncC( pat.Post("/webhooks"), func(ctx context.Context, w http.ResponseWriter, r *http.Request) {}, ) // Delete a webhook mux.HandleFuncC( pat.Delete("/webhooks/:id"), func(ctx context.Context, w http.ResponseWriter, r *http.Request) {}, ) http.ListenAndServe("localhost:8000", mux) wg.Done() }
func (s *Server) Handler() http.Handler { mux := goji.NewMux() mux.HandleFuncC(pat.Get("/healthcheck"), func(c context.Context, w http.ResponseWriter, r *http.Request) { w.Write([]byte("ok\n")) }) return mux }
func TestCheckFnGood(t *testing.T) { // setup test oauth server server := httptest.NewServer(newOauthlibServer(t)) defer server.Close() // set oauth2context HTTPClient to force oauth2 Exchange to use it client := newClient(server.URL) oauth2Context = context.WithValue(oauth2Context, oauth2.HTTPClient, client) // build oauthmw prov := newProvider() sess := newSession() prov.Path = "/" prov.Configs = map[string]*oauth2.Config{ "oauthlib": newOauthlibEndpoint(server.URL), } // setup mux and middleware m0 := goji.NewMux() m0.UseC(sess.Handler) m0.UseC(prov.RequireLogin(newCheckFunc(true, t))) m0.HandleFuncC(pat.Get("/*"), okHandler) // do initial request to establish session r0, l0 := get(m0, "/", nil, t) check(302, r0, t) cookie := getCookie(r0, t) // do redirect r1, l1 := get(m0, l0, cookie, t) check(302, r1, t) urlParse(l1, t) if !strings.HasPrefix(l1, server.URL) { t.Fatalf("should be server.URL, got: %s", l0) } // do authorization resp, err := client.Get(l1) u1 := checkAuthResp(resp, err, t) // change path due to hard coded values in // oauthlib/example.TestStorage u1.Path = "/oauth-login" // do oauth-login r2, l2 := get(m0, u1.String(), cookie, t) check(301, r2, t) // verify redirect resource path is same as original request if "/" != l2 { t.Errorf("redirect path should be /, got: %s", l2) } // check original resource path now passes to 'OK' handler r3, _ := get(m0, "/", cookie, t) checkOK(r3, t) // reset context oauth2Context = oauth2.NoContext }
func main() { stderrBackend := logging.NewLogBackend(os.Stderr, "", 0) stderrFormatter := logging.NewBackendFormatter(stderrBackend, stdout_log_format) logging.SetBackend(stderrFormatter) logging.SetFormatter(stdout_log_format) log.Info("Starting app") log.Debug("version: %s", version) if !strings.ContainsRune(version, '-') { log.Warning("once you tag your commit with name your version number will be prettier") } log.Info("Listening at %s", listenAddr) mux := goji.NewMux() mux.HandleFuncC(pat.Get("/hello/:name"), hello) mux.HandleFuncC(pat.Get("/"), requestDump) http.ListenAndServe(listenAddr, mux) }
func main() { session, err := mgo.Dial("localhost") if err != nil { panic(err) } defer session.Close() session.SetMode(mgo.Monotonic, true) ensureIndex(session) mux := goji.NewMux() mux.HandleFuncC(pat.Get("/books"), allBooks(session)) mux.HandleFuncC(pat.Post("/books"), addBook(session)) mux.HandleFuncC(pat.Get("/books/:isbn"), bookByISBN(session)) mux.HandleFuncC(pat.Put("/books/:isbn"), updateBook(session)) mux.HandleFuncC(pat.Delete("/books/:isbn"), deleteBook(session)) http.ListenAndServe("localhost:8080", mux) }
func initMux(driver federation.Driver) *goji.Mux { mux := goji.NewMux() c := cors.New(cors.Options{ AllowedOrigins: []string{"*"}, AllowedHeaders: []string{"*"}, AllowedMethods: []string{"GET"}, }) mux.Use(c.Handler) fed := &federation.Handler{driver} mux.Handle(pat.Get("/federation"), fed) mux.Handle(pat.Get("/federation/"), fed) return mux }
func API() *goji.Mux { mux := goji.SubMux() // We pass the routes as relative to the point where the API router // will be mounted. The super-router will strip any prefix off for us. mux.HandleFuncC(pat.Get("/people"), api.ListPeople) mux.HandleFuncC(pat.Post("/people"), api.CreatePerson) mux.HandleFuncC(pat.Get("/people/:person"), api.GetPerson) mux.HandleFuncC(pat.Delete("/people/:person"), api.DeletePerson) // Add default 'not found' route that responds with JSON mux.HandleFunc(pat.New("/*"), func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(404) fmt.Fprint(w, `{"error":"not found"}`) }) return mux }
// List registers a `GET /resource` handler for the resource func (res *Resource) List(storage store.List) { res.HandleFuncC( pat.Get(patRoot), func(ctx context.Context, w http.ResponseWriter, r *http.Request) { res.listHandler(ctx, w, r, storage) }, ) res.addRoute(get, patRoot) }
func TestMetrics(t *testing.T) { backend := &stubBackend{} metrics.SetBackend(backend) inner := goji.NewMux() inner.HandleFunc(pat.Get("/:baz"), func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(1) }) inner.UseC(metrics.WrapSubmuxC) outer := goji.NewMux() outer.HandleFunc(pat.Get("/foo"), func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(2) }) outer.HandleC(pat.New("/bar/*"), inner) outer.UseC(metrics.WrapC) cases := []struct { path string expect map[string]int }{ {"/foo", map[string]int{"foo.request": 1, "foo.response.2": 1}}, {"/bar/baz", map[string]int{"bar.:baz.request": 1, "bar.:baz.response.1": 1}}, {"/bar", map[string]int{}}, } for _, testcase := range cases { backend.Reset() req, err := http.NewRequest("GET", testcase.path, nil) if err != nil { t.Fatal(err) } rr := httptest.NewRecorder() outer.ServeHTTPC(context.Background(), rr, req) if have, want := backend.data, testcase.expect; !reflect.DeepEqual(have, want) { t.Errorf("%s: Expected %#v but got %#v", testcase.path, want, have) } } }
// Action allows you to add custom actions to your resource types, it uses the // GET /(prefix/)resourceTypes/:id/<actionName> path format func (res *Resource) Action(actionName string, storage store.Get) { matcher := path.Join(patID, actionName) res.HandleFuncC( pat.Get(matcher), func(ctx context.Context, w http.ResponseWriter, r *http.Request) { res.actionHandler(ctx, w, r, storage) }, ) res.addRoute(patch, matcher) }
// relationshipHandler does the dirty work of setting up both routes for a single // relationship func (res *Resource) relationshipHandler( resourceType string, handler goji.HandlerFunc, ) { // handle /.../:id/<resourceType> matcher := fmt.Sprintf("%s/%s", patID, resourceType) res.HandleFuncC( pat.Get(matcher), handler, ) res.addRoute(get, matcher) // handle /.../:id/relationships/<resourceType> relationshipMatcher := fmt.Sprintf("%s/relationships/%s", patID, resourceType) res.HandleFuncC( pat.Get(relationshipMatcher), handler, ) res.addRoute(get, relationshipMatcher) }
func New(cfg *config.Config, client brew.Reader) http.Handler { app := API{c: client, host: cfg.HostAPI} mux := goji.NewMux() // Setup middleware mux.UseC(Recover) mux.UseC(Tracing) mux.UseC(Headers) mux.UseC(Recover) mux.HandleFuncC(pat.Get("/mtg/cards"), app.HandleCards) mux.HandleFuncC(pat.Get("/mtg/cards/typeahead"), app.HandleTypeahead) mux.HandleFuncC(pat.Get("/mtg/cards/random"), app.HandleRandomCard) mux.HandleFuncC(pat.Get("/mtg/cards/:id"), app.HandleCard) mux.HandleFuncC(pat.Get("/mtg/sets"), app.HandleSets) mux.HandleFuncC(pat.Get("/mtg/sets/:id"), app.HandleSet) mux.HandleFuncC(pat.Get("/mtg/colors"), app.HandleTerm(client.GetColors)) mux.HandleFuncC(pat.Get("/mtg/supertypes"), app.HandleTerm(client.GetSupertypes)) mux.HandleFuncC(pat.Get("/mtg/subtypes"), app.HandleTerm(client.GetSubtypes)) mux.HandleFuncC(pat.Get("/mtg/types"), app.HandleTerm(client.GetTypes)) return mux }
func TestStatesCleanup(t *testing.T) { // setup oauthmw sess := newSession() prov := newProvider() prov.Path = "/" prov.StateLifetime = 1 * time.Second prov.Configs = map[string]*oauth2.Config{ "google": newGoogleEndpoint(""), } prov.checkDefaults() // setup mux and middleware m0 := goji.NewMux() m0.UseC(sess.Handler) m0.UseC(prov.Login(nil)) m0.HandleFuncC(pat.Get("/ok"), okHandler) // do initial request to establish session r0, _ := get(m0, "/ok", nil, t) checkOK(r0, t) cookie := getCookie(r0, t) // add a lot of states for i := 0; i < 2*DefaultMaxStates; i++ { // do redirect request to have state added to session s1 := encodeState(&prov, getSid(sess.Store, &prov, t), "google", "/resource", t) r1, l1 := get(m0, "/oauth-redirect-google?state="+s1, cookie, t) check(302, r1, t) // verify redirect is correct if !strings.HasPrefix(l1, "https://accounts.google.com/o/oauth2/auth?client_id=") { t.Errorf("redirect should be to google, got: %s", l1) } } checkStatesCount(sess.Store, &prov, 2*DefaultMaxStates, "states count should be 2*DefaultMaxStates", t) // expire all states setStatesExpiration(sess.Store, &prov, time.Now().Add(-1*time.Hour), t) // kick cleanup r2, _ := get(m0, "/ok", cookie, t) checkOK(r2, t) checkStatesCount(sess.Store, &prov, 0, "states should be empty after cleanup", t) }
func main() { conf := parseConf() parseLogger(conf.LogFile, conf.LogLevel) dbm := parseDb(conf.DbMaster) dbs := parseDb(conf.DbSlave) dbMMap := model.Init(dbm, log.Logger) dbSMap := model.Init(dbs, log.Logger) mux := goji.NewMux() userDao := dao.NewUser(dbMMap, dbSMap) threadDao := dao.NewThread(dbMMap, dbSMap) threadService := service.NewThread(userDao, threadDao) threadHandler := handler.NewThread(threadService) mux.HandleFuncC(pat.Get("/v1/threads"), wrap(threadHandler.List)) log.Logger.Info("starting server...") http.ListenAndServe("localhost:8080", mux) }
func New(cfg *config.Config, r brew.Reader) http.Handler { mux := goji.NewMux() app := Web{ r: r, t: template.Must(template.New("card").Parse(tmpl)), } // Setup middleware mux.UseC(api.Recover) mux.UseC(api.Tracing) mux.HandleFuncC(pat.Get("/mtg/cards/:id"), app.HandleCard) mux.Handle(pat.New("/*"), http.FileServer(http.Dir("./web/static/"))) return mux }
func TestTracing(t *testing.T) { mux := goji.NewMux() var name string mux.HandleFuncC(pat.Get("/mtg/cards/:id"), func(ctx context.Context, w http.ResponseWriter, r *http.Request) { pattern := middleware.Pattern(ctx).(*pat.Pattern) name = pattern.String() }) req, _ := http.NewRequest("GET", "/mtg/cards/foo", nil) w := httptest.NewRecorder() mux.ServeHTTP(w, req) if name != "/mtg/cards/:id" { t.Errorf("name is %s", name) } }
func TestRedirectErrors(t *testing.T) { // setup oauthmw sess := newSession() prov := newProvider() prov.Path = "/" prov.Configs = map[string]*oauth2.Config{ "google": newGoogleEndpoint(""), "facebook": newFacebookEndpoint(""), } prov.checkDefaults() // setup mux and middleware m0 := goji.NewMux() m0.UseC(sess.Handler) m0.UseC(prov.Login(nil)) m0.HandleFuncC(pat.Get("/ok"), okHandler) // do initial request to establish session r0, _ := get(m0, "/ok", nil, t) checkOK(r0, t) cookie := getCookie(r0, t) // encode correct state s0 := encodeState(&prov, getSid(sess.Store, &prov, t), "google", "/resource", t) // check bad provider r1, _ := get(m0, "/oauth-redirect-bad?state="+s0, cookie, t) checkError(500, "invalid provider", r1, t) // check forged sid s2 := encodeState(&prov, "", "google", "/resource", t) r2, _ := get(m0, "/oauth-redirect-google?state="+s2, cookie, t) checkError(500, "forged sid in redirect", r2, t) // check forged provider r3, _ := get(m0, "/oauth-redirect-facebook?state="+s0, cookie, t) checkError(500, "forged provider in redirect", r3, t) }
func startGojiv2() { mux := gojiv2.NewMux() mux.HandleFuncC(gojiv2pat.Get("/hello"), gojiv2Handler) http.ListenAndServe(":"+strconv.Itoa(port), mux) }
IPPerMinute int // maximum number of requests per IP per minute IPRateBurst int // maximum burst of requests from an IP UserSecret []byte // secret for generating secure user tokens } var Routes = struct { CreateUser, GetUser, GetAnimals, ListMoods, SetMood, GetMood, DeleteMood, ListConversations, CreateConversation, GetConversation, DeleteConversation, CreateLine, GetLine, DeleteLine *pat.Pattern }{ CreateUser: pat.Post("/users"), GetUser: pat.Get("/users/:id"), GetAnimals: pat.Get("/animals"), ListMoods: pat.Get("/moods"), SetMood: pat.Put("/moods/:mood"), GetMood: pat.Get("/moods/:mood"), DeleteMood: pat.Delete("/moods/:mood"), ListConversations: pat.Get("/conversations"), CreateConversation: pat.Post("/conversations"), GetConversation: pat.Get("/conversations/:conversation"), DeleteConversation: pat.Delete("/conversations/:conversation"), CreateLine: pat.Post("/conversations/:conversation/lines"), GetLine: pat.Get("/conversations/:conversation/lines/:line"),