Repository: james-project
Updated Branches:
  refs/heads/master 62466172d -> ae70e0a5c


JAMES-1543 Finish implementing incomplete SIZE extended SMTP behaviour


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/2097ee9e
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/2097ee9e
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/2097ee9e

Branch: refs/heads/master
Commit: 2097ee9eabbe87428ef3308abf18578ef4fb2de1
Parents: 6246617
Author: benwa <btell...@linagora.com>
Authored: Mon Apr 17 16:56:16 2017 +0700
Committer: benwa <btell...@linagora.com>
Committed: Wed Apr 19 13:02:24 2017 +0700

----------------------------------------------------------------------
 .../smtp/core/esmtp/MailSizeEsmtpExtension.java | 38 +++++++----
 .../apache/james/smtpserver/SMTPServerTest.java | 68 ++++++++++++++++++++
 2 files changed, 92 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/2097ee9e/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/esmtp/MailSizeEsmtpExtension.java
----------------------------------------------------------------------
diff --git 
a/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/esmtp/MailSizeEsmtpExtension.java
 
b/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/esmtp/MailSizeEsmtpExtension.java
index d178847..2079403 100644
--- 
a/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/esmtp/MailSizeEsmtpExtension.java
+++ 
b/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/esmtp/MailSizeEsmtpExtension.java
@@ -30,6 +30,7 @@ import org.apache.james.protocols.api.Response;
 import org.apache.james.protocols.api.ProtocolSession.State;
 import org.apache.james.protocols.api.handler.LineHandler;
 import org.apache.james.protocols.smtp.MailEnvelope;
+import org.apache.james.protocols.smtp.SMTPResponse;
 import org.apache.james.protocols.smtp.SMTPRetCode;
 import org.apache.james.protocols.smtp.SMTPSession;
 import org.apache.james.protocols.smtp.core.DataLineFilter;
@@ -50,6 +51,8 @@ public class MailSizeEsmtpExtension implements 
MailParametersHook, EhloExtension
     
     private static final HookResult SYNTAX_ERROR = new 
HookResult(HookReturnCode.DENY, SMTPRetCode.SYNTAX_ERROR_ARGUMENTS, 
DSNStatus.getStatus(DSNStatus.PERMANENT, DSNStatus.DELIVERY_INVALID_ARG) + " 
Syntactically incorrect value for SIZE parameter");
     private static final HookResult QUOTA_EXCEEDED = new 
HookResult(HookReturnCode.DENY, SMTPRetCode.QUOTA_EXCEEDED, 
DSNStatus.getStatus(DSNStatus.PERMANENT, DSNStatus.SYSTEM_MSG_TOO_BIG) + " 
Message size exceeds fixed maximum message size");
+    public static final int SINGLE_CHARACTER_LINE = 3;
+    public static final int DOT_BYTE = 46;
 
     @Override
     public void init(Configuration config) throws ConfigurationException {
@@ -148,16 +151,21 @@ public class MailSizeEsmtpExtension implements 
MailParametersHook, EhloExtension
      * @see 
org.apache.james.protocols.smtp.core.DataLineFilter#onLine(SMTPSession, byte[], 
LineHandler)
      */
     public Response onLine(SMTPSession session, ByteBuffer line, 
LineHandler<SMTPSession> next) {
-        Response response = null;
-       Boolean failed = (Boolean) session.getAttachment(MESG_FAILED, 
State.Transaction);
+        Boolean failed = (Boolean) session.getAttachment(MESG_FAILED, 
State.Transaction);
         // If we already defined we failed and sent a reply we should simply
         // wait for a CRLF.CRLF to be sent by the client.
-        if (failed != null && failed.booleanValue()) {
-            // TODO
+        if (failed != null && failed) {
+            if (isDataTerminated(line)) {
+                line.rewind();
+                next.onLine(session, ByteBuffer.wrap(".\r\n".getBytes()));
+                return new SMTPResponse(SMTPRetCode.QUOTA_EXCEEDED, "Quota 
exceeded");
+            } else {
+                return null;
+            }
         } else {
-            if (line.remaining() == 3 && line.get() == 46) {
+            if (isDataTerminated(line)) {
                 line.rewind();
-                response = next.onLine(session, line);
+                return next.onLine(session, line);
             } else {
                 line.rewind();
                 Long currentSize = (Long) 
session.getAttachment("CURRENT_SIZE", State.Transaction);
@@ -167,25 +175,27 @@ public class MailSizeEsmtpExtension implements 
MailParametersHook, EhloExtension
                 } else {
                     newSize = 
Long.valueOf(currentSize.intValue()+line.remaining());
                 }
-                
+
+                session.setAttachment("CURRENT_SIZE", newSize, 
State.Transaction);
+
                 if (session.getConfiguration().getMaxMessageSize() > 0 && 
newSize.intValue() > session.getConfiguration().getMaxMessageSize()) {
                     // Add an item to the state to suppress
                     // logging of extra lines of data
                     // that are sent after the size limit has
                     // been hit.
                     session.setAttachment(MESG_FAILED, Boolean.TRUE, 
State.Transaction);
-                    // then let the client know that the size
-                    // limit has been hit.
-                    response = next.onLine(session, 
ByteBuffer.wrap(".\r\n".getBytes()));
+
+                    return null;
                 } else {
                     line.rewind();
-                    response = next.onLine(session, line);
+                    return next.onLine(session, line);
                 }
-                
-                session.setAttachment("CURRENT_SIZE", newSize, 
State.Transaction);
             }
         }
-        return response;
+    }
+
+    private boolean isDataTerminated(ByteBuffer line) {
+        return line.remaining() == SINGLE_CHARACTER_LINE && line.get() == 
DOT_BYTE;
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/james-project/blob/2097ee9e/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SMTPServerTest.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SMTPServerTest.java
 
b/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SMTPServerTest.java
index 8faca0f..387db29 100644
--- 
a/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SMTPServerTest.java
+++ 
b/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SMTPServerTest.java
@@ -479,6 +479,74 @@ public class SMTPServerTest {
     }
 
     @Test
+    public void messageExceedingMessageSizeShouldBeDiscarded() throws 
Exception {
+        // Given
+        init(smtpConfiguration);
+        int maxSize = 1024;
+        smtpServer.setMaximalMessageSize(maxSize);
+
+        // When
+        SMTPClient smtpProtocol = new SMTPClient();
+        InetSocketAddress bindedAddress = new 
ProtocolServerUtils(smtpServer).retrieveBindedAddress();
+        smtpProtocol.connect(bindedAddress.getAddress().getHostAddress(), 
bindedAddress.getPort());
+        smtpProtocol.sendCommand("EHLO " + InetAddress.getLocalHost());
+        smtpProtocol.setSender("mail@localhost");
+        smtpProtocol.addRecipient("mail@localhost");
+        // Create a 1K+ message
+        StringBuilder stringBuilder = new StringBuilder();
+        stringBuilder.append("Subject: test\r\n\r\n");
+        String repeatedString = "This is the repeated body...\r\n";
+        int repeatCount = (maxSize / repeatedString.length()) + 1;
+        for (int i = 0; i < repeatCount; i++) {
+            stringBuilder.append(repeatedString);
+        }
+        stringBuilder.append("\r\n\r\n.\r\n");
+        smtpProtocol.sendShortMessageData(stringBuilder.toString());
+
+        // Then
+        assertThat(queue.getLastMail())
+            .as("mail received by mail server")
+            .isNull();
+
+        // finally
+        smtpProtocol.quit();
+        smtpProtocol.disconnect();
+    }
+
+    @Test
+    public void messageExceedingMessageSizeShouldBeRespondedAsOverQuota() 
throws Exception {
+        // Given
+        init(smtpConfiguration);
+        int maxSize = 1024;
+        smtpServer.setMaximalMessageSize(maxSize);
+
+        //When
+        SMTPClient smtpProtocol = new SMTPClient();
+        InetSocketAddress bindedAddress = new 
ProtocolServerUtils(smtpServer).retrieveBindedAddress();
+        smtpProtocol.connect(bindedAddress.getAddress().getHostAddress(), 
bindedAddress.getPort());
+        smtpProtocol.sendCommand("EHLO " + InetAddress.getLocalHost());
+        smtpProtocol.setSender("mail@localhost");
+        smtpProtocol.addRecipient("mail@localhost");
+        // Create a 1K+ message
+        StringBuilder stringBuilder = new StringBuilder();
+        stringBuilder.append("Subject: test\r\n\r\n");
+        String repeatedString = "This is the repeated body...\r\n";
+        int repeatCount = (maxSize / repeatedString.length()) + 1;
+        for (int i = 0; i < repeatCount; i++) {
+            stringBuilder.append(repeatedString);
+        }
+        stringBuilder.append("\r\n\r\n.\r\n");
+        smtpProtocol.sendShortMessageData(stringBuilder.toString());
+
+        // Then
+        assertThat(smtpProtocol.getReplyString()).isEqualTo("552 Quota 
exceeded\r\n");
+
+        // Finally
+        smtpProtocol.quit();
+        smtpProtocol.disconnect();
+    }
+
+    @Test
     public void testStartTLSInEHLO() throws Exception {
         smtpConfiguration.setStartTLS();
         init(smtpConfiguration);


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

Reply via email to