changeset 437:21aff1b3da48 NGINX_0_7_26

nginx 0.7.26 *) Bugfix: in subrequest processing; the bug had appeared in 0.7.25.
author Igor Sysoev <http://sysoev.ru>
date Mon, 08 Dec 2008 00:00:00 +0300
parents 135cffea8f75
children 3b8e9d1bc9bb
files CHANGES CHANGES.ru src/core/nginx.h src/http/modules/perl/nginx.pm src/http/ngx_http_upstream.c
diffstat 5 files changed, 174 insertions(+), 109 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,9 @@
 
+Changes with nginx 0.7.26                                        08 Dec 2008
+
+    *) Bugfix: in subrequest processing; the bug had appeared in 0.7.25.
+
+
 Changes with nginx 0.7.25                                        08 Dec 2008
 
     *) Change: in subrequest processing.
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,4 +1,9 @@
 
+Изменения в nginx 0.7.26                                          08.12.2008
+
+    *) Исправление: в обработке подзапросов; ошибка появилась в 0.7.25.
+
+
 Изменения в nginx 0.7.25                                          08.12.2008
 
     *) Изменение: в обработке подзапросов.
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,7 +8,7 @@
 #define _NGINX_H_INCLUDED_
 
 
-#define NGINX_VERSION      "0.7.25"
+#define NGINX_VERSION      "0.7.26"
 #define NGINX_VER          "nginx/" NGINX_VERSION
 
 #define NGINX_VAR          "NGINX"
--- a/src/http/modules/perl/nginx.pm
+++ b/src/http/modules/perl/nginx.pm
@@ -47,7 +47,7 @@ our @EXPORT = qw(
     HTTP_INSUFFICIENT_STORAGE
 );
 
-our $VERSION = '0.7.25';
+our $VERSION = '0.7.26';
 
 require XSLoader;
 XSLoader::load('nginx', $VERSION);
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -32,12 +32,16 @@ static void ngx_http_upstream_send_respo
     ngx_http_upstream_t *u);
 static void
     ngx_http_upstream_process_non_buffered_downstream(ngx_http_request_t *r);
-static void ngx_http_upstream_process_non_buffered_body(ngx_event_t *ev);
+static void ngx_http_upstream_process_non_buffered_upstream(ngx_event_t *ev);
+static void
+    ngx_http_upstream_process_non_buffered_request(ngx_http_request_t *r,
+    ngx_uint_t do_write);
 static ngx_int_t ngx_http_upstream_non_buffered_filter_init(void *data);
 static ngx_int_t ngx_http_upstream_non_buffered_filter(void *data,
     ssize_t bytes);
 static void ngx_http_upstream_process_downstream(ngx_http_request_t *r);
-static void ngx_http_upstream_process_body(ngx_event_t *ev);
+static void ngx_http_upstream_process_upstream(ngx_event_t *rev);
+static void ngx_http_upstream_process_request(ngx_http_request_t *r);
 static void ngx_http_upstream_store(ngx_http_request_t *r,
     ngx_http_upstream_t *u);
 static void ngx_http_upstream_dummy_handler(ngx_event_t *wev);
@@ -1651,7 +1655,7 @@ ngx_http_upstream_send_response(ngx_http
             u->input_filter_ctx = r;
         }
 
-        u->read_event_handler = ngx_http_upstream_process_non_buffered_body;
+        u->read_event_handler = ngx_http_upstream_process_non_buffered_upstream;
         r->write_event_handler =
                              ngx_http_upstream_process_non_buffered_downstream;
 
@@ -1689,7 +1693,7 @@ ngx_http_upstream_send_response(ngx_http
                 return;
             }
 
-            ngx_http_upstream_process_non_buffered_body(c->write);
+            ngx_http_upstream_process_non_buffered_downstream(r);
 
         } else {
             u->buffer.pos = u->buffer.start;
@@ -1701,7 +1705,7 @@ ngx_http_upstream_send_response(ngx_http
             }
 
             if (u->peer.connection->read->ready) {
-                ngx_http_upstream_process_non_buffered_body(
+                ngx_http_upstream_process_non_buffered_upstream(
                                                      u->peer.connection->read);
             }
         }
@@ -1832,69 +1836,85 @@ ngx_http_upstream_send_response(ngx_http
     p->send_timeout = clcf->send_timeout;
     p->send_lowat = clcf->send_lowat;
 
-    u->read_event_handler = ngx_http_upstream_process_body;
+    u->read_event_handler = ngx_http_upstream_process_upstream;
     r->write_event_handler = ngx_http_upstream_process_downstream;
 
-    ngx_http_upstream_process_body(u->peer.connection->read);
+    ngx_http_upstream_process_upstream(u->peer.connection->read);
 }
 
 
 static void
 ngx_http_upstream_process_non_buffered_downstream(ngx_http_request_t *r)
 {
-    ngx_http_upstream_process_non_buffered_body(r->connection->write);
+    ngx_event_t          *wev;
+    ngx_connection_t     *c;
+    ngx_http_upstream_t  *u;
+
+    c = r->connection;
+    u = r->upstream;
+    wev = c->write;
+
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                   "http upstream process non buffered downstream");
+
+    c->log->action = "sending to client";
+
+    if (wev->timedout) {
+        c->timedout = 1;
+        ngx_connection_error(c, NGX_ETIMEDOUT, "client timed out");
+        ngx_http_upstream_finalize_request(r, u, 0);
+        return;
+    }
+
+    ngx_http_upstream_process_non_buffered_request(r, 1);
 }
 
 
 static void
-ngx_http_upstream_process_non_buffered_body(ngx_event_t *ev)
+ngx_http_upstream_process_non_buffered_upstream(ngx_event_t *rev)
+{
+    ngx_connection_t     *c;
+    ngx_http_request_t   *r;
+    ngx_http_upstream_t  *u;
+
+    c = rev->data;
+    r = c->data;
+    u = r->upstream;
+
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                   "http upstream process non buffered upstream");
+
+    c->log->action = "reading upstream";
+
+    if (rev->timedout) {
+        ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out");
+        ngx_http_upstream_finalize_request(r, u, 0);
+        return;
+    }
+
+    ngx_http_upstream_process_non_buffered_request(r, 0);
+}
+
+
+static void
+ngx_http_upstream_process_non_buffered_request(ngx_http_request_t *r,
+    ngx_uint_t do_write)
 {
     size_t                     size;
     ssize_t                    n;
     ngx_buf_t                 *b;
     ngx_int_t                  rc;
-    ngx_uint_t                 do_write;
-    ngx_connection_t          *c, *downstream, *upstream;
-    ngx_http_request_t        *r;
+    ngx_connection_t          *downstream, *upstream;
     ngx_http_upstream_t       *u;
     ngx_http_core_loc_conf_t  *clcf;
 
-    c = ev->data;
-    r = c->data;
     u = r->upstream;
-
-    if (ev->write) {
-        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
-                       "http upstream process non buffered downstream");
-        c->log->action = "sending to client";
-
-    } else {
-        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
-                       "http upstream process non buffered upstream");
-        c->log->action = "reading upstream";
-    }
-
-    if (ev->timedout) {
-        if (ev->write) {
-            c->timedout = 1;
-            ngx_connection_error(c, NGX_ETIMEDOUT, "client timed out");
-
-        } else {
-            ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out");
-        }
-
-        ngx_http_upstream_finalize_request(r, u, 0);
-        return;
-    }
-
     downstream = r->connection;
     upstream = u->peer.connection;
 
     b = &u->buffer;
 
-    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
-    do_write = ev->write || u->length == 0;
+    do_write = do_write || u->length == 0;
 
     for ( ;; ) {
 
@@ -1960,6 +1980,8 @@ ngx_http_upstream_process_non_buffered_b
         break;
     }
 
+    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
     if (downstream->data == r) {
         if (ngx_handle_write_event(downstream->write, clcf->send_lowat)
             != NGX_OK)
@@ -2042,92 +2064,71 @@ ngx_http_upstream_non_buffered_filter(vo
 static void
 ngx_http_upstream_process_downstream(ngx_http_request_t *r)
 {
-    ngx_http_upstream_process_body(r->connection->write);
-}
-
-
-static void
-ngx_http_upstream_process_body(ngx_event_t *ev)
-{
-    ngx_temp_file_t      *tf;
+    ngx_event_t          *wev;
+    ngx_connection_t     *c;
     ngx_event_pipe_t     *p;
-    ngx_connection_t     *c, *downstream;
-    ngx_http_request_t   *r;
     ngx_http_upstream_t  *u;
 
-    c = ev->data;
-    r = c->data;
+    c = r->connection;
     u = r->upstream;
-    downstream = r->connection;
-
-    if (ev->write) {
-        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
-                       "http upstream process downstream");
-        c->log->action = "sending to client";
-
-    } else {
-        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
-                       "http upstream process upstream");
-        c->log->action = "reading upstream";
-    }
-
     p = u->pipe;
-
-    if (ev->timedout) {
-        if (ev->write) {
-            if (ev->delayed) {
-
-                ev->timedout = 0;
-                ev->delayed = 0;
-
-                if (!ev->ready) {
-                    ngx_add_timer(ev, p->send_timeout);
-
-                    if (ngx_handle_write_event(ev, p->send_lowat) != NGX_OK) {
-                        ngx_http_upstream_finalize_request(r, u, 0);
-                        return;
-                    }
-
+    wev = c->write;
+
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                   "http upstream process downstream");
+
+    c->log->action = "sending to client";
+
+    if (wev->timedout) {
+
+        if (wev->delayed) {
+
+            wev->timedout = 0;
+            wev->delayed = 0;
+
+            if (!wev->ready) {
+                ngx_add_timer(wev, p->send_timeout);
+
+                if (ngx_handle_write_event(wev, p->send_lowat) != NGX_OK) {
+                    ngx_http_upstream_finalize_request(r, u, 0);
+                }
+
+                return;
+            }
+
+            if (ngx_event_pipe(p, wev->write) == NGX_ABORT) {
+
+                if (c->destroyed) {
                     return;
                 }
 
-                if (ngx_event_pipe(p, ev->write) == NGX_ABORT) {
-
-                    if (downstream->destroyed) {
-                        return;
-                    }
-
-                    ngx_http_upstream_finalize_request(r, u, 0);
-                    return;
-                }
-
-            } else {
-                p->downstream_error = 1;
-                c->timedout = 1;
-                ngx_connection_error(c, NGX_ETIMEDOUT, "client timed out");
+                ngx_http_upstream_finalize_request(r, u, 0);
+                return;
             }
 
         } else {
-            p->upstream_error = 1;
-            ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out");
+            p->downstream_error = 1;
+            c->timedout = 1;
+            ngx_connection_error(c, NGX_ETIMEDOUT, "client timed out");
         }
 
     } else {
-        if (ev->write && ev->delayed) {
+
+        if (wev->delayed) {
+
             ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
                            "http downstream delayed");
 
-            if (ngx_handle_write_event(ev, p->send_lowat) != NGX_OK) {
+            if (ngx_handle_write_event(wev, p->send_lowat) != NGX_OK) {
                 ngx_http_upstream_finalize_request(r, u, 0);
-                return;
             }
 
             return;
         }
 
-        if (ngx_event_pipe(p, ev->write) == NGX_ABORT) {
-
-            if (downstream->destroyed) {
+        if (ngx_event_pipe(p, 1) == NGX_ABORT) {
+
+            if (c->destroyed) {
                 return;
             }
 
@@ -2136,6 +2137,60 @@ ngx_http_upstream_process_body(ngx_event
         }
     }
 
+    ngx_http_upstream_process_request(r);
+}
+
+
+static void
+ngx_http_upstream_process_upstream(ngx_event_t *rev)
+{
+    ngx_connection_t     *c;
+    ngx_event_pipe_t     *p;
+    ngx_http_request_t   *r;
+    ngx_http_upstream_t  *u;
+
+    c = rev->data;
+    r = c->data;
+    u = r->upstream;
+    p = u->pipe;
+
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                   "http upstream process upstream");
+
+    c->log->action = "reading upstream";
+
+    if (rev->timedout) {
+        p->upstream_error = 1;
+        ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out");
+
+    } else {
+        c = r->connection;
+
+        if (ngx_event_pipe(p, 0) == NGX_ABORT) {
+
+            if (c->destroyed) {
+                return;
+            }
+
+            ngx_http_upstream_finalize_request(r, u, 0);
+            return;
+        }
+    }
+
+    ngx_http_upstream_process_request(r);
+}
+
+
+static void
+ngx_http_upstream_process_request(ngx_http_request_t *r)
+{
+    ngx_temp_file_t      *tf;
+    ngx_event_pipe_t     *p;
+    ngx_http_upstream_t  *u;
+
+    u = r->upstream;
+    p = u->pipe;
+
     if (u->peer.connection) {
 
         if (u->store) {
@@ -2186,7 +2241,7 @@ ngx_http_upstream_process_body(ngx_event
 #endif
 
         if (p->upstream_done || p->upstream_eof || p->upstream_error) {
-            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
+            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                            "http upstream exit: %p", p->out);
 #if 0
             ngx_http_busy_unlock(u->conf->busy_lock, &u->busy_lock);
@@ -2197,7 +2252,7 @@ ngx_http_upstream_process_body(ngx_event
     }
 
     if (p->downstream_error) {
-        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
+        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                        "http upstream downstream error");
 
         if (!u->cacheable && u->peer.connection) {