1
0
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:
vcptr 2019-12-14 22:24:32 +08:00
parent 904db6bd61
commit 1e76123a4c
9 changed files with 118 additions and 96 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,4 +1,4 @@
package external package jsonem
import "v2ray.com/core/common/errors" import "v2ray.com/core/common/errors"

View File

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

View File

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