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;