func (sh *StatusHandler) serveRestart(rw http.ResponseWriter, req *http.Request) { if req.Method != "POST" { http.Error(rw, "POST to restart", http.StatusMethodNotAllowed) return } _, handlers := sh.handlerFinder.AllHandlers() for _, h := range handlers { ah, ok := h.(*app.Handler) if !ok { continue } log.Printf("Sending SIGINT to %s", ah.ProgramName()) err := ah.Quit() if err != nil { msg := fmt.Sprintf("Not restarting: couldn't interrupt app %s: %v", ah.ProgramName(), err) log.Printf(msg) http.Error(rw, msg, http.StatusInternalServerError) return } } log.Println("Restarting camlistored") rw.Header().Set("Connection", "close") http.Redirect(rw, req, sh.prefix, http.StatusFound) if f, ok := rw.(http.Flusher); ok { f.Flush() } osutil.RestartProcess() }
func (sh *SetupHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) { if !auth.LocalhostAuthorized(req) { fmt.Fprintf(rw, "<html><body>Setup only allowed from localhost"+ "<p><a href='/'>Back</a></p>"+ "</body></html>\n") return } if req.Method == "POST" { err := req.ParseMultipartForm(10e6) if err != nil { httputil.ServerError(rw, req, err) return } if len(req.Form) > 0 { handleSetupChange(rw, req) return } if strings.Contains(req.URL.Path, "restartCamli") { err = osutil.RestartProcess() if err != nil { log.Fatal("Failed to restart: " + err.Error()) } } } sendWizard(rw, req, false) }
func handleSetupChange(rw http.ResponseWriter, req *http.Request) { hilevelConf, err := jsonconfig.ReadFile(osutil.UserServerConfigPath()) if err != nil { httputil.ServeError(rw, req, err) return } if !xsrftoken.Valid(req.FormValue("token"), serverKey, "user", "wizardSave") { http.Error(rw, "Form expired. Press back and reload form.", http.StatusBadRequest) log.Printf("invalid xsrf token=%q", req.FormValue("token")) return } hasChanged := false var el interface{} publish := jsonconfig.Obj{} for k, v := range req.Form { if _, ok := hilevelConf[k]; !ok { if k != "gallery" && k != "blog" { continue } } switch k { case "https", "shareHandler": b, err := strconv.ParseBool(v[0]) if err != nil { httputil.ServeError(rw, req, fmt.Errorf("%v field expects a boolean value", k)) } el = b default: el = v[0] } if reflect.DeepEqual(hilevelConf[k], el) { continue } hasChanged = true hilevelConf[k] = el } // "publish" wasn't checked yet if !reflect.DeepEqual(hilevelConf["publish"], publish) { hilevelConf["publish"] = publish hasChanged = true } if hasChanged { err = rewriteConfig(&hilevelConf, osutil.UserServerConfigPath()) if err != nil { httputil.ServeError(rw, req, err) return } err = osutil.RestartProcess() if err != nil { log.Fatal("Failed to restart: " + err.Error()) http.Error(rw, "Failed to restart process", 500) return } } sendWizard(rw, req, hasChanged) }
func handleSignals() { c := make(chan os.Signal, 1) signal.Notify(c, syscall.SIGHUP) for { sig := <-c sysSig, ok := sig.(syscall.Signal) if !ok { log.Fatal("Not a unix signal") } switch sysSig { case syscall.SIGHUP: log.Print("SIGHUP: restarting camli") err := osutil.RestartProcess() if err != nil { log.Fatal("Failed to restart: " + err.Error()) } default: log.Fatal("Received another signal, should not happen.") } } }
func handleSignals(shutdownc <-chan io.Closer) { c := make(chan os.Signal, 1) signal.Notify(c, syscall.SIGHUP) signal.Notify(c, syscall.SIGINT) for { sig := <-c sysSig, ok := sig.(syscall.Signal) if !ok { log.Fatal("Not a unix signal") } switch sysSig { case syscall.SIGHUP: log.Print("SIGHUP: restarting camli") err := osutil.RestartProcess() if err != nil { log.Fatal("Failed to restart: " + err.Error()) } case syscall.SIGINT: log.Print("Got SIGINT: shutting down") donec := make(chan bool) go func() { cl := <-shutdownc if err := cl.Close(); err != nil { exitf("Error shutting down: %v", err) } donec <- true }() select { case <-donec: log.Printf("Shut down.") osExit(0) case <-time.After(2 * time.Second): exitf("Timeout shutting down. Exiting uncleanly.") } default: log.Fatal("Received another signal, should not happen.") } } }