Mercurial > hg > nginx
comparison src/mail/ngx_mail_smtp_handler.c @ 5398:04e43d03e153
Mail: smtp pipelining support.
Basically, this does the following two changes (and corresponding
modifications of related code):
1. Does not reset session buffer unless it's reached it's end, and always
wait for LF to terminate command (even if we detected invalid command).
2. Record command name to make it available for handlers (since now we
can't assume that command starts from s->buffer->start).
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Mon, 30 Sep 2013 22:09:57 +0400 |
parents | 42f874c0b970 |
children | 07dd5bd222ac |
comparison
equal
deleted
inserted
replaced
5397:ae73d7a4fcde | 5398:04e43d03e153 |
---|---|
484 rc = ngx_mail_auth_cram_md5(s, c); | 484 rc = ngx_mail_auth_cram_md5(s, c); |
485 break; | 485 break; |
486 } | 486 } |
487 } | 487 } |
488 | 488 |
489 if (s->buffer->pos < s->buffer->last) { | |
490 s->blocked = 1; | |
491 } | |
492 | |
489 switch (rc) { | 493 switch (rc) { |
490 | 494 |
491 case NGX_DONE: | 495 case NGX_DONE: |
492 ngx_mail_auth(s, c); | 496 ngx_mail_auth(s, c); |
493 return; | 497 return; |
503 | 507 |
504 /* fall through */ | 508 /* fall through */ |
505 | 509 |
506 case NGX_OK: | 510 case NGX_OK: |
507 s->args.nelts = 0; | 511 s->args.nelts = 0; |
508 s->buffer->pos = s->buffer->start; | 512 |
509 s->buffer->last = s->buffer->start; | 513 if (s->buffer->pos == s->buffer->last) { |
514 s->buffer->pos = s->buffer->start; | |
515 s->buffer->last = s->buffer->start; | |
516 } | |
510 | 517 |
511 if (s->state) { | 518 if (s->state) { |
512 s->arg_start = s->buffer->start; | 519 s->arg_start = s->buffer->pos; |
513 } | 520 } |
514 | 521 |
515 ngx_mail_send(c->write); | 522 ngx_mail_send(c->write); |
516 } | 523 } |
517 } | 524 } |
650 | 657 |
651 | 658 |
652 static ngx_int_t | 659 static ngx_int_t |
653 ngx_mail_smtp_mail(ngx_mail_session_t *s, ngx_connection_t *c) | 660 ngx_mail_smtp_mail(ngx_mail_session_t *s, ngx_connection_t *c) |
654 { | 661 { |
655 u_char ch; | 662 ngx_str_t *arg, cmd; |
656 ngx_str_t l; | |
657 ngx_uint_t i; | |
658 ngx_mail_smtp_srv_conf_t *sscf; | 663 ngx_mail_smtp_srv_conf_t *sscf; |
659 | 664 |
660 sscf = ngx_mail_get_module_srv_conf(s, ngx_mail_smtp_module); | 665 sscf = ngx_mail_get_module_srv_conf(s, ngx_mail_smtp_module); |
661 | 666 |
662 if (!(sscf->auth_methods & NGX_MAIL_AUTH_NONE_ENABLED)) { | 667 if (!(sscf->auth_methods & NGX_MAIL_AUTH_NONE_ENABLED)) { |
670 if (s->smtp_from.len) { | 675 if (s->smtp_from.len) { |
671 ngx_str_set(&s->out, smtp_bad_sequence); | 676 ngx_str_set(&s->out, smtp_bad_sequence); |
672 return NGX_OK; | 677 return NGX_OK; |
673 } | 678 } |
674 | 679 |
675 l.len = s->buffer->last - s->buffer->start; | 680 arg = s->args.elts; |
676 l.data = s->buffer->start; | 681 arg += s->args.nelts - 1; |
677 | 682 |
678 for (i = 0; i < l.len; i++) { | 683 cmd.len = arg->data + arg->len - s->cmd.data; |
679 ch = l.data[i]; | 684 cmd.data = s->cmd.data; |
680 | 685 |
681 if (ch != CR && ch != LF) { | 686 s->smtp_from.len = cmd.len; |
682 continue; | 687 |
683 } | 688 s->smtp_from.data = ngx_pnalloc(c->pool, cmd.len); |
684 | |
685 l.data[i] = ' '; | |
686 } | |
687 | |
688 while (i) { | |
689 if (l.data[i - 1] != ' ') { | |
690 break; | |
691 } | |
692 | |
693 i--; | |
694 } | |
695 | |
696 l.len = i; | |
697 | |
698 s->smtp_from.len = l.len; | |
699 | |
700 s->smtp_from.data = ngx_pnalloc(c->pool, l.len); | |
701 if (s->smtp_from.data == NULL) { | 689 if (s->smtp_from.data == NULL) { |
702 return NGX_ERROR; | 690 return NGX_ERROR; |
703 } | 691 } |
704 | 692 |
705 ngx_memcpy(s->smtp_from.data, l.data, l.len); | 693 ngx_memcpy(s->smtp_from.data, cmd.data, cmd.len); |
706 | 694 |
707 ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, | 695 ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, |
708 "smtp mail from:\"%V\"", &s->smtp_from); | 696 "smtp mail from:\"%V\"", &s->smtp_from); |
709 | 697 |
710 ngx_str_set(&s->out, smtp_ok); | 698 ngx_str_set(&s->out, smtp_ok); |
714 | 702 |
715 | 703 |
716 static ngx_int_t | 704 static ngx_int_t |
717 ngx_mail_smtp_rcpt(ngx_mail_session_t *s, ngx_connection_t *c) | 705 ngx_mail_smtp_rcpt(ngx_mail_session_t *s, ngx_connection_t *c) |
718 { | 706 { |
719 u_char ch; | 707 ngx_str_t *arg, cmd; |
720 ngx_str_t l; | |
721 ngx_uint_t i; | |
722 | 708 |
723 if (s->smtp_from.len == 0) { | 709 if (s->smtp_from.len == 0) { |
724 ngx_str_set(&s->out, smtp_bad_sequence); | 710 ngx_str_set(&s->out, smtp_bad_sequence); |
725 return NGX_OK; | 711 return NGX_OK; |
726 } | 712 } |
727 | 713 |
728 l.len = s->buffer->last - s->buffer->start; | 714 arg = s->args.elts; |
729 l.data = s->buffer->start; | 715 arg += s->args.nelts - 1; |
730 | 716 |
731 for (i = 0; i < l.len; i++) { | 717 cmd.len = arg->data + arg->len - s->cmd.data; |
732 ch = l.data[i]; | 718 cmd.data = s->cmd.data; |
733 | 719 |
734 if (ch != CR && ch != LF) { | 720 s->smtp_to.len = cmd.len; |
735 continue; | 721 |
736 } | 722 s->smtp_to.data = ngx_pnalloc(c->pool, cmd.len); |
737 | |
738 l.data[i] = ' '; | |
739 } | |
740 | |
741 while (i) { | |
742 if (l.data[i - 1] != ' ') { | |
743 break; | |
744 } | |
745 | |
746 i--; | |
747 } | |
748 | |
749 l.len = i; | |
750 | |
751 s->smtp_to.len = l.len; | |
752 | |
753 s->smtp_to.data = ngx_pnalloc(c->pool, l.len); | |
754 if (s->smtp_to.data == NULL) { | 723 if (s->smtp_to.data == NULL) { |
755 return NGX_ERROR; | 724 return NGX_ERROR; |
756 } | 725 } |
757 | 726 |
758 ngx_memcpy(s->smtp_to.data, l.data, l.len); | 727 ngx_memcpy(s->smtp_to.data, cmd.data, cmd.len); |
759 | 728 |
760 ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, | 729 ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, |
761 "smtp rcpt to:\"%V\"", &s->smtp_to); | 730 "smtp rcpt to:\"%V\"", &s->smtp_to); |
762 | 731 |
763 s->auth_method = NGX_MAIL_AUTH_NONE; | 732 s->auth_method = NGX_MAIL_AUTH_NONE; |