package main import ( "context" "crypto/tls" "flag" "log" "net/http" "os" "os/signal" "strconv" "syscall" ) func main() { os.Exit(main_body()) } func main_body() int { var conf_file string var http_only bool // Parse args and read config flag.StringVar(&conf_file, "c", "", "Path to config file") flag.BoolVar(&http_only, "h", false, "HTTP only") flag.Parse() if conf_file == "" { _, err := os.Stat("/etc/shizaru.conf") if !os.IsNotExist(err) { conf_file = "/etc/shizaru.conf" } } config, err := getConfig(conf_file) if err != nil { log.Println("Error reading config file " + conf_file) return 1 } https := ! http_only // Open logfile logfile, err := os.OpenFile(config.LogPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { log.Println("Error opening log file " + config.LogPath + ".") return 2 } defer logfile.Close() // Configure HTTP and HTTPS servers // By default, all the HTTP server does is redirect everything to HTTPS. // Alternatively, serve *only* on HTTP, for use behind nginx or similar. var http_server *http.Server var https_server *http.Server http.HandleFunc("/", LoggingWrapper(logfile, GetHandler(config))) if(http_only) { http_server = &http.Server{Addr: ":"+strconv.Itoa(config.HttpPort), Handler: nil} } else { http_server = &http.Server{Addr: ":"+strconv.Itoa(config.HttpPort), Handler: http.HandlerFunc(GetRedirectTLSHandler(config))} tlscfg := &tls.Config{ MinVersion: tls.VersionTLS10, } https_server = &http.Server{Addr: ":"+strconv.Itoa(config.HttpsPort), Handler: nil, TLSConfig: tlscfg} } // Start HTTP server errs := make(chan error, 2) go func() { errs <- http_server.ListenAndServe() }() // Start HTTPS server if(https) { go func() { errs <- https_server.ListenAndServeTLS(config.CertPath, config.KeyPath) }() log.Println("Listening on ports " + strconv.Itoa(config.HttpPort) + " and " + strconv.Itoa(config.HttpsPort) + "...") } else { log.Println("Listening on port " + strconv.Itoa(config.HttpPort) + "...") } // Listen for signals to gracefully shutdown stop := make(chan os.Signal, 1) signal.Notify(stop, os.Interrupt) signal.Notify(stop, syscall.SIGTERM) // Wait for a signal or an error select { case <-stop: log.Println("Shutting down!") http_server.Shutdown(context.Background()) if(https) { https_server.Shutdown(context.Background()) } case err := <-errs: log.Println("Fatal: " + err.Error()) } return 0 }