-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmultipart.go
77 lines (68 loc) · 1.8 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
package sakuin
import (
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
"mime"
"mime/multipart"
"strings"
"go.uber.org/zap"
)
// ErrMissingBoundary represents a boundary value missing in a multipart form body.
var ErrMissingBoundary = errors.New("missing boundary")
type ContentTypeError struct {
ContentType string
}
func (e ContentTypeError) Error() string {
return fmt.Sprintf("invalid content type: %s", e.ContentType)
}
// ReadParts
func ReadParts(r io.Reader, contentType string) (metadata json.RawMessage, object []byte, err error) {
mediaType, params, err := mime.ParseMediaType(contentType)
if err != nil {
zap.L().Error("", zap.Error(err))
return nil, nil, err
}
if !strings.HasPrefix(mediaType, "multipart/form-data") {
zap.L().Error("unexpected media type", zap.String("content-type", mediaType))
return nil, nil, ContentTypeError{ContentType: mediaType}
}
zap.L().Debug("parsed media type", zap.String("media-type", mediaType), zap.Any("params", params))
boundary, ok := params["boundary"]
if !ok {
zap.L().Error("missing boundary")
return nil, nil, ErrMissingBoundary
}
var p *multipart.Part
mr := multipart.NewReader(r, boundary)
for {
p, err = mr.NextPart()
if err == io.EOF {
err = nil
return
}
if err != nil {
zap.L().Error("unexpected error when getting next part", zap.Error(err))
return
}
pName := p.FormName()
zap.L().Debug("read part", zap.String("name", pName))
switch pName {
case "metadata":
dec := json.NewDecoder(p)
err = dec.Decode(&metadata)
if err != nil {
zap.L().Error("unexpected error when decoding metadata part", zap.Error(err))
return
}
case "object":
object, err = ioutil.ReadAll(p)
if err != nil {
zap.L().Error("unexpected error when reading object content", zap.Error(err))
return
}
}
}
}