diff --git a/src/java/davmail/exchange/ExchangeSession.java b/src/java/davmail/exchange/ExchangeSession.java index 948f223d..72516058 100644 --- a/src/java/davmail/exchange/ExchangeSession.java +++ b/src/java/davmail/exchange/ExchangeSession.java @@ -194,6 +194,7 @@ public abstract class ExchangeSession { /** * Return standard zulu date formatter. + * * @return zulu date formatter */ public static SimpleDateFormat getZuluDateFormat() { @@ -912,29 +913,35 @@ public abstract class ExchangeSession { * Detect visible recipients in message body to determine bcc recipients * * @param rcptToRecipients recipients list - * @param mimeMessage mime message - * @throws IOException on error + * @param mimeMessage mime message + * @throws IOException on error * @throws MessagingException on error */ public void sendMessage(List rcptToRecipients, MimeMessage mimeMessage) throws IOException, MessagingException { - // Exchange 2007 : skip From: header - mimeMessage.removeHeader("from"); + // check Sent folder for duplicates + ExchangeSession.MessageList messages = searchMessages(SENT, headerEquals("message-id", mimeMessage.getMessageID())); + if (!messages.isEmpty()) { + LOGGER.debug("Dropping message: already sent"); + } else { + // Exchange 2007 : skip From: header + mimeMessage.removeHeader("from"); - // remove visible recipients from list - Set visibleRecipients = new HashSet(); - Address[] recipients = mimeMessage.getAllRecipients(); - for (Address address : recipients) { - visibleRecipients.add(address.toString()); - } - for (String recipient : rcptToRecipients) { - if (!visibleRecipients.contains(recipient)) { - mimeMessage.addRecipient(javax.mail.Message.RecipientType.BCC, new InternetAddress(recipient)); + // remove visible recipients from list + Set visibleRecipients = new HashSet(); + Address[] recipients = mimeMessage.getAllRecipients(); + for (Address address : recipients) { + visibleRecipients.add(address.toString()); } - } - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - mimeMessage.writeTo(baos); + for (String recipient : rcptToRecipients) { + if (!visibleRecipients.contains(recipient)) { + mimeMessage.addRecipient(javax.mail.Message.RecipientType.BCC, new InternetAddress(recipient)); + } + } + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + mimeMessage.writeTo(baos); - sendMessage(baos.toByteArray()); + sendMessage(baos.toByteArray()); + } } /** @@ -2778,11 +2785,11 @@ public abstract class ExchangeSession { properties.put("haspicture", "true"); } } - LOGGER.debug("Create or update contact "+itemName+": "+properties); + LOGGER.debug("Create or update contact " + itemName + ": " + properties); // reset missing properties to null for (String key : CONTACT_ATTRIBUTES) { if (!"imapUid".equals(key) && !"etag".equals(key) && !"urlcompname".equals(key) - && !"lastmodified".equals(key) && + && !"lastmodified".equals(key) && !properties.containsKey(key)) { properties.put(key, null); } diff --git a/src/test/davmail/smtp/TestSmtp.java b/src/test/davmail/smtp/TestSmtp.java index 7dc99838..ea8954cd 100644 --- a/src/test/davmail/smtp/TestSmtp.java +++ b/src/test/davmail/smtp/TestSmtp.java @@ -148,6 +148,16 @@ public class TestSmtp extends AbstractDavMailTestCase { sendAndCheckMessage(mimeMessage); } + public void testSendMessageTwice() throws IOException, MessagingException, InterruptedException { + String body = "First line\r\n.\r\nSecond line"; + MimeMessage mimeMessage = new MimeMessage((Session) null); + mimeMessage.addHeader("to", Settings.getProperty("davmail.to")); + mimeMessage.setSubject("Test subject"); + mimeMessage.setText(body); + sendAndCheckMessage(mimeMessage); + sendAndCheckMessage(mimeMessage); + } + public void testQuit() throws IOException { writeLine("QUIT"); assertEquals("221 Closing connection", readLine());