191 lines
5.3 KiB
C
191 lines
5.3 KiB
C
--- ngx_http_redis-0.3.7/ngx_http_redis_module.c 2013-11-28 20:41:16.000000000 -0800
|
|
+++ ngx_http_redis-0.3.7-patched2/ngx_http_redis_module.c 2015-01-29 12:35:38.610133438 -0800
|
|
@@ -18,6 +18,8 @@ typedef struct {
|
|
ngx_int_t index;
|
|
ngx_int_t db;
|
|
ngx_uint_t gzip_flag;
|
|
+
|
|
+ ngx_http_complex_value_t *complex_target; /* for redis_pass */
|
|
} ngx_http_redis_loc_conf_t;
|
|
|
|
|
|
@@ -44,6 +46,9 @@ static char *ngx_http_redis_merge_loc_co
|
|
|
|
static char *ngx_http_redis_pass(ngx_conf_t *cf, ngx_command_t *cmd,
|
|
void *conf);
|
|
+static ngx_http_upstream_srv_conf_t *
|
|
+ ngx_http_redis_upstream_add(ngx_http_request_t *r, ngx_url_t *url);
|
|
+
|
|
|
|
static ngx_conf_bitmask_t ngx_http_redis_next_upstream_masks[] = {
|
|
{ ngx_string("error"), NGX_HTTP_UPSTREAM_FT_ERROR },
|
|
@@ -185,11 +190,43 @@ ngx_http_redis_handler(ngx_http_request_
|
|
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
|
}
|
|
|
|
+ rlcf = ngx_http_get_module_loc_conf(r, ngx_http_redis_module);
|
|
+ if (rlcf->complex_target) {
|
|
+ ngx_str_t target;
|
|
+ ngx_url_t url;
|
|
+
|
|
+ /* variables used in the redis_pass directive */
|
|
+
|
|
+ if (ngx_http_complex_value(r, rlcf->complex_target, &target)
|
|
+ != NGX_OK)
|
|
+ {
|
|
+ return NGX_ERROR;
|
|
+ }
|
|
+
|
|
+ if (target.len == 0) {
|
|
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
|
+ "handler: empty \"redis_pass\" target");
|
|
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
|
+ }
|
|
+
|
|
+ url.host = target;
|
|
+ url.port = 0;
|
|
+ url.default_port = 6379;
|
|
+ url.no_resolve = 1;
|
|
+
|
|
+ rlcf->upstream.upstream = ngx_http_redis_upstream_add(r, &url);
|
|
+
|
|
+ if (rlcf->upstream.upstream == NULL) {
|
|
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
|
+ "redis: upstream \"%V\" not found", &target);
|
|
+
|
|
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
|
+ }
|
|
+ }
|
|
+
|
|
#if defined nginx_version && nginx_version >= 8011
|
|
if (ngx_http_upstream_create(r) != NGX_OK) {
|
|
#else
|
|
- rlcf = ngx_http_get_module_loc_conf(r, ngx_http_redis_module);
|
|
-
|
|
u = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_t));
|
|
if (u == NULL) {
|
|
#endif
|
|
@@ -214,9 +251,7 @@ ngx_http_redis_handler(ngx_http_request_
|
|
u->peer.log_error = NGX_ERROR_ERR;
|
|
#endif
|
|
|
|
-#if defined nginx_version && nginx_version >= 8011
|
|
- rlcf = ngx_http_get_module_loc_conf(r, ngx_http_redis_module);
|
|
-#else
|
|
+#if !defined(nginx_version) || nginx_version < 8011
|
|
u->output.tag = (ngx_buf_tag_t) &ngx_http_redis_module;
|
|
#endif
|
|
|
|
@@ -845,24 +880,15 @@ ngx_http_redis_pass(ngx_conf_t *cf, ngx_
|
|
|
|
ngx_str_t *value;
|
|
ngx_url_t u;
|
|
+ ngx_uint_t n;
|
|
ngx_http_core_loc_conf_t *clcf;
|
|
|
|
+ ngx_http_compile_complex_value_t ccv;
|
|
+
|
|
if (rlcf->upstream.upstream) {
|
|
return "is duplicate";
|
|
}
|
|
|
|
- value = cf->args->elts;
|
|
-
|
|
- ngx_memzero(&u, sizeof(ngx_url_t));
|
|
-
|
|
- u.url = value[1];
|
|
- u.no_resolve = 1;
|
|
-
|
|
- rlcf->upstream.upstream = ngx_http_upstream_add(cf, &u, 0);
|
|
- if (rlcf->upstream.upstream == NULL) {
|
|
- return NGX_CONF_ERROR;
|
|
- }
|
|
-
|
|
clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
|
|
|
|
clcf->handler = ngx_http_redis_handler;
|
|
@@ -879,6 +905,41 @@ ngx_http_redis_pass(ngx_conf_t *cf, ngx_
|
|
|
|
rlcf->db = ngx_http_get_variable_index(cf, &ngx_http_redis_db);
|
|
|
|
+ value = cf->args->elts;
|
|
+
|
|
+ n = ngx_http_script_variables_count(&value[1]);
|
|
+ if (n) {
|
|
+ rlcf->complex_target = ngx_palloc(cf->pool,
|
|
+ sizeof(ngx_http_complex_value_t));
|
|
+
|
|
+ if (rlcf->complex_target == NULL) {
|
|
+ return NGX_CONF_ERROR;
|
|
+ }
|
|
+
|
|
+ ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
|
|
+ ccv.cf = cf;
|
|
+ ccv.value = &value[1];
|
|
+ ccv.complex_value = rlcf->complex_target;
|
|
+
|
|
+ if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
|
|
+ return NGX_CONF_ERROR;
|
|
+ }
|
|
+
|
|
+ return NGX_CONF_OK;
|
|
+ }
|
|
+
|
|
+ rlcf->complex_target = NULL;
|
|
+
|
|
+ ngx_memzero(&u, sizeof(ngx_url_t));
|
|
+
|
|
+ u.url = value[1];
|
|
+ u.no_resolve = 1;
|
|
+
|
|
+ rlcf->upstream.upstream = ngx_http_upstream_add(cf, &u, 0);
|
|
+ if (rlcf->upstream.upstream == NULL) {
|
|
+ return NGX_CONF_ERROR;
|
|
+ }
|
|
+
|
|
return NGX_CONF_OK;
|
|
}
|
|
|
|
@@ -916,3 +977,41 @@ ngx_http_redis_add_variables(ngx_conf_t
|
|
|
|
return NGX_OK;
|
|
}
|
|
+
|
|
+
|
|
+static ngx_http_upstream_srv_conf_t *
|
|
+ngx_http_redis_upstream_add(ngx_http_request_t *r, ngx_url_t *url)
|
|
+{
|
|
+ ngx_http_upstream_main_conf_t *umcf;
|
|
+ ngx_http_upstream_srv_conf_t **uscfp;
|
|
+ ngx_uint_t i;
|
|
+
|
|
+ umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module);
|
|
+
|
|
+ uscfp = umcf->upstreams.elts;
|
|
+
|
|
+ for (i = 0; i < umcf->upstreams.nelts; i++) {
|
|
+
|
|
+ if (uscfp[i]->host.len != url->host.len
|
|
+ || ngx_strncasecmp(uscfp[i]->host.data, url->host.data,
|
|
+ url->host.len) != 0)
|
|
+ {
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ if (uscfp[i]->port != url->port) {
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ if (uscfp[i]->default_port
|
|
+ && url->default_port
|
|
+ && uscfp[i]->default_port != url->default_port)
|
|
+ {
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ return uscfp[i];
|
|
+ }
|
|
+
|
|
+ return NULL;
|
|
+}
|