mirror of
https://github.com/XTLS/Xray-core.git
synced 2026-09-23 01:27:04 +00:00
https://github.com/XTLS/Xray-core/pull/5645#issuecomment-3849778103 https://github.com/XTLS/Xray-core/pull/5645#issuecomment-3851839033 https://github.com/XTLS/Xray-core/pull/6745#issuecomment-5627294204 https://github.com/XTLS/Xray-core/pull/6748#issuecomment-5660444946 https://github.com/XTLS/Xray-core/pull/6748#issuecomment-5719209642 --------- Co-authored-by: RPRX <63339210+RPRX@users.noreply.github.com>
91 lines
2.2 KiB
Go
91 lines
2.2 KiB
Go
package xdrive
|
|
|
|
import (
|
|
"context"
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"strings"
|
|
"sync"
|
|
|
|
"github.com/xtls/xray-core/common/errors"
|
|
"github.com/xtls/xray-core/transport/internet"
|
|
)
|
|
|
|
var errNotFound = errors.New("object not found")
|
|
|
|
type Entry struct {
|
|
Name string
|
|
Inline []byte
|
|
}
|
|
|
|
type Storage interface {
|
|
Put(ctx context.Context, name string, data []byte) error
|
|
Get(ctx context.Context, name string) ([]byte, error)
|
|
Delete(ctx context.Context, name string) error
|
|
List(ctx context.Context, prefix string) ([]Entry, error)
|
|
Close() error
|
|
}
|
|
|
|
func newStorage(streamSettings *internet.MemoryStreamConfig) (Storage, error) {
|
|
config, err := streamConfig(streamSettings)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
switch config.Service {
|
|
case "local":
|
|
return newLocalStorage(config.RemoteFolder)
|
|
case "Google Drive":
|
|
return sharedStorage(streamSettings, config, func() (Storage, error) {
|
|
return newDriveStorage(streamSettings, config)
|
|
})
|
|
case "template":
|
|
return sharedStorage(streamSettings, config, func() (Storage, error) {
|
|
return newTemplateStorage(streamSettings, config)
|
|
})
|
|
default:
|
|
return nil, errors.New("unsupported service: ", config.Service)
|
|
}
|
|
}
|
|
|
|
var (
|
|
sharedMu sync.Mutex
|
|
shared = make(map[string]Storage)
|
|
)
|
|
|
|
func shareKey(streamSettings *internet.MemoryStreamConfig, config *Config) string {
|
|
parts := []string{config.Service, config.RemoteFolder}
|
|
parts = append(parts, config.Secrets...)
|
|
if streamSettings != nil {
|
|
parts = append(parts, streamSettings.SecurityType)
|
|
if streamSettings.Destination != nil {
|
|
parts = append(parts, streamSettings.Destination.NetAddr())
|
|
}
|
|
}
|
|
sum := sha256.Sum256([]byte(strings.Join(parts, "\x00")))
|
|
return hex.EncodeToString(sum[:])
|
|
}
|
|
|
|
func resetSharedStorage() {
|
|
sharedMu.Lock()
|
|
shared = make(map[string]Storage)
|
|
sharedMu.Unlock()
|
|
}
|
|
|
|
func sharedStorage(streamSettings *internet.MemoryStreamConfig, config *Config, build func() (Storage, error)) (Storage, error) {
|
|
key := shareKey(streamSettings, config)
|
|
|
|
sharedMu.Lock()
|
|
defer sharedMu.Unlock()
|
|
|
|
if storage, ok := shared[key]; ok {
|
|
return storage, nil
|
|
}
|
|
storage, err := build()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
shared[key] = storage
|
|
return storage, nil
|
|
}
|