package io.vertx.ext.mail.impl;
import io.vertx.core.Handler;
import io.vertx.core.impl.NoStackTraceThrowable;
import io.vertx.core.impl.logging.Logger;
import io.vertx.core.impl.logging.LoggerFactory;
import io.vertx.ext.mail.MailConfig;
import io.vertx.ext.mail.StartTLSOptions;
class SMTPInitialDialogue {
private static final Logger log = LoggerFactory.getLogger(SMTPInitialDialogue.class);
private final SMTPConnection connection;
private final Handler<Throwable> errorHandler;
private final Handler<Void> finishedHandler;
private final MailConfig config;
private final String hostname;
public SMTPInitialDialogue(SMTPConnection connection, MailConfig config, String hostname, Handler<Void> finishedHandler,
Handler<Throwable> errorHandler) {
this.connection = connection;
this.config = config;
this.hostname = hostname;
this.finishedHandler = finishedHandler;
this.errorHandler = errorHandler;
}
public void start(final String message) {
log.debug("server greeting: " + message);
if (StatusCode.isStatusOk(message)) {
if (!config.isDisableEsmtp()) {
ehloCmd();
} else {
heloCmd();
}
} else {
handleError("got error response " + message);
}
}
private void ehloCmd() {
connection
.write(
"EHLO " + hostname,
message -> {
log.debug("EHLO result: " + message);
if (StatusCode.isStatusOk(message)) {
connection.parseCapabilities(message);
if (connection.getCapa().isStartTLS()
&& !connection.isSsl()
&& (config.getStarttls() == StartTLSOptions.REQUIRED || config.getStarttls() == StartTLSOptions.OPTIONAL)) {
startTLSCmd();
} else {
finished();
}
} else {
heloCmd();
}
});
}
private void heloCmd() {
connection.write("HELO " + hostname, message -> {
log.debug("HELO result: " + message);
if (StatusCode.isStatusOk(message)) {
finished();
} else {
handleError("HELO failed with " + message);
}
});
}
private void handleError(String message) {
log.debug("handleError:" + message);
errorHandler.handle(new NoStackTraceThrowable(message));
}
private void startTLSCmd() {
connection.write("STARTTLS", message -> {
log.debug("STARTTLS result: " + message);
connection.upgradeToSsl(ar -> {
if (ar.succeeded()) {
log.debug("tls started");
ehloCmd();
} else {
}
});
});
}
private void finished() {
if (connection.isSsl() || config.getStarttls() != StartTLSOptions.REQUIRED) {
finishedHandler.handle(null);
} else {
log.warn("STARTTLS required but not supported by server");
handleError("STARTTLS required but not supported by server");
}
}
}