From b33fb9a14aa356ad28ff23e278258a9ba6741e14 Mon Sep 17 00:00:00 2001 From: pengzili Date: Fri, 30 Dec 2016 07:37:23 +0100 Subject: [PATCH 1/7] Added support for multiple recipients in MockMail --- pom.xml | 8 +++++++ .../mail/MockMockMessageHandlerFactory.java | 23 ++++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7964fca..d58a774 100644 --- a/pom.xml +++ b/pom.xml @@ -32,6 +32,14 @@ 2.6 + + + commons-io + commons-io + 2.2 + + + javax.mail mail diff --git a/src/main/java/com/mockmock/mail/MockMockMessageHandlerFactory.java b/src/main/java/com/mockmock/mail/MockMockMessageHandlerFactory.java index 62ce824..dea2cb3 100644 --- a/src/main/java/com/mockmock/mail/MockMockMessageHandlerFactory.java +++ b/src/main/java/com/mockmock/mail/MockMockMessageHandlerFactory.java @@ -2,6 +2,7 @@ import com.google.common.eventbus.EventBus; import com.mockmock.Settings; +import org.apache.commons.io.IOUtils; import org.joda.time.DateTime; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -15,13 +16,14 @@ import javax.mail.Multipart; import javax.mail.Session; import javax.mail.internet.MimeMessage; +import javax.mail.internet.MimeUtility; import java.io.*; import java.util.Properties; @Service public class MockMockMessageHandlerFactory implements MessageHandlerFactory { - private EventBus eventBus; + private final EventBus eventBus; private Settings settings; @Autowired @@ -126,6 +128,9 @@ public void data(InputStream data) throws RejectException, IOException { BodyPart bodyPart = multipart.getBodyPart(i); String contentType = bodyPart.getContentType(); + contentType = contentType.replaceAll("\t|\r|\n", ""); + System.out.println(contentType); + if(contentType.matches("text/plain.*")) { mockMail.setBody(convertStreamToString(bodyPart.getInputStream())); @@ -134,6 +139,22 @@ else if(contentType.matches("text/html.*")) { mockMail.setBodyHtml(convertStreamToString(bodyPart.getInputStream())); } + else if(contentType.matches("multipart/related.*")){ + // compound documents + Multipart contentMulti = (Multipart)bodyPart.getContent(); + for (int j = 0; j < contentMulti.getCount(); j++){ + BodyPart subPart = contentMulti.getBodyPart(i); + String subContentType = subPart.getContentType(); + System.out.println(subContentType); + String encoding = "UTF-8"; + + if(subContentType.matches("text/html.*")){ + String bodyHtml = IOUtils.toString(MimeUtility.decode(subPart.getInputStream(), "quoted-printable"), encoding); + mockMail.setBodyHtml(bodyHtml); + } + } + + } } } else if(messageContent instanceof InputStream) From 18ed14a30dd2a57e5cac40e36e64a31f86ad3598 Mon Sep 17 00:00:00 2001 From: pengzili Date: Fri, 30 Dec 2016 11:23:16 +0100 Subject: [PATCH 2/7] Added support for multiple recipients in MockMail --- .../htmlbuilder/MailViewHtmlBuilder.java | 43 +++++++++++++------ src/main/java/com/mockmock/mail/MockMail.java | 18 ++++++++ .../mail/MockMockMessageHandlerFactory.java | 6 +++ .../java/com/mockmock/server/HttpServer.java | 7 +++ 4 files changed, 61 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/mockmock/htmlbuilder/MailViewHtmlBuilder.java b/src/main/java/com/mockmock/htmlbuilder/MailViewHtmlBuilder.java index 9e9c3d8..226f8c0 100644 --- a/src/main/java/com/mockmock/htmlbuilder/MailViewHtmlBuilder.java +++ b/src/main/java/com/mockmock/htmlbuilder/MailViewHtmlBuilder.java @@ -63,22 +63,39 @@ public String build() .append(" \n"); } - if(mockMail.getBodyHtml() != null) + if(mockMail.getAttacheFileName() != null) { - output.append("
\n") - .append("

HTML body unformatted

\n") - .append("
") - .append(StringEscapeUtils.escapeHtml(mockMail.getBodyHtml())) - .append("
\n") - .append("
\n"); + output.append( + " \n"); + } + if(mockMail.getBodyHtml() != null) + { // also show a parsed version via an iframe - output.append("
\n" + "

HTML body formatted

\n") - .append(" \n") - .append("
"); + output.append( + "") + .append( + "
\n" + + "

HTML body formatted

\n" + + " \n" + + "
"); } // just output the raw mail so we're sure everything is on the screen diff --git a/src/main/java/com/mockmock/mail/MockMail.java b/src/main/java/com/mockmock/mail/MockMail.java index 32739d7..16550ba 100644 --- a/src/main/java/com/mockmock/mail/MockMail.java +++ b/src/main/java/com/mockmock/mail/MockMail.java @@ -13,6 +13,8 @@ public class MockMail implements Comparable private String rawMail; private MimeMessage mimeMessage; private long receivedTime; + private byte[] attachment; + private String attacheFileName; public long getId() { @@ -113,4 +115,20 @@ public void setReceivedTime(long receivedTime) { this.receivedTime = receivedTime; } + + public byte[] getAttachment() { + return attachment; + } + + public void setAttachment(byte[] attachment) { + this.attachment = attachment; + } + + public String getAttacheFileName() { + return attacheFileName; + } + + public void setAttacheFileName(String attacheFileName) { + this.attacheFileName = attacheFileName; + } } diff --git a/src/main/java/com/mockmock/mail/MockMockMessageHandlerFactory.java b/src/main/java/com/mockmock/mail/MockMockMessageHandlerFactory.java index dea2cb3..3c3d77d 100644 --- a/src/main/java/com/mockmock/mail/MockMockMessageHandlerFactory.java +++ b/src/main/java/com/mockmock/mail/MockMockMessageHandlerFactory.java @@ -154,6 +154,12 @@ else if(contentType.matches("multipart/related.*")){ } } + }else if(contentType.matches("application/octet-stream.*")){ + // attachment + String strFileName = MimeUtility.decodeText(bodyPart.getFileName()); + mockMail.setAttacheFileName(strFileName); + byte[] attachContent = IOUtils.toByteArray(bodyPart.getInputStream()); + mockMail.setAttachment(attachContent); } } } diff --git a/src/main/java/com/mockmock/server/HttpServer.java b/src/main/java/com/mockmock/server/HttpServer.java index 9c8cb5f..746a42f 100644 --- a/src/main/java/com/mockmock/server/HttpServer.java +++ b/src/main/java/com/mockmock/server/HttpServer.java @@ -23,6 +23,7 @@ public class HttpServer implements com.mockmock.server.Server private MailDetailHtmlHandler mailDetailHtmlHandler; private MailDeleteHandler mailDeleteHandler; private DeleteHandler deleteHandler; + private MailAttachmentHandler attachmentHandler; public void setPort(int port) { @@ -62,6 +63,7 @@ public void start() this.mailDetailHtmlHandler, this.mailDeleteHandler, this.deleteHandler, + this.attachmentHandler, resourceHandler }; HandlerList handlerList = new HandlerList(); @@ -105,6 +107,11 @@ public void setDeleteHandler(DeleteHandler deleteHandler) { this.deleteHandler = deleteHandler; } + @Autowired + private void setAttachmentHandler(MailAttachmentHandler attachmentHandler) { + this.attachmentHandler = attachmentHandler; + } + @Autowired public void setSettings(Settings settings) { this.settings = settings; From 3aca6fd292dfed5fd0095d2fc18a399268d6bd27 Mon Sep 17 00:00:00 2001 From: pengzili Date: Fri, 30 Dec 2016 18:23:49 +0800 Subject: [PATCH 3/7] add attachment support --- .../mockmock/http/MailAttachmentHandler.java | 121 ++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 src/main/java/com/mockmock/http/MailAttachmentHandler.java diff --git a/src/main/java/com/mockmock/http/MailAttachmentHandler.java b/src/main/java/com/mockmock/http/MailAttachmentHandler.java new file mode 100644 index 0000000..38f6be9 --- /dev/null +++ b/src/main/java/com/mockmock/http/MailAttachmentHandler.java @@ -0,0 +1,121 @@ +package com.mockmock.http; + +import com.mockmock.mail.MailQueue; +import com.mockmock.mail.MockMail; +import org.apache.commons.io.IOUtils; +import org.eclipse.jetty.server.Request; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.MimeTypeUtils; + +import javax.mail.internet.MimeUtility; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URLConnection; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Created by Pengzili on 2016/12/30. + */ + +@Service +public class MailAttachmentHandler extends BaseHandler{ + + private String pattern = "^/attachment/([0-9]+)/?$"; + + private MailQueue mailQueue; + + @Override + public void handle(String target, Request request, HttpServletRequest httpServletRequest, HttpServletResponse response) throws IOException, ServletException { + + if(!isMatch(target)) + { + return; + } + + long mailId = getMailId(target); + if(mailId == 0) + { + return; + } + + MockMail mockMail = this.mailQueue.getById(mailId); + + if(mockMail == null) + { + return; + } + + if(mockMail.getBodyHtml() == null) + { + return; + } + + String fileName = mockMail.getAttacheFileName(); + String fileNameExt =fileName.substring(fileName.lastIndexOf(".")+1, fileName.length()); + String mimeType = "application/octet-stream"; + + if (fileNameExt.equals("pdf")){ + mimeType = "application/pdf"; + }else if(fileNameExt.equals("doc")){ + mimeType = "application/msword"; + }else if(fileNameExt.equals("xls")){ + mimeType = "application/vnd.ms-excel"; + } + + response.setContentType(mimeType); + response.setHeader("Content-Disposition", " attachment;filename="+ MimeUtility.encodeWord(mockMail.getAttacheFileName())); + response.getOutputStream().write(mockMail.getAttachment()); + response.setStatus(HttpServletResponse.SC_OK); + + request.setHandled(true); + + } + + /** + * Checks if this handler should be used for the given target + * @param target String + * @return boolean + */ + private boolean isMatch(String target) + { + return target.matches(pattern); + } + + /** + * Returns the mail id if it is part of the target + * @param target String + * @return long + */ + private long getMailId(String target) + { + Pattern compiledPattern = Pattern.compile(pattern); + + Matcher matcher = compiledPattern.matcher(target); + if(matcher.find()) + { + String result = matcher.group(1); + try + { + return Long.valueOf(result); + } + catch (NumberFormatException e) + { + return 0; + } + } + + return 0; + } + + @Autowired + public void setMailQueue(MailQueue mailQueue) { + this.mailQueue = mailQueue; + } +} From a258935508f574352cf57636f7085ce4ddd45a29 Mon Sep 17 00:00:00 2001 From: pengzili Date: Fri, 30 Dec 2016 11:41:55 +0100 Subject: [PATCH 4/7] Added support for multiple recipients in MockMail --- .../htmlbuilder/MailViewHtmlBuilder.java | 69 +++++++++---------- 1 file changed, 33 insertions(+), 36 deletions(-) diff --git a/src/main/java/com/mockmock/htmlbuilder/MailViewHtmlBuilder.java b/src/main/java/com/mockmock/htmlbuilder/MailViewHtmlBuilder.java index 226f8c0..524ebaa 100644 --- a/src/main/java/com/mockmock/htmlbuilder/MailViewHtmlBuilder.java +++ b/src/main/java/com/mockmock/htmlbuilder/MailViewHtmlBuilder.java @@ -34,7 +34,7 @@ public String build() subjectOutput = StringEscapeUtils.escapeHtml(mockMail.getSubject()); } - subjectOutput += " Delete"; + subjectOutput += " Delete"; StringBuilder output = new StringBuilder("
\n"); @@ -57,58 +57,55 @@ public String build() { output.append("
\n") .append("

Plain text body

\n") - .append("
") - .append(StringEscapeUtils.escapeHtml(mockMail.getBody())) - .append("
\n") + .append("
").append(StringEscapeUtils.escapeHtml(mockMail.getBody())).append("
\n") .append("
\n"); } if(mockMail.getAttacheFileName() != null) { - output.append( - " \n"); + output.append("
\n") + .append("

Attachment

\n") + .append(" \n") + .append("
\n"); } if(mockMail.getBodyHtml() != null) { // also show a parsed version via an iframe - output.append( - "") - .append( - "
\n" + - "

HTML body formatted

\n" + - " \n" + - "
"); + output.append(" ") + .append("
\n") + .append("

HTML body formatted

\n") + .append("
\n") + .append(" \n") + .append("
\n") + .append("
"); } - // just output the raw mail so we're sure everything is on the screen - if(mockMail.getRawMail() != null) - { - // output complete raw mail - output.append("
\n") + // just output the raw mail so we're sure everything is on the screen + if(mockMail.getRawMail() != null) + { + // output complete raw mail + output.append("
\n") .append("

Complete raw mail output

\n") .append("
") .append(StringEscapeUtils.escapeHtml(mockMail.getRawMail())) .append("
\n") .append("
\n"); - } + } output.append("
\n") .append("
\n"); From 77ee3b76868332ec813b4e57ef16c764df35e450 Mon Sep 17 00:00:00 2001 From: pengzili Date: Fri, 9 Jun 2017 14:10:19 +0800 Subject: [PATCH 5/7] small fix --- .../java/com/mockmock/mail/MockMockMessageHandlerFactory.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/mockmock/mail/MockMockMessageHandlerFactory.java b/src/main/java/com/mockmock/mail/MockMockMessageHandlerFactory.java index 3c3d77d..e533edf 100644 --- a/src/main/java/com/mockmock/mail/MockMockMessageHandlerFactory.java +++ b/src/main/java/com/mockmock/mail/MockMockMessageHandlerFactory.java @@ -154,7 +154,7 @@ else if(contentType.matches("multipart/related.*")){ } } - }else if(contentType.matches("application/octet-stream.*")){ + } else if (contentType.matches("application/octet-stream.*") || contentType.matches("application/pdf.*")) { // attachment String strFileName = MimeUtility.decodeText(bodyPart.getFileName()); mockMail.setAttacheFileName(strFileName); From 37044599e3ada51c2bda532eb26908a293f865e3 Mon Sep 17 00:00:00 2001 From: Dominique Comte Date: Mon, 21 Nov 2022 01:16:32 +0100 Subject: [PATCH 6/7] fix Quoted-printable soft line break --- .../com/mockmock/mail/MockMockMessageHandlerFactory.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/mockmock/mail/MockMockMessageHandlerFactory.java b/src/main/java/com/mockmock/mail/MockMockMessageHandlerFactory.java index e533edf..bf815a6 100644 --- a/src/main/java/com/mockmock/mail/MockMockMessageHandlerFactory.java +++ b/src/main/java/com/mockmock/mail/MockMockMessageHandlerFactory.java @@ -149,7 +149,11 @@ else if(contentType.matches("multipart/related.*")){ String encoding = "UTF-8"; if(subContentType.matches("text/html.*")){ - String bodyHtml = IOUtils.toString(MimeUtility.decode(subPart.getInputStream(), "quoted-printable"), encoding); + String originalBodyHtml = IOUtils.toString(subPart.getInputStream()); + String replacedBodyHtml = originalBodyHtml.replaceAll("(? Date: Fri, 13 Nov 2020 03:22:36 +0100 Subject: [PATCH 7/7] fix encoding --- .../java/com/mockmock/mail/MockMockMessageHandlerFactory.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/mockmock/mail/MockMockMessageHandlerFactory.java b/src/main/java/com/mockmock/mail/MockMockMessageHandlerFactory.java index bf815a6..03a1585 100644 --- a/src/main/java/com/mockmock/mail/MockMockMessageHandlerFactory.java +++ b/src/main/java/com/mockmock/mail/MockMockMessageHandlerFactory.java @@ -149,7 +149,7 @@ else if(contentType.matches("multipart/related.*")){ String encoding = "UTF-8"; if(subContentType.matches("text/html.*")){ - String originalBodyHtml = IOUtils.toString(subPart.getInputStream()); + String originalBodyHtml = IOUtils.toString(subPart.getInputStream(), encoding); String replacedBodyHtml = originalBodyHtml.replaceAll("(?