七牛云 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\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)
}

  

时间: 2024-10-27 08:42:55

七牛云 go demo的相关文章

CKeditor七牛云JS SDK前端上传插件修改

七牛云官方有放出JS SDK,没有我想使用的CKeditor前端上传插件,所以结合七牛官方的Javascript SDK对CKeditor做了一些修改使它能够直接上传到七牛云,又同时保留了上传到本地服务的接口. 优点和缺点1.在前端上传到七牛云,不消耗服务器带宽和流量.空间.2.保留了CKeditor上传到自己服务器的能力.3.支持拖拽和剪切板黏贴图片上传(因为是保存为png格式,建议只黏贴色彩单调的图片,要不然图片会很大,浪费流量).4.拖拽和剪切板黏贴图片.不支持4M以上的文件,因为没有分块

七牛云实现js上传

七牛云的官方API写的一塌糊涂.最主要的,还是版本兼容的问题. 一.引入文件 引入了两个文件: 1.jquery-1.10.2.min.js 2.plupload.full.min.js 3.qiniu.js 版本太重要了.我提供了下载地址. 二.html代码 <p class="tip1">本demo实现的图片预览功能需要浏览器支持data URL,IE8+以及其他标准浏览器都是支持的</p> <div class="btn-wraper&qu

Android开发中使用七牛云存储进行图片上传下载

Android开发中的图片存储本来就是比较耗时耗地的事情,而使用第三方的七牛云,便可以很好的解决这些后顾之忧,最近我也是在学习七牛的SDK,将使用过程在这记录下来,方便以后使用. 先说一下七牛云的存储原理,上面这幅图片是官方给出的原理图,表述当然比较清晰了.可以看出,要进行图片上传的话可以分为五大步: 1. 客户端用户登录到APP的账号系统里面: 2. 客户端上传文件之前,需要向业务服务器申请七牛的上传凭证,这个凭证由业务服务器使用七牛提供的服务端SDK生成: 3. 客户端使用七牛提供的客户端S

使用七牛云存储上传文件学习案例

最近学习了使用七牛云储存上传文件的经验过程,和大家分享一下.语言:C# 七牛云储存用户注册地址:https://portal.qiniu.com/signup?code=3lciek5byj2oi 起初看七牛云储存官方的开发文档,按照上面的说的进行配置的过程中,遇到了2个问题,一个是公司网络的问题(泪奔,网管拒绝了对七牛等云储存应用的上传的请求).另一个是开发文档中配置提示不够完善,也许是鄙人没有找到. 开发文档URL:http://developer.qiniu.com/docs/v6/sdk

iOS 七牛云上传并获取图片----【客户端】

       最近做了七牛云存储的有关内容,涉及到与后台交互获取验证的token,无奈,后台自命清高,不与理会,没办法呀,于是自己搞呗.首先呢在在七牛上注册一个账号,然后呢添加一个存储空间这时候空间名是用来识别存储空间的位置,而地区的选择则是设置存储七牛服务器的位置,那么选择一个公开空间免费试用就可以了~~        创建好账号就是查看官方文档编写demo的流程了,顺便附带一个下载地址:http://developer.qiniu.com/code/v7/sdk/objc.html    下

第一次的go访问七牛云存储的api

官网看api,如何使用,对于第一次使用go语言的我略显吃力,嘿嘿,看了个demo就会了,而且超简单 package main import ( "fmt" . "github.com/qiniu/api/conf" "github.com/qiniu/api/fop"//这个地方是坑,网上的api.如果下载下来,请改本地地址,这里是网络地址,而且官网没提示要引用下面几个 "github.com/qiniu/api/io" &q

七牛云--开发笔记

开发文档:https://developer.qiniu.com/kodo/sdk/1241/php 一.下载官方SDK : https://github.com/qiniu/php-sdk/releases?ref=developer.qiniu.com 下载源代码包后,解压到您的项目中. 然后在您的项目中引入 autoloader: 基本使用方法 安装好 SDK 后,接下来介绍如何使用 SDK.在使用 SDK 之前,需要注册一个七牛帐号,并登录控制台获取一对有效的AccessKey和Secr

引入七牛云js上传

云存储有很多种方式,这里介绍前端页面直接通过js上传的方式,应为这种方式页面友好,对浏览器压力也小 云存储也有很多好处: 1.释放服务器磁盘空间 2.减轻服务器磁盘IO压力 3.减轻服务器带宽压力 4.服务器故障无影响 遇到的坑: 1.bad uptoken 2.error:incorrect zone, please use up-z2.qiniu.com 3.怎样获取文件名 4.怎样设置上传路径 5.怎样获取外部链接 6.怎样获取上传进度 bad uptoken: 在官方文档里面,七牛要求服

Laravel项目中使用markdown编辑器及图片粘贴上传七牛云

本文为转载,原文:http://www.chairis.cn/blog/article/15 Markdown Markdown是一种可以使用普通文本编辑器编写的标记语言,通过简单的标记语法,它可以使普通文本内容具有一定的格式.本次我们选用的编辑器是: Editor.md,官网中也有很详细的介绍.从官网中下载安装下载的内容中,也有很多demo可以借鉴.在下载的包中,去除一些多余的内容,只保留我们需要的内容,然后加到项目的public目录下,如下图红色框内的内容: 项目中使用 在项目中使用edit