Пример #1
0
// RunServer runs the app
func RunServer() error {
	cnf, db, err := initConfigDB(true, true)
	if err != nil {
		return err
	}
	defer db.Close()
	if err := initServices(cnf, db); err != nil {
		return err
	}

	// Start a classic negroni app
	app := negroni.New()
	app.Use(negroni.NewRecovery())
	app.Use(negroni.NewLogger())
	app.Use(gzip.Gzip(gzip.DefaultCompression))
	app.Use(negroni.NewStatic(http.Dir("public")))

	// Create a router instance
	router := mux.NewRouter()

	// Add routes
	healthService.RegisterRoutes(router, "/v1")
	oauthService.RegisterRoutes(router, "/v1/oauth")
	webService.RegisterRoutes(router, "/web")

	// Set the router
	app.UseHandler(router)

	// Run the server on port 8080, gracefully stop on SIGTERM signal
	graceful.Run(":8080", 5*time.Second, app)

	return nil
}
Пример #2
0
func main() {
	// Load the configuration.
	err := envconfig.Process("elwinar", &configuration)
	if err != nil {
		log.Fatalln("unable to read the configuration from env:", err)
	}

	// Open the database connection.
	database, err = sqlx.Connect("sqlite3", configuration.Database)
	if err != nil {
		log.Fatalln("unable to open the database:", err)
	}

	// Initialize the router.
	router := httprouter.New()

	// Add the front-office handlers.
	router.GET("/", Index)
	router.GET("/read", List)
	router.GET("/article/:slug", View)
	router.GET("/fortune", Fortune)
	router.GET("/sitemap.xml", Sitemap)

	// Add the back-office handlers.
	router.GET("/login", Login)
	router.POST("/login", Authenticate)
	router.GET("/logout", Logout)
	router.GET("/write", Write)
	router.POST("/write", Create)
	router.GET("/article/:slug/edit", Edit)
	router.POST("/article/:slug/edit", Update)
	router.GET("/article/:slug/delete", Delete)
	router.GET("/article/:slug/publish", Publish)
	router.GET("/article/:slug/unpublish", Unpublish)

	// Initialize the server middleware stack.
	stack := negroni.New()
	stack.Use(gzip.Gzip(gzip.DefaultCompression))
	stack.Use(negroni.NewRecovery())
	stack.Use(negroni.NewStatic(http.Dir(configuration.Public)))
	stack.Use(sessions.Sessions("elwinar", cookiestore.New([]byte(configuration.Secret))))
	stack.UseHandler(router)

	// Initialize the HTTP server.
	server := &graceful.Server{
		Timeout: 1 * time.Second,
		Server: &http.Server{
			Addr:    fmt.Sprintf(":%d", configuration.Port),
			Handler: stack,
		},
	}

	// Run the server.
	err = server.ListenAndServe()
	if err != nil {
		log.Fatalln("unable to run the server:", err)
	}
}
Пример #3
0
// RunServer runs the app
func RunServer() error {
	cnf, db, err := initConfigDB(true, true)
	if err != nil {
		return err
	}
	defer db.Close()

	// Initialise the health service
	healthService := health.NewService(db)

	// Initialise the oauth service
	oauthService := oauth.NewService(cnf, db)

	// Initialise the email service
	emailService := email.NewService(cnf)

	// Initialise the accounts service
	accountsService := accounts.NewService(
		cnf,
		db,
		oauthService,
		emailService,
		nil, // accounts.EmailFactory
	)

	// Initialise the facebook service
	facebookService := facebook.NewService(
		cnf,
		db,
		accountsService,
		nil, // facebook.Adapter
	)

	// Start a negroni app
	app := negroni.New()
	app.Use(negroni.NewRecovery())
	app.Use(negroni.NewLogger())
	app.Use(gzip.Gzip(gzip.DefaultCompression))

	// Create a router instance
	router := mux.NewRouter()

	// Register routes
	healthService.RegisterRoutes(router, "/v1")
	oauthService.RegisterRoutes(router, "/v1/oauth")
	accountsService.RegisterRoutes(router, "/v1")
	facebookService.RegisterRoutes(router, "/v1/facebook")

	// Set the router
	app.UseHandler(router)

	// Run the server on port 8080, gracefully stop on SIGTERM signal
	graceful.Run(":8080", 5*time.Second, app)

	return nil
}
Пример #4
0
func buildMiddlewareStack(conf *Conf) *negroni.Negroni {
	stack := negroni.New()

	// Recover from panics and send them up to Rollbar.
	stack.Use(middleware.NewRecovery())

	// Gzip-compress responses if requested.
	stack.Use(gzip.Gzip(gzip.DefaultCompression))

	return stack
}
Пример #5
0
func main() {

	r := mux.NewRouter()
	r.HandleFunc("/"+config.Secret, WebhookHandler).Methods("POST")
	http.Handle("/", r)

	n := negroni.Classic()
	n.Use(gzip.Gzip(gzip.DefaultCompression))
	n.UseHandler(r)
	n.Run(config.ListenAddress)
}
Пример #6
0
func main() {
	router := mux.NewRouter()
	router.HandleFunc("/black-and-gray", ShowCars)
	n := negroni.New()
	n.Use(negroni.NewLogger())
	// include the gzip middleware above any other middleware that alters response body
	n.Use(gzip.Gzip(gzip.DefaultCompression))
	n.Use(negroni.NewRecovery())
	n.Use(negroni.NewStatic(http.Dir("public")))
	n.UseHandler(router)
	n.Run(":8888")
}
Пример #7
0
// NewApp returns a pointer to an application instance. These
// instances have reasonable defaults and include middleware to:
// recover from panics in handlers, log information about the request,
// and gzip compress all data. Users must specify a default version
// for new methods.
func NewApp() *APIApp {
	a := &APIApp{
		StrictSlash:    true,
		defaultVersion: -1, // this is the same as having no version prepended to the path.
		port:           3000,
	}

	a.AddMiddleware(negroni.NewRecovery())
	a.AddMiddleware(NewAppLogger())
	a.AddMiddleware(gzip.Gzip(gzip.DefaultCompression))

	return a
}
Пример #8
0
func main() {
	r := render.New(render.Options{
		Layout: "layout",
	})

	mux := httprouter.New()
	mux.GET("/", func(w http.ResponseWriter, req *http.Request, _ httprouter.Params) {
		r.HTML(w, http.StatusOK, "index", nil)
	})

	n := negroni.Classic()
	n.Use(gzip.Gzip(gzip.DefaultCompression))
	n.UseHandler(mux)
	graceful.Run(":"+os.Getenv("PORT"), 10*time.Second, n)
}
Пример #9
0
func main() {
	router := mux.NewRouter()
	router.HandleFunc("/routes/{route}", api.Stops)
	router.HandleFunc("/routes", api.AllStops)
	router.HandleFunc("/vehicles/{route}", api.Vehicles)
	router.HandleFunc("/vehicles", api.AllVehicles)

	n := negroni.New()
	n.Use(gzip.Gzip(gzip.DefaultCompression))
	n.UseHandler(cors.Default().Handler(router))

	go jobs.RunFetch()
	go jobs.RunExpire()

	n.Run(":8048")
}
Пример #10
0
func New() http.Handler {
	// set up handlers
	http.HandleFunc("/1/setpoint.json", makeHandler(setpointHandler))
	http.HandleFunc("/1/sleep.json", makeHandler(sleepHandler))
	http.HandleFunc("/1/smooth.json", makeHandler(smoothHandler))
	http.HandleFunc("/1/setpid.json", makeHandler(setpidHandler))
	http.Handle("/1/data.json", negroni.New(
		gzip.Gzip(gzip.DefaultCompression),
		negroni.Wrap(makeHandler(dataHandler)),
	))

	// use negroni
	n := negroni.New(negroni.NewRecovery(), negroni.NewLogger())
	n.UseHandler(http.DefaultServeMux)

	return http.Handler(n)
}
Пример #11
0
// RunServer runs the app
func RunServer() error {
	cnf, db, err := initConfigDB(true, true)
	defer db.Close()
	if err != nil {
		return err
	}

	// Initialise the health service
	healthService := health.NewService(db)

	// Initialise the oauth service
	oauthService := oauth.NewService(cnf, db)

	// Initialise the web service
	webService := web.NewService(cnf, oauthService)

	// Start a classic negroni app
	app := negroni.New()
	app.Use(negroni.NewRecovery())
	app.Use(negroni.NewLogger())
	app.Use(gzip.Gzip(gzip.DefaultCompression))
	app.Use(negroni.NewStatic(http.Dir("public")))

	// Create a router instance
	router := mux.NewRouter()

	// Add routes for the health service (healthcheck endpoint)
	health.RegisterRoutes(router, healthService)

	// Add routes for the oauth service (REST tokens endpoint)
	oauth.RegisterRoutes(router, oauthService)

	// Add routes for the web package (register, login authorize web pages)
	web.RegisterRoutes(router, webService)

	// Set the router
	app.UseHandler(router)

	// Run the server on port 8080
	app.Run(":8080")

	return nil
}
Пример #12
0
func configRoutes(dbh *db.Handle) *negroni.Negroni {
	r := mux.NewRouter().PathPrefix(webroot).Subrouter()
	r.HandleFunc("/api", capsHandler).Queries("t", "caps")
	r.HandleFunc("/api", searchHandler).Queries("t", "search")
	r.HandleFunc("/api", tvSearchHandler).Queries("t", "tvsearch")
	r.HandleFunc("/getnzb", nzbDownloadHandler)
	r.HandleFunc("/", homeHandler)
	n := negroni.Classic()
	n.Use(gzip.Gzip(gzip.DefaultCompression))
	c := cors.New(cors.Options{
		AllowedOrigins: []string{"*"},
	})

	n.Use(negronilogrus.NewCustomMiddleware(logrus.DebugLevel, &logrus.JSONFormatter{}, "web"))
	n.Use(c)
	n.Use(dbMiddleware(dbh))
	n.UseHandler(r)
	return n
}
Пример #13
0
func makeHandler() http.Handler {
	router := httprouter.New()

	GET(router, "/", HandleIndex)
	GET(router, "/auth/user", HandleAuthUser)
	POST(router, "/auth/login", HandleLogin)
	POST(router, "/auth/register", HandleRegister)
	POST(router, "/auth/logout", HandleLogout)
	POST(router, "/auth/stripe", Authed(HandleUpdateStripe))
	POST(router, "/model/create", Authed(HandleCreateModel))
	GET(router, "/user/username/:username", HandleUserByUsername)
	GET(router, "/models/username/:username", HandleModelsByUsername)
	GET(router, "/models/public/latest", HandleLatestPublicModels)
	GET(router, "/models/public/top/:period", HandleTopPublicModels)
	GET(router, "/model/username/:username/slug/:slug", HandleModelByUsernameAndSlug)
	POST(router, "/model/id/:id/readme", Authed(HandleUpdateModelReadme))
	POST(router, "/model/id/:id/deleted", Authed(HandleDeleteModel))
	POST(router, "/file/:username/:slug/:framework/:filename", Authed(HandleFileUpload))
	GET(router, "/file/:username/:slug/:framework/:filename", HandleFile)
	GET(router, "/file-id/:id", HandleFileById)
	GET(router, "/file-versions/:username/:slug/:framework/:filename", HandleFileVersions)
	GET(router, "/model/username/:username/slug/:slug/latest-files", HandleLatestFilesByUsernameAndSlug)

	n := negroni.New(negroni.NewLogger())

	// In production, redirect all traffic to https (except /, for LB health check)
	if utils.Conf.Production {
		n.UseHandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
			if r.URL.Path != "/" && r.Header.Get("X-Forwarded-Proto") != "https" {
				http.RedirectHandler(
					"https://"+r.Host+r.URL.RequestURI(),
					http.StatusFound,
				).ServeHTTP(rw, r)
			}
		})
	}

	n.Use(gzip.Gzip(gzip.BestCompression))
	n.Use(negronilogrus.NewMiddleware())
	n.UseHandler(router)

	return n
}
Пример #14
0
func (a *API) Serve(addr string) {
	router := mux.NewRouter()

	v1 := router.PathPrefix("/1").Subrouter()

	// tasks
	tasksHandler := TasksHandler{a.store.Tasks()}

	task := v1.PathPrefix("/tasks/{id}").Subrouter()
	task.Methods("GET").HandlerFunc(tasksHandler.Get)
	task.Methods("PUT").HandlerFunc(tasksHandler.Set)
	task.Methods("DELETE").HandlerFunc(tasksHandler.Delete)
	task.Methods("POST", "PATCH").HandlerFunc(MethodNotAllowed)

	tasks := v1.PathPrefix("/tasks").Subrouter()
	tasks.Methods("GET").HandlerFunc(tasksHandler.List)
	tasks.Methods("POST").HandlerFunc(tasksHandler.Set)
	tasks.Methods("PUT", "DELETE", "PATCH").HandlerFunc(MethodNotAllowed)

	// events
	eventsHandler := EventsHandler{a.store.Events(), a.Events}

	event := v1.PathPrefix("/events/{id}").Subrouter()
	event.Methods("GET").HandlerFunc(eventsHandler.Get)
	event.Methods("PUT", "POST", "DELETE", "PATCH").HandlerFunc(MethodNotAllowed)

	events := v1.PathPrefix("/events").Subrouter()
	events.Methods("GET").HandlerFunc(eventsHandler.List)
	events.Methods("POST").HandlerFunc(eventsHandler.Create)
	events.Methods("PUT", "DELETE", "PATCH").HandlerFunc(MethodNotAllowed)

	// set up event handlers

	n := negroni.New()
	n.Use(negroni.NewRecovery())
	n.Use(negronilogrus.NewMiddleware())
	n.Use(gzip.Gzip(gzip.DefaultCompression))
	n.UseHandler(router)

	logrus.WithField("addr", addr).Info("listening")
	graceful.Run(addr, 10*time.Second, n)
}
Пример #15
0
func main() {
	// Parse flags
	parseFlags()

	// New logger
	l := log.New(os.Stdout, "[actions-store] ", 0)

	// If database url is empty its a fatal error
	if database == "" {
		l.Fatal("Database url can not be empty. Use `-database` flag or `MONGO_URL` environment variable.")
	}

	// Set database url
	err := models.SetDatabase(database)
	if err != nil {
		l.Fatal(err)
	}

	// Todo: authentication
	n := negroni.Classic()
	n.Use(negroni.HandlerFunc(corsMiddleware))
	n.Use(gzip.Gzip(gzip.DefaultCompression))

	// Bind actions REST api
	n.UseHandler(routes.Router)

	// Start JSON-RPC server
	go func() {
		l.Printf("rpc listening on %s", rpcaddress)
		err := rpc.Listen(rpcaddress)
		if err != nil {
			panic(err)
		}
	}()

	// Start HTTP server
	l.Printf("listening on %s", address)
	l.Fatal(http.ListenAndServe(address, n))
}
Пример #16
0
func main() {
	var httpPort = flag.Int("port", 8080, "port to listen on for HTTP")
	var dbHost = flag.String("dbhost", "localhost:27017", "host/port to connect to DB server")
	flag.Parse()

	session, err := mgo.Dial(*dbHost)
	if err != nil {
		fmt.Println(err)
		return
	}

	lk := logkeeper.New(session, logkeeper.Options{
		DB:  "buildlogs",
		URL: fmt.Sprintf("http://localhost:%v", *httpPort),
	})
	router := lk.NewRouter()
	n := negroni.Classic()
	n.Use(gzip.Gzip(gzip.DefaultCompression))
	n.UseHandler(router)

	graceful.Run(fmt.Sprintf(":%v", *httpPort), 10*time.Second, n)
}
Пример #17
0
func main() {
	// Load configuration
	// TODO: How to share this config with the handlers?
	configuration, err := config.Load("./config.json")
	if err != nil {
		log.Fatal(err)
	}

	// Setup middleware
	middle := negroni.Classic()
	middle.Use(gzip.Gzip(gzip.DefaultCompression))

	store := cookiestore.New([]byte("keyboard cat"))
	middle.Use(sessions.Sessions("tvtio", store))

	// Setup router
	router := httprouter.New()
	router.GET("/", routes.Index)
	router.GET("/search", routes.Search)
	router.GET("/movie/:id", routes.Movie)
	router.GET("/tv/:id", routes.TV)
	router.GET("/person/:id", routes.Person)
	router.GET("/about", routes.About)
	router.GET("/login", routes.Login)
	router.GET("/logout", routes.Logout)
	router.GET("/auth/twitter", routes.AuthTwitter)
	router.GET("/auth/facebook", routes.AuthFacebook)
	router.GET("/auth/facebook/callback", routes.AuthFacebookCallback)
	router.ServeFiles("/css/*filepath", http.Dir(configuration.Templates+"/css"))
	router.ServeFiles("/js/*filepath", http.Dir(configuration.Templates+"/js"))
	router.ServeFiles("/img/*filepath", http.Dir(configuration.Templates+"/img"))

	middle.UseHandler(router)

	// Start server
	fmt.Println("Listening at " + configuration.ServerURL())
	log.Fatal(http.ListenAndServe(configuration.ServerAddress(), middle))
}
Пример #18
0
func main() {
	// render
	ren := render.New(render.Options{
		Layout:        "shared/layout",
		IndentJSON:    true,
		IsDevelopment: false,
	})

	//init db
	db, err := sqlx.Connect("mysql", "root:slurp@tcp(127.0.0.1:3306)/sfs")
	if err != nil {
		log.Print(err)
		log.Print("Error initializing database...")
	}
	defer db.Close()

	// setup context
	c := ctx{db, ren}

	// setup negroni
	n := negroni.New()

	// setup router
	router := mux.NewRouter()

	// routes
	router.HandleFunc("/", c.NewSupporter).Methods("GET")
	router.HandleFunc("/", c.NewSupporterPost).Methods("POST")
	router.HandleFunc("/love", c.ShowSupporters).Methods("GET")

	//n.Use(NewRecovery(false))
	n.Use(gzip.Gzip(gzip.DefaultCompression))
	n.Use(negroni.NewStatic(http.Dir("public")))

	n.UseHandler(router)

	n.Run(fmt.Sprint(":", os.Getenv("PORT")))
}
Пример #19
0
func main() {
	common.Initvars()
	common.Setupdb()
	// common.Setupspellchecker()
	// TODO: Setup shutdown when server is given a signal - see common.SetupShutdown
	defer common.Shutdown()
	// fmt.Println(common.Spk.SuggestSpelling("artointestinal"))
	// fmt.Println(common.Spk.CheckText("Myocariel Infraction"))

	n := negroni.Classic()
	n.Use(gzip.Gzip(gzip.DefaultCompression))
	n.Use(negroni.NewRecovery())
	n.Use(negroni.NewLogger())

	mux := http.NewServeMux()
	mux.Handle("/", http.FileServer(http.Dir(common.Siteroot)))
	mux.HandleFunc("/snomed/searchterm", handlers.Snomedsearchterm)
	mux.HandleFunc("/loinc/searchterm", handlers.Loincsearchterm)
	n.UseHandler(mux)

	fmt.Println("Ontoserver Started")
	n.Run(":80")
}
func main() {
	mainServer := negroni.New()

	// Token auth middleware
	tokenVerification := handlers.NewTokenVerificationMiddleware()
	tokenVerification.Initialize()
	mainServer.Use(negroni.NewRecovery())
	mainServer.Use(negroni.NewLogger())
	mainServer.Use(negroni.HandlerFunc(tokenVerification.Run))
	mainServer.Use(gzip.Gzip(gzip.DefaultCompression))

	// Create external service connections
	s := session.New()
	dynamoDBConnection := createDynamoDBConnection(s)
	geoLookup := geo.NewGoogleGeoLookup(os.Getenv("GOOGLE_API_KEY"))
	geoLookup.Initialize()
	deviceDatabase := db.NewDeviceDatabase(dynamoDBConnection, geoLookup)
	measurementsDatabase, err := createMeasurementsDatabaseConnection(deviceDatabase)
	if err != nil {
		fmt.Printf("Error connecting to InfluxDB: %s\n", err.Error())
		return
	}

	// Initialize HTTP service handlers
	router := mux.NewRouter()
	handlers.InitializeRouterForSensorsDataRetrieval(router, deviceDatabase, measurementsDatabase)
	handlers.InitializeRouterForSensorHandler(router, deviceDatabase)
	mainServer.UseHandler(router)
	go mainServer.Run(":3000")

	// Run healthcheck service
	healthCheckServer := negroni.New()
	healthCheckRouter := mux.NewRouter()
	handlers.InitializeRouterForHealthCheckHandler(healthCheckRouter, dynamoDBConnection)
	healthCheckServer.UseHandler(healthCheckRouter)
	healthCheckServer.Run(":3100")
}
Пример #21
0
func Gzip() Middleware {
	return gzip.Gzip(gzip.DefaultCompression)
}
Пример #22
0
Файл: web.go Проект: imvu/Tetra
// WebApp creates the web application and YAML api for Tetra.
func WebApp() {
	mux := routes.New()
	r := render.New(render.Options{})

	mux.Get("/", func(res http.ResponseWriter, req *http.Request) {
		fmt.Fprintf(res, "error: No method chosen.")
	})

	mux.Get("/info.json", func(w http.ResponseWriter, req *http.Request) {
		r.JSON(w, http.StatusOK, struct {
			Usercount    int `json:"usercount"`
			Channelcount int `json:"channelcount"`
		}{
			Usercount:    len(Clients.ByNick),
			Channelcount: len(Channels),
		})
	})

	mux.Get("/channels.json", func(w http.ResponseWriter, req *http.Request) {
		var channels []channel

		for _, in := range Channels {
			if in.Modes&modes.PROP_SECRET != modes.PROP_SECRET {
				channels = append(channels, convertChannel(in))
			}
		}

		r.JSON(w, http.StatusOK, channels)
	})

	mux.Get("/clients.json", func(res http.ResponseWriter, req *http.Request) {
		var clients []client

		for _, in := range Clients.ByUID {
			myclient := convertClient(in)

			if len(myclient.Joins) == 0 {
				continue
			}

			clients = append(clients, myclient)
		}

		r.JSON(res, http.StatusOK, clients)
	})

	mux.Get("/yo/:id", func(res http.ResponseWriter, req *http.Request) {
		params := req.URL.Query()
		id := params.Get(":id")
		username := req.URL.Query()["username"][0]

		RunHook("YO", username, id)
		RunHook("YO_"+id, username)

		fmt.Fprintf(res, "OK")
	})

	port := os.Getenv("PORT")
	if port == "" {
		port = "3000"
	}

	Log.Printf("listening on %v...\n", port)

	go func() {
		n := negroni.New(negroni.NewRecovery(), negroni.NewStatic(http.Dir("public")), web.NewLogger())

		n.Use(gzip.Gzip(gzip.DefaultCompression))
		n.UseHandler(mux)

		err := http.ListenAndServe(":"+port, n)

		if err != nil {
			Services["tetra"].ServicesLog("Web app died")
			Services["tetra"].ServicesLog(err.Error())
			Log.Fatal(err)
		}
	}()
}
Пример #23
0
// apiRouter sets up the instance of negroni
func apiRouter(apiKillChan chan struct{}) {
	log.Println("api: starting...")

	// Initialize negroni
	n := negroni.New()

	// Set up render
	r := render.New(render.Options{
		// Output human-readable JSON/XML. GZIP will essentially negate the size increase, and this
		// makes the API much more developer-friendly
		IndentJSON: true,
		IndentXML:  true,
	})

	// GZIP all responses
	n.Use(gzip.Gzip(gzip.DefaultCompression))

	// Initial API setup
	n.Use(negroni.HandlerFunc(func(res http.ResponseWriter, req *http.Request, next http.HandlerFunc) {
		// Send a Server header with all responses
		res.Header().Set("Server", fmt.Sprintf("%s/%s (%s_%s)", App, Version, runtime.GOOS, runtime.GOARCH))

		// Store render in context for all API calls
		context.Set(req, api.CtxRender, r)

		// Wrap HTTP request and response with metrics instrumentation
		req.Body = httpRMetricsLogger{req.Body}
		metricsRes := httpWMetricsLogger{res}

		// On debug, log everything
		if env.IsDebug() {
			log.Println(req.Header)
			log.Println(req.URL)

			// Wrap response in debug logging
			next(httpWDebugLogger{metricsRes}, req)
			return
		}

		// Delegate to next middleware
		next(metricsRes, req)
		return
	}))

	// Authenticate all API calls
	n.Use(negroni.HandlerFunc(func(res http.ResponseWriter, req *http.Request, next http.HandlerFunc) {
		// Use factory to determine and invoke the proper authentication method for this path
		user, session, clientErr, serverErr := auth.Factory(req.URL.Path).Authenticate(req)

		// Check for client error
		if clientErr != nil {
			// Check for a Subsonic error, since these are rendered as XML
			if subErr, ok := clientErr.(*subsonic.Container); ok {
				r.XML(res, 200, subErr)
				return
			}

			// If debug mode, and no username or password, send a WWW-Authenticate header to prompt request
			// This allows for manual exploration of the API if needed
			if env.IsDebug() && (clientErr == auth.ErrNoUsername || clientErr == auth.ErrNoPassword) {
				res.Header().Set("WWW-Authenticate", "Basic")
			}

			r.JSON(res, 401, api.ErrorResponse{
				Error: &api.Error{
					Code:    401,
					Message: "authentication failed: " + clientErr.Error(),
				},
			})
			return
		}

		// Check for server error
		if serverErr != nil {
			log.Println(serverErr)

			// Check for a Subsonic error, since these are rendered as XML
			if subErr, ok := serverErr.(*subsonic.Container); ok {
				r.XML(res, 200, subErr)
				return
			}

			r.JSON(res, 500, api.ErrorResponse{
				Error: &api.Error{
					Code:    500,
					Message: "server error",
				},
			})
			return
		}

		// Successful login, map session user and session to gorilla context for this request
		context.Set(req, api.CtxUser, user)
		context.Set(req, api.CtxSession, session)

		// Print information about this API call
		log.Printf("api: [%s] %s %s?%s", req.RemoteAddr, req.Method, req.URL.Path, req.URL.Query().Encode())

		// Perform API call
		next(res, req)
	}))

	// Wait for graceful to signal termination
	gracefulChan := make(chan struct{}, 0)

	// Use gorilla mux with negroni, start server
	n.UseHandler(newRouter())
	go func() {
		// Load config
		conf, err := config.C.Load()
		if err != nil {
			log.Println(err)
			return
		}

		// Check for empty host
		if conf.Host == "" {
			log.Fatalf("api: no host specified in configuration")
		}

		// Start server, allowing up to 10 seconds after shutdown for clients to complete
		log.Println("api: binding to host", conf.Host)
		if err := graceful.ListenAndServe(&http.Server{Addr: conf.Host, Handler: n}, 10*time.Second); err != nil {
			// Check if address in use
			if strings.Contains(err.Error(), "address already in use") {
				log.Fatalf("api: cannot bind to %s, is wavepipe already running?", conf.Host)
			}

			// Ignore error on closing
			if !strings.Contains(err.Error(), "use of closed network connection") {
				// Log other errors
				log.Println(err)
			}
		}

		// Shutdown complete
		close(gracefulChan)
	}()

	// Trigger events via channel
	for {
		select {
		// Stop API
		case <-apiKillChan:
			// If testing, don't wait for graceful shutdown
			if !env.IsTest() {
				// Block and wait for graceful shutdown
				log.Println("api: waiting for remaining connections to close...")
				<-gracefulChan
			}

			// Inform manager that shutdown is complete
			log.Println("api: stopped!")
			apiKillChan <- struct{}{}
			return
		}
	}
}
Пример #24
0
func (l *Gzip) ServeHTTP(c context.Context, w http.ResponseWriter, r *http.Request) context.Context {
	return negroni.Middleware(negroniGzip.Gzip(l.compressionLevel)).ServeHTTP(c, w, r)
}
Пример #25
0
func mindHTTP() {
	r := mux.NewRouter()
	r.HandleFunc("/v1.json", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "text/json")
		statsLock.Lock()
		defer statsLock.Unlock()
		enc := json.NewEncoder(w)
		enc.Encode(stats)
	})
	r.HandleFunc("/v1/gt/{gamertag}.json", func(w http.ResponseWriter, r *http.Request) {
		vars := mux.Vars(r)
		enc := json.NewEncoder(w)
		statsLock.Lock()
		defer statsLock.Unlock()
		if v, ok := stats[vars["gamertag"]]; ok {
			w.Header().Set("Content-Type", "text/json")
			enc.Encode(v)
		} else {
			w.WriteHeader(http.StatusNotFound)
		}
	})
	r.HandleFunc("/v1/slackid/{slackuid}.json", func(w http.ResponseWriter, r *http.Request) {
		vars := mux.Vars(r)
		enc := json.NewEncoder(w)
		statsLock.Lock()
		defer statsLock.Unlock()
		for _, v := range stats {
			if v.User.ID == vars["slackuid"] {
				w.Header().Set("Content-Type", "text/json")
				enc.Encode(v)
				return
			}
		}
		w.WriteHeader(http.StatusNotFound)
	})
	r.HandleFunc("/v1/username/{slackusername}.json", func(w http.ResponseWriter, r *http.Request) {
		vars := mux.Vars(r)
		enc := json.NewEncoder(w)
		statsLock.Lock()
		defer statsLock.Unlock()
		for _, v := range stats {
			if v.User.UserName == vars["slackusername"] {
				w.Header().Set("Content-Type", "text/json")
				enc.Encode(v)
				return
			}
		}
		w.WriteHeader(http.StatusNotFound)
	})
	r.HandleFunc("/v1/compact.json", func(w http.ResponseWriter, r *http.Request) {
		enc := json.NewEncoder(w)
		var out = struct {
			Index map[string]interface{}
			Stats []struct {
				User  singleUser
				Stats map[string]string
			}
		}{
			Stats: []struct {
				User  singleUser
				Stats map[string]string
			}{},
		}
		statsLock.Lock()
		for _, v := range stats {
			var entry = struct {
				User  singleUser
				Stats map[string]string
			}{
				User:  v.User,
				Stats: map[string]string{},
			}
			if out.Index == nil {
				out.Index = map[string]interface{}{}
				for _, s := range v.Stats {
					out.Index[s.Name] = s
				}
			}
			for _, s := range v.Stats {
				entry.Stats[s.Name] = s.Value.String()
			}
			out.Stats = append(out.Stats, entry)
		}
		statsLock.Unlock()
		w.Header().Set("Content-Type", "text/json")
		enc.Encode(out)
	})
	n := negroni.New()
	n.Use(cors.New(cors.Options{AllowedOrigins: []string{"*"}}))
	n.Use(negroni.NewRecovery())
	n.Use(negroni.NewLogger())
	n.Use(gzip.Gzip(gzip.DefaultCompression))
	n.UseHandler(r)
	n.Run(config.Listen)
}
Пример #26
0
func NegroniGzip(compression int) func(http.Handler) http.Handler {
	return adaptors.FromNegroni(gzip.Gzip(compression))
}
Пример #27
0
// httpServer returns an http server
func (s *Server) httpServer(log *logrus.Entry) *http.Server {
	addr := fmt.Sprintf("%s:%d", s.config.HTTPServer.Host, s.config.HTTPServer.Port)
	log.Debugf("http server will listen on: %s", addr)

	mux := mux.NewRouter()
	for _, route := range []struct {
		// name of the route
		name string
		// path of the route
		path string
		// allowed methods for this route
		methods string
		// handler is the http handler to run if the route matches
		handler func(http.ResponseWriter, *http.Request)
		// excluded tells if the route should be added to the router,
		// it's in the negative form so that the default behaviour is to add
		// the route to the router
		excluded bool
	}{
		{
			name:    "GetMovies",
			path:    "/movies",
			methods: "GET",
			handler: s.movieIds,
		},
		{
			name:    "GetMovie",
			path:    "/movies/{id}",
			methods: "GET",
			handler: s.getMovieDetails,
		},
		{
			name:    "DeleteMovie",
			path:    "/movies/{id}",
			methods: "DELETE",
			handler: s.deleteMovie,
		},
		{
			name:     "DownloadMovie",
			path:     "/movies/{id}/download",
			methods:  "GET",
			handler:  s.serveMovie,
			excluded: !s.config.HTTPServer.ServeFiles,
		},
		{
			name:    "GetShows",
			path:    "/shows",
			methods: "GET",
			handler: s.showIds,
		},
		{
			name:    "GetShow",
			path:    "/shows/{id}",
			methods: "GET",
			handler: s.getShowDetails,
		},
		{
			name:    "GetSeason",
			path:    "/shows/{id}/seasons/{season:[0-9]+}",
			methods: "GET",
			handler: s.getSeasonDetails,
		},
		{
			name:    "GetEpisode",
			path:    "/shows/{id}/seasons/{season:[0-9]+}/episodes/{episode:[0-9]+}",
			methods: "GET",
			handler: s.getShowEpisodeIDDetails,
		},
		{
			name:    "DeleteEpisode",
			path:    "/shows/{id}/seasons/{season:[0-9]+}/episodes/{episode:[0-9]+}",
			methods: "DELETE",
			handler: s.deleteEpisode,
		},
		{
			name:     "DownloadEpisode",
			path:     "/shows/{id}/seasons/{season:[0-9]+}/episodes/{episode:[0-9]+}/download",
			methods:  "GET",
			handler:  s.serveShow,
			excluded: !s.config.HTTPServer.ServeFiles,
		},
		{
			name:    "Wishlist",
			path:    "/wishlist",
			methods: "GET",
			handler: s.wishlist,
		},
		{
			name:    "AddTorrent",
			path:    "/torrents",
			methods: "POST",
			handler: s.addTorrent,
		},
	} {
		if route.excluded {
			continue
		}

		// Register the route
		mux.HandleFunc(route.path, route.handler).Name(route.name).Methods(route.methods)
	}

	n := negroni.New()

	// Panic recovery
	n.Use(negroni.NewRecovery())

	// Use logrus as logger
	n.Use(negronilogrus.NewMiddlewareFromLogger(s.log.Logger, "httpServer"))

	// gzip compression
	n.Use(gzip.Gzip(gzip.DefaultCompression))

	// Add basic auth if configured
	if s.config.HTTPServer.BasicAuth {
		log.Info("server will require basic authentication")
		n.Use(NewBasicAuthMiddleware(s.config.HTTPServer.BasicAuthUser, s.config.HTTPServer.BasicAuthPassword))
	}

	// Add token auth middleware if token configuration file specified
	if s.tokenManager != nil {
		n.Use(token.NewMiddleware(s.tokenManager, mux))
		mux.HandleFunc("/tokens/allowed", s.tokenGetAllowed).Name("TokenGetAllowed")
	}

	// Wrap the router
	n.UseHandler(mux)

	return &http.Server{Addr: addr, Handler: n}
}