blob: dc7dff64cfe26456bbb28ecffd0c2027a3462447 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.tools.ant;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.Callable;
/**
* A utility class that pretends to be a mail transfer agent. This
* has minimal functionality and is meant to be used only in tests
*/
public class DummyMailServer implements Runnable, Callable<Void> {
private final String host;
private final int port;
private StringBuilder sb = null;
private volatile boolean stop = false;
ServerSocket ssock = null;
Socket sock = null;
BufferedWriter out = null;
BufferedReader in = null;
private boolean data = false; // state engine: false=envelope, true=message
public DummyMailServer(int port) {
this("localhost", port);
}
public DummyMailServer(final String host, final int port) {
this.host = host;
this.port = port;
}
public int getPort() {
return this.port;
}
public String getHost() {
return this.host;
}
public void run() {
call();
}
public Void call() {
try {
ssock = new ServerSocket(port);
sock = ssock.accept(); // wait for connection
in = new BufferedReader(new InputStreamReader(
sock.getInputStream()));
out = new BufferedWriter(new OutputStreamWriter(
sock.getOutputStream()));
sb = new StringBuilder();
send("220 test SMTP EmailTaskTest\r\n");
while (!stop) {
String response = in.readLine();
if (response == null) {
stop = true;
break;
}
sb.append(response).append("\r\n");
if (!data && response.startsWith("EHLO")) {
// reject Extended HLO semantics, since we don't support it
send("500 EHLO unsupported\r\n");
} else if (!data && response.startsWith("HELO")) {
send("250 " + host + " Hello " + host + " "
+ "[127.0.0.1], pleased to meet you\r\n");
} else if (!data && response.startsWith("MAIL")) {
send("250\r\n");
} else if (!data && response.startsWith("RCPT")) {
send("250\r\n");
} else if (!data && response.startsWith("DATA")) {
send("354\r\n");
data = true;
} else if (data && response.equals(".")) {
send("250\r\n");
data = false;
} else if (!data && response.startsWith("QUIT")) {
send("221\r\n");
stop = true;
} else if (!data) {
send("500 5.5.1 Command unrecognized: \""
+ response + "\"\r\n");
stop = true;
} else {
// sb.append(response + "\r\n");
}
} // while
} catch (IOException ioe) {
if (stop) {
// asked to stop, so ignore the exception and move on
return null;
}
throw new BuildException(ioe);
} finally {
disconnect();
}
return null;
}
private void send(String retmsg) throws IOException {
out.write(retmsg);
out.flush();
sb.append(retmsg);
}
public void disconnect() {
this.stop = true;
if (out != null) {
try {
out.flush();
out.close();
out = null;
} catch (IOException e) {
// ignore
}
}
if (in != null) {
try {
in.close();
in = null;
} catch (IOException e) {
// ignore
}
}
if (sock != null) {
try {
sock.close();
sock = null;
} catch (IOException e) {
// ignore
}
}
if (ssock != null) {
try {
ssock.close();
ssock = null;
} catch (IOException e) {
// ignore
}
}
}
public synchronized String getResult() {
this.stop = true;
return sb.toString();
}
/**
* Starts and returns a new dummy mail server to be used in tests
*
* @return
*/
public static DummyMailServer startMailServer() {
return startMailServer("localhost");
}
/**
* Starts and returns a new dummy mail server to be used in tests
*
* @param host The host on which the mail server will open a server socket to listen on
* @return
*/
public static DummyMailServer startMailServer(final String host) {
final int port = TestHelper.getMaybeAvailablePort();
final DummyMailServer mailServer = new DummyMailServer(host, port);
final Thread thread = new Thread(mailServer);
thread.setDaemon(true);
thread.start();
return mailServer;
}
}