1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package com.dumbster.smtp;
21
22 import java.io.BufferedReader;
23 import java.io.IOException;
24 import java.io.InputStreamReader;
25 import java.io.InterruptedIOException;
26 import java.io.PrintWriter;
27 import java.net.ServerSocket;
28 import java.net.Socket;
29 import java.util.ArrayList;
30 import java.util.Iterator;
31 import java.util.List;
32
33 /***
34 * Dummy SMTP server for testing purposes.
35 */
36 public class SimpleSmtpServer implements Runnable {
37
38 /*** Stores all of the email received since this instance started up. */
39 private List receivedMail;
40
41 /*** Default SMTP port is 25. */
42 public static final int DEFAULT_SMTP_PORT = 25;
43
44 /*** Indicates whether this server is stopped or not. */
45 private volatile boolean stopped = true;
46
47 /*** Indicates if a stop request has been sent to this server. */
48 private volatile boolean doStop = false;
49
50 /*** Port the server listens on - set to the default SMTP port initially. */
51 private int port = DEFAULT_SMTP_PORT;
52
53 /***
54 * Constructor.
55 */
56 public SimpleSmtpServer(int port) {
57 receivedMail = new ArrayList();
58 this.port = port;
59 }
60
61 /***
62 * Main loop of the SMTP server.
63 */
64 public void run() {
65 stopped = false;
66 ServerSocket serverSocket = null;
67 try {
68 serverSocket = new ServerSocket(port);
69 serverSocket.setSoTimeout(500);
70
71
72 while (!doStop) {
73 Socket socket = null;
74 try {
75 socket = serverSocket.accept();
76 } catch (InterruptedIOException iioe) {
77 if (socket != null) {
78 socket.close();
79 }
80 continue;
81 }
82
83
84 BufferedReader input = new BufferedReader(new InputStreamReader(socket
85 .getInputStream()));
86 PrintWriter out = new PrintWriter(socket.getOutputStream());
87
88
89 SmtpState smtpState = SmtpState.CONNECT;
90 SmtpRequest smtpRequest = new SmtpRequest(SmtpActionType.CONNECT, "", smtpState);
91
92
93 SmtpResponse smtpResponse = smtpRequest.execute();
94
95
96 sendResponse(out, smtpResponse);
97 smtpState = smtpResponse.getNextState();
98
99 SmtpMessage msg = new SmtpMessage();
100
101 while (smtpState != SmtpState.CONNECT) {
102 String line = input.readLine();
103
104 if (line == null) {
105 break;
106 }
107
108 SmtpRequest request = SmtpRequest.createRequest(line, smtpState);
109
110 SmtpResponse response = request.execute();
111
112 smtpState = response.getNextState();
113
114 sendResponse(out, response);
115
116
117 msg.store(response, request.getParams());
118 }
119
120 receivedMail.add(msg);
121 socket.close();
122 }
123 } catch (Exception e) {
124
125 } finally {
126 if (serverSocket != null) {
127 try {
128 serverSocket.close();
129 } catch (IOException e) {
130 e.printStackTrace();
131 }
132 }
133 }
134 stopped = true;
135 }
136
137 /***
138 * Send response to client.
139 * @param out socket output stream
140 * @param smtpResponse response object
141 */
142 private void sendResponse(PrintWriter out, SmtpResponse smtpResponse) {
143 if (smtpResponse.getCode() > 0) {
144 out.print(smtpResponse.getCode() + " " + smtpResponse.getMessage() + "\r\n");
145 out.flush();
146 }
147 }
148
149 /***
150 * Get email received by this instance since start up.
151 * @return List of String
152 */
153 public Iterator getReceivedEmail() {
154 return receivedMail.iterator();
155 }
156
157 /***
158 * Get the number of messages received.
159 * @return size of received email list
160 */
161 public int getReceievedEmailSize() {
162 return receivedMail.size();
163 }
164
165 /***
166 * Forces the server to stop after processing the current request.
167 */
168 public void stop() {
169 doStop = true;
170 while (!isStopped()) {}
171 }
172
173 /***
174 * Indicates whether this server is stopped or not.
175 * @return true iff this server is stopped
176 */
177 public boolean isStopped() {
178 return stopped;
179 }
180
181 /***
182 * Creates an instance of SimpleSmtpServer and starts it. Will listen on the default port.
183 * @return a reference to the SMTP server
184 */
185 public static SimpleSmtpServer start() {
186 return start(DEFAULT_SMTP_PORT);
187 }
188
189 /***
190 * Creates an instance of SimpleSmtpServer and starts it.
191 * @param port port number the server should listen to
192 * @return a reference to the SMTP server
193 */
194 public static SimpleSmtpServer start(int port) {
195 SimpleSmtpServer server = new SimpleSmtpServer(port);
196 Thread t = new Thread(server);
197 t.start();
198 return server;
199 }
200
201 }