mime: duplicate parameter name error
I received an email. The Content-Type section contains two charset fields, but the contents of the two charset fields only differ in case. When parsing the email, the following error was reported.
letters.EmailParser.Parse: cannot parse part "multipart/mixed" with boundary "33cef21196996d27cfa60191f95633db16e292796ab85c9c48e957fb63e7": letters.parsers.parsePart: cannot parse Content-Type: letters.parsers.parseContentTypeHeader: cannot parse Content-Type "text/html; charset=utf-8; charset=UTF-8": letters.parsers.parseDefaultMediaType: cannot parse Content-Type "text/html; charset=utf-8; charset=UTF-8": mime: duplicate parameter name
Any ideas?
Thank you for opening the issue, @iceking2nd.
I believe that the best way to handle this and other similar edge cases will be offered in https://github.com/mnako/letters/pull/134. Once the discussion and review there is finished, I will come back to this issue and add an example of how a custom parser can be used to solve this.
@iceking2nd , I have looked into your issue now and found out that the ParseMediaType(v string) that we are using treats duplicate parameter names as incorrect, but allow them if they are equal. We are doing a case-sensitive comparison, so "charset" and "CHARSET" are not equal, thus the error.
I need to dive deeper into to check if doing a case-insensitive comparison is the right thing to do here, but for the time being you can force lower-casing the Content-Type header:
emailParser := letters.NewEmailParser(
letters.WithContentTypeHeaderParser(
func(s string) (letters.ContentTypeHeader, error) {
return letters.ParseContentTypeHeader(strings.ToLower(s))
},
),
)
email, err := emailParser.Parse(rawEmail)
This should be mostly safe for Content-Type, as we are only looking at charset, micalg, and protocol params, but I would recommend against applying this hack to other headers with case-sensitive values, e.g. the Content-Disposition header.