summaryrefslogtreecommitdiff
path: root/src/http
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2007-07-30 09:15:47 +0000
committerJonathan Kolb <jon@b0g.us>2007-07-30 09:15:47 +0000
commitad5526a0773dea7fca82cca22433e2cb0b327837 (patch)
tree83f8ffae019ea0d39633c2c5520b3dfa6cfd47d2 /src/http
parentb9b71bc11c42dce8b014ee3cf3a1f5dc7b9ecc2f (diff)
downloadnginx-ad5526a0773dea7fca82cca22433e2cb0b327837.tar.gz
Changes with nginx 0.6.6 30 Jul 2007v0.6.6
*) Feature: the --sysconfdir=PATH option in configure. *) Feature: named locations. *) Feature: the $args variable can be set with the "set" directive. *) Feature: the $is_args variable. *) Bugfix: fair big weight upstream balancer. *) Bugfix: if a client has closed connection to mail proxy then nginx might not close connection to backend. *) Bugfix: if the same host without specified port was used as backend for HTTP and HTTPS, then nginx used only one port - 80 or 443. *) Bugfix: fix building on Solaris/amd64 by Sun Studio 11 and early versions; bug appeared in 0.6.4.
Diffstat (limited to 'src/http')
-rw-r--r--src/http/modules/ngx_http_auth_basic_module.c2
-rw-r--r--src/http/modules/ngx_http_geo_module.c2
-rw-r--r--src/http/modules/ngx_http_map_module.c2
-rw-r--r--src/http/modules/ngx_http_proxy_module.c11
-rw-r--r--src/http/modules/perl/nginx.pm2
-rw-r--r--src/http/modules/perl/ngx_http_perl_module.c2
-rw-r--r--src/http/ngx_http.c9
-rw-r--r--src/http/ngx_http_core_module.c116
-rw-r--r--src/http/ngx_http_core_module.h11
-rw-r--r--src/http/ngx_http_special_response.c4
-rw-r--r--src/http/ngx_http_upstream.c6
-rw-r--r--src/http/ngx_http_upstream_round_robin.c108
-rw-r--r--src/http/ngx_http_upstream_round_robin.h8
-rw-r--r--src/http/ngx_http_variables.c51
14 files changed, 269 insertions, 65 deletions
diff --git a/src/http/modules/ngx_http_auth_basic_module.c b/src/http/modules/ngx_http_auth_basic_module.c
index 19bfe996e..72b4bbdcb 100644
--- a/src/http/modules/ngx_http_auth_basic_module.c
+++ b/src/http/modules/ngx_http_auth_basic_module.c
@@ -352,7 +352,7 @@ ngx_http_auth_basic_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
}
if (conf->user_file.data) {
- if (ngx_conf_full_name(cf->cycle, &conf->user_file) != NGX_OK) {
+ if (ngx_conf_full_name(cf->cycle, &conf->user_file, 1) != NGX_OK) {
return NGX_CONF_ERROR;
}
diff --git a/src/http/modules/ngx_http_geo_module.c b/src/http/modules/ngx_http_geo_module.c
index 62ef72cf9..9c43bd716 100644
--- a/src/http/modules/ngx_http_geo_module.c
+++ b/src/http/modules/ngx_http_geo_module.c
@@ -198,7 +198,7 @@ ngx_http_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
if (ngx_strcmp(value[0].data, "include") == 0) {
file = value[1];
- if (ngx_conf_full_name(cf->cycle, &file) == NGX_ERROR){
+ if (ngx_conf_full_name(cf->cycle, &file, 1) == NGX_ERROR){
return NGX_CONF_ERROR;
}
diff --git a/src/http/modules/ngx_http_map_module.c b/src/http/modules/ngx_http_map_module.c
index 4a8acd00d..7b3a363fc 100644
--- a/src/http/modules/ngx_http_map_module.c
+++ b/src/http/modules/ngx_http_map_module.c
@@ -378,7 +378,7 @@ ngx_http_map(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
if (ngx_strcmp(value[0].data, "include") == 0) {
file = value[1];
- if (ngx_conf_full_name(cf->cycle, &file) == NGX_ERROR){
+ if (ngx_conf_full_name(cf->cycle, &file, 1) == NGX_ERROR){
return NGX_CONF_ERROR;
}
diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c
index c999adea2..52f67b305 100644
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -2237,6 +2237,7 @@ ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
if (port == 80) {
plcf->port.len = sizeof("80") - 1;
plcf->port.data = (u_char *) "80";
+
} else {
plcf->port.len = sizeof("443") - 1;
plcf->port.data = (u_char *) "443";
@@ -2275,13 +2276,17 @@ ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
plcf->upstream.location = clcf->name;
+ if (clcf->named
#if (NGX_PCRE)
-
- if (clcf->regex || clcf->noname) {
+ || clcf->regex
+#endif
+ || clcf->noname)
+ {
if (plcf->upstream.uri.len) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"\"proxy_pass\" may not have URI part in "
"location given by regular expression, "
+ "or inside named location, "
"or inside the \"if\" statement, "
"or inside the \"limit_except\" block");
return NGX_CONF_ERROR;
@@ -2290,8 +2295,6 @@ ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
plcf->upstream.location.len = 0;
}
-#endif
-
plcf->upstream.url = *url;
if (clcf->name.data[clcf->name.len - 1] == '/') {
diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm
index f510f2df0..ca86b7840 100644
--- a/src/http/modules/perl/nginx.pm
+++ b/src/http/modules/perl/nginx.pm
@@ -47,7 +47,7 @@ our @EXPORT = qw(
HTTP_INSUFFICIENT_STORAGE
);
-our $VERSION = '0.6.5';
+our $VERSION = '0.6.6';
require XSLoader;
XSLoader::load('nginx', $VERSION);
diff --git a/src/http/modules/perl/ngx_http_perl_module.c b/src/http/modules/perl/ngx_http_perl_module.c
index 248f57823..836a415c9 100644
--- a/src/http/modules/perl/ngx_http_perl_module.c
+++ b/src/http/modules/perl/ngx_http_perl_module.c
@@ -454,7 +454,7 @@ ngx_http_perl_init_interpreter(ngx_conf_t *cf, ngx_http_perl_main_conf_t *pmcf)
#endif
if (pmcf->modules.data) {
- if (ngx_conf_full_name(cf->cycle, &pmcf->modules) != NGX_OK) {
+ if (ngx_conf_full_name(cf->cycle, &pmcf->modules, 0) != NGX_OK) {
return NGX_CONF_ERROR;
}
}
diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c
index 5823a2b91..dfe6eff70 100644
--- a/src/http/ngx_http.c
+++ b/src/http/ngx_http.c
@@ -401,6 +401,7 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
cmcf->phase_engine.server_rewrite_index = (ngx_uint_t) -1;
+ cmcf->phase_engine.location_rewrite_index = (ngx_uint_t) -1;
find_config_index = 0;
use_rewrite = cmcf->phases[NGX_HTTP_REWRITE_PHASE].handlers.nelts ? 1 : 0;
use_access = cmcf->phases[NGX_HTTP_ACCESS_PHASE].handlers.nelts ? 1 : 0;
@@ -442,6 +443,14 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
continue;
+ case NGX_HTTP_REWRITE_PHASE:
+ if (cmcf->phase_engine.location_rewrite_index == (ngx_uint_t) -1) {
+ cmcf->phase_engine.location_rewrite_index = n;
+ }
+ checker = ngx_http_core_generic_phase;
+
+ break;
+
case NGX_HTTP_POST_REWRITE_PHASE:
if (use_rewrite) {
ph->checker = ngx_http_core_post_rewrite_phase;
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index a903c9a24..0e732cfe2 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -945,13 +945,12 @@ ngx_http_core_find_location(ngx_http_request_t *r,
clcfp = locations->elts;
for (i = 0; i < locations->nelts; i++) {
+ if (clcfp[i]->noname
#if (NGX_PCRE)
- if (clcfp[i]->regex) {
- break;
- }
+ || clcfp[i]->regex
#endif
-
- if (clcfp[i]->noname) {
+ || clcfp[i]->named)
+ {
break;
}
@@ -1028,7 +1027,7 @@ ngx_http_core_find_location(ngx_http_request_t *r,
for (i = regex_start; i < locations->nelts; i++) {
- if (clcfp[i]->noname) {
+ if (!clcfp[i]->regex) {
break;
}
@@ -1223,7 +1222,8 @@ ngx_http_map_uri_to_path(ngx_http_request_t *r, ngx_str_t *path,
return NULL;
}
- if (ngx_conf_full_name((ngx_cycle_t *) ngx_cycle, path) == NGX_ERROR) {
+ if (ngx_conf_full_name((ngx_cycle_t *) ngx_cycle, path, 0)== NGX_ERROR)
+ {
return NULL;
}
@@ -1513,6 +1513,51 @@ ngx_http_internal_redirect(ngx_http_request_t *r,
}
+ngx_int_t
+ngx_http_named_location(ngx_http_request_t *r, ngx_str_t *name)
+{
+ ngx_uint_t i;
+ ngx_http_core_srv_conf_t *cscf;
+ ngx_http_core_loc_conf_t **clcfp;
+ ngx_http_core_main_conf_t *cmcf;
+
+ cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
+
+ clcfp = cscf->locations.elts;
+
+ for (i = cscf->named_start; i < cscf->locations.nelts; i++) {
+
+ if (name->len != clcfp[i]->name.len
+ || ngx_strncmp(name->data, clcfp[i]->name.data, name->len) != 0)
+ {
+ continue;
+ }
+
+ ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "named location: %V \"%V?%V\"", name, &r->uri, &r->args);
+
+ r->internal = 1;
+
+ r->loc_conf = clcfp[i]->loc_conf;
+
+ ngx_http_update_location_config(r);
+
+ cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
+
+ r->phase_handler = cmcf->phase_engine.location_rewrite_index;
+ ngx_http_core_run_phases(r);
+
+ return NGX_DONE;
+ }
+
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "could not find name location \"%V\"", name);
+
+ ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+ return NGX_DONE;
+}
+
+
ngx_http_cleanup_t *
ngx_http_cleanup_add(ngx_http_request_t *r, size_t size)
{
@@ -1557,10 +1602,8 @@ ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
ngx_http_module_t *module;
ngx_http_conf_ctx_t *ctx, *http_ctx;
ngx_http_core_srv_conf_t *cscf, **cscfp;
- ngx_http_core_main_conf_t *cmcf;
-#if (NGX_PCRE)
ngx_http_core_loc_conf_t **clcfp;
-#endif
+ ngx_http_core_main_conf_t *cmcf;
ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
if (ctx == NULL) {
@@ -1644,10 +1687,11 @@ ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
ngx_sort(cscf->locations.elts, (size_t) cscf->locations.nelts,
sizeof(ngx_http_core_loc_conf_t *), ngx_http_core_cmp_locations);
+ clcfp = cscf->locations.elts;
+
#if (NGX_PCRE)
cscf->regex_start = cscf->locations.nelts;
- clcfp = cscf->locations.elts;
for (i = 0; i < cscf->locations.nelts; i++) {
if (clcfp[i]->regex) {
@@ -1658,6 +1702,15 @@ ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
#endif
+ cscf->named_start = cscf->locations.nelts;
+
+ for (i = 0; i < cscf->locations.nelts; i++) {
+ if (clcfp[i]->named) {
+ cscf->named_start = i;
+ break;
+ }
+ }
+
return rv;
}
@@ -1758,7 +1811,12 @@ ngx_http_core_location(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
}
} else {
+
clcf->name = value[1];
+
+ if (value[1].data[0] == '@') {
+ clcf->named = 1;
+ }
}
pclcf = pctx->loc_conf[ngx_http_core_module.ctx_index];
@@ -1784,6 +1842,14 @@ ngx_http_core_location(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
return NGX_CONF_ERROR;
}
+ if (pclcf->named) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "location \"%V\" could not be inside "
+ "the named location \"%V\"",
+ &clcf->name, &pclcf->name);
+ return NGX_CONF_ERROR;
+ }
+
#if (NGX_PCRE)
if (clcf->regex == NULL
&& ngx_strncmp(clcf->name.data, pclcf->name.data, pclcf->name.len)
@@ -1861,6 +1927,20 @@ ngx_http_core_cmp_locations(const void *one, const void *two)
first = *(ngx_http_core_loc_conf_t **) one;
second = *(ngx_http_core_loc_conf_t **) two;
+ if (first->named && !second->named) {
+ /* shift named locations to the end */
+ return 1;
+ }
+
+ if (!first->named && second->named) {
+ /* shift named locations to the end */
+ return -1;
+ }
+
+ if (first->named && second->named) {
+ return ngx_strcmp(first->name.data, second->name.data);
+ }
+
if (first->noname && !second->noname) {
/* shift no named locations to the end */
return 1;
@@ -1947,7 +2027,7 @@ ngx_http_core_type(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
if (ngx_strcmp(value[0].data, "include") == 0) {
file = value[1];
- if (ngx_conf_full_name(cf->cycle, &file) == NGX_ERROR){
+ if (ngx_conf_full_name(cf->cycle, &file, 1) == NGX_ERROR){
return NGX_CONF_ERROR;
}
@@ -2290,7 +2370,7 @@ ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
conf->root.len = sizeof("html") - 1;
conf->root.data = (u_char *) "html";
- if (ngx_conf_full_name(cf->cycle, &conf->root) == NGX_ERROR) {
+ if (ngx_conf_full_name(cf->cycle, &conf->root, 0) == NGX_ERROR) {
return NGX_CONF_ERROR;
}
}
@@ -2706,6 +2786,14 @@ ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_ERROR;
}
+ if (lcf->named && alias) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "the \"alias\" directive may not be used "
+ "inside named location");
+
+ return NGX_CONF_ERROR;
+ }
+
#if (NGX_PCRE)
if (lcf->regex && alias) {
@@ -2739,7 +2827,7 @@ ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
if (lcf->root.data[0] != '$') {
- if (ngx_conf_full_name(cf->cycle, &lcf->root) == NGX_ERROR) {
+ if (ngx_conf_full_name(cf->cycle, &lcf->root, 0) == NGX_ERROR) {
return NGX_CONF_ERROR;
}
}
diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h
index 59e4624a9..dc443f64a 100644
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -79,6 +79,7 @@ struct ngx_http_phase_handler_s {
typedef struct {
ngx_http_phase_handler_t *handlers;
ngx_uint_t server_rewrite_index;
+ ngx_uint_t location_rewrite_index;
} ngx_http_phase_engine_t;
@@ -117,7 +118,8 @@ typedef struct {
*/
ngx_array_t locations;
- unsigned regex_start:16;
+ unsigned regex_start:15;
+ unsigned named_start:15;
unsigned wildcard:1;
/* array of the ngx_http_listen_t, "listen" directive */
@@ -212,9 +214,10 @@ struct ngx_http_core_loc_conf_s {
ngx_regex_t *regex;
#endif
- unsigned regex_start:16;
+ unsigned regex_start:15;
- unsigned noname:1; /* "if () {}" block */
+ unsigned noname:1; /* "if () {}" block or limit_except */
+ unsigned named:1;
unsigned exact_match:1;
unsigned noregex:1;
@@ -314,6 +317,8 @@ ngx_int_t ngx_http_subrequest(ngx_http_request_t *r,
ngx_http_post_subrequest_t *psr, ngx_uint_t flags);
ngx_int_t ngx_http_internal_redirect(ngx_http_request_t *r,
ngx_str_t *uri, ngx_str_t *args);
+ngx_int_t ngx_http_named_location(ngx_http_request_t *r, ngx_str_t *name);
+
ngx_http_cleanup_t *ngx_http_cleanup_add(ngx_http_request_t *r, size_t size);
diff --git a/src/http/ngx_http_special_response.c b/src/http/ngx_http_special_response.c
index 2598116f7..1797603a0 100644
--- a/src/http/ngx_http_special_response.c
+++ b/src/http/ngx_http_special_response.c
@@ -409,6 +409,10 @@ ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error)
return ngx_http_internal_redirect(r, uri, NULL);
}
+ if (uri->data[0] == '@') {
+ return ngx_http_named_location(r, uri);
+ }
+
r->headers_out.location =
ngx_list_push(&r->headers_out.headers);
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
index 376b85fcd..bc4567458 100644
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -3209,6 +3209,12 @@ ngx_http_upstream_add(ngx_conf_t *cf, ngx_url_t *u, ngx_uint_t flags)
continue;
}
+ if (uscfp[i]->default_port && u->default_port
+ && uscfp[i]->default_port != u->default_port)
+ {
+ continue;
+ }
+
return uscfp[i];
}
diff --git a/src/http/ngx_http_upstream_round_robin.c b/src/http/ngx_http_upstream_round_robin.c
index af90d1d59..6756d2bc2 100644
--- a/src/http/ngx_http_upstream_round_robin.c
+++ b/src/http/ngx_http_upstream_round_robin.c
@@ -9,6 +9,10 @@
#include <ngx_http.h>
+static ngx_uint_t
+ngx_http_upstream_get_peer(ngx_http_upstream_rr_peers_t *peers);
+
+
ngx_int_t
ngx_http_upstream_init_round_robin(ngx_conf_t *cf,
ngx_http_upstream_srv_conf_t *us)
@@ -215,7 +219,12 @@ ngx_http_upstream_get_round_robin_peer(ngx_peer_connection_t *pc, void *data)
/* it's a first try - get a current peer */
for ( ;; ) {
- rrp->current = rrp->peers->current;
+ rrp->current = ngx_http_upstream_get_peer(rrp->peers);
+
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0,
+ "get rr peer, current: %ui %i",
+ rrp->current,
+ rrp->peers->peer[rrp->current].current_weight);
n = rrp->current / (8 * sizeof(uintptr_t));
m = (uintptr_t) 1 << rrp->current % (8 * sizeof(uintptr_t));
@@ -236,6 +245,8 @@ ngx_http_upstream_get_round_robin_peer(ngx_peer_connection_t *pc, void *data)
break;
}
+ peer->current_weight = 0;
+
} else {
rrp->tried[n] |= m;
}
@@ -243,12 +254,6 @@ ngx_http_upstream_get_round_robin_peer(ngx_peer_connection_t *pc, void *data)
pc->tries--;
}
- rrp->peers->current++;
-
- if (rrp->peers->current >= rrp->peers->number) {
- rrp->peers->current = 0;
- }
-
if (pc->tries) {
continue;
}
@@ -258,16 +263,6 @@ ngx_http_upstream_get_round_robin_peer(ngx_peer_connection_t *pc, void *data)
peer->current_weight--;
- if (peer->current_weight == 0) {
- peer->current_weight = peer->weight;
-
- rrp->peers->current++;
-
- if (rrp->peers->current >= rrp->peers->number) {
- rrp->peers->current = 0;
- }
- }
-
} else {
for ( ;; ) {
n = rrp->current / (8 * sizeof(uintptr_t));
@@ -290,6 +285,8 @@ ngx_http_upstream_get_round_robin_peer(ngx_peer_connection_t *pc, void *data)
break;
}
+ peer->current_weight = 0;
+
} else {
rrp->tried[n] |= m;
}
@@ -311,18 +308,6 @@ ngx_http_upstream_get_round_robin_peer(ngx_peer_connection_t *pc, void *data)
}
peer->current_weight--;
-
- if (peer->current_weight == 0) {
- peer->current_weight = peer->weight;
-
- if (rrp->current == rrp->peers->current) {
- rrp->peers->current++;
-
- if (rrp->peers->current >= rrp->peers->number) {
- rrp->peers->current = 0;
- }
- }
- }
}
rrp->tried[n] |= m;
@@ -352,6 +337,61 @@ failed:
}
+static ngx_uint_t
+ngx_http_upstream_get_peer(ngx_http_upstream_rr_peers_t *peers)
+{
+ ngx_uint_t i, n;
+ ngx_http_upstream_rr_peer_t *peer;
+
+ peer = &peers->peer[0];
+
+ for ( ;; ) {
+
+ for (i = 0; i < peers->number; i++) {
+
+ if (peer[i].current_weight <= 0) {
+ continue;
+ }
+
+ n = i;
+
+ while (i < peers->number - 1) {
+
+ i++;
+
+ if (peer[i].current_weight <= 0) {
+ continue;
+ }
+
+ if (peer[n].current_weight * 1000 / peer[i].current_weight
+ >= peer[n].weight * 1000 / peer[i].weight)
+ {
+ return n;
+ }
+
+ n = i;
+ }
+
+ if (peer[i].current_weight > 0) {
+ n = i;
+ }
+
+ return n;
+ }
+
+ for (i = 0; i < peers->number; i++) {
+ if (peer[i].fails == 0) {
+ peer[i].current_weight += peer[i].weight;
+
+ } else {
+ /* 1 allows to go to quick recovery when all peers failed */
+ peer[i].current_weight = 1;
+ }
+ }
+ }
+}
+
+
void
ngx_http_upstream_free_round_robin_peer(ngx_peer_connection_t *pc, void *data,
ngx_uint_t state)
@@ -385,8 +425,14 @@ ngx_http_upstream_free_round_robin_peer(ngx_peer_connection_t *pc, void *data,
peer->fails++;
peer->accessed = now;
- if (peer->current_weight > 1) {
- peer->current_weight /= 2;
+ peer->current_weight -= peer->weight / peer->max_fails;
+
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0,
+ "free rr peer failed: %ui %i",
+ rrp->current, peer->current_weight);
+
+ if (peer->current_weight < 0) {
+ peer->current_weight = 0;
}
/* ngx_unlock_mutex(rrp->peers->mutex); */
diff --git a/src/http/ngx_http_upstream_round_robin.h b/src/http/ngx_http_upstream_round_robin.h
index 2e2bf132f..15e69153a 100644
--- a/src/http/ngx_http_upstream_round_robin.h
+++ b/src/http/ngx_http_upstream_round_robin.h
@@ -18,8 +18,8 @@ typedef struct {
socklen_t socklen;
ngx_str_t name;
- ngx_uint_t current_weight;
- ngx_uint_t weight;
+ ngx_int_t current_weight;
+ ngx_int_t weight;
ngx_uint_t fails;
time_t accessed;
@@ -29,15 +29,13 @@ typedef struct {
ngx_uint_t down; /* unsigned down:1; */
-#if (NGX_SSL)
+#if (NGX_HTTP_SSL)
ngx_ssl_session_t *ssl_session; /* local to a process */
#endif
} ngx_http_upstream_rr_peer_t;
typedef struct {
- ngx_uint_t current;
-
ngx_uint_t number;
ngx_uint_t last_cached;
diff --git a/src/http/ngx_http_variables.c b/src/http/ngx_http_variables.c
index af54d29b0..123017d80 100644
--- a/src/http/ngx_http_variables.c
+++ b/src/http/ngx_http_variables.c
@@ -13,6 +13,8 @@
static ngx_int_t ngx_http_variable_request(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
+static void ngx_http_variable_request_set(ngx_http_request_t *r,
+ ngx_http_variable_value_t *v, uintptr_t data);
static void ngx_http_variable_request_set_size(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_variable_header(ngx_http_request_t *r,
@@ -39,6 +41,8 @@ static ngx_int_t ngx_http_variable_server_port(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_variable_scheme(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_http_variable_is_args(ngx_http_request_t *r,
+ ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_variable_document_root(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_variable_request_filename(ngx_http_request_t *r,
@@ -155,9 +159,14 @@ static ngx_http_variable_t ngx_http_core_variables[] = {
offsetof(ngx_http_request_t, args),
NGX_HTTP_VAR_NOCACHABLE, 0 },
- { ngx_string("args"), NULL, ngx_http_variable_request,
+ { ngx_string("args"),
+ ngx_http_variable_request_set,
+ ngx_http_variable_request,
offsetof(ngx_http_request_t, args),
- NGX_HTTP_VAR_NOCACHABLE, 0 },
+ NGX_HTTP_VAR_CHANGABLE|NGX_HTTP_VAR_NOCACHABLE, 0 },
+
+ { ngx_string("is_args"), NULL, ngx_http_variable_is_args,
+ 0, NGX_HTTP_VAR_NOCACHABLE, 0 },
{ ngx_string("request_filename"), NULL,
ngx_http_variable_request_filename, 0,
@@ -501,6 +510,19 @@ ngx_http_variable_request(ngx_http_request_t *r, ngx_http_variable_value_t *v,
static void
+ngx_http_variable_request_set(ngx_http_request_t *r,
+ ngx_http_variable_value_t *v, uintptr_t data)
+{
+ ngx_str_t *s;
+
+ s = (ngx_str_t *) ((char *) r + data);
+
+ s->len = v->len;
+ s->data = v->data;
+}
+
+
+static void
ngx_http_variable_request_set_size(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data)
{
@@ -860,6 +882,27 @@ ngx_http_variable_scheme(ngx_http_request_t *r,
static ngx_int_t
+ngx_http_variable_is_args(ngx_http_request_t *r,
+ ngx_http_variable_value_t *v, uintptr_t data)
+{
+ v->valid = 1;
+ v->no_cachable = 0;
+ v->not_found = 0;
+
+ if (r->args.len == 0) {
+ v->len = 0;
+ v->data = NULL;
+ return NGX_OK;
+ }
+
+ v->len = 1;
+ v->data = (u_char *) "?";
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
ngx_http_variable_document_root(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data)
{
@@ -883,7 +926,9 @@ ngx_http_variable_document_root(ngx_http_request_t *r,
return NGX_ERROR;
}
- if (ngx_conf_full_name((ngx_cycle_t *) ngx_cycle, &path) == NGX_ERROR) {
+ if (ngx_conf_full_name((ngx_cycle_t *) ngx_cycle, &path, 0)
+ == NGX_ERROR)
+ {
return NGX_ERROR;
}