mirror of
https://github.com/nginx/nginx.git
synced 2026-08-27 04:07:18 +00:00
nginx-0.3.27-RELEASE import
*) Change: the "variables_hash_max_size" and
"variables_hash_bucket_size" directives.
*) Feature: the $body_bytes_sent variable can be used not only in the
"log_format" directive.
*) Feature: the $ssl_protocol and $ssl_cipher variables.
*) Feature: the cache line size detection for widespread CPUs at start
time.
*) Feature: now the "accept_mutex" directive is supported using
fcntl(2) on platforms different from i386, amd64, sparc64, and ppc.
*) Feature: the "lock_file" directive and the --with-lock-path=PATH
autoconfiguration directive.
*) Bugfix: if the HTTPS protocol was used in the "proxy_pass" directive
then the requests with the body was not transferred.
This commit is contained in:
parent
2446d5d6ad
commit
ffe714403d
40 changed files with 1073 additions and 433 deletions
|
|
@ -741,6 +741,8 @@ ngx_http_proxy_create_request(ngx_http_request_t *r)
|
|||
body = body->next;
|
||||
}
|
||||
|
||||
b->flush = 1;
|
||||
|
||||
} else {
|
||||
u->request_bufs = cl;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -271,6 +271,8 @@ ngx_http_referer_merge_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
conf->blocked_referer = 0;
|
||||
}
|
||||
|
||||
conf->keys = NULL;
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
ngx_str_t name;
|
||||
ngx_uint_t key;
|
||||
ngx_str_t value;
|
||||
} ngx_http_ssi_var_t;
|
||||
|
||||
|
|
@ -62,7 +63,7 @@ static ngx_int_t ngx_http_ssi_output(ngx_http_request_t *r,
|
|||
static ngx_int_t ngx_http_ssi_parse(ngx_http_request_t *r,
|
||||
ngx_http_ssi_ctx_t *ctx);
|
||||
static ngx_str_t *ngx_http_ssi_get_variable(ngx_http_request_t *r,
|
||||
ngx_str_t *name);
|
||||
ngx_str_t *name, ngx_uint_t key);
|
||||
static ngx_int_t ngx_http_ssi_evaluate_string(ngx_http_request_t *r,
|
||||
ngx_http_ssi_ctx_t *ctx, ngx_str_t *text, ngx_uint_t flags);
|
||||
|
||||
|
|
@ -1335,7 +1336,8 @@ ngx_http_ssi_parse(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx)
|
|||
|
||||
|
||||
static ngx_str_t *
|
||||
ngx_http_ssi_get_variable(ngx_http_request_t *r, ngx_str_t *name)
|
||||
ngx_http_ssi_get_variable(ngx_http_request_t *r, ngx_str_t *name,
|
||||
ngx_uint_t key)
|
||||
{
|
||||
ngx_uint_t i;
|
||||
ngx_http_ssi_var_t *var;
|
||||
|
|
@ -1349,7 +1351,11 @@ ngx_http_ssi_get_variable(ngx_http_request_t *r, ngx_str_t *name)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (ngx_strncasecmp(name->data, var[i].name.data, name->len) == 0) {
|
||||
if (key != var[i].key) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ngx_strncmp(name->data, var[i].name.data, name->len) == 0) {
|
||||
return &var[i].value;
|
||||
}
|
||||
}
|
||||
|
|
@ -1365,6 +1371,7 @@ ngx_http_ssi_evaluate_string(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
|
|||
u_char ch, *p, **value, *data, *part_data;
|
||||
size_t *size, len, prefix, part_len;
|
||||
ngx_str_t var, *val;
|
||||
ngx_int_t key;
|
||||
ngx_uint_t i, j, n, bracket;
|
||||
ngx_array_t lengths, values;
|
||||
ngx_http_variable_value_t *vv;
|
||||
|
|
@ -1469,14 +1476,17 @@ ngx_http_ssi_evaluate_string(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
|
|||
goto invalid_variable;
|
||||
}
|
||||
|
||||
key = 0;
|
||||
|
||||
for (j = 0; j < var.len; j++) {
|
||||
var.data[j] = ngx_tolower(var.data[j]);
|
||||
key = ngx_hash(key, var.data[j]);
|
||||
}
|
||||
|
||||
val = ngx_http_ssi_get_variable(r, &var);
|
||||
val = ngx_http_ssi_get_variable(r, &var, key);
|
||||
|
||||
if (val == NULL) {
|
||||
vv = ngx_http_get_variable(r, &var);
|
||||
vv = ngx_http_get_variable(r, &var, key);
|
||||
|
||||
if (vv == NULL) {
|
||||
return NGX_ERROR;
|
||||
|
|
@ -1636,6 +1646,7 @@ static ngx_int_t
|
|||
ngx_http_ssi_echo(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
|
||||
ngx_str_t **params)
|
||||
{
|
||||
ngx_int_t key;
|
||||
ngx_uint_t i;
|
||||
ngx_buf_t *b;
|
||||
ngx_str_t *var, *value, text;
|
||||
|
|
@ -1644,14 +1655,17 @@ ngx_http_ssi_echo(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
|
|||
|
||||
var = params[NGX_HTTP_SSI_ECHO_VAR];
|
||||
|
||||
value = ngx_http_ssi_get_variable(r, var);
|
||||
key = 0;
|
||||
|
||||
for (i = 0; i < var->len; i++) {
|
||||
var->data[i] = ngx_tolower(var->data[i]);
|
||||
key = ngx_hash(key, var->data[i]);
|
||||
}
|
||||
|
||||
value = ngx_http_ssi_get_variable(r, var, key);
|
||||
|
||||
if (value == NULL) {
|
||||
for (i = 0; i < var->len; i++) {
|
||||
var->data[i] = ngx_tolower(var->data[i]);
|
||||
}
|
||||
|
||||
vv = ngx_http_get_variable(r, var);
|
||||
vv = ngx_http_get_variable(r, var, key);
|
||||
|
||||
if (vv == NULL) {
|
||||
return NGX_HTTP_SSI_ERROR;
|
||||
|
|
@ -1735,6 +1749,8 @@ static ngx_int_t
|
|||
ngx_http_ssi_set(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
|
||||
ngx_str_t **params)
|
||||
{
|
||||
ngx_int_t key;
|
||||
ngx_uint_t i;
|
||||
ngx_str_t *name, *value, *vv;
|
||||
ngx_http_ssi_var_t *var;
|
||||
ngx_http_ssi_ctx_t *mctx;
|
||||
|
|
@ -1756,7 +1772,14 @@ ngx_http_ssi_set(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
|
|||
return NGX_HTTP_SSI_ERROR;
|
||||
}
|
||||
|
||||
vv = ngx_http_ssi_get_variable(r, name);
|
||||
key = 0;
|
||||
|
||||
for (i = 0; i < name->len; i++) {
|
||||
name->data[i] = ngx_tolower(name->data[i]);
|
||||
key = ngx_hash(key, name->data[i]);
|
||||
}
|
||||
|
||||
vv = ngx_http_ssi_get_variable(r, name, key);
|
||||
|
||||
if (vv) {
|
||||
*vv = *value;
|
||||
|
|
@ -1769,6 +1792,7 @@ ngx_http_ssi_set(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
|
|||
}
|
||||
|
||||
var->name = *name;
|
||||
var->key = key;
|
||||
var->value = *value;
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
|
|
|
|||
|
|
@ -9,11 +9,18 @@
|
|||
#include <ngx_http.h>
|
||||
|
||||
|
||||
typedef u_char *(*ngx_ssl_variable_handler_pt)(ngx_connection_t *);
|
||||
|
||||
|
||||
#define NGX_DEFLAUT_CERTIFICATE "cert.pem"
|
||||
#define NGX_DEFLAUT_CERTIFICATE_KEY "cert.pem"
|
||||
#define NGX_DEFLAUT_CIPHERS "ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP"
|
||||
|
||||
|
||||
static ngx_int_t ngx_http_ssl_variable(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
|
||||
static ngx_int_t ngx_http_ssl_add_variables(ngx_conf_t *cf);
|
||||
static void *ngx_http_ssl_create_srv_conf(ngx_conf_t *cf);
|
||||
static char *ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf,
|
||||
void *parent, void *child);
|
||||
|
|
@ -97,7 +104,7 @@ static ngx_command_t ngx_http_ssl_commands[] = {
|
|||
|
||||
|
||||
static ngx_http_module_t ngx_http_ssl_module_ctx = {
|
||||
NULL, /* preconfiguration */
|
||||
ngx_http_ssl_add_variables, /* preconfiguration */
|
||||
NULL, /* postconfiguration */
|
||||
|
||||
NULL, /* create main configuration */
|
||||
|
|
@ -127,9 +134,70 @@ ngx_module_t ngx_http_ssl_module = {
|
|||
};
|
||||
|
||||
|
||||
static ngx_http_variable_t ngx_http_ssl_vars[] = {
|
||||
|
||||
{ ngx_string("ssl_protocol"), ngx_http_ssl_variable,
|
||||
(uintptr_t) ngx_ssl_get_protocol, NGX_HTTP_VAR_CHANGABLE, 0 },
|
||||
|
||||
{ ngx_string("ssl_cipher"), ngx_http_ssl_variable,
|
||||
(uintptr_t) ngx_ssl_get_cipher_name, NGX_HTTP_VAR_CHANGABLE, 0 },
|
||||
|
||||
{ ngx_null_string, NULL, 0, 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
static u_char ngx_http_session_id_ctx[] = "HTTP";
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_ssl_variable(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data)
|
||||
{
|
||||
ngx_ssl_variable_handler_pt handler = (ngx_ssl_variable_handler_pt) data;
|
||||
|
||||
size_t len;
|
||||
u_char *name;
|
||||
|
||||
if (r->connection->ssl) {
|
||||
|
||||
name = handler(r->connection);
|
||||
|
||||
for (len = 0; name[len]; len++) { /* void */ }
|
||||
|
||||
v->len = len;
|
||||
v->valid = 1;
|
||||
v->no_cachable = 0;
|
||||
v->not_found = 0;
|
||||
v->data = name;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
v->not_found = 1;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_ssl_add_variables(ngx_conf_t *cf)
|
||||
{
|
||||
ngx_http_variable_t *var, *v;
|
||||
|
||||
for (v = ngx_http_ssl_vars; v->name.len; v++) {
|
||||
var = ngx_http_add_variable(cf, &v->name, v->flags);
|
||||
if (var == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
var->handler = v->handler;
|
||||
var->data = v->data;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
ngx_http_ssl_create_srv_conf(ngx_conf_t *cf)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -77,6 +77,20 @@ static ngx_conf_enum_t ngx_http_restrict_host_names[] = {
|
|||
|
||||
static ngx_command_t ngx_http_core_commands[] = {
|
||||
|
||||
{ ngx_string("variables_hash_max_size"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_num_slot,
|
||||
NGX_HTTP_MAIN_CONF_OFFSET,
|
||||
offsetof(ngx_http_core_main_conf_t, variables_hash_max_size),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("variables_hash_bucket_size"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_num_slot,
|
||||
NGX_HTTP_MAIN_CONF_OFFSET,
|
||||
offsetof(ngx_http_core_main_conf_t, variables_hash_bucket_size),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("server_names_hash_max_size"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_num_slot,
|
||||
|
|
@ -1787,6 +1801,9 @@ ngx_http_core_create_main_conf(ngx_conf_t *cf)
|
|||
cmcf->server_names_hash_max_size = NGX_CONF_UNSET_UINT;
|
||||
cmcf->server_names_hash_bucket_size = NGX_CONF_UNSET_UINT;
|
||||
|
||||
cmcf->variables_hash_max_size = NGX_CONF_UNSET_UINT;
|
||||
cmcf->variables_hash_bucket_size = NGX_CONF_UNSET_UINT;
|
||||
|
||||
return cmcf;
|
||||
}
|
||||
|
||||
|
|
@ -1807,6 +1824,18 @@ ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf)
|
|||
cmcf->server_names_hash_bucket_size =
|
||||
ngx_align(cmcf->server_names_hash_bucket_size, ngx_cacheline_size);
|
||||
|
||||
|
||||
if (cmcf->variables_hash_max_size == NGX_CONF_UNSET_UINT) {
|
||||
cmcf->variables_hash_max_size = 512;
|
||||
}
|
||||
|
||||
if (cmcf->variables_hash_bucket_size == NGX_CONF_UNSET_UINT) {
|
||||
cmcf->variables_hash_bucket_size = 64;
|
||||
}
|
||||
|
||||
cmcf->variables_hash_bucket_size =
|
||||
ngx_align(cmcf->variables_hash_bucket_size, ngx_cacheline_size);
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
|
@ -2224,7 +2253,7 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
|
||||
ls->family = AF_INET;
|
||||
ls->port = (in_port_t) (inet_upstream.default_port ?
|
||||
80 : inet_upstream.port);
|
||||
80 : inet_upstream.port);
|
||||
ls->file_name = cf->conf_file->file.name;
|
||||
ls->line = cf->conf_file->line;
|
||||
ls->conf.backlog = -1;
|
||||
|
|
|
|||
|
|
@ -71,13 +71,18 @@ typedef struct {
|
|||
ngx_http_phase_t phases[NGX_HTTP_LOG_PHASE + 1];
|
||||
|
||||
ngx_hash0_t headers_in_hash;
|
||||
ngx_hash0_t variables_hash;
|
||||
|
||||
ngx_hash_t variables_hash;
|
||||
|
||||
ngx_array_t variables; /* ngx_http_variable_t */
|
||||
|
||||
ngx_uint_t server_names_hash_max_size;
|
||||
ngx_uint_t server_names_hash_bucket_size;
|
||||
|
||||
ngx_array_t variables; /* ngx_http_variable_t */
|
||||
ngx_array_t all_variables; /* ngx_http_variable_t */
|
||||
ngx_uint_t variables_hash_max_size;
|
||||
ngx_uint_t variables_hash_bucket_size;
|
||||
|
||||
ngx_hash_keys_arrays_t *variables_keys;
|
||||
} ngx_http_core_main_conf_t;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -174,7 +174,7 @@ ngx_http_init_connection(ngx_connection_t *c)
|
|||
if (rev->ready) {
|
||||
/* the deferred accept(), rtsig, aio, iocp */
|
||||
|
||||
if (ngx_accept_mutex) {
|
||||
if (ngx_use_accept_mutex) {
|
||||
ngx_post_event(rev, &ngx_posted_events);
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1457,11 +1457,10 @@ ngx_http_upstream_process_non_buffered_body(ngx_event_t *ev)
|
|||
if (ev->timedout) {
|
||||
if (ev->write) {
|
||||
c->timedout = 1;
|
||||
ngx_log_error(NGX_LOG_ERR, c->log, NGX_ETIMEDOUT,
|
||||
"client timed out");
|
||||
ngx_connection_error(c, NGX_ETIMEDOUT, "client timed out");
|
||||
|
||||
} else {
|
||||
ngx_log_error(NGX_LOG_ERR, c->log, NGX_ETIMEDOUT,
|
||||
"upstream timed out");
|
||||
ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1681,14 +1680,12 @@ ngx_http_upstream_process_body(ngx_event_t *ev)
|
|||
} else {
|
||||
p->downstream_error = 1;
|
||||
c->timedout = 1;
|
||||
ngx_log_error(NGX_LOG_ERR, c->log, NGX_ETIMEDOUT,
|
||||
"client timed out");
|
||||
ngx_connection_error(c, NGX_ETIMEDOUT, "client timed out");
|
||||
}
|
||||
|
||||
} else {
|
||||
p->upstream_error = 1;
|
||||
ngx_log_error(NGX_LOG_ERR, c->log, NGX_ETIMEDOUT,
|
||||
"upstream timed out");
|
||||
ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out");
|
||||
}
|
||||
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -42,6 +42,8 @@ static ngx_int_t ngx_http_variable_request_method(ngx_http_request_t *r,
|
|||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
static ngx_int_t ngx_http_variable_remote_user(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
static ngx_int_t ngx_http_variable_body_bytes_sent(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
|
||||
|
||||
/*
|
||||
|
|
@ -130,6 +132,9 @@ static ngx_http_variable_t ngx_http_core_variables[] = {
|
|||
|
||||
{ ngx_string("remote_user"), ngx_http_variable_remote_user, 0, 0, 0 },
|
||||
|
||||
{ ngx_string("body_bytes_sent"), ngx_http_variable_body_bytes_sent,
|
||||
0, 0, 0 },
|
||||
|
||||
{ ngx_null_string, NULL, 0, 0, 0 }
|
||||
};
|
||||
|
||||
|
|
@ -143,30 +148,34 @@ ngx_http_variable_value_t ngx_http_variable_true_value =
|
|||
ngx_http_variable_t *
|
||||
ngx_http_add_variable(ngx_conf_t *cf, ngx_str_t *name, ngx_uint_t flags)
|
||||
{
|
||||
ngx_int_t rc;
|
||||
ngx_uint_t i;
|
||||
ngx_hash_key_t *key;
|
||||
ngx_http_variable_t *v;
|
||||
ngx_http_core_main_conf_t *cmcf;
|
||||
|
||||
cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
|
||||
|
||||
v = cmcf->all_variables.elts;
|
||||
for (i = 0; i < cmcf->all_variables.nelts; i++) {
|
||||
if (name->len != v[i].name.len
|
||||
|| ngx_strncasecmp(name->data, v[i].name.data, name->len) != 0)
|
||||
key = cmcf->variables_keys->keys.elts;
|
||||
for (i = 0; i < cmcf->variables_keys->keys.nelts; i++) {
|
||||
if (name->len != key[i].key.len
|
||||
|| ngx_strncasecmp(name->data, key[i].key.data, name->len) != 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(v[i].flags & NGX_HTTP_VAR_CHANGABLE)) {
|
||||
v = key[i].value;
|
||||
|
||||
if (!(v->flags & NGX_HTTP_VAR_CHANGABLE)) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"the duplicate \"%V\" variable", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &v[i];
|
||||
return v;
|
||||
}
|
||||
|
||||
v = ngx_array_push(&cmcf->all_variables);
|
||||
v = ngx_palloc(cf->pool, sizeof(ngx_http_variable_t));
|
||||
if (v == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -186,6 +195,18 @@ ngx_http_add_variable(ngx_conf_t *cf, ngx_str_t *name, ngx_uint_t flags)
|
|||
v->flags = flags;
|
||||
v->index = 0;
|
||||
|
||||
rc = ngx_hash_add_key(cmcf->variables_keys, &v->name, v, 0);
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (rc == NGX_BUSY) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"conflicting variable name \"%V\"", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
|
|
@ -298,34 +319,25 @@ ngx_http_get_flushed_variable(ngx_http_request_t *r, ngx_uint_t index)
|
|||
|
||||
|
||||
ngx_http_variable_value_t *
|
||||
ngx_http_get_variable(ngx_http_request_t *r, ngx_str_t *name)
|
||||
ngx_http_get_variable(ngx_http_request_t *r, ngx_str_t *name, ngx_uint_t key)
|
||||
{
|
||||
ngx_uint_t i, key;
|
||||
ngx_http_variable_t *v;
|
||||
ngx_http_variable_value_t *vv;
|
||||
ngx_http_core_main_conf_t *cmcf;
|
||||
|
||||
cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
|
||||
|
||||
key = 0;
|
||||
for (i = 0; i < name->len; i++) {
|
||||
key += name->data[i];
|
||||
}
|
||||
v = ngx_hash_find(&cmcf->variables_hash, key, name->data, name->len);
|
||||
|
||||
key %= cmcf->variables_hash.hash_size;
|
||||
v = (ngx_http_variable_t *) cmcf->variables_hash.buckets;
|
||||
|
||||
if (v[key].name.len == name->len
|
||||
&& ngx_strncmp(v[key].name.data, name->data, name->len) == 0)
|
||||
{
|
||||
if (v[key].flags & NGX_HTTP_VAR_INDEXED) {
|
||||
return ngx_http_get_indexed_variable(r, v[key].index);
|
||||
if (v) {
|
||||
if (v->flags & NGX_HTTP_VAR_INDEXED) {
|
||||
return ngx_http_get_indexed_variable(r, v->index);
|
||||
|
||||
} else {
|
||||
|
||||
vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t));
|
||||
|
||||
if (vv && v[key].handler(r, vv, v[key].data) == NGX_OK) {
|
||||
if (vv && v->handler(r, vv, v->data) == NGX_OK) {
|
||||
return vv;
|
||||
}
|
||||
|
||||
|
|
@ -758,28 +770,72 @@ ngx_http_variable_remote_user(ngx_http_request_t *r,
|
|||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_variable_body_bytes_sent(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data)
|
||||
{
|
||||
off_t sent;
|
||||
u_char *p;
|
||||
|
||||
sent = r->connection->sent - r->header_size;
|
||||
|
||||
if (sent < 0) {
|
||||
sent = 0;
|
||||
}
|
||||
|
||||
p = ngx_palloc(r->pool, NGX_OFF_T_LEN);
|
||||
if (p == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
v->len = ngx_sprintf(p, "%O", sent) - p;
|
||||
v->valid = 1;
|
||||
v->no_cachable = 0;
|
||||
v->not_found = 0;
|
||||
v->data = p;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_http_variables_add_core_vars(ngx_conf_t *cf)
|
||||
{
|
||||
ngx_http_variable_t *v, *cv;
|
||||
ngx_int_t rc;
|
||||
ngx_http_variable_t *v;
|
||||
ngx_http_core_main_conf_t *cmcf;
|
||||
|
||||
cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
|
||||
|
||||
if (ngx_array_init(&cmcf->all_variables, cf->pool, 32,
|
||||
sizeof(ngx_http_variable_t))
|
||||
== NGX_ERROR)
|
||||
cmcf->variables_keys = ngx_pcalloc(cf->temp_pool,
|
||||
sizeof(ngx_hash_keys_arrays_t));
|
||||
if (cmcf->variables_keys == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
cmcf->variables_keys->pool = cf->pool;
|
||||
cmcf->variables_keys->temp_pool = cf->pool;
|
||||
|
||||
if (ngx_hash_keys_array_init(cmcf->variables_keys, NGX_HASH_SMALL)
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
for (cv = ngx_http_core_variables; cv->name.len; cv++) {
|
||||
v = ngx_array_push(&cmcf->all_variables);
|
||||
if (v == NULL) {
|
||||
return NGX_ERROR;
|
||||
for (v = ngx_http_core_variables; v->name.len; v++) {
|
||||
rc = ngx_hash_add_key(cmcf->variables_keys, &v->name, v,
|
||||
NGX_HASH_READONLY_KEY);
|
||||
|
||||
if (rc == NGX_OK) {
|
||||
continue;
|
||||
}
|
||||
|
||||
*v = *cv;
|
||||
if (rc == NGX_BUSY) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"conflicting variable name \"%V\"", &v->name);
|
||||
}
|
||||
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
|
|
@ -790,6 +846,8 @@ ngx_int_t
|
|||
ngx_http_variables_init_vars(ngx_conf_t *cf)
|
||||
{
|
||||
ngx_uint_t i, n;
|
||||
ngx_hash_key_t *key;
|
||||
ngx_hash_init_t hash;
|
||||
ngx_http_variable_t *v, *av;
|
||||
ngx_http_core_main_conf_t *cmcf;
|
||||
|
||||
|
|
@ -798,23 +856,25 @@ ngx_http_variables_init_vars(ngx_conf_t *cf)
|
|||
cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
|
||||
|
||||
v = cmcf->variables.elts;
|
||||
av = cmcf->all_variables.elts;
|
||||
key = cmcf->variables_keys->keys.elts;
|
||||
|
||||
for (i = 0; i < cmcf->variables.nelts; i++) {
|
||||
|
||||
for (n = 0; n < cmcf->all_variables.nelts; n++) {
|
||||
for (n = 0; n < cmcf->variables_keys->keys.nelts; n++) {
|
||||
|
||||
if (v[i].name.len == av[n].name.len
|
||||
&& ngx_strncmp(v[i].name.data, av[n].name.data, v[i].name.len)
|
||||
if (v[i].name.len == key[n].key.len
|
||||
&& ngx_strncmp(v[i].name.data, key[n].key.data, v[i].name.len)
|
||||
== 0)
|
||||
{
|
||||
v[i].handler = av[n].handler;
|
||||
v[i].data = av[n].data;
|
||||
av = key[n].value;
|
||||
|
||||
av[n].flags |= NGX_HTTP_VAR_INDEXED;
|
||||
v[i].flags = av[n].flags;
|
||||
v[i].handler = av->handler;
|
||||
v[i].data = av->data;
|
||||
|
||||
av[n].index = i;
|
||||
av->flags |= NGX_HTTP_VAR_INDEXED;
|
||||
v[i].flags = av->flags;
|
||||
|
||||
av->index = i;
|
||||
|
||||
goto next;
|
||||
}
|
||||
|
|
@ -843,36 +903,32 @@ ngx_http_variables_init_vars(ngx_conf_t *cf)
|
|||
continue;
|
||||
}
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, cf->log, 0,
|
||||
"http variables: %ui", cmcf->variables.nelts);
|
||||
|
||||
for (n = 0; n < cmcf->variables_keys->keys.nelts; n++) {
|
||||
av = key[n].value;
|
||||
|
||||
for (n = 0; n < cmcf->all_variables.nelts; n++) {
|
||||
if (av[n].flags & NGX_HTTP_VAR_NOHASH) {
|
||||
av[n].name.data = NULL;
|
||||
if (av->flags & NGX_HTTP_VAR_NOHASH) {
|
||||
key[n].key.data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* init the all http variables hash */
|
||||
hash.hash = &cmcf->variables_hash;
|
||||
hash.key = ngx_hash_key;
|
||||
hash.max_size = cmcf->variables_hash_max_size;
|
||||
hash.bucket_size = cmcf->variables_hash_bucket_size;
|
||||
hash.name = "variables_hash";
|
||||
hash.pool = cf->pool;
|
||||
hash.temp_pool = NULL;
|
||||
|
||||
cmcf->variables_hash.max_size = 500;
|
||||
cmcf->variables_hash.bucket_limit = 1;
|
||||
cmcf->variables_hash.bucket_size = sizeof(ngx_http_variable_t);
|
||||
cmcf->variables_hash.name = "http variables";
|
||||
|
||||
if (ngx_hash0_init(&cmcf->variables_hash, cf->pool,
|
||||
cmcf->all_variables.elts, cmcf->all_variables.nelts)
|
||||
if (ngx_hash_init(&hash, cmcf->variables_keys->keys.elts,
|
||||
cmcf->variables_keys->keys.nelts)
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_log_debug3(NGX_LOG_DEBUG_HTTP, cf->log, 0,
|
||||
"http variables hash size: %ui for %ui values, "
|
||||
"max buckets per entry: %ui",
|
||||
cmcf->variables_hash.hash_size, cmcf->all_variables.nelts,
|
||||
cmcf->variables_hash.min_buckets);
|
||||
cmcf->variables_keys = NULL;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ ngx_http_variable_value_t *ngx_http_get_flushed_variable(ngx_http_request_t *r,
|
|||
ngx_uint_t index);
|
||||
|
||||
ngx_http_variable_value_t *ngx_http_get_variable(ngx_http_request_t *r,
|
||||
ngx_str_t *name);
|
||||
ngx_str_t *name, ngx_uint_t key);
|
||||
|
||||
#define ngx_http_clear_variable(r, index) r->variables0[index].text.data = NULL;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue