Mercurial > hg > nginx-vendor-0-5
comparison src/imap/ngx_imap_proxy_module.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 | 6ae11d59d10e |
children | 71c46860eb55 |
comparison
equal
deleted
inserted
replaced
87:5b7ec80c3c40 | 88:e916a291e9aa |
---|---|
11 #include <ngx_imap.h> | 11 #include <ngx_imap.h> |
12 | 12 |
13 | 13 |
14 typedef struct { | 14 typedef struct { |
15 ngx_flag_t enable; | 15 ngx_flag_t enable; |
16 size_t buffer_size; | |
17 ngx_msec_t timeout; | |
16 } ngx_imap_proxy_conf_t; | 18 } ngx_imap_proxy_conf_t; |
17 | 19 |
18 | 20 |
19 static void ngx_imap_proxy_block_read(ngx_event_t *rev); | 21 static void ngx_imap_proxy_block_read(ngx_event_t *rev); |
20 static void ngx_imap_proxy_imap_handler(ngx_event_t *rev); | 22 static void ngx_imap_proxy_imap_handler(ngx_event_t *rev); |
33 #define NGX_IMAP_WAIT_OK 0 | 35 #define NGX_IMAP_WAIT_OK 0 |
34 #define NGX_IMAP_WAIT_NEXT 1 | 36 #define NGX_IMAP_WAIT_NEXT 1 |
35 | 37 |
36 | 38 |
37 static ngx_command_t ngx_imap_proxy_commands[] = { | 39 static ngx_command_t ngx_imap_proxy_commands[] = { |
40 | |
38 { ngx_string("proxy"), | 41 { ngx_string("proxy"), |
39 NGX_IMAP_MAIN_CONF|NGX_IMAP_SRV_CONF|NGX_CONF_FLAG, | 42 NGX_IMAP_MAIN_CONF|NGX_IMAP_SRV_CONF|NGX_CONF_FLAG, |
40 ngx_conf_set_flag_slot, | 43 ngx_conf_set_flag_slot, |
41 NGX_IMAP_SRV_CONF_OFFSET, | 44 NGX_IMAP_SRV_CONF_OFFSET, |
42 offsetof(ngx_imap_proxy_conf_t, enable), | 45 offsetof(ngx_imap_proxy_conf_t, enable), |
46 NULL }, | |
47 | |
48 { ngx_string("proxy_buffer"), | |
49 NGX_IMAP_MAIN_CONF|NGX_IMAP_SRV_CONF|NGX_CONF_TAKE1, | |
50 ngx_conf_set_size_slot, | |
51 NGX_IMAP_SRV_CONF_OFFSET, | |
52 offsetof(ngx_imap_proxy_conf_t, buffer_size), | |
53 NULL }, | |
54 | |
55 { ngx_string("proxy_timeout"), | |
56 NGX_IMAP_MAIN_CONF|NGX_IMAP_SRV_CONF|NGX_CONF_TAKE1, | |
57 ngx_conf_set_msec_slot, | |
58 NGX_IMAP_SRV_CONF_OFFSET, | |
59 offsetof(ngx_imap_proxy_conf_t, timeout), | |
43 NULL }, | 60 NULL }, |
44 | 61 |
45 ngx_null_command | 62 ngx_null_command |
46 }; | 63 }; |
47 | 64 |
129 | 146 |
130 | 147 |
131 static void | 148 static void |
132 ngx_imap_proxy_imap_handler(ngx_event_t *rev) | 149 ngx_imap_proxy_imap_handler(ngx_event_t *rev) |
133 { | 150 { |
134 u_char *p; | 151 u_char *p; |
135 ngx_int_t rc; | 152 ngx_int_t rc; |
136 ngx_str_t line; | 153 ngx_str_t line; |
137 ngx_connection_t *c; | 154 ngx_connection_t *c; |
138 ngx_imap_session_t *s; | 155 ngx_imap_session_t *s; |
139 ngx_imap_core_srv_conf_t *cscf; | 156 ngx_imap_proxy_conf_t *pcf; |
140 | 157 |
141 ngx_log_debug0(NGX_LOG_DEBUG_IMAP, rev->log, 0, | 158 ngx_log_debug0(NGX_LOG_DEBUG_IMAP, rev->log, 0, |
142 "imap proxy imap auth handler"); | 159 "imap proxy imap auth handler"); |
143 | 160 |
144 c = rev->data; | 161 c = rev->data; |
150 ngx_imap_proxy_internal_server_error(s); | 167 ngx_imap_proxy_internal_server_error(s); |
151 return; | 168 return; |
152 } | 169 } |
153 | 170 |
154 if (s->proxy->buffer == NULL) { | 171 if (s->proxy->buffer == NULL) { |
155 cscf = ngx_imap_get_module_srv_conf(s, ngx_imap_core_module); | 172 pcf = ngx_imap_get_module_srv_conf(s, ngx_imap_proxy_module); |
156 | 173 |
157 s->proxy->buffer = ngx_create_temp_buf(c->pool, | 174 s->proxy->buffer = ngx_create_temp_buf(c->pool, pcf->buffer_size); |
158 cscf->proxy_buffer_size); | |
159 if (s->proxy->buffer == NULL) { | 175 if (s->proxy->buffer == NULL) { |
160 ngx_imap_proxy_internal_server_error(s); | 176 ngx_imap_proxy_internal_server_error(s); |
161 return; | 177 return; |
162 } | 178 } |
163 } | 179 } |
245 line.data = NULL; | 261 line.data = NULL; |
246 #endif | 262 #endif |
247 break; | 263 break; |
248 } | 264 } |
249 | 265 |
250 if (ngx_send(c, line.data, line.len) < (ssize_t) line.len) { | 266 if (c->send(c, line.data, line.len) < (ssize_t) line.len) { |
251 /* | 267 /* |
252 * we treat the incomplete sending as NGX_ERROR | 268 * we treat the incomplete sending as NGX_ERROR |
253 * because it is very strange here | 269 * because it is very strange here |
254 */ | 270 */ |
255 ngx_imap_proxy_internal_server_error(s); | 271 ngx_imap_proxy_internal_server_error(s); |
263 s->connection->read->handler = ngx_imap_proxy_handler; | 279 s->connection->read->handler = ngx_imap_proxy_handler; |
264 s->connection->write->handler = ngx_imap_proxy_handler; | 280 s->connection->write->handler = ngx_imap_proxy_handler; |
265 rev->handler = ngx_imap_proxy_handler; | 281 rev->handler = ngx_imap_proxy_handler; |
266 c->write->handler = ngx_imap_proxy_handler; | 282 c->write->handler = ngx_imap_proxy_handler; |
267 | 283 |
284 pcf = ngx_imap_get_module_srv_conf(s, ngx_imap_proxy_module); | |
285 ngx_add_timer(s->connection->read, pcf->timeout); | |
268 ngx_del_timer(c->read); | 286 ngx_del_timer(c->read); |
269 } | 287 } |
270 } | 288 } |
271 | 289 |
272 | 290 |
273 static void | 291 static void |
274 ngx_imap_proxy_pop3_handler(ngx_event_t *rev) | 292 ngx_imap_proxy_pop3_handler(ngx_event_t *rev) |
275 { | 293 { |
276 u_char *p; | 294 u_char *p; |
277 ngx_int_t rc; | 295 ngx_int_t rc; |
278 ngx_str_t line; | 296 ngx_str_t line; |
279 ngx_connection_t *c; | 297 ngx_connection_t *c; |
280 ngx_imap_session_t *s; | 298 ngx_imap_session_t *s; |
281 ngx_imap_core_srv_conf_t *cscf; | 299 ngx_imap_proxy_conf_t *pcf; |
282 | 300 |
283 ngx_log_debug0(NGX_LOG_DEBUG_IMAP, rev->log, 0, | 301 ngx_log_debug0(NGX_LOG_DEBUG_IMAP, rev->log, 0, |
284 "imap proxy pop3 auth handler"); | 302 "imap proxy pop3 auth handler"); |
285 | 303 |
286 c = rev->data; | 304 c = rev->data; |
292 ngx_imap_proxy_internal_server_error(s); | 310 ngx_imap_proxy_internal_server_error(s); |
293 return; | 311 return; |
294 } | 312 } |
295 | 313 |
296 if (s->proxy->buffer == NULL) { | 314 if (s->proxy->buffer == NULL) { |
297 cscf = ngx_imap_get_module_srv_conf(s, ngx_imap_core_module); | 315 pcf = ngx_imap_get_module_srv_conf(s, ngx_imap_proxy_module); |
298 | 316 |
299 s->proxy->buffer = ngx_create_temp_buf(c->pool, | 317 s->proxy->buffer = ngx_create_temp_buf(c->pool, pcf->buffer_size); |
300 cscf->proxy_buffer_size); | |
301 if (s->proxy->buffer == NULL) { | 318 if (s->proxy->buffer == NULL) { |
302 ngx_imap_proxy_internal_server_error(s); | 319 ngx_imap_proxy_internal_server_error(s); |
303 return; | 320 return; |
304 } | 321 } |
305 } | 322 } |
367 line.data = NULL; | 384 line.data = NULL; |
368 #endif | 385 #endif |
369 break; | 386 break; |
370 } | 387 } |
371 | 388 |
372 if (ngx_send(c, line.data, line.len) < (ssize_t) line.len) { | 389 if (c->send(c, line.data, line.len) < (ssize_t) line.len) { |
373 /* | 390 /* |
374 * we treat the incomplete sending as NGX_ERROR | 391 * we treat the incomplete sending as NGX_ERROR |
375 * because it is very strange here | 392 * because it is very strange here |
376 */ | 393 */ |
377 ngx_imap_proxy_internal_server_error(s); | 394 ngx_imap_proxy_internal_server_error(s); |
385 s->connection->read->handler = ngx_imap_proxy_handler; | 402 s->connection->read->handler = ngx_imap_proxy_handler; |
386 s->connection->write->handler = ngx_imap_proxy_handler; | 403 s->connection->write->handler = ngx_imap_proxy_handler; |
387 rev->handler = ngx_imap_proxy_handler; | 404 rev->handler = ngx_imap_proxy_handler; |
388 c->write->handler = ngx_imap_proxy_handler; | 405 c->write->handler = ngx_imap_proxy_handler; |
389 | 406 |
407 pcf = ngx_imap_get_module_srv_conf(s, ngx_imap_proxy_module); | |
408 ngx_add_timer(s->connection->read, pcf->timeout); | |
390 ngx_del_timer(c->read); | 409 ngx_del_timer(c->read); |
391 } | 410 } |
392 } | 411 } |
393 | 412 |
394 | 413 |
406 ssize_t n; | 425 ssize_t n; |
407 ngx_buf_t *b; | 426 ngx_buf_t *b; |
408 | 427 |
409 b = s->proxy->buffer; | 428 b = s->proxy->buffer; |
410 | 429 |
411 n = ngx_recv(s->proxy->upstream.connection, b->last, b->end - b->last); | 430 n = s->proxy->upstream.connection->recv(s->proxy->upstream.connection, |
431 b->last, b->end - b->last); | |
412 | 432 |
413 if (n == NGX_ERROR || n == 0) { | 433 if (n == NGX_ERROR || n == 0) { |
414 return NGX_ERROR; | 434 return NGX_ERROR; |
415 } | 435 } |
416 | 436 |
473 | 493 |
474 | 494 |
475 static void | 495 static void |
476 ngx_imap_proxy_handler(ngx_event_t *ev) | 496 ngx_imap_proxy_handler(ngx_event_t *ev) |
477 { | 497 { |
478 size_t size; | 498 size_t size; |
479 ssize_t n; | 499 ssize_t n; |
480 ngx_buf_t *b; | 500 ngx_buf_t *b; |
481 ngx_uint_t again, do_write; | 501 ngx_uint_t again, do_write; |
482 ngx_connection_t *c, *src, *dst; | 502 ngx_connection_t *c, *src, *dst; |
483 ngx_imap_session_t *s; | 503 ngx_imap_session_t *s; |
504 ngx_imap_proxy_conf_t *pcf; | |
484 | 505 |
485 c = ev->data; | 506 c = ev->data; |
486 s = c->data; | 507 s = c->data; |
487 | 508 |
488 if (ev->timedout) { | 509 if (ev->timedout) { |
535 if (do_write == 1) { | 556 if (do_write == 1) { |
536 | 557 |
537 size = b->last - b->pos; | 558 size = b->last - b->pos; |
538 | 559 |
539 if (size && dst->write->ready) { | 560 if (size && dst->write->ready) { |
540 n = ngx_send(dst, b->pos, size); | 561 n = dst->send(dst, b->pos, size); |
541 | 562 |
542 if (n == NGX_ERROR) { | 563 if (n == NGX_ERROR) { |
543 ngx_imap_proxy_close_session(s); | 564 ngx_imap_proxy_close_session(s); |
544 return; | 565 return; |
545 } | 566 } |
566 } | 587 } |
567 | 588 |
568 size = b->end - b->last; | 589 size = b->end - b->last; |
569 | 590 |
570 if (size && src->read->ready) { | 591 if (size && src->read->ready) { |
571 n = ngx_recv(src, b->last, size); | 592 n = src->recv(src, b->last, size); |
572 | 593 |
573 if (n == NGX_ERROR || n == 0) { | 594 if (n == NGX_ERROR || n == 0) { |
574 ngx_imap_proxy_close_session(s); | 595 ngx_imap_proxy_close_session(s); |
575 return; | 596 return; |
576 } | 597 } |
584 if (n == NGX_AGAIN || n < (ssize_t) size) { | 605 if (n == NGX_AGAIN || n < (ssize_t) size) { |
585 if (ngx_handle_read_event(src->read, 0) == NGX_ERROR) { | 606 if (ngx_handle_read_event(src->read, 0) == NGX_ERROR) { |
586 ngx_imap_proxy_close_session(s); | 607 ngx_imap_proxy_close_session(s); |
587 return; | 608 return; |
588 } | 609 } |
610 } | |
611 | |
612 if (c == s->connection) { | |
613 pcf = ngx_imap_get_module_srv_conf(s, ngx_imap_proxy_module); | |
614 ngx_add_timer(c->read, pcf->timeout); | |
589 } | 615 } |
590 } | 616 } |
591 | 617 |
592 } while (again); | 618 } while (again); |
593 } | 619 } |
632 if (pcf == NULL) { | 658 if (pcf == NULL) { |
633 return NGX_CONF_ERROR; | 659 return NGX_CONF_ERROR; |
634 } | 660 } |
635 | 661 |
636 pcf->enable = NGX_CONF_UNSET; | 662 pcf->enable = NGX_CONF_UNSET; |
663 pcf->buffer_size = NGX_CONF_UNSET_SIZE; | |
664 pcf->timeout = NGX_CONF_UNSET_MSEC; | |
637 | 665 |
638 return pcf; | 666 return pcf; |
639 } | 667 } |
640 | 668 |
641 | 669 |
643 ngx_imap_proxy_merge_conf(ngx_conf_t *cf, void *parent, void *child) | 671 ngx_imap_proxy_merge_conf(ngx_conf_t *cf, void *parent, void *child) |
644 { | 672 { |
645 ngx_imap_proxy_conf_t *prev = parent; | 673 ngx_imap_proxy_conf_t *prev = parent; |
646 ngx_imap_proxy_conf_t *conf = child; | 674 ngx_imap_proxy_conf_t *conf = child; |
647 | 675 |
648 ngx_conf_merge_msec_value(conf->enable, prev->enable, 0); | 676 ngx_conf_merge_value(conf->enable, prev->enable, 0); |
677 ngx_conf_merge_size_value(conf->buffer_size, prev->buffer_size, | |
678 (size_t) ngx_pagesize); | |
679 ngx_conf_merge_msec_value(conf->timeout, prev->timeout, 24 * 60 * 60000); | |
649 | 680 |
650 return NGX_CONF_OK; | 681 return NGX_CONF_OK; |
651 } | 682 } |