Add: selector and proxys & rules router
This commit is contained in:
@ -3,65 +3,47 @@ package hub
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/Dreamacro/clash/tunnel"
|
||||
|
||||
"github.com/go-chi/chi"
|
||||
"github.com/go-chi/render"
|
||||
)
|
||||
|
||||
type Configs struct {
|
||||
Proxys []Proxy `json:"proxys"`
|
||||
Rules []Rule `json:"rules"`
|
||||
}
|
||||
|
||||
type Proxy struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type Rule struct {
|
||||
Name string `json:"name"`
|
||||
Payload string `json:"type"`
|
||||
}
|
||||
|
||||
func configRouter() http.Handler {
|
||||
r := chi.NewRouter()
|
||||
r.Get("/", getConfig)
|
||||
r.Put("/", updateConfig)
|
||||
return r
|
||||
}
|
||||
|
||||
func getConfig(w http.ResponseWriter, r *http.Request) {
|
||||
rulesCfg, proxysCfg := tun.Config()
|
||||
type General struct {
|
||||
Mode string `json:mode`
|
||||
}
|
||||
|
||||
var (
|
||||
rules []Rule
|
||||
proxys []Proxy
|
||||
)
|
||||
|
||||
for _, rule := range rulesCfg {
|
||||
rules = append(rules, Rule{
|
||||
Name: rule.RuleType().String(),
|
||||
Payload: rule.Payload(),
|
||||
})
|
||||
}
|
||||
|
||||
for _, proxy := range proxysCfg {
|
||||
proxys = append(proxys, Proxy{Name: proxy.Name()})
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
render.JSON(w, r, Configs{
|
||||
Rules: rules,
|
||||
Proxys: proxys,
|
||||
})
|
||||
var modeMapping = map[string]tunnel.Mode{
|
||||
"global": tunnel.Global,
|
||||
"rule": tunnel.Rule,
|
||||
"direct": tunnel.Direct,
|
||||
}
|
||||
|
||||
func updateConfig(w http.ResponseWriter, r *http.Request) {
|
||||
err := tun.UpdateConfig()
|
||||
general := &General{}
|
||||
err := render.DecodeJSON(r.Body, general)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
render.JSON(w, r, Error{
|
||||
Error: err.Error(),
|
||||
Error: "Format error",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
mode, ok := modeMapping[general.Mode]
|
||||
if !ok {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
render.JSON(w, r, Error{
|
||||
Error: "Mode error",
|
||||
})
|
||||
return
|
||||
}
|
||||
tun.SetMode(mode)
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
}
|
||||
|
129
hub/proxys.go
Normal file
129
hub/proxys.go
Normal file
@ -0,0 +1,129 @@
|
||||
package hub
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
A "github.com/Dreamacro/clash/adapters"
|
||||
C "github.com/Dreamacro/clash/constant"
|
||||
|
||||
"github.com/go-chi/chi"
|
||||
"github.com/go-chi/render"
|
||||
)
|
||||
|
||||
func proxyRouter() http.Handler {
|
||||
r := chi.NewRouter()
|
||||
r.Get("/", getProxys)
|
||||
r.Get("/{name}", getProxy)
|
||||
r.Put("/{name}", updateProxy)
|
||||
return r
|
||||
}
|
||||
|
||||
type SampleProxy struct {
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
type Selector struct {
|
||||
Type string `json:"type"`
|
||||
Now string `json:"now"`
|
||||
All []string `json:"all"`
|
||||
}
|
||||
|
||||
type URLTest struct {
|
||||
Type string `json:"type"`
|
||||
Now string `json:"now"`
|
||||
}
|
||||
|
||||
func transformProxy(proxy C.Proxy) interface{} {
|
||||
t := proxy.Type()
|
||||
switch t {
|
||||
case C.Selector:
|
||||
selector := proxy.(*A.Selector)
|
||||
return Selector{
|
||||
Type: t.String(),
|
||||
Now: selector.Now(),
|
||||
All: selector.All(),
|
||||
}
|
||||
case C.URLTest:
|
||||
return URLTest{
|
||||
Type: t.String(),
|
||||
Now: proxy.(*A.URLTest).Now(),
|
||||
}
|
||||
default:
|
||||
return SampleProxy{
|
||||
Type: proxy.Type().String(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type GetProxysResponse struct {
|
||||
Proxys map[string]interface{} `json:"proxys"`
|
||||
}
|
||||
|
||||
func getProxys(w http.ResponseWriter, r *http.Request) {
|
||||
_, rawProxys := tun.Config()
|
||||
proxys := make(map[string]interface{})
|
||||
for name, proxy := range rawProxys {
|
||||
proxys[name] = transformProxy(proxy)
|
||||
}
|
||||
render.JSON(w, r, GetProxysResponse{Proxys: proxys})
|
||||
}
|
||||
|
||||
func getProxy(w http.ResponseWriter, r *http.Request) {
|
||||
name := chi.URLParam(r, "name")
|
||||
_, proxys := tun.Config()
|
||||
proxy, exist := proxys[name]
|
||||
if !exist {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
render.JSON(w, r, Error{
|
||||
Error: "Proxy not found",
|
||||
})
|
||||
return
|
||||
}
|
||||
render.JSON(w, r, transformProxy(proxy))
|
||||
}
|
||||
|
||||
type UpdateProxyRequest struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
func updateProxy(w http.ResponseWriter, r *http.Request) {
|
||||
req := UpdateProxyRequest{}
|
||||
if err := render.DecodeJSON(r.Body, &req); err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
render.JSON(w, r, Error{
|
||||
Error: "Format error",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
name := chi.URLParam(r, "name")
|
||||
_, proxys := tun.Config()
|
||||
proxy, exist := proxys[name]
|
||||
if !exist {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
render.JSON(w, r, Error{
|
||||
Error: "Proxy not found",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
selector, ok := proxy.(*A.Selector)
|
||||
if !ok {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
render.JSON(w, r, Error{
|
||||
Error: "Proxy can't update",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if err := selector.Set(req.Name); err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
render.JSON(w, r, Error{
|
||||
Error: fmt.Sprintf("Selector update error: %s", err.Error()),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
}
|
53
hub/rules.go
Normal file
53
hub/rules.go
Normal file
@ -0,0 +1,53 @@
|
||||
package hub
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/go-chi/chi"
|
||||
"github.com/go-chi/render"
|
||||
)
|
||||
|
||||
func ruleRouter() http.Handler {
|
||||
r := chi.NewRouter()
|
||||
r.Get("/", getRules)
|
||||
r.Put("/", updateRules)
|
||||
return r
|
||||
}
|
||||
|
||||
type Rule struct {
|
||||
Name string `json:"name"`
|
||||
Payload string `json:"type"`
|
||||
}
|
||||
|
||||
type GetRulesResponse struct {
|
||||
Rules []Rule `json:"rules"`
|
||||
}
|
||||
|
||||
func getRules(w http.ResponseWriter, r *http.Request) {
|
||||
rulesCfg, _ := tun.Config()
|
||||
|
||||
var rules []Rule
|
||||
for _, rule := range rulesCfg {
|
||||
rules = append(rules, Rule{
|
||||
Name: rule.RuleType().String(),
|
||||
Payload: rule.Payload(),
|
||||
})
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
render.JSON(w, r, GetRulesResponse{
|
||||
Rules: rules,
|
||||
})
|
||||
}
|
||||
|
||||
func updateRules(w http.ResponseWriter, r *http.Request) {
|
||||
err := tun.UpdateConfig()
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
render.JSON(w, r, Error{
|
||||
Error: err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
}
|
@ -31,6 +31,8 @@ func NewHub(addr string) {
|
||||
r.Get("/traffic", traffic)
|
||||
r.Get("/logs", getLogs)
|
||||
r.Mount("/configs", configRouter())
|
||||
r.Mount("/proxys", proxyRouter())
|
||||
r.Mount("/rules", ruleRouter())
|
||||
|
||||
err := http.ListenAndServe(addr, r)
|
||||
if err != nil {
|
||||
|
Reference in New Issue
Block a user