]> git.kaiwu.me - nginx.git/commitdiff
Mail: fixed handling of blocked client read events in proxy.
authorMaxim Dounin <mdounin@mdounin.ru>
Thu, 23 Mar 2023 23:53:21 +0000 (02:53 +0300)
committerMaxim Dounin <mdounin@mdounin.ru>
Thu, 23 Mar 2023 23:53:21 +0000 (02:53 +0300)
When establishing a connection to the backend, nginx blocks reading
from the client with ngx_mail_proxy_block_read().  Previously, such
events were lost, and in some cases this resulted in connection hangs.

Notably, this affected mail_imap_ssl.t on Windows, since the test
closes connections after requesting authentication, but without
waiting for any responses (so the connection close events might be
lost).

Fix is to post an event to read from the client after connecting to
the backend if there were blocked events.

src/mail/ngx_mail_proxy_module.c

index 06679d4e0c9cc970f107738d1360328ad970edec..efed9ab3e610c0f853386d925aef4d38b66fd54c 100644 (file)
@@ -327,7 +327,9 @@ ngx_mail_proxy_pop3_handler(ngx_event_t *rev)
         c->log->action = NULL;
         ngx_log_error(NGX_LOG_INFO, c->log, 0, "client logged in");
 
-        if (s->buffer->pos < s->buffer->last) {
+        if (s->buffer->pos < s->buffer->last
+            || s->connection->read->ready)
+        {
             ngx_post_event(c->write, &ngx_posted_events);
         }
 
@@ -486,7 +488,9 @@ ngx_mail_proxy_imap_handler(ngx_event_t *rev)
         c->log->action = NULL;
         ngx_log_error(NGX_LOG_INFO, c->log, 0, "client logged in");
 
-        if (s->buffer->pos < s->buffer->last) {
+        if (s->buffer->pos < s->buffer->last
+            || s->connection->read->ready)
+        {
             ngx_post_event(c->write, &ngx_posted_events);
         }
 
@@ -821,7 +825,9 @@ ngx_mail_proxy_smtp_handler(ngx_event_t *rev)
         c->log->action = NULL;
         ngx_log_error(NGX_LOG_INFO, c->log, 0, "client logged in");
 
-        if (s->buffer->pos < s->buffer->last) {
+        if (s->buffer->pos < s->buffer->last
+            || s->connection->read->ready)
+        {
             ngx_post_event(c->write, &ngx_posted_events);
         }