mirror of
https://github.com/v2fly/v2ray-core.git
synced 2024-12-21 09:36:34 -05:00
rearrange loader
This commit is contained in:
parent
3b4a4607e5
commit
f14eb97e3c
19
config.go
19
config.go
@ -4,14 +4,13 @@ package core
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/golang/protobuf/proto"
|
"github.com/golang/protobuf/proto"
|
||||||
"v2ray.com/core/common"
|
"v2ray.com/core/common"
|
||||||
"v2ray.com/core/common/buf"
|
"v2ray.com/core/common/buf"
|
||||||
"v2ray.com/core/common/cmdarg"
|
"v2ray.com/core/common/cmdarg"
|
||||||
|
"v2ray.com/core/main/confloader"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ConfigFormat is a configurable format of V2Ray config file.
|
// ConfigFormat is a configurable format of V2Ray config file.
|
||||||
@ -90,18 +89,10 @@ func init() {
|
|||||||
Loader: func(input interface{}) (*Config, error) {
|
Loader: func(input interface{}) (*Config, error) {
|
||||||
switch v := input.(type) {
|
switch v := input.(type) {
|
||||||
case cmdarg.Arg:
|
case cmdarg.Arg:
|
||||||
if len(v) == 0 {
|
r, err := confloader.LoadConfig(v[0])
|
||||||
return nil, newError("input has no element")
|
common.Must(err)
|
||||||
}
|
data, err := buf.ReadAllToBytes(r)
|
||||||
var data []byte
|
common.Must(err)
|
||||||
var rerr error
|
|
||||||
// pb type can only handle the first config
|
|
||||||
if v[0] == "stdin:" {
|
|
||||||
data, rerr = buf.ReadAllToBytes(os.Stdin)
|
|
||||||
} else {
|
|
||||||
data, rerr = ioutil.ReadFile(v[0])
|
|
||||||
}
|
|
||||||
common.Must(rerr)
|
|
||||||
return loadProtobufConfig(data)
|
return loadProtobufConfig(data)
|
||||||
case io.Reader:
|
case io.Reader:
|
||||||
data, err := buf.ReadAllToBytes(v)
|
data, err := buf.ReadAllToBytes(v)
|
||||||
|
30
main/confloader/confloader.go
Normal file
30
main/confloader/confloader.go
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
package confloader
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
type configFileLoader func(string) (io.Reader, error)
|
||||||
|
type extconfigLoader func([]string) (io.Reader, error)
|
||||||
|
|
||||||
|
var (
|
||||||
|
EffectiveConfigFileLoader configFileLoader
|
||||||
|
EffectiveExtConfigLoader extconfigLoader
|
||||||
|
)
|
||||||
|
|
||||||
|
func LoadConfig(file string) (io.Reader, error) {
|
||||||
|
if EffectiveConfigFileLoader == nil {
|
||||||
|
newError("external config module not loaded, reading from stdin").AtInfo().WriteToLog()
|
||||||
|
return os.Stdin, nil
|
||||||
|
}
|
||||||
|
return EffectiveConfigFileLoader(file)
|
||||||
|
}
|
||||||
|
|
||||||
|
func LoadExtConfig(files []string) (io.Reader, error) {
|
||||||
|
if EffectiveExtConfigLoader == nil {
|
||||||
|
return nil, newError("external config module not loaded").AtError()
|
||||||
|
}
|
||||||
|
|
||||||
|
return EffectiveExtConfigLoader(files)
|
||||||
|
}
|
9
main/confloader/errors.generated.go
Normal file
9
main/confloader/errors.generated.go
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package confloader
|
||||||
|
|
||||||
|
import "v2ray.com/core/common/errors"
|
||||||
|
|
||||||
|
type errPathObjHolder struct{}
|
||||||
|
|
||||||
|
func newError(values ...interface{}) *errors.Error {
|
||||||
|
return errors.New(values...).WithPathObj(errPathObjHolder{})
|
||||||
|
}
|
9
main/confloader/external/errors.generated.go
vendored
Normal file
9
main/confloader/external/errors.generated.go
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package external
|
||||||
|
|
||||||
|
import "v2ray.com/core/common/errors"
|
||||||
|
|
||||||
|
type errPathObjHolder struct{}
|
||||||
|
|
||||||
|
func newError(values ...interface{}) *errors.Error {
|
||||||
|
return errors.New(values...).WithPathObj(errPathObjHolder{})
|
||||||
|
}
|
86
main/confloader/external/external.go
vendored
Normal file
86
main/confloader/external/external.go
vendored
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
package external
|
||||||
|
|
||||||
|
//go:generate errorgen
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"v2ray.com/core/common/buf"
|
||||||
|
"v2ray.com/core/common/platform/ctlcmd"
|
||||||
|
"v2ray.com/core/main/confloader"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ConfigLoader(arg string) (out io.Reader, err error) {
|
||||||
|
|
||||||
|
var data []byte
|
||||||
|
if strings.HasPrefix(arg, "http://") || strings.HasPrefix(arg, "https://") {
|
||||||
|
data, err = FetchHTTPContent(arg)
|
||||||
|
} else if arg == "stdin:" {
|
||||||
|
data, err = ioutil.ReadAll(os.Stdin)
|
||||||
|
} else {
|
||||||
|
data, err = ioutil.ReadFile(arg)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
out = bytes.NewBuffer(data)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func FetchHTTPContent(target string) ([]byte, error) {
|
||||||
|
|
||||||
|
parsedTarget, err := url.Parse(target)
|
||||||
|
if err != nil {
|
||||||
|
return nil, newError("invalid URL: ", target).Base(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if s := strings.ToLower(parsedTarget.Scheme); s != "http" && s != "https" {
|
||||||
|
return nil, newError("invalid scheme: ", parsedTarget.Scheme)
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &http.Client{
|
||||||
|
Timeout: 30 * time.Second,
|
||||||
|
}
|
||||||
|
resp, err := client.Do(&http.Request{
|
||||||
|
Method: "GET",
|
||||||
|
URL: parsedTarget,
|
||||||
|
Close: true,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, newError("failed to dial to ", target).Base(err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode != 200 {
|
||||||
|
return nil, newError("unexpected HTTP status code: ", resp.StatusCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
content, err := buf.ReadAllToBytes(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, newError("failed to read HTTP response").Base(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return content, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExtConfigLoader(files []string) (io.Reader, error) {
|
||||||
|
buf, err := ctlcmd.Run(append([]string{"config"}, files...), os.Stdin)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.NewReader(buf.String()), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
confloader.EffectiveConfigFileLoader = ConfigLoader
|
||||||
|
confloader.EffectiveExtConfigLoader = ExtConfigLoader
|
||||||
|
}
|
@ -58,4 +58,7 @@ import (
|
|||||||
_ "v2ray.com/core/main/json"
|
_ "v2ray.com/core/main/json"
|
||||||
// The following line loads JSON internally
|
// The following line loads JSON internally
|
||||||
// _ "v2ray.com/core/main/jsonem"
|
// _ "v2ray.com/core/main/jsonem"
|
||||||
|
|
||||||
|
// Load config from file or http(s)
|
||||||
|
_ "v2ray.com/core/main/confloader/external"
|
||||||
)
|
)
|
||||||
|
@ -4,14 +4,12 @@ package json
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
"os"
|
|
||||||
|
|
||||||
"v2ray.com/core"
|
"v2ray.com/core"
|
||||||
"v2ray.com/core/common"
|
"v2ray.com/core/common"
|
||||||
"v2ray.com/core/common/buf"
|
|
||||||
"v2ray.com/core/common/cmdarg"
|
"v2ray.com/core/common/cmdarg"
|
||||||
"v2ray.com/core/common/platform/ctlcmd"
|
|
||||||
"v2ray.com/core/infra/conf/serial"
|
"v2ray.com/core/infra/conf/serial"
|
||||||
|
"v2ray.com/core/main/confloader"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -21,13 +19,11 @@ func init() {
|
|||||||
Loader: func(input interface{}) (*core.Config, error) {
|
Loader: func(input interface{}) (*core.Config, error) {
|
||||||
switch v := input.(type) {
|
switch v := input.(type) {
|
||||||
case cmdarg.Arg:
|
case cmdarg.Arg:
|
||||||
jsonContent, err := ctlcmd.Run(append([]string{"config"}, v...), os.Stdin)
|
r, err := confloader.LoadExtConfig(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, newError("failed to execute v2ctl to convert config file.").Base(err).AtWarning()
|
return nil, newError("failed to execute v2ctl to convert config file.").Base(err).AtWarning()
|
||||||
}
|
}
|
||||||
return core.LoadConfig("protobuf", "", &buf.MultiBufferContainer{
|
return core.LoadConfig("protobuf", "", r)
|
||||||
MultiBuffer: jsonContent,
|
|
||||||
})
|
|
||||||
case io.Reader:
|
case io.Reader:
|
||||||
return serial.LoadJSONConfig(v)
|
return serial.LoadJSONConfig(v)
|
||||||
default:
|
default:
|
||||||
|
@ -1,21 +1,14 @@
|
|||||||
package jsonem
|
package jsonem
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"v2ray.com/core"
|
"v2ray.com/core"
|
||||||
"v2ray.com/core/common"
|
"v2ray.com/core/common"
|
||||||
"v2ray.com/core/common/buf"
|
|
||||||
"v2ray.com/core/common/cmdarg"
|
"v2ray.com/core/common/cmdarg"
|
||||||
"v2ray.com/core/infra/conf"
|
"v2ray.com/core/infra/conf"
|
||||||
"v2ray.com/core/infra/conf/serial"
|
"v2ray.com/core/infra/conf/serial"
|
||||||
|
"v2ray.com/core/main/confloader"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -28,7 +21,7 @@ func init() {
|
|||||||
cf := &conf.Config{}
|
cf := &conf.Config{}
|
||||||
for _, arg := range v {
|
for _, arg := range v {
|
||||||
newError("Reading config: ", arg).AtInfo().WriteToLog()
|
newError("Reading config: ", arg).AtInfo().WriteToLog()
|
||||||
r, err := LoadArg(arg)
|
r, err := confloader.LoadConfig(arg)
|
||||||
common.Must(err)
|
common.Must(err)
|
||||||
c, err := serial.DecodeJSONConfig(r)
|
c, err := serial.DecodeJSONConfig(r)
|
||||||
common.Must(err)
|
common.Must(err)
|
||||||
@ -43,57 +36,3 @@ func init() {
|
|||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadArg(arg string) (out io.Reader, err error) {
|
|
||||||
|
|
||||||
var data []byte
|
|
||||||
if strings.HasPrefix(arg, "http://") || strings.HasPrefix(arg, "https://") {
|
|
||||||
data, err = FetchHTTPContent(arg)
|
|
||||||
} else if arg == "stdin:" {
|
|
||||||
data, err = ioutil.ReadAll(os.Stdin)
|
|
||||||
} else {
|
|
||||||
data, err = ioutil.ReadFile(arg)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
out = bytes.NewBuffer(data)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func FetchHTTPContent(target string) ([]byte, error) {
|
|
||||||
|
|
||||||
parsedTarget, err := url.Parse(target)
|
|
||||||
if err != nil {
|
|
||||||
return nil, newError("invalid URL: ", target).Base(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if s := strings.ToLower(parsedTarget.Scheme); s != "http" && s != "https" {
|
|
||||||
return nil, newError("invalid scheme: ", parsedTarget.Scheme)
|
|
||||||
}
|
|
||||||
|
|
||||||
client := &http.Client{
|
|
||||||
Timeout: 30 * time.Second,
|
|
||||||
}
|
|
||||||
resp, err := client.Do(&http.Request{
|
|
||||||
Method: "GET",
|
|
||||||
URL: parsedTarget,
|
|
||||||
Close: true,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, newError("failed to dial to ", target).Base(err)
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
if resp.StatusCode != 200 {
|
|
||||||
return nil, newError("unexpected HTTP status code: ", resp.StatusCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
content, err := buf.ReadAllToBytes(resp.Body)
|
|
||||||
if err != nil {
|
|
||||||
return nil, newError("failed to read HTTP response").Base(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return content, nil
|
|
||||||
}
|
|
||||||
|
21
main/main.go
21
main/main.go
@ -22,7 +22,7 @@ var (
|
|||||||
configFiles cmdarg.Arg // "Config file for V2Ray.", the option is customed type, parse in main
|
configFiles cmdarg.Arg // "Config file for V2Ray.", the option is customed type, parse in main
|
||||||
version = flag.Bool("version", false, "Show current version of V2Ray.")
|
version = flag.Bool("version", false, "Show current version of V2Ray.")
|
||||||
test = flag.Bool("test", false, "Test config file only, without launching V2Ray server.")
|
test = flag.Bool("test", false, "Test config file only, without launching V2Ray server.")
|
||||||
format = flag.String("format", "", "Format of input file.")
|
format = flag.String("format", "json", "Format of input file.")
|
||||||
errNoConfig = newError("no valid config")
|
errNoConfig = newError("no valid config")
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -31,23 +31,23 @@ func fileExists(file string) bool {
|
|||||||
return err == nil && !info.IsDir()
|
return err == nil && !info.IsDir()
|
||||||
}
|
}
|
||||||
|
|
||||||
func getConfigFilePath() cmdarg.Arg {
|
func getConfigFilePath() (cmdarg.Arg, error) {
|
||||||
if len(configFiles) > 0 {
|
if len(configFiles) > 0 {
|
||||||
return configFiles
|
return configFiles, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if workingDir, err := os.Getwd(); err == nil {
|
if workingDir, err := os.Getwd(); err == nil {
|
||||||
configFile := filepath.Join(workingDir, "config.json")
|
configFile := filepath.Join(workingDir, "config.json")
|
||||||
if fileExists(configFile) {
|
if fileExists(configFile) {
|
||||||
return cmdarg.Arg{configFile}
|
return cmdarg.Arg{configFile}, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if configFile := platform.GetConfigurationPath(); fileExists(configFile) {
|
if configFile := platform.GetConfigurationPath(); fileExists(configFile) {
|
||||||
return cmdarg.Arg{configFile}
|
return cmdarg.Arg{configFile}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return configFiles
|
return cmdarg.Arg{"stdin:"}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetConfigFormat() string {
|
func GetConfigFormat() string {
|
||||||
@ -60,12 +60,9 @@ func GetConfigFormat() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func startV2Ray() (core.Server, error) {
|
func startV2Ray() (core.Server, error) {
|
||||||
configFiles := getConfigFilePath()
|
configFiles, err := getConfigFilePath()
|
||||||
if len(configFiles) == 0 {
|
if err != nil {
|
||||||
if *format == "" {
|
return nil, err
|
||||||
return nil, errNoConfig
|
|
||||||
}
|
|
||||||
configFiles = []string{"stdin:"}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
config, err := core.LoadConfig(GetConfigFormat(), configFiles[0], configFiles)
|
config, err := core.LoadConfig(GetConfigFormat(), configFiles[0], configFiles)
|
||||||
|
Loading…
Reference in New Issue
Block a user