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/04 11:23:55 UTC

svn commit: r365881 - in /james/server/trunk/src: java/org/apache/james/pop3server/ java/org/apache/james/util/ test/org/apache/james/pop3server/ test/org/apache/james/smtpserver/ test/org/apache/james/util/

Author: bago
Date: Wed Jan  4 02:23:45 2006
New Revision: 365881

URL: http://svn.apache.org/viewcvs?rev=365881&view=rev
Log:
Workaround to backward compatibility broken in JAMES-431.
We now report the wrong size when a message is not CRLF terminated but we correctly terminate it in TOP and RETR responses.
Also added tests for ExtraDotOutputStream and for SMTPServer and POP3Server empty message handling.

Added:
    james/server/trunk/src/test/org/apache/james/util/ExtraDotOutputStreamTest.java
Modified:
    james/server/trunk/src/java/org/apache/james/pop3server/POP3Handler.java
    james/server/trunk/src/java/org/apache/james/util/ExtraDotOutputStream.java
    james/server/trunk/src/test/org/apache/james/pop3server/POP3ServerTest.java
    james/server/trunk/src/test/org/apache/james/smtpserver/SMTPServerTest.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=365881&r1=365880&r2=365881&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 Wed Jan  4 02:23:45 2006
@@ -894,13 +894,15 @@
                     responseString = OK_RESPONSE + " Message follows";
                     writeLoggedFlushedResponse(responseString);
                     try {
-                        OutputStream nouts =
+                        ExtraDotOutputStream edouts =
                                 new ExtraDotOutputStream(outs);
-                        nouts = new BytesWrittenResetOutputStream(nouts,
+                        OutputStream nouts = new BytesWrittenResetOutputStream(edouts,
                                                                   theWatchdog,
                                                                   theConfigData.getResetLength());
                         mc.getMessage().writeTo(nouts);
                         nouts.flush();
+                        edouts.checkCRLFTerminator();
+                        edouts.flush();
                     } finally {
                         out.println(".");
                         out.flush();
@@ -972,13 +974,15 @@
                             out.println(e.nextElement());
                         }
                         out.println();
-                        OutputStream nouts =
+                        ExtraDotOutputStream edouts =
                                 new ExtraDotOutputStream(outs);
-                        nouts = new BytesWrittenResetOutputStream(nouts,
+                        OutputStream nouts = new BytesWrittenResetOutputStream(edouts,
                                                                   theWatchdog,
                                                                   theConfigData.getResetLength());
                         writeMessageContentTo(mc.getMessage(),nouts,lines);
                         nouts.flush();
+                        edouts.checkCRLFTerminator();
+                        edouts.flush();
                     } finally {
                         out.println(".");
                         out.flush();

Modified: james/server/trunk/src/java/org/apache/james/util/ExtraDotOutputStream.java
URL: http://svn.apache.org/viewcvs/james/server/trunk/src/java/org/apache/james/util/ExtraDotOutputStream.java?rev=365881&r1=365880&r2=365881&view=diff
==============================================================================
--- james/server/trunk/src/java/org/apache/james/util/ExtraDotOutputStream.java (original)
+++ james/server/trunk/src/java/org/apache/james/util/ExtraDotOutputStream.java Wed Jan  4 02:23:45 2006
@@ -90,4 +90,15 @@
         }
         out.write(b);
     }
+    
+    /**
+     * Ensure that the stream is CRLF terminated.
+     * 
+     * @throws IOException  if an error occurs writing the byte
+     */
+    public void checkCRLFTerminator() throws IOException {
+        if (countLast0A0D != 2) {
+            write('\n');
+        }
+    }
 }

Modified: 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=365881&r1=365880&r2=365881&view=diff
==============================================================================
--- james/server/trunk/src/test/org/apache/james/pop3server/POP3ServerTest.java (original)
+++ james/server/trunk/src/test/org/apache/james/pop3server/POP3ServerTest.java Wed Jan  4 02:23:45 2006
@@ -20,9 +20,7 @@
 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;
@@ -42,24 +40,26 @@
 
 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 
+ * 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() {
@@ -74,7 +74,8 @@
         m_testConfiguration = new POP3TestConfiguration(m_pop3ListenerPort);
     }
 
-    private void finishSetUp(POP3TestConfiguration testConfiguration) throws Exception {
+    private void finishSetUp(POP3TestConfiguration testConfiguration)
+            throws Exception {
         testConfiguration.init();
         m_pop3Server.configure(testConfiguration);
         m_pop3Server.initialize();
@@ -86,14 +87,16 @@
         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("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();
@@ -102,19 +105,20 @@
     public void testAuthenticationFail() throws Exception, POP3Exception {
         finishSetUp(m_testConfiguration);
 
-        POP3Protocol pop3Protocol = new POP3Protocol("127.0.0.1", m_pop3ListenerPort);
+        POP3Protocol pop3Protocol = new POP3Protocol("127.0.0.1",
+                m_pop3ListenerPort);
         pop3Protocol.openPort();
 
-        m_usersRepository.addUser("known","test2");
-        
+        m_usersRepository.addUser("known", "test2");
+
         int res = 0;
         try {
-            pop3Protocol.userPass("known","test".toCharArray());
+            pop3Protocol.userPass("known", "test".toCharArray());
         } catch (POP3Exception e) {
             res = e.getResponse().getType();
         }
-        
-        assertEquals(-1,res);
+
+        assertEquals(-1, res);
 
         pop3Protocol.quit();
     }
@@ -122,17 +126,18 @@
     public void testUnknownUser() throws Exception, POP3Exception {
         finishSetUp(m_testConfiguration);
 
-        POP3Protocol pop3Protocol = new POP3Protocol("127.0.0.1", m_pop3ListenerPort);
+        POP3Protocol pop3Protocol = new POP3Protocol("127.0.0.1",
+                m_pop3ListenerPort);
         pop3Protocol.openPort();
 
         int res = 0;
         try {
-            pop3Protocol.userPass("unknown","test".toCharArray());
+            pop3Protocol.userPass("unknown", "test".toCharArray());
         } catch (POP3Exception e) {
             res = e.getResponse().getType();
         }
-        
-        assertEquals(-1,res);
+
+        assertEquals(-1, res);
 
         pop3Protocol.quit();
     }
@@ -140,20 +145,21 @@
     public void testknownUserEmptyInbox() throws Exception, POP3Exception {
         finishSetUp(m_testConfiguration);
 
-        POP3Protocol pop3Protocol = new POP3Protocol("127.0.0.1", m_pop3ListenerPort);
+        POP3Protocol pop3Protocol = new POP3Protocol("127.0.0.1",
+                m_pop3ListenerPort);
         pop3Protocol.openPort();
 
-        m_usersRepository.addUser("foo","bar");
+        m_usersRepository.addUser("foo", "bar");
 
         int res = 0;
         try {
-            pop3Protocol.userPass("foo","bar".toCharArray());
+            pop3Protocol.userPass("foo", "bar".toCharArray());
         } catch (POP3Exception e) {
             res = e.getResponse().getType();
         }
-        
-        assertEquals(0,res);
-        
+
+        assertEquals(0, res);
+
         res = 0;
         ScanListEntry[] entries = null;
         try {
@@ -163,55 +169,76 @@
         }
 
         assertNotNull(entries);
-        assertEquals(entries.length,0);
-        assertEquals(res,0);
+        assertEquals(entries.length, 0);
+        assertEquals(res, 0);
 
         pop3Protocol.quit();
     }
 
-    public void testknownUserInboxWithEmptyMessage() throws Exception, POP3Exception {
+    public void testNotAsciiCharsInPassword() throws Exception, POP3Exception {
         finishSetUp(m_testConfiguration);
 
-        POP3Protocol pop3Protocol = new POP3Protocol("127.0.0.1", m_pop3ListenerPort);
+        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() {
+        String pass = "bar" + (new String(new char[] { 200, 210 })) + "foo";
+        m_usersRepository.addUser("foo", pass);
 
-                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) {
+        int res = 0;
+        try {
+            pop3Protocol.userPass("foo", pass.toCharArray());
+        } catch (POP3Exception e) {
+            res = e.getResponse() != null ? e.getResponse().getType() : -1;
         }
-        MimeMessage mw = new MimeMessageWrapper(mmis);
+
+        assertEquals(0, res);
+
+        pop3Protocol.quit();
+    }
+
+    public void testknownUserInboxWithMessages() 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();
+
+        MimeMessage mw = new MimeMessageWrapper(
+                new MimeMessageInputStreamSource(
+                        "test",
+                        new SharedByteArrayInputStream(
+                                ("Return-path: return@test.com\r\n"+
+                                 "Content-Transfer-Encoding: plain\r\n"+
+                                 "Subject: test\r\n\r\n"+
+                                 "Body Text\r\n").getBytes())));
+        MimeMessage mw2 = new MimeMessageWrapper(
+                new MimeMessageInputStreamSource(
+                        "test2",
+                        new SharedByteArrayInputStream(
+                                ("").getBytes())));
         ArrayList recipients = new ArrayList();
         recipients.add(new MailAddress("recipient@test.com"));
-        mailRep.store(new MailImpl("name", new MailAddress("from@test.com"), recipients, mw));
+        mailRep.store(new MailImpl("name", new MailAddress("from@test.com"),
+                recipients, mw));
+        mailRep.store(new MailImpl("name2", new MailAddress("from@test.com"),
+                recipients, mw2));
 
-        
-        m_mailServer.setUserInbox("foo2",mailRep);
-        
+        m_mailServer.setUserInbox("foo2", mailRep);
 
         int res = 0;
         try {
-            pop3Protocol.userPass("foo2","bar2".toCharArray());
+            pop3Protocol.userPass("foo2", "bar2".toCharArray());
         } catch (POP3Exception e) {
             res = e.getResponse().getType();
         }
-        
-        assertEquals(0,res);
-        
+
+        assertEquals(0, res);
+
         res = 0;
         ScanListEntry[] entries = null;
         try {
@@ -219,32 +246,32 @@
         } catch (POP3Exception e) {
             res = e.getResponse().getType();
         }
-        
+
         assertNotNull(entries);
-        assertEquals(1,entries.length);
-        assertEquals(res,0);
-        
+        assertEquals(2, entries.length);
+        assertEquals(res, 0);
+
         Source i = null;
         try {
-            i = pop3Protocol.top(entries[0].getIndex(),0);
+            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();
         
+        i2.close();
+
         boolean deleted = false;
         try {
             deleted = pop3Protocol.dele(entries[0].getIndex());
@@ -253,15 +280,47 @@
         }
 
         assertTrue(deleted);
-        assertEquals(res,0);
+        assertEquals(res, 0);
 
+        pop3Protocol.quit();
+
+        pop3Protocol.openPort();
 
+        res = 0;
+        try {
+            pop3Protocol.userPass("foo2", "bar2".toCharArray());
+        } catch (POP3Exception e) {
+            res = e.getResponse().getType();
+        }
+
+        assertEquals(0, res);
+
+        res = 0;
+        entries = null;
+        try {
+            entries = pop3Protocol.list();
+        } catch (POP3Exception e) {
+            res = e.getResponse().getType();
+        } finally {
+            assertNotNull(entries);
+            assertEquals(1, entries.length);
+            assertEquals(res, 0);
+        }
+
+        i = null;
+        try {
+            i = pop3Protocol.top(entries[0].getIndex(), 0);
+        } catch (POP3Exception e) {
+            res = e.getResponse().getType();
+        } finally {
+            assertNotNull(i);
+            i.close();
+        }
         pop3Protocol.quit();
     }
 }
 
-class MyPOP3Protocol extends POP3Protocol
-{
+class MyPOP3Protocol extends POP3Protocol {
 
     public MyPOP3Protocol(String s, int i) {
         super(s, i);
@@ -272,7 +331,7 @@
     }
 
     public void sendCommand(String string, String[] strings) throws IOException {
-        super.sendCommand(string, strings);     
+        super.sendCommand(string, strings);
     }
 
     public POP3Response getResponse() throws IOException, POP3Exception {

Modified: james/server/trunk/src/test/org/apache/james/smtpserver/SMTPServerTest.java
URL: http://svn.apache.org/viewcvs/james/server/trunk/src/test/org/apache/james/smtpserver/SMTPServerTest.java?rev=365881&r1=365880&r2=365881&view=diff
==============================================================================
--- james/server/trunk/src/test/org/apache/james/smtpserver/SMTPServerTest.java (original)
+++ james/server/trunk/src/test/org/apache/james/smtpserver/SMTPServerTest.java Wed Jan  4 02:23:45 2006
@@ -16,7 +16,6 @@
  ***********************************************************************/
 package org.apache.james.smtpserver;
 
-import junit.framework.TestCase;
 import org.apache.avalon.cornerstone.services.sockets.SocketManager;
 import org.apache.avalon.cornerstone.services.threads.ThreadManager;
 import org.apache.james.services.JamesConnectionManager;
@@ -32,16 +31,27 @@
 import org.apache.james.util.connection.SimpleConnectionManager;
 import org.columba.ristretto.composer.MimeTreeRenderer;
 import org.columba.ristretto.io.CharSequenceSource;
-import org.columba.ristretto.message.*;
+import org.columba.ristretto.message.Address;
+import org.columba.ristretto.message.Header;
+import org.columba.ristretto.message.LocalMimePart;
+import org.columba.ristretto.message.MimeHeader;
+import org.columba.ristretto.message.MimeType;
 import org.columba.ristretto.smtp.SMTPException;
 import org.columba.ristretto.smtp.SMTPProtocol;
 import org.columba.ristretto.smtp.SMTPResponse;
 
+import com.sun.mail.util.SharedByteArrayInputStream;
+
+import javax.mail.internet.MimeMessage;
+
 import java.io.IOException;
+import java.io.InputStream;
 import java.net.InetAddress;
 import java.util.Arrays;
 import java.util.List;
 
+import junit.framework.TestCase;
+
 /**
  * Tests the org.apache.james.smtpserver.SMTPServer unit 
  */
@@ -111,6 +121,33 @@
         // mail was propagated by SMTPServer
         assertNotNull("mail received by mail server", m_mailServer.getLastMail());
     }
+    
+    public void testEmptyMessage() throws Exception {
+        InputStream mSource = new SharedByteArrayInputStream(("").getBytes());
+        finishSetUp(m_testConfiguration);
+
+        SMTPProtocol smtpProtocol = new SMTPProtocol("127.0.0.1", m_smtpListenerPort);
+        smtpProtocol.openPort();
+
+        // no message there, yet
+        assertNull("no mail received by mail server", m_mailServer.getLastMail());
+
+        smtpProtocol.mail(new Address("mail@localhost"));
+        smtpProtocol.rcpt(new Address("mail@localhost"));
+
+        smtpProtocol.data(mSource);
+
+        smtpProtocol.quit();
+
+        // mail was propagated by SMTPServer
+        assertNotNull("mail received by mail server", m_mailServer.getLastMail());
+
+        int size = ((MimeMessage) m_mailServer.getLastMail()[2]).getSize();
+
+        assertEquals(size,2);
+    }
+
+
 
     public void testSimpleMailSendWithHELO() throws Exception, SMTPException {
         finishSetUp(m_testConfiguration);
@@ -266,7 +303,11 @@
         SMTPResponse response = smtpProtocol.getResponse();
         assertEquals("expected error: max msg size exceeded", 552, response.getCode());
 
-        smtpProtocol.rcpt(new Address("mail@localhost"));
+        try {
+            smtpProtocol.rcpt(new Address("mail@localhost"));
+        } catch (SMTPException e) {
+            assertEquals("expected error", 552, response.getCode());
+        }
     }
 
     public void testHandleMessageSizeLimitExceeded() throws Exception, SMTPException {

Added: james/server/trunk/src/test/org/apache/james/util/ExtraDotOutputStreamTest.java
URL: http://svn.apache.org/viewcvs/james/server/trunk/src/test/org/apache/james/util/ExtraDotOutputStreamTest.java?rev=365881&view=auto
==============================================================================
--- james/server/trunk/src/test/org/apache/james/util/ExtraDotOutputStreamTest.java (added)
+++ james/server/trunk/src/test/org/apache/james/util/ExtraDotOutputStreamTest.java Wed Jan  4 02:23:45 2006
@@ -0,0 +1,69 @@
+/***********************************************************************
+ * 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.util;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests for the ExtraDotOutputStream
+ */
+public class ExtraDotOutputStreamTest extends TestCase {
+
+    public void testMain() throws IOException {
+        String data = ".This is a test\r\nof the thing.\r\nWe should not have much trouble.\r\n.doubled?\r\nor not?\n.doubled\nor not?\r\n\r\n\n\n\r\r\r\n";
+        ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+        OutputStream os = new ExtraDotOutputStream(bOut);
+        os.write(data.getBytes());
+        os.flush();
+        String expected = "..This is a test\r\nof the thing.\r\nWe should not have much trouble.\r\n..doubled?\r\nor not?\r\n..doubled\r\nor not?\r\n\r\n\r\n\r\n\r\n\r\n\r\n";
+        assertEquals(expected,bOut.toString());
+    }
+
+    /*
+     * Test method for 'org.apache.james.util.ExtraDotOutputStream.checkCRLFTerminator()'
+     */
+    public void testCheckCRLFTerminator() throws IOException {
+        ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+        ExtraDotOutputStream os = new ExtraDotOutputStream(bOut);
+        // if the stream is empty then we should not add the CRLF.
+        os.checkCRLFTerminator();
+        os.flush();
+        assertEquals("",bOut.toString());
+        os.write("Test".getBytes());
+        os.flush();
+        assertEquals("Test",bOut.toString());
+        os.checkCRLFTerminator();
+        os.flush();
+        assertEquals("Test\r\n",bOut.toString());
+        // if the stream ends with \r we should simply add the \n
+        os.write("A line with incomplete ending\r".getBytes());
+        os.flush();
+        assertEquals("Test\r\nA line with incomplete ending\r",bOut.toString());
+        os.checkCRLFTerminator();
+        os.flush();
+        assertEquals("Test\r\nA line with incomplete ending\r\n",bOut.toString());
+        // already correctly terminated, should leave the output untouched
+        os.checkCRLFTerminator();
+        os.flush();
+        assertEquals("Test\r\nA line with incomplete ending\r\n",bOut.toString());
+    }
+
+}



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