mirror of
https://github.com/M66B/FairEmail.git
synced 2025-01-02 21:24:34 +00:00
Set resent headers correctly
This commit is contained in:
parent
20dffe0ea2
commit
50d8bbc59d
3 changed files with 94 additions and 48 deletions
2
FAQ.md
2
FAQ.md
|
@ -3407,7 +3407,7 @@ Remarks:
|
||||||
* The original subject is sent as-is, unless it is being changed
|
* The original subject is sent as-is, unless it is being changed
|
||||||
* The original message text will be sent as-is, unless text is being entered
|
* The original message text will be sent as-is, unless text is being entered
|
||||||
* The original attachments are sent as they are, unless attachments are being added or removed
|
* The original attachments are sent as they are, unless attachments are being added or removed
|
||||||
* Default CC and BCC addresses will be applied
|
* Default CC and BCC addresses will not be applied
|
||||||
* Read and delivery receipts will be requested when enabled, they could go to the original sender or to you
|
* Read and delivery receipts will be requested when enabled, they could go to the original sender or to you
|
||||||
* The email server might refused resent messages
|
* The email server might refused resent messages
|
||||||
* DKIM, SPF and DMARC will likely fail, often causing resent messages to be considered as spam
|
* DKIM, SPF and DMARC will likely fail, often causing resent messages to be considered as spam
|
||||||
|
|
|
@ -281,75 +281,96 @@ public class MessageHelper {
|
||||||
|
|
||||||
MailDateFormat mdf = new MailDateFormat();
|
MailDateFormat mdf = new MailDateFormat();
|
||||||
mdf.setTimeZone(hide_timezone ? TimeZone.getTimeZone("UTC") : TimeZone.getDefault());
|
mdf.setTimeZone(hide_timezone ? TimeZone.getTimeZone("UTC") : TimeZone.getDefault());
|
||||||
String date = mdf.format(new Date(message.sent == null ? message.received : message.sent));
|
String ourDate = mdf.format(new Date(message.sent == null ? message.received : message.sent));
|
||||||
imessage.setHeader("Date", date);
|
|
||||||
|
|
||||||
Address us = null;
|
Address ourFrom = null;
|
||||||
if (message.from != null && message.from.length > 0) {
|
if (message.from != null && message.from.length > 0)
|
||||||
us = getFrom(message, identity);
|
ourFrom = getFrom(message, identity);
|
||||||
imessage.setFrom(us);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Resend
|
if (message.headers == null) {
|
||||||
if (message.headers != null) {
|
imessage.setHeader("Date", ourDate);
|
||||||
|
|
||||||
|
// Addresses
|
||||||
|
if (ourFrom != null)
|
||||||
|
imessage.setFrom(ourFrom);
|
||||||
|
|
||||||
|
if (message.to != null && message.to.length > 0)
|
||||||
|
imessage.setRecipients(Message.RecipientType.TO, convertAddress(message.to, identity));
|
||||||
|
|
||||||
|
if (message.cc != null && message.cc.length > 0)
|
||||||
|
imessage.setRecipients(Message.RecipientType.CC, convertAddress(message.cc, identity));
|
||||||
|
|
||||||
|
if (message.bcc != null && message.bcc.length > 0)
|
||||||
|
imessage.setRecipients(Message.RecipientType.BCC, convertAddress(message.bcc, identity));
|
||||||
|
} else {
|
||||||
// https://datatracker.ietf.org/doc/html/rfc2822#section-3.6.6
|
// https://datatracker.ietf.org/doc/html/rfc2822#section-3.6.6
|
||||||
if (us != null)
|
|
||||||
imessage.addHeader("Resent-From", us.toString());
|
|
||||||
|
|
||||||
imessage.addHeader("Resent-Date", date);
|
|
||||||
|
|
||||||
ByteArrayInputStream bis = new ByteArrayInputStream(message.headers.getBytes());
|
ByteArrayInputStream bis = new ByteArrayInputStream(message.headers.getBytes());
|
||||||
List<Header> headers = Collections.list(new InternetHeaders(bis).getAllHeaders());
|
List<Header> headers = Collections.list(new InternetHeaders(bis).getAllHeaders());
|
||||||
|
|
||||||
for (Header header : headers) {
|
for (Header header : headers) {
|
||||||
String name = header.getName();
|
String name = header.getName();
|
||||||
String value = header.getValue();
|
String value = header.getValue();
|
||||||
if (name == null || value == null)
|
if (name == null || TextUtils.isEmpty(value))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
switch (name.toLowerCase(Locale.ROOT)) {
|
switch (name.toLowerCase(Locale.ROOT)) {
|
||||||
case "from":
|
|
||||||
// Override default header
|
|
||||||
imessage.setFrom(value);
|
|
||||||
break;
|
|
||||||
case "date":
|
case "date":
|
||||||
// Override default header
|
|
||||||
imessage.setHeader("Date", value);
|
imessage.setHeader("Date", value);
|
||||||
break;
|
break;
|
||||||
|
case "from":
|
||||||
|
imessage.setFrom(value);
|
||||||
|
break;
|
||||||
case "to":
|
case "to":
|
||||||
imessage.addHeader("Resent-To", value);
|
imessage.setRecipients(Message.RecipientType.TO, InternetAddress.parse(value));
|
||||||
break;
|
break;
|
||||||
case "cc":
|
case "cc":
|
||||||
imessage.addHeader("Resent-Cc", value);
|
imessage.setRecipients(Message.RecipientType.CC, InternetAddress.parse(value));
|
||||||
break;
|
break;
|
||||||
case "bcc":
|
case "bcc":
|
||||||
imessage.addHeader("Resent-Bcc", value);
|
imessage.setRecipients(Message.RecipientType.BCC, InternetAddress.parse(value));
|
||||||
|
break;
|
||||||
|
case "reply-to":
|
||||||
|
imessage.setReplyTo(InternetAddress.parse(value));
|
||||||
break;
|
break;
|
||||||
// Resent-Sender
|
// Resent-Sender
|
||||||
// Resent-Message-ID
|
// Resent-Message-ID
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The "Resent-Date:" indicates the date and time at which the resent
|
||||||
|
// message is dispatched by the resender of the message.
|
||||||
|
imessage.addHeader("Resent-Date", ourDate);
|
||||||
|
|
||||||
|
// a simple "Resent-From:" form which
|
||||||
|
// contains the mailbox of the individual doing the resending
|
||||||
|
if (ourFrom != null)
|
||||||
|
imessage.addHeader("Resent-From", ourFrom.toString());
|
||||||
|
|
||||||
|
// The "Resent-To:", "Resent-Cc:", and "Resent-Bcc:" fields function
|
||||||
|
// identically to the "To:", "Cc:", and "Bcc:" fields respectively,
|
||||||
|
// except that they indicate the recipients of the resent message, not
|
||||||
|
// the recipients of the original message.
|
||||||
|
if (message.to != null && message.to.length > 0)
|
||||||
|
imessage.addHeader("Resent-To", InternetAddress.toString(message.to));
|
||||||
|
|
||||||
|
if (message.cc != null && message.cc.length > 0)
|
||||||
|
imessage.addHeader("Resent-Cc", InternetAddress.toString(message.cc));
|
||||||
|
|
||||||
|
if (message.bcc != null && message.bcc.length > 0)
|
||||||
|
imessage.addHeader("Resent-Bcc", InternetAddress.toString(message.bcc));
|
||||||
|
|
||||||
|
// Each new set of resent fields is prepended to the message;
|
||||||
|
// that is, the most recent set of resent fields appear earlier in the message.
|
||||||
for (Header header : headers) {
|
for (Header header : headers) {
|
||||||
String name = header.getName();
|
String name = header.getName();
|
||||||
String value = header.getValue();
|
String value = header.getValue();
|
||||||
if (name == null || value == null)
|
if (name == null || TextUtils.isEmpty(value))
|
||||||
continue;
|
continue;
|
||||||
if (name.toLowerCase(Locale.ROOT).startsWith("resent-"))
|
if (name.toLowerCase(Locale.ROOT).startsWith("resent-"))
|
||||||
imessage.addHeader(name, value);
|
imessage.addHeader(name, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Addresses
|
|
||||||
if (message.to != null && message.to.length > 0)
|
|
||||||
imessage.setRecipients(Message.RecipientType.TO, convertAddress(message.to, identity));
|
|
||||||
|
|
||||||
if (message.cc != null && message.cc.length > 0)
|
|
||||||
imessage.setRecipients(Message.RecipientType.CC, convertAddress(message.cc, identity));
|
|
||||||
|
|
||||||
if (message.bcc != null && message.bcc.length > 0)
|
|
||||||
imessage.setRecipients(Message.RecipientType.BCC, convertAddress(message.bcc, identity));
|
|
||||||
|
|
||||||
if (message.subject != null) {
|
if (message.subject != null) {
|
||||||
int maxlen = MAX_HEADER_LENGTH - "Subject: ".length();
|
int maxlen = MAX_HEADER_LENGTH - "Subject: ".length();
|
||||||
if (message.subject.length() > maxlen)
|
if (message.subject.length() > maxlen)
|
||||||
|
@ -359,17 +380,19 @@ public class MessageHelper {
|
||||||
|
|
||||||
// Send message
|
// Send message
|
||||||
if (identity != null) {
|
if (identity != null) {
|
||||||
// Add reply to
|
if (message.headers == null) {
|
||||||
if (message.headers == null && identity.replyto != null)
|
// Add reply to
|
||||||
imessage.setReplyTo(convertAddress(InternetAddress.parse(identity.replyto), identity));
|
if (identity.replyto != null)
|
||||||
|
imessage.setReplyTo(convertAddress(InternetAddress.parse(identity.replyto), identity));
|
||||||
|
|
||||||
// Add extra cc
|
// Add extra cc
|
||||||
if (identity.cc != null)
|
if (identity.cc != null)
|
||||||
addAddress(identity.cc, Message.RecipientType.CC, imessage, identity);
|
addAddress(identity.cc, Message.RecipientType.CC, imessage, identity);
|
||||||
|
|
||||||
// Add extra bcc
|
// Add extra bcc
|
||||||
if (identity.bcc != null)
|
if (identity.bcc != null)
|
||||||
addAddress(identity.bcc, Message.RecipientType.BCC, imessage, identity);
|
addAddress(identity.bcc, Message.RecipientType.BCC, imessage, identity);
|
||||||
|
}
|
||||||
|
|
||||||
// Delivery/read request
|
// Delivery/read request
|
||||||
if (message.receipt_request != null && message.receipt_request) {
|
if (message.receipt_request != null && message.receipt_request) {
|
||||||
|
|
|
@ -48,6 +48,8 @@ import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -681,9 +683,30 @@ public class ServiceSend extends ServiceBase implements SharedPreferences.OnShar
|
||||||
if (ident.max_size == null)
|
if (ident.max_size == null)
|
||||||
max_size = iservice.getMaxSize();
|
max_size = iservice.getMaxSize();
|
||||||
|
|
||||||
Address[] to = imessage.getAllRecipients();
|
List<Address> recipients = new ArrayList<>();
|
||||||
|
if (message.headers == null) {
|
||||||
|
Address[] all = imessage.getAllRecipients();
|
||||||
|
if (all != null)
|
||||||
|
recipients.addAll(Arrays.asList(all));
|
||||||
|
} else {
|
||||||
|
String to = imessage.getHeader("Resent-To", ",");
|
||||||
|
if (to != null)
|
||||||
|
for (Address a : InternetAddress.parse(to))
|
||||||
|
recipients.add(a);
|
||||||
|
|
||||||
|
String cc = imessage.getHeader("Resent-Cc", ",");
|
||||||
|
if (cc != null)
|
||||||
|
for (Address a : InternetAddress.parse(cc))
|
||||||
|
recipients.add(a);
|
||||||
|
|
||||||
|
String bcc = imessage.getHeader("Resent-Bcc", ",");
|
||||||
|
if (bcc != null)
|
||||||
|
for (Address a : InternetAddress.parse(bcc))
|
||||||
|
recipients.add(a);
|
||||||
|
}
|
||||||
|
|
||||||
String via = "via " + ident.host + "/" + ident.user +
|
String via = "via " + ident.host + "/" + ident.user +
|
||||||
" to " + (to == null ? null : TextUtils.join(", ", to));
|
" recipients=" + TextUtils.join(", ", recipients);
|
||||||
|
|
||||||
iservice.setReporter(new TraceOutputStream.IReport() {
|
iservice.setReporter(new TraceOutputStream.IReport() {
|
||||||
private int progress = -1;
|
private int progress = -1;
|
||||||
|
@ -707,7 +730,7 @@ public class ServiceSend extends ServiceBase implements SharedPreferences.OnShar
|
||||||
// Send message
|
// Send message
|
||||||
EntityLog.log(this, "Sending " + via);
|
EntityLog.log(this, "Sending " + via);
|
||||||
start = new Date().getTime();
|
start = new Date().getTime();
|
||||||
iservice.getTransport().sendMessage(imessage, to);
|
iservice.getTransport().sendMessage(imessage, recipients.toArray(new Address[0]));
|
||||||
end = new Date().getTime();
|
end = new Date().getTime();
|
||||||
EntityLog.log(this, "Sent " + via + " elapse=" + (end - start) + " ms");
|
EntityLog.log(this, "Sent " + via + " elapse=" + (end - start) + " ms");
|
||||||
} catch (MessagingException ex) {
|
} catch (MessagingException ex) {
|
||||||
|
|
Loading…
Reference in a new issue