package main import ( "context" "log" "net/http" "time" "github.com/gin-gonic/gin" ) type App struct { router *gin.Engine srv *http.Server bind string ips []string } func NewApp(htpasswd_file *string, restrict_to_ips *string, baseURL string, bind string) App { gin.ForceConsoleColor() router := gin.Default() var baserouter *gin.RouterGroup if len(baseURL) > 1 { router.GET("/", func(c *gin.Context) { c.Redirect(http.StatusFound, baseURL) }) baserouter = router.Group(baseURL) } else { baserouter = router.Group("") } if htpasswd_file != nil && len(*htpasswd_file) > 0 { baserouter.Use(Htpassword(*htpasswd_file)) } app := App{ router: router, bind: bind, } if restrict_to_ips != nil && len(*restrict_to_ips) > 0 { app.loadAndWatchIPs(*restrict_to_ips) baserouter.Use(app.Restrict2IPs) } declareStaticRoutes(baserouter, baseURL) return app } func (app *App) Start() { app.srv = &http.Server{ Addr: app.bind, Handler: app.router, ReadHeaderTimeout: 15 * time.Second, ReadTimeout: 15 * time.Second, WriteTimeout: 10 * time.Second, IdleTimeout: 30 * time.Second, } log.Printf("Ready, listening on %s\n", app.bind) if err := app.srv.ListenAndServe(); err != nil && err != http.ErrServerClosed { log.Fatalf("listen: %s\n", err) } } func (app *App) Stop() { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() if err := app.srv.Shutdown(ctx); err != nil { log.Fatal("Server Shutdown:", err) } }