-
Notifications
You must be signed in to change notification settings - Fork 6
/
main.go
125 lines (98 loc) · 2.84 KB
/
main.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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
package main
import (
"context"
"encoding/base64"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"os"
"github.com/Azure/azure-storage-blob-go/azblob"
"github.com/direktiv/direktiv-apps/pkg/direktivapps"
)
type AzureBlobUpload struct {
Container string `json:"container"`
Account string `json:"storage-account"`
AccountKey string `json:"storage-account-key"`
Data string `json:"data"`
Blobname string `json:"upload-name"`
}
type AzureBlobOutput struct {
BlobURL string `json:"blob-url"`
}
const code = "com.azure-upload.error"
func main() {
direktivapps.StartServer(AzureUpload)
}
func AzureUpload(w http.ResponseWriter, r *http.Request) {
obj := new(AzureBlobUpload)
_, err := direktivapps.Unmarshal(obj, r)
if err != nil {
direktivapps.RespondWithError(w, code, err.Error())
return
}
ctx := context.Background()
os.Setenv("AZURE_STORAGE_ACCOUNT", obj.Account)
os.Setenv("AZURE_STORAGE_ACCESS_KEY", obj.AccountKey)
credential, err := azblob.NewSharedKeyCredential(obj.Account, obj.AccountKey)
if err != nil {
direktivapps.RespondWithError(w, code, err.Error())
return
}
p := azblob.NewPipeline(credential, azblob.PipelineOptions{})
decoded, err := base64.StdEncoding.DecodeString(obj.Data)
if err != nil {
direktivapps.RespondWithError(w, code, err.Error())
return
}
u, _ := url.Parse(fmt.Sprintf("https://%s.blob.core.windows.net/%s", obj.Account, obj.Container))
containerURL := azblob.NewContainerURL(*u, p)
blobURL := containerURL.NewBlockBlobURL(obj.Blobname)
err = ioutil.WriteFile(obj.Blobname, decoded, 0700)
if err != nil {
direktivapps.RespondWithError(w, code, err.Error())
return
}
file, err := os.Open(obj.Blobname)
if err != nil {
direktivapps.RespondWithError(w, code, err.Error())
return
}
defer file.Close()
contentType, err := GetFileContentType(file)
if err != nil {
direktivapps.RespondWithError(w, code, err.Error())
return
}
file.Seek(0, 0)
// Upload file
resp, err := azblob.UploadFileToBlockBlob(ctx, file, blobURL, azblob.UploadToBlockBlobOptions{
BlobHTTPHeaders: azblob.BlobHTTPHeaders{
ContentType: contentType,
},
})
if err != nil {
direktivapps.RespondWithError(w, code, err.Error())
return
}
httpR := resp.Response()
defer httpR.Body.Close()
data, err := ioutil.ReadAll(httpR.Body)
if err != nil {
direktivapps.RespondWithError(w, code, err.Error())
return
}
direktivapps.Respond(w, data)
}
func GetFileContentType(out *os.File) (string, error) {
// Only the first 512 bytes are used to sniff the content type.
buffer := make([]byte, 512)
_, err := out.Read(buffer)
if err != nil {
return "", err
}
// Use the net/http package's handy DectectContentType function. Always returns a valid
// content-type by returning "application/octet-stream" if no others seemed to match.
contentType := http.DetectContentType(buffer)
return contentType, nil
}