]> git.kaiwu.me - nginx.git/commitdiff
*) ngx_http_upstream_test_next()
authorIgor Sysoev <igor@sysoev.ru>
Tue, 30 Sep 2008 15:39:02 +0000 (15:39 +0000)
committerIgor Sysoev <igor@sysoev.ru>
Tue, 30 Sep 2008 15:39:02 +0000 (15:39 +0000)
*) add proxy_next_upstream http_502 and http_504
*) fix http_503

src/http/modules/ngx_http_proxy_module.c
src/http/ngx_http_upstream.c
src/http/ngx_http_upstream.h

index d8392ee8d57ca6df5853b0383cfd8305cdd56565..f3d747f0fcea1208da6d78f0d76f581d014f1241 100644 (file)
@@ -147,7 +147,9 @@ static ngx_conf_bitmask_t  ngx_http_proxy_next_upstream_masks[] = {
     { 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 }
index 8e5a084a6d01f8f240521f074c27701bcd2b9e33..9144913be94fec46dfa3e8f3ee105a4a0934d8f9 100644 (file)
@@ -22,6 +22,8 @@ static void ngx_http_upstream_send_request(ngx_http_request_t *r,
     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_upstream_vars[] = {
 };
 
 
+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,52 +1185,15 @@ ngx_http_upstream_process_header(ngx_event_t *rev)
 
     /* 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);
-            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->headers_in.status_n >= NGX_HTTP_BAD_REQUEST) {
 
-        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 (r->subrequest_in_memory) {
+            u->buffer.last = u->buffer.pos;
         }
 
-        if (u->conf->intercept_404) {
-            ngx_http_upstream_finalize_request(r, u, NGX_HTTP_NOT_FOUND);
+        if (ngx_http_upstream_test_next(r, u) == NGX_OK) {
             return;
         }
-    }
-
-
-    if (u->headers_in.status_n >= NGX_HTTP_BAD_REQUEST) {
 
         if (ngx_http_upstream_intercept_errors(r, u) == NGX_OK) {
             return;
@@ -1379,6 +1353,49 @@ 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)
+{
+    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)
index 66c2cf3da7c323da90e5c4f7ed7915d469a5af36..dd72ba86da3e7f319203e90ac2e4f2bdf84eef71 100644 (file)
 #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);