I'm trying to develop a class that sends email through the SMTP protocol but without using libraries that facilitate sending mail such as MimeMessage or MailUtility. This is what I've done so far:
public class MailSender {
protected String localMachine;
protected String localSMTPServer;
private String textMail;
private String mailFrom;
public MailSender(String localSMTPServer, String mailFrom) {
try {
this.textMail = "null";
this.localSMTPServer = localSMTPServer;
this.mailFrom = mailFrom;
InetAddress localIP = InetAddress.getLocalHost();
this.localMachine = localIP.getHostAddress();
} catch (UnknownHostException ex) {
Logger.getLogger(MailSender.class.getName()).log(Level.SEVERE, null, ex);
}
}
//getter and setter
public void smtp(String command) {
try {
System.out.println(sIn.readLine());
os.write((command "\n").getBytes());
System.out.println("end");
} catch (IOException ex) {
System.out.println(ex);
Logger.getLogger(MailSender.class.getName()).log(Level.SEVERE, null, ex);
}
}
BufferedReader sIn;
OutputStream os;
public Boolean trySend(String destUser, String subject, String message) {
Socket socket;
try {
socket = new Socket(localSMTPServer, 587);
OutputStreamWriter sOutW = new OutputStreamWriter(socket.getOutputStream(), "ASCII");
PrintWriter sOut = new PrintWriter(sOutW, true);
InputStreamReader sInR = new InputStreamReader(socket.getInputStream(), "ASCII");
sIn = new BufferedReader(sInR);
os = socket.getOutputStream();
this.nextSMTPCode(sIn, 220);
sOut.println("EHLO");
this.nextSMTPCode(sIn, 250);
sOut.println("AUTH LOGIN");
this.nextSMTPCode(sIn, 250);
sOut.println("xxxxxxxxxxxxxxx=="); //username
sOut.println("xxxxxxxxxxxxxx="); //password
this.nextSMTPCode(sIn, 250);
sOut.println("MAIL FROM: <" this.mailFrom ">");
this.nextSMTPCode(sIn, 250);
sOut.println("RCPT TO: <" destUser ">");
this.nextSMTPCode(sIn, 250);
sOut.println("DATA");
this.nextSMTPCode(sIn, 250);
sOut.println("From: " this.mailFrom);
sOut.println("To: " destUser);
sOut.println("Subject: " subject);
sOut.println(message);
sOut.println(".");
this.nextSMTPCode(sIn, 250);
sOut.println("QUIT");
this.nextSMTPCode(sIn, 250);
sIn.close();
textMail = "From " this.mailFrom " To " destUser "\n" "Subject: " subject "\nMessage: " message;
return true;
} catch (IOException ex) {
Logger.getLogger(MailSender.class.getName()).log(Level.SEVERE, null, ex);
}
return false;
}
public String getMail() {
return textMail;
}
private void nextSMTPCode(BufferedReader sIn, int expectedCode) throws IOException {
int code;
String str = sIn.readLine();
System.out.println(str);
String sCode = str.substring(0, 3);
code = Integer.parseInt(sCode);
if (code != expectedCode) {
sIn.close();
System.out.println("Code: " code " expected code was: " expectedCode);
throw new IOException();
}
}
}
I am having problem with communication with smtp server, I am using smtp2go as smtp server. The problem is that I keep getting the 250 code even when this shouldn't show up, finally the email isn't sent. This is a sample communication:
220 mail.smtp2go.com
ESMTP Exim 4.96-S2G Tue, 10 Jan 2023 14:42:02
0000 250-mail.smtp2go.com Hello [xxxxx]
250-SIZE 52428800
250-8BITMIME
250-DSN 250-PIPELINING
250-PIPECONNECT
250-AUTH CRAM-MD5
PLAIN LOGIN
250-CHUNKING
I then get 250-SIZE 52428800 and the other responses (always with the code 250) for every command I send. I tried to telnet and everything seems to work, the problem is in my code but I can't figure out what I'm doing wrong. Does anyone know the cause of this problem?
CodePudding user response:
SMTP can have multiline responses, but you only expect singleline responses. Multiline responses are typical for EHLO. To cite from RFC 5231:
The format for multiline replies requires that every line, except the last, begin with the reply code, followed immediately by a hyphen, "-" (also known as minus), followed by text. The last line will begin with the reply code, followed immediately by , optionally some text, and . As noted above, servers SHOULD send the if subsequent text is not sent, but clients MUST be prepared for it to be omitted.
For example:
250-First line 250-Second line 250-234 Text beginning with numbers 250 The last line