java.lang.Object
i2p.susi.webmail.smtp.SMTPClient
SMTP client for sending email through SMTP servers over I2P. Supports command pipelining, attachments, and size limits optimized for I2P. Includes base64 size calculations and 8BITMIME support for efficient I2P mail delivery.
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprivate static classA result string and code.private static classA command to send and a result code to expect.Field Summary
Modifier and TypeFieldDescriptionprivate final LogLogger for this class.private static final EncodingEncoder for base64-authenticated logins.static final long7629902 ~= 7.27 MB Base64 encodes 57 chars to 76 + \r\n on a line.static final long10.00 MB smtp.postman.i2p as of 2024-06-22.Error message from the last failed operation, or empty if none.private StringThe server's reply to the last command.private longLargest message the server accepts, in bytes.private SocketSocket connection to the SMTP server.private booleanTrue if the server accepts 8-bit message bodies.private booleanTrue if the server accepts pipelined commands.Constructor Summary
ConstructorsMethod Summary
Modifier and TypeMethodDescriptionprivate static StringLooks up a localized string in the message bundle.private static StringLooks up a localized string in the message bundle, substituting one parameter.(package private) static StringcapsText(boolean pipelining, long maxSize, boolean eightBitMime) Reports what the server's EHLO response allowed, so a reader can tell why a message was refused on size or sent without pipelining.private SMTPClient.ResultRead the complete server reply.private intThe numeric code of the last server reply.private intWrites a command to the server and waits for its reply.private intWrites a command to the server, optionally without waiting for the reply.private intWrites a command to the server, optionally without waiting for the reply and optionally masked in the debug log.private voidsendCmdNoWait(String cmd) Does not flush, wait, or read.private voidsendCmdNoWait(String cmd, boolean mask) Does not flush, wait, or read.private intsendCmds(List<SMTPClient.SendExpect> cmds) Sends the commands back to back if the server supports pipelining, otherwise one at a time.booleansendMail(String host, int port, String user, String pass, String sender, List<String> recipients, StringBuilder body, List<Attachment> attachments, String boundary) Sends one message to an SMTP server, authenticating first when a user name is given.static voidwriteMail(Writer out, StringBuilder body, List<Attachment> attachments, String boundary) Caller must close out.
Field Details
DEFAULT_MAX_SIZE
public static final long DEFAULT_MAX_SIZE10.00 MB smtp.postman.i2p as of 2024-06-22.- See Also:
BINARY_MAX_SIZE
public static final long BINARY_MAX_SIZE7629902 ~= 7.27 MB Base64 encodes 57 chars to 76 + \r\n on a line.- See Also:
_log
Logger for this class.socket
Socket connection to the SMTP server.error
Error message from the last failed operation, or empty if none.lastResponse
The server's reply to the last command.supportsPipelining
private boolean supportsPipeliningTrue if the server accepts pipelined commands.supports8BitMime
private boolean supports8BitMimeTrue if the server accepts 8-bit message bodies.maxSize
private long maxSizeLargest message the server accepts, in bytes.base64
Encoder for base64-authenticated logins.
Constructor Details
SMTPClient
public SMTPClient()Creates a client with no error.
Method Details
sendCmd
Writes a command to the server and waits for its reply.- Parameters:
cmd- the command to write, or null to send nothing- Returns:
- result code or 0 for failure
sendCmd
Writes a command to the server, optionally without waiting for the reply.- Parameters:
cmd- the command to write, or null to send nothingshouldWait- if false, don't wait for response, and return 100- Returns:
- result code or 0 for failure
sendCmd
Writes a command to the server, optionally without waiting for the reply and optionally masked in the debug log.- Parameters:
cmd- the command to write, or null to send nothingshouldWait- if false, don't wait for response, and return 100mask- true to mask the command in debug logs (credentials)- Returns:
- result code or 0 for failure
sendCmdNoWait
Does not flush, wait, or read.- Parameters:
cmd- the command to write, never null- Throws:
IOException- if there is no connected socket, or the write fails
sendCmdNoWait
Does not flush, wait, or read.- Parameters:
cmd- the command to write, never nullmask- true to mask the command in debug logs (credentials)- Throws:
IOException- if there is no connected socket, or the write fails
capsText
Reports what the server's EHLO response allowed, so a reader can tell why a message was refused on size or sent without pipelining. Each capability is answered yes or no rather than left as a bare phrase, and the wire name is kept beside the prose so the line stays greppable.- Parameters:
pipelining- whether the server accepts pipelined commandsmaxSize- the message size limit the server reported, in byteseightBitMime- whether the server accepts unencoded 8-bit bodies- Returns:
- the multi-line log message
sendCmds
Sends the commands back to back if the server supports pipelining, otherwise one at a time.- Parameters:
cmds- the commands to send in order, never null or empty- Returns:
- number of successful commands
getResult
private int getResult()The numeric code of the last server reply.- Returns:
- result code or 0 for failure
getFullResult
Read the complete server reply.- Returns:
- result code and string, all lines combined with \r separators, first 3 bytes are the ASCII return code or "000" for failure Result and Result.recv non null
sendMail
public boolean sendMail(String host, int port, String user, String pass, String sender, List<String> recipients, StringBuilder body, List<Attachment> attachments, String boundary) Sends one message to an SMTP server, authenticating first when a user name is given. Any failure is appended to the error field rather than thrown.- Parameters:
host- the SMTP server to connect toport- the SMTP server port to connect touser- the AUTH LOGIN user name, base64-encoded on the wirepass- the AUTH LOGIN password, base64-encoded on the wiresender- the envelope sender, sent as MAIL FROMrecipients- the envelope recipients, sent as one RCPT TO eachbody- headers and body, without the attachmentsattachments- may be nullboundary- non-null if attachments is non-null- Returns:
- true if the server accepted the message, false if any step failed
writeMail
public static void writeMail(Writer out, StringBuilder body, List<Attachment> attachments, String boundary) throws IOException Caller must close out.- Parameters:
out- the writer that receives the message, left open for the callerbody- headers and body, without the attachmentsattachments- may be nullboundary- non-null if attachments is non-null- Throws:
IOException- if the socket write or the attachment encoding fails
_t
_t
Looks up a localized string in the message bundle, substituting one parameter.- Parameters:
s- the English text used as the lookup key, with {0} where the value goeso- substituted for {0} in the message- Returns:
- the translation for the current language, or s itself when untranslated