noel 2004/08/19 20:48:15 Modified: src/java/org/apache/james/core Tag: branch_2_1_fcs MimeMessageWrapper.java src/java/org/apache/james/transport/mailets Tag: branch_2_1_fcs LocalDelivery.java Log: Additional adjustments to fix JAMES-264. InternetHeaders is an awkward class to work with due its own internal handling of header order. This change takes advantage of how InternetHeaders works, pre-placing a null placeholder for a possible Return-Path header so that when setHeader is called, it will use that placeholder, and remove any other Return-Path headers. It also ensures that there are no other placeholders, providing a bit more control as we manipulate the Delivered-To headers (and possibly other headers that JavaMail may want to change internally, such as Message-ID, Date and Mime-Version). Revision Changes Path No revision No revision 1.17.4.11 +9 -2 james-server/src/java/org/apache/james/core/MimeMessageWrapper.java Index: MimeMessageWrapper.java =================================================================== RCS file: /home/cvs/james-server/src/java/org/apache/james/core/MimeMessageWrapper.java,v retrieving revision 1.17.4.10 retrieving revision 1.17.4.11 diff -u -r1.17.4.10 -r1.17.4.11 --- MimeMessageWrapper.java 15 Mar 2004 03:54:15 -0000 1.17.4.10 +++ MimeMessageWrapper.java 20 Aug 2004 03:48:15 -0000 1.17.4.11 @@ -103,6 +103,13 @@ return source.getSourceId(); } + private synchronized MailHeaders loadHeaders(InputStream is) throws MessagingException { + headers = new MailHeaders(new ByteArrayInputStream((RFC2822Headers.RETURN_PATH + ": placeholder").getBytes())); + headers.setHeader(RFC2822Headers.RETURN_PATH, null); + headers.load(is); + return headers; + } + /** * Load the message headers from the internal source. * @@ -117,7 +124,7 @@ try { InputStream in = source.getInputStream(); try { - headers = new MailHeaders(in); + headers = loadHeaders(in); } finally { IOUtil.shutdownStream(in); } @@ -140,7 +147,7 @@ InputStream in = null; try { in = source.getInputStream(); - headers = new MailHeaders(in); + headers = loadHeaders(in); ByteArrayInputStream headersIn = new ByteArrayInputStream(headers.toByteArray()); No revision No revision 1.6.4.10 +28 -29 james-server/src/java/org/apache/james/transport/mailets/LocalDelivery.java Index: LocalDelivery.java =================================================================== RCS file: /home/cvs/james-server/src/java/org/apache/james/transport/mailets/LocalDelivery.java,v retrieving revision 1.6.4.9 retrieving revision 1.6.4.10 diff -u -r1.6.4.9 -r1.6.4.10 --- LocalDelivery.java 19 Aug 2004 05:07:56 -0000 1.6.4.9 +++ LocalDelivery.java 20 Aug 2004 03:48:15 -0000 1.6.4.10 @@ -25,6 +25,7 @@ import javax.mail.Header; import javax.mail.MessagingException; +import javax.mail.Session; import javax.mail.internet.MimeMessage; import javax.mail.internet.InternetHeaders; @@ -53,45 +54,43 @@ MimeMessage message = mail.getMessage(); - // Create an InternetHeader collection with only our Return-Path - // header. The InternetHeader() constructor creates an - // InternetHeader instance with invisible placehoders for - // various headers. - InternetHeaders newHeaders = new InternetHeaders(new java.io.ByteArrayInputStream((RFC2822Headers.RETURN_PATH + ": " + (mail.getSender() == null ? "<>" : "<" + mail.getSender() + ">\r\n")).getBytes())); - // Remove all Return-Path headers from the message - message.removeHeader(RFC2822Headers.RETURN_PATH); - // Copy all remaining header lines from the message to our new header set - Enumeration headers = message.getAllHeaderLines(); - while (headers.hasMoreElements()) { - newHeaders.addHeaderLine((String) headers.nextElement()); + // Set Return-Path and remove all other Return-Path headers from the message + // This only works because there is a placeholder inserted by MimeMessageWrapper + message.setHeader(RFC2822Headers.RETURN_PATH, (mail.getSender() == null ? "<>" : "<" + mail.getSender() + ">")); + +/* + if(message.getMessageID() == null) { + MimeMessage midMsg = new MimeMessage(Session.getDefaultInstance(System.getProperties(), null)); + midMsg.saveChanges(); + message.addHeaderLine("Message-ID: " + midMsg.getMessageID()); } - // Remember all Header names - headers = message.getAllHeaders(); - ArrayList names = new ArrayList(); +*/ + // Copy any Delivered-To headers from the message + InternetHeaders deliveredTo = new InternetHeaders(); + Enumeration headers = message.getMatchingHeaders(new String[] {"Delivered-To"}); while (headers.hasMoreElements()) { - names.add(((Header)headers.nextElement()).getName()); + Header header = (Header) headers.nextElement(); + deliveredTo.addHeader(header.getName(), header.getValue()); } - final String[] headerNames = (String[]) names.toArray(new String[0]); - names = null; for (Iterator i = recipients.iterator(); i.hasNext(); ) { MailAddress recipient = (MailAddress) i.next(); try { - // Remove all headers - for(int h = 0; h < headerNames.length; h++) { - message.removeHeader(headerNames[h]); - } - - // Copy our new header set to the message - headers = newHeaders.getAllHeaderLines(); - while (headers.hasMoreElements()) { - message.addHeaderLine((String) headers.nextElement()); - } - // Add qmail's de facto standard Delivered-To header - message.addHeaderLine("Delivered-To: " + recipient.toString()); + message.addHeader("Delivered-To", recipient.toString()); getMailetContext().storeMail(mail.getSender(), recipient, message); + + if (i.hasNext()) { + // Remove headers but leave all placeholders + message.removeHeader("Delivered-To"); + headers = deliveredTo.getAllHeaders(); + // And restore any original Delivered-To headers + while (headers.hasMoreElements()) { + Header header = (Header) headers.nextElement(); + message.addHeader(header.getName(), header.getValue()); + } + } } catch (Exception ex) { getMailetContext().log("Error while storing mail.", ex); errors.add(recipient);
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]