diff src/event/ngx_event_pipe.c @ 276:c5c2b2883984 NGINX_0_5_8

nginx 0.5.8 *) Bugfix: a segmentation fault might occur if "client_body_in_file_only on" was used and a request body was small. *) Bugfix: a segmentation fault occurred if "client_body_in_file_only on" and "proxy_pass_request_body off" or "fastcgi_pass_request_body off" directives were used, and nginx switched to a next upstream. *) Bugfix: if the "proxy_buffering off" directive was used and a client connection was non-active, then the connection was closed after send timeout; bug appeared in 0.4.7. *) Bugfix: if the "epoll" method was used and a client closed a connection prematurely, then nginx closed the connection after a send timeout only. *) Bugfix: the "[alert] zero size buf" error when FastCGI server was used. *) Bugfixes in the "limit_zone" directive.
author Igor Sysoev <http://sysoev.ru>
date Fri, 19 Jan 2007 00:00:00 +0300
parents 052a7b1d40e5
children 3dbecd747fbb
line wrap: on
line diff
--- a/src/event/ngx_event_pipe.c
+++ b/src/event/ngx_event_pipe.c
@@ -420,7 +420,7 @@ static ngx_int_t
 ngx_event_pipe_write_to_downstream(ngx_event_pipe_t *p)
 {
     size_t             bsize;
-    ngx_uint_t         flush;
+    ngx_uint_t         flush, prev_last_shadow;
     ngx_chain_t       *out, **ll, *cl;
     ngx_connection_t  *downstream;
 
@@ -511,13 +511,13 @@ ngx_event_pipe_write_to_downstream(ngx_e
         out = NULL;
         ll = NULL;
         flush = 0;
+        prev_last_shadow = 1;
 
         for ( ;; ) {
             if (p->out) {
                 cl = p->out;
 
                 if (cl->buf->recycled
-                    && cl->buf->last_shadow
                     && bsize + cl->buf->last - cl->buf->pos > p->busy_size)
                 {
                     flush = 1;
@@ -541,10 +541,24 @@ ngx_event_pipe_write_to_downstream(ngx_e
                     && cl->buf->last_shadow
                     && bsize + cl->buf->last - cl->buf->pos > p->busy_size)
                 {
+                    if (!prev_last_shadow) {
+                        p->in = p->in->next;
+
+                        cl->next = NULL;
+
+                        if (out) {
+                            *ll = cl;
+                        } else {
+                            out = cl;
+                        }
+                    }
+
                     flush = 1;
                     break;
                 }
 
+                prev_last_shadow = cl->buf->last_shadow;
+
                 p->in = p->in->next;
 
             } else {