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  }