comparison src/mail/ngx_mail_handler.c @ 7829:2851e4c7de03

Mail: fixed reading with fully filled buffer (ticket #2159). With SMTP pipelining, ngx_mail_read_command() can be called with s->buffer without any space available, to parse additional commands received to the buffer on previous calls. Previously, this resulted in recv() being called with zero length, resulting in zero being returned, which was interpreted as a connection close by the client, so nginx silently closed connection. Fix is to avoid calling c->recv() if there is no free space in the buffer, but continue parsing of the already received commands.
author Maxim Dounin <mdounin@mdounin.ru>
date Wed, 21 Apr 2021 23:24:59 +0300
parents 777373b5a169
children ec1071830799
comparison
equal deleted inserted replaced
7828:c40f7a65c506 7829:2851e4c7de03
831 ssize_t n; 831 ssize_t n;
832 ngx_int_t rc; 832 ngx_int_t rc;
833 ngx_str_t l; 833 ngx_str_t l;
834 ngx_mail_core_srv_conf_t *cscf; 834 ngx_mail_core_srv_conf_t *cscf;
835 835
836 n = c->recv(c, s->buffer->last, s->buffer->end - s->buffer->last); 836 if (s->buffer->last < s->buffer->end) {
837 837
838 if (n == NGX_ERROR || n == 0) { 838 n = c->recv(c, s->buffer->last, s->buffer->end - s->buffer->last);
839 ngx_mail_close_connection(c); 839
840 return NGX_ERROR; 840 if (n == NGX_ERROR || n == 0) {
841 } 841 ngx_mail_close_connection(c);
842 842 return NGX_ERROR;
843 if (n > 0) { 843 }
844 s->buffer->last += n; 844
845 } 845 if (n > 0) {
846 846 s->buffer->last += n;
847 if (n == NGX_AGAIN) { 847 }
848 if (s->buffer->pos == s->buffer->last) { 848
849 return NGX_AGAIN; 849 if (n == NGX_AGAIN) {
850 if (s->buffer->pos == s->buffer->last) {
851 return NGX_AGAIN;
852 }
850 } 853 }
851 } 854 }
852 855
853 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); 856 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
854 857