Ejemplo n.º 1
0
func ExampleManyRoutes() {
	// new router
	router := vestigo.NewRouter()
	// standard http.HandlerFunc
	handler := func(w http.ResponseWriter, r *http.Request) {
		fmt.Printf("version: %s, resource: %s\n", vestigo.Param(r, "version"), r.URL.Path)
	}
	// setup a GET /v:version/hi endpoint route in router
	router.Get("/v:version/hi", handler)
	// setup a GET /v:version/hi endpoint route in router
	router.Post("/v:version/hi", handler)
	// setup a GET /v:version/hi endpoint route in router
	router.Put("/v:version/hi", handler)
	// setup a GET /v:version/hi endpoint route in router
	router.Delete("/v:version/hi", handler)
	// setup a GET /v:version/hi endpoint route in router
	router.Patch("/v:version/hi", handler)

	// create a new request and response writer
	r, _ := http.NewRequest("PATCH", "/v2.3/hi", nil)
	w := httptest.NewRecorder()

	// execute the request
	router.ServeHTTP(w, r)
	// Output: version: 2.3, resource: /v2.3/hi
}
Ejemplo n.º 2
0
func (s *server) start() error {
	s.client = rpcmq.NewClient("amqp://"+s.config.Rpcmq.Host+":"+s.config.Rpcmq.Port, s.config.Rpcmq.MsgQueue, s.config.Rpcmq.ReplyQueue, s.config.Rpcmq.Exchange, s.config.Rpcmq.ExchangeType)
	s.client.DeliveryMode = rpcmq.Transient
	err := s.client.Init()
	if err != nil {
		log.Fatalf("Init rpcmq: %v", err)
	}
	defer s.client.Shutdown()

	s.supervisor = monmq.NewSupervisor("amqp://"+s.config.Monmq.Host+":"+s.config.Monmq.Port, s.config.Monmq.ReplyQueue, s.config.Monmq.Exchange)
	if err := s.supervisor.Init(); err != nil {
		log.Fatalf("Init monmq: %v", err)
	}
	defer s.supervisor.Shutdown()

	if s.config.DB.Type == "mysql" {
		dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4,utf8", s.config.DB.Username, s.config.DB.Password, s.config.DB.Host, s.config.DB.Port, s.config.DB.Name)
		s.pm = persistence.NewMySQLPersistenceManager(dsn)
		defer s.pm.Close()
	} else if s.config.DB.Type == "elasticsearch" {
		esUrl := fmt.Sprintf("http://%s:%s", s.config.DB.Host, s.config.DB.Port)
		s.pm = persistence.NewElasticPersistenceManager(esUrl, s.config.DB.Name)
	} else {
		log.Fatalf("Invalid DB Type %s. Check the config", s.config.DB.Type)
	}

	m := vestigo.NewRouter()
	logHandler := olog.NewLogHandler(s.logger, logLine)

	m.Post("/tasks", orujo.NewPipe(
		http.HandlerFunc(s.tasksHandler),
		orujo.M(logHandler)).ServeHTTP,
	)
	m.Get("/status", orujo.NewPipe(
		http.HandlerFunc(s.getStatusHandler),
		orujo.M(logHandler)).ServeHTTP,
	)
	m.Post("/status", orujo.NewPipe(
		http.HandlerFunc(s.setStatusHandler),
		orujo.M(logHandler)).ServeHTTP,
	)
	m.Get("/ips/:ip", orujo.NewPipe(
		http.HandlerFunc(s.queryHandler),
		orujo.M(logHandler)).ServeHTTP,
	)
	m.Get("/ips", orujo.NewPipe(
		http.HandlerFunc(s.queryHandler),
		orujo.M(logHandler)).ServeHTTP,
	)

	fmt.Println("Listening on " + s.config.Local.Host + ":" + s.config.Local.Port + "...")
	log.Fatalln(http.ListenAndServe(s.config.Local.Host+":"+s.config.Local.Port, m))

	return nil
}
Ejemplo n.º 3
0
func MarketplaceHandler() http.Handler {
	m := NewMarketplace()

	router := vestigo.NewRouter()
	router.SetGlobalCors(&vestigo.CorsAccessControl{
		AllowOrigin: []string{"*"},
	})

	router.Get("/listings", Serial(m, m.SearchListings))
	router.Post("/listings", Serial(m, m.CreateListing))
	router.Get("/listings/:listing", Serial(m, m.GetListing))
	router.Post("/listings/:listing", Serial(m, m.PatchListing))
	router.Patch("/listings/:listing", Serial(m, m.PatchListing))
	router.Get("/inquiries", Serial(m, m.SearchInquiries))
	router.Post("/listings/:listing/inquiries", Serial(m, m.SendInquiry))
	router.Handle("/", http.FileServer(http.Dir("static")))

	return router
}
Ejemplo n.º 4
0
func ExampleCorsRoute() {
	// new router
	router := vestigo.NewRouter()
	// setup global cors config for router
	router.SetGlobalCors(&vestigo.CorsAccessControl{
		AllowOrigin:      []string{"*", "test.com"},          // allow these origins
		AllowCredentials: true,                               // credentials is allowed globally
		ExposeHeaders:    []string{"X-Header", "X-Y-Header"}, // Expose these headers
		MaxAge:           3600 * time.Second,                 // Cache max age
		AllowHeaders:     []string{"X-Header", "X-Y-Header"}, // Allow these headers
	})

	// standard http.HandlerFunc
	handler := func(w http.ResponseWriter, r *http.Request) {}

	// setup a GET/v:version/hi endpoint route in router
	router.Get("/v:version/hi", handler)

	// Setup a CORS policy for a particular route
	router.SetCors("/v:version/hi", &vestigo.CorsAccessControl{
		AllowMethods: []string{"HEAD"},
		AllowHeaders: []string{"X-Header", "X-Z-Header"},
	})

	// create a new request and response writer
	r, _ := http.NewRequest("OPTIONS", "/v2.3/hi", nil)
	// Initiate CORS
	r.Header.Add("Origin", "test.com")
	r.Header.Add("Access-Control-Request-Method", "HEAD")

	w := httptest.NewRecorder()
	// execute the request
	router.ServeHTTP(w, r)

	fmt.Println(w.Header().Get("Access-Control-Allow-Methods"))
	// Output: HEAD
}
Ejemplo n.º 5
0
func main() {
	// logger setup
	defer glog.Flush()
	if glog.V(logutils.Info) {
		glog.Infof("Starting gonoxious client, listening on %s", ListenAddr)
		if glog.V(logutils.Debug) {
			glog.Infof("start time: %v, listen: %s, privkey: %s, pubkey: %s",
				time.Now(),
				ListenAddr,
				PrivKeyFileName,
				PubKeyFileName)
		}
	}
	// load up keypair, if no keypair, generate keypair
	// TODO: get all the crypto in place

	// negroni middleware setup, with custom logger
	n := negroni.New(
		negroni.NewRecovery(),
		logutils.NewLogMiddleware(logutils.Info),
	)

	// setup URL router
	router := vestigo.NewRouter()
	// chat message endpoint:
	router.Post("/", handlers.ChatHandler)

	n.UseHandler(router)
	// graceful start/stop server
	srv := &graceful.Server{
		Timeout: 5 * time.Second,
		Server:  &http.Server{Addr: ListenAddr, Handler: n},
	}
	srv.ListenAndServe()
	glog.Fatal("ending gonoxious")
}
Ejemplo n.º 6
0
func (s *server) start() error {
	m := vestigo.NewRouter()
	logger := log.New(os.Stdout, "[GODAN-UI] ", log.LstdFlags)
	logHandler := olog.NewLogHandler(logger, logLine)

	m.SetGlobalCors(&vestigo.CorsAccessControl{
		AllowOrigin:      []string{"*"},
		AllowCredentials: false,
		MaxAge:           3600 * time.Second,
		AllowHeaders:     []string{"Authorization", "Content-Type"},
		AllowMethods:     []string{"GET", "POST", "PUT", "DELETE"},
	})

	m.Get("/users/:username", orujo.NewPipe(
		orujo.M(logHandler),
		s.auth,
		http.HandlerFunc(s.getUserHandler)).ServeHTTP,
	)
	m.Put("/users/:username", orujo.NewPipe(
		orujo.M(logHandler),
		s.auth,
		http.HandlerFunc(s.updateUserHandler)).ServeHTTP,
	)
	m.Delete("/users/:username", orujo.NewPipe(
		orujo.M(logHandler),
		s.auth,
		http.HandlerFunc(s.deleteUserHandler)).ServeHTTP,
	)
	m.Get("/users", orujo.NewPipe(
		orujo.M(logHandler),
		s.auth,
		http.HandlerFunc(s.getUsersHandler)).ServeHTTP,
	)
	m.Post("/users", orujo.NewPipe(
		orujo.M(logHandler),
		s.auth,
		http.HandlerFunc(s.newUserHandler)).ServeHTTP,
	)
	m.Post("/login", orujo.NewPipe(
		orujo.M(logHandler),
		http.HandlerFunc(s.loginHandler)).ServeHTTP,
	)

	m.Post("/tasks", orujo.NewPipe(
		orujo.M(logHandler),
		s.auth,
		http.HandlerFunc(s.newTaskHandler)).ServeHTTP,
	)
	m.Get("/ips/:ip", orujo.NewPipe(
		orujo.M(logHandler),
		s.auth,
		http.HandlerFunc(s.getIpHandler)).ServeHTTP,
	)
	m.Get("/ips", orujo.NewPipe(
		orujo.M(logHandler),
		s.auth,
		http.HandlerFunc(s.getIpHandler)).ServeHTTP,
	)
	m.Get("/status", orujo.NewPipe(
		orujo.M(logHandler),
		s.auth,
		http.HandlerFunc(s.getStatusHandler)).ServeHTTP,
	)
	m.Post("/status", orujo.NewPipe(
		orujo.M(logHandler),
		s.auth,
		http.HandlerFunc(s.setStatusHandler)).ServeHTTP,
	)

	fmt.Println("Listening on " + s.config.Local.Host + ":" + s.config.Local.Port + "...")
	log.Fatalln(http.ListenAndServe(s.config.Local.Host+":"+s.config.Local.Port, m))

	return nil
}
Ejemplo n.º 7
0
func NewServer() *vestigo.Router {

	protectedHandler := alice.New(session, ProtectedPage)
	postForm := alice.New(session, ProtectedPage, bindPost)
	postUser := alice.New(session, bindUser)
	recoverUser := alice.New(session, bindUser)
	postSearch := alice.New(bindSearch)
	postReset := alice.New(bindReset)
	postSettings := alice.New(session, bindSettings)
	sessionRedirect := alice.New(session, SessionRedirect)

	r := vestigo.NewRouter()

	r.Get("/", Homepage)
	r.Get("/rss", ReadFeed)
	r.Get("/apple-touch-icon.png", staticFile)
	r.Get("/favicon.ico", staticFile)
	r.Get("/browserconfig.xml", staticFile)
	r.Get("/crossdomain.xml", staticFile)
	r.Get("/robots.txt", staticFile)
	r.Get("/tile-wide.png", staticFile)
	r.Get("/tile.png", staticFile)
	r.Get("/static/*", staticResource)
	// Please note that `/new` route has to be before the `/:slug` route. Otherwise the program will try
	// to fetch for Post named "new".
	// For now I'll keep it this way to streamline route naming.
	r.Get("/posts/new", protectedHandler.ThenFunc(func(w http.ResponseWriter, r *http.Request) {
		render.R.HTML(w, 200, "post/new", nil)
	}).(http.HandlerFunc))
	r.Post("/posts/new", postForm.ThenFunc(CreatePost).(http.HandlerFunc))

	r.Post("/posts/search", postSearch.ThenFunc(SearchPost).(http.HandlerFunc))
	r.Get("/post/:slug/edit", protectedHandler.ThenFunc(EditPost).(http.HandlerFunc))
	r.Post("/post/:slug/edit", postForm.ThenFunc(UpdatePost).(http.HandlerFunc))
	r.Get("/post/:slug/delete", protectedHandler.ThenFunc(DeletePost).(http.HandlerFunc))
	r.Get("/post/:slug/publish", protectedHandler.ThenFunc(PublishPost).(http.HandlerFunc))
	r.Get("/post/:slug/unpublish", protectedHandler.ThenFunc(UnpublishPost).(http.HandlerFunc))
	r.Get("/post/:slug", ReadPost)

	r.Get("/user", protectedHandler.Then(http.HandlerFunc(ReadUser)).(http.HandlerFunc))
	//r.HandleFunc("/delete", ProtectedPage, binding.Form(User{}), DeleteUser)
	r.Get("/user/settings", protectedHandler.ThenFunc(ReadSettings).(http.HandlerFunc))
	r.Post("/user/settings", postSettings.ThenFunc(UpdateSettings).(http.HandlerFunc))

	r.Post("/user/installation", postSettings.ThenFunc(UpdateSettings).(http.HandlerFunc))

	r.Get("/user/register", sessionRedirect.ThenFunc(func(w http.ResponseWriter, r *http.Request) {
		render.R.HTML(w, 200, "user/register", nil)
	}).(http.HandlerFunc))

	r.Post("/user/register", postUser.ThenFunc(CreateUser).(http.HandlerFunc))

	r.Get("/user/recover", func(w http.ResponseWriter, r *http.Request) {
		render.R.HTML(w, 200, "user/recover", nil)
	})

	r.Post("/user/recover", postUser.ThenFunc(RecoverUser).(http.HandlerFunc))
	r.Get("/user/reset/:id/:recovery", sessionRedirect.ThenFunc(func(w http.ResponseWriter, r *http.Request) {
		render.R.HTML(w, 200, "user/reset", nil)
	}).(http.HandlerFunc))

	r.Post("/user/reset/:id/:recovery", postReset.ThenFunc(ResetUserPassword).(http.HandlerFunc))

	r.Get("/user/login", sessionRedirect.ThenFunc(func(w http.ResponseWriter, r *http.Request) {
		render.R.HTML(w, 200, "user/login", nil)
	}).(http.HandlerFunc))

	r.Post("/user/login", recoverUser.ThenFunc(LoginUser).(http.HandlerFunc))
	r.Get("/user/logout", LogoutUser)

	r.Get("/api", func(w http.ResponseWriter, r *http.Request) {
		render.R.HTML(w, 200, "api/index", nil)
	})

	r.Get("/api/settings", protectedHandler.ThenFunc(ReadSettings).(http.HandlerFunc))
	r.Post("/api/settings", postSettings.ThenFunc(UpdateSettings).(http.HandlerFunc))
	r.Post("/api/installation", postSettings.ThenFunc(UpdateSettings).(http.HandlerFunc))
	r.Get("/api/users", ReadUsers)
	r.Get("/api/users/", ReadUsers)
	r.Get("/api/user/logout", LogoutUser)
	r.Get("/api/user/:id", ReadUser)
	//r.Delete("/user", DeleteUser)
	r.Post("/api/user", postUser.ThenFunc(CreateUser).(http.HandlerFunc))
	r.Post("/api/user/login", recoverUser.ThenFunc(LoginUser).(http.HandlerFunc))
	r.Post("/api/user/recover", recoverUser.ThenFunc(RecoverUser).(http.HandlerFunc))
	r.Post("/api/user/reset/:id/:recovery", postReset.ThenFunc(ResetUserPassword).(http.HandlerFunc))

	r.Post("/api/posts/search", postSearch.ThenFunc(SearchPost).(http.HandlerFunc))
	r.Get("/api/posts", ReadPosts)
	r.Post("/api/post", postForm.ThenFunc(CreatePost).(http.HandlerFunc))
	r.Post("/api/post/:slug/edit", postForm.ThenFunc(UpdatePost).(http.HandlerFunc))
	r.Get("/api/post/:slug/delete", protectedHandler.ThenFunc(DeletePost).(http.HandlerFunc))
	r.Get("/api/post/:slug/publish", protectedHandler.ThenFunc(PublishPost).(http.HandlerFunc))
	r.Get("/api/post/:slug/unpublish", protectedHandler.ThenFunc(UnpublishPost).(http.HandlerFunc))
	r.Get("/api/post/:slug", ReadPost)

	return r
}
Ejemplo n.º 8
0
func main() {
	log.SetFlags(log.LstdFlags | log.Lshortfile)

	// Set up validation for config from our environment.
	envVars := map[string]*re.Regexp{
		"PORT":                    digits,
		"DATABASE_URL":            nows,
		"RELAYMSG_PG_DB":          word,
		"RELAYMSG_PG_SCHEMA":      word,
		"RELAYMSG_PG_USER":        word,
		"RELAYMSG_PG_PASS":        nows,
		"RELAYMSG_PG_MAX_CONNS":   digits,
		"RELAYMSG_BATCH_INTERVAL": digits,
		"RELAYMSG_INBOUND_DOMAIN": nows,
		"RELAYMSG_ALLOWED_ORIGIN": nows,
	}
	// Config container
	cfg := map[string]string{}
	for k, v := range envVars {
		cfg[k] = os.Getenv(k)
		if !v.MatchString(cfg[k]) {
			log.Fatalf("Unsupported value for %s, double check your parameters.", k)
		}
	}

	// Set defaults
	if cfg["PORT"] == "" {
		cfg["PORT"] = "5000"
	}
	if cfg["RELAYMSG_BATCH_INTERVAL"] == "" {
		cfg["RELAYMSG_BATCH_INTERVAL"] = "10"
	}
	batchInterval, err := strconv.Atoi(cfg["RELAYMSG_BATCH_INTERVAL"])
	if err != nil {
		log.Fatal(err)
	}
	if cfg["RELAYMSG_INBOUND_DOMAIN"] == "" {
		cfg["RELAYMSG_INBOUND_DOMAIN"] = "hey.avocado.industries"
	}
	if cfg["RELAYMSG_PG_MAX_CONNS"] == "" {
		cfg["RELAYMSG_PG_MAX_CONNS"] = "18"
	}
	maxConns, err := strconv.Atoi(cfg["RELAYMSG_PG_MAX_CONNS"])
	if err != nil {
		log.Fatal(err)
	}

	pgcfg := &pg.PGConfig{
		Db:   cfg["RELAYMSG_PG_DB"],
		User: cfg["RELAYMSG_PG_USER"],
		Pass: cfg["RELAYMSG_PG_PASS"],
		Opts: map[string]string{
			"sslmode": "disable",
		},
		Url: cfg["DATABASE_URL"],
	}
	dbh, err := pgcfg.Connect()
	if err != nil {
		log.Fatal(err)
	}
	if maxConns > 0 {
		dbh.SetMaxOpenConns(maxConns)
	}

	// Configure PostgreSQL dumper with connection details.
	schema := cfg["RELAYMSG_PG_SCHEMA"]
	if schema == "" {
		schema = "request_dump"
	}
	pgDumper := &pg.PgDumper{Schema: schema}

	// make sure schema and raw_requests table exist
	err = pg.SchemaInit(dbh, schema)
	if err != nil {
		log.Fatal(err)
	}
	// make sure relay_messages table exists
	err = SchemaInit(dbh, schema)
	if err != nil {
		log.Fatal(err)
	}

	pgDumper.Dbh = dbh

	// Set up our handler which writes to, and reads from PostgreSQL.
	reqDumper := storage.HandlerFactory(pgDumper)

	// Set up our handler which writes individual events to PostgreSQL.
	msgParser := &RelayMsgParser{
		Dbh:    dbh,
		Schema: schema,
		Domain: cfg["RELAYMSG_INBOUND_DOMAIN"],
	}

	// recurring job to transform blobs of webhook data into relay_messages
	interval := time.Duration(batchInterval) * time.Second
	ticker := time.NewTicker(interval)
	go func() {
		for {
			select {
			case <-ticker.C:
				go func() {
					_, err := storage.ProcessBatch(pgDumper, msgParser)
					if err != nil {
						log.Printf("%s\n", err)
					}
				}()
			}
		}
	}()

	router := vestigo.NewRouter()

	router.SetGlobalCors(&vestigo.CorsAccessControl{
		AllowOrigin:   []string{cfg["RELAYMSG_ALLOWED_ORIGIN"]},
		ExposeHeaders: []string{"accept"},
		AllowHeaders:  []string{"accept"},
	})

	// Install handler to store votes in database (incoming webhook events)
	router.Post("/incoming", reqDumper)
	router.Get("/summary/:localpart", msgParser.SummaryHandler())

	portSpec := fmt.Sprintf(":%s", cfg["PORT"])
	log.Fatal(http.ListenAndServe(portSpec, router))
}