/**
* MailTester servlet v1.0
*
* Denis Bourdon
* dbourdon@dbourdon.com
* www.dbourdon.com
* July 23rd 2001 for the code
* February 2nd 2002 for the English translation
*/
// standard imports
import java.io.*;
import java.util.*;
import java.text.*;
// Servlet
import javax.servlet.*;
import javax.servlet.http.*;
// JavaMail API
import javax.mail.*;
import javax.mail.internet.*;
// JavaBeans Extension Framework (necessary to the JavaMail API)
import javax.activation.*;
public class MailTester extends HttpServlet
{
/** The servlet's name and version. */
protected final static String servletName = "MailTester servlet v1.0";
/** The SMTP Host name (e.g. localhost, smtp.yourdomain.com, etc.);
* set to localhost
if no value set in the properties file.*/
protected static String smtpHost;
/** The Init
method is called the first time the servlet is run;
it sets the initialization parameters from the servlet properties file. */
public void init( ServletConfig config ) throws ServletException {
// usual routine for servlets
super.init(config);
// Set the initialization parameters.
// smtpHost: if no value, set to "localhost"
smtpHost = getInitParameter("smtpHost");
if (smtpHost == null) smtpHost = "localhost";
}
/** The doGet
method is called when the servlet is called with
a GET HTTP request; the servlet response displays a mailer-like form. */
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws IOException
{
PrintWriter out = response.getWriter();
out.print("\n");
out.print("
\n"); out.print("The \"smtpHosts\" field is multivalued. The destination fields (To, Cc, Bcc) are multivalued and nominative (e.g., Denis Bourdon <dbourdon@dbourdon.com>, foo@foo.com).\n"); out.print("
\n"); out.print("
\n"); out.print("doPost
method is called when the servlet is called with
a GET POST request; this is the entry point when the message is received. */
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
throws IOException
{
try
{
// if the ContentType is "multipart/form-data"
if( request.getContentType().startsWith("multipart/form-data") )
{
// calls the doSendMessage method
doSendMessage( request, response );
}
else
{
PrintWriter out = response.getWriter();
out.print("\n\nMailTester error:\n" + "The ContentType of the POST method is not" + " \"multipart/form-data\".\n" + "\n\n"); out.flush(); } } catch(Exception e) { PrintWriter out = response.getWriter(); out.print("\n\nMailTester error:
"); e.printStackTrace(out); out.print("\n"); out.flush(); } } /** The
doSendMessage
method is called when the POST method has
worked. It creates the email and connects to the SMTP server to send it.*/
public void doSendMessage(HttpServletRequest request,
HttpServletResponse response)
throws IOException, MessagingException, AddressException, SendFailedException
{
// creates the boundary relative to the ContentType of the header
String boundary = request.getHeader("Content-Type");
int pos = boundary.indexOf('=');
boundary = boundary.substring(pos + 1);
boundary = "--" + boundary;
// the ServletInputStream flow will be parsed using an array of 512 bytes
byte[] bytes = new byte[512];
// the parsing processus will be a state machine (5 states)
int state = 0;
// buffer
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
String name = null,
value = null,
filename = null,
contentType = null;
Dictionary fields = new Hashtable();
ServletInputStream in = request.getInputStream();
int i = in.readLine(bytes,0,512);
// while the state machine can read 512 bytes
while(i != -1)
{
// converts the array of characters to a string
String st = new String(bytes,0,i);
// machine state initialization
if(st.startsWith(boundary))
{
state = 0;
if(name != null)
{
if(value != null)
{
// name and value not null
// -> it's a from, cc etc.
// updates the fields Dictionnary
// (-2 to remove CR/LF; i.e. final line)
fields.put(name, value.substring(0, value.length() - 2));
}
else if(buffer.size() > 2)
{
// i.e. more than CR/LF
// creates the MimeBodyPart
MimeBodyPart bodyPart = new MimeBodyPart();
DataSource ds = new Attachment(buffer.toByteArray(),
contentType,filename);
bodyPart.setDataHandler( new DataHandler(ds));
bodyPart.setDisposition("attachment; filename=\""
+ filename + "\"");
bodyPart.setFileName(filename);
fields.put(name,bodyPart);
}
// resets the variables
name = null;
value = null;
filename = null;
contentType = null;
buffer = new ByteArrayOutputStream();
}
}
else if(st.startsWith("Content-Disposition: form-data") && state == 0)
{
StringTokenizer tokenizer = new StringTokenizer(st,";=\"");
while(tokenizer.hasMoreTokens())
{
String token = tokenizer.nextToken();
if(token.startsWith(" name"))
{
// it's text data
name = tokenizer.nextToken();
// go to state #2
state = 2;
}
else if(token.startsWith(" filename"))
{
// it's a file
filename = tokenizer.nextToken();
StringTokenizer ftokenizer = new StringTokenizer(filename,"\\/:");
filename = ftokenizer.nextToken();
while(ftokenizer.hasMoreTokens()) filename = ftokenizer.nextToken();
// go to state #1
state = 1;
break;
}
}
}
else if(st.startsWith("Content-Type") && state == 1)
{
// gets the contentType
pos = st.indexOf(":");
// + 2 to remove the space
// - 2 to remove CR/LF
contentType = st.substring(pos + 2,st.length() - 2);
}
else if(st.equals("\r\n") && state == 1)
{
// ready to receive the file -> go to state #3
state = 3;
}
else if(st.equals("\r\n") && state == 2)
{
// ready to receive the text data -> go to state #4
state = 4;
}
else if(state == 4)
{
// sets the value
value = value == null ? st : value + st;
}
else if(state == 3)
{
// gets the file and puts the flow in the ByteArrayOutputStream buffer
buffer.write(bytes,0,i);
}
// reads once more
i = in.readLine(bytes,0,512);
}
// Time to create the email!
// retrieving smtp servers
String smtpHosts = (String)fields.get("smtpHosts");
char currentChar;
String currentHost = "";
for(int l=0;lNo \"from\" address specified.\n" + "\n