mirror of
https://github.com/XTLS/Xray-core.git
synced 2025-04-29 16:58:34 +00:00
v1.0.0
This commit is contained in:
parent
47d23e9972
commit
c7f7c08ead
711 changed files with 82154 additions and 2 deletions
9
common/platform/ctlcmd/attr_other.go
Normal file
9
common/platform/ctlcmd/attr_other.go
Normal file
|
@ -0,0 +1,9 @@
|
|||
// +build !windows
|
||||
|
||||
package ctlcmd
|
||||
|
||||
import "syscall"
|
||||
|
||||
func getSysProcAttr() *syscall.SysProcAttr {
|
||||
return nil
|
||||
}
|
11
common/platform/ctlcmd/attr_windows.go
Normal file
11
common/platform/ctlcmd/attr_windows.go
Normal file
|
@ -0,0 +1,11 @@
|
|||
// +build windows
|
||||
|
||||
package ctlcmd
|
||||
|
||||
import "syscall"
|
||||
|
||||
func getSysProcAttr() *syscall.SysProcAttr {
|
||||
return &syscall.SysProcAttr{
|
||||
HideWindow: true,
|
||||
}
|
||||
}
|
50
common/platform/ctlcmd/ctlcmd.go
Normal file
50
common/platform/ctlcmd/ctlcmd.go
Normal file
|
@ -0,0 +1,50 @@
|
|||
package ctlcmd
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"github.com/xtls/xray-core/v1/common/buf"
|
||||
"github.com/xtls/xray-core/v1/common/platform"
|
||||
)
|
||||
|
||||
//go:generate go run github.com/xtls/xray-core/v1/common/errors/errorgen
|
||||
|
||||
func Run(args []string, input io.Reader) (buf.MultiBuffer, error) {
|
||||
xctl := platform.GetToolLocation("xctl")
|
||||
if _, err := os.Stat(xctl); err != nil {
|
||||
return nil, newError("xctl doesn't exist").Base(err)
|
||||
}
|
||||
|
||||
var errBuffer buf.MultiBufferContainer
|
||||
var outBuffer buf.MultiBufferContainer
|
||||
|
||||
cmd := exec.Command(xctl, args...)
|
||||
cmd.Stderr = &errBuffer
|
||||
cmd.Stdout = &outBuffer
|
||||
cmd.SysProcAttr = getSysProcAttr()
|
||||
if input != nil {
|
||||
cmd.Stdin = input
|
||||
}
|
||||
|
||||
if err := cmd.Start(); err != nil {
|
||||
return nil, newError("failed to start xctl").Base(err)
|
||||
}
|
||||
|
||||
if err := cmd.Wait(); err != nil {
|
||||
msg := "failed to execute xctl"
|
||||
if errBuffer.Len() > 0 {
|
||||
msg += ": \n" + strings.TrimSpace(errBuffer.MultiBuffer.String())
|
||||
}
|
||||
return nil, newError(msg).Base(err)
|
||||
}
|
||||
|
||||
// log stderr, info message
|
||||
if !errBuffer.IsEmpty() {
|
||||
newError("<xctl message> \n", strings.TrimSpace(errBuffer.MultiBuffer.String())).AtInfo().WriteToLog()
|
||||
}
|
||||
|
||||
return outBuffer.MultiBuffer, nil
|
||||
}
|
9
common/platform/ctlcmd/errors.generated.go
Normal file
9
common/platform/ctlcmd/errors.generated.go
Normal file
|
@ -0,0 +1,9 @@
|
|||
package ctlcmd
|
||||
|
||||
import "github.com/xtls/xray-core/v1/common/errors"
|
||||
|
||||
type errPathObjHolder struct{}
|
||||
|
||||
func newError(values ...interface{}) *errors.Error {
|
||||
return errors.New(values...).WithPathObj(errPathObjHolder{})
|
||||
}
|
44
common/platform/filesystem/file.go
Normal file
44
common/platform/filesystem/file.go
Normal file
|
@ -0,0 +1,44 @@
|
|||
package filesystem
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/xtls/xray-core/v1/common/buf"
|
||||
"github.com/xtls/xray-core/v1/common/platform"
|
||||
)
|
||||
|
||||
type FileReaderFunc func(path string) (io.ReadCloser, error)
|
||||
|
||||
var NewFileReader FileReaderFunc = func(path string) (io.ReadCloser, error) {
|
||||
return os.Open(path)
|
||||
}
|
||||
|
||||
func ReadFile(path string) ([]byte, error) {
|
||||
reader, err := NewFileReader(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer reader.Close()
|
||||
|
||||
return buf.ReadAllToBytes(reader)
|
||||
}
|
||||
|
||||
func ReadAsset(file string) ([]byte, error) {
|
||||
return ReadFile(platform.GetAssetLocation(file))
|
||||
}
|
||||
|
||||
func CopyFile(dst string, src string) error {
|
||||
bytes, err := ReadFile(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
f, err := os.OpenFile(dst, os.O_CREATE|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
_, err = f.Write(bytes)
|
||||
return err
|
||||
}
|
44
common/platform/others.go
Normal file
44
common/platform/others.go
Normal file
|
@ -0,0 +1,44 @@
|
|||
// +build !windows
|
||||
|
||||
package platform
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
func ExpandEnv(s string) string {
|
||||
return os.ExpandEnv(s)
|
||||
}
|
||||
|
||||
func LineSeparator() string {
|
||||
return "\n"
|
||||
}
|
||||
|
||||
func GetToolLocation(file string) string {
|
||||
const name = "xray.location.tool"
|
||||
toolPath := EnvFlag{Name: name, AltName: NormalizeEnvName(name)}.GetValue(getExecutableDir)
|
||||
return filepath.Join(toolPath, file)
|
||||
}
|
||||
|
||||
// GetAssetLocation search for `file` in certain locations
|
||||
func GetAssetLocation(file string) string {
|
||||
const name = "xray.location.asset"
|
||||
assetPath := NewEnvFlag(name).GetValue(getExecutableDir)
|
||||
defPath := filepath.Join(assetPath, file)
|
||||
for _, p := range []string{
|
||||
defPath,
|
||||
filepath.Join("/usr/local/share/xray/", file),
|
||||
filepath.Join("/usr/share/xray/", file),
|
||||
} {
|
||||
if _, err := os.Stat(p); os.IsNotExist(err) {
|
||||
continue
|
||||
}
|
||||
|
||||
// asset found
|
||||
return p
|
||||
}
|
||||
|
||||
// asset not found, let the caller throw out the error
|
||||
return defPath
|
||||
}
|
86
common/platform/platform.go
Normal file
86
common/platform/platform.go
Normal file
|
@ -0,0 +1,86 @@
|
|||
package platform // import "github.com/xtls/xray-core/v1/common/platform"
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type EnvFlag struct {
|
||||
Name string
|
||||
AltName string
|
||||
}
|
||||
|
||||
func NewEnvFlag(name string) EnvFlag {
|
||||
return EnvFlag{
|
||||
Name: name,
|
||||
AltName: NormalizeEnvName(name),
|
||||
}
|
||||
}
|
||||
|
||||
func (f EnvFlag) GetValue(defaultValue func() string) string {
|
||||
if v, found := os.LookupEnv(f.Name); found {
|
||||
return v
|
||||
}
|
||||
if len(f.AltName) > 0 {
|
||||
if v, found := os.LookupEnv(f.AltName); found {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
return defaultValue()
|
||||
}
|
||||
|
||||
func (f EnvFlag) GetValueAsInt(defaultValue int) int {
|
||||
useDefaultValue := false
|
||||
s := f.GetValue(func() string {
|
||||
useDefaultValue = true
|
||||
return ""
|
||||
})
|
||||
if useDefaultValue {
|
||||
return defaultValue
|
||||
}
|
||||
v, err := strconv.ParseInt(s, 10, 32)
|
||||
if err != nil {
|
||||
return defaultValue
|
||||
}
|
||||
return int(v)
|
||||
}
|
||||
|
||||
func NormalizeEnvName(name string) string {
|
||||
return strings.ReplaceAll(strings.ToUpper(strings.TrimSpace(name)), ".", "_")
|
||||
}
|
||||
|
||||
func getExecutableDir() string {
|
||||
exec, err := os.Executable()
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return filepath.Dir(exec)
|
||||
}
|
||||
|
||||
func getExecutableSubDir(dir string) func() string {
|
||||
return func() string {
|
||||
return filepath.Join(getExecutableDir(), dir)
|
||||
}
|
||||
}
|
||||
|
||||
func GetPluginDirectory() string {
|
||||
const name = "xray.location.plugin"
|
||||
pluginDir := NewEnvFlag(name).GetValue(getExecutableSubDir("plugins"))
|
||||
return pluginDir
|
||||
}
|
||||
|
||||
func GetConfigurationPath() string {
|
||||
const name = "xray.location.config"
|
||||
configPath := NewEnvFlag(name).GetValue(getExecutableDir)
|
||||
return filepath.Join(configPath, "config.json")
|
||||
}
|
||||
|
||||
// GetConfDirPath reads "xray.location.confdir"
|
||||
func GetConfDirPath() string {
|
||||
const name = "xray.location.confdir"
|
||||
configPath := NewEnvFlag(name).GetValue(func() string { return "" })
|
||||
return configPath
|
||||
}
|
65
common/platform/platform_test.go
Normal file
65
common/platform/platform_test.go
Normal file
|
@ -0,0 +1,65 @@
|
|||
package platform_test
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
"github.com/xtls/xray-core/v1/common"
|
||||
. "github.com/xtls/xray-core/v1/common/platform"
|
||||
)
|
||||
|
||||
func TestNormalizeEnvName(t *testing.T) {
|
||||
cases := []struct {
|
||||
input string
|
||||
output string
|
||||
}{
|
||||
{
|
||||
input: "a",
|
||||
output: "A",
|
||||
},
|
||||
{
|
||||
input: "a.a",
|
||||
output: "A_A",
|
||||
},
|
||||
{
|
||||
input: "A.A.B",
|
||||
output: "A_A_B",
|
||||
},
|
||||
}
|
||||
for _, test := range cases {
|
||||
if v := NormalizeEnvName(test.input); v != test.output {
|
||||
t.Error("unexpected output: ", v, " want ", test.output)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestEnvFlag(t *testing.T) {
|
||||
if v := (EnvFlag{
|
||||
Name: "xxxxx.y",
|
||||
}.GetValueAsInt(10)); v != 10 {
|
||||
t.Error("env value: ", v)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAssetLocation(t *testing.T) {
|
||||
exec, err := os.Executable()
|
||||
common.Must(err)
|
||||
|
||||
loc := GetAssetLocation("t")
|
||||
if filepath.Dir(loc) != filepath.Dir(exec) {
|
||||
t.Error("asset dir: ", loc, " not in ", exec)
|
||||
}
|
||||
|
||||
os.Setenv("xray.location.asset", "/xray")
|
||||
if runtime.GOOS == "windows" {
|
||||
if v := GetAssetLocation("t"); v != "\\xray\\t" {
|
||||
t.Error("asset loc: ", v)
|
||||
}
|
||||
} else {
|
||||
if v := GetAssetLocation("t"); v != "/xray/t" {
|
||||
t.Error("asset loc: ", v)
|
||||
}
|
||||
}
|
||||
}
|
27
common/platform/windows.go
Normal file
27
common/platform/windows.go
Normal file
|
@ -0,0 +1,27 @@
|
|||
// +build windows
|
||||
|
||||
package platform
|
||||
|
||||
import "path/filepath"
|
||||
|
||||
func ExpandEnv(s string) string {
|
||||
// TODO
|
||||
return s
|
||||
}
|
||||
|
||||
func LineSeparator() string {
|
||||
return "\r\n"
|
||||
}
|
||||
|
||||
func GetToolLocation(file string) string {
|
||||
const name = "xray.location.tool"
|
||||
toolPath := EnvFlag{Name: name, AltName: NormalizeEnvName(name)}.GetValue(getExecutableDir)
|
||||
return filepath.Join(toolPath, file+".exe")
|
||||
}
|
||||
|
||||
// GetAssetLocation search for `file` in the excutable dir
|
||||
func GetAssetLocation(file string) string {
|
||||
const name = "xray.location.asset"
|
||||
assetPath := NewEnvFlag(name).GetValue(getExecutableDir)
|
||||
return filepath.Join(assetPath, file)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue