Feature: add custom ui support in API

This commit is contained in:
Dreamacro 2018-12-20 01:29:13 +08:00
parent afc4644dd1
commit a6bbc67afb
3 changed files with 33 additions and 2 deletions

View File

@ -6,6 +6,7 @@ import (
"net" "net"
"net/url" "net/url"
"os" "os"
"path/filepath"
"strings" "strings"
adapters "github.com/Dreamacro/clash/adapters/outbound" adapters "github.com/Dreamacro/clash/adapters/outbound"
@ -27,8 +28,9 @@ type General struct {
AllowLan bool `json:"allow-lan"` AllowLan bool `json:"allow-lan"`
Mode T.Mode `json:"mode"` Mode T.Mode `json:"mode"`
LogLevel log.LogLevel `json:"log-level"` LogLevel log.LogLevel `json:"log-level"`
ExternalController string `json:"external-controller,omitempty"` ExternalController string
Secret string `json:"secret,omitempty"` ExternalUI string
Secret string
} }
// DNS config // DNS config
@ -66,6 +68,7 @@ type rawConfig struct {
Mode T.Mode `yaml:"mode"` Mode T.Mode `yaml:"mode"`
LogLevel log.LogLevel `yaml:"log-level"` LogLevel log.LogLevel `yaml:"log-level"`
ExternalController string `yaml:"external-controller"` ExternalController string `yaml:"external-controller"`
ExternalUI string `yaml:"external-ui"`
Secret string `yaml:"secret"` Secret string `yaml:"secret"`
DNS rawDNS `yaml:"dns"` DNS rawDNS `yaml:"dns"`
@ -145,10 +148,19 @@ func parseGeneral(cfg *rawConfig) (*General, error) {
redirPort := cfg.RedirPort redirPort := cfg.RedirPort
allowLan := cfg.AllowLan allowLan := cfg.AllowLan
externalController := cfg.ExternalController externalController := cfg.ExternalController
externalUI := cfg.ExternalUI
secret := cfg.Secret secret := cfg.Secret
mode := cfg.Mode mode := cfg.Mode
logLevel := cfg.LogLevel logLevel := cfg.LogLevel
if !filepath.IsAbs(externalUI) {
externalUI = filepath.Join(C.Path.HomeDir(), externalUI)
}
if _, err := os.Stat(externalUI); os.IsNotExist(err) {
return nil, fmt.Errorf("external-ui: %s not exist", externalUI)
}
general := &General{ general := &General{
Port: port, Port: port,
SocksPort: socksPort, SocksPort: socksPort,
@ -157,6 +169,7 @@ func parseGeneral(cfg *rawConfig) (*General, error) {
Mode: mode, Mode: mode,
LogLevel: logLevel, LogLevel: logLevel,
ExternalController: externalController, ExternalController: externalController,
ExternalUI: externalUI,
Secret: secret, Secret: secret,
} }
return general, nil return general, nil

View File

@ -12,6 +12,10 @@ func Parse() error {
return err return err
} }
if cfg.General.ExternalUI != "" {
route.SetUIPath(cfg.General.ExternalUI)
}
if cfg.General.ExternalController != "" { if cfg.General.ExternalController != "" {
go route.Start(cfg.General.ExternalController, cfg.General.Secret) go route.Start(cfg.General.ExternalController, cfg.General.Secret)
} }

View File

@ -17,6 +17,8 @@ import (
var ( var (
serverSecret = "" serverSecret = ""
serverAddr = "" serverAddr = ""
uiPath = ""
) )
type Traffic struct { type Traffic struct {
@ -24,6 +26,10 @@ type Traffic struct {
Down int64 `json:"down"` Down int64 `json:"down"`
} }
func SetUIPath(path string) {
uiPath = path
}
func Start(addr string, secret string) { func Start(addr string, secret string) {
if serverAddr != "" { if serverAddr != "" {
return return
@ -49,6 +55,14 @@ func Start(addr string, secret string) {
r.Mount("/proxies", proxyRouter()) r.Mount("/proxies", proxyRouter())
r.Mount("/rules", ruleRouter()) r.Mount("/rules", ruleRouter())
if uiPath != "" {
fs := http.StripPrefix("/ui", http.FileServer(http.Dir(uiPath)))
r.Get("/ui", http.RedirectHandler("/ui/", 301).ServeHTTP)
r.Get("/ui/*", func(w http.ResponseWriter, r *http.Request) {
fs.ServeHTTP(w, r)
})
}
log.Infoln("RESTful API listening at: %s", addr) log.Infoln("RESTful API listening at: %s", addr)
err := http.ListenAndServe(addr, r) err := http.ListenAndServe(addr, r)
if err != nil { if err != nil {