[
https://issues.apache.org/jira/browse/CAMEL-26013?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18130963#comment-18130963
]
Claus Ibsen commented on CAMEL-26013:
-------------------------------------
Fix in https://github.com/apache/camel/pull/28358
_Claude Code on behalf of davsclaus_
> camel-mail - the body of mails: the text of a multipart mail, the charset of
> sent text, and more
> ------------------------------------------------------------------------------------------------
>
> Key: CAMEL-26013
> URL: https://issues.apache.org/jira/browse/CAMEL-26013
> Project: Camel
> Issue Type: Bug
> Components: camel-mail
> Affects Versions: 4.18.0, 4.22.0, 4.23.0
> Reporter: Claus Ibsen
> Assignee: Claus Ibsen
> Priority: Major
> Fix For: 4.24.0
>
>
> Found while checking the body types of the mail component for the catalog
> (CAMEL-24961).
> h4. 1. After a multipart mail with no text part, every multipart mail
> converts to the text MimeMultipart@...
> When a mail consumer gives a multipart mail, the body is a
> {{jakarta.mail.internet.MimeMultipart}}, and
> {{MailConverters.toString(Multipart)}} turns it into the text of its first
> text part ({{MailConverters}}, main 56aa5f4970a6, lines 85-112). For a
> multipart mail with no text part, for example one with only a PDF attachment,
> it returns null. The type converter registry then tries the fallback
> converters, and the last one, {{ToStringTypeConverter}}, gives
> {{jakarta.mail.internet.MimeMultipart@<hash>}}. The registry stores that
> fallback for the pair MimeMultipart to String ({{CoreTypeConverterRegistry}},
> lines 455-469). From then on, every multipart mail in the CamelContext
> converts to {{MimeMultipart@<hash>}}, also the mails that have a text part.
> That breaks {{${body}}}, {{convertBodyTo}}, and an smtp producer that
> forwards the mail.
> Checked on 4.24.0-SNAPSHOT with {{camel run}} and GreenMail, with a pop3
> consumer that logs {{${bodyAs(String)}}}:
> * a multipart/mixed mail with only a PDF attachment:
> {{jakarta.mail.internet.MimeMultipart@785eec1b}};
> * then a multipart/mixed mail with a text part and an attachment:
> {{jakarta.mail.internet.MimeMultipart@1ad1a775}};
> * then a multipart/alternative mail:
> {{jakarta.mail.internet.MimeMultipart@28dd82c}}.
> In a run without the PDF-only mail, the same two mails give their text
> ("Hello with attachment").
> *Proposed change*: mark the converter {{@Converter(allowNull = true)}}, so a
> null result means no text rather than a miss, and the fallback is not used or
> stored.
> h4. 2. Text without a charset in contentType is sent in the JVM charset with
> no charset in the Content-Type
> The mail producer sends the body as text with {{new ByteArrayDataSource(body,
> contentType)}} ({{MailBinding}}, main 56aa5f4970a6, lines 273-283, and line
> 301 for the multipart paths). With the default contentType {{text/plain}}, or
> any contentType without a charset, the text is encoded in the JVM default
> charset, but the Content-Type of the mail has no charset. A reader then
> decodes it as US-ASCII, the MIME default, so any text that is not ASCII
> arrives garbled.
> Checked on 4.24.0-SNAPSHOT with {{camel run}} and GreenMail, sending "Grüße
> aus Kopenhagen" with {{smtp}} and reading it with {{pop3}}:
> * without a charset: Content-Type {{text/plain}}, and the text arrives
> garbled, with ü as "ü" and ß as "Ã" and a control character;
> * with the exchange property {{CamelCharsetName=UTF-8}}: Content-Type
> {{text/plain; charset=UTF-8}}, and the text arrives as sent.
> *Proposed change*: when the contentType has no charset, add the charset the
> text was encoded in to the Content-Type (UTF-8, or the charset of the
> exchange).
> h4. 3. A first text part without a content handler, such as text/csv,
> converts to the name of a stream
> {{MailConverters.toString(Multipart)}} gives the text of the first text part
> of a multipart mail. For a text part that Jakarta Mail has no content handler
> for, such as {{text/csv}} or {{text/calendar}}, the content is an
> InputStream, and the converter returns {{content.toString()}}
> ({{MailConverters}}, main 56aa5f4970a6, line 101). So the text is the name of
> the stream. The same {{toString()}} is used for the first part of a
> {{Message}} (lines 63-76).
> Checked on 4.24.0-SNAPSHOT with {{camel run}} and GreenMail: a
> multipart/mixed mail whose first part is {{text/csv}} with {{a,b 1,2}}, read
> with pop3, gives {{jakarta.mail.util.SharedByteArrayInputStream@5cb748e4}}
> for {{${bodyAs(String)}}}.
> *Proposed change*: read a stream content as text, in the charset of the part.
> h4. 4. A producer on imap or pop3 is accepted and fails every send with
> invalid provider
> The mail endpoint serves imap, imaps, pop3, pop3s, smtp and smtps. A consumer
> on smtp fails at startup with "Protocol smtp cannot be used for a
> MailConsumer" ({{MailEndpoint}}, main 56aa5f4970a6, lines 139-144). A
> producer on imap or pop3 is created without a check (lines 121-129) and asks
> Jakarta Mail for a transport of that protocol on every send
> ({{DefaultJavaMailSender}}, lines 150 and 178-179), which fails.
> Checked on 4.24.0-SNAPSHOT with {{camel run}}: {{to:
> imap://localhost:3143?username=survey&password=secret&to=survey@localhost}}
> fails each exchange with {{jakarta.mail.NoSuchProviderException: invalid
> provider}}.
> *Proposed change*: fail when the producer is created on imap, imaps, pop3 or
> pop3s, with a message that says to use smtp or smtps, as the consumer does
> for smtp.
> h4. 5. A mail read with mapMailMessage=false cannot be sent with smtp, as it
> is read-only
> With {{mapMailMessage=false}}, the body of a mail consumer is the
> {{jakarta.mail.Message}} of the store, an IMAPMessage or a POP3Message. An
> smtp producer sends a MimeMessage body as it is, and calls {{saveChanges()}}
> on it first ({{DefaultJavaMailSender}}, main 56aa5f4970a6, line 159). The
> messages of a store are read-only, so the send fails.
> Checked on 4.24.0-SNAPSHOT with {{camel run}} and GreenMail: {{from:
> pop3://...?mapMailMessage=false}}, then {{to: smtp://...}}:
> {{jakarta.mail.IllegalWriteException: POP3 messages are read-only}}.
> *Proposed change*: copy a message of a store into a new MimeMessage ({{new
> MimeMessage((MimeMessage) message)}}) before it is sent.
> h4. 6. Setting the body of a mail message to null gives back the content of
> the mail
> The body of a {{MailMessage}} is created from the mail when it is first read
> ({{MailMessage.createBody}}, main 56aa5f4970a6, lines 90-93), and
> {{MessageSupport.getBody}} creates it again whenever the body is null. So
> after a processor, a bean or a script sets the body of the message to null,
> the next read gives the content of the mail again. (The setBody EIP is not
> affected, as it replaces the message.)
> Checked on 4.24.0-SNAPSHOT with {{camel run}} and GreenMail: after a pop3
> consumer, a groovy script {{exchange.getIn().setBody(null)}}, then {{log:
> ${body}}}, logs the text of the mail.
> *Proposed change*: remember that the body was set, as JmsMessage does, so a
> null body stays null.
> _Claude Code on behalf of davsclaus_
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)