Browse Source

Add TOML Support (#98)

秋のかえで 4 năm trước cách đây
mục cha
commit
f073456ac0
7 tập tin đã thay đổi với 96 bổ sung0 xóa
  1. 1 0
      go.mod
  2. 1 0
      go.sum
  3. 37 0
      infra/conf/serial/loader.go
  4. 2 0
      main/distro/all/all.go
  5. 2 0
      main/run.go
  6. 9 0
      main/toml/errors.generated.go
  7. 44 0
      main/toml/toml.go

+ 1 - 0
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

+ 1 - 0
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=

+ 37 - 0
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
+}

+ 2 - 0
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"
 

+ 2 - 0
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"
 	}

+ 9 - 0
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{})
+}

+ 44 - 0
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")
+			}
+		},
+	}))
+}