• 七牛云 go demo


    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
    ", 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, "
    header:", resp.Header, "
    ", 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)
    }
    

      

  • 相关阅读:
    [Leetcode]847. Shortest Path Visiting All Nodes(BFS|DP)
    [Lintcode]Word Squares(DFS|字符串)
    [Lintcode]Inorder Successor in Binary Search Tree(DFS)
    xampp搭建discuz论坛
    Codeforces Round #459 (Div. 2):D. MADMAX(记忆化搜索+博弈论)
    网址备份
    java并发系列
    java创建多线程
    (转)深入理解Java内存模型之系列篇
    (转)Java并发编程:线程池的使用
  • 原文地址:https://www.cnblogs.com/cdyboke/p/7341512.html
Copyright © 2020-2023  润新知