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 }