package aliyun import ( "bytes" "crypto/hmac" "crypto/sha1" "encoding/base64" "encoding/json" "fmt" "github.com/aliyun/aliyun-oss-go-sdk/oss" "io" "knowledge/config" "os" "strings" "time" ) // GetOssSignResponse 获取oss签名返回值 type GetOssSignResponse struct { AccessId string `json:"access_id"` // 主键id Host string `json:"host"` Policy string `json:"policy"` Signature string `json:"signature"` Expire int64 `json:"expire"` Callback string `json:"callback"` Dir string `json:"dir"` } // GetOssSign 获取oss签名 func GetOssSign(dir string) (*GetOssSignResponse, error) { now := time.Now() expire := 30 // 设置该policy超时时间是30s,即这个policy过了这个有效时间,将不能访问。 end := now.Add(time.Second * time.Duration(expire)) expiration := strings.Replace(end.Format("2006-01-02T15:04:05.000Z"), "+00:00", ".000Z", 1) start := []interface{}{"starts-with", "$key", dir} conditions := [][]interface{}{start} arr := map[string]interface{}{ "expiration": expiration, "conditions": conditions, } policy, _ := json.Marshal(arr) base64Policy := base64.StdEncoding.EncodeToString(policy) stringToSign := base64Policy h := hmac.New(sha1.New, []byte(config.C.Oss.OssAccessKeySecret)) h.Write([]byte(stringToSign)) signature := base64.StdEncoding.EncodeToString(h.Sum(nil)) response := &GetOssSignResponse{ AccessId: config.C.Oss.OssAccessKey, Host: config.C.Oss.OssCustomDomainName, Policy: base64Policy, Signature: signature, Expire: end.Unix(), Callback: "", Dir: dir, } return response, nil } // CreateClient 创建客户端 func CreateClient() (*oss.Client, error) { // 创建OSSClient实例。 client, err := oss.New(config.C.Oss.OssEndpoint, config.C.Oss.OssAccessKey, config.C.Oss.OssAccessKeySecret) if err != nil { return nil, err } return client, nil } // GetCusTomObjectToRAM 下载自定义风格文件到内存 func GetCusTomObjectToRAM(filename string, style string) (string, error) { if style == "" { style = "image/resize" } ossClient, err := CreateClient() if err != nil { return "", err } // yourBucketName填写存储空间名称。 bucket, err := ossClient.Bucket(config.C.Oss.OssBucket) if err != nil { return "", err } // 下载文件到流。 body, err := bucket.GetObject(filename, oss.Process(style)) if err != nil { return "", err } // 数据读取完成后,获取的流必须关闭,否则会造成连接泄漏,导致请求无连接可用,程序无法正常工作。 defer func(body io.ReadCloser) { _ = body.Close() }(body) data, err := io.ReadAll(body) if err != nil { fmt.Println("Error:", err) os.Exit(-1) } return string(data), nil } // GetObjectToRAM 下载文件到内存 func GetObjectToRAM(filename string) (string, error) { ossClient, err := CreateClient() if err != nil { return "", err } // yourBucketName填写存储空间名称。 bucket, err := ossClient.Bucket(config.C.Oss.OssBucket) if err != nil { return "", err } // 下载文件到流。 body, err := bucket.GetObject(filename) if err != nil { return "", err } // 数据读取完成后,获取的流必须关闭,否则会造成连接泄漏,导致请求无连接可用,程序无法正常工作。 defer func(body io.ReadCloser) { _ = body.Close() }(body) data, err := io.ReadAll(body) if err != nil { fmt.Println("Error:", err) os.Exit(-1) } return string(data), nil } // GetObjectToLocal 下载文件到本地 func GetObjectToLocal(filename, local string) (bool, error) { ossClient, err := CreateClient() if err != nil { return false, err } // yourBucketName填写存储空间名称。 bucket, err := ossClient.Bucket(config.C.Oss.OssBucket) if err != nil { return false, err } // 下载文件到本地文件,并保存到指定的本地路径中。如果指定的本地文件存在会覆盖,不存在则新建。 // 如果未指定本地路径,则下载后的文件默认保存到示例程序所属项目对应本地路径中。 // 依次填写Object完整路径(例如exampledir/exampleobject.txt)和本地文件的完整路径(例如D:\\localpath\\examplefile.txt)。Object完整路径中不能包含Bucket名称。 err = bucket.GetObjectToFile(filename, local) if err != nil { return false, err } return true, nil } // PutObjectByte 上传文件 func PutObjectByte(filename string, content []byte) (bool, error) { ossClient, err := CreateClient() if err != nil { return false, err } // yourBucketName填写存储空间名称。 bucket, err := ossClient.Bucket(config.C.Oss.OssBucket) if err != nil { return false, err } err = bucket.PutObject(filename, bytes.NewReader(content)) if err != nil { return false, err } return true, nil }