mirror of
https://github.com/v2fly/v2ray-core
synced 2024-02-27 03:18:06 +00:00
Merge branch 'master' into v5
This commit is contained in:
@@ -6,9 +6,12 @@ import (
|
||||
"fmt"
|
||||
"go/build"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/v2fly/v2ray-core/v4/common/errors"
|
||||
)
|
||||
@@ -123,3 +126,39 @@ func GetGOPATH() string {
|
||||
}
|
||||
return GOPATH
|
||||
}
|
||||
|
||||
// FetchHTTPContent dials http(s) for remote content
|
||||
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 != http.StatusOK {
|
||||
return nil, newError("unexpected HTTP status code: ", resp.StatusCode)
|
||||
}
|
||||
|
||||
content, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, newError("failed to read HTTP response").Base(err)
|
||||
}
|
||||
|
||||
return content, nil
|
||||
}
|
||||
|
||||
@@ -10,10 +10,16 @@ import (
|
||||
|
||||
type FileReaderFunc func(path string) (io.ReadCloser, error)
|
||||
|
||||
type FileWriterFunc func(path string) (io.WriteCloser, error)
|
||||
|
||||
var NewFileReader FileReaderFunc = func(path string) (io.ReadCloser, error) {
|
||||
return os.Open(path)
|
||||
}
|
||||
|
||||
var NewFileWriter FileWriterFunc = func(path string) (io.WriteCloser, error) {
|
||||
return os.Create(path)
|
||||
}
|
||||
|
||||
func ReadFile(path string) ([]byte, error) {
|
||||
reader, err := NewFileReader(path)
|
||||
if err != nil {
|
||||
@@ -24,6 +30,16 @@ func ReadFile(path string) ([]byte, error) {
|
||||
return buf.ReadAllToBytes(reader)
|
||||
}
|
||||
|
||||
func WriteFile(path string, payload []byte) error {
|
||||
writer, err := NewFileWriter(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer writer.Close()
|
||||
|
||||
return buf.WriteAllBytes(writer, payload)
|
||||
}
|
||||
|
||||
func ReadAsset(file string) ([]byte, error) {
|
||||
return ReadFile(platform.GetAssetLocation(file))
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
package platform
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
@@ -32,7 +34,7 @@ func GetAssetLocation(file string) string {
|
||||
filepath.Join("/usr/share/v2ray/", file),
|
||||
filepath.Join("/opt/share/v2ray/", file),
|
||||
} {
|
||||
if _, err := os.Stat(p); os.IsNotExist(err) {
|
||||
if _, err := os.Stat(p); err != nil && errors.Is(err, fs.ErrNotExist) {
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package platform_test
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
@@ -43,6 +45,33 @@ func TestEnvFlag(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestWrongErrorCheckOnOSStat is a test to detect the misuse of error handling
|
||||
// in os.Stat, which will lead to failure to find & read geoip & geosite files.
|
||||
func TestWrongErrorCheckOnOSStat(t *testing.T) {
|
||||
theExpectedDir := filepath.Join("usr", "local", "share", "v2ray")
|
||||
getAssetLocation := func(file string) string {
|
||||
for _, p := range []string{
|
||||
filepath.Join(theExpectedDir, file),
|
||||
} {
|
||||
// errors.Is(fs.ErrNotExist, err) is a mistake supposed Not to
|
||||
// be discovered by the Go runtime, which will lead to failure to
|
||||
// find & read geoip & geosite files.
|
||||
// The correct code is `errors.Is(err, fs.ErrNotExist)`
|
||||
if _, err := os.Stat(p); err != nil && errors.Is(fs.ErrNotExist, err) {
|
||||
continue
|
||||
}
|
||||
// asset found
|
||||
return p
|
||||
}
|
||||
return filepath.Join("the", "wrong", "path", "not-exist.txt")
|
||||
}
|
||||
|
||||
notExist := getAssetLocation("not-exist.txt")
|
||||
if filepath.Dir(notExist) != theExpectedDir {
|
||||
t.Error("asset dir:", notExist, "not in", theExpectedDir)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAssetLocation(t *testing.T) {
|
||||
exec, err := os.Executable()
|
||||
common.Must(err)
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/v2fly/VSign/insmgr"
|
||||
@@ -18,16 +19,17 @@ type EmbeddedHashProtectedLoader struct {
|
||||
}
|
||||
|
||||
func (e EmbeddedHashProtectedLoader) VerifyAndLoad(filename string) ([]byte, error) {
|
||||
filecontent, err := filesystem.ReadFile(platform.GetAssetLocation(filename))
|
||||
platformFileName := filepath.FromSlash(filename)
|
||||
fileContent, err := filesystem.ReadFile(platform.GetAssetLocation(platformFileName))
|
||||
if err != nil {
|
||||
return nil, newError("Cannot find file", filename).Base(err)
|
||||
}
|
||||
fileHash := sha256.Sum256(filecontent)
|
||||
fileHash := sha256.Sum256(fileContent)
|
||||
fileHashAsString := hex.EncodeToString(fileHash[:])
|
||||
if filenameverified, ok := e.checkedFile[fileHashAsString]; ok {
|
||||
for _, filenameVerifiedIndividual := range strings.Split(filenameverified, ";") {
|
||||
if fileNameVerified, ok := e.checkedFile[fileHashAsString]; ok {
|
||||
for _, filenameVerifiedIndividual := range strings.Split(fileNameVerified, ";") {
|
||||
if strings.HasSuffix(filenameVerifiedIndividual, filename) {
|
||||
return filecontent, nil
|
||||
return fileContent, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
package securedload
|
||||
|
||||
import "path/filepath"
|
||||
|
||||
func GetAssetSecured(name string) ([]byte, error) {
|
||||
name = filepath.FromSlash(name)
|
||||
|
||||
var err error
|
||||
for k, v := range knownProtectedLoader {
|
||||
loadedData, errLoad := v.VerifyAndLoad(name)
|
||||
|
||||
@@ -37,7 +37,7 @@ func ExportIDToError(ctx context.Context) errors.ExportOption {
|
||||
type Inbound struct {
|
||||
// Source address of the inbound connection.
|
||||
Source net.Destination
|
||||
// Getaway address
|
||||
// Gateway address
|
||||
Gateway net.Destination
|
||||
// Tag of the inbound proxy that handles the connection.
|
||||
Tag string
|
||||
|
||||
Reference in New Issue
Block a user