|
|
|
|
// 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, "a, "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
|
|
|
|
|
}
|