SMTP: correct escaping of messages containing lines with single dot.
1.1 --- a/src/org/sonews/daemon/NNTPConnection.java Tue Oct 25 10:16:13 2011 +0200
1.2 +++ b/src/org/sonews/daemon/NNTPConnection.java Tue Oct 25 10:39:57 2011 +0200
1.3 @@ -17,6 +17,7 @@
1.4 */
1.5 package org.sonews.daemon;
1.6
1.7 +import java.io.ByteArrayOutputStream;
1.8 import java.io.IOException;
1.9 import java.net.InetSocketAddress;
1.10 import java.net.SocketException;
1.11 @@ -36,6 +37,8 @@
1.12 import org.sonews.storage.StorageBackendException;
1.13 import org.sonews.util.Log;
1.14 import org.sonews.util.Stats;
1.15 +import org.sonews.util.io.CRLFOutputStream;
1.16 +import org.sonews.util.io.SMTPOutputStream;
1.17
1.18 /**
1.19 * For every SocketChannel (so TCP/IP connection) there is an instance of
1.20 @@ -306,6 +309,30 @@
1.21 this.lineBuffers.addOutputBuffer(ByteBuffer.wrap(rawLines));
1.22 writeToChannel(CharBuffer.wrap(NEWLINE), charset, null);
1.23 }
1.24 +
1.25 + /**
1.26 + * Same as {@link #println(byte[]) } but escapes lines containing single dot,
1.27 + * which has special meaning in protocol (end of message).
1.28 + *
1.29 + * This method is safe to be used for writing messages – if message contains
1.30 + * a line with single dot, it will be doubled and thus not interpreted
1.31 + * by NNTP client as end of message
1.32 + *
1.33 + * @param rawLines
1.34 + * @throws IOException
1.35 + */
1.36 + public void printlnEscapeDots(final byte[] rawLines) throws IOException {
1.37 + // TODO: optimalizace
1.38 +
1.39 + ByteArrayOutputStream baos = new ByteArrayOutputStream(rawLines.length + 10);
1.40 + CRLFOutputStream crlfStream = new CRLFOutputStream(baos);
1.41 + SMTPOutputStream smtpStream = new SMTPOutputStream(crlfStream);
1.42 + smtpStream.write(rawLines);
1.43 +
1.44 + println(baos.toByteArray());
1.45 +
1.46 + smtpStream.close();
1.47 + }
1.48
1.49 /**
1.50 * Encodes the given CharBuffer using the given Charset to a bunch of
2.1 --- a/src/org/sonews/daemon/command/ArticleCommand.java Tue Oct 25 10:16:13 2011 +0200
2.2 +++ b/src/org/sonews/daemon/command/ArticleCommand.java Tue Oct 25 10:39:57 2011 +0200
2.3 @@ -101,11 +101,11 @@
2.4 + " article retrieved - head and body follow");
2.5 conn.println(article.getHeaderSource());
2.6 conn.println("");
2.7 - conn.println(article.getBody());
2.8 + conn.printlnEscapeDots(article.getBody());
2.9 conn.println(".");
2.10 } else if (command[0].equalsIgnoreCase("BODY")) {
2.11 conn.println("222 " + artIndex + " " + article.getMessageID() + " body");
2.12 - conn.println(article.getBody());
2.13 + conn.printlnEscapeDots(article.getBody());
2.14 conn.println(".");
2.15 } /*
2.16 * HEAD: This command is mandatory.
3.1 --- a/src/org/sonews/util/io/CRLFOutputStream.java Tue Oct 25 10:16:13 2011 +0200
3.2 +++ b/src/org/sonews/util/io/CRLFOutputStream.java Tue Oct 25 10:39:57 2011 +0200
3.3 @@ -46,6 +46,7 @@
3.4 * An output stream that filters LFs into CR/LF pairs.
3.5 *
3.6 * @author Chris Burdess (dog@gnu.org)
3.7 + * @version classpath-0.98
3.8 */
3.9 public class CRLFOutputStream extends FilterOutputStream {
3.10