首页 > 代码库 > 七牛云 go demo

七牛云 go demo

package mainimport (	"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 demopackage mainimport (	"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)}

  

七牛云 go demo