comparison src/imap/ngx_imap_proxy_module.c @ 212:56688ed172c8 NGINX_0_3_53

nginx 0.3.53 *) Change: the "add_header" directive adds the string to 204, 301, and 302 responses. *) Feature: the "server" directive in the "upstream" context supports the "weight" parameter. *) Feature: the "server_name" directive supports the "*" wildcard. *) Feature: nginx supports the request body size more than 2G. *) Bugfix: if a client was successfully authorized using "satisfy_any on", then anyway the message "access forbidden by rule" was written in the log. *) Bugfix: the "PUT" method may erroneously not create a file and return the 409 code. *) Bugfix: if the IMAP/POP3 backend returned an error, then nginx continued proxying anyway.
author Igor Sysoev <http://sysoev.ru>
date Fri, 07 Jul 2006 00:00:00 +0400
parents 8e6d4d96ec4c
children 6ae1357b7b7c
comparison
equal deleted inserted replaced
211:f04a54878110 212:56688ed172c8
21 static void ngx_imap_proxy_block_read(ngx_event_t *rev); 21 static void ngx_imap_proxy_block_read(ngx_event_t *rev);
22 static void ngx_imap_proxy_imap_handler(ngx_event_t *rev); 22 static void ngx_imap_proxy_imap_handler(ngx_event_t *rev);
23 static void ngx_imap_proxy_pop3_handler(ngx_event_t *rev); 23 static void ngx_imap_proxy_pop3_handler(ngx_event_t *rev);
24 static void ngx_imap_proxy_dummy_handler(ngx_event_t *ev); 24 static void ngx_imap_proxy_dummy_handler(ngx_event_t *ev);
25 static ngx_int_t ngx_imap_proxy_read_response(ngx_imap_session_t *s, 25 static ngx_int_t ngx_imap_proxy_read_response(ngx_imap_session_t *s,
26 ngx_uint_t what); 26 ngx_uint_t state);
27 static void ngx_imap_proxy_handler(ngx_event_t *ev); 27 static void ngx_imap_proxy_handler(ngx_event_t *ev);
28 static void ngx_imap_proxy_internal_server_error(ngx_imap_session_t *s); 28 static void ngx_imap_proxy_internal_server_error(ngx_imap_session_t *s);
29 static void ngx_imap_proxy_close_session(ngx_imap_session_t *s); 29 static void ngx_imap_proxy_close_session(ngx_imap_session_t *s);
30 static void *ngx_imap_proxy_create_conf(ngx_conf_t *cf); 30 static void *ngx_imap_proxy_create_conf(ngx_conf_t *cf);
31 static char *ngx_imap_proxy_merge_conf(ngx_conf_t *cf, void *parent, 31 static char *ngx_imap_proxy_merge_conf(ngx_conf_t *cf, void *parent,
32 void *child); 32 void *child);
33
34
35 #define NGX_IMAP_WAIT_OK 0
36 #define NGX_IMAP_WAIT_NEXT 1
37 33
38 34
39 static ngx_command_t ngx_imap_proxy_commands[] = { 35 static ngx_command_t ngx_imap_proxy_commands[] = {
40 36
41 { ngx_string("proxy"), 37 { ngx_string("proxy"),
199 ngx_imap_proxy_internal_server_error(s); 195 ngx_imap_proxy_internal_server_error(s);
200 return; 196 return;
201 } 197 }
202 } 198 }
203 199
204 rc = ngx_imap_proxy_read_response(s, s->imap_state == ngx_imap_start ? 200 rc = ngx_imap_proxy_read_response(s, s->imap_state);
205 NGX_IMAP_WAIT_OK : NGX_IMAP_WAIT_NEXT);
206 201
207 if (rc == NGX_AGAIN) { 202 if (rc == NGX_AGAIN) {
208 return; 203 return;
209 } 204 }
210 205
272 *p++ = CR; *p = LF; 267 *p++ = CR; *p = LF;
273 268
274 s->imap_state = ngx_imap_passwd; 269 s->imap_state = ngx_imap_passwd;
275 break; 270 break;
276 271
272 case ngx_imap_passwd:
273 s->connection->read->handler = ngx_imap_proxy_handler;
274 s->connection->write->handler = ngx_imap_proxy_handler;
275 rev->handler = ngx_imap_proxy_handler;
276 c->write->handler = ngx_imap_proxy_handler;
277
278 pcf = ngx_imap_get_module_srv_conf(s, ngx_imap_proxy_module);
279 ngx_add_timer(s->connection->read, pcf->timeout);
280 ngx_del_timer(c->read);
281
282 c->log->action = NULL;
283 ngx_log_error(NGX_LOG_INFO, c->log, 0, "client logged in");
284
285 ngx_imap_proxy_handler(s->connection->write);
286
287 return;
288
277 default: 289 default:
278 #if (NGX_SUPPRESS_WARN) 290 #if (NGX_SUPPRESS_WARN)
279 line.len = 0; 291 line.len = 0;
280 line.data = NULL; 292 line.data = NULL;
281 #endif 293 #endif
291 return; 303 return;
292 } 304 }
293 305
294 s->proxy->buffer->pos = s->proxy->buffer->start; 306 s->proxy->buffer->pos = s->proxy->buffer->start;
295 s->proxy->buffer->last = s->proxy->buffer->start; 307 s->proxy->buffer->last = s->proxy->buffer->start;
296
297 if (s->imap_state == ngx_imap_passwd) {
298 s->connection->read->handler = ngx_imap_proxy_handler;
299 s->connection->write->handler = ngx_imap_proxy_handler;
300 rev->handler = ngx_imap_proxy_handler;
301 c->write->handler = ngx_imap_proxy_handler;
302
303 pcf = ngx_imap_get_module_srv_conf(s, ngx_imap_proxy_module);
304 ngx_add_timer(s->connection->read, pcf->timeout);
305 ngx_del_timer(c->read);
306
307 c->log->action = NULL;
308 ngx_log_error(NGX_LOG_INFO, c->log, 0, "client logged in");
309 }
310 } 308 }
311 309
312 310
313 static void 311 static void
314 ngx_imap_proxy_pop3_handler(ngx_event_t *rev) 312 ngx_imap_proxy_pop3_handler(ngx_event_t *rev)
342 ngx_imap_proxy_internal_server_error(s); 340 ngx_imap_proxy_internal_server_error(s);
343 return; 341 return;
344 } 342 }
345 } 343 }
346 344
347 rc = ngx_imap_proxy_read_response(s, NGX_IMAP_WAIT_OK); 345 rc = ngx_imap_proxy_read_response(s, 0);
348 346
349 if (rc == NGX_AGAIN) { 347 if (rc == NGX_AGAIN) {
350 return; 348 return;
351 } 349 }
352 350
392 p = ngx_cpymem(p, s->passwd.data, s->passwd.len); 390 p = ngx_cpymem(p, s->passwd.data, s->passwd.len);
393 *p++ = CR; *p = LF; 391 *p++ = CR; *p = LF;
394 392
395 s->imap_state = ngx_pop3_passwd; 393 s->imap_state = ngx_pop3_passwd;
396 break; 394 break;
395
396 case ngx_pop3_passwd:
397 s->connection->read->handler = ngx_imap_proxy_handler;
398 s->connection->write->handler = ngx_imap_proxy_handler;
399 rev->handler = ngx_imap_proxy_handler;
400 c->write->handler = ngx_imap_proxy_handler;
401
402 pcf = ngx_imap_get_module_srv_conf(s, ngx_imap_proxy_module);
403 ngx_add_timer(s->connection->read, pcf->timeout);
404 ngx_del_timer(c->read);
405
406 c->log->action = NULL;
407 ngx_log_error(NGX_LOG_INFO, c->log, 0, "client logged in");
408
409 ngx_imap_proxy_handler(s->connection->write);
410
411 return;
397 412
398 default: 413 default:
399 #if (NGX_SUPPRESS_WARN) 414 #if (NGX_SUPPRESS_WARN)
400 line.len = 0; 415 line.len = 0;
401 line.data = NULL; 416 line.data = NULL;
412 return; 427 return;
413 } 428 }
414 429
415 s->proxy->buffer->pos = s->proxy->buffer->start; 430 s->proxy->buffer->pos = s->proxy->buffer->start;
416 s->proxy->buffer->last = s->proxy->buffer->start; 431 s->proxy->buffer->last = s->proxy->buffer->start;
417
418 if (s->imap_state == ngx_pop3_passwd) {
419 s->connection->read->handler = ngx_imap_proxy_handler;
420 s->connection->write->handler = ngx_imap_proxy_handler;
421 rev->handler = ngx_imap_proxy_handler;
422 c->write->handler = ngx_imap_proxy_handler;
423
424 pcf = ngx_imap_get_module_srv_conf(s, ngx_imap_proxy_module);
425 ngx_add_timer(s->connection->read, pcf->timeout);
426 ngx_del_timer(c->read);
427
428 c->log->action = NULL;
429 ngx_log_error(NGX_LOG_INFO, c->log, 0, "client logged in");
430 }
431 } 432 }
432 433
433 434
434 static void 435 static void
435 ngx_imap_proxy_dummy_handler(ngx_event_t *wev) 436 ngx_imap_proxy_dummy_handler(ngx_event_t *wev)
447 } 448 }
448 } 449 }
449 450
450 451
451 static ngx_int_t 452 static ngx_int_t
452 ngx_imap_proxy_read_response(ngx_imap_session_t *s, ngx_uint_t what) 453 ngx_imap_proxy_read_response(ngx_imap_session_t *s, ngx_uint_t state)
453 { 454 {
454 u_char *p; 455 u_char *p;
455 ssize_t n; 456 ssize_t n;
456 ngx_buf_t *b; 457 ngx_buf_t *b;
457 458
494 if (p[0] == '+' && p[1] == 'O' && p[2] == 'K') { 495 if (p[0] == '+' && p[1] == 'O' && p[2] == 'K') {
495 return NGX_OK; 496 return NGX_OK;
496 } 497 }
497 498
498 } else { 499 } else {
499 if (what == NGX_IMAP_WAIT_OK) { 500 switch (state) {
501
502 case ngx_imap_start:
500 if (p[0] == '*' && p[1] == ' ' && p[2] == 'O' && p[3] == 'K') { 503 if (p[0] == '*' && p[1] == ' ' && p[2] == 'O' && p[3] == 'K') {
501 return NGX_OK; 504 return NGX_OK;
502 } 505 }
503 506 break;
504 } else { 507
508 case ngx_imap_login:
509 case ngx_imap_user:
505 if (p[0] == '+') { 510 if (p[0] == '+') {
506 return NGX_OK; 511 return NGX_OK;
507 } 512 }
513 break;
514
515 case ngx_imap_passwd:
516 if (ngx_strncmp(p, s->tag.data, s->tag.len) == 0) {
517 p += s->tag.len;
518 if (p[0] == 'O' && p[1] == 'K') {
519 return NGX_OK;
520 }
521 }
522 break;
508 } 523 }
509 } 524 }
510 525
511 *(b->last - 2) = '\0'; 526 *(b->last - 2) = '\0';
512 ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, 527 ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,