package oss import ( "context" "io" "strings" "github.com/minio/minio-go/v7" "github.com/minio/minio-go/v7/pkg/credentials" ) type MinioClientConfig struct { Domain string Endpoint string AccessKeyID string SecretAccessKey string BucketName string Prefix string } var _ IClient = (*MinioClient)(nil) type MinioClient struct { config MinioClientConfig client *minio.Client } func NewMinioClient(config MinioClientConfig) (*MinioClient, error) { client, err := minio.New(config.Endpoint, &minio.Options{ Creds: credentials.NewStaticV4(config.AccessKeyID, config.SecretAccessKey, ""), }) if err != nil { return nil, err } ctx := context.Background() if exists, err := client.BucketExists(ctx, config.BucketName); err != nil { return nil, err } else if !exists { if err := client.MakeBucket(ctx, config.BucketName, minio.MakeBucketOptions{}); err != nil { return nil, err } } return &MinioClient{ config: config, client: client, }, nil } func (c *MinioClient) PutObject(ctx context.Context, bucketName, objectName string, reader io.ReadSeeker, objectSize int64, options ...PutObjectOptions) (*PutObjectResult, error) { if bucketName == "" { bucketName = c.config.BucketName } var opt PutObjectOptions if len(options) > 0 { opt = options[0] } objectName = formatObjectName(c.config.Prefix, objectName) output, err := c.client.PutObject(ctx, bucketName, objectName, reader, objectSize, minio.PutObjectOptions{ ContentType: opt.ContentType, UserMetadata: opt.UserMetadata, }) if err != nil { return nil, err } return &PutObjectResult{ URL: c.config.Domain + "/" + objectName, Key: output.Key, ETag: output.ETag, Size: output.Size, }, nil } func (c *MinioClient) GetObject(ctx context.Context, bucketName, objectName string) (io.ReadCloser, error) { if bucketName == "" { bucketName = c.config.BucketName } objectName = formatObjectName(c.config.Prefix, objectName) return c.client.GetObject(ctx, bucketName, objectName, minio.GetObjectOptions{}) } func (c *MinioClient) RemoveObject(ctx context.Context, bucketName, objectName string) error { if bucketName == "" { bucketName = c.config.BucketName } objectName = formatObjectName(c.config.Prefix, objectName) return c.client.RemoveObject(ctx, bucketName, objectName, minio.RemoveObjectOptions{}) } func (c *MinioClient) RemoveObjectByURL(ctx context.Context, urlStr string) error { prefix := c.config.Domain + "/" if !strings.HasPrefix(urlStr, prefix) { return nil } objectName := strings.TrimPrefix(urlStr, prefix) return c.RemoveObject(ctx, "", objectName) } func (c *MinioClient) StatObjectByURL(ctx context.Context, urlStr string) (*ObjectStat, error) { prefix := c.config.Domain + "/" if !strings.HasPrefix(urlStr, prefix) { return nil, nil } objectName := strings.TrimPrefix(urlStr, prefix) return c.StatObject(ctx, "", objectName) } func (c *MinioClient) StatObject(ctx context.Context, bucketName, objectName string) (*ObjectStat, error) { if bucketName == "" { bucketName = c.config.BucketName } objectName = formatObjectName(c.config.Prefix, objectName) info, err := c.client.StatObject(ctx, bucketName, objectName, minio.StatObjectOptions{}) if err != nil { return nil, err } return &ObjectStat{ Key: info.Key, Size: info.Size, ETag: info.ETag, ContentType: info.ContentType, UserMetadata: info.UserMetadata, }, nil }