<div style="line-height:1.7;color:#000000;font-size:14px;font-family:arial">Hi, guys<div><br></div><div>In my business, I need dynamicly  to find the backend ip address according to the request. However, I also want to use the upstream to take advantage of load balance. So I add the variable <span style="line-height: 1.7;">support in server directive. For sake of avoiding blocking the whole worker due to resolving domain, at present, only </span>dotted<span style="color: rgb(51, 51, 51); font-family: Arial, SimSun, 'Lucida Sans', 'lucida sans unicode', sans-serif; font-size: 15px; line-height: 18px;"> </span><a href="http://www.nciku.cn/search/en/decimal" style="margin: 0px; padding: 0px; color: rgb(51, 51, 51); text-decoration: none; font-family: Arial, SimSun, 'Lucida Sans', 'lucida sans unicode', sans-serif; font-size: 15px; line-height: 18px;">decimal</a><span style="color: rgb(51, 51, 51); font-family: Arial, SimSun, 'Lucida Sans', 'lucida sans unicode', sans-serif; font-size: 15px; line-height: 18px;"> </span><span style="line-height: 1.7;"> IP address should be parsed in</span></div><div><span style="line-height: 1.7;">the variables. Anyone can help to check or improve it? Thanks. </span></div><div><span style="line-height: 1.7;"><br></span></div><div><span style="line-height: 1.7;">The patch is based on 1.2.7.</span></div><div><span style="line-height: 1.7;"><br></span></div><div><div>diff -ruNp nginx-1.2.7/src/http/ngx_http_upstream.c nginx-1.2.7.m/src/http/ngx_http_upstream.c</div><div>--- nginx-1.2.7/src/http/ngx_http_upstream.c<span class="Apple-tab-span" style="white-space:pre">       </span>2013-02-11 22:39:49.000000000 +0800</div><div>+++ nginx-1.2.7.m/src/http/ngx_http_upstream.c<span class="Apple-tab-span" style="white-space:pre">    </span>2013-05-27 20:33:17.000000000 +0800</div><div>@@ -4220,8 +4220,9 @@ ngx_http_upstream_server(ngx_conf_t *cf,</div><div>     ngx_str_t                   *value, s;</div><div>     ngx_url_t                    u;</div><div>     ngx_int_t                    weight, max_fails;</div><div>-    ngx_uint_t                   i;</div><div>+    ngx_uint_t                   i, n;</div><div>     ngx_http_upstream_server_t  *us;</div><div>+    ngx_http_script_compile_t    sc;</div><div> </div><div>     if (uscf->servers == NULL) {</div><div>         uscf->servers = ngx_array_create(cf->pool, 4,</div><div>@@ -4245,13 +4246,32 @@ ngx_http_upstream_server(ngx_conf_t *cf,</div><div>     u.url = value[1];</div><div>     u.default_port = 80;</div><div> </div><div>-    if (ngx_parse_url(cf->pool, &u) != NGX_OK) {</div><div>-        if (u.err) {</div><div>-            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,</div><div>-                               "%s in upstream \"%V\"", u.err, &u.url);</div><div>+    n = ngx_http_script_variables_count(&value[1]);</div><div>+</div><div>+    if (n) {</div><div>+        ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));</div><div>+</div><div>+        sc.cf = cf;</div><div>+        sc.source = &value[1];</div><div>+        sc.lengths = &us->proxy_lengths;</div><div>+        sc.values = &us->proxy_values;</div><div>+        sc.variables = n;</div><div>+        sc.complete_lengths = 1;</div><div>+        sc.complete_values = 1;</div><div>+</div><div>+        if (ngx_http_script_compile(&sc) != NGX_OK) {</div><div>+            return NGX_CONF_ERROR;</div><div>         }</div><div> </div><div>-        return NGX_CONF_ERROR;</div><div>+    } else {</div><div>+        if (ngx_parse_url(cf->pool, &u) != NGX_OK) {</div><div>+            if (u.err) {</div><div>+                ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,</div><div>+                                   "%s in upstream \"%V\"", u.err, &u.url);</div><div>+            }</div><div>+    </div><div>+            return NGX_CONF_ERROR;</div><div>+        }</div><div>     }</div><div> </div><div>     weight = 1;</div><div>@@ -4333,8 +4353,15 @@ ngx_http_upstream_server(ngx_conf_t *cf,</div><div>         goto invalid;</div><div>     }</div><div> </div><div>-    us->addrs = u.addrs;</div><div>-    us->naddrs = u.naddrs;</div><div>+    if (n) {</div><div>+        us->addrs = NULL;</div><div>+        us->naddrs = 1;</div><div>+</div><div>+    } else {</div><div>+        us->addrs = u.addrs;</div><div>+        us->naddrs = u.naddrs;</div><div>+    }</div><div>+</div><div>     us->weight = weight;</div><div>     us->max_fails = max_fails;</div><div>     us->fail_timeout = fail_timeout;</div><div>diff -ruNp nginx-1.2.7/src/http/ngx_http_upstream.h nginx-1.2.7.m/src/http/ngx_http_upstream.h</div><div>--- nginx-1.2.7/src/http/ngx_http_upstream.h<span class="Apple-tab-span" style="white-space:pre">        </span>2012-02-13 19:01:58.000000000 +0800</div><div>+++ nginx-1.2.7.m/src/http/ngx_http_upstream.h<span class="Apple-tab-span" style="white-space:pre">    </span>2013-05-27 20:38:58.000000000 +0800</div><div>@@ -91,6 +91,9 @@ typedef struct {</div><div>     ngx_uint_t                       max_fails;</div><div>     time_t                           fail_timeout;</div><div> </div><div>+    ngx_array_t                     *proxy_lengths;</div><div>+    ngx_array_t                     *proxy_values;</div><div>+</div><div>     unsigned                         down:1;</div><div>     unsigned                         backup:1;</div><div> } ngx_http_upstream_server_t;</div><div>@@ -116,6 +119,8 @@ struct ngx_http_upstream_srv_conf_s {</div><div>     ngx_uint_t                       line;</div><div>     in_port_t                        port;</div><div>     in_port_t                        default_port;</div><div>+    ngx_uint_t                       variable_peer;</div><div>+    ngx_uint_t                       variable_backup;</div><div> };</div><div> </div><div> </div><div>diff -ruNp nginx-1.2.7/src/http/ngx_http_upstream_round_robin.c nginx-1.2.7.m/src/http/ngx_http_upstream_round_robin.c</div><div>--- nginx-1.2.7/src/http/ngx_http_upstream_round_robin.c<span class="Apple-tab-span" style="white-space:pre">    </span>2013-02-11 22:56:14.000000000 +0800</div><div>+++ nginx-1.2.7.m/src/http/ngx_http_upstream_round_robin.c<span class="Apple-tab-span" style="white-space:pre">        </span>2013-05-27 20:59:49.000000000 +0800</div><div>@@ -78,9 +78,19 @@ ngx_http_upstream_init_round_robin(ngx_c</div><div>                     continue;</div><div>                 }</div><div> </div><div>-                peers->peer[n].sockaddr = server[i].addrs[j].sockaddr;</div><div>-                peers->peer[n].socklen = server[i].addrs[j].socklen;</div><div>-                peers->peer[n].name = server[i].addrs[j].name;</div><div>+                if (server[i].addrs == NULL) {</div><div>+                    us->variable_peer++;</div><div>+                    peers->peer[n].sockaddr = NULL;</div><div>+                    peers->peer[n].socklen = 0;</div><div>+                    ngx_str_null(&peers->peer[n].name);</div><div>+                    peers->peer[n].server = &server[i];</div><div>+</div><div>+                } else {</div><div>+                    peers->peer[n].sockaddr = server[i].addrs[j].sockaddr;</div><div>+                    peers->peer[n].socklen = server[i].addrs[j].socklen;</div><div>+                    peers->peer[n].name = server[i].addrs[j].name;</div><div>+                }</div><div>+</div><div>                 peers->peer[n].max_fails = server[i].max_fails;</div><div>                 peers->peer[n].fail_timeout = server[i].fail_timeout;</div><div>                 peers->peer[n].down = server[i].down;</div><div>@@ -136,9 +146,20 @@ ngx_http_upstream_init_round_robin(ngx_c</div><div>                     continue;</div><div>                 }</div><div> </div><div>-                backup->peer[n].sockaddr = server[i].addrs[j].sockaddr;</div><div>-                backup->peer[n].socklen = server[i].addrs[j].socklen;</div><div>-                backup->peer[n].name = server[i].addrs[j].name;</div><div>+                if (server[i].addrs == NULL) {</div><div>+                    us->variable_backup++;</div><div>+                    backup->peer[n].sockaddr = NULL;</div><div>+                    backup->peer[n].socklen = 0;</div><div>+                    ngx_str_null(&backup->peer[n].name);</div><div>+                    backup->peer[n].server = &server[i];</div><div>+</div><div>+                } else {</div><div>+</div><div>+                    backup->peer[n].sockaddr = server[i].addrs[j].sockaddr;</div><div>+                    backup->peer[n].socklen = server[i].addrs[j].socklen;</div><div>+                    backup->peer[n].name = server[i].addrs[j].name;</div><div>+                }</div><div>+</div><div>                 backup->peer[n].weight = server[i].weight;</div><div>                 backup->peer[n].effective_weight = server[i].weight;</div><div>                 backup->peer[n].current_weight = 0;</div><div>@@ -228,6 +249,73 @@ ngx_http_upstream_cmp_servers(const void</div><div> }</div><div> </div><div> </div><div>+static ngx_int_t</div><div>+ngx_http_upstream_get_round_robin_variable_peer(ngx_http_request_t *r,</div><div>+    ngx_http_upstream_rr_peers_t *peers, ngx_uint_t variable_cnt)</div><div>+{</div><div>+    ngx_uint_t                         i, j, n;</div><div>+    ngx_url_t                          url;</div><div>+    ngx_http_upstream_rr_peer_t       *peer;</div><div>+</div><div>+    n = peers->number;</div><div>+</div><div>+    for (i = 0, j = 0; j < variable_cnt && i < n; i++) {</div><div>+</div><div>+        peer = &peers->peer[i];</div><div>+</div><div>+        if (peer->server) {</div><div>+</div><div>+            peer->sockaddr = NULL;</div><div>+            peer->socklen = 0;</div><div>+            ngx_str_null(&peer->name);</div><div>+</div><div>+            if (ngx_http_script_run(r, &peer->name, </div><div>+                                    peer->server->proxy_lengths->elts, 0,</div><div>+                                    peer->server->proxy_values->elts)</div><div>+                == NULL)</div><div>+            {</div><div>+                return NGX_ERROR;</div><div>+            }</div><div>+</div><div>+            ngx_memzero(&url, sizeof(ngx_url_t));</div><div>+            url.url = peer->name;</div><div>+            url.default_port = 80;</div><div>+            url.no_resolve = 1;</div><div>+</div><div>+            if (ngx_parse_url(r->pool, &url) != NGX_OK) {</div><div>+                if (url.err) {</div><div>+                    ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,</div><div>+                                  "%s in upstream \"%V\"", url.err, &url.url);</div><div>+                }</div><div>+</div><div>+                return NGX_ERROR;</div><div>+            }</div><div>+</div><div>+            url.one_addr = 1;</div><div>+            if (url.no_port) {</div><div>+                url.port = url.default_port;</div><div>+            }</div><div>+</div><div>+            if (ngx_inet_resolve_host(r->pool, &url) != NGX_OK) {</div><div>+                if (url.err) {</div><div>+                    ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,</div><div>+                                  "%s in upstream \"%V\"", url.err, &url.url);</div><div>+                }</div><div>+</div><div>+                return NGX_ERROR;</div><div>+            }</div><div>+</div><div>+            peer->sockaddr = url.addrs[0].sockaddr;</div><div>+            peer->socklen = url.addrs[0].socklen;</div><div>+</div><div>+            j++;</div><div>+        }</div><div>+    }</div><div>+</div><div>+    return NGX_OK;</div><div>+}</div><div>+</div><div>+</div><div> ngx_int_t</div><div> ngx_http_upstream_init_round_robin_peer(ngx_http_request_t *r,</div><div>     ngx_http_upstream_srv_conf_t *us)</div><div>@@ -251,6 +339,25 @@ ngx_http_upstream_init_round_robin_peer(</div><div> </div><div>     n = rrp->peers->number;</div><div> </div><div>+    if (us->variable_peer > 0) {</div><div>+        if (ngx_http_upstream_get_round_robin_variable_peer(r, rrp->peers,</div><div>+                                                            us->variable_peer)</div><div>+            == NGX_ERROR)</div><div>+        {</div><div>+            return NGX_ERROR;</div><div>+        }</div><div>+    }</div><div>+</div><div>+    if (us->variable_backup > 0) {</div><div>+        if (ngx_http_upstream_get_round_robin_variable_peer(r, </div><div>+                                                            rrp->peers->next,</div><div>+                                                            us->variable_backup)</div><div>+            == NGX_ERROR)</div><div>+        {</div><div>+            return NGX_ERROR;</div><div>+        }</div><div>+    }</div><div>+</div><div>     if (rrp->peers->next && rrp->peers->next->number > n) {</div><div>         n = rrp->peers->next->number;</div><div>     }</div><div>diff -ruNp nginx-1.2.7/src/http/ngx_http_upstream_round_robin.h nginx-1.2.7.m/src/http/ngx_http_upstream_round_robin.h</div><div>--- nginx-1.2.7/src/http/ngx_http_upstream_round_robin.h<span class="Apple-tab-span" style="white-space:pre">     </span>2012-07-03 00:41:13.000000000 +0800</div><div>+++ nginx-1.2.7.m/src/http/ngx_http_upstream_round_robin.h<span class="Apple-tab-span" style="white-space:pre">        </span>2013-05-24 13:57:52.000000000 +0800</div><div>@@ -18,6 +18,7 @@ typedef struct {</div><div>     struct sockaddr                *sockaddr;</div><div>     socklen_t                       socklen;</div><div>     ngx_str_t                       name;</div><div>+    ngx_http_upstream_server_t     *server;</div><div> </div><div>     ngx_int_t                       current_weight;</div><div>     ngx_int_t                       effective_weight;</div><div style="line-height: 1.7;"><br></div></div></div><br><br><span title="neteasefooter"><span id="netease_mail_footer"></span></span>