You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

145 lines
4.9 KiB

package oss
import (
"bytes"
"io"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
)
func newSys(options Options) (sys *OSS, err error) {
sys = &OSS{options: options}
err = sys.Init()
return
}
// NewPresigner 用显式凭证构建一个「只用于生成预签名 URL」的 OSS 句柄。
//
// 与 newSys/Init 不同:不做 bucket 存在性检查、也不自动建桶——因为
// 1. 预签名是纯本地签名运算,不需要任何网络请求;
// 2. 托管方(第三方服务配置里填的)AK/SK 往往只有读写对象的权限、没有建桶权限,
// 走 Init 反而会 panic/报错。
//
// 适合 console 按「选中应用」从 svc_config 动态读出凭证后即用即建(无状态、可每请求新建)。
func NewPresigner(endpoint, accessKeyId, accessKeySecret, bucketName string) (sys *OSS, err error) {
sys = &OSS{options: Options{
Endpoint: endpoint,
AccessKeyId: accessKeyId,
AccessKeySecret: accessKeySecret,
BucketName: bucketName,
}}
if sys.client, err = oss.New(endpoint, accessKeyId, accessKeySecret); err != nil {
return nil, err
}
if sys.bucket, err = sys.client.Bucket(bucketName); err != nil {
return nil, err
}
return sys, nil
}
// SignPutURL 生成一个供「浏览器直传(PUT)」用的预签名 URL,有效期 expiredSec 秒。
//
// contentType 非空时会计入签名(OSS V1 签名字符串包含 Content-Type)——因此浏览器 PUT 时
// 必须带完全相同的 Content-Type 请求头,否则 OSS 返回 SignatureDoesNotMatch。
func (this *OSS) SignPutURL(objectName string, contentType string, expiredSec int64) (url string, err error) {
if contentType != "" {
return this.bucket.SignURL(objectName, oss.HTTPPut, expiredSec, oss.ContentType(contentType))
}
return this.bucket.SignURL(objectName, oss.HTTPPut, expiredSec)
}
type OSS struct {
options Options
client *oss.Client
bucket *oss.Bucket
}
func (this *OSS) Init() (err error) {
if this.options.SecurityToken != "" {
this.client, err = oss.New(this.options.Endpoint, this.options.AccessKeyId, this.options.AccessKeySecret, oss.SecurityToken(this.options.SecurityToken))
} else {
this.client, err = oss.New(this.options.Endpoint, this.options.AccessKeyId, this.options.AccessKeySecret)
}
if err != nil {
return err
}
if ok, err := this.client.IsBucketExist(this.options.BucketName); !ok || err != nil {
if err = this.CreateBucket(this.options.BucketName); err == nil {
this.bucket, err = this.client.Bucket(this.options.BucketName)
return err
} else {
return err
}
} else {
this.bucket, err = this.client.Bucket(this.options.BucketName)
return err
}
}
//创建存储空间。
func (this *OSS) CreateBucket(bucketName string) (err error) {
err = this.client.CreateBucket(bucketName)
return err
}
//上传文件
//<objectName>上传文件到OSS时需要指定包含文件后缀在内的完整路径,例如abc/efg/123.jpg。
//<localFileName>由本地文件路径加文件名包括后缀组成,例如/users/local/myfile.txt。
func (this *OSS) UploadFile(objectName string, localFileName string) (err error) {
err = this.bucket.PutObjectFromFile(objectName, localFileName)
return err
}
//上传对象
// <objectName>上传文件到OSS时需要指定包含文件后缀在内的完整路径,例如abc/efg/123.jpg。
// <localFileName>由本地文件路径加文件名包括后缀组成,例如/users/local/myfile.txt。
// 上传文件。
func (this *OSS) UploadObject(objectKey string, reader io.Reader, options ...oss.Option) (err error) {
err = this.bucket.PutObject(objectKey, reader, options...)
return err
}
//下载文件。
//<objectName>从OSS下载文件时需要指定包含文件后缀在内的完整路径,例如abc/efg/123.jpg。
func (this *OSS) DownloadFile(objectName string, downloadedFileName string) (err error) {
err = this.bucket.GetObjectToFile(objectName, downloadedFileName)
return err
}
//下载文件到缓存
func (this *OSS) GetObject(objectName string, options ...oss.Option) ([]byte, error) {
if file, err := this.bucket.GetObject(objectName, options...); err != nil {
return nil, err
} else {
defer file.Close()
buf := new(bytes.Buffer)
if _, err := buf.ReadFrom(file); err != nil {
return nil, err
} else {
return buf.Bytes(), nil
}
}
}
//复制文件
func (this *OSS) CopyObject(srcObjectKey, destObjectKey string, options ...oss.Option) (err error) {
_, err = this.bucket.CopyObject(srcObjectKey, destObjectKey, options...)
return
}
//删除文件
func (this *OSS) DeleteFile(objectName string, options ...oss.Option) (err error) {
err = this.bucket.DeleteObject(objectName, options...)
return
}
func (this *OSS) DeleteFiles(objectNames []string, options ...oss.Option) (err error) {
_, err = this.bucket.DeleteObjects(objectNames, options...)
return
}
//获取临时访问url
func (this *OSS) GetURL(objectName string, expired int64, options ...oss.Option) (url string, err error) {
url, err = this.bucket.SignURL(objectName, oss.HTTPGet, expired, options...)
return
}