Files
OpenFlare/Wavelet/internal/storage/oss.go
T
2026-06-18 15:24:48 +08:00

99 lines
2.5 KiB
Go

// Copyright 2026 Arctel.net
// SPDX-License-Identifier: Apache-2.0
package storage
import (
"context"
"fmt"
"io"
"strings"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
)
type ossBackend struct {
client *oss.Client
bucket string
keyPrefix string
cdnURL string
}
func newOSSBackend(cfg ObjectConfig) (*ossBackend, error) {
options := oss.LoadDefaultConfig().
WithCredentialsProvider(credentials.NewStaticCredentialsProvider(cfg.AccessKeyID, cfg.SecretAccessKey)).
WithRegion(cfg.Region)
if cfg.Endpoint != "" {
options.WithEndpoint(cfg.Endpoint)
}
return &ossBackend{
client: oss.NewClient(options),
bucket: cfg.Bucket,
keyPrefix: strings.Trim(cfg.KeyPrefix, "/"),
cdnURL: strings.TrimRight(cfg.CDNURL, "/"),
}, nil
}
func (b *ossBackend) Put(ctx context.Context, key string, body io.Reader, _ int64, _ string) (PutResult, error) {
key = b.key(key)
_, err := b.client.PutObject(ctx, &oss.PutObjectRequest{
Bucket: oss.Ptr(b.bucket),
Key: oss.Ptr(key),
Body: body,
})
if err != nil {
return PutResult{}, fmt.Errorf("put OSS object: %w", err)
}
return PutResult{Key: key, Bucket: b.bucket}, nil
}
func (b *ossBackend) Get(ctx context.Context, key string) (*Object, error) {
key = b.key(key)
if b.cdnURL != "" {
return getHTTPObject(ctx, b.cdnURL, key)
}
output, err := b.client.GetObject(ctx, &oss.GetObjectRequest{
Bucket: oss.Ptr(b.bucket),
Key: oss.Ptr(key),
})
if err != nil {
return nil, fmt.Errorf("get OSS object: %w", err)
}
contentType := defaultContentType
if output.ContentType != nil {
contentType = *output.ContentType
}
return &Object{Body: output.Body, ContentLength: output.ContentLength, ContentType: contentType}, nil
}
func (b *ossBackend) Delete(ctx context.Context, key string) error {
_, err := b.client.DeleteObject(ctx, &oss.DeleteObjectRequest{
Bucket: oss.Ptr(b.bucket),
Key: oss.Ptr(b.key(key)),
})
if err != nil {
return fmt.Errorf("delete OSS object: %w", err)
}
return nil
}
func (b *ossBackend) Test(ctx context.Context) error {
ok, err := b.client.IsBucketExist(ctx, b.bucket)
if err != nil {
return fmt.Errorf("access OSS bucket: %w", err)
}
if !ok {
return fmt.Errorf("OSS bucket %q does not exist", b.bucket)
}
return nil
}
func (b *ossBackend) key(key string) string {
key = strings.TrimLeft(key, "/")
if b.keyPrefix == "" || strings.HasPrefix(key, b.keyPrefix+"/") {
return key
}
return b.keyPrefix + "/" + key
}