标签:上传 efault sdk flow write highlight yun public for
package main
import (
"bytes"
"crypto/hmac"
"crypto/sha1"
"encoding/base64"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"mime/multipart"
"net/http"
"os"
"path/filepath"
"time"
)
var (
AccessKey = "MYqxCWi4Nrv114F4LeLaD9ekYTgnNdgvrBkyVvRS"
SecretKey = "rHRBY7WTffwK5Na064oVm33sLKyg-Efph3KllhEa"
)
func main() {
/*官网文档 https://developer.qiniu.com/kodo/manual/1208/upload-token
用户根据业务需求,确定上传策略要素,构造出具体的上传策略。例如用户要向空间 my-bucket 上传一个名为 sunflower.jpg 的图片,授权有效期截止到 2015-12-31 00:00:00(该有效期指上传完成后在七牛生成文件的时间,而非上传的开始时间),并且希望得到图片的名称、大小、宽高和校验值。那么相应的上传策略各字段分别为:
scope = ‘my-bucket:sunflower.jpg‘
deadline = 1451491200
returnBody = ‘{
"name": $(fname),
"size": $(fsize),
"w": $(imageInfo.width),
"h": $(imageInfo.height),
"hash": $(etag)
}‘
*/
putPolicy := map[string]interface{}{}
putPolicy["scope"] = "public:qiniuyun.go"
putPolicy["deadline"] = time.Now().Unix() + int64(time.Hour/time.Second) //截至时间!!!一开始写了有效时长上去,而且1s是1e9 。。。
putPolicy["insertOnly"] = 0
putPolicy["returnBody"] = `{
"name": "$(fname)",
"size": "$(fsize)",
"w": "$(imageInfo.width)",
"h": "$(imageInfo.height)",
"hash": "$(etag)"
}`
putPolicyBytes, err := json.Marshal(putPolicy)
if err != nil {
panic(err.Error())
}
fmt.Println("putPolicy:", string(putPolicyBytes))
encodedPutPolicy := base64.URLEncoding.EncodeToString(putPolicyBytes)
fmt.Println("encodePutPolicy:", encodedPutPolicy)
/*官网文档
sign = hmac_sha1(encodedPutPolicy, "<SecretKey>")
#假设 SecretKey 为 MY_SECRET_KEY,实际签名为:
sign = "c10e287f2b1e7f547b20a9ebce2aada26ab20ef2"
注意:签名结果是二进制数据,此处输出的是每个字节的十六进制表示,以便核对检查。
*/
mac := hmac.New(sha1.New, []byte(SecretKey)) //坑点,顺序跟说的不一样???看了SDK才知道这样弄,不然一直bad token
mac.Write([]byte(encodedPutPolicy))
//sign := fmt.Sprintf("%x\n", mac.Sum(nil))
//encodeSign := base64.URLEncoding.EncodeToString([]byte(sign))
digest := mac.Sum(nil) //坑点
/*官网文档
encodedSign = urlsafe_base64_encode(sign)
#最终签名值为:
encodedSign = "wQ4ofysef1R7IKnrziqtomqyDvI="
*/
encodeSign := base64.URLEncoding.EncodeToString(digest)
fmt.Println("encodeSign:", encodeSign)
/*官网文档
uploadToken = AccessKey + ‘:‘ + encodedSign + ‘:‘ + encodedPutPolicy
#假设用户的 AccessKey 为 MY_ACCESS_KEY ,则最后得到的上传凭证应为:
uploadToken = "MY_ACCESS_KEY:wQ4ofysef1R7IKnrziqtomqyDvI=:eyJzY29wZSI6Im15LWJ1Y2tldDpzdW5mbG93ZXIuanBnIiwiZGVhZGxpbmUiOjE0NTE0OTEyMDAsInJldHVybkJvZHkiOiJ7XCJuYW1lXCI6JChmbmFtZSksXCJzaXplXCI6JChmc2l6ZSksXCJ3XCI6JChpbWFnZUluZm8ud2lkdGgpLFwiaFwiOiQoaW1hZ2VJbmZvLmhlaWdodCksXCJoYXNoXCI6JChldGFnKX0ifQ=="
注意:为确保客户端、业务服务器和七牛服务器对于授权截止时间的理解保持一致,需要同步校准各自的时钟。频繁返回 401 状态码时请先检查时钟同步性与生成 deadline 值的代码逻辑。
*/
uploadToken := AccessKey + ":" + encodeSign + ":" + encodedPutPolicy
form := map[string]string{"token": uploadToken, "key": "qiniuyun.go"}
newfileUploadRequest("https://up-z2.qbox.me", form, "file", "./qiniuyun.go")
}
func newfileUploadRequest(uri string, form map[string]string, formFileName, path string) error {
file, err := os.Open(path)
if err != nil {
return err
}
defer file.Close()
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
for key, val := range form {
err = writer.WriteField(key, val)
if err != nil {
return err
}
}
part, err := writer.CreateFormFile(formFileName, filepath.Base(path))
if err != nil {
return err
}
_, err = io.Copy(part, file)
if err != nil {
return err
}
err = writer.Close()
if err != nil {
return err
}
req, err := http.NewRequest("POST", uri, body)
if err != nil {
return err
}
req.Header.Set("Content-Type", writer.FormDataContentType())
req.Header.Set("Host", "upload.qiniu.com")
req.Header.Set("Content-Length", fmt.Sprint(body.Len()))
fmt.Println("reqHeader:", req.Header)
resp, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
Body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
fmt.Println("code:", resp.StatusCode, "\nheader:", resp.Header, "\n", string(Body))
return nil
}
//SDK demo
package main
import (
"context"
"fmt"
"os"
"strings"
"sync"
"time"
"github.com/qiniu/api.v7/auth/qbox"
"github.com/qiniu/api.v7/storage"
)
var (
accessKey = "MYqxCWi4Nrv114F4LeLaD9ekYTgnNdgvrBkyVvRS"
secretKey = "rHRBY7WTffwK5Na064oVm33sLKyg-Efph3KllhEa"
fileDir = "../src/debugPublic"
)
var lock = sync.RWMutex{}
func main() {
broweDir(fileDir)
lock.Lock()
lock.Unlock()
}
func broweDir(path string) {
lock.RLock()
defer lock.RUnlock()
fmt.Println("broweDir:", path)
dir, err := os.Open(path)
if err != nil {
panic(err.Error())
}
defer dir.Close()
names, err := dir.Readdirnames(-1)
if err != nil {
panic(err.Error())
}
for _, name := range names {
dirPath := path + "/" + name
if !isDir(dirPath) {
if updateAfter(dirPath, time.Now().Add(-time.Hour*2)) {
fileName := strings.TrimPrefix(dirPath, fileDir+"/")
uploadImage(dirPath, "debugpublic:"+fileName, fileName)
}
continue
}
//fmt.Println(dirPath, "is dir")
broweDir(dirPath)
}
}
func updateAfter(path string, t time.Time) bool {
fileInfo, err := os.Stat(path)
if err != nil {
panic(err.Error())
}
return fileInfo.ModTime().After(t)
}
func isDir(path string) bool {
fileInfo, err := os.Stat(path)
if err != nil {
panic(err.Error())
}
return fileInfo.IsDir()
}
/*
localFile := "qiniuyun.go"
bucket := "public:qiniuyun.go"
key := "qiniuyun.go"
*/
func uploadImage(localFile, bucket, key string) {
// 自定义返回值结构体
type MyPutRet struct {
Key string
Hash string
Fsize int
Bucket string
Name string
}
// 使用 returnBody 自定义回复格式
putPolicy := storage.PutPolicy{
Scope: bucket,
ReturnBody: `{"key":"$(key)","hash":"$(etag)","fsize":$(fsize),"bucket":"$(bucket)","name":"$(x:name)"}`,
InsertOnly: 0,
}
mac := qbox.NewMac(accessKey, secretKey)
upToken := putPolicy.UploadToken(mac)
cfg := storage.Config{}
formUploader := storage.NewFormUploader(&cfg)
ret := MyPutRet{}
putExtra := storage.PutExtra{
Params: map[string]string{
"x:name": "github logo",
},
}
err := formUploader.PutFile(context.Background(), &ret, upToken, key, localFile, &putExtra)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(ret.Bucket, ret.Key, ret.Fsize, ret.Hash, ret.Name)
}
标签:上传 efault sdk flow write highlight yun public for
原文地址:http://www.cnblogs.com/cdyboke/p/7341512.html