-
Notifications
You must be signed in to change notification settings - Fork 32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
remove duplicate in content type from bogus raw emails #1
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,6 +11,7 @@ import ( | |
"fmt" | ||
"io" | ||
"io/ioutil" | ||
"log" | ||
"mime" | ||
"mime/multipart" | ||
"mime/quotedprintable" | ||
|
@@ -26,6 +27,7 @@ import ( | |
func ParseMessage(r io.Reader) (*Message, error) { | ||
msg, err := mail.ReadMessage(&leftTrimReader{r: bufioReader(r)}) | ||
if err != nil { | ||
log.Println("ReadMessage") | ||
return nil, err | ||
} | ||
// decode any Q-encoded values | ||
|
@@ -58,7 +60,16 @@ func parseMessageWithHeader(headers Header, bodyReader io.Reader) (*Message, err | |
if contentType := headers.Get("Content-Type"); len(contentType) > 0 { | ||
mediaType, mediaTypeParams, err = mime.ParseMediaType(contentType) | ||
if err != nil { | ||
return nil, err | ||
// handle duplicate property bogus content type | ||
// and try to remove the duplicate to prevent parser error | ||
if strings.Index(err.Error(), "duplicate") > -1 { | ||
contentType = removeDuplicate(contentType) | ||
mediaType, mediaTypeParams, err = mime.ParseMediaType(contentType) | ||
} | ||
|
||
if err != nil { | ||
return nil, err | ||
} | ||
} | ||
} // Lack of contentType is not a problem | ||
|
||
|
@@ -93,6 +104,23 @@ func parseMessageWithHeader(headers Header, bodyReader io.Reader) (*Message, err | |
}, nil | ||
} | ||
|
||
// removeDuplicate removes duplicate from bogus content type preventing parsing of email | ||
func removeDuplicate(s string) string { | ||
m := make(map[string]bool) | ||
parts := strings.Split(s, ";") | ||
for _, p := range parts { | ||
if _, ok := m[p]; !ok { | ||
m[p] = true | ||
} | ||
} | ||
|
||
var cleaned string | ||
for k := range m { | ||
cleaned += k + ";" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need a space after the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nevermind, I got ahead of myself, it is a map not a slice/array. I guess you could use a |
||
} | ||
return cleaned | ||
} | ||
|
||
// readParts parses out the parts of a multipart body, including the preamble and epilogue. | ||
func readParts(bodyReader io.Reader, boundary string) ([]*Message, error) { | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I need to re-lookup content types, but isn't the very first entry a special case?
Golang map keys are random, so that
image/png
entry might get put at the back of the list.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good point, I'm reading this in the RFC 2046
Not sure if "In General" means "required" though? I can have the first attribute saved, and remove duplicate than returning first attr + the cleaned up ones?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That sounds good, I think
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or just keep them all in order with a slice beside the map...