数据源和 oss
This commit is contained in:
@@ -21,6 +21,33 @@ type fileStorage struct {
|
||||
}
|
||||
|
||||
func NewFileStorage(config *conf.AdminBackend) (biz.FileStorage, error) {
|
||||
storageType := "local"
|
||||
if config != nil && config.Storage != nil && config.Storage.Type != "" {
|
||||
storageType = strings.ToLower(config.Storage.Type)
|
||||
}
|
||||
if storageType == "qiniu" {
|
||||
return newQiniuStorage(config.Storage.Qiniu)
|
||||
}
|
||||
if storageType != "local" {
|
||||
var object *conf.AdminBackend_ObjectStore
|
||||
switch storageType {
|
||||
case "aliyun-oss":
|
||||
object = config.Storage.AliyunOss
|
||||
case "huawei-obs":
|
||||
object = config.Storage.HuaweiObs
|
||||
case "tencent-cos":
|
||||
object = config.Storage.TencentCos
|
||||
case "aws-s3":
|
||||
object = config.Storage.AwsS3
|
||||
case "cloudflare-r2":
|
||||
object = config.Storage.CloudflareR2
|
||||
case "minio":
|
||||
object = config.Storage.Minio
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported storage type %q", storageType)
|
||||
}
|
||||
return newS3Storage(storageType, object)
|
||||
}
|
||||
root, prefix := "uploads/file", "uploads/file"
|
||||
if config != nil && config.Local != nil {
|
||||
if config.Local.StorePath != "" {
|
||||
@@ -37,6 +64,43 @@ func NewFileStorage(config *conf.AdminBackend) (biz.FileStorage, error) {
|
||||
return &fileStorage{root: root, urlPrefix: "/" + strings.Trim(prefix, "/")}, nil
|
||||
}
|
||||
|
||||
func composeFiles(ctx context.Context, storage biz.FileStorage, names []string, destination string) (*biz.StoredFile, string, error) {
|
||||
reader, writer := io.Pipe()
|
||||
hash := md5.New()
|
||||
errCh := make(chan error, 1)
|
||||
go func() {
|
||||
defer writer.Close()
|
||||
for _, name := range names {
|
||||
if ctx.Err() != nil {
|
||||
errCh <- ctx.Err()
|
||||
return
|
||||
}
|
||||
file, err := storage.Open(ctx, name)
|
||||
if err != nil {
|
||||
errCh <- err
|
||||
return
|
||||
}
|
||||
_, err = io.Copy(io.MultiWriter(writer, hash), file)
|
||||
_ = file.Close()
|
||||
if err != nil {
|
||||
errCh <- err
|
||||
return
|
||||
}
|
||||
}
|
||||
errCh <- nil
|
||||
}()
|
||||
stored, err := storage.Put(ctx, destination, reader)
|
||||
composeErr := <-errCh
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
if composeErr != nil {
|
||||
_ = storage.Delete(ctx, destination)
|
||||
return nil, "", composeErr
|
||||
}
|
||||
return stored, hex.EncodeToString(hash.Sum(nil)), nil
|
||||
}
|
||||
|
||||
func (s *fileStorage) resolve(name string) (string, error) {
|
||||
clean := filepath.Clean(strings.TrimPrefix(name, "/"))
|
||||
if clean == "." || filepath.IsAbs(clean) || clean == ".." || strings.HasPrefix(clean, ".."+string(filepath.Separator)) {
|
||||
@@ -88,40 +152,7 @@ func (s *fileStorage) Delete(ctx context.Context, name string) error {
|
||||
}
|
||||
|
||||
func (s *fileStorage) Compose(ctx context.Context, names []string, destination string) (*biz.StoredFile, string, error) {
|
||||
reader, writer := io.Pipe()
|
||||
hash := md5.New()
|
||||
errCh := make(chan error, 1)
|
||||
go func() {
|
||||
defer writer.Close()
|
||||
for _, name := range names {
|
||||
if ctx.Err() != nil {
|
||||
errCh <- ctx.Err()
|
||||
return
|
||||
}
|
||||
file, err := s.Open(ctx, name)
|
||||
if err != nil {
|
||||
errCh <- err
|
||||
return
|
||||
}
|
||||
_, err = io.Copy(io.MultiWriter(writer, hash), file)
|
||||
_ = file.Close()
|
||||
if err != nil {
|
||||
errCh <- err
|
||||
return
|
||||
}
|
||||
}
|
||||
errCh <- nil
|
||||
}()
|
||||
stored, err := s.Put(ctx, destination, reader)
|
||||
composeErr := <-errCh
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
if composeErr != nil {
|
||||
_ = s.Delete(ctx, destination)
|
||||
return nil, "", composeErr
|
||||
}
|
||||
return stored, hex.EncodeToString(hash.Sum(nil)), nil
|
||||
return composeFiles(ctx, s, names, destination)
|
||||
}
|
||||
func (s *fileStorage) DeletePrefix(ctx context.Context, prefix string) error {
|
||||
path, err := s.resolve(strings.TrimSuffix(prefix, "/") + "/placeholder")
|
||||
|
||||
Reference in New Issue
Block a user