diff --git a/k9mail-library/src/main/java/com/fsck/k9/mail/transport/smtp/SmtpTransport.java b/k9mail-library/src/main/java/com/fsck/k9/mail/transport/smtp/SmtpTransport.java index 9bdf4d8ff..b45610a4c 100644 --- a/k9mail-library/src/main/java/com/fsck/k9/mail/transport/smtp/SmtpTransport.java +++ b/k9mail-library/src/main/java/com/fsck/k9/mail/transport/smtp/SmtpTransport.java @@ -81,7 +81,6 @@ public class SmtpTransport extends Transport { private int largestAcceptableMessage; private boolean retryXoauthWithNewToken; private boolean isPipeliningSupported; - private Queue pipelinedCommand; public SmtpTransport(StoreConfig storeConfig, TrustedSocketFactory trustedSocketFactory, @@ -440,23 +439,21 @@ public class SmtpTransport extends Transport { try { String fromAddress = from[0].getAddress(); if (isPipeliningSupported) { - pipelinedCommand = new LinkedList<>(); + Queue pipelinedCommands = new LinkedList<>(); if (is8bitEncodingAllowed) { - executeCommandPipelined("MAIL FROM:<%s> BODY=8BITMIME", fromAddress); + pipelinedCommands.add(String.format("MAIL FROM:<%s> BODY=8BITMIME", fromAddress)); } else { - executeCommandPipelined("MAIL FROM:<%s>", fromAddress); + pipelinedCommands.add(String.format("MAIL FROM:<%s>", fromAddress)); } for (String address : addresses) { - executeCommandPipelined("RCPT TO:<%s>", address); + pipelinedCommands.add(String.format("RCPT TO:<%s>", address)); } - executeCommandPipelined("DATA"); - CommandResponse commandResponse = readPipelinedResponse(); - if (commandResponse.replyCode != 354) { - String replyText = TextUtils.join(" ", commandResponse.results); - throw new NegativeSmtpReplyException(commandResponse.replyCode, replyText); - } + pipelinedCommands.add("DATA"); + executePipelinedCommands(pipelinedCommands); + readPipelinedResponse(pipelinedCommands); + } else { if (is8bitEncodingAllowed) { executeCommand("MAIL FROM:<%s> BODY=8BITMIME", fromAddress); @@ -647,20 +644,18 @@ public class SmtpTransport extends Transport { return line; } - private void executeCommandPipelined(String format, Object... args) throws IOException { - if (format != null) { - String command = String.format(Locale.ROOT, format, args); - pipelinedCommand.add(command); + private void executePipelinedCommands(Queue pipelinedCommands) throws IOException { + for (String command : pipelinedCommands) { writeLine(command, false); } } - private CommandResponse readPipelinedResponse() throws IOException, MessagingException { + private void readPipelinedResponse(Queue pipelinedCommands) throws IOException, MessagingException { + int noOfPipelinedResponse = pipelinedCommands.size(); String responseLine = null; - List results = null; - int noOfPipelinedResponse = pipelinedCommand.size(); + List results = new ArrayList<>(); while (noOfPipelinedResponse > 0) { - results = new ArrayList<>(); + results.clear(); responseLine = readCommandResponseLine(results); try { responseLineToCommandResponse(responseLine, results); @@ -675,7 +670,13 @@ public class SmtpTransport extends Transport { } noOfPipelinedResponse-- ; } - return responseLineToCommandResponse(responseLine, results); + + try { + responseLineToCommandResponse(responseLine, results); + } catch (NegativeSmtpReplyException exception) { + throw exception; + } + } private CommandResponse responseLineToCommandResponse(String line, List results) throws MessagingException { diff --git a/k9mail-library/src/test/java/com/fsck/k9/mail/transport/smtp/SmtpTransportTest.java b/k9mail-library/src/test/java/com/fsck/k9/mail/transport/smtp/SmtpTransportTest.java index 4940b2041..196067dea 100644 --- a/k9mail-library/src/test/java/com/fsck/k9/mail/transport/smtp/SmtpTransportTest.java +++ b/k9mail-library/src/test/java/com/fsck/k9/mail/transport/smtp/SmtpTransportTest.java @@ -761,6 +761,33 @@ public class SmtpTransportTest { server.verifyInteractionCompleted(); } + @Test + public void sendMessagePipelining_without354ReplyforData_shouldThrow() throws Exception { + Message message = getDefaultMessage(); + MockSmtpServer server = createServerAndSetupForPlainAuthentication("PIPELINING"); + server.expect("MAIL FROM:"); + server.expect("RCPT TO:"); + server.expect("DATA"); + server.output("250 OK"); + server.output("550 remote mail to not allowed"); + server.output("554 no valid recipients given"); + server.expect("QUIT"); + server.output("221 BYE"); + server.closeConnection(); + SmtpTransport transport = startServerAndCreateSmtpTransport(server); + + try { + transport.sendMessage(message); + fail("Expected exception"); + } catch (NegativeSmtpReplyException e) { + assertEquals(554, e.getReplyCode()); + assertEquals("no valid recipients given", e.getReplyText()); + } + + server.verifyConnectionClosed(); + server.verifyInteractionCompleted(); + } + private SmtpTransport startServerAndCreateSmtpTransport(MockSmtpServer server) throws IOException, MessagingException { return startServerAndCreateSmtpTransport(server, AuthType.PLAIN, ConnectionSecurity.NONE);