Add TOML Support (#98)

This commit is contained in:
秋のかえで 2020-12-25 03:11:32 +08:00 committed by GitHub
parent 09f9d03fb6
commit f073456ac0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 96 additions and 0 deletions

1
go.mod
View file

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

1
go.sum
View file

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

View file

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

View file

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

View file

@ -154,6 +154,8 @@ func getConfigFormat() string {
switch strings.ToLower(*format) {
case "pb", "protobuf":
return "protobuf"
case "toml":
return "toml"
default:
return "json"
}

View file

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

44
main/toml/toml.go Normal file
View file

@ -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")
}
},
}))
}