Not sending message if any recipients recieve negative reply.

This commit is contained in:
yesalam 2017-04-10 15:43:19 +05:30 committed by Vincent Breitmoser
parent f322cbe971
commit 346bdc8cd2
4 changed files with 77 additions and 16 deletions

View file

@ -651,22 +651,30 @@ public class SmtpTransport extends Transport {
}
private void readPipelinedResponse(Queue<String> pipelinedCommands) throws IOException, MessagingException {
int noOfPipelinedResponse = pipelinedCommands.size();
String responseLine = null;
List<String> results = new ArrayList<>();
while (noOfPipelinedResponse > 0) {
noOfPipelinedResponse--;
NegativeSmtpReplyException negativeRecipient = null;
for (String command : pipelinedCommands) {
results.clear();
responseLine = readCommandResponseLine(results);
try {
responseLineToCommandResponse(responseLine, results);
} catch (MessagingException exception) {
if (noOfPipelinedResponse == 0) {
if (command.equals("DATA")) {
throw exception;
}
Timber.d("SMTP <<< " + exception.getMessage());
//continue reading response till DATA response .
if (command.startsWith("RCPT")) {
negativeRecipient = (NegativeSmtpReplyException) exception;
}
}
}
if (negativeRecipient != null) {
try {
executeCommand(".");
} catch (NegativeSmtpReplyException e) {
throw negativeRecipient;
}
}

View file

@ -61,7 +61,15 @@ class TestMessage extends MimeMessage {
bufferedSink.emit();
}
private static Address[] toAddressArray(String email) {
return email == null ? new Address[0] : new Address[] { new Address(email) };
private static Address[] toAddressArray(String[] emails) {
return emails == null ? new Address[0] : stringArrayToAddressArray(emails);
}
private static Address[] stringArrayToAddressArray(String[] emails) {
Address addresses[] = new Address[emails.length];
for (int i = 0; i < emails.length; i++) {
addresses[i] = new Address(emails[i]);
}
return addresses;
}
}

View file

@ -5,18 +5,18 @@ import com.fsck.k9.mail.Message;
public class TestMessageBuilder {
String from;
String to;
String[] from;
String[] to;
boolean hasAttachments;
long messageSize;
public TestMessageBuilder from(String email) {
public TestMessageBuilder from(String... email) {
from = email;
return this;
}
public TestMessageBuilder to(String email) {
public TestMessageBuilder to(String... email) {
to = email;
return this;
}

View file

@ -745,17 +745,23 @@ public class SmtpTransportTest {
server.expect("RCPT TO:<user2@localhost>");
server.expect("DATA");
server.output("250 OK");
server.output("421 4.7.0 Temporary system problem");
server.output("550 remote mail to <user2@localhost> not allowed");
server.output("354 End data with <CR><LF>.<CR><LF>");
server.expect("[message data]");
server.expect(".");
server.output("250 OK: queued as 12345");
server.output("554 no valid recipients");
server.expect("QUIT");
server.output("221 BYE");
server.closeConnection();
SmtpTransport transport = startServerAndCreateSmtpTransport(server);
transport.sendMessage(message);
try {
transport.sendMessage(message);
fail("Expected exception");
} catch (NegativeSmtpReplyException e) {
assertEquals(550, e.getReplyCode());
assertEquals("remote mail to <user2@localhost> not allowed", e.getReplyText());
}
server.verifyConnectionClosed();
server.verifyInteractionCompleted();
@ -788,6 +794,38 @@ public class SmtpTransportTest {
server.verifyInteractionCompleted();
}
@Test
public void sendMessagePipelining_with250and550ReplyforRecipients_shouldThrow() throws Exception {
Message message = getMessageWithTwoRecipients();
MockSmtpServer server = createServerAndSetupForPlainAuthentication("PIPELINING");
server.expect("MAIL FROM:<user@localhost>");
server.expect("RCPT TO:<user2@localhost>");
server.expect("RCPT TO:<user3@localhost>");
server.expect("DATA");
server.output("250 OK");
server.output("250 OK");
server.output("550 remote mail to <user3@localhost> not allowed");
server.output("354 End data with <CR><LF>.<CR><LF>");
server.expect(".");
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(550, e.getReplyCode());
assertEquals("remote mail to <user3@localhost> not allowed", e.getReplyText());
}
server.verifyConnectionClosed();
server.verifyInteractionCompleted();
}
private SmtpTransport startServerAndCreateSmtpTransport(MockSmtpServer server) throws IOException,
MessagingException {
return startServerAndCreateSmtpTransport(server, AuthType.PLAIN, ConnectionSecurity.NONE);
@ -840,6 +878,13 @@ public class SmtpTransportTest {
return getDefaultMessageBuilder().build();
}
private Message getMessageWithTwoRecipients() {
return new TestMessageBuilder()
.from("user@localhost")
.to("user2@localhost", "user3@localhost")
.build();
}
private MockSmtpServer createServerAndSetupForPlainAuthentication(String... extensions) {
MockSmtpServer server = new MockSmtpServer();