/
multipart.go
108 lines (88 loc) · 2.04 KB
/
multipart.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
package easy
import (
"bytes"
"fmt"
"io"
"mime/multipart"
"net/http"
"net/textproto"
"os"
"path/filepath"
"strings"
)
type Multipart struct {
body *bytes.Buffer
writer *multipart.Writer
}
// Create a new multipart/form-data object
//
// Example:
//
// m := NewMultipart()
// // Insert k-v data
// err := m.Insert("key", "value")
// require.NoError(t, err)
// // Insert files
// err := m.InsertFile("key", file)
func NewMultipart() *Multipart {
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
return &Multipart{
body: body,
writer: writer,
}
}
// Add a string form
func (c *Multipart) Insert(key string, value string) error {
b := strings.NewReader(value)
part, err := c.writer.CreateFormField(key)
if err != nil {
return err
}
_, err = io.Copy(part, b)
if err != nil {
return err
}
return nil
}
// Add a file objects
//
// Example:
//
// file, err := os.Open("file path")
// require.NoError(t, err)
// m.InsertFile("file", file)
func (c *Multipart) InsertFile(key string, file *os.File) error {
contentType := detectFileContentType(file)
fileName := filepath.Base(file.Name())
mh := make(textproto.MIMEHeader)
mh.Set("Content-Type", contentType)
mh.Set("Content-Disposition", fmt.Sprintf(`form-data; name="%s"; filename="%s"`, key, fileName))
part, err := c.writer.CreatePart(mh)
if err != nil {
return err
}
_, err = io.Copy(part, file)
if err != nil {
return err
}
return nil
}
// Outputs a multipart/form-data format.
func (c *Multipart) Export() *bytes.Buffer {
c.writer.Close()
return c.body
}
// Outputs content-type
//
// ref. https://www.microfocus.com/documentation/idol/IDOL_12_0/MediaServer/Guides/html/English/Content/Shared_Admin/_ADM_POST_requests.htm#:~:text=In%20the%20multipart%2Fform%2Ddata,the%20data%20in%20the%20part.
func (c *Multipart) ContentType() string {
return c.writer.FormDataContentType()
}
func detectFileContentType(file *os.File) string {
buffer := make([]byte, 512)
file.Read(buffer)
contentType := http.DetectContentType(buffer)
file.Seek(0, 0)
return contentType
}