-
Notifications
You must be signed in to change notification settings - Fork 1
/
s3.go
93 lines (74 loc) · 1.72 KB
/
s3.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
package main
import (
"bytes"
"crypto/hmac"
"crypto/md5"
"crypto/sha1"
"encoding/base64"
"fmt"
"io"
"io/ioutil"
"log"
"net/http"
"os"
"strings"
"time"
)
var (
S3KEY string
S3SECRET string
S3PROVIDER string
S3BUCKET string
S3DIRECTORY string
S3ACL string
)
func s3timestamp() string {
return time.Now().UTC().Format(time.RFC1123Z)
}
func s3sign(strs ...string) string {
hash := hmac.New(sha1.New, []byte(S3SECRET))
hash.Write([]byte(strings.Join(strs, "\n")))
return base64.StdEncoding.EncodeToString(hash.Sum(nil))
}
func s3put(fname filename) bool {
file, err := os.Open(fname)
if err != nil {
log.Println(err.Error())
return false
}
chksum := md5.New()
if _, err := io.Copy(chksum, file); err != nil {
log.Println(err.Error())
return false
}
contentmd5 := base64.StdEncoding.EncodeToString(chksum.Sum(nil))
content, _ := ioutil.ReadFile(fname)
contenttype := http.DetectContentType(content)
timestamp := s3timestamp()
destination := strings.Join([]string{S3BUCKET, S3DIRECTORY, _uuid(fname)}, "/")
signature := s3sign(
"PUT",
contentmd5,
contenttype,
timestamp,
"x-amz-acl:"+S3ACL,
"/"+destination,
)
endpoint := fmt.Sprintf("https://%s/%s", S3PROVIDER, destination)
client := &http.Client{}
q, err := http.NewRequest("PUT", endpoint, bytes.NewReader(content))
q.Header.Add("Date", timestamp)
q.Header.Add("Content-Type", contenttype)
q.Header.Add("Content-MD5", contentmd5)
q.Header.Add("X-AMZ-ACL", S3ACL)
q.Header.Add("Authorization", fmt.Sprintf("AWS %s:%s", S3KEY, signature))
r, err := client.Do(q)
if err != nil {
return false
}
c, _ := ioutil.ReadAll(r.Body)
fmt.Println(r.Status, string(c))
fmt.Println(endpoint)
file.Close()
return true
}