[PATCH] Upstream: Add "before_send" option to the 'proxy_next_upstream'.

Yusuke Nojima nojima at ynojima.com
Fri Feb 19 16:21:14 UTC 2016


# HG changeset patch
# User Yusuke Nojima <nojima at ynojima.com>
# Date 1455896920 0
#      Fri Feb 19 15:48:40 2016 +0000
# Node ID 88bbee2e18f6d475ea7ed8ab61b0cb8142c535dc
# Parent  5dfc63c1d9ca5ff5a21a2b0238a2b2782549f62c
Upstream: Add "before_send" option to the 'proxy_next_upstream'.

"error" and "timeout" options are sometimes dangerous because
non-idempotent requests (e.g. typical POST requests) are sent to
more than one upstream server.

When "before_send" option is specified, a request is passed to
the next upstream if an error or a timeout has occurred before
sending the first byte of the request. With this option, one can
avoid the issue mentioned above without losing the ability to deal
with the upstream host failures and daemon failures.

diff -r 5dfc63c1d9ca -r 88bbee2e18f6 src/http/modules/ngx_http_proxy_module.c
--- a/src/http/modules/ngx_http_proxy_module.c  Thu Feb 18 15:49:11 2016 +0300
+++ b/src/http/modules/ngx_http_proxy_module.c  Fri Feb 19 15:48:40 2016 +0000
@@ -220,6 +220,7 @@
     { ngx_string("http_403"), NGX_HTTP_UPSTREAM_FT_HTTP_403 },
     { ngx_string("http_404"), NGX_HTTP_UPSTREAM_FT_HTTP_404 },
     { ngx_string("updating"), NGX_HTTP_UPSTREAM_FT_UPDATING },
+    { ngx_string("before_send"), NGX_HTTP_UPSTREAM_FT_BEFORE_SEND },
     { ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF },
     { ngx_null_string, 0 }
 };
diff -r 5dfc63c1d9ca -r 88bbee2e18f6 src/http/ngx_http_upstream.c
--- a/src/http/ngx_http_upstream.c      Thu Feb 18 15:49:11 2016 +0300
+++ b/src/http/ngx_http_upstream.c      Fri Feb 19 15:48:40 2016 +0000
@@ -3872,11 +3872,15 @@
     }

     if (status) {
+        int matches_next_condition = u->conf->next_upstream & ft_type;
+        if (u->conf->next_upstream & NGX_HTTP_UPSTREAM_FT_BEFORE_SEND)
+            matches_next_condition |= !u->request_sent;
+
         u->state->status = status;
         timeout = u->conf->next_upstream_timeout;

         if (u->peer.tries == 0
-            || !(u->conf->next_upstream & ft_type)
+            || !matches_next_condition
             || (u->request_sent && r->request_body_no_buffering)
             || (timeout && ngx_current_msec - u->peer.start_time >= timeout))
         {
diff -r 5dfc63c1d9ca -r 88bbee2e18f6 src/http/ngx_http_upstream.h
--- a/src/http/ngx_http_upstream.h      Thu Feb 18 15:49:11 2016 +0300
+++ b/src/http/ngx_http_upstream.h      Fri Feb 19 15:48:40 2016 +0000
@@ -29,6 +29,7 @@
 #define NGX_HTTP_UPSTREAM_FT_UPDATING        0x00000400
 #define NGX_HTTP_UPSTREAM_FT_BUSY_LOCK       0x00000800
 #define NGX_HTTP_UPSTREAM_FT_MAX_WAITING     0x00001000
+#define NGX_HTTP_UPSTREAM_FT_BEFORE_SEND     0x00002000
 #define NGX_HTTP_UPSTREAM_FT_NOLIVE          0x40000000
 #define NGX_HTTP_UPSTREAM_FT_OFF             0x80000000



More information about the nginx-devel mailing list