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 结构的描述。