Documentation
¶
Overview ¶
包 qiniupkg.com/api.v7/kodocli 提供了在客户端调用七牛云存储部分服务的能力
客户端,严谨说是非可信环境,主要是指在用户端执行的环境,比如:Android/iOS 设备、Windows/Mac/Linux 桌面环境、也包括浏览器(如果浏览器能够执行 Go 语言代码的话)。
注意,在这种场合下您不应该在任何地方配置 AccessKey/SecretKey。泄露 AccessKey/SecretKey 如同泄露您的用户名/密码一样十分危险,会影响您的数据安全。
第一个问题是如何上传文件。因为是在非可信环境,所以我们首先是要授予它有上传文件的能力。答案是给它颁发上传凭证。假设服务端也是 Go 语言,那么:
import "qiniupkg.com/api.v7/kodo"
kodo.SetMac("your-access-key", "your-secret-key") // 配置 AccessKey/SecretKey
zone := 0
c := kodo.New(zone, nil) // 创建一个 Client 对象
bucket := "your-bucket-name"
key := "foo/bar.jpg"
policy := &kodo.PutPolicy{
Scope: bucket + ":" + key, // 上传文件的限制条件,这里限制只能上传一个名为 "foo/bar.jpg" 的文件
Expires: 3600, // 这是限制上传凭证(uptoken)的过期时长,3600 是一小时
...
}
uptoken := c.MakeUptoken(policy) // 生成上传凭证
生成上传凭证之后,通过某种方式将 uptoken 发送到客户端。这样客户端就可以上传文件了:
zone := 0
uploader := kodocli.NewUploader(zone, nil)
ctx := context.Background()
key := "foo/bar.jpg"
localFile := "/your/local/image/file.jpg"
err := uploader.PutFile(ctx, nil, uptoken, key, localFile, nil)
if err != nil {
... // 上传文件失败处理
return
}
注意,如果客户端上传的 key 不是 uptoken 所要求的 "foo/bar.jpg",那么上传就会被拒绝。
如果我们希望一个 uptoken 可以上传多个文件,那么服务端颁发 uptoken 的代码需要调整下:
bucket := "your-bucket-name"
policy := &kodo.PutPolicy{
Scope: bucket, // 上传文件的限制条件,这里是只限制了要上传到 "your-bucket-name" 空间
Expires: 3600, // 这是限制上传凭证(uptoken)的过期时长,3600 是一小时
...
}
uptoken := c.MakeUptoken(policy)
颁发这样的 uptoken 给客户端,客户端就可以用它上传任意名字(key)的文件,前提是服务器上还没有同名的文件。
特别需要注意的是,这种情况下服务端会拒绝已经有同名文件的上传请求,而不是覆盖服务器上已有的文件。这是出于数据安全的考虑。我们并不非常推荐 uptoken 复用的做法,除了注意文件名可能冲突外,还需要注意 uptoken 是有时效的,过期就需要重新向服务器申请新的上传凭证。
搞定文件的上传后,第二个问题是如何下载文件。如果是公开文件,我们只需要:
import "net/http" domain := "domain-of-your-bucket.com" // 您的空间绑定的域名,这个可以在七牛的Portal中查到 baseUrl := kodocli.MakeBaseUrl(domain, "foo/bar.jpg") // 得到下载 url resp, err := http.Get(baseUrl) ...
但是对于私有空间,事情要复杂一些,需要客户端向您的业务服务器申请下载该文件。业务服务器确认该用户有权访问,则返回一个临时有效的 privateUrl。具体如何生成 privateUrl,可以看服务端 SDK 相关的文档介绍。
Index ¶
- Constants
- Variables
- func BlockCount(fsize int64) int
- func MakeAuthTokenString(key, secret string, auth *AuthPolicy) string
- func MakeBaseUrl(domain, key string) (baseUrl string)
- func NewLogger() *logger
- func NewSectionReader(r io.Reader, n int64) *sectionReader
- func SetAppName(userApp string) error
- func SetLogger(logger Ilog)
- func SetSettings(v *Settings)
- type AuthPolicy
- type BlkputRet
- type CompleteMultipart
- type CompletePartsRet
- type FileType
- type Ilog
- type Part
- type PutExtra
- type PutRet
- type RputExtra
- type Settings
- type UploadConfig
- type UploadPartRet
- type Uploader
- func (p Uploader) Put2(ctx Context, ret interface{}, uptoken, key string, data io.ReaderAt, ...) error
- func (p Uploader) PutFile(ctx Context, ret interface{}, uptoken, key, localFile string, extra *PutExtra) (err error)
- func (p Uploader) PutFileWithoutKey(ctx Context, ret interface{}, uptoken, localFile string, extra *PutExtra) (err error)
- func (p Uploader) Rput(ctx Context, ret interface{}, uptoken string, key string, f io.ReaderAt, ...) error
- func (p Uploader) RputFile(ctx Context, ret interface{}, uptoken, key, localFile string, extra *RputExtra) (err error)
- func (p Uploader) RputFileWithoutKey(ctx Context, ret interface{}, uptoken, localFile string, extra *RputExtra) (err error)
- func (p Uploader) RputWithoutKey(ctx Context, ret interface{}, uptoken string, f io.ReaderAt, fsize int64, ...) error
- func (p Uploader) StreamUpload(ctx context.Context, ret interface{}, uptoken, key string, reader io.Reader, ...) error
- func (p Uploader) StreamUploadWithoutKey(ctx context.Context, ret interface{}, uptoken string, reader io.Reader, ...) error
- func (p Uploader) Upload(ctx context.Context, ret interface{}, uptoken string, key string, ...) error
- func (p Uploader) UploadWithParts(ctx context.Context, ret interface{}, uptoken string, key string, ...) error
- func (p Uploader) UploadWithoutKey(ctx context.Context, ret interface{}, uptoken string, f io.ReaderAt, ...) error
- func (p Uploader) UploadWithoutKeyWithParts(ctx context.Context, ret interface{}, uptoken string, f io.ReaderAt, ...) error
Constants ¶
const ( LOG_LEVEL_DEBUG = iota LOG_LEVEL_INFO LOG_LEVEL_WARN LOG_LEVEL_ERROR LOG_LEVEL_FATAL )
const ( TypeNormal = iota TypeLine )
const ( DontCheckCrc uint32 = 0 CalcAndCheckCrc = 1 )
const (
InvalidCtx = 701 // UP: 无效的上下文(bput),可能情况:Ctx非法或者已经被淘汰(太久未使用)
)
Variables ¶
var ( ErrInvalidPutProgress = errors.New("invalid put progress") ErrPutFailed = errors.New("resumable put failed") ErrUnmatchedChecksum = errors.New("unmatched checksum") )
var ( MaxContinuousFailureTimes = 5 MaxContinuousFailureDuration = 1 * time.Minute MaxFindHostsPrecent = 50 )
var ErrMd5NotMatch = httputil.NewError(406, "md5 not match")
Functions ¶
func BlockCount ¶
func MakeAuthTokenString ¶
func MakeAuthTokenString(key, secret string, auth *AuthPolicy) string
func MakeBaseUrl ¶
根据空间(Bucket)的域名,以及文件的 key,获得 baseUrl。 如果空间是 public 的,那么通过 baseUrl 可以直接下载文件内容。 如果空间是 private 的,那么需要对 baseUrl 进行私有签名得到一个临时有效的 privateUrl 进行下载。
func NewSectionReader ¶
func SetAppName ¶
设置使用这个SDK的应用程序名。userApp 必须满足 [A-Za-z0-9_\ \-\.]*
func SetSettings ¶
func SetSettings(v *Settings)
Types ¶
type AuthPolicy ¶
type AuthPolicy struct {
Scope string `json:"scope"`
IsPrefixalScope uint16 `json:"isPrefixalScope,omitempty"` // 若为非0,则Scope的key部分表示为前缀限定
CallbackUrl string `json:"callbackUrl,omitempty"`
CallbackHost string `json:"callbackHost,omitempty"`
CallbackBodyType string `json:"callbackBodyType,omitempty"`
CallbackBody string `json:"callbackBody,omitempty"`
CallbackFetchKey uint16 `json:"callbackFetchKey,omitempty"` // 先回调取得key再改名 https://pm.qbox.me/issues/11851
CallbackTimeout uint16 `json:"callbackTimeout,omitempty"` // 允许自定义超时需求 https://pm.qbox.me/issues/21576
Customer string `json:"customer,omitempty"`
EndUser string `json:"endUser,omitempty"`
Transform string `json:"transform,omitempty"`
FopTimeout uint32 `json:"fopTimeout,omitempty"`
Deadline int64 `json:"deadline"` // 截止时间(以秒为单位)原来是uint32 上限为到2106年 如果用户设置过期时间超过了这个上限就会鉴权失败 请各单位如果编译不过自行调整https://pm.qbox.me/issues/25718
Escape uint16 `json:"escape,omitempty"` // 是否允许存在转义符号
DetectMime uint16 `json:"detectMime,omitempty"`
Exclusive uint16 `json:"exclusive,omitempty"` // 若为非0, 即使Scope为"Bucket:key"的形式也是insert only
InsertOnly uint16 `json:"insertOnly,omitempty"` // Exclusive 的别名
ForceInsertOnly bool `json:"forceInsertOnly,omitempty"` // 若为true,即使上传hash相同的文件也会报文件已存在,优先级高于InsertOnly
ReturnBody string `json:"returnBody,omitempty"`
SignReturnBody uint16 `json:"signReturnBody,omitempty"` // 默认不开启签名,需要用户的 AK SK
ReturnURL string `json:"returnUrl,omitempty"`
FsizeMin int64 `json:"fsizeMin,omitempty"`
FsizeLimit int64 `json:"fsizeLimit,omitempty"`
MimeLimit string `json:"mimeLimit,omitempty"`
SaveKey string `json:"saveKey,omitempty"`
ForceSaveKey bool `json:"forceSaveKey,omitempty"`
PersistentOps string `json:"persistentOps,omitempty"`
PersistentNotifyUrl string `json:"persistentNotifyUrl,omitempty"`
PersistentPipeline string `json:"persistentPipeline,omitempty"`
Checksum string `json:"checksum,omitempty"`
Accesses []string `json:"accesses,omitempty"`
DeleteAfterDays uint32 `json:"deleteAfterDays,omitempty"`
FileType FileType `json:"fileType,omitempty"`
NotifyQueue string `json:"notifyQueue,omitempty"`
NotifyMessage string `json:"notifyMessage,omitempty"`
NotifyMessageType string `json:"notifyMessageType,omitempty"`
CustomEventMessage string `json:"customEventMessage,omitempty"`
//内部参数
OldFh string `json:"oldFh,omitempty"`
PutTime int64 `json:"putTime,omitempty"`
Cond string `json:"cond,omitempty"` //格式:condKey1=condVal1&condKey2=condVal2,支持hash、mime、fsize、putTime条件,只有条件匹配才会执行覆盖操作
}
type CompleteMultipart ¶
type CompleteMultipart struct {
Parts []Part `json:"parts"`
Fname string `json:"fname"`
MimeType string `json:"mimeType"`
Metadata map[string]string `json:"metadata"`
CustomVars map[string]string `json:"customVars"`
}
func (*CompleteMultipart) Len ¶
func (p *CompleteMultipart) Len() int
func (*CompleteMultipart) Less ¶
func (p *CompleteMultipart) Less(i, j int) bool
func (*CompleteMultipart) Sort ¶
func (p *CompleteMultipart) Sort()
func (*CompleteMultipart) Swap ¶
func (p *CompleteMultipart) Swap(i, j int)
type CompletePartsRet ¶
type Ilog ¶
type Ilog interface {
Debug(v ...interface{})
Info(v ...interface{})
Warn(v ...interface{})
Error(v ...interface{})
Fatal(v ...interface{})
}
type PutExtra ¶
type PutExtra struct {
// 可选,用户自定义参数,必须以 "x:" 开头。若不以x:开头,则忽略。
Params map[string]string
XMeta map[string]string
// 可选,当为 "" 时候,服务端自动判断。
MimeType string
//CRC32校验
Crc32 uint32
//Content-Md5 Trailer
Md5Trailer func() []byte
// 上传事件:进度通知。这个事件的回调函数应该尽可能快地结束。
OnProgress func(fsize, uploaded int64)
}
上传的额外可选项
type PutRet ¶
type PutRet struct {
Hash string `json:"hash"`
PersistentId string `json:"persistentId"`
Key string `json:"key"`
}
如果 uptoken 没有指定 ReturnBody,那么返回值是标准的 PutRet 结构
type RputExtra ¶
type RputExtra struct {
Params map[string]string // 可选。用户自定义参数,以"x:"开头 否则忽略
XMeta map[string]string // 可选。
MimeType string // 可选。
ChunkSize int // 可选。每次上传的Chunk大小
TryTimes int // 可选。尝试次数
Progresses []BlkputRet // 可选。上传进度
Notify func(blkIdx int, blkSize int, ret *BlkputRet) // 可选。进度提示(注意多个block是并行传输的)
NotifyErr func(blkIdx int, blkSize int, err error)
}
type UploadConfig ¶
type UploadPartRet ¶
type Uploader ¶
type Uploader struct {
Conn rpc.Client
UpHosts []string
UploadPartSize int64
Concurrency int
UseBuffer bool
}
func NewUploader ¶
func NewUploader(zone int, cfg *UploadConfig) (p Uploader)
func (Uploader) Put2 ¶
func (p Uploader) Put2( ctx Context, ret interface{}, uptoken, key string, data io.ReaderAt, size int64, extra *PutExtra) error
上传一个文件,普通上传。
ctx 是请求的上下文。 ret 是上传成功后返回的数据。如果 uptoken 中没有设置 CallbackUrl 或 ReturnBody,那么返回的数据结构是 PutRet 结构。 uptoken 是由业务服务器颁发的上传凭证。 key 是要上传的文件访问路径。比如:"foo/bar.jpg"。注意我们建议 key 不要以 '/' 开头。另外,key 为空字符串是合法的。 data 是文件内容的访问接口(io.Reader)。 fsize 是要上传的文件大小。 extra 是上传的一些可选项。详细见 PutExtra 结构的描述。
func (Uploader) PutFile ¶
func (p Uploader) PutFile( ctx Context, ret interface{}, uptoken, key, localFile string, extra *PutExtra) (err error)
上传一个文件。 和 Put 不同的只是一个通过提供文件路径来访问文件内容,一个通过 io.Reader 来访问。
ctx 是请求的上下文。 ret 是上传成功后返回的数据。如果 uptoken 中没有设置 CallbackUrl 或 ReturnBody,那么返回的数据结构是 PutRet 结构。 uptoken 是由业务服务器颁发的上传凭证。 key 是要上传的文件访问路径。比如:"foo/bar.jpg"。注意我们建议 key 不要以 '/' 开头。另外,key 为空字符串是合法的。 localFile 是要上传的文件的本地路径。 extra 是上传的一些可选项。详细见 PutExtra 结构的描述。
func (Uploader) PutFileWithoutKey ¶
func (p Uploader) PutFileWithoutKey( ctx Context, ret interface{}, uptoken, localFile string, extra *PutExtra) (err error)
上传一个文件。文件的访问路径(key)自动生成。 如果 uptoken 中设置了 SaveKey,那么按 SaveKey 要求的规则生成 key,否则自动以文件的 hash 做 key。 和 RputWithoutKey 不同的只是一个通过提供文件路径来访问文件内容,一个通过 io.Reader 来访问。
ctx 是请求的上下文。 ret 是上传成功后返回的数据。如果 uptoken 中没有设置 CallbackUrl 或 ReturnBody,那么返回的数据结构是 PutRet 结构。 uptoken 是由业务服务器颁发的上传凭证。 localFile 是要上传的文件的本地路径。 extra 是上传的一些可选项。详细见 PutExtra 结构的描述。
func (Uploader) Rput ¶
func (p Uploader) Rput( ctx Context, ret interface{}, uptoken string, key string, f io.ReaderAt, fsize int64, extra *RputExtra) error
上传一个文件,支持断点续传和分块上传。
ctx 是请求的上下文。 ret 是上传成功后返回的数据。如果 uptoken 中没有设置 CallbackUrl 或 ReturnBody,那么返回的数据结构是 PutRet 结构。 uptoken 是由业务服务器颁发的上传凭证。 key 是要上传的文件访问路径。比如:"foo/bar.jpg"。注意我们建议 key 不要以 '/' 开头。另外,key 为空字符串是合法的。 f 是文件内容的访问接口。考虑到需要支持分块上传和断点续传,要的是 io.ReaderAt 接口,而不是 io.Reader。 fsize 是要上传的文件大小。 extra 是上传的一些可选项。详细见 RputExtra 结构的描述。
func (Uploader) RputFile ¶
func (p Uploader) RputFile( ctx Context, ret interface{}, uptoken, key, localFile string, extra *RputExtra) (err error)
上传一个文件,支持断点续传和分块上传。 和 Rput 不同的只是一个通过提供文件路径来访问文件内容,一个通过 io.ReaderAt 来访问。
ctx 是请求的上下文。 ret 是上传成功后返回的数据。如果 uptoken 中没有设置 CallbackUrl 或 ReturnBody,那么返回的数据结构是 PutRet 结构。 uptoken 是由业务服务器颁发的上传凭证。 key 是要上传的文件访问路径。比如:"foo/bar.jpg"。注意我们建议 key 不要以 '/' 开头。另外,key 为空字符串是合法的。 localFile 是要上传的文件的本地路径。 extra 是上传的一些可选项。详细见 RputExtra 结构的描述。
func (Uploader) RputFileWithoutKey ¶
func (p Uploader) RputFileWithoutKey( ctx Context, ret interface{}, uptoken, localFile string, extra *RputExtra) (err error)
上传一个文件,支持断点续传和分块上传。文件的访问路径(key)自动生成。 如果 uptoken 中设置了 SaveKey,那么按 SaveKey 要求的规则生成 key,否则自动以文件的 hash 做 key。 和 RputWithoutKey 不同的只是一个通过提供文件路径来访问文件内容,一个通过 io.ReaderAt 来访问。
ctx 是请求的上下文。 ret 是上传成功后返回的数据。如果 uptoken 中没有设置 CallbackUrl 或 ReturnBody,那么返回的数据结构是 PutRet 结构。 uptoken 是由业务服务器颁发的上传凭证。 localFile 是要上传的文件的本地路径。 extra 是上传的一些可选项。详细见 RputExtra 结构的描述。
func (Uploader) RputWithoutKey ¶
func (p Uploader) RputWithoutKey( ctx Context, ret interface{}, uptoken string, f io.ReaderAt, fsize int64, extra *RputExtra) error
上传一个文件,支持断点续传和分块上传。文件的访问路径(key)自动生成。 如果 uptoken 中设置了 SaveKey,那么按 SaveKey 要求的规则生成 key,否则自动以文件的 hash 做 key。
ctx 是请求的上下文。 ret 是上传成功后返回的数据。如果 uptoken 中没有设置 CallbackUrl 或 ReturnBody,那么返回的数据结构是 PutRet 结构。 uptoken 是由业务服务器颁发的上传凭证。 f 是文件内容的访问接口。考虑到需要支持分块上传和断点续传,要的是 io.ReaderAt 接口,而不是 io.Reader。 fsize 是要上传的文件大小。 extra 是上传的一些可选项。详细见 RputExtra 结构的描述。