package main import ( "context" "fmt" "net/http" "os" "os/signal" "time" "git.t-juice.club/torjus/gpaste" "github.com/urfave/cli/v2" ) var ( version = "dev" commit = "none" date = "unknown" ) func main() { cli.VersionFlag = &cli.BoolFlag{Name: "version"} app := cli.App{ Name: "gpaste-server", Version: fmt.Sprintf("gpaste-server %s-%s (%s)", version, commit, date), Flags: []cli.Flag{ &cli.StringFlag{ Name: "config", Usage: "Path to config-file.", }, }, Action: ActionServe, } app.Run(os.Args) } func ActionServe(c *cli.Context) error { configPath := "gpaste-server.toml" if c.IsSet("config") { configPath = c.String("config") } f, err := os.Open(configPath) if err != nil { return cli.Exit(err, 1) } defer f.Close() cfg, err := gpaste.ServerConfigFromReader(f) if err != nil { return cli.Exit(err, 1) } rootCtx, rootCancel := signal.NotifyContext(context.Background(), os.Interrupt) defer rootCancel() httpCtx, httpCancel := context.WithCancel(rootCtx) defer httpCancel() httpShutdownCtx, httpShutdownCancel := context.WithCancel(context.Background()) defer httpShutdownCancel() go func() { srv := gpaste.NewHTTPServer(cfg) srv.Addr = cfg.ListenAddr // Wait for cancel go func() { <-httpCtx.Done() timeoutCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() srv.Shutdown(timeoutCtx) }() if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed { fmt.Printf("Error: %s\n", err) } httpShutdownCancel() }() <-httpShutdownCtx.Done() return nil }