diff src/mail/ngx_mail_smtp_handler.c @ 5398:04e43d03e153

Mail: smtp pipelining support. Basically, this does the following two changes (and corresponding modifications of related code): 1. Does not reset session buffer unless it's reached it's end, and always wait for LF to terminate command (even if we detected invalid command). 2. Record command name to make it available for handlers (since now we can't assume that command starts from s->buffer->start).
author Maxim Dounin <mdounin@mdounin.ru>
date Mon, 30 Sep 2013 22:09:57 +0400
parents 42f874c0b970
children 07dd5bd222ac
line wrap: on
line diff
--- a/src/mail/ngx_mail_smtp_handler.c
+++ b/src/mail/ngx_mail_smtp_handler.c
@@ -486,6 +486,10 @@ ngx_mail_smtp_auth_state(ngx_event_t *re
         }
     }
 
+    if (s->buffer->pos < s->buffer->last) {
+        s->blocked = 1;
+    }
+
     switch (rc) {
 
     case NGX_DONE:
@@ -505,11 +509,14 @@ ngx_mail_smtp_auth_state(ngx_event_t *re
 
     case NGX_OK:
         s->args.nelts = 0;
-        s->buffer->pos = s->buffer->start;
-        s->buffer->last = s->buffer->start;
+
+        if (s->buffer->pos == s->buffer->last) {
+            s->buffer->pos = s->buffer->start;
+            s->buffer->last = s->buffer->start;
+        }
 
         if (s->state) {
-            s->arg_start = s->buffer->start;
+            s->arg_start = s->buffer->pos;
         }
 
         ngx_mail_send(c->write);
@@ -652,9 +659,7 @@ ngx_mail_smtp_auth(ngx_mail_session_t *s
 static ngx_int_t
 ngx_mail_smtp_mail(ngx_mail_session_t *s, ngx_connection_t *c)
 {
-    u_char                     ch;
-    ngx_str_t                  l;
-    ngx_uint_t                 i;
+    ngx_str_t                 *arg, cmd;
     ngx_mail_smtp_srv_conf_t  *sscf;
 
     sscf = ngx_mail_get_module_srv_conf(s, ngx_mail_smtp_module);
@@ -672,37 +677,20 @@ ngx_mail_smtp_mail(ngx_mail_session_t *s
         return NGX_OK;
     }
 
-    l.len = s->buffer->last - s->buffer->start;
-    l.data = s->buffer->start;
-
-    for (i = 0; i < l.len; i++) {
-        ch = l.data[i];
-
-        if (ch != CR && ch != LF) {
-            continue;
-        }
-
-        l.data[i] = ' ';
-    }
+    arg = s->args.elts;
+    arg += s->args.nelts - 1;
 
-    while (i) {
-        if (l.data[i - 1] != ' ') {
-            break;
-        }
+    cmd.len = arg->data + arg->len - s->cmd.data;
+    cmd.data = s->cmd.data;
 
-        i--;
-    }
+    s->smtp_from.len = cmd.len;
 
-    l.len = i;
-
-    s->smtp_from.len = l.len;
-
-    s->smtp_from.data = ngx_pnalloc(c->pool, l.len);
+    s->smtp_from.data = ngx_pnalloc(c->pool, cmd.len);
     if (s->smtp_from.data == NULL) {
         return NGX_ERROR;
     }
 
-    ngx_memcpy(s->smtp_from.data, l.data, l.len);
+    ngx_memcpy(s->smtp_from.data, cmd.data, cmd.len);
 
     ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
                    "smtp mail from:\"%V\"", &s->smtp_from);
@@ -716,46 +704,27 @@ ngx_mail_smtp_mail(ngx_mail_session_t *s
 static ngx_int_t
 ngx_mail_smtp_rcpt(ngx_mail_session_t *s, ngx_connection_t *c)
 {
-    u_char      ch;
-    ngx_str_t   l;
-    ngx_uint_t  i;
+    ngx_str_t  *arg, cmd;
 
     if (s->smtp_from.len == 0) {
         ngx_str_set(&s->out, smtp_bad_sequence);
         return NGX_OK;
     }
 
-    l.len = s->buffer->last - s->buffer->start;
-    l.data = s->buffer->start;
-
-    for (i = 0; i < l.len; i++) {
-        ch = l.data[i];
-
-        if (ch != CR && ch != LF) {
-            continue;
-        }
-
-        l.data[i] = ' ';
-    }
+    arg = s->args.elts;
+    arg += s->args.nelts - 1;
 
-    while (i) {
-        if (l.data[i - 1] != ' ') {
-            break;
-        }
+    cmd.len = arg->data + arg->len - s->cmd.data;
+    cmd.data = s->cmd.data;
 
-        i--;
-    }
+    s->smtp_to.len = cmd.len;
 
-    l.len = i;
-
-    s->smtp_to.len = l.len;
-
-    s->smtp_to.data = ngx_pnalloc(c->pool, l.len);
+    s->smtp_to.data = ngx_pnalloc(c->pool, cmd.len);
     if (s->smtp_to.data == NULL) {
         return NGX_ERROR;
     }
 
-    ngx_memcpy(s->smtp_to.data, l.data, l.len);
+    ngx_memcpy(s->smtp_to.data, cmd.data, cmd.len);
 
     ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
                    "smtp rcpt to:\"%V\"", &s->smtp_to);