sbrewin 2004/02/09 08:15:45 Modified: src/java/org/apache/james/fetchmail Tag: branch_2_1_fcs Account.java FetchMail.java ParsedConfiguration.java MessageProcessor.java FolderProcessor.java ProcessorAbstract.java StoreProcessor.java DynamicAccount.java src/conf Tag: branch_2_1_fcs james-fetchmail.xml src/xdocs Tag: branch_2_1_fcs fetchmail_configuration_2_2.xml Added: src/conf/samples/fetchmail Tag: branch_2_1_fcs maxMessageSize.xml Log: Added ability to filter messages by size. Fixed NullPointer Exception thrown by org.apache.james.fetchmail.MessageProcessor.computeRemoteDomain(), see http://nagoya.apache.org/jira/secure/ViewIssue.jspa?key=JAMES-150. Revision Changes Path No revision No revision 1.1.2.3 +29 -1 james-server/src/java/org/apache/james/fetchmail/Attic/Account.java Index: Account.java =================================================================== RCS file: /home/cvs/james-server/src/java/org/apache/james/fetchmail/Attic/Account.java,v retrieving revision 1.1.2.2 retrieving revision 1.1.2.3 diff -u -r1.1.2.2 -r1.1.2.3 --- Account.java 21 Sep 2003 20:03:35 -0000 1.1.2.2 +++ Account.java 9 Feb 2004 16:15:45 -0000 1.1.2.3 @@ -60,6 +60,8 @@ import java.util.ArrayList; import java.util.List; + +import javax.mail.Session; import javax.mail.internet.ParseException; import org.apache.avalon.framework.configuration.ConfigurationException; @@ -112,6 +114,11 @@ private boolean fieldIgnoreRecipientHeader; /** + * The JavaMail Session for this Account. + */ + + private Session fieldSession; + /** * Constructor for Account. */ private Account() @@ -128,6 +135,7 @@ * @param password * @param recipient * @param ignoreRecipientHeader + * @param session * @throws ConfigurationException */ @@ -137,7 +145,8 @@ String user, String password, String recipient, - boolean ignoreRecipientHeader) + boolean ignoreRecipientHeader, + Session session) throws ConfigurationException { this(); @@ -147,6 +156,7 @@ setPassword(password); setRecipient(recipient); setIgnoreRecipientHeader(ignoreRecipientHeader); + setSession(session); } /** @@ -345,6 +355,24 @@ protected void setParsedConfiguration(ParsedConfiguration parsedConfiguration) { fieldParsedConfiguration = parsedConfiguration; + } + + /** + * Returns the session. + * @return Session + */ + public Session getSession() + { + return fieldSession; + } + + /** + * Sets the session. + * @param session The session to set + */ + protected void setSession(Session session) + { + fieldSession = session; } } 1.9.2.5 +10 -5 james-server/src/java/org/apache/james/fetchmail/FetchMail.java Index: FetchMail.java =================================================================== RCS file: /home/cvs/james-server/src/java/org/apache/james/fetchmail/FetchMail.java,v retrieving revision 1.9.2.4 retrieving revision 1.9.2.5 diff -u -r1.9.2.4 -r1.9.2.5 --- FetchMail.java 20 Oct 2003 03:43:26 -0000 1.9.2.4 +++ FetchMail.java 9 Feb 2004 16:15:45 -0000 1.9.2.5 @@ -448,7 +448,7 @@ getServer(), getLocalUsers()); setConfiguration(parsedConfiguration); - + // Setup the Accounts Configuration[] allAccounts = configuration.getChildren("accounts"); if (allAccounts.length < 1) @@ -487,7 +487,8 @@ accountsChild.getAttribute("password"), accountsChild.getAttribute("recipient"), accountsChild.getAttributeAsBoolean( - "ignorercpt-header"))); + "ignorercpt-header"), + getSession())); continue; } @@ -507,7 +508,11 @@ { // if we are already fetching then just return if (isFetching()) + { + getLogger().info( + "Triggered fetch cancelled. A fetch is already in progress."); return; + } // Enter Fetching State try @@ -561,8 +566,7 @@ { try { - new StoreProcessor((Account) accounts.next(), getSession()) - .process(); + new StoreProcessor((Account) accounts.next()).process(); } catch (MessagingException ex) { @@ -868,7 +872,8 @@ parameters.getPassword(), parameters.getRecipientPrefix(), parameters.getRecipientSuffix(), - parameters.isIgnoreRecipientHeader()); + parameters.isIgnoreRecipientHeader(), + getSession()); } accounts.put(key, account); } 1.1.2.5 +108 -1 james-server/src/java/org/apache/james/fetchmail/Attic/ParsedConfiguration.java Index: ParsedConfiguration.java =================================================================== RCS file: /home/cvs/james-server/src/java/org/apache/james/fetchmail/Attic/ParsedConfiguration.java,v retrieving revision 1.1.2.4 retrieving revision 1.1.2.5 diff -u -r1.1.2.4 -r1.1.2.5 --- ParsedConfiguration.java 20 Oct 2003 03:43:26 -0000 1.1.2.4 +++ ParsedConfiguration.java 9 Feb 2004 16:15:45 -0000 1.1.2.5 @@ -292,8 +292,30 @@ /** * The Set of MailAddresses for whom mail should be rejected */ - private Set fieldBlacklist; + private Set fieldBlacklist; + /** + * The maximum message size limit + * 0 means no limit. + */ + private int fieldMaxMessageSizeLimit = 0; + + /** + * Reject mail exceeding the maximum message size limit + */ + private boolean fieldRejectMaxMessageSizeExceeded; + + /** + * Leave messages on the server that exceed the maximum message size limit. + */ + private boolean fieldLeaveMaxMessageSizeExceeded; + + /** + * Mark as seen messages on the server that exceed the maximum message size + * limit. + */ + private boolean fieldMarkMaxMessageSizeExceededSeen; + /** * The Local Users repository */ @@ -389,6 +411,19 @@ setRemoteReceivedHeaderIndex( conf.getChild("remoteReceivedHeaderIndex").getValueAsInteger(-1)); + Configuration maxmessagesize = conf.getChild("maxmessagesize", false); + if (null != maxmessagesize) + { + setMaxMessageSizeLimit( + maxmessagesize.getAttributeAsInteger("limit") * 1024); + setRejectMaxMessageSizeExceeded( + maxmessagesize.getAttributeAsBoolean("reject")); + setLeaveMaxMessageSizeExceeded( + maxmessagesize.getAttributeAsBoolean("leaveonserver")); + setMarkMaxMessageSizeExceededSeen( + maxmessagesize.getAttributeAsBoolean("markseen")); + } + if (getLogger().isDebugEnabled()) { getLogger().info( @@ -1000,6 +1035,78 @@ protected void setRemoteReceivedHeaderIndex(int remoteReceivedHeaderIndex) { fieldRemoteReceivedHeaderIndex = remoteReceivedHeaderIndex; + } + + /** + * Returns the leaveMaxMessageSize. + * @return boolean + */ + public boolean isLeaveMaxMessageSizeExceeded() + { + return fieldLeaveMaxMessageSizeExceeded; + } + + /** + * Returns the markMaxMessageSizeSeen. + * @return boolean + */ + public boolean isMarkMaxMessageSizeExceededSeen() + { + return fieldMarkMaxMessageSizeExceededSeen; + } + + /** + * Returns the maxMessageSizeLimit. + * @return int + */ + public int getMaxMessageSizeLimit() + { + return fieldMaxMessageSizeLimit; + } + + /** + * Returns the rejectMaxMessageSize. + * @return boolean + */ + public boolean isRejectMaxMessageSizeExceeded() + { + return fieldRejectMaxMessageSizeExceeded; + } + + /** + * Sets the leaveMaxMessageSize. + * @param leaveMaxMessageSize The leaveMaxMessageSize to set + */ + protected void setLeaveMaxMessageSizeExceeded(boolean leaveMaxMessageSize) + { + fieldLeaveMaxMessageSizeExceeded = leaveMaxMessageSize; + } + + /** + * Sets the markMaxMessageSizeSeen. + * @param markMaxMessageSizeSeen The markMaxMessageSizeSeen to set + */ + protected void setMarkMaxMessageSizeExceededSeen(boolean markMaxMessageSizeSeen) + { + fieldMarkMaxMessageSizeExceededSeen = markMaxMessageSizeSeen; + } + + /** + * Sets the maxMessageSizeLimit. + * @param maxMessageSizeLimit The maxMessageSizeLimit to set + */ + protected void setMaxMessageSizeLimit(int maxMessageSizeLimit) + { + fieldMaxMessageSizeLimit = maxMessageSizeLimit; + } + + /** + * Sets the rejectMaxMessageSize. + * @param rejectMaxMessageSize The rejectMaxMessageSize to set + */ + protected void setRejectMaxMessageSizeExceeded(boolean rejectMaxMessageSize) + { + fieldRejectMaxMessageSizeExceeded = rejectMaxMessageSize; } } 1.1.2.4 +226 -53 james-server/src/java/org/apache/james/fetchmail/Attic/MessageProcessor.java Index: MessageProcessor.java =================================================================== RCS file: /home/cvs/james-server/src/java/org/apache/james/fetchmail/Attic/MessageProcessor.java,v retrieving revision 1.1.2.3 retrieving revision 1.1.2.4 diff -u -r1.1.2.3 -r1.1.2.4 --- MessageProcessor.java 20 Oct 2003 03:43:26 -0000 1.1.2.3 +++ MessageProcessor.java 9 Feb 2004 16:15:45 -0000 1.1.2.4 @@ -58,6 +58,7 @@ package org.apache.james.fetchmail; +import java.io.InputStream; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.ArrayList; @@ -68,8 +69,11 @@ import javax.mail.Address; import javax.mail.Flags; +import javax.mail.Folder; import javax.mail.MessagingException; +import javax.mail.Session; import javax.mail.internet.InternetAddress; +import javax.mail.internet.InternetHeaders; import javax.mail.internet.MimeMessage; import javax.mail.internet.ParseException; @@ -94,15 +98,19 @@ * <p>Messages written to the input spool have the following Mail Attributes * set if the corresponding condition is satisfied: * <dl> - * <dt>org.apache.james.fetchmail.isRemoteRecipient (java.lang.Boolean)</dt> + * <dt>org.apache.james.fetchmail.isRemoteRecipient</dt> * <dd>The recipient is on a remote host</dd> - * <dt>org.apache.james.fetchmail.isUserUndefined (java.lang.Boolean)</dt> + * <dt>org.apache.james.fetchmail.isUserUndefined</dt> * <dd>The recipient is on a localhost but not defined to James</dd> - * <dt>org.apache.james.fetchmail.isBlacklistedRecipient (java.lang.Boolean)</dt> + * <dt>org.apache.james.fetchmail.isBlacklistedRecipient</dt> * <dd>The recipient is in the configured blacklist</dd> - * <dt>org.apache.james.fetchmail.isRecipientNotFound (java.lang.Boolean)</dt> + * <dt>org.apache.james.fetchmail.isRecipientNotFound</dt> * <dd>The recipient could not be found. Delivery is to the configured recipient. * See the discussion of delivery to a sole intended recipient below.</dd> + * <dt>org.apache.james.fetchmail.isMaxMessageSizeExceeded (java.lang.String)</dt> + * <dd>The message size exceeds the configured limit. An empty message is + * written to the input spool. The Mail Attribute value is a String + * representing the size of the original message in bytes.</dd> * </dl> * * <p>Configuration settings - @@ -120,6 +128,8 @@ * <dd>Rejects recipients on local hosts who are not defined as James users</dd> * <dt>RejectRecipientNotFound</dt> * <dd>See the discussion of delivery to a sole intended recipient below</dd> + * <dt>RejectMaxMessageSizeExceeded</dt> + * <dd>Rejects messages whose size exceeds the configured limit</dd> * </dl> * * <p>Rejection processing is intentionally limited to managing the status of the @@ -134,6 +144,12 @@ * then be used to perform any further processing required, such as notifying * the Postmaster and/or sender, marking the message for error processing, etc.</p> * + * <p>Note that in the case of a message exceeding the message size limit, the + * message that is written to the input spool has no content. This enables + * configuration of a mailet notifying the sender that their mail has not been + * delivered due to its size while maintaining the purpose of the filter which is + * to avoid injecting excessively large messages into the input spool.</p> + * * <p>Delivery is to a sole intended recipient. The recipient is determined in the * following manner:</p> * @@ -197,6 +213,11 @@ */ private boolean fieldUserUndefined = false; + /** + * The Maximum Message has been exceeded + */ + private Boolean fieldMaxMessageSizeExceeded; + /** * Field names for an RFC2822 compliant RECEIVED Header @@ -311,7 +332,7 @@ StringBuffer messageBuffer = new StringBuffer("Intended recipient not found. Using configured recipient as new envelope recipient - "); messageBuffer.append(intendedRecipient); - messageBuffer.append('.'); + messageBuffer.append('.'); logStatusInfo(messageBuffer.toString()); } @@ -320,8 +341,7 @@ setRemoteRecipient(!isLocalServer(intendedRecipient)); setUserUndefined(!isLocalRecipient(intendedRecipient)); - // Check recipient against blacklist / whitelist - // Return if rejected + // Apply the filters. Return if rejected if (isRejectBlacklisted() && isBlacklistedRecipient()) { rejectBlacklistedRecipient(intendedRecipient); @@ -340,6 +360,13 @@ return; } + if (isRejectMaxMessageSizeExceeded() + && isMaxMessageSizeExceeded().booleanValue()) + { + rejectMaxMessageSizeExceeded(getMessageIn().getSize()); + return; + } + // Create the mail // If any of the mail addresses are malformed, we will get a // ParseException. @@ -364,7 +391,8 @@ return; } - createMailAttributes(mail); + addMailAttributes(mail); + addErrorMessages(mail); // If this mail is bouncing move it to the ERROR repository if (isBouncing()) @@ -473,11 +501,38 @@ logStatusInfo(messageBuffer.toString()); return; - } + } /** - * Method createMessage answers a new <code>MimeMessage</code> from the - * fetched message. + * Method rejectMaxMessageSizeExceeded. + * @param message size + * @throws MessagingException + */ + protected void rejectMaxMessageSizeExceeded(int messageSize) + throws MessagingException + { + // Update the flags of the received message + if (!isLeaveMaxMessageSizeExceeded()) + setMessageDeleted(); + + if (isMarkMaxMessageSizeExceededSeen()) + setMessageSeen(); + + StringBuffer messageBuffer = + new StringBuffer("Rejected mail exceeding message size limit. Message size: "); + messageBuffer.append(messageSize/1024); + messageBuffer.append("KB."); + logStatusInfo(messageBuffer.toString()); + + return; + } + + /** + * <p>Method createMessage answers a new <code>MimeMessage</code> from the + * fetched message.</p> + * + * <p>If the maximum message size is exceeded, an empty message is created, + * else the new message is a copy of the received message.</p> * * @return MimeMessage * @throws MessagingException @@ -485,15 +540,48 @@ protected MimeMessage createMessage() throws MessagingException { // Create a new messsage from the received message - MimeMessage messageOut = new MimeMessage(getMessageIn()); + MimeMessage messageOut = null; + if (isMaxMessageSizeExceeded().booleanValue()) + messageOut = createEmptyMessage(); + else + messageOut = new MimeMessage(getMessageIn()); // set the X-fetched headers // Note this is still required to detect bouncing mail and // for backwards compatibility with fetchPop messageOut.addHeader("X-fetched-from", getFetchTaskName()); - - return messageOut; - } + + return messageOut; + } + + /** + * Method createEmptyMessage answers a new + * <code>MimeMessage</code> from the fetched message with the message + * contents removed. + * + * @return MimeMessage + * @throws MessagingException + */ + protected MimeMessage createEmptyMessage() + throws MessagingException + { + // Create an empty messsage + MimeMessage messageOut = new MimeMessage(getSession()); + + // Propogate the headers and subject + Enumeration headersInEnum = getMessageIn().getAllHeaderLines(); + while (headersInEnum.hasMoreElements()) + messageOut.addHeaderLine((String) headersInEnum.nextElement()); + messageOut.setSubject(getMessageIn().getSubject()); + + // Add empty text + messageOut.setText(""); + + // Save + messageOut.saveChanges(); + + return messageOut; + } /** * Method createMail creates a new <code>Mail</code>. @@ -536,6 +624,7 @@ } return mail; } + /** * Method getSender answers a <code>MailAddress</code> for the sender. @@ -582,37 +671,43 @@ String[] headers = getMessageIn().getHeader(RFC2822Headers.RECEIVED); StringBuffer domainBuffer = new StringBuffer(); - // If there are RECEIVED headers and the index to begin at is greater - // than -1, try and extract the domain - if (headers.length > 0 && getRemoteReceivedHeaderIndex() > -1) - { - final String headerTokens = " \n\r"; - - // Search the headers for a domain - for (int headerIndex = - headers.length > getRemoteReceivedHeaderIndex() - ? getRemoteReceivedHeaderIndex() - : headers.length - 1; - headerIndex >= 0 && domainBuffer.length() == 0; - headerIndex--) + // It isn't documented, but getHeader() will answer null if there + // are no matching headers, so we need to check! + if (null != headers) + { + // If there are RECEIVED headers and the index to begin at is greater + // than -1, try and extract the domain + if (headers.length > 0 && getRemoteReceivedHeaderIndex() > -1) { - // Find the "from" token - StringTokenizer tokenizer = - new StringTokenizer(headers[headerIndex], headerTokens); - boolean inFrom = false; - while (!inFrom && tokenizer.hasMoreTokens()) - inFrom = tokenizer.nextToken().equals("from"); - - // Add subsequent tokens to the domain buffer until another - // field is encountered or there are no more tokens - while (inFrom && tokenizer.hasMoreTokens()) + final String headerTokens = " \n\r"; + + // Search the headers for a domain + for (int headerIndex = + headers.length > getRemoteReceivedHeaderIndex() + ? getRemoteReceivedHeaderIndex() + : headers.length - 1; + headerIndex >= 0 && domainBuffer.length() == 0; + headerIndex--) { - String token = tokenizer.nextToken(); - if (inFrom = - getRFC2822RECEIVEDHeaderFields().indexOf(token) == -1) + // Find the "from" token + StringTokenizer tokenizer = + new StringTokenizer(headers[headerIndex], headerTokens); + boolean inFrom = false; + while (!inFrom && tokenizer.hasMoreTokens()) + inFrom = tokenizer.nextToken().equals("from"); + + // Add subsequent tokens to the domain buffer until another + // field is encountered or there are no more tokens + while (inFrom && tokenizer.hasMoreTokens()) { - domainBuffer.append(token); - domainBuffer.append(' '); + String token = tokenizer.nextToken(); + if (inFrom = + getRFC2822RECEIVEDHeaderFields().indexOf(token) + == -1) + { + domainBuffer.append(token); + domainBuffer.append(' '); + } } } } @@ -732,22 +827,24 @@ } /** - * Check if this mail has been bouncing by counting the X-fetched-from headers + * Check if this mail has been bouncing by counting the X-fetched-from + * headers for this task * * @return boolean - */ + */ protected boolean isBouncing() throws MessagingException { Enumeration enum = getMessageIn().getMatchingHeaderLines( new String[] { "X-fetched-from" }); - int count = 1; + int count = 0; while (enum.hasMoreElements()) { - enum.nextElement(); - count++; + String header = (String) enum.nextElement(); + if (header.equals(getFetchTaskName())) + count++; } - return count > 3; + return count >= 3; } /** @@ -1095,12 +1192,12 @@ { fieldUserUndefined = userUndefined; } - + /** - * Creates the mail attributes on a <code>Mail</code>. + * Adds the mail attributes to a <code>Mail</code>. * @param aMail a Mail instance */ - protected void createMailAttributes(Mail aMail) + protected void addMailAttributes(Mail aMail) throws MessagingException { aMail.setAttribute( getAttributePrefix() + "taskName", @@ -1127,7 +1224,30 @@ aMail.setAttribute( getAttributePrefix() + "isRecipientNotFound", null); - } + + if (isMaxMessageSizeExceeded().booleanValue()) + aMail.setAttribute( + getAttributePrefix() + "isMaxMessageSizeExceeded", + new Integer(getMessageIn().getSize()).toString()); + } + + /** + * Adds any required error messages to a <code>Mail</code>. + * @param aMail a Mail instance + */ + protected void addErrorMessages(Mail mail) throws MessagingException + { + if (isMaxMessageSizeExceeded().booleanValue()) + { + StringBuffer msgBuffer = + new StringBuffer("550 - Rejected - This message has been rejected as the message size of "); + msgBuffer.append(getMessageIn().getSize() * 1000 / 1024 / 1000f); + msgBuffer.append("KB exceeds the maximum permitted size of "); + msgBuffer.append(getMaxMessageSizeLimit() / 1024); + msgBuffer.append("KB."); + mail.setErrorMessage(msgBuffer.toString()); + } + } /** * Sets the Blacklisted. @@ -1339,6 +1459,59 @@ public static String getRFC2822RECEIVEDHeaderFields() { return fieldRFC2822RECEIVEDHeaderFields; + } + + /** + * Returns the maxMessageSizeExceeded, lazily initialised as required. + * @return Boolean + */ + protected Boolean isMaxMessageSizeExceeded() throws MessagingException + { + Boolean isMaxMessageSizeExceeded = null; + if (null + == (isMaxMessageSizeExceeded = isMaxMessageSizeExceededBasic())) + { + updateMaxMessageSizeExceeded(); + return isMaxMessageSizeExceeded(); + } + return isMaxMessageSizeExceeded; + } + + /** + * Refreshes the maxMessageSizeExceeded. + */ + protected void updateMaxMessageSizeExceeded() throws MessagingException + { + setMaxMessageSizeExceeded(computeMaxMessageSizeExceeded()); + } + + /** + * Compute the maxMessageSizeExceeded. + * @return Boolean + */ + protected Boolean computeMaxMessageSizeExceeded() throws MessagingException + { + if (0 == getMaxMessageSizeLimit()) + return Boolean.FALSE; + return new Boolean(getMessageIn().getSize() > getMaxMessageSizeLimit()); + } + + /** + * Returns the maxMessageSizeExceeded. + * @return Boolean + */ + private Boolean isMaxMessageSizeExceededBasic() + { + return fieldMaxMessageSizeExceeded; + } + + /** + * Sets the maxMessageSizeExceeded. + * @param maxMessageSizeExceeded The maxMessageSizeExceeded to set + */ + protected void setMaxMessageSizeExceeded(Boolean maxMessageSizeExceeded) + { + fieldMaxMessageSizeExceeded = maxMessageSizeExceeded; } } 1.1.2.4 +29 -29 james-server/src/java/org/apache/james/fetchmail/Attic/FolderProcessor.java Index: FolderProcessor.java =================================================================== RCS file: /home/cvs/james-server/src/java/org/apache/james/fetchmail/Attic/FolderProcessor.java,v retrieving revision 1.1.2.3 retrieving revision 1.1.2.4 diff -u -r1.1.2.3 -r1.1.2.4 --- FolderProcessor.java 20 Oct 2003 03:43:26 -0000 1.1.2.3 +++ FolderProcessor.java 9 Feb 2004 16:15:45 -0000 1.1.2.4 @@ -66,9 +66,9 @@ import javax.mail.internet.MimeMessage; /** - * <p>Class <code>FolderProcessor</code> opens a Folder, fetches the Envelopes for - * each Message and then iterates over all of the Messages, delegating their - * processing to <code>MessageProcessor</code>.</p> + * <p>Class <code>FolderProcessor</code> opens a Folder and iterates over all + * of the Messages, delegating their processing to + * <code>MessageProcessor</code>.</p> * * <p>If isRecurse(), all subfolders are fetched recursively.</p> * @@ -105,6 +105,7 @@ public void process() throws MessagingException { int messagesProcessed = 0; + int messageCount = 0; try { // open the folder @@ -119,34 +120,31 @@ throw ex; } - // Fetch the Envelopes from the folder - // Note that the fetch profile causes the envelope contents - // for all of the messages to be bulk fetched. This is an - // efficiency measure as we know we are going to read each envelope. - Message[] messagesIn = getFolder().getMessages(); - FetchProfile fp = new FetchProfile(); - fp.add(FetchProfile.Item.ENVELOPE); - getFolder().fetch(messagesIn, fp); - - // Process each message - for (int i = 0; i < messagesIn.length; i++) + // Lock the folder while processing each message + synchronized (getFolder()) { - MimeMessage message = (MimeMessage) messagesIn[i]; - if (isFetchAll() || !isSeen(message)) + messageCount = getFolder().getMessageCount(); + for (int i = 1; i <= messageCount; i++) { - try - { - new MessageProcessor(message, getAccount()).process(); - messagesProcessed++; - } - // Catch and report an exception but don't rethrow it, - // allowing subsequent messages to be processed. - catch (MessagingException mex) + MimeMessage message = + (MimeMessage) getFolder().getMessage(i); + if (isFetchAll() || !isSeen(message)) { - StringBuffer logMessageBuffer = - new StringBuffer("MessagingException processing message ID: "); - logMessageBuffer.append(message.getMessageID()); - getLogger().error(logMessageBuffer.toString(), mex); + try + { + new MessageProcessor(message, getAccount()) + .process(); + messagesProcessed++; + } + // Catch and report an exception but don't rethrow it, + // allowing subsequent messages to be processed. + catch (Exception ex) + { + StringBuffer logMessageBuffer = + new StringBuffer("Exception processing message ID: "); + logMessageBuffer.append(message.getMessageID()); + getLogger().error(logMessageBuffer.toString(), ex); + } } } } @@ -170,7 +168,9 @@ } StringBuffer logMessageBuffer = new StringBuffer("Processed "); logMessageBuffer.append(messagesProcessed); - logMessageBuffer.append(" messages in folder '"); + logMessageBuffer.append(" messages of "); + logMessageBuffer.append(messageCount); + logMessageBuffer.append(" in folder '"); logMessageBuffer.append(getFolder().getName()); logMessageBuffer.append("'"); getLogger().info(logMessageBuffer.toString()); 1.1.2.4 +46 -0 james-server/src/java/org/apache/james/fetchmail/Attic/ProcessorAbstract.java Index: ProcessorAbstract.java =================================================================== RCS file: /home/cvs/james-server/src/java/org/apache/james/fetchmail/Attic/ProcessorAbstract.java,v retrieving revision 1.1.2.3 retrieving revision 1.1.2.4 diff -u -r1.1.2.3 -r1.1.2.4 --- ProcessorAbstract.java 20 Oct 2003 03:43:26 -0000 1.1.2.3 +++ ProcessorAbstract.java 9 Feb 2004 16:15:45 -0000 1.1.2.4 @@ -62,6 +62,7 @@ import java.util.Set; import javax.mail.MessagingException; +import javax.mail.Session; import org.apache.avalon.framework.logger.Logger; import org.apache.james.services.MailServer; @@ -224,6 +225,15 @@ } /** + * Returns the session. + * @return Session + */ + protected Session getSession() + { + return getAccount().getSession(); + } + + /** * Returns the repository of local users. * @return UsersRepository */ @@ -319,6 +329,15 @@ } /** + * Returns the LeaveMaxMessageSizeExceeded. + * @return boolean + */ + protected boolean isLeaveMaxMessageSizeExceeded() + { + return getConfiguration().isLeaveMaxMessageSizeExceeded(); + } + + /** * Returns the leaveUndeliverable. * @return boolean */ @@ -337,6 +356,15 @@ } /** + * Returns the RejectMaxMessageSizeExceeded. + * @return boolean + */ + protected boolean isRejectMaxMessageSizeExceeded() + { + return getConfiguration().isRejectMaxMessageSizeExceeded(); + } + + /** * Returns the RejectUserBlacklisted. * @return boolean */ @@ -409,6 +437,15 @@ } /** + * Returns the MarkMaxMessageSizeExceededSeen. + * @return boolean + */ + protected boolean isMarkMaxMessageSizeExceededSeen() + { + return getConfiguration().isMarkMaxMessageSizeExceededSeen(); + } + + /** * Returns the markUndeliverableSeen. * @return boolean */ @@ -532,5 +569,14 @@ { fieldAccount = account; } + + /** + * Returns the getMaxMessageSizeLimit. + * @return int + */ + protected int getMaxMessageSizeLimit() + { + return getConfiguration().getMaxMessageSizeLimit(); + } } 1.1.2.5 +1 -36 james-server/src/java/org/apache/james/fetchmail/Attic/StoreProcessor.java Index: StoreProcessor.java =================================================================== RCS file: /home/cvs/james-server/src/java/org/apache/james/fetchmail/Attic/StoreProcessor.java,v retrieving revision 1.1.2.4 retrieving revision 1.1.2.5 diff -u -r1.1.2.4 -r1.1.2.5 --- StoreProcessor.java 20 Oct 2003 03:43:26 -0000 1.1.2.4 +++ StoreProcessor.java 9 Feb 2004 16:15:45 -0000 1.1.2.5 @@ -72,31 +72,15 @@ public class StoreProcessor extends ProcessorAbstract { /** - * The Session to use. - */ - private Session fieldSession; - - /** * Constructor for StoreProcessor. * @param account */ - private StoreProcessor(Account account) + protected StoreProcessor(Account account) { super(account); } /** - * Constructor for StoreProcessor. - * @param account - * @param session - */ - protected StoreProcessor(Account account, Session session) - { - this(account); - setSession(session); - } - - /** * Method process connects to a Folder in a Message Store, creates a * <code>FolderProcessor</code> and runs it to process the messages in * the Folder. @@ -106,7 +90,6 @@ public void process() throws MessagingException { Store store = null; - Session session = null; Folder folder = null; StringBuffer logMessageBuffer = @@ -170,24 +153,6 @@ logMessageBuffer.append("'"); getLogger().info(logMessageBuffer.toString()); } - } - - /** - * Returns the session. - * @return Session - */ - protected Session getSession() - { - return fieldSession; - } - - /** - * Sets the session. - * @param session The session to set - */ - protected void setSession(Session session) - { - fieldSession = session; } } 1.1.2.2 +27 -7 james-server/src/java/org/apache/james/fetchmail/Attic/DynamicAccount.java Index: DynamicAccount.java =================================================================== RCS file: /home/cvs/james-server/src/java/org/apache/james/fetchmail/Attic/DynamicAccount.java,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -u -r1.1.2.1 -r1.1.2.2 --- DynamicAccount.java 22 Sep 2003 13:09:12 -0000 1.1.2.1 +++ DynamicAccount.java 9 Feb 2004 16:15:45 -0000 1.1.2.2 @@ -58,6 +58,8 @@ package org.apache.james.fetchmail; +import javax.mail.Session; + import org.apache.avalon.framework.configuration.ConfigurationException; public class DynamicAccount extends Account @@ -71,18 +73,27 @@ * @param password * @param recipient * @param ignoreRecipientHeader + * @param session * @throws ConfigurationException */ private DynamicAccount( int sequenceNumber, - ParsedConfiguration parsedConfiguration, + ParsedConfiguration parsedConfiguration, String user, String password, String recipient, - boolean ignoreRecipientHeader) + boolean ignoreRecipientHeader, + Session session) throws ConfigurationException { - super(sequenceNumber, parsedConfiguration, user, password, recipient, ignoreRecipientHeader); + super( + sequenceNumber, + parsedConfiguration, + user, + password, + recipient, + ignoreRecipientHeader, + session); } /** @@ -96,21 +107,30 @@ * @param recipientPrefix * @param recipientSuffix * @param ignoreRecipientHeader + * @param session * @throws ConfigurationException */ public DynamicAccount( int sequenceNumber, - ParsedConfiguration parsedConfiguration, + ParsedConfiguration parsedConfiguration, String userName, String userPrefix, String userSuffix, - String password, + String password, String recipientPrefix, String recipientSuffix, - boolean ignoreRecipientHeader) + boolean ignoreRecipientHeader, + Session session) throws ConfigurationException { - this(sequenceNumber, parsedConfiguration, null, password, null, ignoreRecipientHeader); + this( + sequenceNumber, + parsedConfiguration, + null, + password, + null, + ignoreRecipientHeader, + session); StringBuffer userBuffer = new StringBuffer(userPrefix); userBuffer.append(userName); No revision No revision 1.1.2.6 +20 -0 james-server/src/conf/Attic/james-fetchmail.xml Index: james-fetchmail.xml =================================================================== RCS file: /home/cvs/james-server/src/conf/Attic/james-fetchmail.xml,v retrieving revision 1.1.2.5 retrieving revision 1.1.2.6 diff -u -r1.1.2.5 -r1.1.2.6 --- james-fetchmail.xml 23 Oct 2003 18:59:32 -0000 1.1.2.5 +++ james-fetchmail.xml 9 Feb 2004 16:15:45 -0000 1.1.2.6 @@ -130,6 +130,26 @@ <!-- if true, messages left on the server will be marked as seen --> <!-- if false, messages left on the server will not be marked as seen --> <fetched leaveonserver="false" markseen="true"/> + + <!-- Specify what happens to messages whose size exceeds the specified limit. --> + <!-- This tag is optional. If omitted, there is no limit. --> + <!-- limit --> + <!-- The maximum message size in Kilobytes of messages injected into James. --> + <!-- A value of 0 means no limit. --> + <!-- reject --> + <!-- if true, messages whose size exceeds the limit will be rejected --> + <!-- if false, messages whose size exceeds the limit will be stripped of their message bodies --> + <!-- prior to injection into James and the MailAttribute "org.apache.james.fetchmail.isMaxMessageSizeExceeded" --> + <!-- will be added to the message with the value set to the original message size in bytes. --> + <!-- Use the HasMailAttribute matcher to detect them. --> + <!-- The following apply if reject="true" and a message is rejected... --> + <!-- leaveonserver --> + <!-- if true, messages will be left on the server --> + <!-- if false, messages will be deleted from the server --> + <!-- markseen --> + <!-- if true, messages left on the server will be marked as seen --> + <!-- if false, messages left on the server will not be marked as seen --> + <maxmessagesize limit=0 reject="false" leaveonserver="true" markseen="false"/> <!-- Specify what happens to undeliverable messages --> <!-- leaveonserver --> No revision No revision 1.1.2.4 +45 -0 james-server/src/xdocs/Attic/fetchmail_configuration_2_2.xml Index: fetchmail_configuration_2_2.xml =================================================================== RCS file: /home/cvs/james-server/src/xdocs/Attic/fetchmail_configuration_2_2.xml,v retrieving revision 1.1.2.3 retrieving revision 1.1.2.4 diff -u -r1.1.2.3 -r1.1.2.4 --- fetchmail_configuration_2_2.xml 20 Oct 2003 03:43:27 -0000 1.1.2.3 +++ fetchmail_configuration_2_2.xml 9 Feb 2004 16:15:45 -0000 1.1.2.4 @@ -128,6 +128,7 @@ <li><strong><a href="#javaMailFolderName">javaMailFolderName</a></strong> (1, 1)</li> <li><strong><a href="#javaMailProperties">javaMailProperties</a></strong> (0, 1)</li> <li><strong><a href="#javaMailProviderName">javaMailProviderName</a></strong> (1, 1)</li> +<li><strong><a href="#maxmessagesize">maxmessagesize</a></strong> (0, 1)</li> <li><strong><a href="#recipientnotfound">recipientnotfound</a></strong> (1, 1)</li> <li><strong><a href="#recursesubfolders">recursesubfolders</a></strong> (1, 1)</li> <li><strong><a href="#remoteReceivedHeaderIndex">remoteReceivedHeaderIndex</a></strong> (0, 1)</li> @@ -358,6 +359,50 @@ <source> <javaMailProviderName>pop3</javaMailProviderName> </source> +</p> +</subsection> + +<subsection name="maxmessagesize"> +<p>The <strong>maxmessagesize</strong> tag declares the maximum permitted message +size for messages injected into the James input spool and what happens to fetched +messages that exceed this size.</p> +<p>The tag has these attributes: +<dl> +<dt><strong>limit</strong></dt> +<dd>An integer. The maximum message size expressed in Kilobytes. If 0, there is +no limit.</dd> +<dt><strong>reject</strong></dt> +<dd>A boolean. If "true", mail whose message size exceeds the maximum +permitted size will not be injected into the James input spool. If +"false", mail whose message size exceeds the maximum permitted size will +have its contents removed, an explanatory error message and the Mail Attribute +<code>org.apache.james.fetchmail.isMaxMessageSizeExceeded</code> added prior to +injection into the James input spool, (see below for the location of an example).</dd> +<dt><strong>leaveonserver</strong></dt> +<dd>A boolean. If "true", mail whose message size exceeds the maximum +permitted size will be left on the server. If "false", mail whose message +size exceeds the maximum permitted size will be marked for deletion.</dd> +<dt><strong>markseen</strong></dt> +<dd>A boolean. If "true", mail whose message size exceeds the maximum +permitted size will be marked as seen on the server. If "false", +mail whose message size exceeds the maximum permitted size will not be marked as +seen.</dd> +</dl> +</p> + +<p> +<source> +<maxmessagesize + limit="4096" + reject="false" + leaveonserver="false" + markseen="false"/> +</source> +</p> + +<p>An example configuration using James mailet processing to bounce fetched +messages that exceed the maximum permitted size can be found in the file +<code>$PHOENIX_HOME/apps/james/conf/samples/fetchmail/maxMessageSize.xml</code>. </p> </subsection> No revision No revision 1.1.2.1 +105 -0 james-server/src/conf/samples/fetchmail/Attic/maxMessageSize.xml
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]