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: [EMAIL PROTECTED]: 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: [EMAIL PROTECTED]: 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("[EMAIL PROTECTED]"));
+ mailRep.store(new MailImpl("name", new MailAddress("[EMAIL
PROTECTED]"), 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: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]