github.com/igoogolx/clash@v1.19.8/hub/route/configs.go (about) 1 package route 2 3 import ( 4 "net/http" 5 "path/filepath" 6 7 "github.com/igoogolx/clash/component/resolver" 8 "github.com/igoogolx/clash/config" 9 C "github.com/igoogolx/clash/constant" 10 "github.com/igoogolx/clash/hub/executor" 11 "github.com/igoogolx/clash/listener" 12 "github.com/igoogolx/clash/log" 13 "github.com/igoogolx/clash/tunnel" 14 15 "github.com/go-chi/chi/v5" 16 "github.com/go-chi/render" 17 "github.com/samber/lo" 18 ) 19 20 func configRouter() http.Handler { 21 r := chi.NewRouter() 22 r.Get("/", getConfigs) 23 r.Put("/", updateConfigs) 24 r.Patch("/", patchConfigs) 25 return r 26 } 27 28 func getConfigs(w http.ResponseWriter, r *http.Request) { 29 general := executor.GetGeneral() 30 render.JSON(w, r, general) 31 } 32 33 func patchConfigs(w http.ResponseWriter, r *http.Request) { 34 general := struct { 35 Port *int `json:"port"` 36 SocksPort *int `json:"socks-port"` 37 RedirPort *int `json:"redir-port"` 38 TProxyPort *int `json:"tproxy-port"` 39 MixedPort *int `json:"mixed-port"` 40 AllowLan *bool `json:"allow-lan"` 41 BindAddress *string `json:"bind-address"` 42 Mode *tunnel.TunnelMode `json:"mode"` 43 LogLevel *log.LogLevel `json:"log-level"` 44 IPv6 *bool `json:"ipv6"` 45 }{} 46 if err := render.DecodeJSON(r.Body, &general); err != nil { 47 render.Status(r, http.StatusBadRequest) 48 render.JSON(w, r, ErrBadRequest) 49 return 50 } 51 52 if general.Mode != nil { 53 tunnel.SetMode(*general.Mode) 54 } 55 56 if general.LogLevel != nil { 57 log.SetLevel(*general.LogLevel) 58 } 59 60 if general.IPv6 != nil { 61 resolver.DisableIPv6 = !*general.IPv6 62 } 63 64 if general.AllowLan != nil { 65 listener.SetAllowLan(*general.AllowLan) 66 } 67 68 if general.BindAddress != nil { 69 listener.SetBindAddress(*general.BindAddress) 70 } 71 72 ports := listener.GetPorts() 73 ports.Port = lo.FromPtrOr(general.Port, ports.Port) 74 ports.SocksPort = lo.FromPtrOr(general.SocksPort, ports.SocksPort) 75 ports.RedirPort = lo.FromPtrOr(general.RedirPort, ports.RedirPort) 76 ports.TProxyPort = lo.FromPtrOr(general.TProxyPort, ports.TProxyPort) 77 ports.MixedPort = lo.FromPtrOr(general.MixedPort, ports.MixedPort) 78 79 listener.ReCreatePortsListeners(*ports, tunnel.TCPIn(), tunnel.UDPIn()) 80 81 render.NoContent(w, r) 82 } 83 84 func updateConfigs(w http.ResponseWriter, r *http.Request) { 85 req := struct { 86 Path string `json:"path"` 87 Payload string `json:"payload"` 88 }{} 89 if err := render.DecodeJSON(r.Body, &req); err != nil { 90 render.Status(r, http.StatusBadRequest) 91 render.JSON(w, r, ErrBadRequest) 92 return 93 } 94 95 force := r.URL.Query().Get("force") == "true" 96 var cfg *config.Config 97 var err error 98 99 if req.Payload != "" { 100 cfg, err = executor.ParseWithBytes([]byte(req.Payload)) 101 if err != nil { 102 render.Status(r, http.StatusBadRequest) 103 render.JSON(w, r, newError(err.Error())) 104 return 105 } 106 } else { 107 if req.Path == "" { 108 req.Path = C.Path.Config() 109 } 110 if !filepath.IsAbs(req.Path) { 111 render.Status(r, http.StatusBadRequest) 112 render.JSON(w, r, newError("path is not a absolute path")) 113 return 114 } 115 116 cfg, err = executor.ParseWithPath(req.Path) 117 if err != nil { 118 render.Status(r, http.StatusBadRequest) 119 render.JSON(w, r, newError(err.Error())) 120 return 121 } 122 } 123 124 executor.ApplyConfig(cfg, force) 125 render.NoContent(w, r) 126 }