letters icon indicating copy to clipboard operation
letters copied to clipboard

mime: duplicate parameter name error

Open iceking2nd opened this issue 1 year ago • 2 comments

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?

iceking2nd avatar Feb 13 '25 01:02 iceking2nd

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.

mnako avatar Feb 21 '25 15:02 mnako

@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.

mnako avatar Mar 02 '25 00:03 mnako