Author: dbkr
Date: 2007-02-15 23:06:25 +0000 (Thu, 15 Feb 2007)
New Revision: 11805
Added:
trunk/apps/Freemail/src/freemail/MailHeaderFilter.java
Modified:
trunk/apps/Freemail/src/freemail/OutboundContact.java
Log:
Filter the headers on the mail we send to remove the user agent and the
timezone we're in.
Added: trunk/apps/Freemail/src/freemail/MailHeaderFilter.java
===================================================================
--- trunk/apps/Freemail/src/freemail/MailHeaderFilter.java
(rev 0)
+++ trunk/apps/Freemail/src/freemail/MailHeaderFilter.java 2007-02-15
23:06:25 UTC (rev 11805)
@@ -0,0 +1,139 @@
+/*
+ * MailHeaderFilter.java
+ * This file is part of Freemail, copyright (C) 2006 Dave Baker
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ *
+ */
+
+/*
+ * MailHeaderFilter - A class to parse an Email message line by line
+ * and strip out information we'd rather not send
+ */
+
+package freemail;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.lang.StringBuffer;
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.TimeZone;
+import java.util.Calendar;
+import java.text.ParseException;
+
+class MailHeaderFilter {
+ private final BufferedReader reader;
+ private final StringBuffer buffer;
+ private boolean foundEnd;
+ private static final SimpleDateFormat sdf;
+ private static final TimeZone gmt;
+ private static final Calendar cal;
+
+ static {
+ sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z");
+ gmt = TimeZone.getTimeZone("GMT");
+ cal = Calendar.getInstance(gmt);
+ }
+
+ public MailHeaderFilter(BufferedReader rdr) {
+ this.reader = rdr;
+ this.buffer = new StringBuffer();
+ this.foundEnd = false;
+ }
+
+ public String readHeader() throws IOException {
+ String retval = null;
+
+ while (retval == null) {
+ if (this.foundEnd) {
+ return this.flush();
+ }
+
+ String line = this.reader.readLine();
+ if (line == null) {
+ System.out.println("Warning - reached end of
message file before reaching end of headers! This shouldn't happen!");
+ throw new IOException("Header filter reached
end of message file before reaching end of headers");
+ }
+
+ if (line.length() == 0) {
+ // end of the headers
+ this.foundEnd = true;
+ retval = this.flush();
+ } else if (line.startsWith(" ") ||
line.startsWith("\t")) {
+ // continuation of the previous header
+ this.buffer.append("\r\n"+line.trim());
+ } else {
+ retval = this.flush();
+ this.buffer.append(line);
+ }
+ }
+ return retval;
+ }
+
+ // this is called once a header is in the buffer
+ // if the header is invalid or filtered out entirely,
+ // return null. Otherwise return the filtered header.
+ private String flush() {
+ if (this.buffer.length() == 0) return null;
+
+ String[] bits = this.buffer.toString().split(": ", 2);
+ this.buffer.delete(0, this.buffer.length());
+
+ // invalid header - ditch it.
+ if (bits.length < 2) return null;
+
+ bits[1] = this.filterHeader(bits[0], bits[1]);
+ if (bits[1] == null) return null;
+
+ return bits[0]+": "+bits[1];
+ }
+
+ private String filterHeader(String name, String val) {
+ // simple blacklist filter for now
+ // a whitelist filter is probably excessive
+ if (name.equalsIgnoreCase("Date")) {
+ // the norm is to put the sender's local time here,
with the sender's local time offset
+ // at the end. Rather than giving away what time zone
we're in, parse the date in
+ // and return it as a GMT time.
+
+ Date d = null;
+ try {
+ d = sdf.parse(val);
+ } catch (ParseException pe) {
+ // ...the compiler whinges unless we catch this
exception...
+ System.out.println("Warning: couldn't parse
date: "+val+" (caught exception)");
+ return null;
+ }
+ // but the docs don't say that it throws it, but says
that it return null
+ //
http://java.sun.com/j2se/1.5.0/docs/api/java/text/SimpleDateFormat.html#parse(java.lang.String,
java.text.ParsePosition)
+ if (d == null) {
+ // invalid date - ditch the header
+ System.out.println("Warning: couldn't parse
date: "+val+" (got null)");
+ return null;
+ }
+ cal.setTime(d);
+ cal.setTimeZone(gmt);
+ return sdf.format(cal.getTime());
+ } else if (name.equalsIgnoreCase("User-Agent")) {
+ // might as well hide this
+ return null;
+ } else {
+ return val;
+ }
+ }
+}
Modified: trunk/apps/Freemail/src/freemail/OutboundContact.java
===================================================================
--- trunk/apps/Freemail/src/freemail/OutboundContact.java 2007-02-15
21:33:54 UTC (rev 11804)
+++ trunk/apps/Freemail/src/freemail/OutboundContact.java 2007-02-15
23:06:25 UTC (rev 11805)
@@ -32,6 +32,7 @@
import java.net.MalformedURLException;
import java.math.BigInteger;
import java.security.SecureRandom;
+import java.io.PrintWriter;
import freemail.utils.EmailAddress;
import freemail.utils.PropsFile;
@@ -513,30 +514,35 @@
QueuedMessage qm = new QueuedMessage(uid);
File msg;
- FileOutputStream fos;
+ PrintWriter pw;
try {
msg = File.createTempFile("ogm", "msg",
Freemail.getTempDir());
- fos = new FileOutputStream(msg);
+ pw = new PrintWriter(new FileOutputStream(msg));
} catch (IOException ioe) {
System.out.println("IO Error encountered whilst trying
to send message: "+ioe.getMessage()+" Will try again soon");
return false;
}
- FileInputStream fis;
try {
- fos.write(new String("id="+uid+"\r\n\r\n").getBytes());
-
- fis = new FileInputStream(body);
+ pw.print("id="+uid+"\r\n\r\n");
- byte[] buf = new byte[1024];
- int read;
- while ( (read = fis.read(buf)) > 0) {
- fos.write(buf, 0, read);
+ BufferedReader br = new BufferedReader(new
FileReader(body));
+ MailHeaderFilter filter = new MailHeaderFilter(br);
+
+ String chunk;
+ while ( (chunk = filter.readHeader()) != null ) {
+ pw.print(chunk+"\r\n");
}
+ pw.print("\r\n");
- fis.close();
- fos.close();
+ // Headers are done, copy the rest
+ while ( (chunk = br.readLine()) != null ) {
+ pw.print(chunk+"\r\n");
+ }
+
+ pw.close();
+ br.close();
} catch (IOException ioe) {
System.out.println("IO Error encountered whilst trying
to send message: "+ioe.getMessage()+" Will try again soon");
qm.delete();