diff --git a/net-mail/src/test/java/org/xbib/net/mail/test/imap/IMAPAlertTest.java b/net-mail/src/test/java/org/xbib/net/mail/test/imap/IMAPAlertTest.java index 617ac32..0152984 100644 --- a/net-mail/src/test/java/org/xbib/net/mail/test/imap/IMAPAlertTest.java +++ b/net-mail/src/test/java/org/xbib/net/mail/test/imap/IMAPAlertTest.java @@ -24,6 +24,7 @@ import org.junit.jupiter.api.Test; import org.xbib.net.mail.test.test.TestServer; import java.io.IOException; +import java.io.OutputStream; import java.util.Properties; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -80,7 +81,7 @@ public final class IMAPAlertTest { store.close(); } } catch (final Exception e) { - e.printStackTrace(); + //e.printStackTrace(); fail(e.getMessage()); } finally { if (server != null) { @@ -94,9 +95,9 @@ public final class IMAPAlertTest { */ private static final class IMAPHandlerAlert extends IMAPHandler { @Override - public void login() throws IOException { - untagged("OK [ALERT] account is over quota"); - super.login(); + public void login(OutputStream outputStream) throws IOException { + untagged(outputStream, "OK [ALERT] account is over quota"); + super.login(outputStream); } } } diff --git a/net-mail/src/test/java/org/xbib/net/mail/test/imap/IMAPCloseFailureTest.java b/net-mail/src/test/java/org/xbib/net/mail/test/imap/IMAPCloseFailureTest.java index 7fefacf..16e8e0a 100644 --- a/net-mail/src/test/java/org/xbib/net/mail/test/imap/IMAPCloseFailureTest.java +++ b/net-mail/src/test/java/org/xbib/net/mail/test/imap/IMAPCloseFailureTest.java @@ -23,6 +23,7 @@ import org.junit.jupiter.api.Test; import org.xbib.net.mail.test.test.TestServer; import java.io.IOException; +import java.io.OutputStream; import java.util.Properties; import static org.junit.jupiter.api.Assertions.fail; @@ -37,11 +38,11 @@ public final class IMAPCloseFailureTest { static boolean first = true; @Override - public void examine(String line) throws IOException { + public void examine(OutputStream outputStream, String line) throws IOException { if (first) - no("mailbox gone"); + no(outputStream, "mailbox gone"); else - super.examine(line); + super.examine(outputStream, line); first = false; } } @@ -50,11 +51,11 @@ public final class IMAPCloseFailureTest { static boolean first = true; @Override - public void examine(String line) throws IOException { + public void examine(OutputStream outputStream, String line) throws IOException { if (first) - bad("mailbox gone"); + bad(outputStream, "mailbox gone"); else - super.examine(line); + super.examine(outputStream, line); first = false; } } diff --git a/net-mail/src/test/java/org/xbib/net/mail/test/imap/IMAPConnectFailureTest.java b/net-mail/src/test/java/org/xbib/net/mail/test/imap/IMAPConnectFailureTest.java index 112d1f9..a925d35 100644 --- a/net-mail/src/test/java/org/xbib/net/mail/test/imap/IMAPConnectFailureTest.java +++ b/net-mail/src/test/java/org/xbib/net/mail/test/imap/IMAPConnectFailureTest.java @@ -25,6 +25,7 @@ import org.xbib.net.mail.test.test.TestServer; import org.xbib.net.mail.util.MailConnectException; import java.io.IOException; +import java.io.OutputStream; import java.net.ServerSocket; import java.util.Properties; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -89,12 +90,12 @@ public final class IMAPConnectFailureTest { try { final IMAPHandler handler = new IMAPHandler() { @Override - public void sendGreetings() throws IOException { - untagged("OK IMAPHandler"); + public void sendGreetings(OutputStream outputStream) throws IOException { + untagged(outputStream, "OK IMAPHandler"); } @Override - public void capability() throws IOException { + public void capability(OutputStream outputStream) throws IOException { exit(); } }; diff --git a/net-mail/src/test/java/org/xbib/net/mail/test/imap/IMAPFetchProfileTest.java b/net-mail/src/test/java/org/xbib/net/mail/test/imap/IMAPFetchProfileTest.java index 67e5066..3de3b5e 100644 --- a/net-mail/src/test/java/org/xbib/net/mail/test/imap/IMAPFetchProfileTest.java +++ b/net-mail/src/test/java/org/xbib/net/mail/test/imap/IMAPFetchProfileTest.java @@ -28,6 +28,7 @@ import org.xbib.net.mail.imap.IMAPFolder; import org.xbib.net.mail.test.test.TestServer; import java.io.IOException; +import java.io.OutputStream; import java.util.HashSet; import java.util.Properties; import java.util.Set; @@ -75,11 +76,12 @@ public final class IMAPFetchProfileTest { }, new IMAPHandlerFetch() { @Override - public void fetch(String line) throws IOException { - if (line.contains("INTERNALDATE")) + public void fetch(OutputStream outputStream, String line) throws IOException { + if (line.contains("INTERNALDATE")) { saw.add("INTERNALDATE"); - untagged("1 FETCH (INTERNALDATE \"" + RDATE + "\")"); - ok(); + } + untagged(outputStream, "1 FETCH (INTERNALDATE \"" + RDATE + "\")"); + ok(outputStream); } }); } @@ -103,11 +105,12 @@ public final class IMAPFetchProfileTest { }, new IMAPHandlerFetch() { @Override - public void fetch(String line) throws IOException { - if (line.contains("INTERNALDATE")) + public void fetch(OutputStream outputStream, String line) throws IOException { + if (line.contains("INTERNALDATE")) { saw.add("INTERNALDATE"); - untagged("1 FETCH (INTERNALDATE \"" + RDATE + "\")"); - ok(); + } + untagged(outputStream, "1 FETCH (INTERNALDATE \"" + RDATE + "\")"); + ok(outputStream); } }); } @@ -126,12 +129,13 @@ public final class IMAPFetchProfileTest { }, new IMAPHandlerFetch() { @Override - public void fetch(String line) throws IOException { - if (line.contains("INTERNALDATE")) + public void fetch(OutputStream outputStream, String line) throws IOException { + if (line.contains("INTERNALDATE")) { saw.add("INTERNALDATE"); - untagged("1 FETCH (ENVELOPE " + ENVELOPE + + } + untagged(outputStream, "1 FETCH (ENVELOPE " + ENVELOPE + " INTERNALDATE \"" + RDATE + "\" RFC822.SIZE 0)"); - ok(); + ok(outputStream); } }); } @@ -182,9 +186,9 @@ public final class IMAPFetchProfileTest { protected static Set saw = new HashSet<>(); @Override - public void select(String line) throws IOException { + public void select(OutputStream outputStream, String line) throws IOException { numberOfMessages = 1; - super.select(line); + super.select(outputStream, line); } public boolean saw(String item) { diff --git a/net-mail/src/test/java/org/xbib/net/mail/test/imap/IMAPFolderTest.java b/net-mail/src/test/java/org/xbib/net/mail/test/imap/IMAPFolderTest.java index 6df6fa4..bba306f 100644 --- a/net-mail/src/test/java/org/xbib/net/mail/test/imap/IMAPFolderTest.java +++ b/net-mail/src/test/java/org/xbib/net/mail/test/imap/IMAPFolderTest.java @@ -27,6 +27,7 @@ import org.xbib.net.mail.imap.IMAPFolder; import org.xbib.net.mail.test.test.TestServer; import java.io.IOException; +import java.io.OutputStream; import java.util.Properties; import java.util.StringTokenizer; import java.util.logging.Level; @@ -75,21 +76,21 @@ class IMAPFolderTest { }, new IMAPHandler() { @Override - public void create(String line) throws IOException { + public void create(OutputStream outputStream,String line) throws IOException { StringTokenizer st = new StringTokenizer(line); st.nextToken(); // skip tag st.nextToken(); // skip "CREATE" String name = st.nextToken(); if (name.equals(utf7Folder)) - ok(); + ok(outputStream); else - no("wrong name"); + no(outputStream, "wrong name"); } @Override - public void list(String line) throws IOException { - untagged("LIST (\\HasNoChildren) \"/\" " + utf7Folder); - ok(); + public void list(OutputStream outputStream, String line) throws IOException { + untagged(outputStream, "LIST (\\HasNoChildren) \"/\" " + utf7Folder); + ok(outputStream); } }); } @@ -111,22 +112,21 @@ class IMAPFolderTest { }, new IMAPUtf8Handler() { @Override - public void create(String line) throws IOException { + public void create(OutputStream outputStream, String line) throws IOException { StringTokenizer st = new StringTokenizer(line); st.nextToken(); // skip tag st.nextToken(); // skip "CREATE" String name = unquote(st.nextToken()); if (name.equals(utf8Folder)) - ok(); + ok(outputStream); else - no("wrong name"); + no(outputStream, "wrong name"); } @Override - public void list(String line) throws IOException { - untagged("LIST (\\HasNoChildren) \"/\" \"" + - utf8Folder + "\""); - ok(); + public void list(OutputStream outputStream, String line) throws IOException { + untagged(outputStream, "LIST (\\HasNoChildren) \"/\" \"" + utf8Folder + "\""); + ok(outputStream); } }); } @@ -148,15 +148,15 @@ class IMAPFolderTest { }, new IMAPHandler() { @Override - public void delete(String line) throws IOException { + public void delete(OutputStream outputStream, String line) throws IOException { StringTokenizer st = new StringTokenizer(line); st.nextToken(); // skip tag st.nextToken(); // skip "DELETE" String name = st.nextToken(); if (name.equals(utf7Folder)) - ok(); + ok(outputStream); else - no("wrong name"); + no(outputStream, "wrong name"); } }); } @@ -178,15 +178,16 @@ class IMAPFolderTest { }, new IMAPUtf8Handler() { @Override - public void delete(String line) throws IOException { + public void delete(OutputStream outputStream, String line) throws IOException { StringTokenizer st = new StringTokenizer(line); st.nextToken(); // skip tag st.nextToken(); // skip "DELETE" String name = unquote(st.nextToken()); - if (name.equals(utf8Folder)) - ok(); - else - no("wrong name"); + if (name.equals(utf8Folder)) { + ok(outputStream); + } else { + no(outputStream, "wrong name"); + } } }); } @@ -210,15 +211,15 @@ class IMAPFolderTest { }, new IMAPHandler() { @Override - public void select(String line) throws IOException { + public void select(OutputStream outputStream, String line) throws IOException { StringTokenizer st = new StringTokenizer(line); st.nextToken(); // skip tag st.nextToken(); // skip "SELECT" String name = st.nextToken(); if (name.equals(utf7Folder)) - ok(); + ok(outputStream); else - no("wrong name"); + no(outputStream, "wrong name"); } }); } @@ -242,15 +243,15 @@ class IMAPFolderTest { }, new IMAPUtf8Handler() { @Override - public void select(String line) throws IOException { + public void select(OutputStream outputStream, String line) throws IOException { StringTokenizer st = new StringTokenizer(line); st.nextToken(); // skip tag st.nextToken(); // skip "SELECT" String name = unquote(st.nextToken()); if (name.equals(utf8Folder)) - ok(); + ok(outputStream); else - no("wrong name"); + no(outputStream, "wrong name"); } }); } @@ -274,15 +275,15 @@ class IMAPFolderTest { }, new IMAPHandler() { @Override - public void examine(String line) throws IOException { + public void examine(OutputStream outputStream, String line) throws IOException { StringTokenizer st = new StringTokenizer(line); st.nextToken(); // skip tag st.nextToken(); // skip "EXAMINE" String name = st.nextToken(); if (name.equals(utf7Folder)) - ok(); + ok(outputStream); else - no("wrong name"); + no(outputStream, "wrong name"); } }); } @@ -306,15 +307,15 @@ class IMAPFolderTest { }, new IMAPUtf8Handler() { @Override - public void examine(String line) throws IOException { + public void examine(OutputStream outputStream, String line) throws IOException { StringTokenizer st = new StringTokenizer(line); st.nextToken(); // skip tag st.nextToken(); // skip "EXAMINE" String name = unquote(st.nextToken()); if (name.equals(utf8Folder)) - ok(); + ok(outputStream); else - no("wrong name"); + no(outputStream, "wrong name"); } }); } @@ -336,17 +337,17 @@ class IMAPFolderTest { }, new IMAPHandler() { @Override - public void status(String line) throws IOException { + public void status(OutputStream outputStream, String line) throws IOException { StringTokenizer st = new StringTokenizer(line); st.nextToken(); // skip tag st.nextToken(); // skip "STATUS" String name = st.nextToken(); if (name.equals(utf7Folder)) { - untagged("STATUS " + utf7Folder + + untagged(outputStream, "STATUS " + utf7Folder + " (UIDVALIDITY 123)"); - ok(); + ok(outputStream); } else - no("wrong name"); + no(outputStream, "wrong name"); } }); } @@ -368,17 +369,17 @@ class IMAPFolderTest { }, new IMAPUtf8Handler() { @Override - public void status(String line) throws IOException { + public void status(OutputStream outputStream, String line) throws IOException { StringTokenizer st = new StringTokenizer(line); st.nextToken(); // skip tag st.nextToken(); // skip "STATUS" String name = unquote(st.nextToken()); if (name.equals(utf8Folder)) { - untagged("STATUS \"" + utf8Folder + + untagged(outputStream, "STATUS \"" + utf8Folder + "\" (UIDVALIDITY 123)"); - ok(); + ok(outputStream); } else - no("wrong name"); + no(outputStream, "wrong name"); } }); } @@ -426,9 +427,9 @@ class IMAPFolderTest { }, new IMAPHandler() { @Override - public void select(String line) throws IOException { - untagged("NO [UIDNOTSTICKY]"); - super.select(line); + public void select(OutputStream outputStream, String line) throws IOException { + untagged(outputStream, "NO [UIDNOTSTICKY]"); + super.select(outputStream, line); } }); } @@ -457,10 +458,10 @@ class IMAPFolderTest { }, new IMAPHandler() { @Override - public void search(String line) throws IOException { - untagged("1 EXPUNGE"); - untagged("0 EXISTS"); - super.search(line); + public void search(OutputStream outputStream, String line) throws IOException { + untagged(outputStream, "1 EXPUNGE"); + untagged(outputStream, "0 EXISTS"); + super.search(outputStream, line); } }); } @@ -527,8 +528,8 @@ class IMAPFolderTest { } @Override - public void enable(String line) throws IOException { - ok(); + public void enable(OutputStream outputStream, String line) throws IOException { + ok(outputStream); } } } diff --git a/net-mail/src/test/java/org/xbib/net/mail/test/imap/IMAPHandler.java b/net-mail/src/test/java/org/xbib/net/mail/test/imap/IMAPHandler.java index 4cc1d04..a2f6d84 100644 --- a/net-mail/src/test/java/org/xbib/net/mail/test/imap/IMAPHandler.java +++ b/net-mail/src/test/java/org/xbib/net/mail/test/imap/IMAPHandler.java @@ -21,10 +21,12 @@ import org.xbib.net.mail.test.test.ProtocolHandler; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.nio.channels.Channels; import java.nio.charset.StandardCharsets; import java.util.Base64; import java.util.StringTokenizer; import java.util.logging.Level; +import java.util.logging.Logger; /** * Handle IMAP connection. @@ -33,6 +35,8 @@ import java.util.logging.Level; */ public class IMAPHandler extends ProtocolHandler { + private static final Logger logger = Logger.getLogger(IMAPHandler.class.getName()); + /** * Current line. */ @@ -58,19 +62,14 @@ public class IMAPHandler extends ProtocolHandler { */ protected int numberOfRecentMessages = 0; - public IMAPHandler(InputStream inputStream, - OutputStream outputStream) { - super(inputStream, outputStream); - } - /** * Send greetings. * * @throws IOException unable to write to socket */ @Override - public void sendGreetings() throws IOException { - untagged("OK [CAPABILITY " + capabilities + "] IMAPHandler"); + public void sendGreetings(OutputStream outputStream) throws IOException { + untagged(outputStream, "OK [CAPABILITY " + capabilities + "] IMAPHandler"); } /** @@ -79,10 +78,9 @@ public class IMAPHandler extends ProtocolHandler { * @param str String to send * @throws IOException unable to write to socket */ - public void println(final String str) throws IOException { - writer.print(str); - writer.print("\r\n"); - writer.flush(); + public void println(OutputStream outputStream, final String str) throws IOException { + Channels.newChannel(outputStream).write(StandardCharsets.UTF_8.encode(str + "\r\n")); + outputStream.flush(); } /** @@ -91,8 +89,8 @@ public class IMAPHandler extends ProtocolHandler { * @param resp the response to send * @throws IOException unable to read/write to socket */ - public void tagged(final String resp) throws IOException { - println(tag + " " + resp); + public void tagged(OutputStream outputStream, final String resp) throws IOException { + println(outputStream, tag + " " + resp); } /** @@ -101,8 +99,8 @@ public class IMAPHandler extends ProtocolHandler { * @param resp the response to send * @throws IOException unable to read/write to socket */ - public void untagged(final String resp) throws IOException { - println("* " + resp); + public void untagged(OutputStream outputStream, final String resp) throws IOException { + println(outputStream, "* " + resp); } /** @@ -110,8 +108,8 @@ public class IMAPHandler extends ProtocolHandler { * * @throws IOException unable to read/write to socket */ - public void ok() throws IOException { - tagged("OK"); + public void ok(OutputStream outputStream) throws IOException { + tagged(outputStream, "OK"); } /** @@ -120,8 +118,8 @@ public class IMAPHandler extends ProtocolHandler { * @param msg the message to send * @throws IOException unable to read/write to socket */ - public void ok(final String msg) throws IOException { - tagged("OK " + (msg != null ? msg : "")); + public void ok(OutputStream outputStream, final String msg) throws IOException { + tagged(outputStream, "OK " + (msg != null ? msg : "")); } /** @@ -130,8 +128,8 @@ public class IMAPHandler extends ProtocolHandler { * @param msg the message to send * @throws IOException unable to read/write to socket */ - public void no(final String msg) throws IOException { - tagged("NO " + (msg != null ? msg : "")); + public void no(OutputStream outputStream, final String msg) throws IOException { + tagged(outputStream, "NO " + (msg != null ? msg : "")); } /** @@ -140,8 +138,8 @@ public class IMAPHandler extends ProtocolHandler { * @param msg the message to send * @throws IOException unable to read/write to socket */ - public void bad(final String msg) throws IOException { - tagged("BAD " + (msg != null ? msg : "")); + public void bad(OutputStream outputStream, final String msg) throws IOException { + tagged(outputStream, "BAD " + (msg != null ? msg : "")); } /** @@ -150,8 +148,8 @@ public class IMAPHandler extends ProtocolHandler { * @param msg the message to send * @throws IOException unable to read/write to socket */ - public void bye(final String msg) throws IOException { - untagged("BYE " + (msg != null ? msg : "")); + public void bye(OutputStream outputStream, final String msg) throws IOException { + untagged(outputStream, "BYE " + (msg != null ? msg : "")); exit(); } @@ -160,8 +158,8 @@ public class IMAPHandler extends ProtocolHandler { * * @throws IOException unable to read/write to socket */ - public void cont() throws IOException { - println("+ please continue"); + public void cont(OutputStream outputStream) throws IOException { + println(outputStream, "+ please continue"); } /** @@ -169,8 +167,8 @@ public class IMAPHandler extends ProtocolHandler { * * @throws IOException unable to read/write to socket */ - public void cont(String msg) throws IOException { - println("+ " + (msg != null ? msg : "")); + public void cont(OutputStream outputStream, String msg) throws IOException { + println(outputStream, "+ " + (msg != null ? msg : "")); } /** @@ -179,96 +177,92 @@ public class IMAPHandler extends ProtocolHandler { * @throws IOException unable to read/write to socket */ @Override - public void handleCommand() throws IOException { - currentLine = super.readLine(); - + public void handleCommand(InputStream inputStream, OutputStream outputStream) throws IOException { + currentLine = super.readLine(inputStream); if (currentLine == null) { // probably just EOF because the socket was closed //LOGGER.severe("Current line is null!"); exit(); return; } - StringTokenizer ct = new StringTokenizer(currentLine, " "); if (!ct.hasMoreTokens()) { - LOGGER.log(Level.SEVERE, "ERROR no command tag: {0}", - escape(currentLine)); - bad("no command tag"); + logger.log(Level.SEVERE, "ERROR no command tag: {0}", escape(currentLine)); + bad(outputStream, "no command tag"); return; } tag = ct.nextToken(); if (!ct.hasMoreTokens()) { - LOGGER.log(Level.SEVERE, "ERROR no command: {0}", + logger.log(Level.SEVERE, "ERROR no command: {0}", escape(currentLine)); - bad("no command"); + bad(outputStream, "no command"); return; } final String commandName = ct.nextToken().toUpperCase(); - if (commandName == null) { - LOGGER.severe("Command name is empty!"); + if (commandName.isEmpty()) { + logger.severe("Command name is empty!"); exit(); return; } - if (commandName.equals("LOGIN")) { - login(); + login(outputStream); } else if (commandName.equals("AUTHENTICATE")) { String mech = ct.nextToken().toUpperCase(); String ir = null; - if (ct.hasMoreTokens()) + if (ct.hasMoreTokens()) { ir = ct.nextToken(); - authenticate(mech, ir); + } + authenticate(inputStream, outputStream, mech, ir); } else if (commandName.equals("CAPABILITY")) { - capability(); + capability(outputStream); } else if (commandName.equals("NOOP")) { - noop(); + noop(outputStream); } else if (commandName.equals("SELECT")) { - select(currentLine); + select(outputStream, currentLine); } else if (commandName.equals("EXAMINE")) { - examine(currentLine); + examine(outputStream, currentLine); } else if (commandName.equals("LIST")) { - list(currentLine); + list(outputStream, currentLine); } else if (commandName.equals("IDLE")) { - idle(); + idle(inputStream, outputStream); } else if (commandName.equals("FETCH")) { - fetch(currentLine); + fetch(outputStream, currentLine); } else if (commandName.equals("STORE")) { - store(currentLine); + store(outputStream, currentLine); } else if (commandName.equals("SEARCH")) { - search(currentLine); + search(outputStream, currentLine); } else if (commandName.equals("APPEND")) { - append(currentLine); + append(inputStream, outputStream, currentLine); } else if (commandName.equals("CLOSE")) { - close(); + close(outputStream); } else if (commandName.equals("LOGOUT")) { - logout(); + logout(outputStream); } else if (commandName.equals("UID")) { String subcommandName = ct.nextToken().toUpperCase(); if (subcommandName.equals("FETCH")) { - uidfetch(currentLine); + uidfetch(outputStream, currentLine); } else if (subcommandName.equals("STORE")) { - uidstore(currentLine); + uidstore(outputStream, currentLine); } else { - LOGGER.log(Level.SEVERE, "ERROR UID command unknown: {0}", - subcommandName); - bad("unknown UID command"); + logger.log(Level.SEVERE, "ERROR UID command unknown: {0}", subcommandName); + bad(outputStream, "unknown UID command"); } } else if (commandName.equals("ID")) { - id(currentLine); + id(outputStream, currentLine); } else if (commandName.equals("ENABLE")) { - enable(currentLine); + enable(outputStream, currentLine); } else if (commandName.equals("CREATE")) { - create(currentLine); + create(outputStream, currentLine); } else if (commandName.equals("DELETE")) { - delete(currentLine); + delete(outputStream, currentLine); } else if (commandName.equals("STATUS")) { - status(currentLine); + status(outputStream, currentLine); } else if (commandName.equals("NAMESPACE")) { - namespace(); + namespace(outputStream); } else { - LOGGER.log(Level.SEVERE, "ERROR command unknown: {0}", + logger.log(Level.SEVERE, "ERROR command unknown: {0}", escape(currentLine)); - bad("unknown command"); + bad(outputStream, "unknown command"); } } @@ -277,8 +271,8 @@ public class IMAPHandler extends ProtocolHandler { * * @throws IOException unable to read/write to socket */ - public void login() throws IOException { - ok("[CAPABILITY " + capabilities + "]"); + public void login(OutputStream outputStream) throws IOException { + ok(outputStream, "[CAPABILITY " + capabilities + "]"); } /** @@ -286,13 +280,13 @@ public class IMAPHandler extends ProtocolHandler { * * @throws IOException unable to read/write to socket */ - public void authenticate(String mech, String ir) throws IOException { + public void authenticate(InputStream inputStream, OutputStream outputStream, String mech, String ir) throws IOException { if (mech.equals("LOGIN")) - authlogin(ir); + authlogin(inputStream, outputStream, ir); else if (mech.equals("PLAIN")) - authplain(ir); + authplain(inputStream, outputStream, ir); else - bad("AUTHENTICATE not supported"); + bad(outputStream, "AUTHENTICATE not supported"); } /** @@ -300,14 +294,14 @@ public class IMAPHandler extends ProtocolHandler { * * @throws IOException unable to read/write to socket */ - public void authlogin(String ir) throws IOException { + public void authlogin(InputStream inputStream, OutputStream outputStream, String ir) throws IOException { if (ir != null) - bad("AUTHENTICATE LOGIN does not support initial response"); - cont(base64encode("Username")); - String username = readLine(); - cont(base64encode("Password")); - String password = readLine(); - ok("[CAPABILITY " + capabilities + "]"); + bad(outputStream, "AUTHENTICATE LOGIN does not support initial response"); + cont(outputStream, base64encode("Username")); + String username = readLine(inputStream); + cont(outputStream, base64encode("Password")); + String password = readLine(inputStream); + ok(outputStream, "[CAPABILITY " + capabilities + "]"); } /** @@ -315,12 +309,12 @@ public class IMAPHandler extends ProtocolHandler { * * @throws IOException unable to read/write to socket */ - public void authplain(String ir) throws IOException { + public void authplain(InputStream inputStream, OutputStream outputStream, String ir) throws IOException { if (ir == null) { - cont(""); - String resp = readLine(); + cont(outputStream, ""); + String resp = readLine(inputStream); } - ok("[CAPABILITY " + capabilities + "]"); + ok(outputStream, "[CAPABILITY " + capabilities + "]"); } /** @@ -328,9 +322,9 @@ public class IMAPHandler extends ProtocolHandler { * * @throws IOException unable to read/write to socket */ - public void capability() throws IOException { - untagged("CAPABILITY " + capabilities); - ok(); + public void capability(OutputStream outputStream) throws IOException { + untagged(outputStream, "CAPABILITY " + capabilities); + ok(outputStream); } /** @@ -338,10 +332,10 @@ public class IMAPHandler extends ProtocolHandler { * * @throws IOException unable to read/write to socket */ - public void select(String line) throws IOException { - untagged(numberOfMessages + " EXISTS"); - untagged(numberOfRecentMessages + " RECENT"); - ok(); + public void select(OutputStream outputStream, String line) throws IOException { + untagged(outputStream, numberOfMessages + " EXISTS"); + untagged(outputStream, numberOfRecentMessages + " RECENT"); + ok(outputStream); } /** @@ -349,10 +343,10 @@ public class IMAPHandler extends ProtocolHandler { * * @throws IOException unable to read/write to socket */ - public void examine(String line) throws IOException { - untagged(numberOfMessages + " EXISTS"); - untagged(numberOfRecentMessages + " RECENT"); - ok(); + public void examine(OutputStream outputStream, String line) throws IOException { + untagged(outputStream, numberOfMessages + " EXISTS"); + untagged(outputStream, numberOfRecentMessages + " RECENT"); + ok(outputStream); } /** @@ -360,8 +354,8 @@ public class IMAPHandler extends ProtocolHandler { * * @throws IOException unable to read/write to socket */ - public void list(String line) throws IOException { - ok(); + public void list(OutputStream outputStream, String line) throws IOException { + ok(outputStream); } /** @@ -369,29 +363,27 @@ public class IMAPHandler extends ProtocolHandler { * * @throws IOException unable to read/write to socket */ - public void idle() throws IOException { - cont(); - idleWait(); - ok(); + public void idle(InputStream inputStream, OutputStream outputStream) throws IOException { + cont(outputStream); + idleWait(inputStream, outputStream); + ok(outputStream); } @Override - protected String readLine() throws IOException { - currentLine = super.readLine(); + protected String readLine(InputStream inputStream) throws IOException { + currentLine = super.readLine(inputStream); if (currentLine == null) { - LOGGER.severe("Current line is null!"); + logger.severe("Current line is null!"); exit(); } return currentLine; } - protected void idleWait() throws IOException { - String line = readLine(); - + protected void idleWait(InputStream inputStream, OutputStream outputStream) throws IOException { + String line = readLine(inputStream); if (line != null && !line.equalsIgnoreCase("DONE")) { - LOGGER.severe("Didn't get DONE response to IDLE"); + logger.severe("Didn't get DONE response to IDLE"); exit(); - return; } } @@ -400,8 +392,8 @@ public class IMAPHandler extends ProtocolHandler { * * @throws IOException unable to read/write to socket */ - public void fetch(String line) throws IOException { - ok(); // XXX + public void fetch(OutputStream outputStream, String line) throws IOException { + ok(outputStream); } /** @@ -409,8 +401,8 @@ public class IMAPHandler extends ProtocolHandler { * * @throws IOException unable to read/write to socket */ - public void store(String line) throws IOException { - ok(); // XXX + public void store(OutputStream outputStream, String line) throws IOException { + ok(outputStream); } /** @@ -418,9 +410,9 @@ public class IMAPHandler extends ProtocolHandler { * * @throws IOException unable to read/write to socket */ - public void search(String line) throws IOException { - untagged("SEARCH"); - ok(); // XXX + public void search(OutputStream outputStream, String line) throws IOException { + untagged(outputStream, "SEARCH"); + ok(outputStream); } /** @@ -428,8 +420,8 @@ public class IMAPHandler extends ProtocolHandler { * * @throws IOException unable to read/write to socket */ - public void uidfetch(String line) throws IOException { - ok(); // XXX + public void uidfetch(OutputStream outputStream, String line) throws IOException { + ok(outputStream); } /** @@ -437,8 +429,8 @@ public class IMAPHandler extends ProtocolHandler { * * @throws IOException unable to read/write to socket */ - public void uidstore(String line) throws IOException { - ok(); // XXX + public void uidstore(OutputStream outputStream, String line) throws IOException { + ok(outputStream); } /** @@ -446,13 +438,13 @@ public class IMAPHandler extends ProtocolHandler { * * @throws IOException unable to read/write to socket */ - public void append(String line) throws IOException { + public void append(InputStream inputStream, OutputStream outputStream, String line) throws IOException { int left = line.lastIndexOf('{'); int right = line.indexOf('}', left); int bytes = Integer.parseInt(line.substring(left + 1, right)); - cont("waiting for message"); - collectMessage(bytes); - ok(); // XXX + cont(outputStream, "waiting for message"); + collectMessage(inputStream, outputStream, bytes); + ok(outputStream); } /** @@ -460,9 +452,9 @@ public class IMAPHandler extends ProtocolHandler { * * @throws IOException unable to read/write to socket */ - public void id(String line) throws IOException { - untagged("ID NIL"); - ok(); + public void id(OutputStream outputStream, String line) throws IOException { + untagged(outputStream, "ID NIL"); + ok(outputStream); } /** @@ -470,8 +462,8 @@ public class IMAPHandler extends ProtocolHandler { * * @throws IOException unable to read/write to socket */ - public void enable(String line) throws IOException { - no("can't enable"); + public void enable(OutputStream outputStream, String line) throws IOException { + no(outputStream, "can't enable"); } /** @@ -479,8 +471,8 @@ public class IMAPHandler extends ProtocolHandler { * * @throws IOException unable to read/write to socket */ - public void create(String line) throws IOException { - no("can't create"); + public void create(OutputStream outputStream, String line) throws IOException { + no(outputStream, "can't create"); } /** @@ -488,8 +480,8 @@ public class IMAPHandler extends ProtocolHandler { * * @throws IOException unable to read/write to socket */ - public void delete(String line) throws IOException { - no("can't delete"); + public void delete(OutputStream outputStream, String line) throws IOException { + no(outputStream, "can't delete"); } /** @@ -497,8 +489,8 @@ public class IMAPHandler extends ProtocolHandler { * * @throws IOException unable to read/write to socket */ - public void status(String line) throws IOException { - no("can't get status"); + public void status(OutputStream outputStream, String line) throws IOException { + no(outputStream, "can't get status"); } /** @@ -506,23 +498,23 @@ public class IMAPHandler extends ProtocolHandler { * * @throws IOException unable to read/write to socket */ - public void namespace() throws IOException { - no("no namespaces"); + public void namespace(OutputStream outputStream) throws IOException { + no(outputStream, "no namespaces"); } /** * Collect "bytes" worth of data for the message being appended. */ - protected void collectMessage(int bytes) throws IOException { - readLiteral(bytes); // read the data and throw it away - super.readLine(); // data followed by a newline + protected void collectMessage(InputStream inputStream, OutputStream outputStream, int bytes) throws IOException { + readLiteral(inputStream, outputStream, bytes); // read the data and throw it away + super.readLine(inputStream); // data followed by a newline } /** * Read a literal of "bytes" bytes and return it as a UTF-8 string. */ - protected String readLiteral(int bytes) throws IOException { - println("+"); + protected String readLiteral(InputStream inputStream, OutputStream outputStream, int bytes) throws IOException { + println(outputStream, "+"); byte[] data = new byte[bytes]; int len = data.length; int off = 0; @@ -539,8 +531,8 @@ public class IMAPHandler extends ProtocolHandler { * * @throws IOException unable to read/write to socket */ - public void close() throws IOException { - ok(); + public void close(OutputStream outputStream) throws IOException { + ok(outputStream); } /** @@ -548,8 +540,8 @@ public class IMAPHandler extends ProtocolHandler { * * @throws IOException unable to read/write to socket */ - public void noop() throws IOException { - ok(); + public void noop(OutputStream outputStream) throws IOException { + ok(outputStream); } /** @@ -557,8 +549,8 @@ public class IMAPHandler extends ProtocolHandler { * * @throws IOException unable to read/write to socket */ - public void logout() throws IOException { - ok(); + public void logout(OutputStream outputStream) throws IOException { + ok(outputStream); exit(); } diff --git a/net-mail/src/test/java/org/xbib/net/mail/test/imap/IMAPIDTest.java b/net-mail/src/test/java/org/xbib/net/mail/test/imap/IMAPIDTest.java index 3dd5de4..0544cea 100644 --- a/net-mail/src/test/java/org/xbib/net/mail/test/imap/IMAPIDTest.java +++ b/net-mail/src/test/java/org/xbib/net/mail/test/imap/IMAPIDTest.java @@ -23,6 +23,7 @@ import org.xbib.net.mail.imap.IMAPStore; import org.xbib.net.mail.test.test.TestServer; import java.io.IOException; +import java.io.OutputStream; import java.util.Map; import java.util.Properties; import java.util.StringTokenizer; @@ -79,13 +80,13 @@ public final class IMAPIDTest { private static final class IMAPHandlerID extends IMAPHandler { @Override - public void id(String line) throws IOException { + public void id(OutputStream outputStream, String line) throws IOException { StringTokenizer st = new StringTokenizer(line); String tag = st.nextToken(); String cmd = st.nextToken(); String arg = st.nextToken(); - untagged("ID (\"test\" \"" + arg.equals("NIL") + "\")"); - ok(); + untagged(outputStream, "ID (\"test\" \"" + arg.equals("NIL") + "\")"); + ok(outputStream); } } } diff --git a/net-mail/src/test/java/org/xbib/net/mail/test/imap/IMAPIdleManagerTest.java b/net-mail/src/test/java/org/xbib/net/mail/test/imap/IMAPIdleManagerTest.java index b2f29ad..bcee616 100644 --- a/net-mail/src/test/java/org/xbib/net/mail/test/imap/IMAPIdleManagerTest.java +++ b/net-mail/src/test/java/org/xbib/net/mail/test/imap/IMAPIdleManagerTest.java @@ -26,6 +26,7 @@ import org.xbib.net.mail.imap.IMAPStore; import org.xbib.net.mail.imap.IdleManager; import org.xbib.net.mail.test.test.TestServer; import java.io.IOException; +import java.io.OutputStream; import java.util.Properties; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; @@ -347,9 +348,9 @@ public final class IMAPIdleManagerTest { */ private static abstract class IMAPHandlerIdle extends IMAPHandler { @Override - public void select(String line) throws IOException { + public void select(OutputStream outputStream, String line) throws IOException { numberOfMessages = 1; - super.select(line); + super.select(outputStream, line); } public abstract void waitForIdle() throws InterruptedException; diff --git a/net-mail/src/test/java/org/xbib/net/mail/test/imap/IMAPSaslHandler.java b/net-mail/src/test/java/org/xbib/net/mail/test/imap/IMAPSaslHandler.java index 9fdf3e1..c06bb17 100644 --- a/net-mail/src/test/java/org/xbib/net/mail/test/imap/IMAPSaslHandler.java +++ b/net-mail/src/test/java/org/xbib/net/mail/test/imap/IMAPSaslHandler.java @@ -57,11 +57,11 @@ public class IMAPSaslHandler extends IMAPHandler { CallbackHandler cbh = new CallbackHandler() { @Override public void handle(Callback[] callbacks) { - if (LOGGER.isLoggable(Level.FINE)) - LOGGER.fine("SASL callback length: " + callbacks.length); + if (logger.isLoggable(Level.FINE)) + logger.fine("SASL callback length: " + callbacks.length); for (int i = 0; i < callbacks.length; i++) { - if (LOGGER.isLoggable(Level.FINE)) - LOGGER.fine("SASL callback " + i + ": " + callbacks[i]); + if (logger.isLoggable(Level.FINE)) + logger.fine("SASL callback " + i + ": " + callbacks[i]); if (callbacks[i] instanceof NameCallback) { NameCallback ncb = (NameCallback) callbacks[i]; ncb.setName(u); @@ -70,8 +70,8 @@ public class IMAPSaslHandler extends IMAPHandler { pcb.setPassword(p.toCharArray()); } else if (callbacks[i] instanceof AuthorizeCallback) { AuthorizeCallback ac = (AuthorizeCallback) callbacks[i]; - if (LOGGER.isLoggable(Level.FINE)) - LOGGER.fine("SASL authorize: " + + if (logger.isLoggable(Level.FINE)) + logger.fine("SASL authorize: " + "authn: " + ac.getAuthenticationID() + ", " + "authz: " + ac.getAuthorizationID() + ", " + "authorized: " + ac.getAuthorizedID()); @@ -104,17 +104,17 @@ public class IMAPSaslHandler extends IMAPHandler { try { ss = Sasl.createSaslServer(mech, "imap", "localhost", null, cbh); } catch (SaslException sex) { - LOGGER.log(Level.FINE, "Failed to create SASL server", sex); + logger.log(Level.FINE, "Failed to create SASL server", sex); no("Failed to create SASL server"); return; } if (ss == null) { - LOGGER.fine("No SASL support"); + logger.fine("No SASL support"); no("No SASL support"); return; } - if (LOGGER.isLoggable(Level.FINE)) - LOGGER.fine("SASL server " + ss.getMechanismName()); + if (logger.isLoggable(Level.FINE)) + logger.fine("SASL server " + ss.getMechanismName()); byte[] response = new byte[0]; while (!ss.isComplete()) { @@ -124,8 +124,8 @@ public class IMAPSaslHandler extends IMAPHandler { break; } else { // send challenge - if (LOGGER.isLoggable(Level.FINE)) - LOGGER.fine("SASL challenge: " + + if (logger.isLoggable(Level.FINE)) + logger.fine("SASL challenge: " + ASCIIUtility.toString(chal, 0, chal.length)); byte[] ba = Base64.getEncoder().encode(chal); if (ba.length > 0) @@ -148,7 +148,7 @@ public class IMAPSaslHandler extends IMAPHandler { if (qop != null && (qop.equalsIgnoreCase("auth-int") || qop.equalsIgnoreCase("auth-conf"))) { // XXX - NOT SUPPORTED!!! - LOGGER.fine( + logger.fine( "SASL Mechanism requires integrity or confidentiality"); no("SASL Mechanism requires integrity or confidentiality"); return; diff --git a/net-mail/src/test/java/org/xbib/net/mail/test/pop3/POP3Handler.java b/net-mail/src/test/java/org/xbib/net/mail/test/pop3/POP3Handler.java index ae01828..615a7c9 100644 --- a/net-mail/src/test/java/org/xbib/net/mail/test/pop3/POP3Handler.java +++ b/net-mail/src/test/java/org/xbib/net/mail/test/pop3/POP3Handler.java @@ -118,7 +118,7 @@ public class POP3Handler extends ProtocolHandler { final String commandName = st.nextToken().toUpperCase(); final String arg = st.hasMoreTokens() ? st.nextToken() : null; if (commandName == null) { - LOGGER.severe("Command name is empty!"); + logger.severe("Command name is empty!"); this.exit(); return; } @@ -150,7 +150,7 @@ public class POP3Handler extends ProtocolHandler { } else if (commandName.equals("AUTH")) { this.auth(); } else { - LOGGER.log(Level.SEVERE, "ERROR command unknown: {0}", commandName); + logger.log(Level.SEVERE, "ERROR command unknown: {0}", commandName); this.println("-ERR unknown command"); } } diff --git a/net-mail/src/test/java/org/xbib/net/mail/test/smtp/SMTPHandler.java b/net-mail/src/test/java/org/xbib/net/mail/test/smtp/SMTPHandler.java index e241302..574610f 100644 --- a/net-mail/src/test/java/org/xbib/net/mail/test/smtp/SMTPHandler.java +++ b/net-mail/src/test/java/org/xbib/net/mail/test/smtp/SMTPHandler.java @@ -94,7 +94,7 @@ public class SMTPHandler extends ProtocolHandler { final StringTokenizer st = new StringTokenizer(currentLine, " "); final String commandName = st.nextToken().toUpperCase(); if (commandName == null) { - LOGGER.severe("Command name is empty!"); + logger.severe("Command name is empty!"); exit(); return; } @@ -120,7 +120,7 @@ public class SMTPHandler extends ProtocolHandler { } else if (commandName.equals("AUTH")) { auth(currentLine); } else { - LOGGER.log(Level.SEVERE, "ERROR command unknown: {0}", commandName); + logger.log(Level.SEVERE, "ERROR command unknown: {0}", commandName); println("-ERR unknown command"); } } diff --git a/net-mail/src/test/java/org/xbib/net/mail/test/smtp/SMTPLoginHandler.java b/net-mail/src/test/java/org/xbib/net/mail/test/smtp/SMTPLoginHandler.java index 3924e05..7d51a8d 100644 --- a/net-mail/src/test/java/org/xbib/net/mail/test/smtp/SMTPLoginHandler.java +++ b/net-mail/src/test/java/org/xbib/net/mail/test/smtp/SMTPLoginHandler.java @@ -58,8 +58,8 @@ public class SMTPLoginHandler extends SMTPHandler { if (ct.hasMoreTokens()) ir = ct.nextToken(); - if (LOGGER.isLoggable(Level.FINE)) - LOGGER.fine(line); + if (logger.isLoggable(Level.FINE)) + logger.fine(line); if (mech.equalsIgnoreCase("PLAIN")) plain(ir); else if (mech.equalsIgnoreCase("LOGIN")) @@ -82,8 +82,8 @@ public class SMTPLoginHandler extends SMTPHandler { byte[] response = resp.getBytes(StandardCharsets.US_ASCII); response = Base64.getDecoder().decode(response); String u = new String(response, StandardCharsets.UTF_8); - if (LOGGER.isLoggable(Level.FINE)) - LOGGER.fine("USER: " + u); + if (logger.isLoggable(Level.FINE)) + logger.fine("USER: " + u); println("334"); // read password @@ -95,8 +95,8 @@ public class SMTPLoginHandler extends SMTPHandler { response = resp.getBytes(StandardCharsets.US_ASCII); response = Base64.getDecoder().decode(response); String p = new String(response, StandardCharsets.UTF_8); - if (LOGGER.isLoggable(Level.FINE)) - LOGGER.fine("PASSWORD: " + p); + if (logger.isLoggable(Level.FINE)) + logger.fine("PASSWORD: " + p); //System.out.printf("USER: %s, PASSWORD: %s%n", u, p); if (!u.equals(username) || !p.equals(password)) { diff --git a/net-mail/src/test/java/org/xbib/net/mail/test/smtp/SMTPSaslHandler.java b/net-mail/src/test/java/org/xbib/net/mail/test/smtp/SMTPSaslHandler.java index 2cfe929..b96d45a 100644 --- a/net-mail/src/test/java/org/xbib/net/mail/test/smtp/SMTPSaslHandler.java +++ b/net-mail/src/test/java/org/xbib/net/mail/test/smtp/SMTPSaslHandler.java @@ -72,11 +72,11 @@ public class SMTPSaslHandler extends SMTPHandler { CallbackHandler cbh = new CallbackHandler() { @Override public void handle(Callback[] callbacks) { - if (LOGGER.isLoggable(Level.FINE)) - LOGGER.fine("SASL callback length: " + callbacks.length); + if (logger.isLoggable(Level.FINE)) + logger.fine("SASL callback length: " + callbacks.length); for (int i = 0; i < callbacks.length; i++) { - if (LOGGER.isLoggable(Level.FINE)) - LOGGER.fine("SASL callback " + i + ": " + callbacks[i]); + if (logger.isLoggable(Level.FINE)) + logger.fine("SASL callback " + i + ": " + callbacks[i]); if (callbacks[i] instanceof NameCallback) { NameCallback ncb = (NameCallback) callbacks[i]; ncb.setName(u); @@ -85,8 +85,8 @@ public class SMTPSaslHandler extends SMTPHandler { pcb.setPassword(p.toCharArray()); } else if (callbacks[i] instanceof AuthorizeCallback) { AuthorizeCallback ac = (AuthorizeCallback) callbacks[i]; - if (LOGGER.isLoggable(Level.FINE)) - LOGGER.fine("SASL authorize: " + + if (logger.isLoggable(Level.FINE)) + logger.fine("SASL authorize: " + "authn: " + ac.getAuthenticationID() + ", " + "authz: " + ac.getAuthorizationID() + ", " + "authorized: " + ac.getAuthorizedID()); @@ -119,25 +119,25 @@ public class SMTPSaslHandler extends SMTPHandler { try { ss = Sasl.createSaslServer(mech, "smtp", "localhost", null, cbh); } catch (SaslException sex) { - LOGGER.log(Level.FINE, "Failed to create SASL server", sex); + logger.log(Level.FINE, "Failed to create SASL server", sex); println("501 Failed to create SASL server"); return; } if (ss == null) { - LOGGER.fine("No SASL support"); + logger.fine("No SASL support"); println("501 No SASL support"); return; } - if (LOGGER.isLoggable(Level.FINE)) - LOGGER.fine("SASL server " + ss.getMechanismName()); + if (logger.isLoggable(Level.FINE)) + logger.fine("SASL server " + ss.getMechanismName()); byte[] response = ir.getBytes(); while (!ss.isComplete()) { try { byte[] chal = ss.evaluateResponse(response); // send challenge - if (LOGGER.isLoggable(Level.FINE)) - LOGGER.fine("SASL challenge: " + + if (logger.isLoggable(Level.FINE)) + logger.fine("SASL challenge: " + ASCIIUtility.toString(chal, 0, chal.length)); byte[] ba = Base64.getEncoder().encode(chal); if (ba.length > 0) @@ -164,7 +164,7 @@ public class SMTPSaslHandler extends SMTPHandler { if (qop != null && (qop.equalsIgnoreCase("auth-int") || qop.equalsIgnoreCase("auth-conf"))) { // XXX - NOT SUPPORTED!!! - LOGGER.fine( + logger.fine( "SASL Mechanism requires integrity or confidentiality"); println("501 " + "SASL Mechanism requires integrity or confidentiality"); diff --git a/net-mail/src/test/java/org/xbib/net/mail/test/test/ProtocolHandler.java b/net-mail/src/test/java/org/xbib/net/mail/test/test/ProtocolHandler.java index 2b48307..b4e50a5 100644 --- a/net-mail/src/test/java/org/xbib/net/mail/test/test/ProtocolHandler.java +++ b/net-mail/src/test/java/org/xbib/net/mail/test/test/ProtocolHandler.java @@ -16,12 +16,9 @@ package org.xbib.net.mail.test.test; -import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.PrintWriter; import java.io.PushbackInputStream; import java.nio.charset.StandardCharsets; import java.util.logging.Level; @@ -35,64 +32,82 @@ import java.util.logging.Logger; * @author sbo * @author Bill Shannon */ -public abstract class ProtocolHandler implements Runnable { +public abstract class ProtocolHandler { /** * Logger for this class. */ - protected final Logger LOGGER = Logger.getLogger(this.getClass().getName()); + private static final Logger logger = Logger.getLogger(ProtocolHandler.class.getName()); /** * Quit? */ protected boolean quit; - /** - * Writer to socket. - */ - protected PrintWriter writer; - - /** - * Input from socket. - */ - protected InputStream inputStream; - - public ProtocolHandler(InputStream inputStream, OutputStream outputStream) { - this.inputStream = new BufferedInputStream(inputStream); - this.writer = new PrintWriter(new OutputStreamWriter(outputStream, StandardCharsets.UTF_8)); + public void handle(InputStream inputStream, OutputStream outputStream) { + try { + sendGreetings(outputStream); + while (!quit) { + handleCommand(inputStream, outputStream); + } + if (quit) { + try { + if (inputStream != null) + inputStream.close(); + if (outputStream != null) { + outputStream.close(); + } + } catch (final IOException e) { + logger.log(Level.SEVERE, "Error", e); + } + } + } catch (IOException sex) { + // ignore it, often get "connection reset" when client closes + } catch (Exception e) { + logger.log(Level.SEVERE, "Error", e); + } finally { + try { + if (inputStream != null) + inputStream.close(); + if (outputStream != null) { + outputStream.close(); + } + } catch (final IOException ioe) { + logger.log(Level.SEVERE, "Error", ioe); + } + } } /** * Optionally send a greeting when first connected. */ - public void sendGreetings() throws IOException { + public void sendGreetings(OutputStream outputStream) throws IOException { } /** * Read and process a single command. */ - public abstract void handleCommand() throws IOException; + public abstract void handleCommand(InputStream inputStream, OutputStream outputStream) throws IOException; /** * Read a single line terminated by newline or CRLF. * Convert the UTF-8 bytes in the line (minus the line terminator) * to a String. */ - protected String readLine() throws IOException { + protected String readLine(InputStream inputStream) throws IOException { byte[] buf = new byte[128]; - int room = buf.length; int offset = 0; int c; - while ((c = inputStream.read()) != -1) { if (c == '\n') { break; } else if (c == '\r') { int c2 = inputStream.read(); if ((c2 != '\n') && (c2 != -1)) { - if (!(inputStream instanceof PushbackInputStream)) - this.inputStream = new PushbackInputStream(inputStream); + if (!(inputStream instanceof PushbackInputStream)) { + inputStream = new PushbackInputStream(inputStream); + } ((PushbackInputStream) inputStream).unread(c2); } break; @@ -106,51 +121,13 @@ public abstract class ProtocolHandler implements Runnable { buf[offset++] = (byte) c; } } - if ((c == -1) && (offset == 0)) + if ((c == -1) && (offset == 0)) { return null; + } return new String(buf, 0, offset, StandardCharsets.UTF_8); } - /** - * {@inheritDoc} - */ - @Override - public final void run() { - try { - sendGreetings(); - while (!quit) { - handleCommand(); - } - } catch (IOException sex) { - // ignore it, often get "connection reset" when client closes - } catch (Exception e) { - LOGGER.log(Level.SEVERE, "Error", e); - } finally { - try { - if (inputStream != null) - inputStream.close(); - if (writer != null) { - writer.close(); - } - } catch (final IOException ioe) { - LOGGER.log(Level.SEVERE, "Error", ioe); - } - } - } - - /** - * Quit. - */ public void exit() { quit = true; - try { - if (inputStream != null) - inputStream.close(); - if (writer != null) { - writer.close(); - } - } catch (final IOException e) { - LOGGER.log(Level.SEVERE, "Error", e); - } } } diff --git a/net-mail/src/test/java/org/xbib/net/mail/test/test/TestServer.java b/net-mail/src/test/java/org/xbib/net/mail/test/test/TestServer.java index 32430ea..fc3ae47 100644 --- a/net-mail/src/test/java/org/xbib/net/mail/test/test/TestServer.java +++ b/net-mail/src/test/java/org/xbib/net/mail/test/test/TestServer.java @@ -16,6 +16,9 @@ package org.xbib.net.mail.test.test; +import java.io.BufferedInputStream; +import java.io.InputStream; +import java.io.OutputStream; import java.security.KeyManagementException; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; @@ -32,8 +35,11 @@ import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; import java.security.KeyStore; -import java.util.ArrayList; -import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.logging.Level; +import java.util.logging.Logger; /** * A simple server for testing. @@ -46,13 +52,17 @@ import java.util.List; * @author sbo * @author Bill Shannon */ -public final class TestServer extends Thread { +public final class TestServer { + + private static final Logger logger = Logger.getLogger(TestServer.class.getName()); /** * Server socket. */ private ServerSocket serverSocket; + private final ExecutorService executorService = Executors.newCachedThreadPool(); + /** * Keep on? */ @@ -63,7 +73,6 @@ public final class TestServer extends Thread { */ private final ProtocolHandler handler; - private List clients = new ArrayList(); /** * Test server. @@ -83,7 +92,6 @@ public final class TestServer extends Thread { public TestServer(final ProtocolHandler handler, final boolean isSSL) throws IOException { this.handler = handler; - /* * Allowing the JDK to pick a port number sometimes results in it * picking a number that's already in use by another process, but @@ -96,10 +104,6 @@ public final class TestServer extends Thread { * already in use. */ for (int port = 49152; port < 50000 /*65535*/; port++) { - /* - if (isListening(port)) - continue; - */ try { serverSocket = createServerSocket(port, isSSL); return; @@ -170,12 +174,7 @@ public final class TestServer extends Thread { } } - /** - * {@inheritDoc} - */ - @Override public void start() { - super.start(); // don't return until server is really listening // XXX - this might not be necessary for (int tries = 0; tries < 10; tries++) { @@ -193,25 +192,23 @@ public final class TestServer extends Thread { /** * {@inheritDoc} */ - @Override public void run() { try { keepOn = true; - while (keepOn) { try { final Socket clientSocket = serverSocket.accept(); - final ProtocolHandler pHandler = handler; - pHandler.setClientSocket(clientSocket); - Thread t = new Thread(pHandler); - synchronized (clients) { - clients.add(t); - } - t.start(); - } catch (final IOException e) { - //e.printStackTrace(); - } catch (NullPointerException nex) { - // serverSocket can be set to null before we could check + executorService.submit(new Callable() { + final InputStream inputStream = new BufferedInputStream(clientSocket.getInputStream()); + final OutputStream outputStream = clientSocket.getOutputStream(); + @Override + public Object call() { + handler.handle(inputStream, outputStream); + return null; + } + }); + } catch (Exception e) { + logger.log(Level.SEVERE, e.getMessage(), e); } } } finally { @@ -219,20 +216,14 @@ public final class TestServer extends Thread { } } - /** - * Return number of clients ever created. - */ - public int clientCount() { + /*public int clientCount() { synchronized (clients) { // isListening creates a client that we don't count return clients.size() - 1; } - } + }*/ - /** - * Wait for at least n clients to terminate. - */ - public void waitForClients(int n) { + /*public void waitForClients(int n) { if (n > clientCount()) throw new RuntimeException("not that many clients"); for (; ; ) { @@ -250,7 +241,7 @@ public final class TestServer extends Thread { } catch (InterruptedException ex) { } } - } + }*/ private boolean isListening(int port) { try { @@ -265,10 +256,4 @@ public final class TestServer extends Thread { return false; } - class WrappedProtocolHandler { - Socket clientSocket; - ProtocolHandler handler; - - - } }