Add: selector and proxys & rules router

This commit is contained in:
Dreamacro
2018-07-12 23:28:38 +08:00
parent 39b45513af
commit 0eef9bbf5d
12 changed files with 390 additions and 47 deletions

View File

@ -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
View 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
View 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)
}

View File

@ -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 {