aboutsummaryrefslogtreecommitdiff
path: root/src/imap/ngx_imap_parse.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/imap/ngx_imap_parse.c')
-rw-r--r--src/imap/ngx_imap_parse.c152
1 files changed, 130 insertions, 22 deletions
diff --git a/src/imap/ngx_imap_parse.c b/src/imap/ngx_imap_parse.c
index 08ff86355..e29791d73 100644
--- a/src/imap/ngx_imap_parse.c
+++ b/src/imap/ngx_imap_parse.c
@@ -5,49 +5,75 @@
#include <ngx_imap.h>
-ngx_int_t ngx_pop3_parse_command(ngx_imap_request_t *r)
+ngx_int_t ngx_pop3_parse_command(ngx_imap_session_t *s)
{
- u_char ch, *p, *c;
+ u_char ch, *p, *c;
+ ngx_str_t *arg;
enum {
sw_start = 0,
+ sw_spaces_before_argument,
+ sw_argument,
+ sw_almost_done,
sw_done
} state;
- while (p < r->buf->last && state < sw_done) {
+ state = s->state;
+ p = s->buffer->pos;
+
+ while (p < s->buffer->last && state < sw_done) {
ch = *p++;
switch (state) {
- /* POP3 commands */
+ /* POP3 command */
+
case sw_start:
- if (ch == ' ') {
- c = r->buf->start;
+ if (ch == ' ' || ch == CR || ch == LF) {
+ c = s->buffer->start;
- if (p - 1 - m == 4) {
+ if (p - 1 - c == 4) {
- if (*c == 'U' && *(c + 1) == 'S'
- && *(c + 2) == 'E' && *(c + 3) == 'R')
+ if (c[0] == 'U' && c[1] == 'S'
+ && c[2] == 'E' && c[3] == 'R')
{
- r->command = NGX_POP3_USER;
+ s->command = NGX_POP3_USER;
- } else if (*c == 'P' && *(c + 1) == 'A'
- && *(c + 2) == 'A' && *(c + 3) == 'S')
+ } else if (c[0] == 'P' && c[1] == 'A'
+ && c[2] == 'A' && c[3] == 'S')
{
- r->method = NGX_POP3_PASS;
+ s->command = NGX_POP3_PASS;
- } else if (*c == 'Q' && *(c + 1) == 'U'
- && *(c + 2) == 'I' && *(c + 3) == 'T')
+ } else if (c[0] == 'Q' && c[1] == 'U'
+ && c[2] == 'I' && c[3] == 'T')
{
- r->method = NGX_POP3_QUIT;
+ s->command = NGX_POP3_QUIT;
- } else if (*c == 'N' && *(c + 1) == 'O'
- && *(c + 2) == 'O' && *(c + 3) == 'P')
+#if 0
+ } else if (c[0] == 'N' && c[1] == 'O'
+ && c[2] == 'O' && c[3] == 'P')
{
- r->method = NGX_POP3_NOOP;
+ s->command = NGX_POP3_NOOP;
+#endif
+
+ } else {
+ return NGX_IMAP_PARSE_INVALID_COMMAND;
}
+
+ } else {
+ return NGX_IMAP_PARSE_INVALID_COMMAND;
}
- state = sw_spaces_before_arg;
+ switch (ch) {
+ case ' ':
+ state = sw_spaces_before_argument;
+ break;
+ case CR:
+ state = sw_almost_done;
+ break;
+ case LF:
+ state = sw_done;
+ break;
+ }
break;
}
@@ -56,7 +82,72 @@ ngx_int_t ngx_pop3_parse_command(ngx_imap_request_t *r)
}
break;
- }
+
+ /* the spaces before the argument */
+ case sw_spaces_before_argument:
+ switch (ch) {
+ case ' ':
+ break;
+ case CR:
+ state = sw_almost_done;
+ s->arg_end = p - 1;
+ break;
+ case LF:
+ state = sw_done;
+ s->arg_end = p - 1;
+ break;
+ default:
+ if (s->args.nelts > 2) {
+ return NGX_IMAP_PARSE_INVALID_COMMAND;
+ }
+
+ state = sw_argument;
+ s->arg_start = p - 1;
+ break;
+ }
+ break;
+
+ /* the argument */
+ case sw_argument:
+ switch (ch) {
+ case ' ':
+ case CR:
+ case LF:
+ if (!(arg = ngx_array_push(&s->args))) {
+ return NGX_ERROR;
+ }
+ arg->len = p - s->arg_start;
+ arg->data = s->arg_start;
+ s->arg_start = NULL;
+
+ switch (ch) {
+ case ' ':
+ state = sw_spaces_before_argument;
+ break;
+ case CR:
+ state = sw_almost_done;
+ break;
+ case LF:
+ state = sw_done;
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ /* end of request line */
+ case sw_almost_done:
+ switch (ch) {
+ case LF:
+ state = sw_done;
+ break;
+ default:
+ return NGX_IMAP_PARSE_INVALID_COMMAND;
+ }
+ break;
/* suppress warning */
case sw_done:
@@ -64,5 +155,22 @@ ngx_int_t ngx_pop3_parse_command(ngx_imap_request_t *r)
}
}
- return NGX_OK;
+ s->buffer->pos = p;
+
+ if (state == sw_done) {
+ if (s->arg_start) {
+ if (!(arg = ngx_array_push(&s->args))) {
+ return NGX_ERROR;
+ }
+ arg->len = s->arg_end - s->arg_start;
+ arg->data = s->arg_start;
+ s->arg_start = NULL;
+ }
+
+ return NGX_OK;
+
+ } else {
+ s->state = state;
+ return NGX_AGAIN;
+ }
}