Skip to content

Instantly share code, notes, and snippets.

@widuu
Last active August 29, 2015 14:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save widuu/91446f2450cf969c586c to your computer and use it in GitHub Desktop.
Save widuu/91446f2450cf969c586c to your computer and use it in GitHub Desktop.
package main
import (
"bytes"
"crypto/hmac"
"crypto/sha1"
"encoding/base64"
"encoding/json"
"flag"
"fmt"
"io"
"io/ioutil"
"mime/multipart"
"net/http"
"os"
"path/filepath"
"strconv"
"strings"
"time"
)
type Policy struct {
Scope string `json:"scope"`
Deadline int `json:"deadline"`
ReturnBody string `json:"returnBody"`
}
type ret struct {
Name string
Size int
W string
h string
Hash string
}
const (
SK = "your sk"
AK = "your ak"
BUCKET = "your bucket"
)
var Typefile = flag.String("type", "", "input dir or file")
func main() {
flag.Parse()
if *Typefile == "" {
usage()
return
}
switch *Typefile {
case "file":
if flag.NArg() < 1 {
fmt.Println("请输入文件名称")
return
}
for _, v := range flag.Args() {
f, err := os.Open(v)
defer f.Close()
if os.IsNotExist(err) {
fmt.Println("文件不存在")
return
}
postFile(v)
}
case "dir":
if flag.NArg() < 1 {
fmt.Println("请输入目录名称")
return
}
if flag.NArg() > 1 {
fmt.Println("目录只支持一个")
return
}
dir := flag.Args()
uf, _ := os.Stat(dir[0])
if !uf.IsDir() {
fmt.Println("不是目录")
return
}
err := filepath.Walk(dir[0], func(path string, f os.FileInfo, err error) error {
if f == nil {
return err
}
if f.IsDir() {
return nil
}
postFile(path)
return nil
})
if err != nil {
fmt.Println("上传错误")
}
break
default:
fmt.Println("-type 需要指定file或dir")
return
}
}
func postFile(filename string) error {
bodyBuf := &bytes.Buffer{}
bodyWrite := multipart.NewWriter(bodyBuf)
filewriter, err := bodyWrite.CreateFormFile("file", filename)
if err != nil {
fmt.Println("写入文件失败")
return err
}
fh, err := os.Open(filename)
if err != nil {
fmt.Println("error opening error")
return err
}
defer fh.Close()
_, err = io.Copy(filewriter, fh)
if err != nil {
return err
}
contentType := bodyWrite.FormDataContentType()
Token := getToken(filename)
bodyWrite.WriteField("token", Token)
bodyWrite.WriteField("key", filename)
bodyWrite.Close()
resp, err := http.Post("http://upload.qiniu.com", contentType, bodyBuf)
if err != nil {
return err
}
defer resp.Body.Close()
resp_body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
var r ret
if resp.StatusCode == 200 {
json.Unmarshal(resp_body, &r)
fmt.Printf("文件%s上传成功,大小%d,Hash值%s\r\n", r.Name, r.Size, r.Hash)
}
return nil
}
func getToken(name string) string {
h1 := time.Now().Add(10800 * time.Second).Unix()
d, _ := strconv.Atoi(strconv.FormatInt(h1, 10))
var s = &Policy{Scope: BUCKET + ":" + name, Deadline: d, ReturnBody: "{\"name\":$(fname),\"size\":$(fsize),\"w\":$(imageInfo.width),\"h\":$(imageInfo.height),\"hash\":$(etag)}"}
b, err := json.Marshal(s)
if err != nil {
fmt.Println(err)
}
encodedPutPolicy := base64.StdEncoding.EncodeToString(b)
encodedPutPolicy = strings.Replace(encodedPutPolicy, "+", "-", -1)
encodedPutPolicy = strings.Replace(encodedPutPolicy, "/", "_", -1)
mac := hmac.New(sha1.New, []byte(SK))
mac.Write([]byte(encodedPutPolicy))
sign := mac.Sum(nil)
encodedSign := base64.StdEncoding.EncodeToString(sign)
encodedSign = strings.Replace(encodedSign, "+", "-", -1)
encodedSign = strings.Replace(encodedSign, "/", "_", -1)
uploadtoken := AK + ":" + string(encodedSign) + ":" + string(encodedPutPolicy)
return uploadtoken
}
func usage() {
var cmd string = `
Usage:
fileupload command [arguments]
The commands are:
-type file or dir
plase write file list after -type (file|dir)
`
fmt.Println(cmd)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment