Merge branch 'master' into v5

This commit is contained in:
loyalsoldier
2021-04-13 14:19:02 +08:00
49 changed files with 986 additions and 11782 deletions
+39
View File
@@ -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
}
+16
View File
@@ -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 -1
View 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
}
+29
View File
@@ -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)
+7 -5
View File
@@ -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
}
}
}
-4
View File
@@ -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)
+1 -1
View File
@@ -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