mirror of
https://github.com/XTLS/Xray-core.git
synced 2026-11-06 02:07:17 +00:00
Compare commits
6
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9b80222423 | ||
|
|
6c7e3d63b4 | ||
|
|
cc1355d7e9 | ||
|
|
d9da576f68 | ||
|
|
556767e40b | ||
|
|
967ade1e03 |
@@ -9,8 +9,8 @@ ARG TARGETARCH
|
|||||||
RUN GOOS=$TARGETOS GOARCH=$TARGETARCH CGO_ENABLED=0 go build -o xray -trimpath -buildvcs=false -gcflags="all=-l=4" -ldflags "-s -w -buildid=" ./main
|
RUN GOOS=$TARGETOS GOARCH=$TARGETARCH CGO_ENABLED=0 go build -o xray -trimpath -buildvcs=false -gcflags="all=-l=4" -ldflags "-s -w -buildid=" ./main
|
||||||
|
|
||||||
# Download geodat into a staging directory
|
# Download geodat into a staging directory
|
||||||
ADD https://raw.githubusercontent.com/XTLS/Xray-rules-dat/release/geoip/geoip-full.dat /tmp/geodat/geoip.dat
|
ADD https://github.com/XTLS/Xray-rules-dat/releases/latest/download/geoip-full.dat /tmp/geodat/geoip.dat
|
||||||
ADD https://raw.githubusercontent.com/XTLS/Xray-rules-dat/release/geosite/geosite-expand.dat /tmp/geodat/geosite.dat
|
ADD https://github.com/XTLS/Xray-rules-dat/releases/latest/download/geosite-expand.dat /tmp/geodat/geosite.dat
|
||||||
|
|
||||||
RUN mkdir -p /tmp/empty
|
RUN mkdir -p /tmp/empty
|
||||||
|
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ ARG TARGETARCH
|
|||||||
RUN GOOS=$TARGETOS GOARCH=$TARGETARCH CGO_ENABLED=0 go build -o xray -trimpath -buildvcs=false -gcflags="all=-l=4" -ldflags "-s -w -buildid=" ./main
|
RUN GOOS=$TARGETOS GOARCH=$TARGETARCH CGO_ENABLED=0 go build -o xray -trimpath -buildvcs=false -gcflags="all=-l=4" -ldflags "-s -w -buildid=" ./main
|
||||||
|
|
||||||
# Download geodat into a staging directory
|
# Download geodat into a staging directory
|
||||||
ADD https://raw.githubusercontent.com/XTLS/Xray-rules-dat/release/geoip/geoip-full.dat /tmp/geodat/geoip.dat
|
ADD https://github.com/XTLS/Xray-rules-dat/releases/latest/download/geoip-full.dat /tmp/geodat/geoip.dat
|
||||||
ADD https://raw.githubusercontent.com/XTLS/Xray-rules-dat/release/geosite/geosite-expand.dat /tmp/geodat/geosite.dat
|
ADD https://github.com/XTLS/Xray-rules-dat/releases/latest/download/geosite-expand.dat /tmp/geodat/geosite.dat
|
||||||
|
|
||||||
RUN mkdir -p /tmp/empty
|
RUN mkdir -p /tmp/empty
|
||||||
|
|
||||||
|
|||||||
+11
-1
@@ -2,6 +2,7 @@ package conf
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/robfig/cron/v3"
|
"github.com/robfig/cron/v3"
|
||||||
"github.com/xtls/xray-core/app/geodata"
|
"github.com/xtls/xray-core/app/geodata"
|
||||||
@@ -19,11 +20,20 @@ func (c *GeodataAssetConfig) Build() (*geodata.Asset, error) {
|
|||||||
return nil, errors.New("invalid geodata asset url: ", c.URL).Base(err)
|
return nil, errors.New("invalid geodata asset url: ", c.URL).Base(err)
|
||||||
}
|
}
|
||||||
return &geodata.Asset{
|
return &geodata.Asset{
|
||||||
Url: c.URL,
|
Url: migrateGeodataURL(c.URL),
|
||||||
File: c.File,
|
File: c.File,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func migrateGeodataURL(assetURL string) string
|
||||||
|
if strings.HasSuffix(strings.ToLower(assetURL), ".dat") && (strings.HasPrefix(strings.ToLower(assetURL), "https://github.com/xtls/xray-rules-dat/")
|
||||||
|
|| strings.HasPrefix(strings.ToLower(assetURL), "https://raw.githubusercontent.com/xtls/xray-rules-dat/")) {
|
||||||
|
errors.PrintDeprecatedFeatureWarning(assetURL, assetURL+".gz")
|
||||||
|
return assetURL + ".gz"
|
||||||
|
}
|
||||||
|
return assetURL
|
||||||
|
}
|
||||||
|
|
||||||
func validateHTTPS(s string) error {
|
func validateHTTPS(s string) error {
|
||||||
u, err := url.ParseRequestURI(s)
|
u, err := url.ParseRequestURI(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ func (s *localStorage) Get(ctx context.Context, name string) ([]byte, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
data, err := os.ReadFile(full)
|
data, err := readFile(ctx, full)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
return nil, errNotFound
|
return nil, errNotFound
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
//go:build !windows
|
||||||
|
|
||||||
|
package xdrive
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func readFile(_ context.Context, name string) ([]byte, error) {
|
||||||
|
return os.ReadFile(name)
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package xdrive
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"golang.org/x/sys/windows"
|
||||||
|
)
|
||||||
|
|
||||||
|
// readFile retries os.ReadFile for up to 2 seconds on sharing violations:
|
||||||
|
// os.Rename (MoveFileEx) in Put holds the file with DELETE access, which
|
||||||
|
// os.ReadFile does not share, until a moment after its new name appears in List
|
||||||
|
func readFile(ctx context.Context, name string) ([]byte, error) {
|
||||||
|
deadline := time.Now().Add(2 * time.Second)
|
||||||
|
delay := time.Millisecond
|
||||||
|
for {
|
||||||
|
data, err := os.ReadFile(name)
|
||||||
|
if !errors.Is(err, windows.ERROR_SHARING_VIOLATION) || time.Now().Add(delay).After(deadline) {
|
||||||
|
return data, err
|
||||||
|
}
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return nil, err
|
||||||
|
case <-time.After(delay):
|
||||||
|
}
|
||||||
|
delay = min(2*delay, 100*time.Millisecond)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
package xdrive
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"sync"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"golang.org/x/sys/windows"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestLocalSharingViolation(t *testing.T) {
|
||||||
|
storage, err := newLocalStorage(t.TempDir())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("newLocalStorage: %v", err)
|
||||||
|
}
|
||||||
|
const name = "streams/session/c2s/000000000.seg"
|
||||||
|
if err := storage.Put(context.Background(), name, []byte("segment")); err != nil {
|
||||||
|
t.Fatalf("Put: %v", err)
|
||||||
|
}
|
||||||
|
full, err := storage.resolve(name)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("resolve: %v", err)
|
||||||
|
}
|
||||||
|
path, err := windows.UTF16PtrFromString(full)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("UTF16PtrFromString: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// os.Rename holds the file like this until a moment after its new name
|
||||||
|
// appears
|
||||||
|
handle, err := windows.CreateFile(path, windows.DELETE,
|
||||||
|
windows.FILE_SHARE_READ|windows.FILE_SHARE_WRITE|windows.FILE_SHARE_DELETE,
|
||||||
|
nil, windows.OPEN_EXISTING, 0, 0)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("CreateFile: %v", err)
|
||||||
|
}
|
||||||
|
var once sync.Once
|
||||||
|
release := func() { once.Do(func() { windows.CloseHandle(handle) }) }
|
||||||
|
defer release()
|
||||||
|
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 50*time.Millisecond)
|
||||||
|
defer cancel()
|
||||||
|
if _, err := storage.Get(ctx, name); !errors.Is(err, windows.ERROR_SHARING_VIOLATION) {
|
||||||
|
t.Fatalf("Get returned %v while the file is held, want a sharing violation", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
time.AfterFunc(100*time.Millisecond, release)
|
||||||
|
data, err := storage.Get(context.Background(), name)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Get: %v", err)
|
||||||
|
}
|
||||||
|
if string(data) != "segment" {
|
||||||
|
t.Fatalf("Get returned %q, want %q", data, "segment")
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user