changeset 2268:33556140681a

*) ngx_http_upstream_test_next() *) add proxy_next_upstream http_502 and http_504 *) fix http_503
author Igor Sysoev <igor@sysoev.ru>
date Tue, 30 Sep 2008 15:39:02 +0000
parents 920be89a3d2d
children 7155dbb2317e
files src/http/modules/ngx_http_proxy_module.c src/http/ngx_http_upstream.c src/http/ngx_http_upstream.h
diffstat 3 files changed, 80 insertions(+), 48 deletions(-) [+]
line wrap: on
line diff
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -147,7 +147,9 @@ static ngx_conf_bitmask_t  ngx_http_prox
     { ngx_string("timeout"), NGX_HTTP_UPSTREAM_FT_TIMEOUT },
     { ngx_string("invalid_header"), NGX_HTTP_UPSTREAM_FT_INVALID_HEADER },
     { ngx_string("http_500"), NGX_HTTP_UPSTREAM_FT_HTTP_500 },
+    { ngx_string("http_502"), NGX_HTTP_UPSTREAM_FT_HTTP_502 },
     { ngx_string("http_503"), NGX_HTTP_UPSTREAM_FT_HTTP_503 },
+    { ngx_string("http_504"), NGX_HTTP_UPSTREAM_FT_HTTP_504 },
     { ngx_string("http_404"), NGX_HTTP_UPSTREAM_FT_HTTP_404 },
     { ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF },
     { ngx_null_string, 0 }
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -22,6 +22,8 @@ static void ngx_http_upstream_send_reque
     ngx_http_upstream_t *u);
 static void ngx_http_upstream_send_request_handler(ngx_event_t *wev);
 static void ngx_http_upstream_process_header(ngx_event_t *rev);
+static ngx_int_t ngx_http_upstream_test_next(ngx_http_request_t *r,
+    ngx_http_upstream_t *u);
 static ngx_int_t ngx_http_upstream_intercept_errors(ngx_http_request_t *r,
     ngx_http_upstream_t *u);
 static ngx_int_t ngx_http_upstream_test_connect(ngx_connection_t *c);
@@ -284,6 +286,15 @@ static ngx_http_variable_t  ngx_http_ups
 };
 
 
+static ngx_http_upstream_next_t  ngx_http_upstream_next_errors[] = {
+    { 500, NGX_HTTP_UPSTREAM_FT_HTTP_500 },
+    { 502, NGX_HTTP_UPSTREAM_FT_HTTP_502 },
+    { 503, NGX_HTTP_UPSTREAM_FT_HTTP_503 },
+    { 504, NGX_HTTP_UPSTREAM_FT_HTTP_504 },
+    { 404, NGX_HTTP_UPSTREAM_FT_HTTP_404 },
+    { 0, 0 }
+};
+
 void
 ngx_http_upstream_init(ngx_http_request_t *r)
 {
@@ -1174,53 +1185,16 @@ ngx_http_upstream_process_header(ngx_eve
 
     /* rc == NGX_OK */
 
-    if (u->headers_in.status_n >= NGX_HTTP_BAD_REQUEST
-        && r->subrequest_in_memory)
-    {
-        u->buffer.last = u->buffer.pos;
-    }
-
-    if (u->headers_in.status_n == NGX_HTTP_INTERNAL_SERVER_ERROR) {
-
-        if (u->peer.tries > 1
-            && (u->conf->next_upstream & NGX_HTTP_UPSTREAM_FT_HTTP_500))
-        {
-            ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_HTTP_500);
+    if (u->headers_in.status_n >= NGX_HTTP_BAD_REQUEST) {
+
+        if (r->subrequest_in_memory) {
+            u->buffer.last = u->buffer.pos;
+        }
+
+        if (ngx_http_upstream_test_next(r, u) == NGX_OK) {
             return;
         }
 
-#if (NGX_HTTP_CACHE)
-
-        if (u->peer.tries == 0
-            && u->stale
-            && (u->conf->use_stale & NGX_HTTP_UPSTREAM_FT_HTTP_500))
-        {
-            ngx_http_upstream_finalize_request(r, u,
-                                              ngx_http_send_cached_response(r));
-            return;
-        }
-
-#endif
-    }
-
-    if (u->headers_in.status_n == NGX_HTTP_NOT_FOUND) {
-
-        if (u->peer.tries > 1
-            && u->conf->next_upstream & NGX_HTTP_UPSTREAM_FT_HTTP_404)
-        {
-            ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_HTTP_404);
-            return;
-        }
-
-        if (u->conf->intercept_404) {
-            ngx_http_upstream_finalize_request(r, u, NGX_HTTP_NOT_FOUND);
-            return;
-        }
-    }
-
-
-    if (u->headers_in.status_n >= NGX_HTTP_BAD_REQUEST) {
-
         if (ngx_http_upstream_intercept_errors(r, u) == NGX_OK) {
             return;
         }
@@ -1380,6 +1354,49 @@ ngx_http_upstream_process_header(ngx_eve
 
 
 static ngx_int_t
+ngx_http_upstream_test_next(ngx_http_request_t *r, ngx_http_upstream_t *u)
+{
+    ngx_uint_t                 status;
+    ngx_http_upstream_next_t  *un;
+
+    if (!(u->conf->next_upstream & NGX_HTTP_UPSTREAM_FT_STATUS)) {
+        return NGX_DECLINED;
+    }
+
+    status = u->headers_in.status_n;
+
+    for (un = ngx_http_upstream_next_errors; un->status; un++) {
+
+        if (status != un->status) {
+            continue;
+        }
+
+        if (u->peer.tries > 1 && (u->conf->next_upstream & un->mask)) {
+            ngx_http_upstream_next(r, u, un->mask);
+            return NGX_OK;
+        }
+
+        if (status == NGX_HTTP_NOT_FOUND && u->conf->intercept_404) {
+            ngx_http_upstream_finalize_request(r, u, NGX_HTTP_NOT_FOUND);
+            return NGX_OK;
+        }
+
+#if (NGX_HTTP_CACHE)
+
+        if (u->peer.tries == 0 && u->stale && (u->conf->use_stale & un->mask)) {
+            ngx_http_upstream_finalize_request(r, u,
+                                              ngx_http_send_cached_response(r));
+            return NGX_OK;
+        }
+
+#endif
+    }
+
+    return NGX_DECLINED;
+}
+
+
+static ngx_int_t
 ngx_http_upstream_intercept_errors(ngx_http_request_t *r,
     ngx_http_upstream_t *u)
 {
--- a/src/http/ngx_http_upstream.h
+++ b/src/http/ngx_http_upstream.h
@@ -20,13 +20,20 @@
 #define NGX_HTTP_UPSTREAM_FT_TIMEOUT         0x00000004
 #define NGX_HTTP_UPSTREAM_FT_INVALID_HEADER  0x00000008
 #define NGX_HTTP_UPSTREAM_FT_HTTP_500        0x00000010
-#define NGX_HTTP_UPSTREAM_FT_HTTP_503        0x00000020
-#define NGX_HTTP_UPSTREAM_FT_HTTP_404        0x00000040
-#define NGX_HTTP_UPSTREAM_FT_BUSY_LOCK       0x00000080
-#define NGX_HTTP_UPSTREAM_FT_MAX_WAITING     0x00000100
+#define NGX_HTTP_UPSTREAM_FT_HTTP_502        0x00000020
+#define NGX_HTTP_UPSTREAM_FT_HTTP_503        0x00000040
+#define NGX_HTTP_UPSTREAM_FT_HTTP_504        0x00000080
+#define NGX_HTTP_UPSTREAM_FT_HTTP_404        0x00000100
+#define NGX_HTTP_UPSTREAM_FT_BUSY_LOCK       0x00000200
+#define NGX_HTTP_UPSTREAM_FT_MAX_WAITING     0x00000400
 #define NGX_HTTP_UPSTREAM_FT_NOLIVE          0x40000000
 #define NGX_HTTP_UPSTREAM_FT_OFF             0x80000000
 
+#define NGX_HTTP_UPSTREAM_FT_STATUS          (NGX_HTTP_UPSTREAM_FT_HTTP_500  \
+                                             |NGX_HTTP_UPSTREAM_FT_HTTP_502  \
+                                             |NGX_HTTP_UPSTREAM_FT_HTTP_503  \
+                                             |NGX_HTTP_UPSTREAM_FT_HTTP_504  \
+                                             |NGX_HTTP_UPSTREAM_FT_HTTP_404)
 
 #define NGX_HTTP_UPSTREAM_INVALID_HEADER     40
 
@@ -267,6 +274,12 @@ struct ngx_http_upstream_s {
 };
 
 
+typedef struct {
+    ngx_uint_t                      status;
+    ngx_uint_t                      mask;
+} ngx_http_upstream_next_t;
+
+
 ngx_int_t ngx_http_upstream_header_variable(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data);