mirror of https://github.com/v2ray/v2ray-core
				
				
				
			abstract type for conf load func
							parent
							
								
									61e95e06c0
								
							
						
					
					
						commit
						1bb34bfe17
					
				|  | @ -0,0 +1,14 @@ | |||
| package cmdarg | ||||
| 
 | ||||
| import "strings" | ||||
| 
 | ||||
| type Arg []string | ||||
| 
 | ||||
| func (c *Arg) String() string { | ||||
| 	return strings.Join([]string(*c), " ") | ||||
| } | ||||
| 
 | ||||
| func (c *Arg) Set(value string) error { | ||||
| 	*c = append(*c, value) | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										34
									
								
								config.go
								
								
								
								
							
							
						
						
									
										34
									
								
								config.go
								
								
								
								
							|  | @ -4,11 +4,13 @@ package core | |||
| 
 | ||||
| import ( | ||||
| 	"io" | ||||
| 	"io/ioutil" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"github.com/golang/protobuf/proto" | ||||
| 	"v2ray.com/core/common" | ||||
| 	"v2ray.com/core/common/buf" | ||||
| 	"v2ray.com/core/common/cmdarg" | ||||
| ) | ||||
| 
 | ||||
| // ConfigFormat is a configurable format of V2Ray config file.
 | ||||
|  | @ -19,7 +21,7 @@ type ConfigFormat struct { | |||
| } | ||||
| 
 | ||||
| // ConfigLoader is a utility to load V2Ray config from external source.
 | ||||
| type ConfigLoader func(input io.Reader) (*Config, error) | ||||
| type ConfigLoader func(input interface{}) (*Config, error) | ||||
| 
 | ||||
| var ( | ||||
| 	configLoaderByName = make(map[string]*ConfigFormat) | ||||
|  | @ -54,7 +56,10 @@ func getExtension(filename string) string { | |||
| } | ||||
| 
 | ||||
| // LoadConfig loads config with given format from given source.
 | ||||
| func LoadConfig(formatName string, filename string, input io.Reader) (*Config, error) { | ||||
| // input accepts 2 different types:
 | ||||
| // * []string slice of multiple filename/url(s) to open to read
 | ||||
| // * io.Reader that reads a config content (the original way)
 | ||||
| func LoadConfig(formatName string, filename string, input interface{}) (*Config, error) { | ||||
| 	ext := getExtension(filename) | ||||
| 	if len(ext) > 0 { | ||||
| 		if f, found := configLoaderByExt[ext]; found { | ||||
|  | @ -69,12 +74,8 @@ func LoadConfig(formatName string, filename string, input io.Reader) (*Config, e | |||
| 	return nil, newError("Unable to load config in ", formatName).AtWarning() | ||||
| } | ||||
| 
 | ||||
| func loadProtobufConfig(input io.Reader) (*Config, error) { | ||||
| func loadProtobufConfig(data []byte) (*Config, error) { | ||||
| 	config := new(Config) | ||||
| 	data, err := buf.ReadAllToBytes(input) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	if err := proto.Unmarshal(data, config); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | @ -85,6 +86,23 @@ func init() { | |||
| 	common.Must(RegisterConfigLoader(&ConfigFormat{ | ||||
| 		Name:      "Protobuf", | ||||
| 		Extension: []string{"pb"}, | ||||
| 		Loader:    loadProtobufConfig, | ||||
| 		Loader: func(input interface{}) (*Config, error) { | ||||
| 			switch v := input.(type) { | ||||
| 			case cmdarg.Arg: | ||||
| 				if len(v) == 0 { | ||||
| 					return nil, newError("input has no element") | ||||
| 				} | ||||
| 				// pb type can only handle the first config
 | ||||
| 				data, err := ioutil.ReadFile(v[0]) | ||||
| 				common.Must(err) | ||||
| 				return loadProtobufConfig(data) | ||||
| 			case io.Reader: | ||||
| 				data, err := buf.ReadAllToBytes(v) | ||||
| 				common.Must(err) | ||||
| 				return loadProtobufConfig(data) | ||||
| 			default: | ||||
| 				return nil, newError("unknow type") | ||||
| 			} | ||||
| 		}, | ||||
| 	})) | ||||
| } | ||||
|  |  | |||
|  | @ -3,31 +3,35 @@ package json | |||
| //go:generate errorgen
 | ||||
| 
 | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"io" | ||||
| 	"io/ioutil" | ||||
| 
 | ||||
| 	"v2ray.com/core" | ||||
| 	"v2ray.com/core/common" | ||||
| 	"v2ray.com/core/common/buf" | ||||
| 	"v2ray.com/core/common/cmdarg" | ||||
| 	"v2ray.com/core/common/platform/ctlcmd" | ||||
| 	"v2ray.com/core/infra/conf/serial" | ||||
| ) | ||||
| 
 | ||||
| func init() { | ||||
| 	common.Must(core.RegisterConfigLoader(&core.ConfigFormat{ | ||||
| 		Name:      "JSON", | ||||
| 		Extension: []string{"json"}, | ||||
| 		Loader: func(input io.Reader) (*core.Config, error) { | ||||
| 			fns := []string{} | ||||
| 			data, _ := ioutil.ReadAll(input) | ||||
| 			json.Unmarshal(data, &fns) | ||||
| 			jsonContent, err := ctlcmd.Run(append([]string{"config"}, fns...), nil) | ||||
| 			if err != nil { | ||||
| 				return nil, newError("failed to execute v2ctl to convert config file.").Base(err).AtWarning() | ||||
| 		Loader: func(input interface{}) (*core.Config, error) { | ||||
| 			switch v := input.(type) { | ||||
| 			case cmdarg.Arg: | ||||
| 				jsonContent, err := ctlcmd.Run(append([]string{"config"}, v...), nil) | ||||
| 				if err != nil { | ||||
| 					return nil, newError("failed to execute v2ctl to convert config file.").Base(err).AtWarning() | ||||
| 				} | ||||
| 				return core.LoadConfig("protobuf", "", &buf.MultiBufferContainer{ | ||||
| 					MultiBuffer: jsonContent, | ||||
| 				}) | ||||
| 			case io.Reader: | ||||
| 				return serial.LoadJSONConfig(v) | ||||
| 			default: | ||||
| 				return nil, newError("unknow type") | ||||
| 			} | ||||
| 			return core.LoadConfig("protobuf", "", &buf.MultiBufferContainer{ | ||||
| 				MultiBuffer: jsonContent, | ||||
| 			}) | ||||
| 		}, | ||||
| 	})) | ||||
| } | ||||
|  |  | |||
|  | @ -2,7 +2,6 @@ package jsonem | |||
| 
 | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"encoding/json" | ||||
| 	"io" | ||||
| 	"io/ioutil" | ||||
| 	"net/http" | ||||
|  | @ -13,6 +12,7 @@ import ( | |||
| 	"v2ray.com/core" | ||||
| 	"v2ray.com/core/common" | ||||
| 	"v2ray.com/core/common/buf" | ||||
| 	"v2ray.com/core/common/cmdarg" | ||||
| 	"v2ray.com/core/infra/conf" | ||||
| 	"v2ray.com/core/infra/conf/serial" | ||||
| ) | ||||
|  | @ -21,21 +21,25 @@ func init() { | |||
| 	common.Must(core.RegisterConfigLoader(&core.ConfigFormat{ | ||||
| 		Name:      "JSON", | ||||
| 		Extension: []string{"json"}, | ||||
| 		Loader: func(input io.Reader) (*core.Config, error) { | ||||
| 			fns := []string{} | ||||
| 			data, _ := ioutil.ReadAll(input) | ||||
| 			json.Unmarshal(data, &fns) | ||||
| 
 | ||||
| 			cf := &conf.Config{} | ||||
| 			for _, arg := range fns { | ||||
| 				r, err := LoadArg(arg) | ||||
| 				common.Must(err) | ||||
| 				c, err := serial.DecodeJSONConfig(r) | ||||
| 				common.Must(err) | ||||
| 				cf.Override(c, arg) | ||||
| 		Loader: func(input interface{}) (*core.Config, error) { | ||||
| 			switch v := input.(type) { | ||||
| 			case cmdarg.Arg: | ||||
| 				cf := &conf.Config{} | ||||
| 				for _, arg := range v { | ||||
| 					r, err := LoadArg(arg) | ||||
| 					common.Must(err) | ||||
| 					c, err := serial.DecodeJSONConfig(r) | ||||
| 					common.Must(err) | ||||
| 					cf.Override(c, arg) | ||||
| 				} | ||||
| 				return cf.Build() | ||||
| 			case io.Reader: | ||||
| 				return serial.LoadJSONConfig(v) | ||||
| 			default: | ||||
| 				return nil, newError("unknow type") | ||||
| 			} | ||||
| 			return cf.Build() | ||||
| 		}})) | ||||
| 		}, | ||||
| 	})) | ||||
| } | ||||
| 
 | ||||
| func LoadArg(arg string) (out io.Reader, err error) { | ||||
|  |  | |||
							
								
								
									
										42
									
								
								main/main.go
								
								
								
								
							
							
						
						
									
										42
									
								
								main/main.go
								
								
								
								
							|  | @ -3,8 +3,6 @@ package main | |||
| //go:generate errorgen
 | ||||
| 
 | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"encoding/json" | ||||
| 	"flag" | ||||
| 	"fmt" | ||||
| 	"os" | ||||
|  | @ -15,26 +13,17 @@ import ( | |||
| 	"syscall" | ||||
| 
 | ||||
| 	"v2ray.com/core" | ||||
| 	"v2ray.com/core/common/cmdarg" | ||||
| 	"v2ray.com/core/common/platform" | ||||
| 	_ "v2ray.com/core/main/distro/all" | ||||
| ) | ||||
| 
 | ||||
| type CmdConfig []string | ||||
| 
 | ||||
| func (c *CmdConfig) String() string { | ||||
| 	return strings.Join([]string(*c), ",") | ||||
| } | ||||
| 
 | ||||
| func (c *CmdConfig) Set(value string) error { | ||||
| 	*c = append(*c, value) | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| var ( | ||||
| 	configFiles CmdConfig // "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.") | ||||
| 	test        = flag.Bool("test", false, "Test config file only, without launching V2Ray server.") | ||||
| 	format      = flag.String("format", "json", "Format of input file.") | ||||
| 	format      = flag.String("format", "", "Format of input file.") | ||||
| 	errNoConfig = newError("no valid config") | ||||
| ) | ||||
| 
 | ||||
| func fileExists(file string) bool { | ||||
|  | @ -42,8 +31,7 @@ func fileExists(file string) bool { | |||
| 	return err == nil && !info.IsDir() | ||||
| } | ||||
| 
 | ||||
| func getConfigFilePath() CmdConfig { | ||||
| 
 | ||||
| func getConfigFilePath() cmdarg.Arg { | ||||
| 	if len(configFiles) > 0 { | ||||
| 		return configFiles | ||||
| 	} | ||||
|  | @ -51,15 +39,15 @@ func getConfigFilePath() CmdConfig { | |||
| 	if workingDir, err := os.Getwd(); err == nil { | ||||
| 		configFile := filepath.Join(workingDir, "config.json") | ||||
| 		if fileExists(configFile) { | ||||
| 			return []string{configFile} | ||||
| 			return cmdarg.Arg{configFile} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if configFile := platform.GetConfigurationPath(); fileExists(configFile) { | ||||
| 		return []string{configFile} | ||||
| 		return cmdarg.Arg{configFile} | ||||
| 	} | ||||
| 
 | ||||
| 	return []string{} | ||||
| 	return configFiles | ||||
| } | ||||
| 
 | ||||
| func GetConfigFormat() string { | ||||
|  | @ -73,8 +61,14 @@ func GetConfigFormat() string { | |||
| 
 | ||||
| func startV2Ray() (core.Server, error) { | ||||
| 	configFiles := getConfigFilePath() | ||||
| 	fs, _ := json.Marshal(configFiles) | ||||
| 	config, err := core.LoadConfig(GetConfigFormat(), configFiles[0], bytes.NewBuffer(fs)) | ||||
| 	if len(configFiles) == 0 { | ||||
| 		if *format == "" { | ||||
| 			return nil, errNoConfig | ||||
| 		} | ||||
| 		configFiles = []string{"stdin:"} | ||||
| 	} | ||||
| 
 | ||||
| 	config, err := core.LoadConfig(GetConfigFormat(), configFiles[0], configFiles) | ||||
| 	if err != nil { | ||||
| 		return nil, newError("failed to read config files: [", configFiles.String(), "]").Base(err) | ||||
| 	} | ||||
|  | @ -96,6 +90,7 @@ func printVersion() { | |||
| 
 | ||||
| func main() { | ||||
| 	flag.Var(&configFiles, "config", "Config file for V2Ray. Multiple assign is accepted (only json). Latter ones overrides the former ones.") | ||||
| 	flag.Var(&configFiles, "c", "short alias of -config") | ||||
| 	flag.Parse() | ||||
| 
 | ||||
| 	printVersion() | ||||
|  | @ -108,6 +103,9 @@ func main() { | |||
| 	if err != nil { | ||||
| 		fmt.Println(err.Error()) | ||||
| 		// Configuration error. Exit with a special value to prevent systemd from restarting.
 | ||||
| 		if err == errNoConfig { | ||||
| 			flag.PrintDefaults() | ||||
| 		} | ||||
| 		os.Exit(23) | ||||
| 	} | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 vcptr
						vcptr