From f073456ac0f112e2412f9b06b5648d49bd9fecf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A7=8B=E3=81=AE=E3=81=8B=E3=81=88=E3=81=A7?= Date: Fri, 25 Dec 2020 03:11:32 +0800 Subject: [PATCH] Add TOML Support (#98) --- go.mod | 1 + go.sum | 1 + infra/conf/serial/loader.go | 37 +++++++++++++++++++++++++++++ main/distro/all/all.go | 2 ++ main/run.go | 2 ++ main/toml/errors.generated.go | 9 +++++++ main/toml/toml.go | 44 +++++++++++++++++++++++++++++++++++ 7 files changed, 96 insertions(+) create mode 100644 main/toml/errors.generated.go create mode 100644 main/toml/toml.go diff --git a/go.mod b/go.mod index 7179abd9..5906486a 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/xtls/xray-core go 1.15 require ( + github.com/BurntSushi/toml v0.3.1 github.com/dgryski/go-metro v0.0.0-20200812162917-85c65e2d0165 // indirect github.com/golang/mock v1.4.4 github.com/golang/protobuf v1.4.3 diff --git a/go.sum b/go.sum index d176f143..72190eb4 100644 --- a/go.sum +++ b/go.sum @@ -7,6 +7,7 @@ dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBr dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4= dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= diff --git a/infra/conf/serial/loader.go b/infra/conf/serial/loader.go index 03075d96..b0f9f128 100644 --- a/infra/conf/serial/loader.go +++ b/infra/conf/serial/loader.go @@ -4,7 +4,9 @@ import ( "bytes" "encoding/json" "io" + "io/ioutil" + "github.com/BurntSushi/toml" "github.com/xtls/xray-core/common/errors" "github.com/xtls/xray-core/core" "github.com/xtls/xray-core/infra/conf" @@ -80,3 +82,38 @@ func LoadJSONConfig(reader io.Reader) (*core.Config, error) { return pbConfig, nil } + +func DecodeTOMLConfig(reader io.Reader) (*conf.Config, error) { + tomlFile, err := ioutil.ReadAll(reader) + if err != nil { + return nil, newError("failed to read config file").Base(err) + } + + configMap := make(map[string]interface{}) + + if _, err := toml.Decode(string(tomlFile), &configMap); err != nil { + return nil, newError("failed to convert TOML to Map").Base(err) + } + + jsonFile, err := json.Marshal(&configMap) + + if err != nil { + return nil, newError("failed to convert Map to JSON").Base(err) + } + + return DecodeJSONConfig(bytes.NewReader(jsonFile)) +} + +func LoadTOMLConfig(reader io.Reader) (*core.Config, error) { + tomlConfig, err := DecodeTOMLConfig(reader) + if err != nil { + return nil, err + } + + pbConfig, err := tomlConfig.Build() + if err != nil { + return nil, newError("failed to parse toml config").Base(err) + } + + return pbConfig, nil +} diff --git a/main/distro/all/all.go b/main/distro/all/all.go index ee7babf8..cc7ec2f0 100644 --- a/main/distro/all/all.go +++ b/main/distro/all/all.go @@ -63,6 +63,8 @@ import ( // The following line loads JSON internally _ "github.com/xtls/xray-core/main/jsonem" + _ "github.com/xtls/xray-core/main/toml" + // Load config from file or http(s) _ "github.com/xtls/xray-core/main/confloader/external" diff --git a/main/run.go b/main/run.go index 3c11ee0c..33fefaa1 100644 --- a/main/run.go +++ b/main/run.go @@ -154,6 +154,8 @@ func getConfigFormat() string { switch strings.ToLower(*format) { case "pb", "protobuf": return "protobuf" + case "toml": + return "toml" default: return "json" } diff --git a/main/toml/errors.generated.go b/main/toml/errors.generated.go new file mode 100644 index 00000000..0bad202e --- /dev/null +++ b/main/toml/errors.generated.go @@ -0,0 +1,9 @@ +package toml + +import "github.com/xtls/xray-core/common/errors" + +type errPathObjHolder struct{} + +func newError(values ...interface{}) *errors.Error { + return errors.New(values...).WithPathObj(errPathObjHolder{}) +} diff --git a/main/toml/toml.go b/main/toml/toml.go new file mode 100644 index 00000000..f6fbfefc --- /dev/null +++ b/main/toml/toml.go @@ -0,0 +1,44 @@ +package toml + +import ( + "io" + + "github.com/xtls/xray-core/common" + "github.com/xtls/xray-core/common/cmdarg" + "github.com/xtls/xray-core/core" + "github.com/xtls/xray-core/infra/conf" + "github.com/xtls/xray-core/infra/conf/serial" + "github.com/xtls/xray-core/main/confloader" +) + +func init() { + common.Must(core.RegisterConfigLoader(&core.ConfigFormat{ + Name: "TOML", + Extension: []string{"toml"}, + Loader: func(input interface{}) (*core.Config, error) { + switch v := input.(type) { + case cmdarg.Arg: + cf := &conf.Config{} + for i, arg := range v { + newError("Reading config: ", arg).AtInfo().WriteToLog() + r, err := confloader.LoadConfig(arg) + common.Must(err) + c, err := serial.DecodeTOMLConfig(r) + common.Must(err) + if i == 0 { + // This ensure even if the muti-json parser do not support a setting, + // It is still respected automatically for the first configure file + *cf = *c + continue + } + cf.Override(c, arg) + } + return cf.Build() + case io.Reader: + return serial.LoadTOMLConfig(v) + default: + return nil, newError("unknow type") + } + }, + })) +}