package route import ( "errors" "fmt" "net/http" "os" "github.com/Dreamacro/clash/config" "github.com/Dreamacro/clash/hub/updater" "github.com/Dreamacro/clash/log" "github.com/go-chi/chi/v5" "github.com/go-chi/render" ) func upgradeRouter() http.Handler { r := chi.NewRouter() r.Post("/", upgradeCore) r.Post("/ui", updateUI) return r } func upgradeCore(w http.ResponseWriter, r *http.Request) { // modify from https://github.com/AdguardTeam/AdGuardHome/blob/595484e0b3fb4c457f9bb727a6b94faa78a66c5f/internal/home/controlupdate.go#L108 log.Infoln("start update") execPath, err := os.Executable() if err != nil { render.Status(r, http.StatusInternalServerError) render.JSON(w, r, newError(fmt.Sprintf("getting path: %s", err))) return } err = updater.Update(execPath) if err != nil { log.Warnln("%s", err) render.Status(r, http.StatusInternalServerError) render.JSON(w, r, newError(fmt.Sprintf("%s", err))) return } render.JSON(w, r, render.M{"status": "ok"}) if f, ok := w.(http.Flusher); ok { f.Flush() } go restartExecutable(execPath) } func updateUI(w http.ResponseWriter, r *http.Request) { err := config.UpdateUI() if err != nil { if errors.Is(err, config.ErrImcompleteConf) { log.Warnln("%s", err) render.Status(r, http.StatusNotImplemented) render.JSON(w, r, newError(fmt.Sprintf("%s", err))) } else { log.Warnln("%s", err) render.Status(r, http.StatusInternalServerError) render.JSON(w, r, newError(fmt.Sprintf("%s", err))) } return } render.JSON(w, r, render.M{"status": "ok"}) if f, ok := w.(http.Flusher); ok { f.Flush() } }