mirror of
https://github.com/v2fly/v2ray-core.git
synced 2024-12-30 05:56:54 -05:00
main loads multiple
This commit is contained in:
parent
904db6bd61
commit
1e76123a4c
@ -39,8 +39,10 @@ func Run(args []string, input io.Reader) (buf.MultiBuffer, error) {
|
|||||||
}
|
}
|
||||||
return nil, newError(msg).Base(err)
|
return nil, newError(msg).Base(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// log stderr, info message
|
||||||
if !errBuffer.IsEmpty() {
|
if !errBuffer.IsEmpty() {
|
||||||
newError("v2ctl > ", errBuffer.String()).AtInfo().WriteToLog()
|
newError("v2ctl > \n", errBuffer.MultiBuffer.String()).AtInfo().WriteToLog()
|
||||||
}
|
}
|
||||||
|
|
||||||
return outBuffer.MultiBuffer, nil
|
return outBuffer.MultiBuffer, nil
|
||||||
|
@ -16,7 +16,7 @@ import (
|
|||||||
type MconfigCommand struct{}
|
type MconfigCommand struct{}
|
||||||
|
|
||||||
func (c *MconfigCommand) Name() string {
|
func (c *MconfigCommand) Name() string {
|
||||||
return "mconfig"
|
return "config"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *MconfigCommand) Description() Description {
|
func (c *MconfigCommand) Description() Description {
|
@ -1,19 +0,0 @@
|
|||||||
package confloader
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
)
|
|
||||||
|
|
||||||
type configFileLoader func(string) (io.ReadCloser, error)
|
|
||||||
|
|
||||||
var (
|
|
||||||
EffectiveConfigFileLoader configFileLoader
|
|
||||||
)
|
|
||||||
|
|
||||||
func LoadConfig(file string) (io.ReadCloser, error) {
|
|
||||||
if EffectiveConfigFileLoader == nil {
|
|
||||||
return os.Stdin, nil
|
|
||||||
}
|
|
||||||
return EffectiveConfigFileLoader(file)
|
|
||||||
}
|
|
48
main/confloader/external/external.go
vendored
48
main/confloader/external/external.go
vendored
@ -1,48 +0,0 @@
|
|||||||
package external
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"v2ray.com/core/common/buf"
|
|
||||||
"v2ray.com/core/common/platform/ctlcmd"
|
|
||||||
"v2ray.com/core/main/confloader"
|
|
||||||
)
|
|
||||||
|
|
||||||
//go:generate errorgen
|
|
||||||
|
|
||||||
func loadConfigFile(configFile string) (io.ReadCloser, error) {
|
|
||||||
if configFile == "stdin:" {
|
|
||||||
return os.Stdin, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if strings.HasPrefix(configFile, "http://") || strings.HasPrefix(configFile, "https://") {
|
|
||||||
content, err := ctlcmd.Run([]string{"fetch", configFile}, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &buf.MultiBufferContainer{
|
|
||||||
MultiBuffer: content,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
fixedFile := os.ExpandEnv(configFile)
|
|
||||||
file, err := os.Open(fixedFile)
|
|
||||||
if err != nil {
|
|
||||||
return nil, newError("config file not readable").Base(err)
|
|
||||||
}
|
|
||||||
defer file.Close()
|
|
||||||
|
|
||||||
content, err := buf.ReadFrom(file)
|
|
||||||
if err != nil {
|
|
||||||
return nil, newError("failed to load config file: ", fixedFile).Base(err).AtWarning()
|
|
||||||
}
|
|
||||||
return &buf.MultiBufferContainer{
|
|
||||||
MultiBuffer: content,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
confloader.EffectiveConfigFileLoader = loadConfigFile
|
|
||||||
}
|
|
@ -58,7 +58,4 @@ 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"
|
|
||||||
)
|
)
|
||||||
|
@ -3,7 +3,9 @@ package json
|
|||||||
//go:generate errorgen
|
//go:generate errorgen
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"io"
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
|
||||||
"v2ray.com/core"
|
"v2ray.com/core"
|
||||||
"v2ray.com/core/common"
|
"v2ray.com/core/common"
|
||||||
@ -16,7 +18,10 @@ func init() {
|
|||||||
Name: "JSON",
|
Name: "JSON",
|
||||||
Extension: []string{"json"},
|
Extension: []string{"json"},
|
||||||
Loader: func(input io.Reader) (*core.Config, error) {
|
Loader: func(input io.Reader) (*core.Config, error) {
|
||||||
jsonContent, err := ctlcmd.Run([]string{"config"}, input)
|
fns := []string{}
|
||||||
|
data, _ := ioutil.ReadAll(input)
|
||||||
|
json.Unmarshal(data, &fns)
|
||||||
|
jsonContent, err := ctlcmd.Run(append([]string{"config"}, fns...), nil)
|
||||||
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()
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package external
|
package jsonem
|
||||||
|
|
||||||
import "v2ray.com/core/common/errors"
|
import "v2ray.com/core/common/errors"
|
||||||
|
|
@ -1,8 +1,19 @@
|
|||||||
package jsonem
|
package jsonem
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"v2ray.com/core"
|
"v2ray.com/core"
|
||||||
"v2ray.com/core/common"
|
"v2ray.com/core/common"
|
||||||
|
"v2ray.com/core/common/buf"
|
||||||
|
"v2ray.com/core/infra/conf"
|
||||||
"v2ray.com/core/infra/conf/serial"
|
"v2ray.com/core/infra/conf/serial"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -10,6 +21,71 @@ func init() {
|
|||||||
common.Must(core.RegisterConfigLoader(&core.ConfigFormat{
|
common.Must(core.RegisterConfigLoader(&core.ConfigFormat{
|
||||||
Name: "JSON",
|
Name: "JSON",
|
||||||
Extension: []string{"json"},
|
Extension: []string{"json"},
|
||||||
Loader: serial.LoadJSONConfig,
|
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)
|
||||||
|
}
|
||||||
|
return cf.Build()
|
||||||
|
}}))
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {
|
||||||
|
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
|
||||||
}
|
}
|
||||||
|
49
main/main.go
49
main/main.go
@ -3,6 +3,8 @@ package main
|
|||||||
//go:generate errorgen
|
//go:generate errorgen
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
@ -14,15 +16,25 @@ import (
|
|||||||
|
|
||||||
"v2ray.com/core"
|
"v2ray.com/core"
|
||||||
"v2ray.com/core/common/platform"
|
"v2ray.com/core/common/platform"
|
||||||
"v2ray.com/core/main/confloader"
|
|
||||||
_ "v2ray.com/core/main/distro/all"
|
_ "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 (
|
var (
|
||||||
configFile = flag.String("config", "", "Config file for V2Ray.")
|
configFiles CmdConfig // "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", "json", "Format of input file.")
|
format = flag.String("format", "json", "Format of input file.")
|
||||||
)
|
)
|
||||||
|
|
||||||
func fileExists(file string) bool {
|
func fileExists(file string) bool {
|
||||||
@ -30,23 +42,24 @@ func fileExists(file string) bool {
|
|||||||
return err == nil && !info.IsDir()
|
return err == nil && !info.IsDir()
|
||||||
}
|
}
|
||||||
|
|
||||||
func getConfigFilePath() string {
|
func getConfigFilePath() CmdConfig {
|
||||||
if len(*configFile) > 0 {
|
|
||||||
return *configFile
|
if len(configFiles) > 0 {
|
||||||
|
return configFiles
|
||||||
}
|
}
|
||||||
|
|
||||||
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 configFile
|
return []string{configFile}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if configFile := platform.GetConfigurationPath(); fileExists(configFile) {
|
if configFile := platform.GetConfigurationPath(); fileExists(configFile) {
|
||||||
return configFile
|
return []string{configFile}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ""
|
return []string{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetConfigFormat() string {
|
func GetConfigFormat() string {
|
||||||
@ -59,16 +72,11 @@ func GetConfigFormat() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func startV2Ray() (core.Server, error) {
|
func startV2Ray() (core.Server, error) {
|
||||||
configFile := getConfigFilePath()
|
configFiles := getConfigFilePath()
|
||||||
configInput, err := confloader.LoadConfig(configFile)
|
fs, _ := json.Marshal(configFiles)
|
||||||
|
config, err := core.LoadConfig(GetConfigFormat(), configFiles[0], bytes.NewBuffer(fs))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, newError("failed to load config: ", configFile).Base(err)
|
return nil, newError("failed to read config files: [", configFiles.String(), "]").Base(err)
|
||||||
}
|
|
||||||
defer configInput.Close()
|
|
||||||
|
|
||||||
config, err := core.LoadConfig(GetConfigFormat(), configFile, configInput)
|
|
||||||
if err != nil {
|
|
||||||
return nil, newError("failed to read config file: ", configFile).Base(err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
server, err := core.New(config)
|
server, err := core.New(config)
|
||||||
@ -87,6 +95,7 @@ func printVersion() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
flag.Var(&configFiles, "config", "Config file for V2Ray. Multiple assign is accepted (only json). Latter ones overrides the former ones.")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
printVersion()
|
printVersion()
|
||||||
|
Loading…
Reference in New Issue
Block a user