-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathmultipart.go
More file actions
65 lines (59 loc) · 1.53 KB
/
Copy pathmultipart.go
File metadata and controls
65 lines (59 loc) · 1.53 KB
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
// Handle multipart messages.
package emlparser
import (
"bytes"
"errors"
"io"
"io/ioutil"
"mime"
"mime/multipart"
"regexp"
)
type Part struct {
Type string
Charset string
Data []byte
Headers map[string][]string
}
// Parse the body of a message, using the given content-type. If the content
// type is multipart, the parts slice will contain an entry for each part
// present; otherwise, it will contain a single entry, with the entire (raw)
// message contents.
func parseBody(ct string, body []byte) (parts []Part, err error) {
_, ps, err := mime.ParseMediaType(ct)
if err != nil {
return
}
// if mt != "multipart/alternative" {
// parts = append(parts, Part{ct, body, nil})
// return
// }
boundary, ok := ps["boundary"]
if !ok {
return nil, errors.New("multipart specified without boundary")
}
r := multipart.NewReader(bytes.NewReader(body), boundary)
p, err := r.NextPart()
for err == nil {
data, _ := ioutil.ReadAll(p) // ignore error
var subparts []Part
subparts, err = parseBody(p.Header["Content-Type"][0], data)
//if err == nil then body have sub multipart, and append him
if err == nil {
parts = append(parts, subparts...)
} else {
contenttype := regexp.MustCompile("(?is)charset=(.*)").FindStringSubmatch(p.Header["Content-Type"][0])
charset := "UTF-8"
if len(contenttype) > 1 {
charset = contenttype[1]
}
part := Part{p.Header["Content-Type"][0], charset, data, p.Header}
parts = append(parts, part)
}
p, err = r.NextPart()
}
if err == io.EOF {
err = nil
}
return
}