Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package com.infrared5.mail;
- /*
- * This code was created by Paul Gregoire for personal / professional projects.
- * It is free to use by Infrared5, Inc. forever and may be used in any capacity
- * without notification or approval of Paul Gregoire.
- */
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.io.PrintStream;
- import java.net.InetAddress;
- import java.net.Socket;
- import java.net.UnknownHostException;
- import java.security.Security;
- import java.text.SimpleDateFormat;
- import java.util.ArrayList;
- import java.util.Date;
- import java.util.List;
- import java.util.regex.Matcher;
- import java.util.regex.Pattern;
- import org.apache.commons.codec.binary.Base64;
- import org.bouncycastle.crypto.tls.AlwaysValidVerifyer;
- import org.bouncycastle.crypto.tls.CertificateVerifyer;
- import org.bouncycastle.crypto.tls.TlsProtocolHandler;
- import org.bouncycastle.jce.provider.BouncyCastleProvider;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.beans.BeansException;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.ApplicationContextAware;
- /**
- * <p/>
- * All purpose mailer object, provides programmatic interface to SMTP services.
- * <br>
- * Excellent guides:
- * <a href=http://www.cs.cf.ac.uk/Dave/PERL/node175.html>Sending Mail (SMTP)</a> | <a href=http://perl.about.com/library/weekly/aa032402a.htm>SMTP 101</a>
- * </p>
- * <p/>
- * <i>Quick reference SMTP reply codes:</i>
- * <pre>
- * 211 System status, or system help reply
- * 214 Help message
- * [Information on how to use the receiver or the meaning of a
- * particular non-standard command; this reply is useful only
- * to the human user]
- * 220 <domain> Service ready
- * 221 <domain> Service closing transmission channel
- * 250 Requested mail action okay, completed
- * 251 User not local; will forward to <forward-path>
- * 354 Start mail input; end with <CRLF>.<CRLF>
- * 421 <domain> Service not available,
- * closing transmission channel
- * [This may be a reply to any command if the service knows it
- * must shut down]
- * 450 Requested mail action not taken: mailbox unavailable
- * [E.g., mailbox busy]
- * 451 Requested action aborted: local error in processing
- * 452 Requested action not taken: insufficient system storage
- * 500 Syntax error, command unrecognized
- * [This may include errors such as command line too long]
- * 501 Syntax error in parameters or arguments
- * 502 Command not implemented
- * 503 Bad sequence of commands
- * 504 Command parameter not implemented
- * 550 Requested action not taken: mailbox unavailable
- * [E.g., mailbox not found, no access]
- * 551 User not local; please try <forward-path>
- * 552 Requested mail action aborted: exceeded storage allocation
- * 553 Requested action not taken: mailbox name not allowed
- * [E.g., mailbox syntax incorrect]
- * 554 Transaction failed / Service unavailable
- * </pre>
- *
- * @author <a href="mailto:paul@gregoire.org">Paul Gregoire</a>
- * @version $Revision: 31 $
- */
- public class Mailer implements ApplicationContextAware {
- private static ApplicationContext applicationContext;
- public static final String VERSION = "Mailer v1.13 by Paul Gregoire";
- /**
- * This header line should allow us to by pass spamcop and cause the spam
- * blame to fall upon the actual user.
- */
- private static final String SMTP_SERVER_RECEIVED_FROM_HEADER = "Received: from [%s] by %s via HTTP; %s";
- private static final Pattern PAT_MESSAGE_ID = Pattern.compile("250 (Ok: queued as |[\\d]\\.[\\d]\\.[\\d] ){0,1}([a-zA-Z0-9]{4,32}).*",
- Pattern.CANON_EQ);
- private static final Pattern PAT_TLS_READY = Pattern.compile("220 ([\\d]\\.[\\d]\\.[\\d] ){0,1}([R|r]eady).*",
- Pattern.CANON_EQ);
- private static final Pattern PAT_SMTP_COMMAND = Pattern.compile("(HELO|RCPT|MAIL|DATA|VRFY|QUIT)");
- private static final String TEXT_HEADER_MIME = "Mime-Version: 1.0";
- private static final String TEXT_QUOTED_PLAIN = "Content-Type: text/plain; charset=\"iso-8859-1\"\nContent-Transfer-Encoding: quoted-printable";
- private static final String TEXT_QUOTED_HTML = "Content-Type: text/html; charset=\"iso-8859-1\"\nContent-Transfer-Encoding: quoted-printable";
- private static final String TEXT_HEADER_CONTENT_CLASS = "Content-class: urn:content-classes:message";
- private static final String CRLF = "\r\n";
- private static final String DASH = "--";
- private static String SENDING_HOST = null;
- private Socket smtp;
- private BufferedReader input;
- private PrintStream output;
- private String serverReply;
- private String type = "html";
- private String boundary1 = "----=_PG0123456";
- private String boundary2 = "----=_GP7890123";
- private List<MailFile> files;
- private String messageId;
- private static String SMTP_SERVER;
- private static int SMTP_PORT = 25;
- private static String AUTH_USER;
- private static String AUTH_PASSWORD;
- private static final byte[] EMPTY_ARRAY;
- // rfc 2822
- private SimpleDateFormat formatter = null;
- //socket read timeout, default 15s
- private static int socketTimeout = 15000;
- //time between emails
- private static long mailDelay = 1000;
- private static String authType = "none";
- private static Logger logger = LoggerFactory.getLogger(Mailer.class);
- static {
- //add bouncycastle provider
- Security.addProvider(new BouncyCastleProvider());
- //prefill base64 line array
- EMPTY_ARRAY = new byte[76];
- for (int b = 0; b < 76; b++) {
- EMPTY_ARRAY[b] = (byte) '=';
- }
- }
- /**
- * Default ctor, uses DB configured SMTP server address.
- */
- public Mailer() {
- if (null == SENDING_HOST) {
- try {
- //get this boxes ip for use as sending host
- SENDING_HOST = InetAddress.getLocalHost().getHostAddress();
- } catch (UnknownHostException ex) {
- logger.warn("Exception getting host address: {}", ex.getMessage());
- }
- }
- formatter = new SimpleDateFormat("EEE, dd MMM yyyy kk:mm:ss Z");
- files = new ArrayList<MailFile>(1);
- //regenerate the boundaries
- generateBoundaries();
- }
- private void generateBoundaries() {
- String prefix = "----=_";
- StringBuilder sb = new StringBuilder();
- //seed data
- byte[] seed = (System.currentTimeMillis() + VERSION).getBytes();
- for (int i = 0; i < seed.length; i++) {
- int positiveValue = seed[i] & 0x000000FF;
- //logger.trace("Value: {}", positiveValue);
- sb.append(Integer.toHexString(positiveValue));
- }
- //the seed provides about 84 characters to work with
- logger.trace("Seed data output length: {}", sb.length());
- boundary1 = prefix + sb.substring(0, 16);
- boundary2 = prefix + sb.substring(21, 37);
- logger.debug("Generated mime boundaries: {} {}", boundary1, boundary2);
- }
- public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
- Mailer.applicationContext = applicationContext;
- logger.debug("App context: {}", Mailer.applicationContext.getDisplayName());
- }
- public void setType(String emailtype) {
- type = emailtype;
- }
- public String getAuthType() {
- return Mailer.authType;
- }
- public void setAuthType(String authType) {
- Mailer.authType = authType;
- }
- /**
- * Executes the SMTP VRFY (verify) command. This is not very well supported due
- * to its use by spammers.
- *
- * @param mailto email address to check
- * @throws Exception
- * @throws MailerException
- */
- public void verify(String mailto) throws Exception, MailerException {
- startSession();
- submitCommand("VRFY " + mailto.subSequence(0, mailto.indexOf('@')));
- endSession();
- }
- /**
- * Sends the email via SMTP
- *
- * @param email
- * @throws MailerException
- */
- public void sendMail(Email email) throws Exception, MailerException {
- if (email.hasPlainText && email.getHtmlText() == null) {
- type = "plain";
- }
- String from = email.getFrom();
- String originIp = email.getOriginIP();
- String dateString = getFormattedDate();
- String to = null;
- while (email.getNumRecipients() > 0) {
- logger.debug("Recipients: {} hasRecipients: {}", email.getNumRecipients(), email.hasRecipients());
- //get the recipient
- to = email.getTo();
- if (null == to) {
- logger.warn("Recipient address was null");
- break;
- }
- //sender header
- if (!submitCommand(String.format("MAIL FROM: <%s>", from))) {
- logger.warn("Mail from not accepted: {}", from);
- throw new MailerException(getClass().getName() + " error during mail transmission.");
- }
- //recipient header
- if (!submitCommand(String.format("RCPT TO: <%s>", to))) {
- logger.warn("Mail to not accepted: {}", to);
- continue;
- }
- //start message
- if (!submitCommand("DATA")) {
- logger.warn("Start of mail body not accepted");
- continue;
- }
- //do replacement of "special header fields"
- //senders actual ip address, this host ip, date
- String recvHeader = String.format(SMTP_SERVER_RECEIVED_FROM_HEADER, originIp, SENDING_HOST, dateString);
- //construct the header and message body
- StringBuilder sb = new StringBuilder(recvHeader);
- sb.append(CRLF);
- sb.append("From: \"");
- sb.append(email.getNiceNameFrom());
- sb.append("\" <");
- sb.append(from);
- sb.append(">");
- sb.append(CRLF);
- sb.append("To: ");
- if (email.hasNiceNameTo()) {
- sb.append("\"");
- sb.append(email.getNiceNameTo());
- sb.append("\" <");
- sb.append(to);
- sb.append(">");
- } else {
- sb.append(to);
- }
- sb.append(CRLF);
- sb.append("Subject: ");
- sb.append(email.getSubject());
- sb.append(CRLF);
- sb.append("Date: ");
- sb.append(dateString);
- sb.append(CRLF);
- sb.append("Return-Path: <");
- sb.append(from);
- sb.append(">");
- sb.append(CRLF);
- sb.append(TEXT_HEADER_CONTENT_CLASS);
- sb.append(CRLF);
- if (type.equals("html")) {
- sb.append(TEXT_HEADER_MIME);
- sb.append(CRLF);
- sb.append(TEXT_QUOTED_HTML);
- sb.append(CRLF);
- getXHeaders(sb, originIp);
- //line feed before message
- sb.append(CRLF);
- //now add the message text
- //as quoted-printable
- sb.append(QuotedPrintable.encode(email.getHtmlText()));
- } else if (type.equals("inline")) {
- sb.append(TEXT_HEADER_MIME);
- sb.append(CRLF);
- sb.append("Content-Type: multipart/related; type=\"multipart/alternative\";\n\tboundary=\"");
- sb.append(boundary1);
- sb.append("\"");
- sb.append(CRLF);
- getXHeaders(sb, originIp);
- sb.append(CRLF);
- sb.append(DASH);
- sb.append(boundary1);
- sb.append(CRLF);
- sb.append("Content-Type: multipart/alternative;\n\tboundary=\"");
- sb.append(boundary2);
- sb.append("\"");
- sb.append(CRLF);
- sb.append(CRLF);
- sb.append(DASH);
- sb.append(boundary2);
- sb.append(CRLF);
- // send the message plain text as quoted-printable
- sb.append(TEXT_QUOTED_PLAIN);
- sb.append(CRLF);
- sb.append(CRLF);
- if (email.hasPlainText()) {
- sb.append(QuotedPrintable.encode(email.getPlainText()));
- } else {
- sb.append("This is an HTML email please switch your view.");
- }
- sb.append(CRLF);
- sb.append(CRLF);
- sb.append(DASH);
- sb.append(boundary2);
- sb.append(CRLF);
- // send the message html text as quoted-printable
- sb.append(TEXT_QUOTED_HTML);
- sb.append(CRLF);
- sb.append(CRLF);
- sb.append(QuotedPrintable.encode(email.getHtmlText()));
- //line feed?
- sb.append(CRLF);
- // last line
- sb.append(DASH);
- sb.append(boundary2);
- sb.append(DASH);
- sb.append(CRLF);
- sb.append(CRLF);
- for (int f = 0; f < files.size(); f++) {
- MailFile file = files.get(f);
- //add each image
- addInline(sb, file);
- }
- // last line
- sb.append(DASH);
- sb.append(boundary1);
- sb.append(DASH);
- sb.append(CRLF);
- sb.append(CRLF);
- } else {
- //line feed before message
- sb.append(CRLF);
- //now add the message text
- sb.append(email.getPlainText());
- }
- //tells the SMTP server that we are done with the data
- sb.append(CRLF);
- sb.append(".");
- if (submitCommand(sb.toString())) {
- //some mail servers can't keep up so wait n seconds between mails
- try {
- Thread.sleep(mailDelay);
- } catch (Exception e) {
- logger.debug("Stack trace", e);
- }
- } else {
- logger.error("Error during mail transmission {}", email);
- }
- //clear and re-use
- sb.delete(0, sb.length() - 1);
- }
- //clear list
- files.clear();
- }
- /**
- * Initiates the connection to the mail server.
- *
- * @throws MailerException
- */
- public void startSession() throws MailerException {
- try {
- createSocket();
- input = new BufferedReader(new InputStreamReader(smtp.getInputStream()));
- output = new PrintStream(smtp.getOutputStream());
- serverReply = input.readLine();
- if (serverReply.charAt(0) != '2') {
- logger.error("Error connecting to SMTP server {} on port {} reply {}", new Object[]{SMTP_SERVER, SMTP_PORT, serverReply});
- }
- submitCommand("HELO " + SENDING_HOST);
- } catch (UnknownHostException e) {
- throw new MailerException(getClass().getName() + " error - unknown host: " + SMTP_SERVER);
- } catch (Exception e) {
- throw new MailerException(getClass().getName() + " error: " + e.getMessage());
- }
- }
- /**
- * Initiates the connection to an SMTP server using AUTH.
- *
- *<pre>
- 220 mail.example-nt.com (IMail 8.12 786621-2) NT-ESMTP Server X1
- EHLO tech-flash
- 502 unimplemented command
- EHLO tech-flash
- 250-mail.example.com says hello
- 250-SIZE 0
- 250-8BITMIME
- 250-DSN
- 250-ETRN
- 250-AUTH LOGIN CRAM-MD5
- 250-AUTH=LOGIN
- 250 EXPN
- AUTH LOGIN
- 334 VXNlcm5hbWU6
- root
- 334 UGFzc3dvcmQ6
- ag98dg
- 500 failed authentication
- </pre>
- *
- * @throws MailerException
- */
- public void startSessionWithAuth() throws MailerException {
- try {
- createSocket();
- input = new BufferedReader(new InputStreamReader(smtp.getInputStream()));
- output = new PrintStream(smtp.getOutputStream());
- serverReply = input.readLine();
- if (serverReply.charAt(0) != '2') {
- logger.warn("Error connecting to SMTP server: {} port: {} reply: {}", new Object[]{SMTP_SERVER, SMTP_PORT, serverReply});
- }
- submitCommand("EHLO " + SENDING_HOST);
- submitCommand("AUTH LOGIN");
- submitCommand(Base64.encodeBase64URLSafeString(AUTH_USER.getBytes()));
- submitCommand(Base64.encodeBase64URLSafeString(AUTH_PASSWORD.getBytes()));
- //read server replies until we get auth message
- serverReply = input.readLine();
- //only wait thru 10 responses
- int count = 1;
- while (serverReply.indexOf("authenticated") < 0) {
- serverReply = input.readLine();
- logger.debug("Server reply in auth wait loop: {}", serverReply);
- if (count++ >= 10) {
- break;
- }
- }
- } catch (UnknownHostException e) {
- throw new MailerException(getClass().getName() + " error - unknown host: " + SMTP_SERVER);
- } catch (Exception e) {
- throw new MailerException(getClass().getName() + " error: " + e.getMessage());
- }
- }
- /**
- * Initiates a connection to an SMTP server using TLS.
- * http://www.faqs.org/rfcs/rfc2487.html
- * TLS http://www.faqs.org/rfcs/rfc2246.html
- *
- * @throws MailerException
- */
- public void startSessionWithTLS() throws MailerException {
- try {
- createSocket();
- input = new BufferedReader(new InputStreamReader(smtp.getInputStream()));
- output = new PrintStream(smtp.getOutputStream());
- serverReply = input.readLine();
- System.out.printf("1 Server reply: %s\n", serverReply);
- if (serverReply.charAt(0) != '2') {
- logger.warn("Error connecting to SMTP server: {} port: {} reply: {}", new Object[]{SMTP_SERVER, SMTP_PORT, serverReply});
- }
- submitCommand("EHLO " + SENDING_HOST);
- //only wait thru 10 responses
- int count = 1;
- do {
- serverReply = input.readLine();
- System.out.printf("%s Server reply: %s\n", (count + 1), serverReply);
- if (serverReply.indexOf("STARTTLS") != -1) {
- System.out.println("STARTTLS was received");
- }
- if (count++ >= 10) {
- break;
- }
- } while (serverReply.startsWith("250-"));
- System.out.println("Loop exited");
- submitCommand("STARTTLS");
- //negotiate ciphers
- //mandatory suite: TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA
- TlsProtocolHandler tlsHandler = new TlsProtocolHandler(smtp.getInputStream(), smtp.getOutputStream());
- CertificateVerifyer cv = new AlwaysValidVerifyer();
- tlsHandler.connect(cv);
- //reassign the i/o streams using the tls generated i/o streams
- input = new BufferedReader(new InputStreamReader(tlsHandler.getInputStream()));
- output = new PrintStream(tlsHandler.getOutputStream());
- //hello must be resent after tls setup
- submitCommand("EHLO " + SENDING_HOST);
- serverReply = input.readLine();
- System.out.printf("%s Server reply (2nd hello): %s\n", (count + 1), serverReply);
- //read server replies looking for "220 ready for tls"
- Matcher m = PAT_TLS_READY.matcher(serverReply);
- if (!m.matches()) {
- logger.warn("Error in TLS start: {} port: {} reply: {}", new Object[]{SMTP_SERVER, SMTP_PORT, serverReply});
- }
- count = 1;
- do {
- serverReply = input.readLine();
- System.out.printf("%s Server reply: %s\n", (count + 1), serverReply);
- if (serverReply.indexOf("AUTH") > 0) {
- submitCommand("AUTH LOGIN");
- }
- if (count++ >= 10) {
- break;
- }
- } while (serverReply.startsWith("250-"));
- System.out.println("Loop exited");
- String str = Base64.encodeBase64URLSafeString(AUTH_USER.getBytes());
- System.out.printf("Username: %s\n", str);
- submitCommand(str);
- str = Base64.encodeBase64URLSafeString(AUTH_PASSWORD.getBytes());
- System.out.printf("Password: %s\n", str);
- submitCommand(str);
- //only wait thru 10 responses
- count = 1;
- do {
- serverReply = input.readLine();
- System.out.printf("Server reply in auth wait loop: %s\n", serverReply);
- //gmail sends 235 2.7.0 Accepted
- if (serverReply.indexOf("Accepted") > 0) {
- break;
- }
- if (serverReply.indexOf("authenticated") > 0) {
- break;
- }
- if (count++ >= 10) {
- break;
- }
- } while (true);
- } catch (UnknownHostException e) {
- throw new MailerException(getClass().getName() + " error - unknown host: " + SMTP_SERVER);
- } catch (Exception e) {
- throw new MailerException(getClass().getName() + " error: " + e.getMessage());
- }
- }
- /**
- * Initiates a connection to an SMTP server using TLS/SSL.
- * http://www.faqs.org/rfcs/rfc2487.html
- * TLS http://www.faqs.org/rfcs/rfc2246.html
- *
- * @throws MailerException
- */
- public void startSessionWithSSL() throws MailerException {
- try {
- createSocket();
- //negotiate ciphers
- //mandatory suite: TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA
- TlsProtocolHandler tlsHandler = new TlsProtocolHandler(smtp.getInputStream(), smtp.getOutputStream());
- CertificateVerifyer cv = new AlwaysValidVerifyer();
- tlsHandler.connect(cv);
- //reassign the i/o streams using the tls generated i/o streams
- input = new BufferedReader(new InputStreamReader(tlsHandler.getInputStream()));
- output = new PrintStream(tlsHandler.getOutputStream());
- serverReply = input.readLine();
- System.out.printf("1 Server reply: %s\n", serverReply);
- if (serverReply.charAt(0) != '2') {
- logger.warn("Error connecting to SMTP server: {} port: {} reply: {}", new Object[]{SMTP_SERVER, SMTP_PORT, serverReply});
- }
- submitCommand("EHLO " + SENDING_HOST);
- //only wait thru 10 responses
- int count = 1;
- do {
- serverReply = input.readLine();
- System.out.printf("%s Server reply: %s\n", (count + 1), serverReply);
- if (serverReply.indexOf("AUTH") > 0) {
- submitCommand("AUTH LOGIN");
- }
- if (count++ >= 10) {
- break;
- }
- } while (serverReply.startsWith("250-"));
- System.out.println("Loop exited");
- String str = Base64.encodeBase64URLSafeString(AUTH_USER.getBytes());
- System.out.printf("Username: %s\n", str);
- submitCommand(str);
- str = Base64.encodeBase64URLSafeString(AUTH_PASSWORD.getBytes());
- System.out.printf("Password: %s\n", str);
- submitCommand(str);
- //only wait thru 10 responses
- count = 1;
- do {
- serverReply = input.readLine();
- System.out.printf("Server reply in auth wait loop: %s\n", serverReply);
- //gmail sends 235 2.7.0 Accepted
- if (serverReply.indexOf("Accepted") > 0) {
- break;
- }
- if (serverReply.indexOf("authenticated") > 0) {
- break;
- }
- if (count++ >= 10) {
- break;
- }
- } while (true);
- } catch (UnknownHostException e) {
- throw new MailerException(getClass().getName() + " error - unknown host: " + SMTP_SERVER);
- } catch (Exception e) {
- throw new MailerException(getClass().getName() + " error: " + e.getMessage());
- }
- }
- private void createSocket() throws UnknownHostException, IOException {
- //check for null smtp server
- if (null == SMTP_SERVER || SMTP_SERVER.length() < 3) {
- //look in system props
- String tmp = System.getProperty("mail.server");
- if (null == tmp) {
- tmp = "mail.example.com";
- }
- SMTP_SERVER = tmp;
- }
- //connect to the MX
- smtp = new Socket(SMTP_SERVER, SMTP_PORT);
- //set a socket timeout
- logger.debug("After socket creation, timeout: {}", smtp.getSoTimeout());
- smtp.setSoTimeout(socketTimeout);
- }
- /**
- * Flushes the stream and closes all aspects of the connection.
- */
- public void endSession() {
- //disconnect
- try {
- submitCommand("QUIT");
- if (input != null) {
- input.close();
- }
- if (output != null) {
- output.flush();
- output.close();
- }
- if (smtp != null) {
- smtp.close();
- }
- } catch (Exception e) {
- logger.error("Logout error", e);
- }
- }
- /**
- * Convenience method to allow a "quick" send.
- *
- * @param email
- * @return true if no errors occur, false otherwise
- */
- public boolean sendMessage(Email email) {
- boolean result = false;
- try {
- if ("none".equals(authType)) {
- startSession();
- } else if ("ssl".equals(authType)) {
- startSessionWithSSL();
- } else if ("tls".equals(authType)) {
- startSessionWithTLS();
- }
- sendMail(email);
- result = true;
- } catch (Exception ex) {
- logger.error("Could not send email {}", ex);
- } finally {
- endSession();
- }
- return result;
- }
- private void getXHeaders(StringBuilder sb, String originIp) {
- sb.append("X-Coder: http://www.gregoire.org/");
- sb.append(CRLF);
- sb.append("X-Originating-IP: [");
- sb.append(originIp);
- sb.append("]");
- sb.append(CRLF);
- }
- /**
- * Sends an SMTP command to the connected mail server.
- *
- * @param command valid SMTP command
- * @return true if successful, false otherwise
- * @throws MailerException
- */
- private boolean submitCommand(String command) throws MailerException {
- boolean result = false;
- try {
- //to eliminate the "binary" logging
- if (!command.startsWith("Received: from")) {
- logger.debug("Submit command: {}", command);
- }
- output.print(command);
- output.print(CRLF);
- serverReply = input.readLine();
- logger.debug("Server Reply: {}", serverReply);
- //if the command is message data, get the message id for storage in db
- //when we get the reply
- Matcher m = PAT_SMTP_COMMAND.matcher(command.subSequence(0, 4));
- if (!m.matches()) {
- //reset the matcher
- m.reset();
- // Postfix = 250 Ok: queued as 2727171
- // MS Exchange = 250 Ok: queued as C6F496722E
- // Cox InterMail = 250 xH0R1V00j09Def40000000 mail accepted for delivery
- // 250 2.0.0 hB0N1c00F411ueG03B0NQB mail accepted for delivery
- m = PAT_MESSAGE_ID.matcher(serverReply);
- if (m.find()) {
- logger.debug("Group 1: {}", m.group(1));
- logger.debug("Group 2: {}", m.group(2));
- try {
- String messageId = serverReply.substring(m.start(2), m.end(2));
- logger.info("Found message id: {}", messageId);
- } catch (Exception e) {
- }
- } else {
- logger.debug("Didnt find message id");
- }
- }
- //true if there is a failure of some kind
- if (serverReply.charAt(0) == '4' || serverReply.charAt(0) == '5') {
- logger.warn("The mail server returned an error: {}", serverReply);
- } else {
- result = true;
- }
- } catch (Exception e) {
- logger.error("Error in mail command", e);
- throw new MailerException(getClass().getName() + " error: " + e.getMessage() + " during " + command, serverReply);
- }
- return result;
- }
- /**
- * Returns a properly formatted date.
- * The RFC that states this is 2822 and a link is: http://ftp.rfc-editor.org/in-notes/rfc2822.txt
- * <br>
- * ex: Mon, 21 Apr 2003 13:49:43 -0700
- * <br>
- *
- * @return formatted date
- */
- public String getFormattedDate() {
- return formatter.format(new Date());
- }
- public void setInlineFiles(MailFile mailFile) {
- if (mailFile != null) {
- this.type = "inline";
- files.add(mailFile);
- }
- }
- public void setInlineFiles(MailFile[] mailFiles) {
- this.type = "inline";
- for (int mf = 0; mf < mailFiles.length; mf++) {
- files.add(mailFiles[mf]);
- }
- }
- /**
- * Adds an inline file to the email
- *
- * @param sb email text
- * @param file object containing file data
- */
- public void addInline(StringBuilder sb, MailFile file) {
- sb.append(DASH);
- sb.append(boundary1);
- sb.append(CRLF);
- // image
- sb.append("Content-Type: ");
- sb.append(file.getMimeType());
- sb.append("; name=\"");
- sb.append(file.getFileName());
- sb.append("\"\nContent-Transfer-Encoding: base64\nContent-ID: <");
- sb.append(file.getFileName());
- sb.append(">");
- sb.append(CRLF);
- sb.append(CRLF);
- //Some mail servers will reject emails if they contain lines longer than 76 chars
- byte[] byteLine = new byte[76];
- byte[] buf = file.getDataBuffer();
- int bufLen = buf.length;
- int bufIndex = 0;
- while (bufIndex < bufLen) {
- for (int b = 0; b < 76; b++) {
- if (bufIndex >= bufLen) {
- break;
- }
- byteLine[b] = buf[bufIndex++];
- }
- sb.append(new String(byteLine)); //a byte line must be no longer than 76 bytes + CRLF
- sb.append(CRLF);
- //reset byteline
- System.arraycopy(EMPTY_ARRAY, 0, byteLine, 0, 76);
- }
- sb.append(CRLF);
- }
- /**
- * The host name to use when executing the HELO command.
- *
- * @param sendHost
- */
- public void setSendingHost(String sendHost) {
- Mailer.SENDING_HOST = sendHost;
- }
- public void setSmtpPort(int port) {
- Mailer.SMTP_PORT = port;
- }
- public void setSmtpServer(String serverAddress) {
- Mailer.SMTP_SERVER = serverAddress;
- }
- public void setAuthUser(String userName) {
- Mailer.AUTH_USER = userName;
- }
- public void setAuthPassword(String password) {
- Mailer.AUTH_PASSWORD = password;
- }
- public int getSocketTimeout() {
- return Mailer.socketTimeout;
- }
- public void setSocketTimeout(int socketTimeout) {
- Mailer.socketTimeout = socketTimeout;
- }
- /**
- * Returns the message id assigned to the email by the mail server.
- *
- * @return 10 character message id
- */
- public String getMessageId() {
- return messageId;
- }
- public void setMessageId(String id) {
- messageId = id;
- }
- public static void main(String[] args) {
- Mailer m = new Mailer();
- m.setSendingHost("127.0.0.1");
- m.setAuthUser("your-sending-gmail-email-address");
- m.setAuthPassword("your-gmail-password");
- m.setSmtpServer("smtp.gmail.com");
- m.setSmtpPort(587); //tls
- m.setType("plain");
- Email mail = new Email();
- mail.setFrom("your-sending-gmail-email-address");
- mail.setNiceNameFrom("Sally Sender");
- mail.setTo("your-recipients-address");
- mail.setNiceNameTo("John Q. Public");
- mail.setSubject("Testing tls");
- mail.setPlainText("This is a test of my tls impl.");
- mail.setOriginIP("127.0.0.1"); //use a real origin ip
- try {
- m.startSessionWithTLS();
- m.sendMail(mail);
- System.out.printf("Message id: %s", m.getMessageId());
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- m.endSession();
- }
- }
- }
Add Comment
Please, Sign In to add comment