Author: sebb Date: Mon Aug 24 14:19:46 2015 New Revision: 1697406 URL: http://svn.apache.org/r1697406 Log: NET-581 SimpleSMTPHeader fails to supply the required Date: header
Modified: commons/proper/net/trunk/src/changes/changes.xml commons/proper/net/trunk/src/main/java/org/apache/commons/net/smtp/SimpleSMTPHeader.java commons/proper/net/trunk/src/test/java/org/apache/commons/net/smtp/SimpleSMTPHeaderTestCase.java Modified: commons/proper/net/trunk/src/changes/changes.xml URL: http://svn.apache.org/viewvc/commons/proper/net/trunk/src/changes/changes.xml?rev=1697406&r1=1697405&r2=1697406&view=diff ============================================================================== --- commons/proper/net/trunk/src/changes/changes.xml [utf-8] (original) +++ commons/proper/net/trunk/src/changes/changes.xml [utf-8] Mon Aug 24 14:19:46 2015 @@ -73,6 +73,9 @@ This is mainly a bug-fix release. See fu This is the inverse of the IMAPImportMbox example added previously "> + <action issue="NET-581" type="fix" dev="sebb"> + SimpleSMTPHeader fails to supply the required Date: header + </action> <action issue="NET-582" type="fix" dev="sebb"> SimpleSMTPHeader does not allow for missing To: field </action> Modified: commons/proper/net/trunk/src/main/java/org/apache/commons/net/smtp/SimpleSMTPHeader.java URL: http://svn.apache.org/viewvc/commons/proper/net/trunk/src/main/java/org/apache/commons/net/smtp/SimpleSMTPHeader.java?rev=1697406&r1=1697405&r2=1697406&view=diff ============================================================================== --- commons/proper/net/trunk/src/main/java/org/apache/commons/net/smtp/SimpleSMTPHeader.java (original) +++ commons/proper/net/trunk/src/main/java/org/apache/commons/net/smtp/SimpleSMTPHeader.java Mon Aug 24 14:19:46 2015 @@ -17,6 +17,10 @@ package org.apache.commons.net.smtp; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + /*** * This class is used to construct a bare minimum * acceptable header for an email message. To construct more @@ -51,6 +55,7 @@ public class SimpleSMTPHeader private final String __from; private final String __to; private final StringBuffer __headerFields; + private boolean hasHeaderDate; private StringBuffer __cc; /*** @@ -93,6 +98,9 @@ public class SimpleSMTPHeader ***/ public void addHeaderField(String headerField, String value) { + if (!hasHeaderDate && "Date".equals(headerField)) { + hasHeaderDate = true; + } __headerFields.append(headerField); __headerFields.append(": "); __headerFields.append(value); @@ -130,6 +138,12 @@ public class SimpleSMTPHeader { StringBuilder header = new StringBuilder(); + final String pattern = "EEE, dd MMM yyyy HH:mm:ss Z"; // Fri, 21 Nov 1997 09:55:06 -0600 + final SimpleDateFormat format = new SimpleDateFormat(pattern, Locale.ENGLISH); + + if (!hasHeaderDate) { + addHeaderField("Date", format.format(new Date())); + } if (__headerFields.length() > 0) { header.append(__headerFields.toString()); } Modified: commons/proper/net/trunk/src/test/java/org/apache/commons/net/smtp/SimpleSMTPHeaderTestCase.java URL: http://svn.apache.org/viewvc/commons/proper/net/trunk/src/test/java/org/apache/commons/net/smtp/SimpleSMTPHeaderTestCase.java?rev=1697406&r1=1697405&r2=1697406&view=diff ============================================================================== --- commons/proper/net/trunk/src/test/java/org/apache/commons/net/smtp/SimpleSMTPHeaderTestCase.java (original) +++ commons/proper/net/trunk/src/test/java/org/apache/commons/net/smtp/SimpleSMTPHeaderTestCase.java Mon Aug 24 14:19:46 2015 @@ -2,15 +2,24 @@ package org.apache.commons.net.smtp; import static org.junit.Assert.*; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + import org.junit.Before; import org.junit.Test; public class SimpleSMTPHeaderTestCase { private SimpleSMTPHeader header; + private Date beforeDate; @Before public void setUp() { + beforeDate = new Date(); header = new SimpleSMTPHeader("from@here.invalid", "to@there.invalid", "Test email"); } @@ -18,7 +27,7 @@ public class SimpleSMTPHeaderTestCase { public void testToString() { assertNotNull(header); // Note that the DotTerminatedMessageWriter converts LF to CRLF - assertEquals("From: from@here.invalid\nTo: to@there.invalid\nSubject: Test email\n\n", header.toString()); + assertEquals("From: from@here.invalid\nTo: to@there.invalid\nSubject: Test email\n\n", checkDate(header.toString())); } @Test @@ -26,7 +35,7 @@ public class SimpleSMTPHeaderTestCase { SimpleSMTPHeader hdr = new SimpleSMTPHeader("from@here.invalid", "to@there.invalid", null); assertNotNull(hdr); // Note that the DotTerminatedMessageWriter converts LF to CRLF - assertEquals("From: from@here.invalid\nTo: to@there.invalid\n\n", hdr.toString()); + assertEquals("From: from@here.invalid\nTo: to@there.invalid\n\n", checkDate(hdr.toString())); } @Test(expected=IllegalArgumentException.class) @@ -39,6 +48,63 @@ public class SimpleSMTPHeaderTestCase { SimpleSMTPHeader hdr = new SimpleSMTPHeader("from@here.invalid", null, null); assertNotNull(hdr); // Note that the DotTerminatedMessageWriter converts LF to CRLF - assertEquals("From: from@here.invalid\n\n", hdr.toString()); + assertEquals("From: from@here.invalid\n\n", checkDate(hdr.toString())); + } + + @Test + public void testToStringAddHeader() { + SimpleSMTPHeader hdr = new SimpleSMTPHeader("from@here.invalid", null, null); + assertNotNull(hdr); + hdr.addHeaderField("X-Header1", "value 1"); + hdr.addHeaderField("X-Header2", "value 2"); + // Note that the DotTerminatedMessageWriter converts LF to CRLF + assertEquals("X-Header1: value 1\nX-Header2: value 2\nFrom: from@here.invalid\n\n", checkDate(hdr.toString())); + } + + @Test + public void testToStringAddHeaderDate() { + SimpleSMTPHeader hdr = new SimpleSMTPHeader("from@here.invalid", null, null); + assertNotNull(hdr); + hdr.addHeaderField("Date", "dummy date"); + // does not replace the Date field + assertEquals("Date: dummy date\nFrom: from@here.invalid\n\n", hdr.toString()); + } + + // Returns the msg without a date + private String checkDate(String msg) { + Pattern pat = Pattern.compile("^(Date: (.+))$", Pattern.MULTILINE); + Matcher m = pat.matcher(msg); + if (m.find()) { + String date = m.group(2); + final String pattern = "EEE, dd MMM yyyy HH:mm:ss Z"; // Fri, 21 Nov 1997 09:55:06 -0600 + final SimpleDateFormat format = new SimpleDateFormat(pattern, Locale.ENGLISH); + try { + final Date sentDate = format.parse(date); + // Round to nearest second because the text format does not include ms + long sentSecs = sentDate.getTime() / 1000; + long beforeDateSecs = beforeDate.getTime() / 1000; + Date afterDate = new Date(); + long afterDateSecs = afterDate.getTime() / 1000; + if (sentSecs < beforeDateSecs) { + fail(sentDate + " should be after "+beforeDate); + } + if (sentSecs > (afterDateSecs)) { + fail(sentDate+" should be before "+afterDate); + } + } catch (ParseException e) { + fail(""+e); + } + + int start = m.start(1); + int end = m.end(1); + if (start == 0) { + return msg.substring(end+1); + } else { + return msg.substring(0, start)+msg.substring(end+1); + } + } else { + fail("Expecting Date header in "+msg); + } + return null; } }