Mercurial > hg > nginx
annotate src/imap/ngx_imap_handler.c @ 541:b09ee85d0ac8 release-0.1.45
nginx-0.1.45-RELEASE import
*) Change: the "ssl_engine" directive was canceled in the
ngx_http_ssl_module and now is introduced at global level.
*) Bugfix: the responses with SSI subrequests did not transferred via
SSL connection.
*) Various bug fixes in the IMAP/POP3 proxy.
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Thu, 08 Sep 2005 14:36:09 +0000 |
parents | 371c1cee100d |
children | 511a89da35ad |
rev | line source |
---|---|
441
da8c5707af39
nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents:
423
diff
changeset
|
1 |
da8c5707af39
nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents:
423
diff
changeset
|
2 /* |
444
42d11f017717
nginx-0.1.0-2004-09-29-20:00:49 import; remove years from copyright
Igor Sysoev <igor@sysoev.ru>
parents:
441
diff
changeset
|
3 * Copyright (C) Igor Sysoev |
441
da8c5707af39
nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents:
423
diff
changeset
|
4 */ |
da8c5707af39
nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents:
423
diff
changeset
|
5 |
413
de9d4726e28a
nginx-0.0.10-2004-08-31-23:05:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
6 |
de9d4726e28a
nginx-0.0.10-2004-08-31-23:05:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
7 #include <ngx_config.h> |
de9d4726e28a
nginx-0.0.10-2004-08-31-23:05:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
8 #include <ngx_core.h> |
de9d4726e28a
nginx-0.0.10-2004-08-31-23:05:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
9 #include <ngx_event.h> |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
10 #include <ngx_imap.h> |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
11 |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
12 |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
13 static void ngx_imap_init_session(ngx_event_t *rev); |
541 | 14 static void ngx_imap_init_protocol(ngx_event_t *rev); |
527 | 15 static ngx_int_t ngx_imap_read_command(ngx_imap_session_t *s); |
541 | 16 static u_char *ngx_imap_log_error(ngx_log_t *log, u_char *buf, size_t len); |
413
de9d4726e28a
nginx-0.0.10-2004-08-31-23:05:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
17 |
539 | 18 #if (NGX_IMAP_SSL) |
19 static void ngx_imap_ssl_close_handler(ngx_event_t *ev); | |
20 #endif | |
21 | |
413
de9d4726e28a
nginx-0.0.10-2004-08-31-23:05:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
22 |
521 | 23 static ngx_str_t greetings[] = { |
527 | 24 ngx_string("+OK POP3 ready" CRLF), |
529 | 25 ngx_string("* OK IMAP4 ready" CRLF) |
521 | 26 }; |
27 | |
525 | 28 static ngx_str_t internal_server_errors[] = { |
29 ngx_string("-ERR internal server error" CRLF), | |
30 ngx_string("* BAD internal server error" CRLF), | |
31 }; | |
32 | |
521 | 33 static u_char pop3_ok[] = "+OK" CRLF; |
34 static u_char pop3_invalid_command[] = "-ERR invalid command" CRLF; | |
35 | |
529 | 36 static u_char imap_ok[] = "OK completed" CRLF; |
527 | 37 static u_char imap_next[] = "+ OK" CRLF; |
38 static u_char imap_bye[] = "* BYE" CRLF; | |
39 static u_char imap_invalid_command[] = "BAD invalid command" CRLF; | |
40 | |
521 | 41 |
42 void | |
43 ngx_imap_init_connection(ngx_connection_t *c) | |
413
de9d4726e28a
nginx-0.0.10-2004-08-31-23:05:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
44 { |
541 | 45 ngx_imap_log_ctx_t *ctx; |
46 | |
47 ngx_log_debug0(NGX_LOG_DEBUG_IMAP, c->log, 0, "imap init connection"); | |
48 | |
49 ctx = ngx_palloc(c->pool, sizeof(ngx_imap_log_ctx_t)); | |
50 if (ctx == NULL) { | |
51 ngx_imap_close_connection(c); | |
52 return; | |
53 } | |
54 | |
55 ctx->client = &c->addr_text; | |
56 ctx->session = NULL; | |
57 | |
58 c->log->connection = c->number; | |
59 c->log->handler = ngx_imap_log_error; | |
60 c->log->data = ctx; | |
61 c->log->action = "sending client greeting line"; | |
62 | |
63 c->log_error = NGX_ERROR_INFO; | |
64 | |
65 ngx_imap_init_session(c->read); | |
66 } | |
67 | |
68 | |
69 static void | |
70 ngx_imap_init_session(ngx_event_t *rev) | |
71 { | |
72 ngx_connection_t *c; | |
539 | 73 ngx_imap_session_t *s; |
541 | 74 ngx_imap_log_ctx_t *lctx; |
521 | 75 ngx_imap_conf_ctx_t *ctx; |
541 | 76 ngx_imap_core_srv_conf_t *cscf; |
539 | 77 #if (NGX_IMAP_SSL) |
78 ngx_int_t rc; | |
79 ngx_imap_ssl_conf_t *sslcf; | |
80 #endif | |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
81 |
541 | 82 c = rev->data; |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
83 |
521 | 84 ctx = c->ctx; |
539 | 85 |
541 | 86 cscf = ngx_imap_get_module_srv_conf(ctx, ngx_imap_core_module); |
87 | |
539 | 88 #if (NGX_IMAP_SSL) |
89 | |
90 sslcf = ngx_imap_get_module_srv_conf(ctx, ngx_imap_ssl_module); | |
91 | |
92 if (sslcf->enable) { | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
93 |
539 | 94 if (ngx_ssl_create_session(sslcf->ssl_ctx, c, NGX_SSL_BUFFER) |
95 == NGX_ERROR) | |
96 { | |
97 ngx_imap_close_connection(c); | |
98 return; | |
99 } | |
521 | 100 |
539 | 101 rc = ngx_ssl_handshake(c); |
102 | |
103 if (rc == NGX_ERROR) { | |
104 ngx_imap_close_connection(c); | |
105 return; | |
106 } | |
107 | |
541 | 108 if (rc == NGX_AGAIN) { |
109 ngx_add_timer(rev, cscf->timeout); | |
110 c->read->handler = ngx_imap_init_session; | |
111 | |
112 if (ngx_handle_read_event(rev, 0) == NGX_ERROR) { | |
113 ngx_imap_close_connection(c); | |
114 } | |
115 | |
116 return; | |
117 } | |
118 | |
539 | 119 c->recv = ngx_ssl_recv; |
120 c->send = ngx_ssl_write; | |
121 c->send_chain = ngx_ssl_send_chain; | |
122 } | |
123 | |
124 #endif | |
125 | |
126 s = ngx_pcalloc(c->pool, sizeof(ngx_imap_session_t)); | |
127 if (s == NULL) { | |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
128 ngx_imap_close_connection(c); |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
129 return; |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
130 } |
413
de9d4726e28a
nginx-0.0.10-2004-08-31-23:05:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
131 |
539 | 132 c->data = s; |
133 s->connection = c; | |
134 | |
135 s->protocol = cscf->protocol; | |
136 | |
137 s->ctx = ngx_pcalloc(c->pool, sizeof(void *) * ngx_imap_max_module); | |
138 if (s->ctx == NULL) { | |
139 ngx_imap_session_internal_server_error(s); | |
140 return; | |
141 } | |
142 | |
143 s->main_conf = ctx->main_conf; | |
144 s->srv_conf = ctx->srv_conf; | |
145 | |
146 s->out = greetings[s->protocol]; | |
147 | |
541 | 148 lctx = c->log->data; |
149 lctx->session = s; | |
150 | |
151 c->read->handler = ngx_imap_init_protocol; | |
539 | 152 c->write->handler = ngx_imap_send; |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
153 |
541 | 154 ngx_add_timer(rev, cscf->timeout); |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
155 |
541 | 156 if (ngx_handle_read_event(rev, 0) == NGX_ERROR) { |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
157 ngx_imap_close_connection(c); |
413
de9d4726e28a
nginx-0.0.10-2004-08-31-23:05:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
158 } |
539 | 159 |
160 ngx_imap_send(c->write); | |
161 } | |
162 | |
163 | |
164 void | |
165 ngx_imap_send(ngx_event_t *wev) | |
166 { | |
541 | 167 ngx_int_t n; |
168 ngx_connection_t *c; | |
169 ngx_imap_session_t *s; | |
170 ngx_imap_core_srv_conf_t *cscf; | |
539 | 171 |
172 c = wev->data; | |
173 s = c->data; | |
174 | |
175 if (wev->timedout) { | |
176 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out"); | |
177 ngx_imap_close_connection(c); | |
178 return; | |
179 } | |
180 | |
181 if (s->out.len == 0) { | |
182 if (ngx_handle_write_event(c->write, 0) == NGX_ERROR) { | |
183 ngx_imap_close_connection(c); | |
184 } | |
185 | |
186 return; | |
187 } | |
188 | |
189 n = c->send(c, s->out.data, s->out.len); | |
190 | |
191 if (n > 0) { | |
192 s->out.len -= n; | |
193 | |
541 | 194 if (wev->timer_set) { |
195 ngx_del_timer(wev); | |
196 } | |
197 | |
539 | 198 if (s->quit) { |
199 ngx_imap_close_connection(c); | |
200 return; | |
201 } | |
202 | |
203 if (s->blocked) { | |
204 c->read->handler(c->read); | |
205 } | |
206 | |
207 return; | |
208 } | |
209 | |
210 if (n == NGX_ERROR) { | |
211 ngx_imap_close_connection(c); | |
212 return; | |
213 } | |
214 | |
215 /* n == NGX_AGAIN */ | |
216 | |
541 | 217 cscf = ngx_imap_get_module_srv_conf(s, ngx_imap_core_module); |
218 | |
219 ngx_add_timer(c->write, cscf->timeout); | |
220 | |
539 | 221 if (ngx_handle_write_event(c->write, 0) == NGX_ERROR) { |
222 ngx_imap_close_connection(c); | |
223 return; | |
224 } | |
413
de9d4726e28a
nginx-0.0.10-2004-08-31-23:05:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
225 } |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
226 |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
227 |
521 | 228 static void |
541 | 229 ngx_imap_init_protocol(ngx_event_t *rev) |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
230 { |
521 | 231 size_t size; |
232 ngx_connection_t *c; | |
233 ngx_imap_session_t *s; | |
234 ngx_imap_core_srv_conf_t *cscf; | |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
235 |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
236 c = rev->data; |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
237 |
541 | 238 c->log->action = "in auth state"; |
239 | |
423
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
240 if (rev->timedout) { |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
241 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out"); |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
242 ngx_imap_close_connection(c); |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
243 return; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
244 } |
420
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
245 |
539 | 246 s = c->data; |
521 | 247 |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
248 if (ngx_array_init(&s->args, c->pool, 2, sizeof(ngx_str_t)) == NGX_ERROR) { |
527 | 249 ngx_imap_session_internal_server_error(s); |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
250 return; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
251 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
252 |
539 | 253 if (s->protocol == NGX_IMAP_POP3_PROTOCOL) { |
521 | 254 size = 128; |
527 | 255 s->imap_state = ngx_pop3_start; |
521 | 256 c->read->handler = ngx_pop3_auth_state; |
257 | |
258 } else { | |
539 | 259 cscf = ngx_imap_get_module_srv_conf(s, ngx_imap_core_module); |
521 | 260 size = cscf->imap_client_buffer_size; |
527 | 261 s->imap_state = ngx_imap_start; |
521 | 262 c->read->handler = ngx_imap_auth_state; |
263 } | |
420
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
264 |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
265 s->buffer = ngx_create_temp_buf(c->pool, size); |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
266 if (s->buffer == NULL) { |
527 | 267 ngx_imap_session_internal_server_error(s); |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
268 return; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
269 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
270 |
521 | 271 c->read->handler(rev); |
420
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
272 } |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
273 |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
274 |
527 | 275 void |
521 | 276 ngx_imap_auth_state(ngx_event_t *rev) |
277 { | |
539 | 278 u_char *text, *last, *p; |
279 ssize_t text_len, last_len; | |
527 | 280 ngx_str_t *arg; |
281 ngx_int_t rc; | |
539 | 282 ngx_uint_t tag; |
527 | 283 ngx_connection_t *c; |
284 ngx_imap_session_t *s; | |
285 ngx_imap_core_srv_conf_t *cscf; | |
521 | 286 |
287 c = rev->data; | |
527 | 288 s = c->data; |
521 | 289 |
527 | 290 ngx_log_debug0(NGX_LOG_DEBUG_IMAP, c->log, 0, "imap auth state"); |
291 | |
292 if (rev->timedout) { | |
293 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out"); | |
294 ngx_imap_close_connection(c); | |
295 return; | |
296 } | |
297 | |
539 | 298 if (s->out.len) { |
299 ngx_log_debug0(NGX_LOG_DEBUG_IMAP, c->log, 0, "imap send handler busy"); | |
300 s->blocked = 1; | |
301 return; | |
302 } | |
303 | |
304 s->blocked = 0; | |
305 | |
527 | 306 rc = ngx_imap_read_command(s); |
307 | |
308 ngx_log_debug1(NGX_LOG_DEBUG_IMAP, c->log, 0, "imap auth: %i", rc); | |
309 | |
310 if (rc == NGX_AGAIN || rc == NGX_ERROR) { | |
311 return; | |
312 } | |
313 | |
314 tag = 1; | |
315 | |
316 text = NULL; | |
317 text_len = 0; | |
318 | |
319 last = imap_ok; | |
320 last_len = sizeof(imap_ok) - 1; | |
321 | |
322 if (rc == NGX_OK) { | |
323 | |
324 ngx_log_debug1(NGX_LOG_DEBUG_IMAP, c->log, 0, "imap auth command: %i", | |
325 s->command); | |
326 | |
327 switch (s->command) { | |
328 | |
329 case NGX_IMAP_LOGIN: | |
330 if (s->args.nelts == 2) { | |
331 | |
332 arg = s->args.elts; | |
333 | |
334 s->login.len = arg[0].len; | |
335 s->login.data = ngx_palloc(c->pool, s->login.len); | |
336 if (s->login.data == NULL) { | |
337 ngx_imap_session_internal_server_error(s); | |
338 return; | |
339 } | |
340 | |
341 ngx_memcpy(s->login.data, arg[0].data, s->login.len); | |
342 | |
343 s->passwd.len = arg[1].len; | |
344 s->passwd.data = ngx_palloc(c->pool, s->passwd.len); | |
345 if (s->passwd.data == NULL) { | |
346 ngx_imap_session_internal_server_error(s); | |
347 return; | |
348 } | |
349 | |
350 ngx_memcpy(s->passwd.data, arg[1].data, s->passwd.len); | |
351 | |
352 ngx_log_debug2(NGX_LOG_DEBUG_IMAP, c->log, 0, | |
353 "imap login:\"%V\" passwd:\"%V\"", | |
354 &s->login, &s->passwd); | |
355 | |
356 s->args.nelts = 0; | |
357 s->buffer->pos = s->buffer->start; | |
358 s->buffer->last = s->buffer->start; | |
359 | |
360 if (rev->timer_set) { | |
361 ngx_del_timer(rev); | |
362 } | |
363 | |
364 s->login_attempt++; | |
365 | |
366 ngx_imap_auth_http_init(s); | |
367 | |
368 return; | |
369 | |
370 } else { | |
371 rc = NGX_IMAP_PARSE_INVALID_COMMAND; | |
372 } | |
373 | |
374 break; | |
375 | |
376 case NGX_IMAP_CAPABILITY: | |
377 cscf = ngx_imap_get_module_srv_conf(s, ngx_imap_core_module); | |
378 text = cscf->imap_capability->pos; | |
379 text_len = cscf->imap_capability->last - cscf->imap_capability->pos; | |
380 break; | |
381 | |
382 case NGX_IMAP_LOGOUT: | |
539 | 383 s->quit = 1; |
527 | 384 text = imap_bye; |
385 text_len = sizeof(imap_bye) - 1; | |
386 break; | |
387 | |
388 case NGX_IMAP_NOOP: | |
389 break; | |
390 | |
391 default: | |
392 rc = NGX_IMAP_PARSE_INVALID_COMMAND; | |
393 break; | |
394 } | |
395 | |
396 } else if (rc == NGX_IMAP_NEXT) { | |
397 last = imap_next; | |
398 last_len = sizeof(imap_next) - 1; | |
399 tag = 0; | |
400 } | |
401 | |
402 if (rc == NGX_IMAP_PARSE_INVALID_COMMAND) { | |
403 last = imap_invalid_command; | |
404 last_len = sizeof(imap_invalid_command) - 1; | |
405 } | |
406 | |
407 if (tag) { | |
539 | 408 if (s->tagged_line.len < s->tag.len + text_len + last_len) { |
409 s->tagged_line.len = s->tag.len + text_len + last_len; | |
410 s->tagged_line.data = ngx_palloc(c->pool, s->tagged_line.len); | |
411 if (s->tagged_line.data == NULL) { | |
527 | 412 ngx_imap_close_connection(c); |
413 return; | |
414 } | |
415 } | |
416 | |
539 | 417 s->out.data = s->tagged_line.data; |
418 s->out.len = s->tag.len + text_len + last_len; | |
419 | |
420 p = s->out.data; | |
527 | 421 |
422 if (text) { | |
423 p = ngx_cpymem(p, text, text_len); | |
424 } | |
425 p = ngx_cpymem(p, s->tag.data, s->tag.len); | |
426 ngx_memcpy(p, last, last_len); | |
427 | |
428 | |
429 } else { | |
539 | 430 s->out.data = last; |
431 s->out.len = last_len; | |
527 | 432 } |
433 | |
539 | 434 if (rc != NGX_IMAP_NEXT) { |
435 s->args.nelts = 0; | |
436 s->buffer->pos = s->buffer->start; | |
437 s->buffer->last = s->buffer->start; | |
438 s->tag.len = 0; | |
527 | 439 } |
440 | |
539 | 441 ngx_imap_send(c->write); |
521 | 442 } |
443 | |
444 | |
527 | 445 void |
521 | 446 ngx_pop3_auth_state(ngx_event_t *rev) |
420
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
447 { |
527 | 448 u_char *text; |
449 ssize_t size; | |
450 ngx_int_t rc; | |
451 ngx_str_t *arg; | |
452 ngx_connection_t *c; | |
453 ngx_imap_session_t *s; | |
454 ngx_imap_core_srv_conf_t *cscf; | |
420
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
455 |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
456 c = rev->data; |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
457 s = c->data; |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
458 |
421
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
459 ngx_log_debug0(NGX_LOG_DEBUG_IMAP, c->log, 0, "pop3 auth state"); |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
460 |
423
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
461 if (rev->timedout) { |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
462 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out"); |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
463 ngx_imap_close_connection(c); |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
464 return; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
465 } |
420
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
466 |
539 | 467 if (s->out.len) { |
468 ngx_log_debug0(NGX_LOG_DEBUG_IMAP, c->log, 0, "imap send handler busy"); | |
469 s->blocked = 1; | |
470 return; | |
471 } | |
472 | |
473 s->blocked = 0; | |
474 | |
527 | 475 rc = ngx_imap_read_command(s); |
420
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
476 |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
477 if (rc == NGX_AGAIN || rc == NGX_ERROR) { |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
478 return; |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
479 } |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
480 |
421
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
481 text = pop3_ok; |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
482 size = sizeof(pop3_ok) - 1; |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
483 |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
484 if (rc == NGX_OK) { |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
485 switch (s->imap_state) { |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
486 |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
487 case ngx_pop3_start: |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
488 |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
489 switch (s->command) { |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
490 |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
491 case NGX_POP3_USER: |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
492 if (s->args.nelts == 1) { |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
493 s->imap_state = ngx_pop3_user; |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
494 |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
495 arg = s->args.elts; |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
496 s->login.len = arg[0].len; |
527 | 497 s->login.data = ngx_palloc(c->pool, s->login.len); |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
498 if (s->login.data == NULL) { |
527 | 499 ngx_imap_session_internal_server_error(s); |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
500 return; |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
501 } |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
502 |
527 | 503 ngx_memcpy(s->login.data, arg[0].data, s->login.len); |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
504 |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
505 ngx_log_debug1(NGX_LOG_DEBUG_IMAP, c->log, 0, |
527 | 506 "pop3 login: \"%V\"", &s->login); |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
507 |
421
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
508 } else { |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
509 rc = NGX_IMAP_PARSE_INVALID_COMMAND; |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
510 } |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
511 |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
512 break; |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
513 |
527 | 514 case NGX_POP3_CAPA: |
515 cscf = ngx_imap_get_module_srv_conf(s, ngx_imap_core_module); | |
516 text = cscf->pop3_capability->pos; | |
517 size = cscf->pop3_capability->last - cscf->pop3_capability->pos; | |
518 break; | |
519 | |
421
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
520 case NGX_POP3_QUIT: |
539 | 521 s->quit = 1; |
421
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
522 break; |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
523 |
527 | 524 case NGX_POP3_NOOP: |
525 break; | |
526 | |
421
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
527 default: |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
528 s->imap_state = ngx_pop3_start; |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
529 rc = NGX_IMAP_PARSE_INVALID_COMMAND; |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
530 break; |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
531 } |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
532 |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
533 break; |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
534 |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
535 case ngx_pop3_user: |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
536 |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
537 switch (s->command) { |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
538 |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
539 case NGX_POP3_PASS: |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
540 if (s->args.nelts == 1) { |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
541 /* STUB */ s->imap_state = ngx_pop3_start; |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
542 |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
543 arg = s->args.elts; |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
544 s->passwd.len = arg[0].len; |
527 | 545 s->passwd.data = ngx_palloc(c->pool, s->passwd.len); |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
546 if (s->passwd.data == NULL) { |
527 | 547 ngx_imap_session_internal_server_error(s); |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
548 return; |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
549 } |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
550 |
527 | 551 ngx_memcpy(s->passwd.data, arg[0].data, s->passwd.len); |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
552 |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
553 ngx_log_debug1(NGX_LOG_DEBUG_IMAP, c->log, 0, |
527 | 554 "pop3 passwd: \"%V\"", &s->passwd); |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
555 |
527 | 556 s->args.nelts = 0; |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
557 s->buffer->pos = s->buffer->start; |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
558 s->buffer->last = s->buffer->start; |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
559 |
527 | 560 if (rev->timer_set) { |
561 ngx_del_timer(rev); | |
562 } | |
563 | |
521 | 564 ngx_imap_auth_http_init(s); |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
565 |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
566 return; |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
567 |
421
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
568 } else { |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
569 rc = NGX_IMAP_PARSE_INVALID_COMMAND; |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
570 } |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
571 |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
572 break; |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
573 |
527 | 574 case NGX_POP3_CAPA: |
575 cscf = ngx_imap_get_module_srv_conf(s, ngx_imap_core_module); | |
576 text = cscf->pop3_capability->pos; | |
577 size = cscf->pop3_capability->last - cscf->pop3_capability->pos; | |
578 break; | |
579 | |
421
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
580 case NGX_POP3_QUIT: |
539 | 581 s->quit = 1; |
421
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
582 break; |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
583 |
527 | 584 case NGX_POP3_NOOP: |
585 break; | |
586 | |
421
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
587 default: |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
588 s->imap_state = ngx_pop3_start; |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
589 rc = NGX_IMAP_PARSE_INVALID_COMMAND; |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
590 break; |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
591 } |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
592 |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
593 break; |
527 | 594 |
595 /* suppress warinings */ | |
596 case ngx_pop3_passwd: | |
597 break; | |
421
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
598 } |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
599 } |
420
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
600 |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
601 if (rc == NGX_IMAP_PARSE_INVALID_COMMAND) { |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
602 text = pop3_invalid_command; |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
603 size = sizeof(pop3_invalid_command) - 1; |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
604 } |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
605 |
421
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
606 s->args.nelts = 0; |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
607 s->buffer->pos = s->buffer->start; |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
608 s->buffer->last = s->buffer->start; |
539 | 609 |
610 s->out.data = text; | |
611 s->out.len = size; | |
612 | |
613 ngx_imap_send(c->write); | |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
614 } |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
615 |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
616 |
521 | 617 static ngx_int_t |
527 | 618 ngx_imap_read_command(ngx_imap_session_t *s) |
420
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
619 { |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
620 ssize_t n; |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
621 ngx_int_t rc; |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
622 |
539 | 623 n = s->connection->recv(s->connection, s->buffer->last, |
624 s->buffer->end - s->buffer->last); | |
420
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
625 |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
626 if (n == NGX_ERROR || n == 0) { |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
627 ngx_imap_close_connection(s->connection); |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
628 return NGX_ERROR; |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
629 } |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
630 |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
631 if (n > 0) { |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
632 s->buffer->last += n; |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
633 } |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
634 |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
635 if (n == NGX_AGAIN) { |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
636 if (ngx_handle_read_event(s->connection->read, 0) == NGX_ERROR) { |
527 | 637 ngx_imap_session_internal_server_error(s); |
420
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
638 return NGX_ERROR; |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
639 } |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
640 |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
641 return NGX_AGAIN; |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
642 } |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
643 |
527 | 644 if (s->protocol == NGX_IMAP_POP3_PROTOCOL) { |
645 rc = ngx_pop3_parse_command(s); | |
646 } else { | |
647 rc = ngx_imap_parse_command(s); | |
648 } | |
420
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
649 |
527 | 650 if (rc == NGX_AGAIN |
651 || rc == NGX_IMAP_NEXT | |
652 || rc == NGX_IMAP_PARSE_INVALID_COMMAND) | |
653 { | |
420
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
654 return rc; |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
655 } |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
656 |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
657 if (rc == NGX_ERROR) { |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
658 ngx_imap_close_connection(s->connection); |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
659 return NGX_ERROR; |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
660 } |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
661 |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
662 return NGX_OK; |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
663 } |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
664 |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
665 |
521 | 666 void |
525 | 667 ngx_imap_session_internal_server_error(ngx_imap_session_t *s) |
668 { | |
539 | 669 s->out = internal_server_errors[s->protocol]; |
670 s->quit = 1; | |
525 | 671 |
539 | 672 ngx_imap_send(s->connection->write); |
525 | 673 } |
674 | |
675 | |
676 void | |
521 | 677 ngx_imap_close_connection(ngx_connection_t *c) |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
678 { |
479 | 679 ngx_pool_t *pool; |
680 | |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
681 ngx_log_debug1(NGX_LOG_DEBUG_IMAP, c->log, 0, |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
682 "close imap connection: %d", c->fd); |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
683 |
539 | 684 #if (NGX_IMAP_SSL) |
685 | |
686 if (c->ssl) { | |
687 if (ngx_ssl_shutdown(c) == NGX_AGAIN) { | |
688 c->read->handler = ngx_imap_ssl_close_handler; | |
689 c->write->handler = ngx_imap_ssl_close_handler; | |
690 return; | |
691 } | |
692 } | |
693 | |
694 #endif | |
695 | |
479 | 696 pool = c->pool; |
697 | |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
698 ngx_close_connection(c); |
479 | 699 |
501 | 700 ngx_destroy_pool(pool); |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
701 } |
539 | 702 |
703 | |
704 #if (NGX_IMAP_SSL) | |
705 | |
706 static void | |
707 ngx_imap_ssl_close_handler(ngx_event_t *ev) | |
708 { | |
709 ngx_connection_t *c; | |
710 | |
711 c = ev->data; | |
712 | |
713 ngx_log_debug0(NGX_LOG_DEBUG_IMAP, ev->log, 0, "http ssl close handler"); | |
714 | |
715 if (ngx_ssl_shutdown(c) == NGX_AGAIN) { | |
716 return; | |
717 } | |
718 | |
719 ngx_imap_close_connection(c); | |
720 } | |
721 | |
722 #endif | |
541 | 723 |
724 | |
725 static u_char * | |
726 ngx_imap_log_error(ngx_log_t *log, u_char *buf, size_t len) | |
727 { | |
728 u_char *p; | |
729 ngx_imap_session_t *s; | |
730 ngx_imap_log_ctx_t *ctx; | |
731 | |
732 if (log->action) { | |
733 p = ngx_snprintf(buf, len, " while %s", log->action); | |
734 len -= p - buf; | |
735 buf = p; | |
736 } | |
737 | |
738 ctx = log->data; | |
739 | |
740 p = ngx_snprintf(buf, len, ", client: %V", ctx->client); | |
741 len -= p - buf; | |
742 buf = p; | |
743 | |
744 s = ctx->session; | |
745 | |
746 if (s == NULL) { | |
747 return p; | |
748 } | |
749 | |
750 p = ngx_snprintf(buf, len, ", server: %V", | |
751 &s->connection->listening->addr_text); | |
752 len -= p - buf; | |
753 buf = p; | |
754 | |
755 if (s->login.len == 0) { | |
756 return p; | |
757 } | |
758 | |
759 p = ngx_snprintf(buf, len, ", login: \"%V\"", &s->login); | |
760 len -= p - buf; | |
761 buf = p; | |
762 | |
763 if (s->proxy == NULL) { | |
764 return p; | |
765 } | |
766 | |
767 p = ngx_snprintf(buf, len, ", upstream: %V", | |
768 &s->proxy->upstream.peers->peer[0].name); | |
769 | |
770 return p; | |
771 } |