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.
go-library/vendor/github.com/qiniu/go-sdk/v7/storage/uc.go

605 lines
22 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

// package storage 提供了用户存储配置(uc)方面的功能, 定义了UC API 的返回结构体类型
package storage
import (
"context"
"fmt"
"net/url"
"strconv"
"strings"
"time"
"github.com/qiniu/go-sdk/v7/auth"
)
// BucketSummary 存储空间信息
type BucketSummary struct {
// 存储空间名字
Name string `json:"name"`
Info BucketInfo `json:"info"`
}
// BucketInfo 存储空间的详细信息
type BucketInfo struct {
// 镜像回源地址, 接口返回的多个地址以;分割
Source string `json:"source"`
// 镜像回源的时候请求头中的HOST
Host string `json:"host"`
// 镜像回源地址过期时间(秒数) 现在这个功能没有实现,因此这个字段现在是没有意义的
Expires int `json:"expires"`
// 是否开启了原图保护
Protected int `json:"protected"`
// 是否是私有空间
Private int `json:"private"`
// 如果NoIndexPage是false表示开启了空间根目录index.html
// 如果是true, 表示没有开启
// 开启了根目录下的index.html, 文件将会被作为默认首页展示
NoIndexPage int `json:"no_index_page"`
// 在规定的时效内使客户端缓存更新的效果
MaxAge int `json:"max_age"`
// 图片样式分隔符, 接口返回的可能有多个
Separator string `json:"separator"`
// 图片样式, map中的key表示图片样式命令名字
// map中的value表示图片样式命令的内容
Styles map[string]string `json:"styles"`
// 防盗链模式
// 1 - 表示设置了防盗链的referer白名单
// 2 - 表示设置了防盗链的referer黑名单
AntiLeechMode int `json:"anti_leech_mode"`
// 使用token签名进行防盗链
// 0 - 表示关闭
// 1 - 表示开启
TokenAntiLeechMode int `json:"token_anti_leech"`
// 防盗链referer白名单列表
ReferWl []string `json:"refer_wl"`
// 防盗链referer黑名单列表
ReferBl []string `json:"refer_bl"`
// 在源站支持的情况下开启源站的Referer防盗链
EnableSource bool `json:"source_enabled"`
// 是否允许空的referer访问
NoRefer bool `json:"no_refer"`
// 用于防盗链token的生成
MacKey string `json:"mac_key"`
// 用于防盗链token的生成
MacKey2 string `json:"mac_key2"`
// 存储区域, 兼容保留
Zone string
// 存储区域
Region string
// 空间备注信息
Remark string
// 空间创建时间
Ctime time.Time
}
// ReferAntiLeechConfig 是用户存储空间的Refer防盗链配置
type ReferAntiLeechConfig struct {
// 防盗链模式, 0 - 关闭Refer防盗链, 1 - 开启Referer白名单2 - 开启Referer黑名单
Mode int
// 是否允许空的referer访问
AllowEmptyReferer bool
// Pattern 匹配HTTP Referer头, 当模式是1或者2的时候有效
// Mode为1的时候表示允许Referer符合该Pattern的HTTP请求访问
// Mode为2的时候表示禁止Referer符合该Pattern的HTTP请求访问
// 当前允许的匹配字符串格式分为三种:
// 一种为空主机头域名, 比如 foo.com; 一种是泛域名, 比如 *.bar.com;
// 一种是完全通配符, 即一个 *;
// 多个规则之间用;隔开, 比如: foo.com;*.bar.com;sub.foo.com;*.sub.bar.com
Pattern string
// 是否开启源站的防盗链, 默认为0 只开启CDN防盗链 当设置为1的时候
// 在源站支持的情况下开启源站的Referer防盗链
EnableSource bool
}
// SetMode 设置referer防盗链模式
func (r *ReferAntiLeechConfig) SetMode(mode int) *ReferAntiLeechConfig {
if mode != 0 && mode != 1 && mode != 2 {
panic("Referer anti_leech_mode must be in [0, 1, 2]")
}
r.Mode = mode
return r
}
// SetEmptyReferer 设置是否允许空Referer访问
func (r *ReferAntiLeechConfig) SetEmptyReferer(enable bool) *ReferAntiLeechConfig {
r.AllowEmptyReferer = enable
return r
}
// SetPattern 设置匹配Referer的模式
func (r *ReferAntiLeechConfig) SetPattern(pattern string) *ReferAntiLeechConfig {
if pattern == "" {
panic("Empty pattern is not allowed")
}
r.Pattern = pattern
return r
}
// AddDomainPattern 添加pattern到Pattern字段
// 假入Pattern值为"*.qiniu.com" 使用AddDomainPattern("*.baidu.com")后
// r.Pattern的值为"*.qiniu.com;*.baidu.com"
func (r *ReferAntiLeechConfig) AddDomainPattern(pattern string) *ReferAntiLeechConfig {
if strings.HasSuffix(r.Pattern, ";") {
r.Pattern = strings.TrimRight(r.Pattern, ";")
}
r.Pattern = strings.Join([]string{r.Pattern, pattern}, ";")
return r
}
// SetEnableSource 设置是否开启源站的防盗链
func (r *ReferAntiLeechConfig) SetEnableSource(enable bool) *ReferAntiLeechConfig {
r.EnableSource = enable
return r
}
// AsQueryString 编码成query参数格式
func (r *ReferAntiLeechConfig) AsQueryString() string {
params := make(url.Values, 4)
params.Add("mode", strconv.Itoa(r.Mode))
params.Add("pattern", r.Pattern)
if r.AllowEmptyReferer {
params.Add("norefer", "1")
} else {
params.Add("norefer", "0")
}
if r.EnableSource {
params.Add("source_enabled", "1")
} else {
params.Add("source_enabled", "0")
}
return params.Encode()
}
// ProtectedOn 返回true or false
// 如果开启了原图保护返回true, 否则false
func (b *BucketInfo) ProtectedOn() bool {
return b.Protected == 1
}
// IsPrivate 返回布尔值
// 如果是私有空间, 返回 true, 否则返回false
func (b *BucketInfo) IsPrivate() bool {
return b.Private == 1
}
// ImageSources 返回多个镜像回源地址的列表
func (b *BucketInfo) ImageSources() (srcs []string) {
srcs = strings.Split(b.Source, ";")
return
}
// IndexPageOn 返回空间是否开启了根目录下的index.html
func (b *BucketInfo) IndexPageOn() bool {
return b.NoIndexPage == 0
}
// Separators 返回分隔符列表
func (b *BucketInfo) Separators() (ret []rune) {
for _, r := range b.Separator {
ret = append(ret, r)
}
return
}
// WhiteListSet 是否设置了防盗链白名单
func (b *BucketInfo) WhiteListSet() bool {
return b.AntiLeechMode == 1
}
// BlackListSet 是否设置了防盗链黑名单
func (b *BucketInfo) BlackListSet() bool {
return b.AntiLeechMode == 2
}
// TokenAntiLeechModeOn 返回是否使用token签名防盗链开启了
func (b *BucketInfo) TokenAntiLeechModeOn() bool {
return b.TokenAntiLeechMode == 1
}
// GetBucketInfo 返回BucketInfo结构
func (m *BucketManager) GetBucketInfo(bucketName string) (bucketInfo BucketInfo, err error) {
reqURL := fmt.Sprintf("%s/v2/bucketInfo?bucket=%s", getUcHost(m.Cfg.UseHTTPS), bucketName)
err = m.Client.CredentialedCall(context.Background(), m.Mac, auth.TokenQiniu, &bucketInfo, "POST", reqURL, nil)
return
}
// SetRemark 设置空间备注信息
func (m *BucketManager) SetRemark(bucketName, remark string) (err error) {
reqURL := fmt.Sprintf("%s/buckets/%s?remark", getUcHost(m.Cfg.UseHTTPS), bucketName)
body := struct {
Remark string `json:"remark"`
}{Remark: remark}
err = m.Client.CredentialedCallWithJson(context.Background(), m.Mac, auth.TokenQiniu, nil, "PUT", reqURL, nil, body)
return
}
// BucketInfosForRegion 获取指定区域的该用户的所有bucketInfo信息
func (m *BucketManager) BucketInfosInRegion(region RegionID, statistics bool) (bucketInfos []BucketSummary, err error) {
reqURL := fmt.Sprintf("%s/v2/bucketInfos?region=%s&fs=%t", getUcHost(m.Cfg.UseHTTPS), string(region), statistics)
err = m.Client.CredentialedCall(context.Background(), m.Mac, auth.TokenQiniu, &bucketInfos, "POST", reqURL, nil)
return
}
// SetReferAntiLeechMode 配置存储空间referer防盗链模式
func (m *BucketManager) SetReferAntiLeechMode(bucketName string, refererAntiLeechConfig *ReferAntiLeechConfig) (err error) {
reqURL := fmt.Sprintf("%s/referAntiLeech?bucket=%s&%s", getUcHost(m.Cfg.UseHTTPS), bucketName, refererAntiLeechConfig.AsQueryString())
err = m.Client.CredentialedCall(context.Background(), m.Mac, auth.TokenQiniu, nil, "POST", reqURL, nil)
return
}
// BucketLifeCycleRule 定义了关于七牛存储空间关于生命周期的一些配置,规则。
// 比如存储空间中文件可以设置多少天后删除,多少天后转低频存储等等
type BucketLifeCycleRule struct {
// 规则名称, 在设置的bucket中规则名称需要是唯一的
// 同时长度小于50 不能为空
// 由字母,数字和下划线组成
Name string `json:"name"`
// 以该前缀开头的文件应用此规则
Prefix string `json:"prefix"`
// 指定存储空间内的文件多少天后删除
// 0 - 不删除
// > 0 表示多少天后删除
DeleteAfterDays int `json:"delete_after_days"`
// 在多少天后转低频存储
// 0 - 表示不转低频
// < 0 表示上传的文件立即使用低频存储
// > 0 表示多少天后转低频存储
ToLineAfterDays int `json:"to_line_after_days"`
// 指定文件上传多少天后转归档存储。
// 0 表示不转归档存储,
// < 0 表示上传的文件立即变归档存储
// > 0 表示多少天后转归档存储
ToArchiveAfterDays int `json:"to_archive_after_days"`
// 指定文件上传多少天后转深度归档存储。
// < 0 表示上传的文件立即变深度归档存储
// > 0 表示多少天后转深度归档存储
ToDeepArchiveAfterDays int `json:"to_deep_archive_after_days"`
}
// SetBucketLifeCycleRule 设置存储空间内文件的生命周期规则
func (m *BucketManager) AddBucketLifeCycleRule(bucketName string, lifeCycleRule *BucketLifeCycleRule) (err error) {
params := make(map[string][]string)
// 没有检查参数的合法性,交给服务端检查
params["bucket"] = []string{bucketName}
params["name"] = []string{lifeCycleRule.Name}
params["prefix"] = []string{lifeCycleRule.Prefix}
params["delete_after_days"] = []string{strconv.Itoa(lifeCycleRule.DeleteAfterDays)}
params["to_ia_after_days"] = []string{strconv.Itoa(lifeCycleRule.ToLineAfterDays)}
params["to_archive_after_days"] = []string{strconv.Itoa(lifeCycleRule.ToArchiveAfterDays)}
params["to_deep_archive_after_days"] = []string{strconv.Itoa(lifeCycleRule.ToDeepArchiveAfterDays)}
reqURL := getUcHost(m.Cfg.UseHTTPS) + "/rules/add"
err = m.Client.CredentialedCallWithForm(context.Background(), m.Mac, auth.TokenQiniu, nil, "POST", reqURL, nil, params)
return
}
// DelBucketLifeCycleRule 删除特定存储空间上设定的规则
func (m *BucketManager) DelBucketLifeCycleRule(bucketName, ruleName string) (err error) {
params := make(map[string][]string)
params["bucket"] = []string{bucketName}
params["name"] = []string{ruleName}
reqURL := getUcHost(m.Cfg.UseHTTPS) + "/rules/delete"
err = m.Client.CredentialedCallWithForm(context.Background(), m.Mac, auth.TokenQiniu, nil, "POST", reqURL, nil, params)
return
}
// UpdateBucketLifeCycleRule 更新特定存储空间上的生命周期规则
func (m *BucketManager) UpdateBucketLifeCycleRule(bucketName string, rule *BucketLifeCycleRule) (err error) {
params := make(map[string][]string)
params["bucket"] = []string{bucketName}
params["name"] = []string{rule.Name}
params["prefix"] = []string{rule.Prefix}
params["delete_after_days"] = []string{strconv.Itoa(rule.DeleteAfterDays)}
params["to_line_after_days"] = []string{strconv.Itoa(rule.ToLineAfterDays)}
params["to_archive_after_days"] = []string{strconv.Itoa(rule.ToArchiveAfterDays)}
params["to_deep_archive_after_days"] = []string{strconv.Itoa(rule.ToDeepArchiveAfterDays)}
reqURL := getUcHost(m.Cfg.UseHTTPS) + "/rules/update"
err = m.Client.CredentialedCallWithForm(context.Background(), m.Mac, auth.TokenQiniu, nil, "POST", reqURL, nil, params)
return
}
// GetBucketLifeCycleRule 获取指定空间上设置的生命周期规则
func (m *BucketManager) GetBucketLifeCycleRule(bucketName string) (rules []BucketLifeCycleRule, err error) {
reqURL := getUcHost(m.Cfg.UseHTTPS) + "/rules/get?bucket=" + bucketName
err = m.Client.CredentialedCall(context.Background(), m.Mac, auth.TokenQiniu, &rules, "GET", reqURL, nil)
return
}
// BucketEnvent 定义了存储空间发生事件时候的通知规则
// 比如调用了存储的"delete"删除接口删除文件, 这个是一个事件;
// 当这个事件发生的时候, 我们要对哪些文件,做什么处理,是否要作回调,
// 都可以通过这个结构体配置
type BucketEventRule struct {
// 规则名字
Name string `json:"name"`
// 匹配文件前缀
Prefix string `json:"prefix"`
// 匹配文件后缀
Suffix string `json:"suffix"`
// 事件类型
// put,mkfile,delete,copy,move,append,disable,enable,deleteMarkerCreate
Event []string `json:"event"`
// 回调通知地址, 可以指定多个
CallbackURL []string `json:"callback_urls"`
// 用户的AccessKey 可选, 设置的话会对通知请求用对应的ak、sk进行签名
AccessKey string `json:"access_key"`
// 回调通知的请求HOST, 可选
Host string `json:"host"`
}
// Params 返回一个hash结构
func (r *BucketEventRule) Params(bucket string) map[string][]string {
params := make(map[string][]string)
params["bucket"] = []string{bucket}
params["name"] = []string{r.Name}
if r.Prefix != "" {
params["prefix"] = []string{r.Prefix}
}
if r.Suffix != "" {
params["suffix"] = []string{r.Suffix}
}
params["event"] = r.Event
params["callbackURL"] = r.CallbackURL
if r.AccessKey != "" {
params["access_key"] = []string{r.AccessKey}
}
if r.Host != "" {
params["host"] = []string{r.Host}
}
return params
}
// AddBucketEvent 增加存储空间事件通知规则
func (m *BucketManager) AddBucketEvent(bucket string, rule *BucketEventRule) (err error) {
params := rule.Params(bucket)
reqURL := getUcHost(m.Cfg.UseHTTPS) + "/events/add"
err = m.Client.CredentialedCallWithForm(context.Background(), m.Mac, auth.TokenQiniu, nil, "POST", reqURL, nil, params)
return
}
// DelBucketEvent 删除指定存储空间的通知事件规则
func (m *BucketManager) DelBucketEvent(bucket, ruleName string) (err error) {
params := make(map[string][]string)
params["bucket"] = []string{bucket}
params["name"] = []string{ruleName}
reqURL := getUcHost(m.Cfg.UseHTTPS) + "/events/delete"
err = m.Client.CredentialedCallWithForm(context.Background(), m.Mac, auth.TokenQiniu, nil, "POST", reqURL, nil, params)
return
}
// UpdateBucketEnvent 更新指定存储空间的事件通知规则
func (m *BucketManager) UpdateBucketEnvent(bucket string, rule *BucketEventRule) (err error) {
params := rule.Params(bucket)
reqURL := getUcHost(m.Cfg.UseHTTPS) + "/events/update"
err = m.Client.CredentialedCallWithForm(context.Background(), m.Mac, auth.TokenQiniu, nil, "POST", reqURL, nil, params)
return
}
// GetBucketEvent 获取指定存储空间的事件通知规则
func (m *BucketManager) GetBucketEvent(bucket string) (rule []BucketEventRule, err error) {
reqURL := getUcHost(m.Cfg.UseHTTPS) + "/events/get?bucket=" + bucket
err = m.Client.CredentialedCall(context.Background(), m.Mac, auth.TokenQiniu, &rule, "GET", reqURL, nil)
return
}
// CorsRule 是关于存储的跨域规则
// 最多允许设置10条跨域规则
// 对于同一个域名如果设置了多条规则,那么按顺序使用第一条匹配的规则去生成返回值。
// 对于简单跨域请求,只匹配 Origin
// 对于预检请求, 需要匹配 Origin、AllowedMethod、AllowedHeader
// 如果没有设置任何corsRules那么默认允许所有的跨域请求
// 参考: https://www.w3.org/TR/cors/
type CorsRule struct {
// allowed_orgin: 允许的域名。必填;支持通配符**表示全部匹配;只有第一个*生效;需要设置"Scheme";大小写敏感。例如
// 规则http://*.abc.*.com 请求:"http://test.abc.test.com" 结果:不通过
// 规则:"http://abc.com" 请求:"https://abc.com"/"abc.com" 结果:不通过
// 规则:"abc.com" 请求:"http://abc.com" 结果:不通过
AllowedOrigin []string `json:"allowed_origin"`
// allowed_method: 允许的方法。必填;不支持通配符;大小写不敏感;
AllowedMethod []string `json:"allowed_method"`
// allowed_header: 允许的header。选填支持通配符*,但只能是单独的*表示允许全部header其他*不生效空则不允许任何header大小写不敏感
AllowedHeader []string `json:"allowed_header"`
// 暴露的header。选填不支持通配符X-Log, X-Reqid是默认会暴露的两个header其他的header如果没有设置则不会暴露大小写不敏感
ExposedHeader []string `json:"exposed_header"`
// max_age: 结果可以缓存的时间。选填;空则不缓存
MaxAge int64 `json:"max_age"`
}
// AddCorsRules 设置指定存储空间的跨域规则
func (m *BucketManager) AddCorsRules(bucket string, corsRules []CorsRule) (err error) {
reqURL := getUcHost(m.Cfg.UseHTTPS) + "/corsRules/set/" + bucket
err = m.Client.CredentialedCallWithJson(context.Background(), m.Mac, auth.TokenQiniu, nil, "POST", reqURL, nil, corsRules)
return
}
// GetCorsRules 获取指定存储空间的跨域规则
func (m *BucketManager) GetCorsRules(bucket string) (corsRules []CorsRule, err error) {
reqURL := getUcHost(m.Cfg.UseHTTPS) + "/corsRules/get/" + bucket
err = m.Client.CredentialedCall(context.Background(), m.Mac, auth.TokenQiniu, &corsRules, "GET", reqURL, nil)
return
}
// BucketQuota 七牛存储空间的配额信息
type BucketQuota struct {
// 如果HTTP请求没有发送该参数或者发送的参数是0表示不更改当前配置
// 如果是-1 表示取消限额
// 一下两个参数都使用于这个逻辑
// 空间存储量配额信息
Size int64
// 空间文件数配置信息
Count int64
}
// SetBucketQuota 设置存储空间的配额限制
// 配额限制主要是两块, 空间存储量的限制和空间文件数限制
func (m *BucketManager) SetBucketQuota(bucket string, size, count int64) (err error) {
host := getUcHost(m.Cfg.UseHTTPS)
host = strings.TrimRight(host, "/")
reqURL := fmt.Sprintf("%s/setbucketquota/%s/size/%d/count/%d", host, bucket, size, count)
err = m.Client.CredentialedCall(context.Background(), m.Mac, auth.TokenQiniu, nil, "POST", reqURL, nil)
return
}
// GetBucketQuota 获取存储空间的配额信息
func (m *BucketManager) GetBucketQuota(bucket string) (quota BucketQuota, err error) {
host := getUcHost(m.Cfg.UseHTTPS)
host = strings.TrimRight(host, "/")
reqURL := host + "/getbucketquota/" + bucket
err = m.Client.CredentialedCall(context.Background(), m.Mac, auth.TokenQiniu, &quota, "POST", reqURL, nil)
return
}
// SetBucketAccessStyle 可以用来开启或关闭制定存储空间的原图保护
// mode - 1 ==> 开启原图保护
// mode - 0 ==> 关闭原图保护
func (m *BucketManager) SetBucketAccessStyle(bucket string, mode int) error {
reqURL := fmt.Sprintf("%s/accessMode/%s/mode/%d", getUcHost(m.Cfg.UseHTTPS), bucket, mode)
return m.Client.CredentialedCall(context.Background(), m.Mac, auth.TokenQiniu, nil, "POST", reqURL, nil)
}
// TurnOffBucketProtected 开启指定存储空间的原图保护
func (m *BucketManager) TurnOnBucketProtected(bucket string) error {
return m.SetBucketAccessStyle(bucket, 1)
}
// TurnOffBucketProtected 关闭指定空间的原图保护
func (m *BucketManager) TurnOffBucketProtected(bucket string) error {
return m.SetBucketAccessStyle(bucket, 0)
}
// SetBucketMaxAge 设置指定存储空间的MaxAge响应头
// maxAge <= 0时表示使用默认值31536000
func (m *BucketManager) SetBucketMaxAge(bucket string, maxAge int64) error {
reqURL := fmt.Sprintf("%s/maxAge?bucket=%s&maxAge=%d", getUcHost(m.Cfg.UseHTTPS), bucket, maxAge)
return m.Client.CredentialedCall(context.Background(), m.Mac, auth.TokenQiniu, nil, "POST", reqURL, nil)
}
// SetBucketAccessMode 设置指定空间的私有属性
// mode - 1 表示设置空间为私有空间, 私有空间访问需要鉴权
// mode - 0 表示设置空间为公开空间
func (m *BucketManager) SetBucketAccessMode(bucket string, mode int) error {
reqURL := fmt.Sprintf("%s/private?bucket=%s&private=%d", getUcHost(m.Cfg.UseHTTPS), bucket, mode)
return m.Client.CredentialedCall(context.Background(), m.Mac, auth.TokenQiniu, nil, "POST", reqURL, nil)
}
// MakeBucketPublic 设置空间为公有空间
func (m *BucketManager) MakeBucketPublic(bucket string) error {
return m.SetBucketAccessMode(bucket, 0)
}
// MakeBucketPrivate 设置空间为私有空间
func (m *BucketManager) MakeBucketPrivate(bucket string) error {
return m.SetBucketAccessMode(bucket, 1)
}
// TurnOnIndexPage 设置默认首页
func (m *BucketManager) TurnOnIndexPage(bucket string) error {
return m.setIndexPage(bucket, 0)
}
// TurnOnIndexPage 关闭默认首页
func (m *BucketManager) TurnOffIndexPage(bucket string) error {
return m.setIndexPage(bucket, 1)
}
func (m *BucketManager) setIndexPage(bucket string, noIndexPage int) error {
reqURL := fmt.Sprintf("%s/noIndexPage?bucket=%s&noIndexPage=%d", getUcHost(m.Cfg.UseHTTPS), bucket, noIndexPage)
return m.Client.CredentialedCall(context.Background(), m.Mac, auth.TokenQiniu, nil, "POST", reqURL, nil)
}
// BucketTagging 为 Bucket 设置标签
type BucketTagging struct {
Tags []BucketTag `json:"Tags"`
}
type BucketTag struct {
Key string `json:"Key"`
Value string `json:"Value"`
}
// SetTagging 设置 Bucket 标签
// 该方法为覆盖所有 Bucket 上之前设置的标签,标签 Key 最大 64 字节Value 最大 128 字节,均不能为空,且区分大小写
// Key 不能以 kodo 为前缀Key 和 Value 的字符只能为:字母,数字,空格,+-=._:/@,不能支持中文
func (m *BucketManager) SetTagging(bucket string, tags map[string]string) error {
tagging := BucketTagging{Tags: make([]BucketTag, 0, len(tags))}
for key, value := range tags {
tagging.Tags = append(tagging.Tags, BucketTag{Key: key, Value: value})
}
reqURL := fmt.Sprintf("%s/bucketTagging?bucket=%s", getUcHost(m.Cfg.UseHTTPS), bucket)
return m.Client.CredentialedCallWithJson(context.Background(), m.Mac, auth.TokenQiniu, nil, "PUT", reqURL, nil, &tagging)
}
// ClearTagging 清空 Bucket 标签
func (m *BucketManager) ClearTagging(bucket string) error {
reqURL := fmt.Sprintf("%s/bucketTagging?bucket=%s", getUcHost(m.Cfg.UseHTTPS), bucket)
return m.Client.CredentialedCall(context.Background(), m.Mac, auth.TokenQiniu, nil, "DELETE", reqURL, nil)
}
// GetTagging 获取 Bucket 标签
func (m *BucketManager) GetTagging(bucket string) (tags map[string]string, err error) {
var tagging BucketTagging
reqURL := fmt.Sprintf("%s/bucketTagging?bucket=%s", getUcHost(m.Cfg.UseHTTPS), bucket)
if err = m.Client.CredentialedCall(context.Background(), m.Mac, auth.TokenQiniu, &tagging, "GET", reqURL, nil); err != nil {
return
}
tags = make(map[string]string, len(tagging.Tags))
for _, tag := range tagging.Tags {
tags[tag.Key] = tag.Value
}
return
}