Mercurial > hg > nginx-vendor-0-6
comparison src/imap/ngx_imap_handler.c @ 88:e916a291e9aa NGINX_0_1_44
nginx 0.1.44
*) Feature: the IMAP/POP3 proxy supports SSL.
*) Feature: the "proxy_timeout" directive of the ngx_imap_proxy_module.
*) Feature: the "userid_mark" directive.
*) Feature: the $remote_user variable value is determined independently
of authorization use.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Tue, 06 Sep 2005 00:00:00 +0400 |
parents | 9db7e0b5b27f |
children | 71c46860eb55 |
comparison
equal
deleted
inserted
replaced
87:5b7ec80c3c40 | 88:e916a291e9aa |
---|---|
11 | 11 |
12 | 12 |
13 static void ngx_imap_init_session(ngx_event_t *rev); | 13 static void ngx_imap_init_session(ngx_event_t *rev); |
14 static ngx_int_t ngx_imap_read_command(ngx_imap_session_t *s); | 14 static ngx_int_t ngx_imap_read_command(ngx_imap_session_t *s); |
15 | 15 |
16 #if (NGX_IMAP_SSL) | |
17 static void ngx_imap_ssl_close_handler(ngx_event_t *ev); | |
18 #endif | |
19 | |
16 | 20 |
17 static ngx_str_t greetings[] = { | 21 static ngx_str_t greetings[] = { |
18 ngx_string("+OK POP3 ready" CRLF), | 22 ngx_string("+OK POP3 ready" CRLF), |
19 ngx_string("* OK IMAP4 ready" CRLF) | 23 ngx_string("* OK IMAP4 ready" CRLF) |
20 }; | 24 }; |
34 | 38 |
35 | 39 |
36 void | 40 void |
37 ngx_imap_init_connection(ngx_connection_t *c) | 41 ngx_imap_init_connection(ngx_connection_t *c) |
38 { | 42 { |
39 ssize_t size; | 43 ngx_imap_session_t *s; |
40 ngx_imap_conf_ctx_t *ctx; | 44 ngx_imap_conf_ctx_t *ctx; |
45 #if (NGX_IMAP_SSL) | |
46 ngx_int_t rc; | |
47 ngx_imap_ssl_conf_t *sslcf; | |
48 #endif | |
41 ngx_imap_core_srv_conf_t *cscf; | 49 ngx_imap_core_srv_conf_t *cscf; |
42 | 50 |
43 ngx_log_debug0(NGX_LOG_DEBUG_IMAP, c->log, 0, "imap init connection"); | 51 ngx_log_debug0(NGX_LOG_DEBUG_IMAP, c->log, 0, "imap init connection"); |
44 | 52 |
45 c->log_error = NGX_ERROR_INFO; | 53 c->log_error = NGX_ERROR_INFO; |
46 | 54 |
47 ctx = c->ctx; | 55 ctx = c->ctx; |
56 | |
57 #if (NGX_IMAP_SSL) | |
58 | |
59 sslcf = ngx_imap_get_module_srv_conf(ctx, ngx_imap_ssl_module); | |
60 | |
61 if (sslcf->enable) { | |
62 | |
63 if (ngx_ssl_create_session(sslcf->ssl_ctx, c, NGX_SSL_BUFFER) | |
64 == NGX_ERROR) | |
65 { | |
66 ngx_imap_close_connection(c); | |
67 return; | |
68 } | |
69 | |
70 rc = ngx_ssl_handshake(c); | |
71 | |
72 if (rc == NGX_ERROR) { | |
73 ngx_imap_close_connection(c); | |
74 return; | |
75 } | |
76 | |
77 c->recv = ngx_ssl_recv; | |
78 c->send = ngx_ssl_write; | |
79 c->send_chain = ngx_ssl_send_chain; | |
80 } | |
81 | |
82 #endif | |
83 | |
84 s = ngx_pcalloc(c->pool, sizeof(ngx_imap_session_t)); | |
85 if (s == NULL) { | |
86 ngx_imap_close_connection(c); | |
87 return; | |
88 } | |
89 | |
90 c->data = s; | |
91 s->connection = c; | |
92 | |
48 cscf = ngx_imap_get_module_srv_conf(ctx, ngx_imap_core_module); | 93 cscf = ngx_imap_get_module_srv_conf(ctx, ngx_imap_core_module); |
49 | 94 s->protocol = cscf->protocol; |
50 size = greetings[cscf->protocol].len; | 95 |
51 | 96 s->ctx = ngx_pcalloc(c->pool, sizeof(void *) * ngx_imap_max_module); |
52 if (ngx_send(c, greetings[cscf->protocol].data, size) < size) { | 97 if (s->ctx == NULL) { |
53 /* | 98 ngx_imap_session_internal_server_error(s); |
54 * we treat the incomplete sending as NGX_ERROR | 99 return; |
55 * because it is very strange here | 100 } |
56 */ | 101 |
57 ngx_imap_close_connection(c); | 102 s->main_conf = ctx->main_conf; |
58 return; | 103 s->srv_conf = ctx->srv_conf; |
59 } | 104 |
105 s->out = greetings[s->protocol]; | |
60 | 106 |
61 c->read->handler = ngx_imap_init_session; | 107 c->read->handler = ngx_imap_init_session; |
62 | 108 c->write->handler = ngx_imap_send; |
109 | |
110 ngx_add_timer(c->write, cscf->timeout); | |
63 ngx_add_timer(c->read, cscf->timeout); | 111 ngx_add_timer(c->read, cscf->timeout); |
64 | 112 |
65 if (ngx_handle_read_event(c->read, 0) == NGX_ERROR) { | 113 if (ngx_handle_read_event(c->read, 0) == NGX_ERROR) { |
66 ngx_imap_close_connection(c); | 114 ngx_imap_close_connection(c); |
115 } | |
116 | |
117 ngx_imap_send(c->write); | |
118 } | |
119 | |
120 | |
121 void | |
122 ngx_imap_send(ngx_event_t *wev) | |
123 { | |
124 ngx_int_t n; | |
125 ngx_connection_t *c; | |
126 ngx_imap_session_t *s; | |
127 | |
128 c = wev->data; | |
129 s = c->data; | |
130 | |
131 if (wev->timedout) { | |
132 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out"); | |
133 ngx_imap_close_connection(c); | |
134 return; | |
135 } | |
136 | |
137 if (s->out.len == 0) { | |
138 if (ngx_handle_write_event(c->write, 0) == NGX_ERROR) { | |
139 ngx_imap_close_connection(c); | |
140 } | |
141 | |
142 return; | |
143 } | |
144 | |
145 n = c->send(c, s->out.data, s->out.len); | |
146 | |
147 if (n > 0) { | |
148 s->out.len -= n; | |
149 | |
150 if (s->quit) { | |
151 ngx_imap_close_connection(c); | |
152 return; | |
153 } | |
154 | |
155 if (s->blocked) { | |
156 c->read->handler(c->read); | |
157 } | |
158 | |
159 return; | |
160 } | |
161 | |
162 if (n == NGX_ERROR) { | |
163 ngx_imap_close_connection(c); | |
164 return; | |
165 } | |
166 | |
167 /* n == NGX_AGAIN */ | |
168 | |
169 if (ngx_handle_write_event(c->write, 0) == NGX_ERROR) { | |
170 ngx_imap_close_connection(c); | |
171 return; | |
67 } | 172 } |
68 } | 173 } |
69 | 174 |
70 | 175 |
71 static void | 176 static void |
72 ngx_imap_init_session(ngx_event_t *rev) | 177 ngx_imap_init_session(ngx_event_t *rev) |
73 { | 178 { |
74 size_t size; | 179 size_t size; |
75 ngx_connection_t *c; | 180 ngx_connection_t *c; |
76 ngx_imap_session_t *s; | 181 ngx_imap_session_t *s; |
77 ngx_imap_conf_ctx_t *ctx; | |
78 ngx_imap_core_srv_conf_t *cscf; | 182 ngx_imap_core_srv_conf_t *cscf; |
79 | 183 |
80 c = rev->data; | 184 c = rev->data; |
81 | 185 |
82 if (rev->timedout) { | 186 if (rev->timedout) { |
83 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out"); | 187 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out"); |
84 ngx_imap_close_connection(c); | 188 ngx_imap_close_connection(c); |
85 return; | 189 return; |
86 } | 190 } |
87 | 191 |
88 s = ngx_pcalloc(c->pool, sizeof(ngx_imap_session_t)); | 192 s = c->data; |
89 if (s == NULL) { | |
90 ngx_imap_session_internal_server_error(s); | |
91 return; | |
92 } | |
93 | |
94 c->data = s; | |
95 s->connection = c; | |
96 | |
97 s->ctx = ngx_pcalloc(c->pool, sizeof(void *) * ngx_imap_max_module); | |
98 if (s->ctx == NULL) { | |
99 ngx_imap_session_internal_server_error(s); | |
100 return; | |
101 } | |
102 | |
103 ctx = c->ctx; | |
104 s->main_conf = ctx->main_conf; | |
105 s->srv_conf = ctx->srv_conf; | |
106 | 193 |
107 if (ngx_array_init(&s->args, c->pool, 2, sizeof(ngx_str_t)) == NGX_ERROR) { | 194 if (ngx_array_init(&s->args, c->pool, 2, sizeof(ngx_str_t)) == NGX_ERROR) { |
108 ngx_imap_session_internal_server_error(s); | 195 ngx_imap_session_internal_server_error(s); |
109 return; | 196 return; |
110 } | 197 } |
111 | 198 |
112 cscf = ngx_imap_get_module_srv_conf(s, ngx_imap_core_module); | 199 if (s->protocol == NGX_IMAP_POP3_PROTOCOL) { |
113 | |
114 s->protocol = cscf->protocol; | |
115 | |
116 if (cscf->protocol == NGX_IMAP_POP3_PROTOCOL) { | |
117 size = 128; | 200 size = 128; |
118 s->imap_state = ngx_pop3_start; | 201 s->imap_state = ngx_pop3_start; |
119 c->read->handler = ngx_pop3_auth_state; | 202 c->read->handler = ngx_pop3_auth_state; |
120 | 203 |
121 } else { | 204 } else { |
205 cscf = ngx_imap_get_module_srv_conf(s, ngx_imap_core_module); | |
122 size = cscf->imap_client_buffer_size; | 206 size = cscf->imap_client_buffer_size; |
123 s->imap_state = ngx_imap_start; | 207 s->imap_state = ngx_imap_start; |
124 c->read->handler = ngx_imap_auth_state; | 208 c->read->handler = ngx_imap_auth_state; |
125 } | 209 } |
126 | 210 |
135 | 219 |
136 | 220 |
137 void | 221 void |
138 ngx_imap_auth_state(ngx_event_t *rev) | 222 ngx_imap_auth_state(ngx_event_t *rev) |
139 { | 223 { |
140 u_char *text, *last, *out, *p; | 224 u_char *text, *last, *p; |
141 ssize_t size, text_len, last_len; | 225 ssize_t text_len, last_len; |
142 ngx_str_t *arg; | 226 ngx_str_t *arg; |
143 ngx_int_t rc; | 227 ngx_int_t rc; |
144 ngx_uint_t quit, tag; | 228 ngx_uint_t tag; |
145 ngx_connection_t *c; | 229 ngx_connection_t *c; |
146 ngx_imap_session_t *s; | 230 ngx_imap_session_t *s; |
147 ngx_imap_core_srv_conf_t *cscf; | 231 ngx_imap_core_srv_conf_t *cscf; |
148 | 232 |
149 c = rev->data; | 233 c = rev->data; |
155 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out"); | 239 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out"); |
156 ngx_imap_close_connection(c); | 240 ngx_imap_close_connection(c); |
157 return; | 241 return; |
158 } | 242 } |
159 | 243 |
244 if (s->out.len) { | |
245 ngx_log_debug0(NGX_LOG_DEBUG_IMAP, c->log, 0, "imap send handler busy"); | |
246 s->blocked = 1; | |
247 return; | |
248 } | |
249 | |
250 s->blocked = 0; | |
251 | |
160 rc = ngx_imap_read_command(s); | 252 rc = ngx_imap_read_command(s); |
161 | 253 |
162 ngx_log_debug1(NGX_LOG_DEBUG_IMAP, c->log, 0, "imap auth: %i", rc); | 254 ngx_log_debug1(NGX_LOG_DEBUG_IMAP, c->log, 0, "imap auth: %i", rc); |
163 | 255 |
164 if (rc == NGX_AGAIN || rc == NGX_ERROR) { | 256 if (rc == NGX_AGAIN || rc == NGX_ERROR) { |
165 return; | 257 return; |
166 } | 258 } |
167 | 259 |
168 quit = 0; | |
169 tag = 1; | 260 tag = 1; |
170 | 261 |
171 text = NULL; | 262 text = NULL; |
172 text_len = 0; | 263 text_len = 0; |
173 | 264 |
233 text = cscf->imap_capability->pos; | 324 text = cscf->imap_capability->pos; |
234 text_len = cscf->imap_capability->last - cscf->imap_capability->pos; | 325 text_len = cscf->imap_capability->last - cscf->imap_capability->pos; |
235 break; | 326 break; |
236 | 327 |
237 case NGX_IMAP_LOGOUT: | 328 case NGX_IMAP_LOGOUT: |
329 s->quit = 1; | |
238 text = imap_bye; | 330 text = imap_bye; |
239 text_len = sizeof(imap_bye) - 1; | 331 text_len = sizeof(imap_bye) - 1; |
240 quit = 1; | |
241 break; | 332 break; |
242 | 333 |
243 case NGX_IMAP_NOOP: | 334 case NGX_IMAP_NOOP: |
244 break; | 335 break; |
245 | 336 |
258 last = imap_invalid_command; | 349 last = imap_invalid_command; |
259 last_len = sizeof(imap_invalid_command) - 1; | 350 last_len = sizeof(imap_invalid_command) - 1; |
260 } | 351 } |
261 | 352 |
262 if (tag) { | 353 if (tag) { |
263 if (s->out.len < text_len + s->tag.len + last_len) { | 354 if (s->tagged_line.len < s->tag.len + text_len + last_len) { |
264 | 355 s->tagged_line.len = s->tag.len + text_len + last_len; |
265 s->out.len = text_len + s->tag.len + last_len; | 356 s->tagged_line.data = ngx_palloc(c->pool, s->tagged_line.len); |
266 s->out.data = ngx_palloc(c->pool, s->out.len); | 357 if (s->tagged_line.data == NULL) { |
267 if (s->out.data == NULL) { | |
268 ngx_imap_close_connection(c); | 358 ngx_imap_close_connection(c); |
269 return; | 359 return; |
270 } | 360 } |
271 } | 361 } |
272 | 362 |
273 out = s->out.data; | 363 s->out.data = s->tagged_line.data; |
274 p = out; | 364 s->out.len = s->tag.len + text_len + last_len; |
365 | |
366 p = s->out.data; | |
275 | 367 |
276 if (text) { | 368 if (text) { |
277 p = ngx_cpymem(p, text, text_len); | 369 p = ngx_cpymem(p, text, text_len); |
278 } | 370 } |
279 p = ngx_cpymem(p, s->tag.data, s->tag.len); | 371 p = ngx_cpymem(p, s->tag.data, s->tag.len); |
280 ngx_memcpy(p, last, last_len); | 372 ngx_memcpy(p, last, last_len); |
281 | 373 |
282 size = text_len + s->tag.len + last_len; | |
283 | 374 |
284 } else { | 375 } else { |
285 out = last; | 376 s->out.data = last; |
286 size = last_len; | 377 s->out.len = last_len; |
287 } | 378 } |
288 | 379 |
289 if (ngx_send(c, out, size) < size) { | 380 if (rc != NGX_IMAP_NEXT) { |
290 /* | 381 s->args.nelts = 0; |
291 * we treat the incomplete sending as NGX_ERROR | 382 s->buffer->pos = s->buffer->start; |
292 * because it is very strange here | 383 s->buffer->last = s->buffer->start; |
293 */ | 384 s->tag.len = 0; |
294 ngx_imap_close_connection(c); | 385 } |
295 return; | 386 |
296 } | 387 ngx_imap_send(c->write); |
297 | |
298 if (rc == NGX_IMAP_NEXT) { | |
299 return; | |
300 } | |
301 | |
302 if (quit) { | |
303 ngx_imap_close_connection(c); | |
304 return; | |
305 } | |
306 | |
307 s->args.nelts = 0; | |
308 s->buffer->pos = s->buffer->start; | |
309 s->buffer->last = s->buffer->start; | |
310 s->tag.len = 0; | |
311 } | 388 } |
312 | 389 |
313 | 390 |
314 void | 391 void |
315 ngx_pop3_auth_state(ngx_event_t *rev) | 392 ngx_pop3_auth_state(ngx_event_t *rev) |
316 { | 393 { |
317 u_char *text; | 394 u_char *text; |
318 ssize_t size; | 395 ssize_t size; |
319 ngx_int_t rc; | 396 ngx_int_t rc; |
320 ngx_uint_t quit; | |
321 ngx_str_t *arg; | 397 ngx_str_t *arg; |
322 ngx_connection_t *c; | 398 ngx_connection_t *c; |
323 ngx_imap_session_t *s; | 399 ngx_imap_session_t *s; |
324 ngx_imap_core_srv_conf_t *cscf; | 400 ngx_imap_core_srv_conf_t *cscf; |
325 | 401 |
332 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out"); | 408 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out"); |
333 ngx_imap_close_connection(c); | 409 ngx_imap_close_connection(c); |
334 return; | 410 return; |
335 } | 411 } |
336 | 412 |
413 if (s->out.len) { | |
414 ngx_log_debug0(NGX_LOG_DEBUG_IMAP, c->log, 0, "imap send handler busy"); | |
415 s->blocked = 1; | |
416 return; | |
417 } | |
418 | |
419 s->blocked = 0; | |
420 | |
337 rc = ngx_imap_read_command(s); | 421 rc = ngx_imap_read_command(s); |
338 | 422 |
339 if (rc == NGX_AGAIN || rc == NGX_ERROR) { | 423 if (rc == NGX_AGAIN || rc == NGX_ERROR) { |
340 return; | 424 return; |
341 } | 425 } |
342 | 426 |
343 quit = 0; | |
344 text = pop3_ok; | 427 text = pop3_ok; |
345 size = sizeof(pop3_ok) - 1; | 428 size = sizeof(pop3_ok) - 1; |
346 | 429 |
347 if (rc == NGX_OK) { | 430 if (rc == NGX_OK) { |
348 switch (s->imap_state) { | 431 switch (s->imap_state) { |
379 text = cscf->pop3_capability->pos; | 462 text = cscf->pop3_capability->pos; |
380 size = cscf->pop3_capability->last - cscf->pop3_capability->pos; | 463 size = cscf->pop3_capability->last - cscf->pop3_capability->pos; |
381 break; | 464 break; |
382 | 465 |
383 case NGX_POP3_QUIT: | 466 case NGX_POP3_QUIT: |
384 quit = 1; | 467 s->quit = 1; |
385 break; | 468 break; |
386 | 469 |
387 case NGX_POP3_NOOP: | 470 case NGX_POP3_NOOP: |
388 break; | 471 break; |
389 | 472 |
439 text = cscf->pop3_capability->pos; | 522 text = cscf->pop3_capability->pos; |
440 size = cscf->pop3_capability->last - cscf->pop3_capability->pos; | 523 size = cscf->pop3_capability->last - cscf->pop3_capability->pos; |
441 break; | 524 break; |
442 | 525 |
443 case NGX_POP3_QUIT: | 526 case NGX_POP3_QUIT: |
444 quit = 1; | 527 s->quit = 1; |
445 break; | 528 break; |
446 | 529 |
447 case NGX_POP3_NOOP: | 530 case NGX_POP3_NOOP: |
448 break; | 531 break; |
449 | 532 |
464 if (rc == NGX_IMAP_PARSE_INVALID_COMMAND) { | 547 if (rc == NGX_IMAP_PARSE_INVALID_COMMAND) { |
465 text = pop3_invalid_command; | 548 text = pop3_invalid_command; |
466 size = sizeof(pop3_invalid_command) - 1; | 549 size = sizeof(pop3_invalid_command) - 1; |
467 } | 550 } |
468 | 551 |
469 if (ngx_send(c, text, size) < size) { | |
470 /* | |
471 * we treat the incomplete sending as NGX_ERROR | |
472 * because it is very strange here | |
473 */ | |
474 ngx_imap_close_connection(c); | |
475 return; | |
476 } | |
477 | |
478 if (quit) { | |
479 ngx_imap_close_connection(c); | |
480 return; | |
481 } | |
482 | |
483 s->args.nelts = 0; | 552 s->args.nelts = 0; |
484 s->buffer->pos = s->buffer->start; | 553 s->buffer->pos = s->buffer->start; |
485 s->buffer->last = s->buffer->start; | 554 s->buffer->last = s->buffer->start; |
555 | |
556 s->out.data = text; | |
557 s->out.len = size; | |
558 | |
559 ngx_imap_send(c->write); | |
486 } | 560 } |
487 | 561 |
488 | 562 |
489 static ngx_int_t | 563 static ngx_int_t |
490 ngx_imap_read_command(ngx_imap_session_t *s) | 564 ngx_imap_read_command(ngx_imap_session_t *s) |
491 { | 565 { |
492 ssize_t n; | 566 ssize_t n; |
493 ngx_int_t rc; | 567 ngx_int_t rc; |
494 | 568 |
495 n = ngx_recv(s->connection, s->buffer->last, | 569 n = s->connection->recv(s->connection, s->buffer->last, |
496 s->buffer->end - s->buffer->last); | 570 s->buffer->end - s->buffer->last); |
497 | 571 |
498 if (n == NGX_ERROR || n == 0) { | 572 if (n == NGX_ERROR || n == 0) { |
499 ngx_imap_close_connection(s->connection); | 573 ngx_imap_close_connection(s->connection); |
500 return NGX_ERROR; | 574 return NGX_ERROR; |
501 } | 575 } |
536 | 610 |
537 | 611 |
538 void | 612 void |
539 ngx_imap_session_internal_server_error(ngx_imap_session_t *s) | 613 ngx_imap_session_internal_server_error(ngx_imap_session_t *s) |
540 { | 614 { |
541 (void) ngx_send(s->connection, internal_server_errors[s->protocol].data, | 615 s->out = internal_server_errors[s->protocol]; |
542 internal_server_errors[s->protocol].len); | 616 s->quit = 1; |
543 | 617 |
544 ngx_imap_close_connection(s->connection); | 618 ngx_imap_send(s->connection->write); |
545 } | 619 } |
546 | 620 |
547 | 621 |
548 void | 622 void |
549 ngx_imap_close_connection(ngx_connection_t *c) | 623 ngx_imap_close_connection(ngx_connection_t *c) |
551 ngx_pool_t *pool; | 625 ngx_pool_t *pool; |
552 | 626 |
553 ngx_log_debug1(NGX_LOG_DEBUG_IMAP, c->log, 0, | 627 ngx_log_debug1(NGX_LOG_DEBUG_IMAP, c->log, 0, |
554 "close imap connection: %d", c->fd); | 628 "close imap connection: %d", c->fd); |
555 | 629 |
630 #if (NGX_IMAP_SSL) | |
631 | |
632 if (c->ssl) { | |
633 if (ngx_ssl_shutdown(c) == NGX_AGAIN) { | |
634 c->read->handler = ngx_imap_ssl_close_handler; | |
635 c->write->handler = ngx_imap_ssl_close_handler; | |
636 return; | |
637 } | |
638 } | |
639 | |
640 #endif | |
641 | |
556 pool = c->pool; | 642 pool = c->pool; |
557 | 643 |
558 ngx_close_connection(c); | 644 ngx_close_connection(c); |
559 | 645 |
560 ngx_destroy_pool(pool); | 646 ngx_destroy_pool(pool); |
561 } | 647 } |
648 | |
649 | |
650 #if (NGX_IMAP_SSL) | |
651 | |
652 static void | |
653 ngx_imap_ssl_close_handler(ngx_event_t *ev) | |
654 { | |
655 ngx_connection_t *c; | |
656 | |
657 c = ev->data; | |
658 | |
659 ngx_log_debug0(NGX_LOG_DEBUG_IMAP, ev->log, 0, "http ssl close handler"); | |
660 | |
661 if (ngx_ssl_shutdown(c) == NGX_AGAIN) { | |
662 return; | |
663 } | |
664 | |
665 ngx_imap_close_connection(c); | |
666 } | |
667 | |
668 #endif |