/
publish.go
150 lines (129 loc) · 3.8 KB
/
publish.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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
package create
import (
"bytes"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
"github.com/aleph-im/aleph-sdk-go/messages"
"io"
"mime/multipart"
"net/http"
"os"
"strings"
"github.com/imroc/req"
)
type PushResponse struct {
Hash string `json:"hash"`
}
type StandardPushConfiguration struct {
Value interface{}
APIServer string
StorageEngine messages.StorageEngine
}
type PutContentConfiguration struct {
Message *messages.BaseMessage
Content interface{}
InlineRequested bool
StorageEngine messages.StorageEngine
APIServer string
}
type FilePushConfiguration struct {
APIServer string
StorageEngine messages.StorageEngine
Key string
Value io.Reader
}
func PushToStorageEngine(spc StandardPushConfiguration) (*PushResponse, error) {
url := spc.APIServer + "/api/v0/" + strings.ToLower(spc.StorageEngine) + "/add_json"
requester := req.New()
serialized, err := json.Marshal(spc.Value)
if err != nil {
return nil, fmt.Errorf("failed to marshal value: %v", err)
}
header := make(http.Header)
header.Set("Content-Type", "application/json")
response, err := requester.Post(url, serialized, header)
if err != nil {
return nil, fmt.Errorf("POST request has failed: %v", err)
}
buffer := &PushResponse{}
err = response.ToJSON(buffer)
if err != nil {
return nil, fmt.Errorf("failed to convert response to JSON: %v", err)
}
return buffer, nil
}
func PutContentToStorageEngine(pcc PutContentConfiguration) error {
if pcc.InlineRequested {
serialized, err := json.Marshal(pcc.Content)
if err != nil {
return fmt.Errorf("failed to marshal content: %v", err)
}
if len(serialized) > 150000 {
pcc.InlineRequested = false
} else {
pcc.Message.ItemType = messages.IT_INLINE
pcc.Message.ItemContent = string(serialized)
hasher := sha256.New()
_, err := hasher.Write(serialized)
if err != nil {
return fmt.Errorf("failed to write: %v", err)
}
pcc.Message.ItemHash = hex.EncodeToString(hasher.Sum(nil))
}
}
if !pcc.InlineRequested {
pcc.Message.ItemType = pcc.StorageEngine
spc := StandardPushConfiguration{
Value: pcc.Content,
APIServer: pcc.APIServer,
StorageEngine: pcc.StorageEngine,
}
response, err := PushToStorageEngine(spc)
if err != nil {
return fmt.Errorf("failed to push to desired storage engine: %v", err)
}
pcc.Message.ItemHash = response.Hash
}
return nil
}
func PushFileToStorageEngine(configuration FilePushConfiguration) (string, error) {
var buffer bytes.Buffer
var fileWriter io.Writer
var err error
writer := multipart.NewWriter(&buffer)
if x, ok := configuration.Value.(io.Closer); ok {
defer x.Close()
}
if x, ok := configuration.Value.(*os.File); ok {
if fileWriter, err = writer.CreateFormFile(configuration.Key, x.Name()); err != nil {
return "", fmt.Errorf("failed to create form file: %v", err)
}
} else {
if fileWriter, err = writer.CreateFormField(configuration.Key); err != nil {
return "", fmt.Errorf("failed to create form field: %v", err)
}
}
if _, err = io.Copy(fileWriter, configuration.Value); err != nil {
return "", fmt.Errorf("failed to perform copy: %v", err)
}
err = writer.Close()
if err != nil {
return "", fmt.Errorf("failed to close writer: %v", err)
}
url := configuration.APIServer + "/api/v0/" + strings.ToLower(configuration.StorageEngine) + "/add_file"
requester := req.New()
header := make(http.Header)
header.Set("Content-Type", writer.FormDataContentType())
response, err := requester.Post(url, &buffer, header)
if err != nil {
return "", fmt.Errorf("POST request has failed: %v", err)
}
placeholder := &PushResponse{}
err = json.Unmarshal(response.Bytes(), &placeholder)
if err != nil {
return "", fmt.Errorf("failed to unmarshal store response: %v", err)
}
return placeholder.Hash, nil
}