james-server-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pgoldst...@apache.org
Subject cvs commit: jakarta-james/src/java/org/apache/james/transport/mailets RemoteDelivery.java
Date Sat, 14 Sep 2002 07:25:00 GMT
pgoldstein    2002/09/14 00:25:00

  Modified:    src/java/org/apache/james BaseConnectionHandler.java
               src/java/org/apache/james/smtpserver SMTPHandler.java
                        SMTPServer.java
               src/java/org/apache/james/transport/mailets
                        RemoteDelivery.java
  Log:
  Patched a bug with the earlier mailet context change (Thanks to Noel Bergman).
  Added more complex option parsing for SMTP MAIL and RCPT commands as a precursor to later
extension support.
  Changed SMTPHandler.java to use RFC2822Headers
  
  Revision  Changes    Path
  1.11      +22 -10    jakarta-james/src/java/org/apache/james/BaseConnectionHandler.java
  
  Index: BaseConnectionHandler.java
  ===================================================================
  RCS file: /home/cvs/jakarta-james/src/java/org/apache/james/BaseConnectionHandler.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- BaseConnectionHandler.java	19 Aug 2002 18:57:07 -0000	1.10
  +++ BaseConnectionHandler.java	14 Sep 2002 07:25:00 -0000	1.11
  @@ -36,28 +36,40 @@
       protected String helloName;
   
       /**
  -     * Pass the <code>Configuration</code> to the instance.
  +     * Get the hello name for this server
        *
  -     * @param configuration the class configurations.
  -     * @throws ConfigurationException if an error occurs
  +     * @param configuration a configuration object containing server name configuration
info
  +     * @return the hello name for this server
        */
  -    public void configure( final Configuration configuration )
  +    public static String configHelloName(final Configuration configuration)
           throws ConfigurationException {
  -
  -        timeout = configuration.getChild( "connectiontimeout" ).getValueAsInteger( 1800000
);
           String hostName = null;
  +
           try {
               hostName = InetAddress.getLocalHost().getHostName();
           } catch  (UnknownHostException ue) {
  +            // Default to localhost if we can't get the local host name.
               hostName = "localhost";
           }
   
           Configuration helloConf = configuration.getChild("helloName");
           boolean autodetect = helloConf.getAttributeAsBoolean("autodetect", true);
  -        if (autodetect)
  -            helloName = hostName;
  -        else
  -            helloName = helloConf.getValue("localhost");
  +
  +        return autodetect ? hostName : helloConf.getValue("localhost");
  +    }
  +
  +
  +    /**
  +     * Pass the <code>Configuration</code> to the instance.
  +     *
  +     * @param configuration the class configurations.
  +     * @throws ConfigurationException if an error occurs
  +     */
  +    public void configure( final Configuration configuration )
  +        throws ConfigurationException {
  +
  +        timeout = configuration.getChild( "connectiontimeout" ).getValueAsInteger( 1800000
);
  +        helloName = configHelloName(configuration);
           getLogger().info("Hello Name is: " + helloName);
       }
   
  
  
  
  1.25      +98 -48    jakarta-james/src/java/org/apache/james/smtpserver/SMTPHandler.java
  
  Index: SMTPHandler.java
  ===================================================================
  RCS file: /home/cvs/jakarta-james/src/java/org/apache/james/smtpserver/SMTPHandler.java,v
  retrieving revision 1.24
  retrieving revision 1.25
  diff -u -r1.24 -r1.25
  --- SMTPHandler.java	11 Sep 2002 07:30:41 -0000	1.24
  +++ SMTPHandler.java	14 Sep 2002 07:25:00 -0000	1.25
  @@ -10,7 +10,6 @@
   import org.apache.avalon.cornerstone.services.scheduler.PeriodicTimeTrigger;
   import org.apache.avalon.cornerstone.services.scheduler.Target;
   import org.apache.avalon.cornerstone.services.scheduler.TimeScheduler;
  -import org.apache.avalon.framework.activity.Initializable;
   import org.apache.avalon.framework.component.ComponentException;
   import org.apache.avalon.framework.component.ComponentManager;
   import org.apache.avalon.framework.component.Composable;
  @@ -26,7 +25,6 @@
   import org.apache.james.services.UsersStore;
   import org.apache.james.util.*;
   import org.apache.mailet.MailAddress;
  -import org.apache.mailet.MailetContext;
   import javax.mail.MessagingException;
   import java.io.*;
   import java.net.Socket;
  @@ -48,7 +46,7 @@
    */
   public class SMTPHandler
       extends BaseConnectionHandler
  -    implements ConnectionHandler, Composable, Configurable, Initializable, Target {
  +    implements ConnectionHandler, Composable, Configurable, Target {
   
       /**
        * SMTP Server identification string used in SMTP headers
  @@ -127,11 +125,6 @@
   
       private MailServer mailServer;      // The internal mail server service
   
  -    /**
  -     * The system-wide component manager
  -     */
  -    private ComponentManager componentManager;
  -
       private HashMap state = new HashMap();  // The hash map that holds variables for the
SMTP
                                               // session in progress.
   
  @@ -152,7 +145,6 @@
           UsersStore usersStore =
               (UsersStore) componentManager.lookup("org.apache.james.services.UsersStore");
           users = usersStore.getRepository("LocalUsers");
  -        this.componentManager = componentManager;
        }
   
       /**
  @@ -176,19 +168,6 @@
       }
   
       /**
  -     * Initialize the component. In the SMTPHandler this looks up the mailet
  -     * context and sets the appropriate value for the hello name.
  -     *
  -     * @throws Exception if an error occurs
  -     */
  -    public void initialize() throws Exception {
  -        // make our "helloName" available through the MailetContext
  -        MailetContext mailetcontext
  -                = (MailetContext) componentManager.lookup("org.apache.mailet.MailetContext");
  -        mailetcontext.setAttribute(Constants.HELLO_NAME, this.helloName);
  -    }
  -
  -    /**
        * Handle a connection.
        * This handler is responsible for processing connections as they occur.
        *
  @@ -663,33 +642,72 @@
           } else {
               String sender = argument1.trim();
               int lastChar = sender.lastIndexOf('>');
  -            if (sender.length() > lastChar + 1) {
  -                //handle a SIZE=### command if it's sent
  -                String cmdString = sender.substring(lastChar + 1).trim();
  -                if (cmdString.toUpperCase(Locale.US).startsWith("SIZE")) {
  -                    try {
  -                        int size =
  -                            Integer.parseInt(cmdString.substring(cmdString.indexOf('=')
+ 1));
  -                        if (maxmessagesize > 0 && size > maxmessagesize)
{
  +            // Check to see if any options are present and, if so, whether they are correctly
formatted
  +            // (separated from the closing angle bracket by a ' ').
  +            if ((lastChar > 0) && (sender.length() > lastChar + 2) &&
(sender.charAt(lastChar + 1) == ' ')) {
  +                String mailOptionString = sender.substring(lastChar + 2);
  +
  +                // Remove the options from the sender
  +                sender = sender.substring(0, lastChar + 1);
  +
  +                StringTokenizer optionTokenizer = new StringTokenizer(mailOptionString,
" ");
  +                while (optionTokenizer.hasMoreElements()) {
  +                    String mailOption = optionTokenizer.nextToken();
  +                    int equalIndex = mailOptionString.indexOf('=');
  +                    String mailOptionName = mailOption;
  +                    String mailOptionValue = "";
  +                    if (equalIndex > 0) {
  +                        mailOptionName = mailOption.substring(0, (equalIndex - 1)).toUpperCase(Locale.US);
  +                        mailOptionValue = mailOption.substring(equalIndex + 1);
  +                    }
  +
  +                    // Handle the SIZE extension keyword
   
  +                    // TODO: Encapsulate option logic in a method
  +                    if (mailOptionName.startsWith("SIZE")) {
  +                        int size = 0;
  +                        try {
  +                            size = Integer.parseInt(mailOptionValue);
  +                        } catch (NumberFormatException pe) {
  +                            // This is a malformed option value.  We ignore it
  +                            // and proceed to the next option.
  +                            continue;
  +                        }
  +                        if (getLogger().isDebugEnabled()) {
  +                            StringBuffer debugBuffer = 
  +                                new StringBuffer(128)
  +                                    .append("MAIL command option SIZE received with value
")
  +                                    .append(size)
  +                                    .append(".");
  +                            getLogger().debug(debugBuffer.toString());
  +                        }
  +                        if ((maxmessagesize > 0) && (size > maxmessagesize))
{
  +                            // Let the client know that the size limit has been hit.
                               responseString = "552 Message size exceeds fixed maximum message
size";
  -                            //let the client know that the size limit has been hit.
                               out.println(responseString);
  -
  +                            out.flush();
  +    
                               logResponseString(responseString);
                               getLogger().error(responseString);
                               return;
                           } else {
  -                            //put the message size in the message state so it can be used
  -                            //  later to restrict messages for user quotas, etc.
  +                            // put the message size in the message state so it can be used
  +                            // later to restrict messages for user quotas, etc.
                               state.put(MESG_SIZE, new Integer(size));
                           }
  -                    } catch (Exception e) {
  -                        // TODO: Comment what specific exceptions this is handling
  +                    } else {
  +                        // Unexpected option attached to the Mail command
  +                        if (getLogger().isDebugEnabled()) {
  +                            StringBuffer debugBuffer = 
  +                                new StringBuffer(128)
  +                                    .append("MAIL command had unrecognized/unexpected option
")
  +                                    .append(mailOptionName)
  +                                    .append(" with value ")
  +                                    .append(mailOptionValue);
  +                            getLogger().debug(debugBuffer.toString());
  +                        }
                       }
                   }
  -                //cut off the extra bit in the sender string
  -                sender = sender.substring(0, lastChar + 1);
               }
               if (!sender.startsWith("<") || !sender.endsWith(">")) {
                   responseString = "501 Syntax error in parameters or arguments";
  @@ -768,9 +786,41 @@
                   rcptColl = new Vector();
               }
               String recipient = argument1.trim();
  +            int lastChar = recipient.lastIndexOf('>');
  +            // Check to see if any options are present and, if so, whether they are correctly
formatted
  +            // (separated from the closing angle bracket by a ' ').
  +            if ((lastChar > 0) && (recipient.length() > lastChar + 2) &&
(recipient.charAt(lastChar + 1) == ' ')) {
  +                String rcptOptionString = recipient.substring(lastChar + 2);
  +
  +                // Remove the options from the recipient
  +                recipient = recipient.substring(0, lastChar + 1);
  +
  +                StringTokenizer optionTokenizer = new StringTokenizer(rcptOptionString,
" ");
  +                while (optionTokenizer.hasMoreElements()) {
  +                    String rcptOption = optionTokenizer.nextToken();
  +                    int equalIndex = rcptOptionString.indexOf('=');
  +                    String rcptOptionName = rcptOption;
  +                    String rcptOptionValue = "";
  +                    if (equalIndex > 0) {
  +                        rcptOptionName = rcptOption.substring(0, (equalIndex - 1)).toUpperCase(Locale.US);
  +                        rcptOptionValue = rcptOption.substring(equalIndex + 1);
  +                    }
  +                    // Unexpected option attached to the RCPT command
  +                    if (getLogger().isDebugEnabled()) {
  +                        StringBuffer debugBuffer = 
  +                            new StringBuffer(128)
  +                                .append("RCPT command had unrecognized/unexpected option
")
  +                                .append(rcptOptionName)
  +                                .append(" with value ")
  +                                .append(rcptOptionValue);
  +                        getLogger().debug(debugBuffer.toString());
  +                    }
  +                }
  +            }
               if (!recipient.startsWith("<") || !recipient.endsWith(">")) {
                   responseString = "501 Syntax error in parameters or arguments";
                   out.println(responseString);
  +                out.flush();
                   logResponseString(responseString);
                   if (getLogger().isErrorEnabled()) {
                       StringBuffer errorBuffer = 
  @@ -950,15 +1000,15 @@
                   MailHeaders headers = new MailHeaders(msgIn);
                   // if headers do not contains minimum REQUIRED headers fields,
                   // add them
  -                if (!headers.isSet("Date")) {
  -                    headers.setHeader("Date", rfc822DateFormat.format(new Date()));
  +                if (!headers.isSet(RFC2822Headers.DATE)) {
  +                    headers.setHeader(RFC2822Headers.DATE, rfc822DateFormat.format(new
Date()));
                   }
  -                if (!headers.isSet("From") && state.get(SENDER) != null) {
  -                    headers.setHeader("From", state.get(SENDER).toString());
  +                if (!headers.isSet(RFC2822Headers.FROM) && state.get(SENDER) !=
null) {
  +                    headers.setHeader(RFC2822Headers.FROM, state.get(SENDER).toString());
                   }
                   //Determine the Return-Path
  -                String returnPath = headers.getHeader("Return-Path", "\r\n");
  -                headers.removeHeader("Return-Path");
  +                String returnPath = headers.getHeader(RFC2822Headers.RETURN_PATH, "\r\n");
  +                headers.removeHeader(RFC2822Headers.RETURN_PATH);
                   if (returnPath == null) {
                       if (state.get(SENDER) == null) {
                           returnPath = "<>";
  @@ -976,11 +1026,11 @@
                   Enumeration headerLines = headers.getAllHeaderLines();
                   headers = new MailHeaders();
                   //Put the Return-Path first
  -                headers.addHeaderLine("Return-Path" + ": " + returnPath);
  +                headers.addHeaderLine(RFC2822Headers.RETURN_PATH + ": " + returnPath);
                   //Put our Received header next
                   StringBuffer headerLineBuffer = 
                       new StringBuffer(128)
  -                            .append("Received" + ": from ")
  +                            .append(RFC2822Headers.RECEIVED + ": from ")
                               .append(state.get(REMOTE_NAME))
                               .append(" ([")
                               .append(state.get(REMOTE_IP))
  
  
  
  1.10      +35 -1     jakarta-james/src/java/org/apache/james/smtpserver/SMTPServer.java
  
  Index: SMTPServer.java
  ===================================================================
  RCS file: /home/cvs/jakarta-james/src/java/org/apache/james/smtpserver/SMTPServer.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- SMTPServer.java	15 Aug 2002 21:37:34 -0000	1.9
  +++ SMTPServer.java	14 Sep 2002 07:25:00 -0000	1.10
  @@ -10,10 +10,15 @@
   import org.apache.avalon.cornerstone.services.connection.AbstractService;
   import org.apache.avalon.cornerstone.services.connection.ConnectionHandlerFactory;
   import org.apache.avalon.cornerstone.services.connection.DefaultHandlerFactory;
  +import org.apache.avalon.framework.component.ComponentException;
  +import org.apache.avalon.framework.component.ComponentManager;
   import org.apache.avalon.framework.configuration.Configuration;
   import org.apache.avalon.framework.configuration.ConfigurationException;
   import org.apache.avalon.framework.component.Component;
   
  +import org.apache.mailet.MailetContext;
  +import org.apache.james.Constants;
  +
   import java.net.InetAddress;
   import java.net.UnknownHostException;
   
  @@ -27,14 +32,39 @@
    * @author  Matthew Pangaro <mattp@lokitech.com>
    * @author  <a href="mailto:donaldp@apache.org">Peter Donald</a>
    */
  +
  +/*
  + * IMPORTANT: SMTPServer extends AbstractService.  If you implement ANY
  + * lifecycle methods, you MUST call super.<method> as well.
  + */
  +
   public class SMTPServer
       extends AbstractService implements Component {
   
  +    /**
  +     * The mailet context - we access it here to set the hello name for the Mailet API
  +     */
  +    MailetContext mailetcontext;
  +
       protected ConnectionHandlerFactory createFactory()
       {
           return new DefaultHandlerFactory( SMTPHandler.class );
       }
   
  +     /**
  +      * Pass the <code>ComponentManager</code> to the <code>composer</code>.
  +      * The instance uses the specified <code>ComponentManager</code> to 
  +      * acquire the components it needs for execution.
  +      *
  +      * @param componentManager The <code>ComponentManager</code> which this
  +      *                <code>Composable</code> uses.
  +      * @throws ComponentException if an error occurs
  +      */
  +     public void compose(final ComponentManager componentManager) throws ComponentException
{
  +         super.compose(componentManager);
  +         mailetcontext = (MailetContext) componentManager.lookup("org.apache.mailet.MailetContext");
  +     }
  +
       /**
        * Pass the <code>Configuration</code> to the instance.
        *
  @@ -64,7 +94,11 @@
               m_serverSocketType = "ssl";
           }
   
  -       super.configure( configuration.getChild( "handler" ) );
  +        super.configure( configuration.getChild( "handler" ) );
  +
  +        // make our "helloName" available through the MailetContext
  +        String helloName = SMTPHandler.configHelloName(configuration.getChild( "handler"
));
  +        mailetcontext.setAttribute(Constants.HELLO_NAME, helloName);
       }
   
       /**
  
  
  
  1.25      +16 -2     jakarta-james/src/java/org/apache/james/transport/mailets/RemoteDelivery.java
  
  Index: RemoteDelivery.java
  ===================================================================
  RCS file: /home/cvs/jakarta-james/src/java/org/apache/james/transport/mailets/RemoteDelivery.java,v
  retrieving revision 1.24
  retrieving revision 1.25
  diff -u -r1.24 -r1.25
  --- RemoteDelivery.java	23 Aug 2002 08:53:36 -0000	1.24
  +++ RemoteDelivery.java	14 Sep 2002 07:25:00 -0000	1.25
  @@ -497,6 +497,20 @@
        * there are any
        */
       public void run() {
  +
  +        /* TODO: CHANGE ME!!! The problem is that we need to wait for James to
  +         * finish initializing.  We expect the HELLO_NAME to be put into
  +         * the MailetContext, but in the current configuration we get
  +         * started before the SMTP Server, which establishes the value.
  +         * Since there is no contractual guarantee that there will be a
  +         * HELLO_NAME value, we can't just wait for it.  As a temporary
  +         * measure, I'm inserting this philosophically unsatisfactory
  +         * fix.
  +         */
  +        try {
  +            Thread.sleep(5000);
  +        } catch (Exception ignored) {} // wait for James to finish initializing
  +
           //Checks the pool and delivers a mail message
           Properties props = new Properties();
           //Not needed for production environment
  
  
  

--
To unsubscribe, e-mail:   <mailto:james-dev-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:james-dev-help@jakarta.apache.org>


Mime
View raw message