changeset 116:e38f51cd0905 NGINX_0_3_5

nginx 0.3.5 *) Bugfix: the segmentation fault may occurred if the IMAP/POP3 login was changed by authorization server; bug appeared in 0.2.2. *) Bugfix: the accept mutex did not work and all connections were handled by one process; bug appeared in 0.3.3. *) Bugfix: the timeout did not work if the "rtsig" method and the "timer_resolution" directive were used.
author Igor Sysoev <http://sysoev.ru>
date Fri, 21 Oct 2005 00:00:00 +0400
parents 45a230988aa5
children 0821ea4ccfc5
files CHANGES CHANGES.ru conf/mime.types src/core/nginx.h src/event/modules/ngx_devpoll_module.c src/event/modules/ngx_epoll_module.c src/event/modules/ngx_kqueue_module.c src/event/modules/ngx_poll_module.c src/event/modules/ngx_rtsig_module.c src/event/modules/ngx_select_module.c src/event/ngx_event.c src/http/ngx_http_request.c src/imap/ngx_imap_auth_http_module.c src/imap/ngx_imap_handler.c
diffstat 14 files changed, 202 insertions(+), 205 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,17 @@
 
-Changes with nginx 0.3.4                                         19 Sep 2005
+Changes with nginx 0.3.5                                         21 Oct 2005
+
+    *) Bugfix: the segmentation fault may occurred if the IMAP/POP3 login 
+       was changed by authorization server; bug appeared in 0.2.2.
+
+    *) Bugfix: the accept mutex did not work and all connections were 
+       handled by one process; bug appeared in 0.3.3.
+
+    *) Bugfix: the timeout did not work if the "rtsig" method and the 
+       "timer_resolution" directive were used.
+
+
+Changes with nginx 0.3.4                                         19 Oct 2005
 
     *) Bugfix: nginx could not be built on Linux 2.4+ and MacOS X; bug 
        appeared in 0.3.3.
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,5 +1,17 @@
 
-Изменения в nginx 0.3.4                                           19.09.2005
+Изменения в nginx 0.3.5                                           21.10.2005
+
+    *) Исправление: если логин IMAP/POP3 менялся сервером авторизации, то 
+       мог произойти segmentation fault; ошибка появилась в 0.2.2.
+
+    *) Исправление: accept mutex не работал, все соединения обрабатывались 
+       одним рабочим процессом; ошибка появилась в 0.3.3.
+
+    *) Исправление: при использовании метода rtsig и директивы 
+       timer_resolution не работали таймауты.
+
+
+Изменения в nginx 0.3.4                                           19.10.2005
 
     *) Исправление: nginx не собирался на Linux 2.4+ и MacOS X; ошибка 
        появилась в 0.3.3.
--- a/conf/mime.types
+++ b/conf/mime.types
@@ -1,31 +1,52 @@
 
 types {
-    text/html                      html htm shtml;
-    text/xml                       xml rss;
-    text/css                       css;
-    text/plain                     txt;
-    text/x-component               htc;
+    text/css                              css;
+    text/html                             html htm shtml;
+    text/plain                            txt;
+    text/xml                              xml rss;
+    text/x-component                      htc;
+    text/mathml                           mml;
 
-    image/gif                      gif;
-    image/png                      png;
-    image/jpeg                     jpeg jpg;
-    image/x-icon                   ico;
-    image/x-jng                    jng;
+    image/gif                             gif;
+    image/jpeg                            jpeg jpg;
+    image/png                             png;
+    image/x-icon                          ico;
+    image/x-jng                           jng;
 
-    application/pdf                pdf;
-    application/x-shockwave-flash  swf;
-    application/x-javascript       js;
-    application/x-rar-compressed   rar;
-    application/x-xpinstall        xpi;
-    application/x-x509-ca-cert     der pem crt;
+    application/java-archive              jar war ear;
+    application/mac-binhex40              hqx;
+    application/pdf                       pdf;
+    application/x-cocoa                   cco;
+    application/x-javascript              js;
+    application/x-java-archive-diff       jardiff;
+    application/x-java-jnlp-file          jnlp;
+    application/x-makeself                run;
+    application/x-perl                    pl pm;
+    application/x-pilot                   prc pdb;
+    application/x-rar-compressed          rar;
+    application/x-redhat-package-manager  rpm;
+    application/x-sea                     sea;
+    application/x-shockwave-flash         swf;
+    application/x-stuffit                 sit;
+    application/x-tcl                     tcl tk;
+    application/x-x509-ca-cert            der pem crt;
+    application/x-xpinstall               xpi;
+    application/zip                       zip;
 
-    audio/mpeg                     mp3;
-    audio/x-realaudio              ra;
+    application/octet-stream              deb;
+    application/octet-stream              bin exe dll;
+    application/octet-stream              dmg;
+    application/octet-stream              eot;
+    application/octet-stream              iso img;
+    application/octet-stream              msi msp msm;
 
-    video/mpeg                     mpeg mpg;
-    video/quicktime                mov;
-    video/x-flv                    flv;
-    video/x-msvideo                avi;
-    video/x-ms-wmv                 wmv;
-    video/x-mng                    mng;
+    audio/mpeg                            mp3;
+    audio/x-realaudio                     ra;
+
+    video/mpeg                            mpeg mpg;
+    video/quicktime                       mov;
+    video/x-flv                           flv;
+    video/x-msvideo                       avi;
+    video/x-ms-wmv                        wmv;
+    video/x-mng                           mng;
 }
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,7 +8,7 @@
 #define _NGINX_H_INCLUDED_
 
 
-#define NGINX_VER          "nginx/0.3.4"
+#define NGINX_VER          "nginx/0.3.5"
 
 #define NGINX_VAR          "NGINX"
 #define NGX_OLDPID_EXT     ".oldbin"
--- a/src/event/modules/ngx_devpoll_module.c
+++ b/src/event/modules/ngx_devpoll_module.c
@@ -332,7 +332,6 @@ ngx_devpoll_process_events(ngx_cycle_t *
     ngx_err_t           err;
     ngx_int_t           i;
     ngx_uint_t          level;
-    ngx_msec_t          delta;
     ngx_event_t        *rev, *wev, **queue;
     ngx_connection_t   *c;
     struct dvpoll       dvp;
@@ -349,6 +348,8 @@ ngx_devpoll_process_events(ngx_cycle_t *
                           "write(/dev/poll) failed");
             return NGX_ERROR;
         }
+
+        nchanges = 0;
     }
 
     dvp.dp_fds = event_list;
@@ -362,10 +363,6 @@ ngx_devpoll_process_events(ngx_cycle_t *
         err = 0;
     }
 
-    nchanges = 0;
-
-    delta = ngx_current_msec;
-    
     if (flags & NGX_UPDATE_TIME) {
         ngx_time_update(0, 0);
     }
@@ -388,21 +385,14 @@ ngx_devpoll_process_events(ngx_cycle_t *
         return NGX_ERROR;
     }
 
-    if (timer != NGX_TIMER_INFINITE) {
-        delta = ngx_current_msec - delta;
+    if (events == 0) {
+        if (timer != NGX_TIMER_INFINITE) {
+            return NGX_OK;
+        }
 
-        ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
-                       "devpoll timer: %M, delta: %M", timer, delta);
-    } else {
-        if (events == 0) {
-            ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
-                          "ioctl(DP_POLL) returned no events without timeout");
-            return NGX_ERROR;
-        }
-    }
-
-    if (events == 0) {
-        return NGX_OK;
+        ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
+                      "ioctl(DP_POLL) returned no events without timeout");
+        return NGX_ERROR;
     }
 
     ngx_mutex_lock(ngx_posted_events_mutex);
--- a/src/event/modules/ngx_epoll_module.c
+++ b/src/event/modules/ngx_epoll_module.c
@@ -391,7 +391,6 @@ ngx_epoll_process_events(ngx_cycle_t *cy
     ngx_uint_t         level;
     ngx_err_t          err;
     ngx_log_t         *log;
-    ngx_msec_t         delta;
     ngx_event_t       *rev, *wev, **queue;
     ngx_connection_t  *c;
 
@@ -408,25 +407,10 @@ ngx_epoll_process_events(ngx_cycle_t *cy
         err = 0;
     }
 
-    delta = ngx_current_msec;
-    
     if (flags & NGX_UPDATE_TIME) {
         ngx_time_update(0, 0);
     }
 
-    if (timer != NGX_TIMER_INFINITE) {
-        delta = ngx_current_msec - delta;
-
-        ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
-                       "epoll timer: %M, delta: %M", timer, delta);
-    } else {
-        if (events == 0) {
-            ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
-                          "epoll_wait() returned no events without timeout");
-            return NGX_ERROR;
-        }
-    }
-
     if (err) {
         if (err == NGX_EINTR) {
 
@@ -446,7 +430,13 @@ ngx_epoll_process_events(ngx_cycle_t *cy
     }
 
     if (events == 0) {
-        return NGX_OK;
+        if (timer != NGX_TIMER_INFINITE) {
+            return NGX_OK;
+        }
+
+        ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
+                      "epoll_wait() returned no events without timeout");
+        return NGX_ERROR;
     }
 
     ngx_mutex_lock(ngx_posted_events_mutex);
--- a/src/event/modules/ngx_kqueue_module.c
+++ b/src/event/modules/ngx_kqueue_module.c
@@ -473,7 +473,6 @@ ngx_kqueue_process_events(ngx_cycle_t *c
     ngx_int_t         i, instance;
     ngx_uint_t        level;
     ngx_err_t         err;
-    ngx_msec_t        delta;
     ngx_event_t      *ev, **queue;
     struct timespec   ts, *tp;
 
@@ -509,8 +508,6 @@ ngx_kqueue_process_events(ngx_cycle_t *c
         err = 0;
     }
 
-    delta = ngx_current_msec;
-
     if (flags & NGX_UPDATE_TIME) {
         ngx_time_update(0, 0);
     }
@@ -536,22 +533,14 @@ ngx_kqueue_process_events(ngx_cycle_t *c
         return NGX_ERROR;
     }
 
-    if (timer != NGX_TIMER_INFINITE) {
-        delta = ngx_current_msec - delta;
-
-        ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
-                       "kevent timer: %M, delta: %M", timer, delta);
+    if (events == 0) {
+        if (timer != NGX_TIMER_INFINITE) {
+            return NGX_OK;
+        }
 
-    } else {
-        if (events == 0) {
-            ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
-                          "kevent() returned no events without timeout");
-            return NGX_ERROR;
-        }
-    }
-
-    if (events == 0) {
-        return NGX_OK;
+        ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
+                      "kevent() returned no events without timeout");
+        return NGX_ERROR;
     }
 
     ngx_mutex_lock(ngx_posted_events_mutex);
--- a/src/event/modules/ngx_poll_module.c
+++ b/src/event/modules/ngx_poll_module.c
@@ -241,7 +241,6 @@ ngx_poll_process_events(ngx_cycle_t *cyc
     ngx_err_t           err;
     ngx_int_t           i, nready;
     ngx_uint_t          found, level;
-    ngx_msec_t          delta;
     ngx_event_t        *ev, **queue;
     ngx_connection_t   *c;
 
@@ -267,8 +266,6 @@ ngx_poll_process_events(ngx_cycle_t *cyc
         err = 0;
     }
 
-    delta = ngx_current_msec;
-
     if (flags & NGX_UPDATE_TIME) {
         ngx_time_update(0, 0);
     }
@@ -294,21 +291,14 @@ ngx_poll_process_events(ngx_cycle_t *cyc
         return NGX_ERROR;
     }
 
-    if (timer != NGX_TIMER_INFINITE) {
-        delta = ngx_current_msec - delta;
+    if (ready == 0) {
+        if (timer != NGX_TIMER_INFINITE) {
+            return NGX_OK;
+        }
 
-        ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
-                       "poll timer: %M, delta: %M", timer, delta);
-    } else {
-        if (ready == 0) {
-            ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
-                          "poll() returned no events without timeout");
-            return NGX_ERROR;
-        }
-    }
-
-    if (ready == 0) {
-        return NGX_OK;
+        ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
+                      "poll() returned no events without timeout");
+        return NGX_ERROR;
     }
 
     ngx_mutex_lock(ngx_posted_events_mutex);
--- a/src/event/modules/ngx_rtsig_module.c
+++ b/src/event/modules/ngx_rtsig_module.c
@@ -286,7 +286,6 @@ ngx_rtsig_process_events(ngx_cycle_t *cy
 {
     int                 signo;
     ngx_int_t           instance;
-    ngx_msec_t          delta;
     ngx_err_t           err;
     siginfo_t           si;
     ngx_event_t        *rev, *wev;
@@ -317,41 +316,34 @@ ngx_rtsig_process_events(ngx_cycle_t *cy
         ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, err,
                        "rtsig signo:%d", signo);
 
-        if (err == NGX_EAGAIN) {
-
-            if (timer == NGX_TIMER_INFINITE) {
-                ngx_log_error(NGX_LOG_ALERT, cycle->log, err,
-                              "sigtimedwait() returned EAGAIN without timeout");
-                return NGX_ERROR;
-            }
-
-            err = 0;
+        if (flags & NGX_UPDATE_TIME) {
+            ngx_time_update(0, 0);
         }
 
-    } else {
-        err = 0;
-        ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
-                       "rtsig signo:%d fd:%d band:%04Xd",
-                       signo, si.si_fd, si.si_band);
-    }
+        if (err == NGX_EAGAIN) {
+
+            /* timeout */
 
-    delta = ngx_current_msec;
-    
-    if (flags & NGX_UPDATE_TIME) {
-        ngx_time_update(0, 0);
-    }
+            if (timer != NGX_TIMER_INFINITE) {
+                return NGX_AGAIN;
+            }
+                
+            ngx_log_error(NGX_LOG_ALERT, cycle->log, err,
+                          "sigtimedwait() returned EAGAIN without timeout");
+            return NGX_ERROR;
+        }
 
-    if (err) {
         ngx_log_error((err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT,
                       cycle->log, err, "sigtimedwait() failed");
         return NGX_ERROR;
     }
 
-    if (timer != NGX_TIMER_INFINITE) {
-        delta = ngx_current_msec - delta;
+    ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
+                   "rtsig signo:%d fd:%d band:%04Xd",
+                   signo, si.si_fd, si.si_band);
 
-        ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
-                       "rtsig timer: %M, delta: %M", timer, delta);
+    if (flags & NGX_UPDATE_TIME) {
+        ngx_time_update(0, 0);
     }
 
     rtscf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_rtsig_module);
@@ -400,8 +392,12 @@ ngx_rtsig_process_events(ngx_cycle_t *cy
             wev->handler(wev);
         }
 
+        return NGX_OK;
+
     } else if (signo == SIGALRM) {
 
+        ngx_time_update(0, 0);
+
         return NGX_OK;
 
     } else if (signo == SIGIO) {
@@ -431,18 +427,12 @@ ngx_rtsig_process_events(ngx_cycle_t *cy
 
         return NGX_ERROR;
 
-    } else if (signo != -1) {
-        ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
-                      "sigtimedwait() returned unexpected signal: %d", signo);
-
-        return NGX_ERROR;
     }
 
-    if (signo != -1) {
-        return NGX_OK;
-    }
+    ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
+                  "sigtimedwait() returned unexpected signal: %d", signo);
 
-    return NGX_AGAIN;
+    return NGX_ERROR;
 }
 
 
--- a/src/event/modules/ngx_select_module.c
+++ b/src/event/modules/ngx_select_module.c
@@ -250,7 +250,6 @@ ngx_select_process_events(ngx_cycle_t *c
     int                 ready, nready;
     ngx_uint_t          i, found;
     ngx_err_t           err;
-    ngx_msec_t          delta;
     ngx_event_t        *ev, **queue;
     ngx_connection_t   *c;
     struct timeval      tv, *tp;
@@ -331,26 +330,10 @@ ngx_select_process_events(ngx_cycle_t *c
         err = 0;
     }
 
-    delta = ngx_current_msec;
-
     if (flags & NGX_UPDATE_TIME) {
         ngx_time_update(0, 0);
     }
 
-    if (timer != NGX_TIMER_INFINITE) {
-        delta = ngx_current_msec - delta;
-
-        ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
-                       "select timer: %M, delta: %M", timer, delta);
-
-    } else {
-        if (ready == 0) {
-            ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
-                          "select() returned no events without timeout");
-            return NGX_ERROR;
-        }
-    }
-
     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
                    "select ready %d", ready);
 
@@ -383,8 +366,14 @@ ngx_select_process_events(ngx_cycle_t *c
 
 #endif
 
-    if (nevents == 0) {
-        return NGX_OK;
+    if (ready == 0) {
+        if (timer != NGX_TIMER_INFINITE) {
+            return NGX_OK;
+        }
+
+        ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
+                      "select() returned no events without timeout");
+        return NGX_ERROR;
     }
 
     ngx_mutex_lock(ngx_posted_events_mutex);
--- a/src/event/ngx_event.c
+++ b/src/event/ngx_event.c
@@ -199,7 +199,7 @@ void
 ngx_process_events_and_timers(ngx_cycle_t *cycle)
 {
     ngx_uint_t  flags;
-    ngx_msec_t  timer;
+    ngx_msec_t  timer, delta;
 
     if (ngx_timer_resolution) {
         timer = NGX_TIMER_INFINITE;
@@ -240,16 +240,25 @@ ngx_process_events_and_timers(ngx_cycle_
         }
     }
 
+    delta = ngx_current_msec;
+
     (void) ngx_process_events(cycle, timer, flags);
 
-    ngx_event_expire_timers();
+    delta = ngx_current_msec - delta;
+
+    ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
+                   "timer delta: %M", delta);
+
+    if (delta) {
+        ngx_event_expire_timers();
+    }
 
     if (ngx_posted_accept_events) {
         ngx_event_process_posted(cycle, &ngx_posted_accept_events);
     }
 
     if (ngx_accept_mutex_held) {
-        ngx_accept_mutex = 0;
+        *ngx_accept_mutex = 0;
     }
 
     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -159,23 +159,18 @@ ngx_http_init_connection(ngx_connection_
 
     /* STUB: epoll edge */ c->write->handler = ngx_http_empty_handler;
 
+#if (NGX_STAT_STUB)
+    ngx_atomic_fetch_add(ngx_stat_reading, 1);
+#endif
+
     if (rev->ready) {
         /* the deferred accept(), rtsig, aio, iocp */
 
         if (ngx_accept_mutex) {
-
             ngx_post_event(rev, &ngx_posted_events);
-
-#if (NGX_STAT_STUB)
-            ngx_atomic_fetch_add(ngx_stat_reading, 1);
-#endif
             return;
         }
 
-#if (NGX_STAT_STUB)
-        ngx_atomic_fetch_add(ngx_stat_reading, 1);
-#endif
-
         ngx_http_init_request(rev);
         return;
     }
@@ -183,14 +178,12 @@ ngx_http_init_connection(ngx_connection_
     ngx_add_timer(rev, c->listening->post_accept_timeout);
 
     if (ngx_handle_read_event(rev, 0) == NGX_ERROR) {
+#if (NGX_STAT_STUB)
+        ngx_atomic_fetch_add(ngx_stat_reading, -1);
+#endif
         ngx_http_close_connection(c);
         return;
     }
-
-#if (NGX_STAT_STUB)
-    ngx_atomic_fetch_add(ngx_stat_reading, 1);
-#endif
-
 }
 
 
@@ -213,35 +206,24 @@ void ngx_http_init_request(ngx_event_t *
     ngx_http_ssl_srv_conf_t   *sscf;
 #endif
 
+#if (NGX_STAT_STUB)
+    ngx_atomic_fetch_add(ngx_stat_reading, -1);
+#endif
+
     c = rev->data;
 
     if (rev->timedout) {
         ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
 
-#if (NGX_STAT_STUB)
-        ngx_atomic_fetch_add(ngx_stat_reading, -1);
-#endif
-
         ngx_http_close_connection(c);
         return;
     }
 
     hc = c->data;
 
-    if (hc) {
-
-#if (NGX_STAT_STUB)
-        ngx_atomic_fetch_add(ngx_stat_reading, 1);
-#endif
-
-    } else {
+    if (hc == NULL) {
         hc = ngx_pcalloc(c->pool, sizeof(ngx_http_connection_t));
         if (hc == NULL) {
-
-#if (NGX_STAT_STUB)
-            ngx_atomic_fetch_add(ngx_stat_reading, -1);
-#endif
-
             ngx_http_close_connection(c);
             return;
         }
@@ -261,11 +243,6 @@ void ngx_http_init_request(ngx_event_t *
     } else {
         r = ngx_pcalloc(c->pool, sizeof(ngx_http_request_t));
         if (r == NULL) {
-
-#if (NGX_STAT_STUB)
-            ngx_atomic_fetch_add(ngx_stat_reading, -1);
-#endif
-
             ngx_http_close_connection(c);
             return;
         }
@@ -273,10 +250,6 @@ void ngx_http_init_request(ngx_event_t *
         hc->request = r;
     }
 
-#if (NGX_STAT_STUB)
-    ngx_atomic_fetch_add(ngx_stat_reading, -1);
-#endif
-
     c->data = r;
     r->http_connection = hc;
 
@@ -1652,8 +1625,15 @@ ngx_http_writer(ngx_http_request_t *r)
             ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT,
                           "client timed out");
             c->timedout = 1;
-            ngx_http_close_request(r, NGX_HTTP_REQUEST_TIME_OUT);
+
+#if 0
+            ngx_http_close_request(r->main, NGX_HTTP_REQUEST_TIME_OUT);
             ngx_http_close_connection(c);
+#endif
+
+            c->closed = 1;
+            ngx_http_finalize_request(r, 0);
+
             return;
         }
 
@@ -1665,7 +1645,7 @@ ngx_http_writer(ngx_http_request_t *r)
             ngx_add_timer(wev, clcf->send_timeout);
 
             if (ngx_handle_write_event(wev, clcf->send_lowat) == NGX_ERROR) {
-                ngx_http_close_request(r, 0);
+                ngx_http_close_request(r->main, 0);
                 ngx_http_close_connection(r->connection);
             }
 
@@ -1680,7 +1660,7 @@ ngx_http_writer(ngx_http_request_t *r)
             clcf = ngx_http_get_module_loc_conf(r->main, ngx_http_core_module);
 
             if (ngx_handle_write_event(wev, clcf->send_lowat) == NGX_ERROR) {
-                ngx_http_close_request(r, 0);
+                ngx_http_close_request(r->main, 0);
                 ngx_http_close_connection(r->connection);
             }
 
@@ -1711,7 +1691,7 @@ ngx_http_writer(ngx_http_request_t *r)
         }
 
         if (ngx_handle_write_event(wev, clcf->send_lowat) == NGX_ERROR) {
-            ngx_http_close_request(r, 0);
+            ngx_http_close_request(r->main, 0);
             ngx_http_close_connection(r->connection);
         }
 
@@ -1988,8 +1968,13 @@ ngx_http_set_keepalive(ngx_http_request_
 
         ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "pipelined request");
 
+#if (NGX_STAT_STUB)
+        ngx_atomic_fetch_add(ngx_stat_reading, 1);
+#endif
+
         hc->pipeline = 1;
         c->log->action = "reading client pipelined request line";
+
         ngx_http_init_request(rev);
         return;
     }
@@ -2206,6 +2191,10 @@ ngx_http_keepalive_handler(ngx_event_t *
 
     b->last += n;
 
+#if (NGX_STAT_STUB)
+    ngx_atomic_fetch_add(ngx_stat_reading, 1);
+#endif
+
     c->log->handler = ngx_http_log_error;
     c->log->action = "reading client request line";
 
@@ -2388,6 +2377,7 @@ ngx_http_close_request(ngx_http_request_
     }
 
 #if (NGX_STAT_STUB)
+
     if (r->stat_reading) {
         ngx_atomic_fetch_add(ngx_stat_reading, -1);
     }
@@ -2395,6 +2385,7 @@ ngx_http_close_request(ngx_http_request_
     if (r->stat_writing) {
         ngx_atomic_fetch_add(ngx_stat_writing, -1);
     }
+
 #endif
 
     if (error && r->headers_out.status == 0) {
--- a/src/imap/ngx_imap_auth_http_module.c
+++ b/src/imap/ngx_imap_auth_http_module.c
@@ -44,6 +44,7 @@ struct ngx_imap_auth_http_ctx_s {
     ngx_str_t                       addr;
     ngx_str_t                       port;
     ngx_str_t                       err;
+    ngx_str_t                       errmsg;
 
     time_t                          sleep;
 
@@ -459,6 +460,9 @@ ngx_imap_auth_http_process_headers(ngx_i
                     continue;
                 }
 
+                ctx->errmsg.len = len;
+                ctx->errmsg.data = ctx->header_start;
+
                 if (s->protocol == NGX_IMAP_POP3_PROTOCOL) {
                     size = sizeof("-ERR") - 1 + len + sizeof(CRLF) - 1;
 
@@ -486,6 +490,7 @@ ngx_imap_auth_http_process_headers(ngx_i
                 }
 
                 *p++ = ' ';
+
                 p = ngx_cpymem(p, ctx->header_start, len);
                 *p++ = CR; *p++ = LF;
 
@@ -519,7 +524,16 @@ ngx_imap_auth_http_process_headers(ngx_i
                                    sizeof("Auth-User") - 1) == 0)
             {
                 s->login.len = ctx->header_end - ctx->header_start;
-                s->login.data = ctx->header_start;
+
+                s->login.data = ngx_palloc(s->connection->pool, s->login.len);
+                if (s->login.data == NULL) {
+                    ngx_close_connection(ctx->peer.connection);
+                    ngx_destroy_pool(ctx->pool);
+                    ngx_imap_session_internal_server_error(s);
+                    return;
+                }
+
+                ngx_memcpy(s->login.data, ctx->header_start, s->login.len);
 
                 continue;
             }
@@ -550,14 +564,14 @@ ngx_imap_auth_http_process_headers(ngx_i
             ngx_close_connection(ctx->peer.connection);
 
             if (ctx->err.len) {
+                ngx_log_error(NGX_LOG_INFO, s->connection->log, 0,
+                              "client login failed: \"%V\"", &ctx->errmsg);
+
                 s->out = ctx->err;
                 timer = ctx->sleep;
 
                 ngx_destroy_pool(ctx->pool);
 
-                ngx_log_error(NGX_LOG_INFO, s->connection->log, 0,
-                              "client login failed");
-
                 if (timer == 0) {
                     s->quit = 1;
                     ngx_imap_send(s->connection->write);
--- a/src/imap/ngx_imap_handler.c
+++ b/src/imap/ngx_imap_handler.c
@@ -767,9 +767,9 @@ ngx_imap_ssl_close_handler(ngx_event_t *
 static u_char *
 ngx_imap_log_error(ngx_log_t *log, u_char *buf, size_t len)
 {
-    u_char                 *p;
-    ngx_imap_session_t     *s;
-    ngx_imap_log_ctx_t     *ctx;
+    u_char              *p;
+    ngx_imap_session_t  *s;
+    ngx_imap_log_ctx_t  *ctx;
 
     if (log->action) {
         p = ngx_snprintf(buf, len, " while %s", log->action);