65 lines
1.5 KiB
Go
65 lines
1.5 KiB
Go
package app
|
|
|
|
import (
|
|
"encoding/json"
|
|
"io"
|
|
"net/http"
|
|
"os"
|
|
"strings"
|
|
"syscall"
|
|
)
|
|
|
|
func handleRoutesUpdate(w http.ResponseWriter, r *http.Request) {
|
|
if r.Method != http.MethodPost {
|
|
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
|
|
return
|
|
}
|
|
var body struct {
|
|
Iface string `json:"iface"`
|
|
}
|
|
if r.Body != nil {
|
|
defer r.Body.Close()
|
|
_ = json.NewDecoder(io.LimitReader(r.Body, 1<<20)).Decode(&body)
|
|
}
|
|
iface := strings.TrimSpace(body.Iface)
|
|
iface = normalizePreferredIface(iface)
|
|
if iface == "" {
|
|
iface, _ = resolveTrafficIface(loadTrafficModeState().PreferredIface)
|
|
}
|
|
|
|
lock, err := os.OpenFile(lockFile, os.O_CREATE|os.O_RDWR, 0o644)
|
|
if err != nil {
|
|
http.Error(w, "lock open error", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
if err := syscall.Flock(int(lock.Fd()), syscall.LOCK_EX|syscall.LOCK_NB); err != nil {
|
|
writeJSON(w, http.StatusOK, map[string]any{
|
|
"ok": false,
|
|
"message": "routes update already running",
|
|
})
|
|
lock.Close()
|
|
return
|
|
}
|
|
|
|
go func(iface string, lockFile *os.File) {
|
|
defer syscall.Flock(int(lockFile.Fd()), syscall.LOCK_UN)
|
|
defer lockFile.Close()
|
|
|
|
res := routesUpdate(iface)
|
|
evKind := "routes_update_done"
|
|
if !res.OK {
|
|
evKind = "routes_update_error"
|
|
}
|
|
events.push(evKind, map[string]any{
|
|
"ok": res.OK,
|
|
"message": res.Message,
|
|
"ip_cnt": res.ExitCode, // reuse exitCode to pass ip_count if set
|
|
})
|
|
}(iface, lock)
|
|
|
|
writeJSON(w, http.StatusOK, map[string]any{
|
|
"ok": true,
|
|
"message": "routes update started",
|
|
})
|
|
}
|