private Message(Fountain in) throws Malformed {
super(in);
+
this.envelopeTo = headers.get("Envelope-To") != null ? Address.parse(headers.get("Envelope-To")) : null;
this.envelopeFrom = headers.get("Return-Path") != null ? Address.parse(headers.get("Return-Path")) : null;
this.to = headers.get("To") != null ? Address.parse(headers.get("To")) : this.envelopeTo;
this.cc = Address.list(headers.get("Cc"));
this.bcc = Address.list(headers.get("Bcc"));
this.date = parseDate(headers.get("Date")) == null ? new Date() : parseDate(headers.get("Date"));
+
+ if (this.messageid==null)
+ throw new RuntimeException("every RFC2822 message must have a Message-ID: header");
+
+ /*
+ // synthesize a message-id if not provided
+ this.messageid = headers.get("Message-Id") == null ? generateFreshMessageId(sha1(in.getStream())) : headers.get("Message-Id");
+ if (headers.get("Message-Id") == null) {
+ headers = headers.set("Message-Id", this.messageid);
+ Log.warn(Message.class, "synthesizing message-id for " + summary());
+ }
+ */
+
this.arrival = this.date; // FIXME wrong; grab this from traces?
}
+ /*
+ private static String sha1(Stream stream) {
+ SHA1 sha1 = new SHA1();
+ byte[] b = new byte[1024];
+ while(true) {
+ int numread = stream.read(b, 0, b.length);
+ if (numread == -1) break;
+ sha1.update(b, 0, numread);
+ }
+ byte[] results = new byte[sha1.getDigestSize()];
+ sha1.doFinal(results, 0);
+ return new String(Encode.toBase64(results));
+ }
+ */
// Helpers /////////////////////////////////////////////////////////////////////////////
// http://www.jwz.org/doc/mid.html
private static final Random random = new Random();
public static String generateFreshMessageId() {
+ return generateFreshMessageId(Base36.encode(System.currentTimeMillis())+'.'+
+ Base36.encode(random.nextLong()));
+ }
+ public static String generateFreshMessageId(String seed) {
StringBuffer ret = new StringBuffer();
ret.append('<');
- ret.append(Base36.encode(System.currentTimeMillis()));
- ret.append('.');
- ret.append(Base36.encode(random.nextLong()));
- ret.append('.');
+ ret.append(seed);
+ ret.append('@');
try { ret.append(InetAddress.getLocalHost().getHostName()); } catch (UnknownHostException e) { /* DELIBERATE */ }
ret.append('>');
return ret.toString();
}
// this is belived to be compliant with QSBMF (http://cr.yp.to/proto/qsbmf.txt)
-v v v v v v v
public Message bounce(String reason) {
if (envelopeFrom==null || envelopeFrom.toString().equals("")) return null;
return null;
}
}
-*************
-v v v v v v v
- public Message bounce(String reason) {
- Log.warn(Message.class, "bounce not implemented");
- return null;
- } // FIXME!
-
-*************
- public Message bounce(String reason) {
- Log.warn(Message.class, "bounce not implemented");
- } // FIXME!
-
-^ ^ ^ ^ ^ ^ ^
- public String summary() {
- return
- " Subject: " + subject + "\n" +
- " EnvelopeFrom: " + envelope.from + "\n" +
- " EnvelopeTo: " + envelope.to + "\n" +
- " MessageId: " + messageid;
- }
-^ ^ ^ ^ ^ ^ ^
- public String toString() { throw new RuntimeException("Message.toString() called"); }
- public String summary() { return "[" + envelopeFrom + " -> " + envelopeTo + "] " + subject; }
+ public String toString() { throw new RuntimeException("Message.toString() called"); }
+ public final String summary() { return "[" + envelopeFrom + " -> " + envelopeTo + "] " + subject; }
public static class Malformed extends MailException { public Malformed(String s) { super(s); } }
}