changeset 1584:d3728e3e5af3

mail work
author Franklin Schmidt <fschmidt@gmail.com>
date Thu, 11 Mar 2021 01:22:20 -0700
parents 1cc6c7fa803d
children c0ef8acf069d
files src/goodjava/mail/Examples.java src/goodjava/mail/MailException.java src/goodjava/mail/Message.java src/goodjava/mail/Smtp.java src/goodjava/mail/SmtpException.java
diffstat 5 files changed, 151 insertions(+), 91 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/goodjava/mail/Examples.java	Thu Mar 11 01:22:20 2021 -0700
@@ -0,0 +1,82 @@
+package goodjava.mail;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.net.Socket;
+import java.net.URL;
+import java.util.Map;
+import java.util.LinkedHashMap;
+
+
+public class Examples {
+
+	private static Smtp newSmtp() throws IOException, MailException {
+		Socket socket = new Socket("smtpcorp.com",2525);
+		Smtp smtp = new Smtp(socket);
+		smtp.authenticate("smtp@luan.software","luanhost");
+		return smtp;
+	}
+
+	private static void smtp() throws IOException, MailException {
+		Smtp smtp = newSmtp();
+		smtp.from("smtp@luan.software");
+		smtp.to("fschmidt@gmail.com");
+		String text = "\r\n"
+			+"test3\r\n"
+			+".q\r\n"
+			+"x\r\n"
+			+"rg; ;lrg dsl rgj errlgerrg neskrjg skrg rdsg drskrg sd;gr s;kgr skrg skrg sdg ds fg;ks gegr erg ;sg sd; g;sdr gsklrg sg s;kkrg s;hg ;slrg ;elrg ;reg r;g ;r g;er g;ler g;e g; g;r g rg; srkd fjl kj kklsjrg lsk gskdf;rs gkrj glj grekjs lksjgkjn kjslg rklrg ;rsd; kj drsg akrglk kalrgklrsdnrgkgj;r ;s ns b;n;sn ;njslk r;n\r\n"
+		;
+		smtp.data(text);
+		smtp.close();
+	}
+
+	private static void mailText() throws IOException, MailException {
+		String text = ""
+			+"testm 2\n"
+			+"x\n"
+			+"产品\n"  // some random chinese
+			+"rg; ;lrg dsl rgj errlgerrg neskrjg skrg rdsg drskrg sd;gr s;kgr skrg skrg sdg ds fg;ks gegr erg ;sg sd; g;sdr gsklrg sg s;kkrg s;hg ;slrg ;elrg ;reg r;g ;r g;er g;ler g;e g; g;r g rg; srkd fjl kj kklsjrg lsk gskdf;rs gkrj glj grekjs lksjgkjn kjslg rklrg ;rsd; kj drsg akrglk kalrgklrsdnrgkgj;r ;s ns b;n;sn ;njslk r;n\n"
+		;
+		Map<String,String> headers = new LinkedHashMap<String,String>();
+		headers.put("From","smtp@luan.software");
+		headers.put("To","fschmidt@gmail.com");
+		headers.put("Subject","test text");
+		headers.put("Content-Type","text/plain; charset=utf-8");
+		Message msg = new Message(headers,text);
+		Smtp smtp = newSmtp();
+		smtp.send(msg);
+		smtp.close();
+	}
+
+	private static byte[] flag() throws IOException {
+		URL url = new URL("https://upload.wikimedia.org/wikipedia/commons/thumb/9/9a/Confederate_Rebel_Flag.svg/440px-Confederate_Rebel_Flag.svg.png");
+		InputStream in = url.openConnection().getInputStream();
+		byte[] a = new byte[100000];
+		int n = 0;
+		int i;
+		while( (i=in.read(a,n,a.length-n)) != -1 )
+			n += i;
+		in.close();
+		byte[] rtn = new byte[n];
+		System.arraycopy(a,0,rtn,0,n);
+		return rtn;
+	}
+
+	private static void mailFlag() throws IOException, MailException {
+		byte[] flag = flag();
+		Map<String,String> headers = new LinkedHashMap<String,String>();
+		headers.put("From","smtp@luan.software");
+		headers.put("To","fschmidt@gmail.com");
+		headers.put("Subject","test flag");
+		headers.put("Content-Type","image/png; name=\"flag.png\"");
+		Message msg = new Message(headers,flag);
+		Smtp smtp = newSmtp();
+		smtp.send(msg);
+		smtp.close();
+	}
+
+	public static void main(String[] args) throws Exception {
+		mailText();
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/goodjava/mail/MailException.java	Thu Mar 11 01:22:20 2021 -0700
@@ -0,0 +1,9 @@
+package goodjava.mail;
+
+
+public class MailException extends Exception {
+
+	public MailException(String msg) {
+		super(msg);
+	}
+}
--- a/src/goodjava/mail/Message.java	Sun Mar 07 02:22:09 2021 -0700
+++ b/src/goodjava/mail/Message.java	Thu Mar 11 01:22:20 2021 -0700
@@ -1,76 +1,70 @@
 package goodjava.mail;
 
 import java.util.Map;
-import java.util.LinkedHashMap;
+import java.util.Base64;
 import java.util.regex.Pattern;
 import java.util.regex.Matcher;
 import goodjava.util.GoodUtils;
 
-import java.net.Socket;
-
 
 public class Message {
-	public final Map<String,String> headers = new LinkedHashMap<String,String>();
-	public final String content;
-	public final String contentType;
+	public final Map<String,String> headers;
+	public final Object content;
 	private static Pattern line = Pattern.compile("(?m)^.*$");
 
-	public Message(String content) {
-		this(content,"text/plain");
+	public Message(Map<String,String> headers,Object content) {
+		this.headers = headers;
+		this.content = content;
 	}
 
-	public Message(String content,String contentType) {
-		this.content = content;
-		this.contentType = contentType;
+	private static void addBase64(StringBuilder sb,byte[] a) {
+		String s = Base64.getEncoder().encodeToString(a);
+		int n = s.length() - 76;
+		int i;
+		for( i=0; i<n; i+=76 ) {
+			sb.append(s.substring(i,i+76)).append("\r\n");
+		}
+		sb.append(s.substring(i)).append("\r\n");
 	}
 
-	public String toText() {
+	public String toText() throws MailException {
 		StringBuilder sb = new StringBuilder();
+		String contentType = null;
 		for( Map.Entry<String,String> entry : headers.entrySet() ) {
 			String name = entry.getKey();
+			String value = entry.getValue();
 			if( name.equalsIgnoreCase("bcc") )
 				continue;
-			String value = entry.getValue();
+			if( name.equalsIgnoreCase("content-type") ) {
+				contentType = value;
+				continue;
+			}
 			sb.append( name ).append( ": " ).append( value ).append( "\r\n" );
 		}
-		sb.append( "Content-Type: " ).append( contentType ).append( "; charset=\"UTF-8\"\r\n" );
-		boolean isAscii = content.matches("\\p{ASCII}*");
-		if( !isAscii )
-			sb.append( "Content-Transfer-Encoding: base64\r\n" );
-		sb.append( "\r\n" );
-		if( isAscii ) {
-			Matcher m = line.matcher(content);
-			while( m.find() ) {
-				sb.append(m.group()).append("\r\n");		
+		if( contentType==null )
+			throw new MailException("Content-Type not defined");
+		if( content instanceof String ) {
+			String s = (String)content;
+			sb.append( "Content-Type: " ).append( contentType ).append( "\r\n" );
+			boolean isAscii = s.matches("\\p{ASCII}*");
+			if( !isAscii )
+				sb.append( "Content-Transfer-Encoding: base64\r\n" );
+			sb.append( "\r\n" );
+			if( isAscii ) {
+				Matcher m = line.matcher(s);
+				while( m.find() ) {
+					sb.append(m.group()).append("\r\n");		
+				}
+			} else {
+				addBase64( sb, GoodUtils.getBytes(s,"UTF-8") );
 			}
-		} else {
-			String s = GoodUtils.base64Encode(content);
-			int n = s.length() - 76;
-			int i;
-			for( i=0; i<n; i+=76 ) {
-				sb.append(s.substring(i,i+76)).append("\r\n");
-			}
-			sb.append(s.substring(i)).append("\r\n");
-		}
+		} else if( content instanceof byte[] ) {
+			sb.append( "Content-Type: " ).append( contentType ).append( "\r\n" );
+			sb.append( "Content-Transfer-Encoding: base64\r\n" );
+			sb.append( "\r\n" );
+			addBase64( sb, (byte[])content );
+		} else
+			throw new MailException("content is unrecognized type");
 		return sb.toString();
 	}
-
-	public static void main(String[] args) throws Exception {
-		String text = ""
-			+"testm 2\n"
-			+"x\n"
-//			+"产品\n"
-			+"rg; ;lrg dsl rgj errlgerrg neskrjg skrg rdsg drskrg sd;gr s;kgr skrg skrg sdg ds fg;ks gegr erg ;sg sd; g;sdr gsklrg sg s;kkrg s;hg ;slrg ;elrg ;reg r;g ;r g;er g;ler g;e g; g;r g rg; srkd fjl kj kklsjrg lsk gskdf;rs gkrj glj grekjs lksjgkjn kjslg rklrg ;rsd; kj drsg akrglk kalrgklrsdnrgkgj;r ;s ns b;n;sn ;njslk r;n\r\n"
-		;
-		Message msg = new Message(text);
-		msg.headers.put("From","smtp@luan.software");
-		msg.headers.put("To","fschmidt@gmail.com");
-		msg.headers.put("Subject","test");
-		Socket socket = new Socket("smtpcorp.com",2525);
-		Smtp smtp = new Smtp(socket);
-		smtp.authenticate("smtp@luan.software","luanhost");
-		smtp.send(msg);
-		smtp.close();
-		System.out.println("done msg");
-	}
 }
--- a/src/goodjava/mail/Smtp.java	Sun Mar 07 02:22:09 2021 -0700
+++ b/src/goodjava/mail/Smtp.java	Thu Mar 11 01:22:20 2021 -0700
@@ -17,30 +17,30 @@
 	private final Writer writer;
 	public final String ehlo;
 
-	public Smtp(Socket socket) throws IOException, SmtpException {
+	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 SmtpException(s);
+			throw new MailException(s);
 		write( "EHLO\r\n" );
 		ehlo = read();
 		if( !ehlo.startsWith("250") )
-			throw new SmtpException(ehlo);
+			throw new MailException(ehlo);
 	}
 
-	public String authenticate(String username,String password) throws IOException, SmtpException {
+	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 SmtpException(r);
+			throw new MailException(r);
 		return r;
 	}
 
-	public void send(Message msg) throws IOException, SmtpException {
+	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();
@@ -59,42 +59,42 @@
 		data( msg.toText() );
 	}
 
-	public void close() throws IOException, SmtpException {
+	public void close() throws IOException, MailException {
 		write( "QUIT\r\n" );
 		String s = read();
 		if( !s.startsWith("221") )
-			throw new SmtpException(s);
+			throw new MailException(s);
 		socket.close();
 	}
 
-	public String from(String address) throws IOException, SmtpException {
+	public String from(String address) throws IOException, MailException {
 		write( "MAIL FROM: " + address + "\r\n" );
 		String r = read();
 		if( !r.startsWith("250") )
-			throw new SmtpException(r);
+			throw new MailException(r);
 		return r;
 	}
 
-	public String to(String address) throws IOException, SmtpException {
+	public String to(String address) throws IOException, MailException {
 		write( "RCPT TO: " + address + "\r\n" );
 		String r = read();
 		if( !r.startsWith("250") )
-			throw new SmtpException(r);
+			throw new MailException(r);
 		return r;
 	}
 
-	public String data(String text) throws IOException, SmtpException {
+	public String data(String text) throws IOException, MailException {
 		if( !text.endsWith("\r\n") )
-			throw new SmtpException("text must end with \\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 SmtpException(r);
+			throw new MailException(r);
 		write( text + ".\r\n" );
 		r = read();
 		if( !r.startsWith("250") )
-			throw new SmtpException(r);
+			throw new MailException(r);
 		return r;
 	}
 
@@ -107,20 +107,4 @@
 		writer.write(s);
 		writer.flush();
 	}
-
-	public static void main(String[] args) throws Exception {
-		Socket socket = new Socket("smtpcorp.com",2525);
-		Smtp smtp = new Smtp(socket);
-		smtp.authenticate("smtp@luan.software","luanhost");
-		smtp.from("smtp@luan.software");
-		smtp.to(" fschmidt@gmail.com");
-		String text = "\r\n"
-			+"test3\r\n"
-			+".q\r\n"
-			+"x\r\n"
-			+"rg; ;lrg dsl rgj errlgerrg neskrjg skrg rdsg drskrg sd;gr s;kgr skrg skrg sdg ds fg;ks gegr erg ;sg sd; g;sdr gsklrg sg s;kkrg s;hg ;slrg ;elrg ;reg r;g ;r g;er g;ler g;e g; g;r g rg; srkd fjl kj kklsjrg lsk gskdf;rs gkrj glj grekjs lksjgkjn kjslg rklrg ;rsd; kj drsg akrglk kalrgklrsdnrgkgj;r ;s ns b;n;sn ;njslk r;n\r\n"
-		;
-		smtp.data(text);
-		smtp.close();
-	}
 }
--- a/src/goodjava/mail/SmtpException.java	Sun Mar 07 02:22:09 2021 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-package goodjava.mail;
-
-
-public class SmtpException extends Exception {
-
-	public SmtpException(String msg) {
-		super(msg);
-	}
-}