Mercurial > hg > nginx-mail
comparison src/mail/ngx_mail_smtp_handler.c @ 436:9b19e26b2660
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 as the first argument 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 | Thu, 11 Sep 2008 15:26:25 +0400 |
parents | e2df123bbbe2 |
children | d67e93e97b4a |
comparison
equal
deleted
inserted
replaced
435:e2df123bbbe2 | 436:9b19e26b2660 |
---|---|
465 rc = ngx_mail_auth_cram_md5(s, c); | 465 rc = ngx_mail_auth_cram_md5(s, c); |
466 break; | 466 break; |
467 } | 467 } |
468 } | 468 } |
469 | 469 |
470 if (s->buffer->pos < s->buffer->last) { | |
471 s->blocked = 1; | |
472 } | |
473 | |
470 switch (rc) { | 474 switch (rc) { |
471 | 475 |
472 case NGX_DONE: | 476 case NGX_DONE: |
473 ngx_mail_auth(s, c); | 477 ngx_mail_auth(s, c); |
474 return; | 478 return; |
486 | 490 |
487 /* fall through */ | 491 /* fall through */ |
488 | 492 |
489 case NGX_OK: | 493 case NGX_OK: |
490 s->args.nelts = 0; | 494 s->args.nelts = 0; |
491 s->buffer->pos = s->buffer->start; | 495 |
492 s->buffer->last = s->buffer->start; | 496 if (s->buffer->pos == s->buffer->last) { |
497 s->buffer->pos = s->buffer->start; | |
498 s->buffer->last = s->buffer->start; | |
499 } | |
493 | 500 |
494 if (s->state) { | 501 if (s->state) { |
495 s->arg_start = s->buffer->start; | 502 s->arg_start = s->buffer->pos; |
496 } | 503 } |
497 | 504 |
498 ngx_mail_send(c->write); | 505 ngx_mail_send(c->write); |
499 } | 506 } |
500 } | 507 } |
504 ngx_mail_smtp_helo(ngx_mail_session_t *s, ngx_connection_t *c) | 511 ngx_mail_smtp_helo(ngx_mail_session_t *s, ngx_connection_t *c) |
505 { | 512 { |
506 ngx_str_t *arg; | 513 ngx_str_t *arg; |
507 ngx_mail_smtp_srv_conf_t *sscf; | 514 ngx_mail_smtp_srv_conf_t *sscf; |
508 | 515 |
509 if (s->args.nelts != 1) { | 516 if (s->args.nelts != 2) { |
510 s->out.len = sizeof(smtp_invalid_argument) - 1; | 517 s->out.len = sizeof(smtp_invalid_argument) - 1; |
511 s->out.data = smtp_invalid_argument; | 518 s->out.data = smtp_invalid_argument; |
512 s->state = 0; | 519 s->state = 0; |
513 return NGX_OK; | 520 return NGX_OK; |
514 } | 521 } |
515 | 522 |
516 arg = s->args.elts; | 523 arg = s->args.elts; |
517 | 524 |
518 s->smtp_helo.len = arg[0].len; | 525 s->smtp_helo.len = arg[1].len; |
519 | 526 |
520 s->smtp_helo.data = ngx_pnalloc(c->pool, arg[0].len); | 527 s->smtp_helo.data = ngx_pnalloc(c->pool, arg[1].len); |
521 if (s->smtp_helo.data == NULL) { | 528 if (s->smtp_helo.data == NULL) { |
522 return NGX_ERROR; | 529 return NGX_ERROR; |
523 } | 530 } |
524 | 531 |
525 ngx_memcpy(s->smtp_helo.data, arg[0].data, arg[0].len); | 532 ngx_memcpy(s->smtp_helo.data, arg[1].data, arg[1].len); |
526 | 533 |
527 s->smtp_from.len = 0; | 534 s->smtp_from.len = 0; |
528 s->smtp_from.data = NULL; | 535 s->smtp_from.data = NULL; |
529 s->smtp_to.len = 0; | 536 s->smtp_to.len = 0; |
530 s->smtp_to.data = NULL; | 537 s->smtp_to.data = NULL; |
574 if (ngx_mail_starttls_only(s, c)) { | 581 if (ngx_mail_starttls_only(s, c)) { |
575 return NGX_MAIL_PARSE_INVALID_COMMAND; | 582 return NGX_MAIL_PARSE_INVALID_COMMAND; |
576 } | 583 } |
577 #endif | 584 #endif |
578 | 585 |
579 if (s->args.nelts == 0) { | 586 if (s->args.nelts < 2) { |
580 s->out.len = sizeof(smtp_invalid_argument) - 1; | 587 s->out.len = sizeof(smtp_invalid_argument) - 1; |
581 s->out.data = smtp_invalid_argument; | 588 s->out.data = smtp_invalid_argument; |
582 s->state = 0; | 589 s->state = 0; |
583 return NGX_OK; | 590 return NGX_OK; |
584 } | 591 } |
632 | 639 |
633 | 640 |
634 static ngx_int_t | 641 static ngx_int_t |
635 ngx_mail_smtp_mail(ngx_mail_session_t *s, ngx_connection_t *c) | 642 ngx_mail_smtp_mail(ngx_mail_session_t *s, ngx_connection_t *c) |
636 { | 643 { |
637 u_char ch; | 644 ngx_str_t *arg, *end, cmd; |
638 ngx_str_t l; | |
639 ngx_uint_t i; | |
640 ngx_mail_smtp_srv_conf_t *sscf; | 645 ngx_mail_smtp_srv_conf_t *sscf; |
641 | 646 |
642 sscf = ngx_mail_get_module_srv_conf(s, ngx_mail_smtp_module); | 647 sscf = ngx_mail_get_module_srv_conf(s, ngx_mail_smtp_module); |
643 | 648 |
644 if (!(sscf->auth_methods & NGX_MAIL_AUTH_NONE_ENABLED)) { | 649 if (!(sscf->auth_methods & NGX_MAIL_AUTH_NONE_ENABLED)) { |
657 s->out.len = sizeof(smtp_bad_sequence) - 1; | 662 s->out.len = sizeof(smtp_bad_sequence) - 1; |
658 s->out.data = smtp_bad_sequence; | 663 s->out.data = smtp_bad_sequence; |
659 return NGX_OK; | 664 return NGX_OK; |
660 } | 665 } |
661 | 666 |
662 l.len = s->buffer->last - s->buffer->start; | 667 arg = s->args.elts; |
663 l.data = s->buffer->start; | 668 end = arg + s->args.nelts - 1; |
664 | 669 |
665 for (i = 0; i < l.len; i++) { | 670 cmd.len = end->data + end->len - arg->data; |
666 ch = l.data[i]; | 671 cmd.data = arg->data; |
667 | 672 |
668 if (ch != CR && ch != LF) { | 673 s->smtp_from.len = cmd.len; |
669 continue; | 674 |
670 } | 675 s->smtp_from.data = ngx_palloc(c->pool, cmd.len); |
671 | |
672 l.data[i] = ' '; | |
673 } | |
674 | |
675 while (i) { | |
676 if (l.data[i - 1] != ' ') { | |
677 break; | |
678 } | |
679 | |
680 i--; | |
681 } | |
682 | |
683 l.len = i; | |
684 | |
685 s->smtp_from.len = l.len; | |
686 | |
687 s->smtp_from.data = ngx_palloc(c->pool, l.len); | |
688 if (s->smtp_from.data == NULL) { | 676 if (s->smtp_from.data == NULL) { |
689 return NGX_ERROR; | 677 return NGX_ERROR; |
690 } | 678 } |
691 | 679 |
692 ngx_memcpy(s->smtp_from.data, l.data, l.len); | 680 ngx_memcpy(s->smtp_from.data, cmd.data, cmd.len); |
693 | 681 |
694 s->out.len = sizeof(smtp_ok) - 1; | 682 s->out.len = sizeof(smtp_ok) - 1; |
695 s->out.data = smtp_ok; | 683 s->out.data = smtp_ok; |
696 | 684 |
697 return NGX_OK; | 685 return NGX_OK; |
699 | 687 |
700 | 688 |
701 static ngx_int_t | 689 static ngx_int_t |
702 ngx_mail_smtp_rcpt(ngx_mail_session_t *s, ngx_connection_t *c) | 690 ngx_mail_smtp_rcpt(ngx_mail_session_t *s, ngx_connection_t *c) |
703 { | 691 { |
704 u_char ch; | 692 ngx_str_t *arg, *end, cmd; |
705 ngx_str_t l; | |
706 ngx_uint_t i; | |
707 | 693 |
708 if (s->smtp_from.len == 0) { | 694 if (s->smtp_from.len == 0) { |
709 s->out.len = sizeof(smtp_bad_sequence) - 1; | 695 s->out.len = sizeof(smtp_bad_sequence) - 1; |
710 s->out.data = smtp_bad_sequence; | 696 s->out.data = smtp_bad_sequence; |
711 return NGX_OK; | 697 return NGX_OK; |
712 } | 698 } |
713 | 699 |
714 l.len = s->buffer->last - s->buffer->start; | 700 arg = s->args.elts; |
715 l.data = s->buffer->start; | 701 end = arg + s->args.nelts - 1; |
716 | 702 |
717 for (i = 0; i < l.len; i++) { | 703 cmd.len = end->data + end->len - arg->data; |
718 ch = l.data[i]; | 704 cmd.data = arg->data; |
719 | 705 |
720 if (ch != CR && ch != LF) { | 706 s->smtp_to.len = cmd.len; |
721 continue; | 707 |
722 } | 708 s->smtp_to.data = ngx_palloc(c->pool, cmd.len); |
723 | |
724 l.data[i] = ' '; | |
725 } | |
726 | |
727 while (i) { | |
728 if (l.data[i - 1] != ' ') { | |
729 break; | |
730 } | |
731 | |
732 i--; | |
733 } | |
734 | |
735 l.len = i; | |
736 | |
737 s->smtp_to.len = l.len; | |
738 | |
739 s->smtp_to.data = ngx_palloc(c->pool, l.len); | |
740 if (s->smtp_to.data == NULL) { | 709 if (s->smtp_to.data == NULL) { |
741 return NGX_ERROR; | 710 return NGX_ERROR; |
742 } | 711 } |
743 | 712 |
744 ngx_memcpy(s->smtp_to.data, l.data, l.len); | 713 ngx_memcpy(s->smtp_to.data, cmd.data, cmd.len); |
745 | 714 |
746 s->auth_method = NGX_MAIL_AUTH_NONE; | 715 s->auth_method = NGX_MAIL_AUTH_NONE; |
747 | 716 |
748 return NGX_DONE; | 717 return NGX_DONE; |
749 } | 718 } |