[PATCH] Upstream: proxy_bind/fastcgi_bind/memcached_bind variables support
Maxim Dounin
mdounin at mdounin.ru
Tue Apr 6 23:12:58 MSD 2010
# HG changeset patch
# User Maxim Dounin <mdounin at mdounin.ru>
# Date 1270581171 -14400
# Node ID c82ced18c40e3574b865428b5b48f39f2f2d388f
# Parent 0d9b939b555e0adfcfc2e4ab4fc40fd7e9d56700
Upstream: proxy_bind/fastcgi_bind/memcached_bind variables support.
While here also fixed missing inheritance for "proxy_bind", "fastcgi_bind"
and "memcached_bind" directives, and added protection against duplicate
directives.
Changes since last submit: fixed segmentation fault on bind() error.
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
@@ -245,7 +245,7 @@ static ngx_command_t ngx_http_fastcgi_c
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_http_upstream_bind_set_slot,
NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_fastcgi_loc_conf_t, upstream.local),
+ offsetof(ngx_http_fastcgi_loc_conf_t, upstream),
NULL },
{ ngx_string("fastcgi_connect_timeout"),
@@ -1921,6 +1921,8 @@ ngx_http_fastcgi_create_loc_conf(ngx_con
* conf->upstream.location = NULL;
* conf->upstream.store_lengths = NULL;
* conf->upstream.store_values = NULL;
+ * conf->upstream.local = NULL;
+ * conf->upstream.local_value = NULL;
*
* conf->index.len = 0;
* conf->index.data = NULL;
@@ -2216,6 +2218,14 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf
conf->upstream.upstream = prev->upstream.upstream;
}
+ if (conf->upstream.local == NULL) {
+ conf->upstream.local = prev->upstream.local;
+
+ if (conf->upstream.local_value == NULL) {
+ conf->upstream.local_value = prev->upstream.local_value;
+ }
+ }
+
if (conf->fastcgi_lengths == NULL) {
conf->fastcgi_lengths = prev->fastcgi_lengths;
conf->fastcgi_values = prev->fastcgi_values;
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
@@ -67,7 +67,7 @@ static ngx_command_t ngx_http_memcached
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_http_upstream_bind_set_slot,
NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_memcached_loc_conf_t, upstream.local),
+ offsetof(ngx_http_memcached_loc_conf_t, upstream),
NULL },
{ ngx_string("memcached_connect_timeout"),
@@ -531,6 +531,8 @@ ngx_http_memcached_create_loc_conf(ngx_c
* conf->upstream.temp_path = NULL;
* conf->upstream.uri = { 0, NULL };
* conf->upstream.location = NULL;
+ * conf->upstream.local = NULL;
+ * conf->upstream.local_value = NULL;
*/
conf->upstream.connect_timeout = NGX_CONF_UNSET_MSEC;
@@ -593,6 +595,14 @@ ngx_http_memcached_merge_loc_conf(ngx_co
conf->upstream.upstream = prev->upstream.upstream;
}
+ if (conf->upstream.local == NULL) {
+ conf->upstream.local = prev->upstream.local;
+
+ if (conf->upstream.local_value == NULL) {
+ conf->upstream.local_value = prev->upstream.local_value;
+ }
+ }
+
if (conf->index == NGX_CONF_UNSET) {
conf->index = prev->index;
}
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
@@ -233,7 +233,7 @@ static ngx_command_t ngx_http_proxy_com
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_http_upstream_bind_set_slot,
NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_proxy_loc_conf_t, upstream.local),
+ offsetof(ngx_http_proxy_loc_conf_t, upstream),
NULL },
{ ngx_string("proxy_connect_timeout"),
@@ -1906,6 +1906,8 @@ ngx_http_proxy_create_loc_conf(ngx_conf_
* conf->upstream.location = NULL;
* conf->upstream.store_lengths = NULL;
* conf->upstream.store_values = NULL;
+ * conf->upstream.local = NULL;
+ * conf->upstream.local_value = NULL;
*
* conf->method = NULL;
* conf->headers_source = NULL;
@@ -2275,6 +2277,14 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t
conf->vars = prev->vars;
}
+ if (conf->upstream.local == NULL) {
+ conf->upstream.local = prev->upstream.local;
+
+ if (conf->upstream.local_value == NULL) {
+ conf->upstream.local_value = prev->upstream.local_value;
+ }
+ }
+
if (conf->body_source.data == NULL) {
conf->body_source = prev->body_source;
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
@@ -26,11 +26,11 @@ typedef u_char *(*ngx_http_log_handler_p
#include <ngx_http_variables.h>
#include <ngx_http_request.h>
+#include <ngx_http_script.h>
#include <ngx_http_upstream.h>
#include <ngx_http_upstream_round_robin.h>
#include <ngx_http_config.h>
#include <ngx_http_busy_lock.h>
-#include <ngx_http_script.h>
#include <ngx_http_core_module.h>
#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
@@ -124,6 +124,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_complex_value_t *cv, ngx_addr_t *addr);
+
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);
@@ -480,7 +483,8 @@ 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_value,
+ u->conf->local);
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
@@ -4209,26 +4213,51 @@ char *
ngx_http_upstream_bind_set_slot(ngx_conf_t *cf, ngx_command_t *cmd,
void *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_http_upstream_conf_t *upstream = conf;
+
+ ngx_int_t rc;
+ ngx_str_t *value;
+ ngx_http_complex_value_t cv;
+ ngx_http_compile_complex_value_t ccv;
+
+ if (upstream->local != NULL || upstream->local_value != NULL) {
+ return "is duplicate";
}
value = cf->args->elts;
- rc = ngx_parse_addr(cf->pool, *paddr, value[1].data, value[1].len);
+ 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;
+ }
+
+ if (cv.lengths != NULL) {
+ upstream->local_value = ngx_palloc(cf->pool,
+ sizeof(ngx_http_complex_value_t));
+ if (upstream->local_value == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ *upstream->local_value = cv;
+
+ return NGX_CONF_OK;
+ }
+
+ upstream->local = ngx_palloc(cf->pool, sizeof(ngx_addr_t));
+ if (upstream->local == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ rc = ngx_parse_addr(cf->pool, upstream->local, value[1].data, value[1].len);
switch (rc) {
case NGX_OK:
- (*paddr)->name = value[1];
+ upstream->local->name = value[1];
return NGX_CONF_OK;
case NGX_DECLINED:
@@ -4240,6 +4269,49 @@ ngx_http_upstream_bind_set_slot(ngx_conf
}
+static ngx_addr_t *
+ngx_http_upstream_get_local(ngx_http_request_t *r,
+ ngx_http_complex_value_t *cv, ngx_addr_t *addr)
+{
+ ngx_int_t rc;
+ ngx_str_t val;
+ ngx_addr_t *local;
+
+ if (cv == NULL) {
+ return addr;
+ }
+
+ if (ngx_http_complex_value(r, cv, &val) != NGX_OK) {
+ return NULL;
+ }
+
+ if (val.len == 0) {
+ return NULL;
+ }
+
+ local = ngx_palloc(r->pool, sizeof(ngx_addr_t));
+ if (local == NULL) {
+ return NULL;
+ }
+
+ rc = ngx_parse_addr(r->pool, local, val.data, val.len);
+
+ switch (rc) {
+ case NGX_OK:
+ local->name = val;
+ return local;
+
+ case NGX_DECLINED:
+ ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
+ "invalid local address \"%V\"", &val);
+ return NULL;
+
+ default:
+ return NULL;
+ }
+}
+
+
ngx_int_t
ngx_http_upstream_hide_headers_hash(ngx_conf_t *cf,
ngx_http_upstream_conf_t *conf, ngx_http_upstream_conf_t *prev,
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
@@ -153,6 +153,7 @@ typedef struct {
ngx_array_t *pass_headers;
ngx_addr_t *local;
+ ngx_http_complex_value_t *local_value;
#if (NGX_HTTP_CACHE)
ngx_shm_zone_t *cache;
More information about the nginx-devel
mailing list