Mercurial > hg > nginx
comparison src/mail/ngx_mail_parse.c @ 7838:815c63581be4
Mail: POP3 pipelining support.
The change is mostly the same as the SMTP one (04e43d03e153 and 3f5d0af4e40a),
and ensures that nginx is able to properly handle or reject multiple POP3
commands, as required by the PIPELINING capability (RFC 2449). The s->cmd
field is not really used and set for consistency.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Wed, 19 May 2021 03:13:18 +0300 |
parents | ba8a8299b904 |
children | 3974f4e56a4e |
comparison
equal
deleted
inserted
replaced
7837:ba8a8299b904 | 7838:815c63581be4 |
---|---|
19 { | 19 { |
20 u_char ch, *p, *c, c0, c1, c2, c3; | 20 u_char ch, *p, *c, c0, c1, c2, c3; |
21 ngx_str_t *arg; | 21 ngx_str_t *arg; |
22 enum { | 22 enum { |
23 sw_start = 0, | 23 sw_start = 0, |
24 sw_command, | |
25 sw_invalid, | |
24 sw_spaces_before_argument, | 26 sw_spaces_before_argument, |
25 sw_argument, | 27 sw_argument, |
26 sw_almost_done | 28 sw_almost_done |
27 } state; | 29 } state; |
28 | 30 |
33 | 35 |
34 switch (state) { | 36 switch (state) { |
35 | 37 |
36 /* POP3 command */ | 38 /* POP3 command */ |
37 case sw_start: | 39 case sw_start: |
40 s->cmd_start = p; | |
41 state = sw_command; | |
42 | |
43 /* fall through */ | |
44 | |
45 case sw_command: | |
38 if (ch == ' ' || ch == CR || ch == LF) { | 46 if (ch == ' ' || ch == CR || ch == LF) { |
39 c = s->buffer->start; | 47 c = s->cmd_start; |
40 | 48 |
41 if (p - c == 4) { | 49 if (p - c == 4) { |
42 | 50 |
43 c0 = ngx_toupper(c[0]); | 51 c0 = ngx_toupper(c[0]); |
44 c1 = ngx_toupper(c[1]); | 52 c1 = ngx_toupper(c[1]); |
83 | 91 |
84 } else { | 92 } else { |
85 goto invalid; | 93 goto invalid; |
86 } | 94 } |
87 | 95 |
96 s->cmd.data = s->cmd_start; | |
97 s->cmd.len = p - s->cmd_start; | |
98 | |
88 switch (ch) { | 99 switch (ch) { |
89 case ' ': | 100 case ' ': |
90 state = sw_spaces_before_argument; | 101 state = sw_spaces_before_argument; |
91 break; | 102 break; |
92 case CR: | 103 case CR: |
101 if ((ch < 'A' || ch > 'Z') && (ch < 'a' || ch > 'z')) { | 112 if ((ch < 'A' || ch > 'Z') && (ch < 'a' || ch > 'z')) { |
102 goto invalid; | 113 goto invalid; |
103 } | 114 } |
104 | 115 |
105 break; | 116 break; |
117 | |
118 case sw_invalid: | |
119 goto invalid; | |
106 | 120 |
107 case sw_spaces_before_argument: | 121 case sw_spaces_before_argument: |
108 switch (ch) { | 122 switch (ch) { |
109 case ' ': | 123 case ' ': |
110 break; | 124 break; |
203 | 217 |
204 return NGX_OK; | 218 return NGX_OK; |
205 | 219 |
206 invalid: | 220 invalid: |
207 | 221 |
208 s->state = sw_start; | 222 s->state = sw_invalid; |
209 s->arg_start = NULL; | 223 s->arg_start = NULL; |
210 | 224 |
211 return NGX_MAIL_PARSE_INVALID_COMMAND; | 225 /* skip invalid command till LF */ |
226 | |
227 for ( /* void */ ; p < s->buffer->last; p++) { | |
228 if (*p == LF) { | |
229 s->state = sw_start; | |
230 s->buffer->pos = p + 1; | |
231 return NGX_MAIL_PARSE_INVALID_COMMAND; | |
232 } | |
233 } | |
234 | |
235 s->buffer->pos = p; | |
236 | |
237 return NGX_AGAIN; | |
212 } | 238 } |
213 | 239 |
214 | 240 |
215 ngx_int_t | 241 ngx_int_t |
216 ngx_mail_imap_parse_command(ngx_mail_session_t *s) | 242 ngx_mail_imap_parse_command(ngx_mail_session_t *s) |