# HG changeset patch # User Ruslan Ermilov # Date 1358329377 0 # Node ID fd84344f1df73709eb5c27c94e0de7188cc38724 # Parent 13c4c155f26f772b0bc1074a05298088d6499218 Fixed and improved the "*_bind" directives of proxying modules. The "proxy_bind", "fastcgi_bind", "uwsgi_bind", "scgi_bind" and "memcached_bind" directives are now inherited; inherited value can be reset by the "off" parameter. Duplicate directives are now detected. Parameter value can now contain variables. diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c --- a/src/http/modules/ngx_http_fastcgi_module.c +++ b/src/http/modules/ngx_http_fastcgi_module.c @@ -2106,6 +2106,8 @@ ngx_http_fastcgi_create_loc_conf(ngx_con conf->upstream.buffering = NGX_CONF_UNSET; conf->upstream.ignore_client_abort = NGX_CONF_UNSET; + conf->upstream.local = NGX_CONF_UNSET_PTR; + conf->upstream.connect_timeout = NGX_CONF_UNSET_MSEC; conf->upstream.send_timeout = NGX_CONF_UNSET_MSEC; conf->upstream.read_timeout = NGX_CONF_UNSET_MSEC; @@ -2177,6 +2179,9 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf ngx_conf_merge_value(conf->upstream.ignore_client_abort, prev->upstream.ignore_client_abort, 0); + ngx_conf_merge_ptr_value(conf->upstream.local, + prev->upstream.local, NULL); + ngx_conf_merge_msec_value(conf->upstream.connect_timeout, prev->upstream.connect_timeout, 60000); diff --git a/src/http/modules/ngx_http_memcached_module.c b/src/http/modules/ngx_http_memcached_module.c --- a/src/http/modules/ngx_http_memcached_module.c +++ b/src/http/modules/ngx_http_memcached_module.c @@ -574,6 +574,7 @@ ngx_http_memcached_create_loc_conf(ngx_c * conf->upstream.location = NULL; */ + conf->upstream.local = NGX_CONF_UNSET_PTR; conf->upstream.connect_timeout = NGX_CONF_UNSET_MSEC; conf->upstream.send_timeout = NGX_CONF_UNSET_MSEC; conf->upstream.read_timeout = NGX_CONF_UNSET_MSEC; @@ -607,6 +608,9 @@ ngx_http_memcached_merge_loc_conf(ngx_co ngx_http_memcached_loc_conf_t *prev = parent; ngx_http_memcached_loc_conf_t *conf = child; + ngx_conf_merge_ptr_value(conf->upstream.local, + prev->upstream.local, NULL); + ngx_conf_merge_msec_value(conf->upstream.connect_timeout, prev->upstream.connect_timeout, 60000); diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c --- a/src/http/modules/ngx_http_proxy_module.c +++ b/src/http/modules/ngx_http_proxy_module.c @@ -2369,6 +2369,8 @@ ngx_http_proxy_create_loc_conf(ngx_conf_ conf->upstream.buffering = NGX_CONF_UNSET; conf->upstream.ignore_client_abort = NGX_CONF_UNSET; + conf->upstream.local = NGX_CONF_UNSET_PTR; + conf->upstream.connect_timeout = NGX_CONF_UNSET_MSEC; conf->upstream.send_timeout = NGX_CONF_UNSET_MSEC; conf->upstream.read_timeout = NGX_CONF_UNSET_MSEC; @@ -2453,6 +2455,9 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t ngx_conf_merge_value(conf->upstream.ignore_client_abort, prev->upstream.ignore_client_abort, 0); + ngx_conf_merge_ptr_value(conf->upstream.local, + prev->upstream.local, NULL); + ngx_conf_merge_msec_value(conf->upstream.connect_timeout, prev->upstream.connect_timeout, 60000); diff --git a/src/http/modules/ngx_http_scgi_module.c b/src/http/modules/ngx_http_scgi_module.c --- a/src/http/modules/ngx_http_scgi_module.c +++ b/src/http/modules/ngx_http_scgi_module.c @@ -1067,6 +1067,8 @@ ngx_http_scgi_create_loc_conf(ngx_conf_t conf->upstream.buffering = NGX_CONF_UNSET; conf->upstream.ignore_client_abort = NGX_CONF_UNSET; + conf->upstream.local = NGX_CONF_UNSET_PTR; + conf->upstream.connect_timeout = NGX_CONF_UNSET_MSEC; conf->upstream.send_timeout = NGX_CONF_UNSET_MSEC; conf->upstream.read_timeout = NGX_CONF_UNSET_MSEC; @@ -1135,6 +1137,9 @@ ngx_http_scgi_merge_loc_conf(ngx_conf_t ngx_conf_merge_value(conf->upstream.ignore_client_abort, prev->upstream.ignore_client_abort, 0); + ngx_conf_merge_ptr_value(conf->upstream.local, + prev->upstream.local, NULL); + ngx_conf_merge_msec_value(conf->upstream.connect_timeout, prev->upstream.connect_timeout, 60000); diff --git a/src/http/modules/ngx_http_uwsgi_module.c b/src/http/modules/ngx_http_uwsgi_module.c --- a/src/http/modules/ngx_http_uwsgi_module.c +++ b/src/http/modules/ngx_http_uwsgi_module.c @@ -1104,6 +1104,8 @@ ngx_http_uwsgi_create_loc_conf(ngx_conf_ conf->upstream.buffering = NGX_CONF_UNSET; conf->upstream.ignore_client_abort = NGX_CONF_UNSET; + conf->upstream.local = NGX_CONF_UNSET_PTR; + conf->upstream.connect_timeout = NGX_CONF_UNSET_MSEC; conf->upstream.send_timeout = NGX_CONF_UNSET_MSEC; conf->upstream.read_timeout = NGX_CONF_UNSET_MSEC; @@ -1172,6 +1174,9 @@ ngx_http_uwsgi_merge_loc_conf(ngx_conf_t ngx_conf_merge_value(conf->upstream.ignore_client_abort, prev->upstream.ignore_client_abort, 0); + ngx_conf_merge_ptr_value(conf->upstream.local, + prev->upstream.local, NULL); + ngx_conf_merge_msec_value(conf->upstream.connect_timeout, prev->upstream.connect_timeout, 60000); diff --git a/src/http/ngx_http.h b/src/http/ngx_http.h --- a/src/http/ngx_http.h +++ b/src/http/ngx_http.h @@ -28,11 +28,11 @@ typedef u_char *(*ngx_http_log_handler_p #include #include +#include #include #include #include #include -#include #include #if (NGX_HTTP_CACHE) diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -134,6 +134,9 @@ static char *ngx_http_upstream(ngx_conf_ static char *ngx_http_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +static ngx_addr_t *ngx_http_upstream_get_local(ngx_http_request_t *r, + ngx_http_upstream_local_t *local); + static void *ngx_http_upstream_create_main_conf(ngx_conf_t *cf); static char *ngx_http_upstream_init_main_conf(ngx_conf_t *cf, void *conf); @@ -507,7 +510,7 @@ ngx_http_upstream_init_request(ngx_http_ return; } - u->peer.local = u->conf->local; + u->peer.local = ngx_http_upstream_get_local(r, u->conf->local); clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); @@ -4474,24 +4477,63 @@ ngx_http_upstream_bind_set_slot(ngx_conf { char *p = conf; - ngx_int_t rc; - ngx_str_t *value; - ngx_addr_t **paddr; - - paddr = (ngx_addr_t **) (p + cmd->offset); - - *paddr = ngx_palloc(cf->pool, sizeof(ngx_addr_t)); - if (*paddr == NULL) { - return NGX_CONF_ERROR; + ngx_int_t rc; + ngx_str_t *value; + ngx_http_complex_value_t cv; + ngx_http_upstream_local_t **plocal, *local; + ngx_http_compile_complex_value_t ccv; + + plocal = (ngx_http_upstream_local_t **) (p + cmd->offset); + + if (*plocal != NGX_CONF_UNSET_PTR) { + return "is duplicate"; } value = cf->args->elts; - rc = ngx_parse_addr(cf->pool, *paddr, value[1].data, value[1].len); + if (ngx_strcmp(value[1].data, "off") == 0) { + *plocal = NULL; + return NGX_CONF_OK; + } + + ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); + + ccv.cf = cf; + ccv.value = &value[1]; + ccv.complex_value = &cv; + + if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { + return NGX_CONF_ERROR; + } + + local = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_local_t)); + if (local == NULL) { + return NGX_CONF_ERROR; + } + + *plocal = local; + + if (cv.lengths) { + local->value = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t)); + if (local->value == NULL) { + return NGX_CONF_ERROR; + } + + *local->value = cv; + + return NGX_CONF_OK; + } + + local->addr = ngx_palloc(cf->pool, sizeof(ngx_addr_t)); + if (local->addr == NULL) { + return NGX_CONF_ERROR; + } + + rc = ngx_parse_addr(cf->pool, local->addr, value[1].data, value[1].len); switch (rc) { case NGX_OK: - (*paddr)->name = value[1]; + local->addr->name = value[1]; return NGX_CONF_OK; case NGX_DECLINED: @@ -4505,6 +4547,53 @@ ngx_http_upstream_bind_set_slot(ngx_conf } +static ngx_addr_t * +ngx_http_upstream_get_local(ngx_http_request_t *r, + ngx_http_upstream_local_t *local) +{ + ngx_int_t rc; + ngx_str_t val; + ngx_addr_t *addr; + + if (local == NULL) { + return NULL; + } + + if (local->value == NULL) { + return local->addr; + } + + if (ngx_http_complex_value(r, local->value, &val) != NGX_OK) { + return NULL; + } + + if (val.len == 0) { + return NULL; + } + + addr = ngx_palloc(r->pool, sizeof(ngx_addr_t)); + if (addr == NULL) { + return NULL; + } + + rc = ngx_parse_addr(r->pool, addr, val.data, val.len); + + switch (rc) { + case NGX_OK: + addr->name = val; + return addr; + + case NGX_DECLINED: + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "invalid local address \"%V\"", &val); + /* fall through */ + + default: + return NULL; + } +} + + char * ngx_http_upstream_param_set_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) diff --git a/src/http/ngx_http_upstream.h b/src/http/ngx_http_upstream.h --- a/src/http/ngx_http_upstream.h +++ b/src/http/ngx_http_upstream.h @@ -121,6 +121,12 @@ struct ngx_http_upstream_srv_conf_s { typedef struct { + ngx_addr_t *addr; + ngx_http_complex_value_t *value; +} ngx_http_upstream_local_t; + + +typedef struct { ngx_http_upstream_srv_conf_t *upstream; ngx_msec_t connect_timeout; @@ -158,7 +164,7 @@ typedef struct { ngx_array_t *hide_headers; ngx_array_t *pass_headers; - ngx_addr_t *local; + ngx_http_upstream_local_t *local; #if (NGX_HTTP_CACHE) ngx_shm_zone_t *cache;