view src/goodjava/mail/Smtp.java @ 1721:5c69d2e8bd75

no regex in String.find and String.split
author Franklin Schmidt <fschmidt@gmail.com>
date Tue, 26 Jul 2022 12:44:52 -0600
parents e34b73678a4f
children 1ffe1e06ea55
line wrap: on
line source

package goodjava.mail;

import java.io.Reader;
import java.io.InputStreamReader;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.IOException;
import java.net.Socket;
import java.util.Map;
import goodjava.util.GoodUtils;


public class Smtp {
	private final char[] buf = new char[1000];
	private final Socket socket;
	private final Reader reader;
	private final Writer writer;
	public final String ehlo;

	public Smtp(Socket socket) throws IOException, MailException {
		this.socket = socket;
		this.reader = new InputStreamReader(socket.getInputStream());
		this.writer = new OutputStreamWriter(socket.getOutputStream());
		String s = read();
		if( !s.startsWith("220") )
			throw new MailException(s);
		write( "EHLO\r\n" );
		ehlo = read();
		if( !ehlo.startsWith("250") )
			throw new MailException(ehlo);
	}

	public String authenticate(String username,String password) throws IOException, MailException {
		String s = "\0" + username + "\0" + password;
		s = GoodUtils.base64Encode(s);
		write( "AUTH PLAIN " + s + "\r\n" );
		String r = read();
		if( !r.startsWith("235") )
			throw new MailException(r);
		return r;
	}

	public void send(Message msg) throws IOException, MailException {
		for( Map.Entry<String,String> entry : msg.headers.entrySet() ) {
			String name = entry.getKey();
			String value = entry.getValue();
			if( name.equalsIgnoreCase("from") ) {
				from(value);
			}
		}
		for( Map.Entry<String,String> entry : msg.headers.entrySet() ) {
			String name = entry.getKey();
			String value = entry.getValue();
			if( name.equalsIgnoreCase("to")
				|| name.equalsIgnoreCase("cc")
				|| name.equalsIgnoreCase("bcc")
			) {
				for( String s : value.split(",") ) {
					to(s);
				}
			}
		}
		data( msg.toText() );
	}

	public void close() throws IOException, MailException {
		write( "QUIT\r\n" );
		String s = read();
		if( !s.startsWith("221") )
			throw new MailException(s);
		socket.close();
	}

	public String from(String address) throws IOException, MailException {
		write( "MAIL FROM: " + address + "\r\n" );
		String r = read();
		if( !r.startsWith("250") )
			throw new MailException(r);
		return r;
	}

	public String to(String address) throws IOException, MailException {
		write( "RCPT TO: " + address + "\r\n" );
		String r = read();
		if( !r.startsWith("250") )
			throw new MailException(r);
		return r;
	}

	public String data(String text) throws IOException, MailException {
		if( !text.endsWith("\r\n") )
			throw new MailException("text must end with \\r\\n");
		text = text.replace("\r\n.","\r\n..");
		write( "DATA\r\n" );
		String r = read();
		if( !r.startsWith("354") )
			throw new MailException(r);
		write( text + ".\r\n" );
		r = read();
		if( !r.startsWith("250") )
			throw new MailException(r);
		return r;
	}

	private String read() throws IOException {
		int n = reader.read(buf);
		return new String(buf,0,n);
	}

	private void write(String s) throws IOException {
		writer.write(s);
		writer.flush();
	}
}