You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by ba...@apache.org on 2006/01/03 11:53:19 UTC

svn commit: r365604 - in /james/server/trunk/src: java/org/apache/james/pop3server/ test/org/apache/james/pop3server/ test/org/apache/james/test/mock/avalon/ test/org/apache/james/test/mock/james/

Author: bago
Date: Tue Jan  3 02:53:07 2006
New Revision: 365604

URL: http://svn.apache.org/viewcvs?rev=365604&view=rev
Log:
Removed superflous CRLF at the end of POP3 messages (POP3 protocol compliance), Changed pop3 stream from InputStream to RawInputStream.
I'm not sure this is correct but the RFC simply doesn't talk of message decoding and this change allow for malformed messages to be transmitted correctly (fixes JAMES-328)
Added a few ristretto tests for POP3 (and the proof for JAMES-328). Added finally clause to the pop3 TOP and RETR clauses to always send "." at the end of the response.

Added:
    james/server/trunk/src/test/org/apache/james/pop3server/POP3ServerTest.java
    james/server/trunk/src/test/org/apache/james/pop3server/POP3TestConfiguration.java
Modified:
    james/server/trunk/src/java/org/apache/james/pop3server/POP3Handler.java
    james/server/trunk/src/test/org/apache/james/test/mock/avalon/MockLogger.java
    james/server/trunk/src/test/org/apache/james/test/mock/james/MockMailRepository.java
    james/server/trunk/src/test/org/apache/james/test/mock/james/MockMailServer.java

Modified: james/server/trunk/src/java/org/apache/james/pop3server/POP3Handler.java
URL: http://svn.apache.org/viewcvs/james/server/trunk/src/java/org/apache/james/pop3server/POP3Handler.java?rev=365604&r1=365603&r2=365604&view=diff
==============================================================================
--- james/server/trunk/src/java/org/apache/james/pop3server/POP3Handler.java (original)
+++ james/server/trunk/src/java/org/apache/james/pop3server/POP3Handler.java Tue Jan  3 02:53:07 2006
@@ -893,17 +893,18 @@
                 if (mc != DELETED) {
                     responseString = OK_RESPONSE + " Message follows";
                     writeLoggedFlushedResponse(responseString);
-                    OutputStream nouts =
-                            new ExtraDotOutputStream(outs);
-                    nouts = new BytesWrittenResetOutputStream(nouts,
-                                                              theWatchdog,
-                                                              theConfigData.getResetLength());
-                    mc.getMessage().writeTo(nouts);
-                    nouts.flush();
-                    // TODO: Is this an extra CRLF?
-                    out.println();
-                    out.println(".");
-                    out.flush();
+                    try {
+                        OutputStream nouts =
+                                new ExtraDotOutputStream(outs);
+                        nouts = new BytesWrittenResetOutputStream(nouts,
+                                                                  theWatchdog,
+                                                                  theConfigData.getResetLength());
+                        mc.getMessage().writeTo(nouts);
+                        nouts.flush();
+                    } finally {
+                        out.println(".");
+                        out.flush();
+                    }
                 } else {
                     StringBuffer responseBuffer =
                         new StringBuffer(64)
@@ -966,19 +967,22 @@
                 if (mc != DELETED) {
                     responseString = OK_RESPONSE + " Message follows";
                     writeLoggedFlushedResponse(responseString);
-                    for (Enumeration e = mc.getMessage().getAllHeaderLines(); e.hasMoreElements(); ) {
-                        out.println(e.nextElement());
+                    try {
+                        for (Enumeration e = mc.getMessage().getAllHeaderLines(); e.hasMoreElements(); ) {
+                            out.println(e.nextElement());
+                        }
+                        out.println();
+                        OutputStream nouts =
+                                new ExtraDotOutputStream(outs);
+                        nouts = new BytesWrittenResetOutputStream(nouts,
+                                                                  theWatchdog,
+                                                                  theConfigData.getResetLength());
+                        writeMessageContentTo(mc.getMessage(),nouts,lines);
+                        nouts.flush();
+                    } finally {
+                        out.println(".");
+                        out.flush();
                     }
-                    out.println();
-                    OutputStream nouts =
-                            new ExtraDotOutputStream(outs);
-                    nouts = new BytesWrittenResetOutputStream(nouts,
-                                                              theWatchdog,
-                                                              theConfigData.getResetLength());
-                    writeMessageContentTo(mc.getMessage(),nouts,lines);
-                    nouts.flush();
-                    out.println(".");
-                    out.flush();
                 } else {
                     StringBuffer responseBuffer =
                         new StringBuffer(64)
@@ -1026,7 +1030,7 @@
         String line;
         BufferedReader br;
         if (message != null) {
-            br = new BufferedReader(new InputStreamReader(message.getInputStream()));
+            br = new BufferedReader(new InputStreamReader(message.getRawInputStream()));
             try {
                 while (lines-- > 0) {
                     if ((line = br.readLine()) == null) {

Added: james/server/trunk/src/test/org/apache/james/pop3server/POP3ServerTest.java
URL: http://svn.apache.org/viewcvs/james/server/trunk/src/test/org/apache/james/pop3server/POP3ServerTest.java?rev=365604&view=auto
==============================================================================
--- james/server/trunk/src/test/org/apache/james/pop3server/POP3ServerTest.java (added)
+++ james/server/trunk/src/test/org/apache/james/pop3server/POP3ServerTest.java Tue Jan  3 02:53:07 2006
@@ -0,0 +1,281 @@
+/***********************************************************************
+ * Copyright (c) 1999-2006 The Apache Software Foundation.             *
+ * All rights reserved.                                                *
+ * ------------------------------------------------------------------- *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you *
+ * may not use this file except in compliance with the License. You    *
+ * may obtain a copy of the License at:                                *
+ *                                                                     *
+ *     http://www.apache.org/licenses/LICENSE-2.0                      *
+ *                                                                     *
+ * Unless required by applicable law or agreed to in writing, software *
+ * distributed under the License is distributed on an "AS IS" BASIS,   *
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or     *
+ * implied.  See the License for the specific language governing       *
+ * permissions and limitations under the License.                      *
+ ***********************************************************************/
+package org.apache.james.pop3server;
+
+import org.apache.avalon.cornerstone.services.sockets.SocketManager;
+import org.apache.avalon.cornerstone.services.threads.ThreadManager;
+import org.apache.james.core.MailImpl;
+import org.apache.james.core.MimeMessageInputStreamSource;
+import org.apache.james.core.MimeMessageSource;
+import org.apache.james.core.MimeMessageWrapper;
+import org.apache.james.fetchmail.ReaderInputStream;
+import org.apache.james.services.JamesConnectionManager;
+import org.apache.james.test.mock.avalon.MockLogger;
+import org.apache.james.test.mock.avalon.MockServiceManager;
+import org.apache.james.test.mock.avalon.MockSocketManager;
+import org.apache.james.test.mock.avalon.MockThreadManager;
+import org.apache.james.test.mock.james.MockMailRepository;
+import org.apache.james.test.mock.james.MockMailServer;
+import org.apache.james.test.mock.james.MockUsersRepository;
+import org.apache.james.test.util.Util;
+import org.apache.james.util.connection.SimpleConnectionManager;
+import org.apache.mailet.MailAddress;
+import org.columba.ristretto.io.Source;
+import org.columba.ristretto.pop3.POP3Exception;
+import org.columba.ristretto.pop3.POP3Protocol;
+import org.columba.ristretto.pop3.POP3Response;
+import org.columba.ristretto.pop3.ScanListEntry;
+
+import com.sun.mail.util.SharedByteArrayInputStream;
+
+import javax.mail.MessagingException;
+import javax.mail.internet.MimeMessage;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringReader;
+import java.util.ArrayList;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests the org.apache.james.smtpserver.SMTPServer unit 
+ */
+public class POP3ServerTest extends TestCase {
+    private int m_pop3ListenerPort = Util.getRandomNonPrivilegedPort();
+    private MockMailServer m_mailServer;
+    private POP3TestConfiguration m_testConfiguration;
+    private POP3Server m_pop3Server;
+    private MockUsersRepository m_usersRepository = new MockUsersRepository();
+
+    public POP3ServerTest() {
+        super("POP3ServerTest");
+    }
+
+    protected void setUp() throws Exception {
+        m_pop3Server = new POP3Server();
+        m_pop3Server.enableLogging(new MockLogger());
+
+        m_pop3Server.service(setUpServiceManager());
+        m_testConfiguration = new POP3TestConfiguration(m_pop3ListenerPort);
+    }
+
+    private void finishSetUp(POP3TestConfiguration testConfiguration) throws Exception {
+        testConfiguration.init();
+        m_pop3Server.configure(testConfiguration);
+        m_pop3Server.initialize();
+    }
+
+    private MockServiceManager setUpServiceManager() {
+        MockServiceManager serviceManager = new MockServiceManager();
+        SimpleConnectionManager connectionManager = new SimpleConnectionManager();
+        connectionManager.enableLogging(new MockLogger());
+        serviceManager.put(JamesConnectionManager.ROLE, connectionManager);
+        m_mailServer = new MockMailServer();
+        serviceManager.put("org.apache.james.services.MailServer", m_mailServer);
+        serviceManager.put("org.apache.james.services.UsersRepository", m_usersRepository);
+        serviceManager.put(SocketManager.ROLE, new MockSocketManager(m_pop3ListenerPort));
+        serviceManager.put(ThreadManager.ROLE, new MockThreadManager());
+        return serviceManager;
+    }
+    
+    
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        m_pop3Server.dispose();
+    }
+
+    public void testAuthenticationFail() throws Exception, POP3Exception {
+        finishSetUp(m_testConfiguration);
+
+        POP3Protocol pop3Protocol = new POP3Protocol("127.0.0.1", m_pop3ListenerPort);
+        pop3Protocol.openPort();
+
+        m_usersRepository.addUser("known","test2");
+        
+        int res = 0;
+        try {
+            pop3Protocol.userPass("known","test".toCharArray());
+        } catch (POP3Exception e) {
+            res = e.getResponse().getType();
+        }
+        
+        assertEquals(-1,res);
+
+        pop3Protocol.quit();
+    }
+
+    public void testUnknownUser() throws Exception, POP3Exception {
+        finishSetUp(m_testConfiguration);
+
+        POP3Protocol pop3Protocol = new POP3Protocol("127.0.0.1", m_pop3ListenerPort);
+        pop3Protocol.openPort();
+
+        int res = 0;
+        try {
+            pop3Protocol.userPass("unknown","test".toCharArray());
+        } catch (POP3Exception e) {
+            res = e.getResponse().getType();
+        }
+        
+        assertEquals(-1,res);
+
+        pop3Protocol.quit();
+    }
+
+    public void testknownUserEmptyInbox() throws Exception, POP3Exception {
+        finishSetUp(m_testConfiguration);
+
+        POP3Protocol pop3Protocol = new POP3Protocol("127.0.0.1", m_pop3ListenerPort);
+        pop3Protocol.openPort();
+
+        m_usersRepository.addUser("foo","bar");
+
+        int res = 0;
+        try {
+            pop3Protocol.userPass("foo","bar".toCharArray());
+        } catch (POP3Exception e) {
+            res = e.getResponse().getType();
+        }
+        
+        assertEquals(0,res);
+        
+        res = 0;
+        ScanListEntry[] entries = null;
+        try {
+            entries = pop3Protocol.list();
+        } catch (POP3Exception e) {
+            res = e.getResponse().getType();
+        }
+
+        assertNotNull(entries);
+        assertEquals(entries.length,0);
+        assertEquals(res,0);
+
+        pop3Protocol.quit();
+    }
+
+    public void testknownUserInboxWithEmptyMessage() throws Exception, POP3Exception {
+        finishSetUp(m_testConfiguration);
+
+        POP3Protocol pop3Protocol = new POP3Protocol("127.0.0.1", m_pop3ListenerPort);
+        pop3Protocol.openPort();
+
+        m_usersRepository.addUser("foo2","bar2");
+        MockMailRepository mailRep = new MockMailRepository();
+        
+        MimeMessageSource mmis = null;
+        try {
+            mmis = new MimeMessageInputStreamSource("test", new SharedByteArrayInputStream(("Return-path: return@test.com\r\nContent-Transfer-Encoding: plain\r\nSubject: test\r\n\r\nBody Text\r\n").getBytes()));
+            mmis = new MimeMessageSource() {
+
+                public String getSourceId() {
+                    return "test";
+                }
+
+                public InputStream getInputStream() throws IOException {
+                    return new ReaderInputStream(new StringReader("Return-path: return@test.com\r\nContent-Transfer-Encoding: plain\r\nSubject: test\r\n\r\nBody Text\r\n"));
+                }
+                
+            };
+        } catch (MessagingException e) {
+        }
+        MimeMessage mw = new MimeMessageWrapper(mmis);
+        ArrayList recipients = new ArrayList();
+        recipients.add(new MailAddress("recipient@test.com"));
+        mailRep.store(new MailImpl("name", new MailAddress("from@test.com"), recipients, mw));
+
+        
+        m_mailServer.setUserInbox("foo2",mailRep);
+        
+
+        int res = 0;
+        try {
+            pop3Protocol.userPass("foo2","bar2".toCharArray());
+        } catch (POP3Exception e) {
+            res = e.getResponse().getType();
+        }
+        
+        assertEquals(0,res);
+        
+        res = 0;
+        ScanListEntry[] entries = null;
+        try {
+            entries = pop3Protocol.list();
+        } catch (POP3Exception e) {
+            res = e.getResponse().getType();
+        }
+        
+        assertNotNull(entries);
+        assertEquals(1,entries.length);
+        assertEquals(res,0);
+        
+        Source i = null;
+        try {
+            i = pop3Protocol.top(entries[0].getIndex(),0);
+        } catch (POP3Exception e) {
+            res = e.getResponse().getType();
+        }
+        
+        assertNotNull(i);
+        i.close();
+        
+        InputStream i2 = null;
+        try {
+            i2 = pop3Protocol.retr(entries[0].getIndex());
+        } catch (POP3Exception e) {
+            res = e.getResponse().getType();
+        }
+        
+
+        assertNotNull(i2);
+        i2.close();
+        
+        boolean deleted = false;
+        try {
+            deleted = pop3Protocol.dele(entries[0].getIndex());
+        } catch (POP3Exception e) {
+            res = e.getResponse().getType();
+        }
+
+        assertTrue(deleted);
+        assertEquals(res,0);
+
+
+        pop3Protocol.quit();
+    }
+}
+
+class MyPOP3Protocol extends POP3Protocol
+{
+
+    public MyPOP3Protocol(String s, int i) {
+        super(s, i);
+    }
+
+    public MyPOP3Protocol(String s) {
+        super(s);
+    }
+
+    public void sendCommand(String string, String[] strings) throws IOException {
+        super.sendCommand(string, strings);     
+    }
+
+    public POP3Response getResponse() throws IOException, POP3Exception {
+        return super.readSingleLineResponse();
+    }
+}

Added: james/server/trunk/src/test/org/apache/james/pop3server/POP3TestConfiguration.java
URL: http://svn.apache.org/viewcvs/james/server/trunk/src/test/org/apache/james/pop3server/POP3TestConfiguration.java?rev=365604&view=auto
==============================================================================
--- james/server/trunk/src/test/org/apache/james/pop3server/POP3TestConfiguration.java (added)
+++ james/server/trunk/src/test/org/apache/james/pop3server/POP3TestConfiguration.java Tue Jan  3 02:53:07 2006
@@ -0,0 +1,41 @@
+/***********************************************************************
+ * Copyright (c) 2000-2006 The Apache Software Foundation.             *
+ * All rights reserved.                                                *
+ * ------------------------------------------------------------------- *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you *
+ * may not use this file except in compliance with the License. You    *
+ * may obtain a copy of the License at:                                *
+ *                                                                     *
+ *     http://www.apache.org/licenses/LICENSE-2.0                      *
+ *                                                                     *
+ * Unless required by applicable law or agreed to in writing, software *
+ * distributed under the License is distributed on an "AS IS" BASIS,   *
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or     *
+ * implied.  See the License for the specific language governing       *
+ * permissions and limitations under the License.                      *
+ ***********************************************************************/
+package org.apache.james.pop3server;
+
+import org.apache.avalon.framework.configuration.DefaultConfiguration;
+import org.apache.james.test.util.Util;
+
+public class POP3TestConfiguration extends DefaultConfiguration {
+
+    private int m_pop3ListenerPort;
+
+    public POP3TestConfiguration(int pop3ListenerPort) {
+        super("pop3server");
+        m_pop3ListenerPort = pop3ListenerPort;
+    }
+
+    public void init() {
+        setAttribute("enabled", true);
+        addChild(Util.getValuedConfiguration("port", "" + m_pop3ListenerPort));
+        DefaultConfiguration handlerConfig = new DefaultConfiguration("handler");
+        handlerConfig.addChild(Util.getValuedConfiguration("helloName", "myMailServer"));
+        handlerConfig.addChild(Util.getValuedConfiguration("connectiontimeout", "360000"));
+
+        addChild(handlerConfig);
+    }
+
+}

Modified: james/server/trunk/src/test/org/apache/james/test/mock/avalon/MockLogger.java
URL: http://svn.apache.org/viewcvs/james/server/trunk/src/test/org/apache/james/test/mock/avalon/MockLogger.java?rev=365604&r1=365603&r2=365604&view=diff
==============================================================================
--- james/server/trunk/src/test/org/apache/james/test/mock/avalon/MockLogger.java (original)
+++ james/server/trunk/src/test/org/apache/james/test/mock/avalon/MockLogger.java Tue Jan  3 02:53:07 2006
@@ -27,6 +27,7 @@
 
     public void debug(java.lang.String string, java.lang.Throwable throwable) {
         System.out.println(string + throwable.toString());
+        throwable.printStackTrace();
     }
 
     public boolean isDebugEnabled() {
@@ -43,6 +44,7 @@
 
     public void info(java.lang.String string, java.lang.Throwable throwable) {
         System.out.println(string + throwable.toString());
+        throwable.printStackTrace();
     }
 
     public boolean isInfoEnabled() {
@@ -55,6 +57,7 @@
 
     public void warn(java.lang.String string, java.lang.Throwable throwable) {
         System.out.println(string + throwable.toString());
+        throwable.printStackTrace();
     }
 
     public boolean isWarnEnabled() {
@@ -67,6 +70,7 @@
 
     public void error(java.lang.String string, java.lang.Throwable throwable) {
         System.out.println(string + throwable.toString());
+        throwable.printStackTrace();
     }
 
     public boolean isErrorEnabled() {
@@ -79,6 +83,7 @@
 
     public void fatalError(java.lang.String string, java.lang.Throwable throwable) {
         System.out.println(string + throwable.toString());
+        throwable.printStackTrace();
     }
 
     public boolean isFatalErrorEnabled() {

Modified: james/server/trunk/src/test/org/apache/james/test/mock/james/MockMailRepository.java
URL: http://svn.apache.org/viewcvs/james/server/trunk/src/test/org/apache/james/test/mock/james/MockMailRepository.java?rev=365604&r1=365603&r2=365604&view=diff
==============================================================================
--- james/server/trunk/src/test/org/apache/james/test/mock/james/MockMailRepository.java (original)
+++ james/server/trunk/src/test/org/apache/james/test/mock/james/MockMailRepository.java Tue Jan  3 02:53:07 2006
@@ -22,33 +22,40 @@
 import org.apache.mailet.Mail;
 
 import javax.mail.MessagingException;
+
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Collection;
 
 public class MockMailRepository implements MailRepository {
+    
+    private HashMap messages = new HashMap();
 
     public void store(Mail mc) throws MessagingException {
-        // trivial implementation
+        this.messages.put(mc.getName(),mc);
     }
 
     public Iterator list() throws MessagingException {
-        return null;  // trivial implementation
+        return messages.keySet().iterator();  // trivial implementation
     }
 
     public Mail retrieve(String key) throws MessagingException {
-        return null;  // trivial implementation
+        return (Mail) messages.get(key);  // trivial implementation
     }
 
     public void remove(Mail mail) throws MessagingException {
-        // trivial implementation
+        messages.remove(mail.getName());
     }
 
     public void remove(Collection mails) throws MessagingException {
-        // trivial implementation
+        for (Iterator i = mails.iterator(); i.hasNext(); ) {
+            Mail m = (Mail) i.next();
+            messages.remove(m.getName());
+        }
     }
 
     public void remove(String key) throws MessagingException {
-        // trivial implementation
+        messages.remove(key);
     }
 
     public boolean lock(String key) throws MessagingException {

Modified: james/server/trunk/src/test/org/apache/james/test/mock/james/MockMailServer.java
URL: http://svn.apache.org/viewcvs/james/server/trunk/src/test/org/apache/james/test/mock/james/MockMailServer.java?rev=365604&r1=365603&r2=365604&view=diff
==============================================================================
--- james/server/trunk/src/test/org/apache/james/test/mock/james/MockMailServer.java (original)
+++ james/server/trunk/src/test/org/apache/james/test/mock/james/MockMailServer.java Tue Jan  3 02:53:07 2006
@@ -38,6 +38,8 @@
 
     private final ArrayList mails = new ArrayList();
 
+    private HashMap inboxes;
+
     public void sendMail(MailAddress sender, Collection recipients, MimeMessage msg) throws MessagingException {
         Object[] mailObjects = new Object[]{sender, recipients, msg};
         mails.add(mailObjects);
@@ -76,7 +78,19 @@
     }
 
     public MailRepository getUserInbox(String userName) {
-        return null; // trivial implementation 
+        if (inboxes==null) {
+            return null;
+        } else {
+            return (MailRepository) inboxes.get(userName);
+        }
+        
+    }
+    
+    public void setUserInbox(String userName, MailRepository inbox) {
+        if (inboxes == null) {
+            inboxes = new HashMap();
+        }
+        inboxes.put(userName,inbox);
     }
 
     public Map getRepositoryCounters() {



---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org