Author: norman
Date: Thu Jan 6 10:34:45 2011
New Revision: 1055821
URL: http://svn.apache.org/viewvc?rev=1055821&view=rev
Log:
Make sure we append a CRLF if needed when reading the message via POP3. See
JAMES-1174
Modified:
james/server/trunk/pop3server/src/main/java/org/apache/james/pop3server/core/CRLFTerminatedInputStream.java
james/server/trunk/pop3server/src/main/java/org/apache/james/pop3server/core/RetrCmdHandler.java
james/server/trunk/pop3server/src/main/java/org/apache/james/pop3server/core/TopCmdHandler.java
james/server/trunk/pop3server/src/test/java/org/apache/james/pop3server/CRLFTerminatedInputStreamTest.java
Modified:
james/server/trunk/pop3server/src/main/java/org/apache/james/pop3server/core/CRLFTerminatedInputStream.java
URL:
http://svn.apache.org/viewvc/james/server/trunk/pop3server/src/main/java/org/apache/james/pop3server/core/CRLFTerminatedInputStream.java?rev=1055821&r1=1055820&r2=1055821&view=diff
==============================================================================
---
james/server/trunk/pop3server/src/main/java/org/apache/james/pop3server/core/CRLFTerminatedInputStream.java
(original)
+++
james/server/trunk/pop3server/src/main/java/org/apache/james/pop3server/core/CRLFTerminatedInputStream.java
Thu Jan 6 10:34:45 2011
@@ -25,14 +25,17 @@ import java.io.InputStream;
/**
* This {...@link FilterInputStream} makes sure that the last chars of the
stream are \r\n
+ *
+ * See JAMES-1174 for an use case
*
*/
-public class CRLFTerminatedInputStream extends ReadByteFilterInputStream{
+public class CRLFTerminatedInputStream extends FilterInputStream{
private int last;
private byte[] extraData;
private int pos = 0;
-
+ private boolean complete = false;
+
private boolean endOfStream = false;
public CRLFTerminatedInputStream(InputStream in) {
@@ -40,33 +43,84 @@ public class CRLFTerminatedInputStream e
}
@Override
+ public int read(byte[] b, int off, int len) throws IOException {
+ if (endOfStream == false) {
+
+ int r = in.read(b, off, len);
+ if (r == -1) {
+ endOfStream = true;
+ calculateExtraData();
+
+ return fillArray(b, off, len);
+ } else {
+ last = b[r -1];
+ return r;
+ }
+ } else {
+ return fillArray(b, off, len);
+ }
+ }
+
+ private int fillArray(byte[] b, int off, int len) {
+ int a = -1;
+ int i = 0;
+ if (complete) {
+ return -1;
+ }
+ while( i < len) {
+ a = readNext();
+ if (a == -1) {
+ complete = true;
+ break;
+ } else {
+ b[off + i++] = (byte) a;
+
+ }
+ }
+ return i;
+ }
+
+ @Override
+ public int read(byte[] b) throws IOException {
+ return read(b, 0, b.length);
+ }
+
+ @Override
public int read() throws IOException {
if (endOfStream == false) {
int i = super.read();
if (i == -1) {
endOfStream = true;
- if (last != '\r') {
- extraData = new byte[2];
- extraData[0] = '\r';
- extraData[1] = '\n';
- } else if (last != '\n') {
- extraData = new byte[1];
- extraData[0] = '\r';
- } else {
- extraData = null;
- }
-
+ calculateExtraData();
+ return readNext();
} else {
last = i;
}
return i;
} else {
- if (extraData == null || extraData.length == pos) {
- return -1;
- } else {
- return extraData[pos++];
- }
+ return readNext();
+ }
+ }
+
+ private void calculateExtraData() {
+ if (last == '\n') {
+ extraData = null;
+ } else if (last == '\r') {
+ extraData = new byte[1];
+ extraData[0] = '\n';
+ } else {
+ extraData = new byte[2];
+ extraData[0] = '\r';
+ extraData[1] = '\n';
+ }
+
+ }
+ private int readNext() {
+ if (extraData == null || extraData.length == pos) {
+ return -1;
+ } else {
+ return extraData[pos++];
}
}
}
Modified:
james/server/trunk/pop3server/src/main/java/org/apache/james/pop3server/core/RetrCmdHandler.java
URL:
http://svn.apache.org/viewvc/james/server/trunk/pop3server/src/main/java/org/apache/james/pop3server/core/RetrCmdHandler.java?rev=1055821&r1=1055820&r2=1055821&view=diff
==============================================================================
---
james/server/trunk/pop3server/src/main/java/org/apache/james/pop3server/core/RetrCmdHandler.java
(original)
+++
james/server/trunk/pop3server/src/main/java/org/apache/james/pop3server/core/RetrCmdHandler.java
Thu Jan 6 10:34:45 2011
@@ -88,7 +88,9 @@ public class RetrCmdHandler implements C
} else {
in = createInputStream(content);
}
- session.writeStream(new ExtraDotInputStream(in));
+ //session.writeStream(new ExtraDotInputStream(in));
+ session.writeStream(new ExtraDotInputStream(new
CRLFTerminatedInputStream(in)));
+
} finally {
// write a single dot to mark message as complete
session.writeStream(new
ByteArrayInputStream(".\r\n".getBytes()));
Modified:
james/server/trunk/pop3server/src/main/java/org/apache/james/pop3server/core/TopCmdHandler.java
URL:
http://svn.apache.org/viewvc/james/server/trunk/pop3server/src/main/java/org/apache/james/pop3server/core/TopCmdHandler.java?rev=1055821&r1=1055820&r2=1055821&view=diff
==============================================================================
---
james/server/trunk/pop3server/src/main/java/org/apache/james/pop3server/core/TopCmdHandler.java
(original)
+++
james/server/trunk/pop3server/src/main/java/org/apache/james/pop3server/core/TopCmdHandler.java
Thu Jan 6 10:34:45 2011
@@ -128,7 +128,7 @@ public class TopCmdHandler extends RetrC
bodyIn = createInputStream(content);
}
// write body
- session.writeStream(new
CountingBodyInputStream(bodyIn, lines));
+ session.writeStream(new CountingBodyInputStream(new
CRLFTerminatedInputStream(bodyIn), lines));
} finally {
// write a single dot to mark message as complete
Modified:
james/server/trunk/pop3server/src/test/java/org/apache/james/pop3server/CRLFTerminatedInputStreamTest.java
URL:
http://svn.apache.org/viewvc/james/server/trunk/pop3server/src/test/java/org/apache/james/pop3server/CRLFTerminatedInputStreamTest.java?rev=1055821&r1=1055820&r2=1055821&view=diff
==============================================================================
---
james/server/trunk/pop3server/src/test/java/org/apache/james/pop3server/CRLFTerminatedInputStreamTest.java
(original)
+++
james/server/trunk/pop3server/src/test/java/org/apache/james/pop3server/CRLFTerminatedInputStreamTest.java
Thu Jan 6 10:34:45 2011
@@ -31,7 +31,30 @@ public class CRLFTerminatedInputStreamTe
public void testCRLFPresent() throws IOException {
String data = "Subject: test\r\n\r\ndata\r\n";
- CRLFTerminatedInputStream in = new CRLFTerminatedInputStream(new
ByteArrayInputStream(data.getBytes()));
+ check(data, data);
+ checkWithArray(data, data);
+
+ }
+
+
+ public void testCRPresent() throws IOException {
+ String data = "Subject: test\r\n\r\ndata\r";
+ String expected = data + "\n";
+ check(data, expected);
+ checkWithArray(data, expected);
+ }
+
+ public void testNonPresent() throws IOException {
+ String data = "Subject: test\r\n\r\ndata";
+ String expected = data + "\r\n";
+ check(data, expected);
+ checkWithArray(data, expected);
+
+ }
+
+
+ private void check(String source, String expected) throws IOException {
+ CRLFTerminatedInputStream in = new CRLFTerminatedInputStream(new
ByteArrayInputStream(source.getBytes()));
ByteArrayOutputStream out = new ByteArrayOutputStream();
@@ -43,6 +66,24 @@ public class CRLFTerminatedInputStreamTe
out.close();
String output = new String(out.toByteArray());
- assertEquals(data, output);
+ assertEquals(expected, output);
+ }
+
+ private void checkWithArray(String source, String expected) throws
IOException {
+ CRLFTerminatedInputStream in = new CRLFTerminatedInputStream(new
ByteArrayInputStream(source.getBytes()));
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+ byte[] buf = new byte[1024];
+ int i = 0;
+ while ((i = in.read(buf)) != -1) {
+ out.write(buf, 0, i);
+ }
+
+ in.close();
+ out.close();
+
+ String output = new String(out.toByteArray());
+ assertEquals(expected, output);
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]