add AUTH & EMPTY to SmtpCommand (#9999)

Motivation:
AUTH command is used to login to a SMTP server.
EMPTY command is for request with only parameter.

Modifications:
Add AUTH & EMPTY to SmtpCommand & SmtpRequests
Update SmtpRequestEncoder#writeParameters, handle SP according to
command
Add unit test

Result:
fix #9995
This commit is contained in:
Ruwei 2020-02-07 21:29:46 +08:00 committed by Norman Maurer
parent 98cf4cf565
commit 6cd9617311
4 changed files with 39 additions and 3 deletions

View File

@ -32,6 +32,7 @@ import java.util.Map;
public final class SmtpCommand { public final class SmtpCommand {
public static final SmtpCommand EHLO = new SmtpCommand(AsciiString.cached("EHLO")); public static final SmtpCommand EHLO = new SmtpCommand(AsciiString.cached("EHLO"));
public static final SmtpCommand HELO = new SmtpCommand(AsciiString.cached("HELO")); public static final SmtpCommand HELO = new SmtpCommand(AsciiString.cached("HELO"));
public static final SmtpCommand AUTH = new SmtpCommand(AsciiString.cached("AUTH"));
public static final SmtpCommand MAIL = new SmtpCommand(AsciiString.cached("MAIL")); public static final SmtpCommand MAIL = new SmtpCommand(AsciiString.cached("MAIL"));
public static final SmtpCommand RCPT = new SmtpCommand(AsciiString.cached("RCPT")); public static final SmtpCommand RCPT = new SmtpCommand(AsciiString.cached("RCPT"));
public static final SmtpCommand DATA = new SmtpCommand(AsciiString.cached("DATA")); public static final SmtpCommand DATA = new SmtpCommand(AsciiString.cached("DATA"));
@ -41,11 +42,13 @@ public final class SmtpCommand {
public static final SmtpCommand VRFY = new SmtpCommand(AsciiString.cached("VRFY")); public static final SmtpCommand VRFY = new SmtpCommand(AsciiString.cached("VRFY"));
public static final SmtpCommand HELP = new SmtpCommand(AsciiString.cached("HELP")); public static final SmtpCommand HELP = new SmtpCommand(AsciiString.cached("HELP"));
public static final SmtpCommand QUIT = new SmtpCommand(AsciiString.cached("QUIT")); public static final SmtpCommand QUIT = new SmtpCommand(AsciiString.cached("QUIT"));
public static final SmtpCommand EMPTY = new SmtpCommand(AsciiString.cached(""));
private static final Map<String, SmtpCommand> COMMANDS = new HashMap<>(); private static final Map<String, SmtpCommand> COMMANDS = new HashMap<>();
static { static {
COMMANDS.put(EHLO.name().toString(), EHLO); COMMANDS.put(EHLO.name().toString(), EHLO);
COMMANDS.put(HELO.name().toString(), HELO); COMMANDS.put(HELO.name().toString(), HELO);
COMMANDS.put(AUTH.name().toString(), AUTH);
COMMANDS.put(MAIL.name().toString(), MAIL); COMMANDS.put(MAIL.name().toString(), MAIL);
COMMANDS.put(RCPT.name().toString(), RCPT); COMMANDS.put(RCPT.name().toString(), RCPT);
COMMANDS.put(DATA.name().toString(), DATA); COMMANDS.put(DATA.name().toString(), DATA);
@ -55,6 +58,7 @@ public final class SmtpCommand {
COMMANDS.put(VRFY.name().toString(), VRFY); COMMANDS.put(VRFY.name().toString(), VRFY);
COMMANDS.put(HELP.name().toString(), HELP); COMMANDS.put(HELP.name().toString(), HELP);
COMMANDS.put(QUIT.name().toString(), QUIT); COMMANDS.put(QUIT.name().toString(), QUIT);
COMMANDS.put(EMPTY.name().toString(), EMPTY);
} }
/** /**

View File

@ -58,7 +58,8 @@ public final class SmtpRequestEncoder extends MessageToMessageEncoder<Object> {
final ByteBuf buffer = ctx.alloc().buffer(); final ByteBuf buffer = ctx.alloc().buffer();
try { try {
req.command().encode(buffer); req.command().encode(buffer);
writeParameters(req.parameters(), buffer); boolean notEmpty = req.command() != SmtpCommand.EMPTY;
writeParameters(req.parameters(), buffer, notEmpty);
ByteBufUtil.writeShortBE(buffer, CRLF_SHORT); ByteBufUtil.writeShortBE(buffer, CRLF_SHORT);
out.add(buffer); out.add(buffer);
release = false; release = false;
@ -85,11 +86,13 @@ public final class SmtpRequestEncoder extends MessageToMessageEncoder<Object> {
} }
} }
private static void writeParameters(List<CharSequence> parameters, ByteBuf out) { private static void writeParameters(List<CharSequence> parameters, ByteBuf out, boolean commandNotEmpty) {
if (parameters.isEmpty()) { if (parameters.isEmpty()) {
return; return;
} }
out.writeByte(SP); if (commandNotEmpty) {
out.writeByte(SP);
}
if (parameters instanceof RandomAccess) { if (parameters instanceof RandomAccess) {
final int sizeMinusOne = parameters.size() - 1; final int sizeMinusOne = parameters.size() - 1;
for (int i = 0; i < sizeMinusOne; i++) { for (int i = 0; i < sizeMinusOne; i++) {

View File

@ -51,6 +51,20 @@ public final class SmtpRequests {
return new DefaultSmtpRequest(SmtpCommand.EHLO, hostname); return new DefaultSmtpRequest(SmtpCommand.EHLO, hostname);
} }
/**
* Creates a {@code EMPTY} request.
*/
public static SmtpRequest empty(CharSequence... parameter) {
return new DefaultSmtpRequest(SmtpCommand.EMPTY, parameter);
}
/**
* Creates a {@code AUTH} request.
*/
public static SmtpRequest auth(CharSequence... parameter) {
return new DefaultSmtpRequest(SmtpCommand.AUTH, parameter);
}
/** /**
* Creates a {@code NOOP} request. * Creates a {@code NOOP} request.
*/ */

View File

@ -38,6 +38,21 @@ public class SmtpRequestEncoderTest {
testEncode(SmtpRequests.helo("localhost"), "HELO localhost\r\n"); testEncode(SmtpRequests.helo("localhost"), "HELO localhost\r\n");
} }
@Test
public void testEncodeAuth() {
testEncode(SmtpRequests.auth("LOGIN"), "AUTH LOGIN\r\n");
}
@Test
public void testEncodeAuthWithParameter() {
testEncode(SmtpRequests.auth("PLAIN", "dGVzdAB0ZXN0ADEyMzQ="), "AUTH PLAIN dGVzdAB0ZXN0ADEyMzQ=\r\n");
}
@Test
public void testEncodeEmpty() {
testEncode(SmtpRequests.empty("dGVzdAB0ZXN0ADEyMzQ="), "dGVzdAB0ZXN0ADEyMzQ=\r\n");
}
@Test @Test
public void testEncodeMail() { public void testEncodeMail() {
testEncode(SmtpRequests.mail("me@netty.io"), "MAIL FROM:<me@netty.io>\r\n"); testEncode(SmtpRequests.mail("me@netty.io"), "MAIL FROM:<me@netty.io>\r\n");