Adjust JSON & TOML & YAML

This commit is contained in:
RPRX 2020-12-25 18:53:17 +08:00
parent 3d7e86efba
commit ffd8fd1d8a
9 changed files with 32 additions and 75 deletions

View File

@ -85,6 +85,8 @@ func LoadJSONConfig(reader io.Reader) (*core.Config, error) {
return pbConfig, nil return pbConfig, nil
} }
// DecodeTOMLConfig reads from reader and decode the config into *conf.Config
// using github.com/BurntSushi/toml and map to convert toml to json.
func DecodeTOMLConfig(reader io.Reader) (*conf.Config, error) { func DecodeTOMLConfig(reader io.Reader) (*conf.Config, error) {
tomlFile, err := ioutil.ReadAll(reader) tomlFile, err := ioutil.ReadAll(reader)
if err != nil { if err != nil {
@ -92,15 +94,13 @@ func DecodeTOMLConfig(reader io.Reader) (*conf.Config, error) {
} }
configMap := make(map[string]interface{}) configMap := make(map[string]interface{})
if _, err := toml.Decode(string(tomlFile), &configMap); err != nil { if _, err := toml.Decode(string(tomlFile), &configMap); err != nil {
return nil, newError("failed to convert TOML to Map").Base(err) return nil, newError("failed to convert toml to map").Base(err)
} }
jsonFile, err := json.Marshal(&configMap) jsonFile, err := json.Marshal(&configMap)
if err != nil { if err != nil {
return nil, newError("failed to convert Map to JSON").Base(err) return nil, newError("failed to convert map to json").Base(err)
} }
return DecodeJSONConfig(bytes.NewReader(jsonFile)) return DecodeJSONConfig(bytes.NewReader(jsonFile))
@ -121,10 +121,8 @@ func LoadTOMLConfig(reader io.Reader) (*core.Config, error) {
} }
// DecodeYAMLConfig reads from reader and decode the config into *conf.Config // DecodeYAMLConfig reads from reader and decode the config into *conf.Config
// using github.com/ghodss/yaml to convert yaml to json // using github.com/ghodss/yaml to convert yaml to json.
// syntax error could be detected.
func DecodeYAMLConfig(reader io.Reader) (*conf.Config, error) { func DecodeYAMLConfig(reader io.Reader) (*conf.Config, error) {
yamlFile, err := ioutil.ReadAll(reader) yamlFile, err := ioutil.ReadAll(reader)
if err != nil { if err != nil {
return nil, newError("failed to read config file").Base(err) return nil, newError("failed to read config file").Base(err)
@ -132,7 +130,7 @@ func DecodeYAMLConfig(reader io.Reader) (*conf.Config, error) {
jsonFile, err := yaml.YAMLToJSON(yamlFile) jsonFile, err := yaml.YAMLToJSON(yamlFile)
if err != nil { if err != nil {
return nil, newError("failed to read config file").Base(err) return nil, newError("failed to convert yaml to json").Base(err)
} }
return DecodeJSONConfig(bytes.NewReader(jsonFile)) return DecodeJSONConfig(bytes.NewReader(jsonFile))

View File

@ -57,18 +57,14 @@ import (
_ "github.com/xtls/xray-core/transport/internet/headers/wechat" _ "github.com/xtls/xray-core/transport/internet/headers/wechat"
_ "github.com/xtls/xray-core/transport/internet/headers/wireguard" _ "github.com/xtls/xray-core/transport/internet/headers/wireguard"
// JSON config support. Choose only one from the two below. // JSON & TOML & YAML
// The following line loads JSON from xctl _ "github.com/xtls/xray-core/main/json"
// _ "github.com/xtls/xray-core/main/json"
// The following line loads JSON internally
_ "github.com/xtls/xray-core/main/jsonem"
_ "github.com/xtls/xray-core/main/yaml"
_ "github.com/xtls/xray-core/main/toml" _ "github.com/xtls/xray-core/main/toml"
_ "github.com/xtls/xray-core/main/yaml"
// Load config from file or http(s) // Load config from file or http(s)
_ "github.com/xtls/xray-core/main/confloader/external" _ "github.com/xtls/xray-core/main/confloader/external"
// commands // Commands
_ "github.com/xtls/xray-core/main/commands/all" _ "github.com/xtls/xray-core/main/commands/all"
) )

View File

@ -1,38 +0,0 @@
package json
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
import (
"io"
"os"
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/cmdarg"
core "github.com/xtls/xray-core/core"
"github.com/xtls/xray-core/main/confloader"
)
func init() {
common.Must(core.RegisterConfigLoader(&core.ConfigFormat{
Name: "JSON",
Extension: []string{"json"},
Loader: func(input interface{}) (*core.Config, error) {
switch v := input.(type) {
case cmdarg.Arg:
r, err := confloader.LoadExtConfig(v, os.Stdin)
if err != nil {
return nil, newError("failed to execute xctl to convert config file.").Base(err).AtWarning()
}
return core.LoadConfig("protobuf", "", r)
case io.Reader:
r, err := confloader.LoadExtConfig([]string{"stdin:"}, os.Stdin)
if err != nil {
return nil, newError("failed to execute xctl to convert config file.").Base(err).AtWarning()
}
return core.LoadConfig("protobuf", "", r)
default:
return nil, newError("unknown type")
}
},
}))
}

View File

@ -1,4 +1,4 @@
package jsonem package json
import ( import (
"io" "io"

View File

@ -1,9 +0,0 @@
package jsonem
import "github.com/xtls/xray-core/common/errors"
type errPathObjHolder struct{}
func newError(values ...interface{}) *errors.Error {
return errors.New(values...).WithPathObj(errPathObjHolder{})
}

View File

@ -66,17 +66,19 @@ func executeRun(cmd *base.Command, args []string) {
printVersion() printVersion()
server, err := startXray() server, err := startXray()
if err != nil { if err != nil {
base.Fatalf("Failed to start: %s", err) fmt.Println("Failed to start:", err)
// Configuration error. Exit with a special value to prevent systemd from restarting.
os.Exit(23)
} }
if *test { if *test {
fmt.Println("Configuration OK.") fmt.Println("Configuration OK.")
base.SetExitStatus(0) os.Exit(0)
base.Exit()
} }
if err := server.Start(); err != nil { if err := server.Start(); err != nil {
base.Fatalf("Failed to start: %s", err) fmt.Println("Failed to start:", err)
os.Exit(-1)
} }
defer server.Close() defer server.Close()
@ -152,10 +154,10 @@ func getConfigFilePath() cmdarg.Arg {
func getConfigFormat() string { func getConfigFormat() string {
switch strings.ToLower(*format) { switch strings.ToLower(*format) {
case "yaml", "yml":
return "yaml"
case "pb", "protobuf": case "pb", "protobuf":
return "protobuf" return "protobuf"
case "yaml", "yml":
return "yaml"
case "toml": case "toml":
return "toml" return "toml"
default: default:

View File

@ -22,9 +22,13 @@ func init() {
for i, arg := range v { for i, arg := range v {
newError("Reading config: ", arg).AtInfo().WriteToLog() newError("Reading config: ", arg).AtInfo().WriteToLog()
r, err := confloader.LoadConfig(arg) r, err := confloader.LoadConfig(arg)
common.Must(err) if err != nil {
return nil, newError("failed to read config: ", arg).Base(err)
}
c, err := serial.DecodeTOMLConfig(r) c, err := serial.DecodeTOMLConfig(r)
common.Must(err) if err != nil {
return nil, newError("failed to decode config: ", arg).Base(err)
}
if i == 0 { if i == 0 {
// This ensure even if the muti-json parser do not support a setting, // This ensure even if the muti-json parser do not support a setting,
// It is still respected automatically for the first configure file // It is still respected automatically for the first configure file

View File

@ -22,9 +22,13 @@ func init() {
for i, arg := range v { for i, arg := range v {
newError("Reading config: ", arg).AtInfo().WriteToLog() newError("Reading config: ", arg).AtInfo().WriteToLog()
r, err := confloader.LoadConfig(arg) r, err := confloader.LoadConfig(arg)
common.Must(err) if err != nil {
return nil, newError("failed to read config: ", arg).Base(err)
}
c, err := serial.DecodeYAMLConfig(r) c, err := serial.DecodeYAMLConfig(r)
common.Must(err) if err != nil {
return nil, newError("failed to decode config: ", arg).Base(err)
}
if i == 0 { if i == 0 {
// This ensure even if the muti-json parser do not support a setting, // This ensure even if the muti-json parser do not support a setting,
// It is still respected automatically for the first configure file // It is still respected automatically for the first configure file

View File

@ -137,7 +137,7 @@ func TestHTTPConnectionHeader(t *testing.T) {
func TestDomainSocket(t *testing.T) { func TestDomainSocket(t *testing.T) {
if runtime.GOOS == "windows" || runtime.GOOS == "android" { if runtime.GOOS == "windows" || runtime.GOOS == "android" {
t.Skip("Not supported on windows and android") t.Skip("Not supported on windows or android")
return return
} }
tcpServer := tcp.Server{ tcpServer := tcp.Server{