2005-04-08 23:18:55 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Copyright (C) Igor Sysoev
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#include <ngx_config.h>
|
|
|
|
#include <ngx_core.h>
|
|
|
|
|
|
|
|
|
2005-12-16 23:07:08 +08:00
|
|
|
void *
|
|
|
|
ngx_hash_find(ngx_hash_t *hash, ngx_uint_t key, u_char *name, size_t len)
|
|
|
|
{
|
|
|
|
ngx_uint_t i;
|
|
|
|
ngx_hash_elt_t *elt;
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
ngx_str_t line;
|
|
|
|
|
|
|
|
line.len = len;
|
|
|
|
line.data = name;
|
|
|
|
ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "hf:\"%V\"", &line);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
elt = hash->buckets[key % hash->size];
|
|
|
|
|
|
|
|
if (elt == NULL) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (elt->value) {
|
|
|
|
if (len != (size_t) elt->len) {
|
|
|
|
goto next;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < len; i++) {
|
|
|
|
if (name[i] != elt->name[i]) {
|
|
|
|
goto next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return elt->value;
|
|
|
|
|
|
|
|
next:
|
|
|
|
|
|
|
|
elt = (ngx_hash_elt_t *) ngx_align_ptr(&elt->name[0] + elt->len,
|
|
|
|
sizeof(void *));
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void *
|
|
|
|
ngx_hash_find_wildcard(ngx_hash_wildcard_t *hwc, u_char *name, size_t len)
|
|
|
|
{
|
|
|
|
void *value;
|
|
|
|
ngx_uint_t i, n, key;
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
ngx_str_t line;
|
|
|
|
|
|
|
|
line.len = len;
|
|
|
|
line.data = name;
|
|
|
|
ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "wc:\"%V\"", &line);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
n = len;
|
|
|
|
|
|
|
|
while (n) {
|
|
|
|
if (name[n - 1] == '.') {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
n--;
|
|
|
|
}
|
|
|
|
|
|
|
|
key = 0;
|
|
|
|
|
|
|
|
for (i = n; i < len; i++) {
|
|
|
|
key = ngx_hash(key, name[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "key:\"%ui\"", key);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
value = ngx_hash_find(&hwc->hash, key, &name[n], len - n);
|
|
|
|
|
|
|
|
if (value) {
|
2005-12-19 00:02:44 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* the 2 low bits of value have the special meaning:
|
|
|
|
* 00 - value is data pointer,
|
|
|
|
* 01 - value is pointer to wildcard hash allowing
|
|
|
|
* "*.example.com" only,
|
|
|
|
* 11 - value is pointer to wildcard hash allowing
|
|
|
|
* both "example.com" and "*.example.com".
|
|
|
|
*/
|
|
|
|
|
2005-12-16 23:07:08 +08:00
|
|
|
if ((uintptr_t) value & 1) {
|
2005-12-19 00:02:44 +08:00
|
|
|
|
|
|
|
hwc = (ngx_hash_wildcard_t *) ((uintptr_t) value & (uintptr_t) ~3);
|
|
|
|
|
|
|
|
if (n == 0) {
|
|
|
|
if ((uintptr_t) value & 2) {
|
|
|
|
return hwc->value;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
2005-12-16 23:07:08 +08:00
|
|
|
|
|
|
|
value = ngx_hash_find_wildcard(hwc, name, n - 1);
|
|
|
|
|
|
|
|
if (value) {
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
|
|
|
return hwc->value;
|
|
|
|
}
|
|
|
|
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
|
|
|
return hwc->value;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#define NGX_HASH_ELT_SIZE(name) \
|
2005-12-28 22:23:52 +08:00
|
|
|
(sizeof(void *) + ngx_align((name)->key.len + 1, sizeof(void *)))
|
2005-12-16 23:07:08 +08:00
|
|
|
|
|
|
|
ngx_int_t
|
|
|
|
ngx_hash_init(ngx_hash_init_t *hinit, ngx_hash_key_t *names, ngx_uint_t nelts)
|
|
|
|
{
|
|
|
|
u_char *elts;
|
2005-12-28 22:23:52 +08:00
|
|
|
size_t len;
|
|
|
|
u_short *test;
|
2005-12-16 23:07:08 +08:00
|
|
|
ngx_uint_t i, n, key, size, start, bucket_size;
|
|
|
|
ngx_hash_elt_t *elt, **buckets;
|
|
|
|
|
|
|
|
for (n = 0; n < nelts; n++) {
|
|
|
|
if (names[n].key.len >= 255) {
|
|
|
|
ngx_log_error(NGX_LOG_EMERG, hinit->pool->log, 0,
|
|
|
|
"the \"%V\" value to hash is to long: %uz bytes, "
|
|
|
|
"the maximum length can be 255 bytes only",
|
|
|
|
&names[n].key, names[n].key.len);
|
|
|
|
return NGX_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (hinit->bucket_size < NGX_HASH_ELT_SIZE(&names[n]) + sizeof(void *))
|
|
|
|
{
|
|
|
|
ngx_log_error(NGX_LOG_EMERG, hinit->pool->log, 0,
|
2005-12-28 22:23:52 +08:00
|
|
|
"could not build the %s, you should "
|
2005-12-16 23:07:08 +08:00
|
|
|
"increase %s_bucket_size: %i",
|
|
|
|
hinit->name, hinit->name, hinit->bucket_size);
|
|
|
|
return NGX_ERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-12-28 22:23:52 +08:00
|
|
|
test = ngx_alloc(hinit->max_size * sizeof(u_short), hinit->pool->log);
|
2005-12-16 23:07:08 +08:00
|
|
|
if (test == NULL) {
|
|
|
|
return NGX_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
start = nelts / (ngx_cacheline_size / (2 * sizeof(void *)) - 1);
|
|
|
|
start = start ? start : 1;
|
|
|
|
|
|
|
|
bucket_size = hinit->bucket_size - sizeof(void *);
|
|
|
|
|
|
|
|
for (size = start; size < hinit->max_size; size++) {
|
|
|
|
|
2005-12-28 22:23:52 +08:00
|
|
|
ngx_memzero(test, size * sizeof(u_short));
|
2005-12-16 23:07:08 +08:00
|
|
|
|
|
|
|
for (n = 0; n < nelts; n++) {
|
|
|
|
if (names[n].key.data == NULL) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
key = names[n].key_hash % size;
|
2005-12-28 22:23:52 +08:00
|
|
|
test[key] = (u_short) (test[key] + NGX_HASH_ELT_SIZE(&names[n]));
|
2005-12-16 23:07:08 +08:00
|
|
|
|
|
|
|
#if 0
|
|
|
|
ngx_log_error(NGX_LOG_ALERT, hinit->pool->log, 0,
|
|
|
|
"%ui: %ui %ui \"%V\"",
|
|
|
|
size, key, test[key], &names[n].key);
|
|
|
|
#endif
|
|
|
|
|
2005-12-28 22:23:52 +08:00
|
|
|
if (test[key] > (u_short) bucket_size) {
|
2005-12-16 23:07:08 +08:00
|
|
|
goto next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
goto found;
|
|
|
|
|
|
|
|
next:
|
|
|
|
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
ngx_log_error(NGX_LOG_EMERG, hinit->pool->log, 0,
|
2005-12-28 22:23:52 +08:00
|
|
|
"could not build the %s, you should increase "
|
2005-12-16 23:07:08 +08:00
|
|
|
"either %s_max_size: %i or %s_bucket_size: %i",
|
|
|
|
hinit->name, hinit->name, hinit->max_size,
|
|
|
|
hinit->name, hinit->bucket_size);
|
|
|
|
|
|
|
|
ngx_free(test);
|
|
|
|
|
|
|
|
return NGX_ERROR;
|
|
|
|
|
|
|
|
found:
|
|
|
|
|
|
|
|
for (i = 0; i < size; i++) {
|
|
|
|
test[i] = sizeof(void *);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (n = 0; n < nelts; n++) {
|
|
|
|
if (names[n].key.data == NULL) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
key = names[n].key_hash % size;
|
2005-12-28 22:23:52 +08:00
|
|
|
test[key] = (u_short) (test[key] + NGX_HASH_ELT_SIZE(&names[n]));
|
2005-12-16 23:07:08 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
len = 0;
|
|
|
|
|
|
|
|
for (i = 0; i < size; i++) {
|
|
|
|
if (test[i] == sizeof(void *)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2005-12-28 22:23:52 +08:00
|
|
|
test[i] = (u_short) (ngx_align(test[i], ngx_cacheline_size));
|
2005-12-16 23:07:08 +08:00
|
|
|
|
|
|
|
len += test[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (hinit->hash == NULL) {
|
|
|
|
hinit->hash = ngx_pcalloc(hinit->pool, sizeof(ngx_hash_wildcard_t)
|
|
|
|
+ size * sizeof(ngx_hash_elt_t *));
|
|
|
|
if (hinit->hash == NULL) {
|
|
|
|
ngx_free(test);
|
|
|
|
return NGX_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
buckets = (ngx_hash_elt_t **)
|
|
|
|
((u_char *) hinit->hash + sizeof(ngx_hash_wildcard_t));
|
|
|
|
|
|
|
|
} else {
|
|
|
|
buckets = ngx_pcalloc(hinit->pool, size * sizeof(ngx_hash_elt_t *));
|
|
|
|
if (buckets == NULL) {
|
|
|
|
ngx_free(test);
|
|
|
|
return NGX_ERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
elts = ngx_palloc(hinit->pool, len + ngx_cacheline_size);
|
|
|
|
if (elts == NULL) {
|
|
|
|
ngx_free(test);
|
|
|
|
return NGX_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
elts = ngx_align_ptr(elts, ngx_cacheline_size);
|
|
|
|
|
|
|
|
for (i = 0; i < size; i++) {
|
|
|
|
if (test[i] == sizeof(void *)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
buckets[i] = (ngx_hash_elt_t *) elts;
|
|
|
|
elts += test[i];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < size; i++) {
|
|
|
|
test[i] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (n = 0; n < nelts; n++) {
|
|
|
|
if (names[n].key.data == NULL) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
key = names[n].key_hash % size;
|
|
|
|
elt = (ngx_hash_elt_t *) ((u_char *) buckets[key] + test[key]);
|
|
|
|
|
|
|
|
elt->value = names[n].value;
|
|
|
|
elt->len = (u_char) names[n].key.len;
|
|
|
|
|
|
|
|
for (i = 0; i < names[n].key.len; i++) {
|
|
|
|
elt->name[i] = ngx_tolower(names[n].key.data[i]);
|
|
|
|
}
|
|
|
|
|
2005-12-28 22:23:52 +08:00
|
|
|
test[key] = (u_short) (test[key] + NGX_HASH_ELT_SIZE(&names[n]));
|
2005-12-16 23:07:08 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < size; i++) {
|
|
|
|
if (buckets[i] == NULL) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
elt = (ngx_hash_elt_t *) ((u_char *) buckets[i] + test[i]);
|
|
|
|
|
|
|
|
elt->value = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
ngx_free(test);
|
|
|
|
|
|
|
|
hinit->hash->buckets = buckets;
|
|
|
|
hinit->hash->size = size;
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
|
|
|
for (i = 0; i < size; i++) {
|
|
|
|
ngx_str_t val;
|
|
|
|
ngx_uint_t key;
|
|
|
|
|
|
|
|
elt = buckets[i];
|
|
|
|
|
|
|
|
if (elt == NULL) {
|
|
|
|
ngx_log_error(NGX_LOG_ALERT, hinit->pool->log, 0,
|
|
|
|
"%ui: NULL", i);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (elt->value) {
|
|
|
|
val.len = elt->len;
|
|
|
|
val.data = &elt->name[0];
|
|
|
|
|
|
|
|
key = hinit->key(val.data, val.len);
|
|
|
|
|
|
|
|
ngx_log_error(NGX_LOG_ALERT, hinit->pool->log, 0,
|
|
|
|
"%ui: %p \"%V\" %ui", i, elt, &val, key);
|
|
|
|
|
|
|
|
elt = (ngx_hash_elt_t *) ngx_align_ptr(&elt->name[0] + elt->len,
|
|
|
|
sizeof(void *));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return NGX_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ngx_int_t
|
|
|
|
ngx_hash_wildcard_init(ngx_hash_init_t *hinit, ngx_hash_key_t *names,
|
|
|
|
ngx_uint_t nelts)
|
|
|
|
{
|
2005-12-27 01:07:48 +08:00
|
|
|
size_t len, dot_len;
|
2005-12-19 00:02:44 +08:00
|
|
|
ngx_uint_t i, n, dot;
|
2005-12-16 23:07:08 +08:00
|
|
|
ngx_array_t curr_names, next_names;
|
|
|
|
ngx_hash_key_t *name, *next_name;
|
|
|
|
ngx_hash_init_t h;
|
|
|
|
ngx_hash_wildcard_t *wdc;
|
|
|
|
|
|
|
|
if (ngx_array_init(&curr_names, hinit->temp_pool, nelts,
|
|
|
|
sizeof(ngx_hash_key_t))
|
|
|
|
!= NGX_OK)
|
|
|
|
{
|
|
|
|
return NGX_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ngx_array_init(&next_names, hinit->temp_pool, nelts,
|
|
|
|
sizeof(ngx_hash_key_t))
|
|
|
|
!= NGX_OK)
|
|
|
|
{
|
|
|
|
return NGX_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (n = 0; n < nelts; n = i) {
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
ngx_log_error(NGX_LOG_ALERT, hinit->pool->log, 0,
|
|
|
|
"wc0: \"%V\"", &names[n].key);
|
|
|
|
#endif
|
|
|
|
|
2005-12-19 00:02:44 +08:00
|
|
|
dot = 0;
|
|
|
|
|
2005-12-16 23:07:08 +08:00
|
|
|
for (len = 0; len < names[n].key.len; len++) {
|
|
|
|
if (names[n].key.data[len] == '.') {
|
2005-12-19 00:02:44 +08:00
|
|
|
dot = 1;
|
2005-12-16 23:07:08 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
name = ngx_array_push(&curr_names);
|
|
|
|
if (name == NULL) {
|
|
|
|
return NGX_ERROR;
|
|
|
|
}
|
|
|
|
|
2005-12-19 00:02:44 +08:00
|
|
|
name->key.len = len;
|
2005-12-16 23:07:08 +08:00
|
|
|
name->key.data = names[n].key.data;
|
|
|
|
name->key_hash = hinit->key(name->key.data, name->key.len);
|
|
|
|
name->value = names[n].value;
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
ngx_log_error(NGX_LOG_ALERT, hinit->pool->log, 0,
|
2005-12-27 01:07:48 +08:00
|
|
|
"wc1: \"%V\" %ui", &name->key, dot);
|
2005-12-16 23:07:08 +08:00
|
|
|
#endif
|
|
|
|
|
2005-12-27 01:07:48 +08:00
|
|
|
dot_len = len + 1;
|
|
|
|
|
2005-12-19 00:02:44 +08:00
|
|
|
if (dot) {
|
|
|
|
len++;
|
|
|
|
}
|
|
|
|
|
2005-12-16 23:07:08 +08:00
|
|
|
next_names.nelts = 0;
|
|
|
|
|
|
|
|
if (names[n].key.len != len) {
|
|
|
|
next_name = ngx_array_push(&next_names);
|
|
|
|
if (next_name == NULL) {
|
|
|
|
return NGX_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
next_name->key.len = names[n].key.len - len;
|
|
|
|
next_name->key.data = names[n].key.data + len;
|
|
|
|
next_name->key_hash= 0;
|
|
|
|
next_name->value = names[n].value;
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
ngx_log_error(NGX_LOG_ALERT, hinit->pool->log, 0,
|
|
|
|
"wc2: \"%V\"", &next_name->key);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = n + 1; i < nelts; i++) {
|
|
|
|
if (ngx_strncmp(names[n].key.data, names[i].key.data, len) != 0) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2005-12-27 01:07:48 +08:00
|
|
|
if (!dot
|
|
|
|
&& names[i].key.len > len
|
|
|
|
&& names[i].key.data[len] != '.')
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2005-12-16 23:07:08 +08:00
|
|
|
next_name = ngx_array_push(&next_names);
|
|
|
|
if (next_name == NULL) {
|
|
|
|
return NGX_ERROR;
|
|
|
|
}
|
|
|
|
|
2005-12-27 01:07:48 +08:00
|
|
|
next_name->key.len = names[i].key.len - dot_len;
|
|
|
|
next_name->key.data = names[i].key.data + dot_len;
|
2005-12-16 23:07:08 +08:00
|
|
|
next_name->key_hash= 0;
|
|
|
|
next_name->value = names[i].value;
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
ngx_log_error(NGX_LOG_ALERT, hinit->pool->log, 0,
|
2005-12-19 00:02:44 +08:00
|
|
|
"wc3: \"%V\"", &next_name->key);
|
2005-12-16 23:07:08 +08:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
if (next_names.nelts) {
|
2005-12-27 01:07:48 +08:00
|
|
|
|
2005-12-16 23:07:08 +08:00
|
|
|
h = *hinit;
|
|
|
|
h.hash = NULL;
|
|
|
|
|
|
|
|
if (ngx_hash_wildcard_init(&h, (ngx_hash_key_t *) next_names.elts,
|
|
|
|
next_names.nelts)
|
|
|
|
!= NGX_OK)
|
|
|
|
{
|
|
|
|
return NGX_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
wdc = (ngx_hash_wildcard_t *) h.hash;
|
|
|
|
|
|
|
|
if (names[n].key.len == len) {
|
|
|
|
wdc->value = names[n].value;
|
|
|
|
#if 0
|
2005-12-27 01:07:48 +08:00
|
|
|
ngx_log_error(NGX_LOG_ALERT, hinit->pool->log, 0,
|
|
|
|
"wdc: \"%V\"", wdc->value);
|
2005-12-16 23:07:08 +08:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2005-12-19 00:02:44 +08:00
|
|
|
name->value = (void *) ((uintptr_t) wdc | (dot ? 1 : 3));
|
2005-12-16 23:07:08 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ngx_hash_init(hinit, (ngx_hash_key_t *) curr_names.elts,
|
|
|
|
curr_names.nelts)
|
|
|
|
!= NGX_OK)
|
|
|
|
{
|
|
|
|
return NGX_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NGX_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ngx_uint_t
|
|
|
|
ngx_hash_key(u_char *data, size_t len)
|
|
|
|
{
|
|
|
|
ngx_uint_t i, key;
|
|
|
|
|
|
|
|
key = 0;
|
|
|
|
|
|
|
|
for (i = 0; i < len; i++) {
|
|
|
|
key = ngx_hash(key, data[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
return key;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ngx_uint_t
|
|
|
|
ngx_hash_key_lc(u_char *data, size_t len)
|
|
|
|
{
|
|
|
|
ngx_uint_t i, key;
|
|
|
|
|
|
|
|
key = 0;
|
|
|
|
|
|
|
|
for (i = 0; i < len; i++) {
|
|
|
|
key = ngx_hash(key, ngx_tolower(data[i]));
|
|
|
|
}
|
|
|
|
|
|
|
|
return key;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-04-08 23:18:55 +08:00
|
|
|
ngx_int_t
|
2005-12-16 23:07:08 +08:00
|
|
|
ngx_hash0_init(ngx_hash0_t *hash, ngx_pool_t *pool, void *names,
|
|
|
|
ngx_uint_t nelts)
|
2005-04-08 23:18:55 +08:00
|
|
|
{
|
|
|
|
u_char *p;
|
nginx-0.1.29-RELEASE import
*) Feature: the ngx_http_ssi_module supports "include virtual" command.
*) Feature: the ngx_http_ssi_module supports the condition command like
'if expr="$NAME"' and "else" and "endif" commands. Only one nested
level is supported.
*) Feature: the ngx_http_ssi_module supports the DATE_LOCAL and
DATE_GMT variables and "config timefmt" command.
*) Feature: the "ssi_ignore_recycled_buffers" directive.
*) Bugfix: the "echo" command did not show the default value for the
empty QUERY_STRING variable.
*) Change: the ngx_http_proxy_module was rewritten.
*) Feature: the "proxy_redirect", "proxy_pass_request_headers",
"proxy_pass_request_body", and "proxy_method" directives.
*) Feature: the "proxy_set_header" directive. The "proxy_x_var" was
canceled and must be replaced with the proxy_set_header directive.
*) Change: the "proxy_preserve_host" is canceled and must be replaced
with the "proxy_set_header Host $host" and the "proxy_redirect off"
directives, the "proxy_set_header Host $host:$proxy_port" directive
and the appropriate proxy_redirect directives.
*) Change: the "proxy_set_x_real_ip" is canceled and must be replaced
with the "proxy_set_header X-Real-IP $remote_addr" directive.
*) Change: the "proxy_add_x_forwarded_for" is canceled and must be
replaced with
the "proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for"
directive.
*) Change: the "proxy_set_x_url" is canceled and must be replaced with
the "proxy_set_header X-URL http://$host:$server_port$request_uri"
directive.
*) Feature: the "fastcgi_param" directive.
*) Change: the "fastcgi_root", "fastcgi_set_var" and "fastcgi_params"
directive are canceled and must be replaced with the fastcgi_param
directives.
*) Feature: the "index" directive can use the variables.
*) Feature: the "index" directive can be used at http and server levels.
*) Change: the last index only in the "index" directive can be absolute.
*) Feature: the "rewrite" directive can use the variables.
*) Feature: the "internal" directive.
*) Feature: the CONTENT_LENGTH, CONTENT_TYPE, REMOTE_PORT, SERVER_ADDR,
SERVER_PORT, SERVER_PROTOCOL, DOCUMENT_ROOT, SERVER_NAME,
REQUEST_METHOD, REQUEST_URI, and REMOTE_USER variables.
*) Change: nginx now passes the invalid lines in a client request
headers or a backend response header.
*) Bugfix: if the backend did not transfer response for a long time and
the "send_timeout" was less than "proxy_read_timeout", then nginx
returned the 408 response.
*) Bugfix: the segmentation fault was occurred if the backend sent an
invalid line in response header; the bug had appeared in 0.1.26.
*) Bugfix: the segmentation fault may occurred in FastCGI fault
tolerance configuration.
*) Bugfix: the "expires" directive did not remove the previous
"Expires" and "Cache-Control" headers.
*) Bugfix: nginx did not take into account trailing dot in "Host"
header line.
*) Bugfix: the ngx_http_auth_module did not work under Linux.
*) Bugfix: the rewrite directive worked incorrectly, if the arguments
were in a request.
*) Bugfix: nginx could not be built on MacOS X.
2005-05-12 22:58:06 +08:00
|
|
|
ngx_str_t *name, *bucket;
|
|
|
|
ngx_uint_t i, n, key, size, best, *test, buckets, min_buckets;
|
|
|
|
|
|
|
|
if (nelts == 0) {
|
|
|
|
for (name = (ngx_str_t *) names;
|
|
|
|
name->len;
|
|
|
|
name = (ngx_str_t *) ((char *) name + hash->bucket_size))
|
|
|
|
{
|
|
|
|
nelts++;
|
|
|
|
}
|
|
|
|
}
|
2005-04-08 23:18:55 +08:00
|
|
|
|
|
|
|
test = ngx_alloc(hash->max_size * sizeof(ngx_uint_t), pool->log);
|
|
|
|
if (test == NULL) {
|
|
|
|
return NGX_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
min_buckets = hash->bucket_limit + 1;
|
|
|
|
|
|
|
|
#if (NGX_SUPPRESS_WARN)
|
|
|
|
best = 0;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
for (size = 1; size < hash->max_size; size++) {
|
|
|
|
|
|
|
|
buckets = 0;
|
|
|
|
|
|
|
|
for (i = 0; i < size; i++) {
|
|
|
|
test[i] = 0;
|
|
|
|
}
|
|
|
|
|
nginx-0.1.29-RELEASE import
*) Feature: the ngx_http_ssi_module supports "include virtual" command.
*) Feature: the ngx_http_ssi_module supports the condition command like
'if expr="$NAME"' and "else" and "endif" commands. Only one nested
level is supported.
*) Feature: the ngx_http_ssi_module supports the DATE_LOCAL and
DATE_GMT variables and "config timefmt" command.
*) Feature: the "ssi_ignore_recycled_buffers" directive.
*) Bugfix: the "echo" command did not show the default value for the
empty QUERY_STRING variable.
*) Change: the ngx_http_proxy_module was rewritten.
*) Feature: the "proxy_redirect", "proxy_pass_request_headers",
"proxy_pass_request_body", and "proxy_method" directives.
*) Feature: the "proxy_set_header" directive. The "proxy_x_var" was
canceled and must be replaced with the proxy_set_header directive.
*) Change: the "proxy_preserve_host" is canceled and must be replaced
with the "proxy_set_header Host $host" and the "proxy_redirect off"
directives, the "proxy_set_header Host $host:$proxy_port" directive
and the appropriate proxy_redirect directives.
*) Change: the "proxy_set_x_real_ip" is canceled and must be replaced
with the "proxy_set_header X-Real-IP $remote_addr" directive.
*) Change: the "proxy_add_x_forwarded_for" is canceled and must be
replaced with
the "proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for"
directive.
*) Change: the "proxy_set_x_url" is canceled and must be replaced with
the "proxy_set_header X-URL http://$host:$server_port$request_uri"
directive.
*) Feature: the "fastcgi_param" directive.
*) Change: the "fastcgi_root", "fastcgi_set_var" and "fastcgi_params"
directive are canceled and must be replaced with the fastcgi_param
directives.
*) Feature: the "index" directive can use the variables.
*) Feature: the "index" directive can be used at http and server levels.
*) Change: the last index only in the "index" directive can be absolute.
*) Feature: the "rewrite" directive can use the variables.
*) Feature: the "internal" directive.
*) Feature: the CONTENT_LENGTH, CONTENT_TYPE, REMOTE_PORT, SERVER_ADDR,
SERVER_PORT, SERVER_PROTOCOL, DOCUMENT_ROOT, SERVER_NAME,
REQUEST_METHOD, REQUEST_URI, and REMOTE_USER variables.
*) Change: nginx now passes the invalid lines in a client request
headers or a backend response header.
*) Bugfix: if the backend did not transfer response for a long time and
the "send_timeout" was less than "proxy_read_timeout", then nginx
returned the 408 response.
*) Bugfix: the segmentation fault was occurred if the backend sent an
invalid line in response header; the bug had appeared in 0.1.26.
*) Bugfix: the segmentation fault may occurred in FastCGI fault
tolerance configuration.
*) Bugfix: the "expires" directive did not remove the previous
"Expires" and "Cache-Control" headers.
*) Bugfix: nginx did not take into account trailing dot in "Host"
header line.
*) Bugfix: the ngx_http_auth_module did not work under Linux.
*) Bugfix: the rewrite directive worked incorrectly, if the arguments
were in a request.
*) Bugfix: nginx could not be built on MacOS X.
2005-05-12 22:58:06 +08:00
|
|
|
for (n = 0, name = (ngx_str_t *) names;
|
|
|
|
n < nelts;
|
|
|
|
n++, name = (ngx_str_t *) ((char *) name + hash->bucket_size))
|
2005-04-08 23:18:55 +08:00
|
|
|
{
|
2005-12-05 21:18:09 +08:00
|
|
|
if (name->data == NULL) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2005-04-08 23:18:55 +08:00
|
|
|
key = 0;
|
|
|
|
|
nginx-0.1.29-RELEASE import
*) Feature: the ngx_http_ssi_module supports "include virtual" command.
*) Feature: the ngx_http_ssi_module supports the condition command like
'if expr="$NAME"' and "else" and "endif" commands. Only one nested
level is supported.
*) Feature: the ngx_http_ssi_module supports the DATE_LOCAL and
DATE_GMT variables and "config timefmt" command.
*) Feature: the "ssi_ignore_recycled_buffers" directive.
*) Bugfix: the "echo" command did not show the default value for the
empty QUERY_STRING variable.
*) Change: the ngx_http_proxy_module was rewritten.
*) Feature: the "proxy_redirect", "proxy_pass_request_headers",
"proxy_pass_request_body", and "proxy_method" directives.
*) Feature: the "proxy_set_header" directive. The "proxy_x_var" was
canceled and must be replaced with the proxy_set_header directive.
*) Change: the "proxy_preserve_host" is canceled and must be replaced
with the "proxy_set_header Host $host" and the "proxy_redirect off"
directives, the "proxy_set_header Host $host:$proxy_port" directive
and the appropriate proxy_redirect directives.
*) Change: the "proxy_set_x_real_ip" is canceled and must be replaced
with the "proxy_set_header X-Real-IP $remote_addr" directive.
*) Change: the "proxy_add_x_forwarded_for" is canceled and must be
replaced with
the "proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for"
directive.
*) Change: the "proxy_set_x_url" is canceled and must be replaced with
the "proxy_set_header X-URL http://$host:$server_port$request_uri"
directive.
*) Feature: the "fastcgi_param" directive.
*) Change: the "fastcgi_root", "fastcgi_set_var" and "fastcgi_params"
directive are canceled and must be replaced with the fastcgi_param
directives.
*) Feature: the "index" directive can use the variables.
*) Feature: the "index" directive can be used at http and server levels.
*) Change: the last index only in the "index" directive can be absolute.
*) Feature: the "rewrite" directive can use the variables.
*) Feature: the "internal" directive.
*) Feature: the CONTENT_LENGTH, CONTENT_TYPE, REMOTE_PORT, SERVER_ADDR,
SERVER_PORT, SERVER_PROTOCOL, DOCUMENT_ROOT, SERVER_NAME,
REQUEST_METHOD, REQUEST_URI, and REMOTE_USER variables.
*) Change: nginx now passes the invalid lines in a client request
headers or a backend response header.
*) Bugfix: if the backend did not transfer response for a long time and
the "send_timeout" was less than "proxy_read_timeout", then nginx
returned the 408 response.
*) Bugfix: the segmentation fault was occurred if the backend sent an
invalid line in response header; the bug had appeared in 0.1.26.
*) Bugfix: the segmentation fault may occurred in FastCGI fault
tolerance configuration.
*) Bugfix: the "expires" directive did not remove the previous
"Expires" and "Cache-Control" headers.
*) Bugfix: nginx did not take into account trailing dot in "Host"
header line.
*) Bugfix: the ngx_http_auth_module did not work under Linux.
*) Bugfix: the rewrite directive worked incorrectly, if the arguments
were in a request.
*) Bugfix: nginx could not be built on MacOS X.
2005-05-12 22:58:06 +08:00
|
|
|
for (i = 0; i < name->len; i++) {
|
|
|
|
key += ngx_tolower(name->data[i]);
|
2005-04-08 23:18:55 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
key %= size;
|
|
|
|
|
|
|
|
if (test[key] == hash->bucket_limit) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
test[key]++;
|
|
|
|
|
|
|
|
if (buckets < test[key]) {
|
|
|
|
buckets = test[key];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
nginx-0.1.29-RELEASE import
*) Feature: the ngx_http_ssi_module supports "include virtual" command.
*) Feature: the ngx_http_ssi_module supports the condition command like
'if expr="$NAME"' and "else" and "endif" commands. Only one nested
level is supported.
*) Feature: the ngx_http_ssi_module supports the DATE_LOCAL and
DATE_GMT variables and "config timefmt" command.
*) Feature: the "ssi_ignore_recycled_buffers" directive.
*) Bugfix: the "echo" command did not show the default value for the
empty QUERY_STRING variable.
*) Change: the ngx_http_proxy_module was rewritten.
*) Feature: the "proxy_redirect", "proxy_pass_request_headers",
"proxy_pass_request_body", and "proxy_method" directives.
*) Feature: the "proxy_set_header" directive. The "proxy_x_var" was
canceled and must be replaced with the proxy_set_header directive.
*) Change: the "proxy_preserve_host" is canceled and must be replaced
with the "proxy_set_header Host $host" and the "proxy_redirect off"
directives, the "proxy_set_header Host $host:$proxy_port" directive
and the appropriate proxy_redirect directives.
*) Change: the "proxy_set_x_real_ip" is canceled and must be replaced
with the "proxy_set_header X-Real-IP $remote_addr" directive.
*) Change: the "proxy_add_x_forwarded_for" is canceled and must be
replaced with
the "proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for"
directive.
*) Change: the "proxy_set_x_url" is canceled and must be replaced with
the "proxy_set_header X-URL http://$host:$server_port$request_uri"
directive.
*) Feature: the "fastcgi_param" directive.
*) Change: the "fastcgi_root", "fastcgi_set_var" and "fastcgi_params"
directive are canceled and must be replaced with the fastcgi_param
directives.
*) Feature: the "index" directive can use the variables.
*) Feature: the "index" directive can be used at http and server levels.
*) Change: the last index only in the "index" directive can be absolute.
*) Feature: the "rewrite" directive can use the variables.
*) Feature: the "internal" directive.
*) Feature: the CONTENT_LENGTH, CONTENT_TYPE, REMOTE_PORT, SERVER_ADDR,
SERVER_PORT, SERVER_PROTOCOL, DOCUMENT_ROOT, SERVER_NAME,
REQUEST_METHOD, REQUEST_URI, and REMOTE_USER variables.
*) Change: nginx now passes the invalid lines in a client request
headers or a backend response header.
*) Bugfix: if the backend did not transfer response for a long time and
the "send_timeout" was less than "proxy_read_timeout", then nginx
returned the 408 response.
*) Bugfix: the segmentation fault was occurred if the backend sent an
invalid line in response header; the bug had appeared in 0.1.26.
*) Bugfix: the segmentation fault may occurred in FastCGI fault
tolerance configuration.
*) Bugfix: the "expires" directive did not remove the previous
"Expires" and "Cache-Control" headers.
*) Bugfix: nginx did not take into account trailing dot in "Host"
header line.
*) Bugfix: the ngx_http_auth_module did not work under Linux.
*) Bugfix: the rewrite directive worked incorrectly, if the arguments
were in a request.
*) Bugfix: nginx could not be built on MacOS X.
2005-05-12 22:58:06 +08:00
|
|
|
if (n == nelts) {
|
2005-04-08 23:18:55 +08:00
|
|
|
if (min_buckets > buckets) {
|
|
|
|
min_buckets = buckets;
|
|
|
|
best = size;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (hash->bucket_limit == 1) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (min_buckets == hash->bucket_limit + 1) {
|
|
|
|
ngx_log_error(NGX_LOG_EMERG, pool->log, 0,
|
|
|
|
"could not build the %s hash, you should increase "
|
|
|
|
"either %s_size: %i or %s_bucket_limit: %i",
|
|
|
|
hash->name, hash->name, hash->max_size,
|
|
|
|
hash->name, hash->bucket_limit);
|
|
|
|
ngx_free(test);
|
|
|
|
return NGX_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
hash->buckets = ngx_pcalloc(pool, best * hash->bucket_size);
|
|
|
|
if (hash->buckets == NULL) {
|
|
|
|
ngx_free(test);
|
|
|
|
return NGX_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (hash->bucket_limit != 1) {
|
|
|
|
|
|
|
|
for (i = 0; i < best; i++) {
|
|
|
|
test[i] = 0;
|
|
|
|
}
|
|
|
|
|
nginx-0.1.29-RELEASE import
*) Feature: the ngx_http_ssi_module supports "include virtual" command.
*) Feature: the ngx_http_ssi_module supports the condition command like
'if expr="$NAME"' and "else" and "endif" commands. Only one nested
level is supported.
*) Feature: the ngx_http_ssi_module supports the DATE_LOCAL and
DATE_GMT variables and "config timefmt" command.
*) Feature: the "ssi_ignore_recycled_buffers" directive.
*) Bugfix: the "echo" command did not show the default value for the
empty QUERY_STRING variable.
*) Change: the ngx_http_proxy_module was rewritten.
*) Feature: the "proxy_redirect", "proxy_pass_request_headers",
"proxy_pass_request_body", and "proxy_method" directives.
*) Feature: the "proxy_set_header" directive. The "proxy_x_var" was
canceled and must be replaced with the proxy_set_header directive.
*) Change: the "proxy_preserve_host" is canceled and must be replaced
with the "proxy_set_header Host $host" and the "proxy_redirect off"
directives, the "proxy_set_header Host $host:$proxy_port" directive
and the appropriate proxy_redirect directives.
*) Change: the "proxy_set_x_real_ip" is canceled and must be replaced
with the "proxy_set_header X-Real-IP $remote_addr" directive.
*) Change: the "proxy_add_x_forwarded_for" is canceled and must be
replaced with
the "proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for"
directive.
*) Change: the "proxy_set_x_url" is canceled and must be replaced with
the "proxy_set_header X-URL http://$host:$server_port$request_uri"
directive.
*) Feature: the "fastcgi_param" directive.
*) Change: the "fastcgi_root", "fastcgi_set_var" and "fastcgi_params"
directive are canceled and must be replaced with the fastcgi_param
directives.
*) Feature: the "index" directive can use the variables.
*) Feature: the "index" directive can be used at http and server levels.
*) Change: the last index only in the "index" directive can be absolute.
*) Feature: the "rewrite" directive can use the variables.
*) Feature: the "internal" directive.
*) Feature: the CONTENT_LENGTH, CONTENT_TYPE, REMOTE_PORT, SERVER_ADDR,
SERVER_PORT, SERVER_PROTOCOL, DOCUMENT_ROOT, SERVER_NAME,
REQUEST_METHOD, REQUEST_URI, and REMOTE_USER variables.
*) Change: nginx now passes the invalid lines in a client request
headers or a backend response header.
*) Bugfix: if the backend did not transfer response for a long time and
the "send_timeout" was less than "proxy_read_timeout", then nginx
returned the 408 response.
*) Bugfix: the segmentation fault was occurred if the backend sent an
invalid line in response header; the bug had appeared in 0.1.26.
*) Bugfix: the segmentation fault may occurred in FastCGI fault
tolerance configuration.
*) Bugfix: the "expires" directive did not remove the previous
"Expires" and "Cache-Control" headers.
*) Bugfix: nginx did not take into account trailing dot in "Host"
header line.
*) Bugfix: the ngx_http_auth_module did not work under Linux.
*) Bugfix: the rewrite directive worked incorrectly, if the arguments
were in a request.
*) Bugfix: nginx could not be built on MacOS X.
2005-05-12 22:58:06 +08:00
|
|
|
for (n = 0, name = (ngx_str_t *) names;
|
|
|
|
n < nelts;
|
|
|
|
n++, name = (ngx_str_t *) ((char *) name + hash->bucket_size))
|
2005-04-08 23:18:55 +08:00
|
|
|
{
|
2005-12-05 21:18:09 +08:00
|
|
|
if (name->data == NULL) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2005-04-08 23:18:55 +08:00
|
|
|
key = 0;
|
|
|
|
|
nginx-0.1.29-RELEASE import
*) Feature: the ngx_http_ssi_module supports "include virtual" command.
*) Feature: the ngx_http_ssi_module supports the condition command like
'if expr="$NAME"' and "else" and "endif" commands. Only one nested
level is supported.
*) Feature: the ngx_http_ssi_module supports the DATE_LOCAL and
DATE_GMT variables and "config timefmt" command.
*) Feature: the "ssi_ignore_recycled_buffers" directive.
*) Bugfix: the "echo" command did not show the default value for the
empty QUERY_STRING variable.
*) Change: the ngx_http_proxy_module was rewritten.
*) Feature: the "proxy_redirect", "proxy_pass_request_headers",
"proxy_pass_request_body", and "proxy_method" directives.
*) Feature: the "proxy_set_header" directive. The "proxy_x_var" was
canceled and must be replaced with the proxy_set_header directive.
*) Change: the "proxy_preserve_host" is canceled and must be replaced
with the "proxy_set_header Host $host" and the "proxy_redirect off"
directives, the "proxy_set_header Host $host:$proxy_port" directive
and the appropriate proxy_redirect directives.
*) Change: the "proxy_set_x_real_ip" is canceled and must be replaced
with the "proxy_set_header X-Real-IP $remote_addr" directive.
*) Change: the "proxy_add_x_forwarded_for" is canceled and must be
replaced with
the "proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for"
directive.
*) Change: the "proxy_set_x_url" is canceled and must be replaced with
the "proxy_set_header X-URL http://$host:$server_port$request_uri"
directive.
*) Feature: the "fastcgi_param" directive.
*) Change: the "fastcgi_root", "fastcgi_set_var" and "fastcgi_params"
directive are canceled and must be replaced with the fastcgi_param
directives.
*) Feature: the "index" directive can use the variables.
*) Feature: the "index" directive can be used at http and server levels.
*) Change: the last index only in the "index" directive can be absolute.
*) Feature: the "rewrite" directive can use the variables.
*) Feature: the "internal" directive.
*) Feature: the CONTENT_LENGTH, CONTENT_TYPE, REMOTE_PORT, SERVER_ADDR,
SERVER_PORT, SERVER_PROTOCOL, DOCUMENT_ROOT, SERVER_NAME,
REQUEST_METHOD, REQUEST_URI, and REMOTE_USER variables.
*) Change: nginx now passes the invalid lines in a client request
headers or a backend response header.
*) Bugfix: if the backend did not transfer response for a long time and
the "send_timeout" was less than "proxy_read_timeout", then nginx
returned the 408 response.
*) Bugfix: the segmentation fault was occurred if the backend sent an
invalid line in response header; the bug had appeared in 0.1.26.
*) Bugfix: the segmentation fault may occurred in FastCGI fault
tolerance configuration.
*) Bugfix: the "expires" directive did not remove the previous
"Expires" and "Cache-Control" headers.
*) Bugfix: nginx did not take into account trailing dot in "Host"
header line.
*) Bugfix: the ngx_http_auth_module did not work under Linux.
*) Bugfix: the rewrite directive worked incorrectly, if the arguments
were in a request.
*) Bugfix: nginx could not be built on MacOS X.
2005-05-12 22:58:06 +08:00
|
|
|
for (i = 0; i < name->len; i++) {
|
|
|
|
key += ngx_tolower(name->data[i]);
|
2005-04-08 23:18:55 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
key %= best;
|
|
|
|
|
|
|
|
test[key]++;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < best; i++) {
|
|
|
|
if (test[i] == 0) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
bucket = ngx_palloc(pool, test[i] * hash->bucket_size);
|
|
|
|
if (bucket == NULL) {
|
|
|
|
ngx_free(test);
|
|
|
|
return NGX_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
hash->buckets[i] = bucket;
|
|
|
|
bucket->len = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
nginx-0.1.29-RELEASE import
*) Feature: the ngx_http_ssi_module supports "include virtual" command.
*) Feature: the ngx_http_ssi_module supports the condition command like
'if expr="$NAME"' and "else" and "endif" commands. Only one nested
level is supported.
*) Feature: the ngx_http_ssi_module supports the DATE_LOCAL and
DATE_GMT variables and "config timefmt" command.
*) Feature: the "ssi_ignore_recycled_buffers" directive.
*) Bugfix: the "echo" command did not show the default value for the
empty QUERY_STRING variable.
*) Change: the ngx_http_proxy_module was rewritten.
*) Feature: the "proxy_redirect", "proxy_pass_request_headers",
"proxy_pass_request_body", and "proxy_method" directives.
*) Feature: the "proxy_set_header" directive. The "proxy_x_var" was
canceled and must be replaced with the proxy_set_header directive.
*) Change: the "proxy_preserve_host" is canceled and must be replaced
with the "proxy_set_header Host $host" and the "proxy_redirect off"
directives, the "proxy_set_header Host $host:$proxy_port" directive
and the appropriate proxy_redirect directives.
*) Change: the "proxy_set_x_real_ip" is canceled and must be replaced
with the "proxy_set_header X-Real-IP $remote_addr" directive.
*) Change: the "proxy_add_x_forwarded_for" is canceled and must be
replaced with
the "proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for"
directive.
*) Change: the "proxy_set_x_url" is canceled and must be replaced with
the "proxy_set_header X-URL http://$host:$server_port$request_uri"
directive.
*) Feature: the "fastcgi_param" directive.
*) Change: the "fastcgi_root", "fastcgi_set_var" and "fastcgi_params"
directive are canceled and must be replaced with the fastcgi_param
directives.
*) Feature: the "index" directive can use the variables.
*) Feature: the "index" directive can be used at http and server levels.
*) Change: the last index only in the "index" directive can be absolute.
*) Feature: the "rewrite" directive can use the variables.
*) Feature: the "internal" directive.
*) Feature: the CONTENT_LENGTH, CONTENT_TYPE, REMOTE_PORT, SERVER_ADDR,
SERVER_PORT, SERVER_PROTOCOL, DOCUMENT_ROOT, SERVER_NAME,
REQUEST_METHOD, REQUEST_URI, and REMOTE_USER variables.
*) Change: nginx now passes the invalid lines in a client request
headers or a backend response header.
*) Bugfix: if the backend did not transfer response for a long time and
the "send_timeout" was less than "proxy_read_timeout", then nginx
returned the 408 response.
*) Bugfix: the segmentation fault was occurred if the backend sent an
invalid line in response header; the bug had appeared in 0.1.26.
*) Bugfix: the segmentation fault may occurred in FastCGI fault
tolerance configuration.
*) Bugfix: the "expires" directive did not remove the previous
"Expires" and "Cache-Control" headers.
*) Bugfix: nginx did not take into account trailing dot in "Host"
header line.
*) Bugfix: the ngx_http_auth_module did not work under Linux.
*) Bugfix: the rewrite directive worked incorrectly, if the arguments
were in a request.
*) Bugfix: nginx could not be built on MacOS X.
2005-05-12 22:58:06 +08:00
|
|
|
for (n = 0, name = (ngx_str_t *) names;
|
|
|
|
n < nelts;
|
|
|
|
n++, name = (ngx_str_t *) ((char *) name + hash->bucket_size))
|
2005-04-08 23:18:55 +08:00
|
|
|
{
|
2005-12-05 21:18:09 +08:00
|
|
|
if (name->data == NULL) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2005-04-08 23:18:55 +08:00
|
|
|
key = 0;
|
|
|
|
|
nginx-0.1.29-RELEASE import
*) Feature: the ngx_http_ssi_module supports "include virtual" command.
*) Feature: the ngx_http_ssi_module supports the condition command like
'if expr="$NAME"' and "else" and "endif" commands. Only one nested
level is supported.
*) Feature: the ngx_http_ssi_module supports the DATE_LOCAL and
DATE_GMT variables and "config timefmt" command.
*) Feature: the "ssi_ignore_recycled_buffers" directive.
*) Bugfix: the "echo" command did not show the default value for the
empty QUERY_STRING variable.
*) Change: the ngx_http_proxy_module was rewritten.
*) Feature: the "proxy_redirect", "proxy_pass_request_headers",
"proxy_pass_request_body", and "proxy_method" directives.
*) Feature: the "proxy_set_header" directive. The "proxy_x_var" was
canceled and must be replaced with the proxy_set_header directive.
*) Change: the "proxy_preserve_host" is canceled and must be replaced
with the "proxy_set_header Host $host" and the "proxy_redirect off"
directives, the "proxy_set_header Host $host:$proxy_port" directive
and the appropriate proxy_redirect directives.
*) Change: the "proxy_set_x_real_ip" is canceled and must be replaced
with the "proxy_set_header X-Real-IP $remote_addr" directive.
*) Change: the "proxy_add_x_forwarded_for" is canceled and must be
replaced with
the "proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for"
directive.
*) Change: the "proxy_set_x_url" is canceled and must be replaced with
the "proxy_set_header X-URL http://$host:$server_port$request_uri"
directive.
*) Feature: the "fastcgi_param" directive.
*) Change: the "fastcgi_root", "fastcgi_set_var" and "fastcgi_params"
directive are canceled and must be replaced with the fastcgi_param
directives.
*) Feature: the "index" directive can use the variables.
*) Feature: the "index" directive can be used at http and server levels.
*) Change: the last index only in the "index" directive can be absolute.
*) Feature: the "rewrite" directive can use the variables.
*) Feature: the "internal" directive.
*) Feature: the CONTENT_LENGTH, CONTENT_TYPE, REMOTE_PORT, SERVER_ADDR,
SERVER_PORT, SERVER_PROTOCOL, DOCUMENT_ROOT, SERVER_NAME,
REQUEST_METHOD, REQUEST_URI, and REMOTE_USER variables.
*) Change: nginx now passes the invalid lines in a client request
headers or a backend response header.
*) Bugfix: if the backend did not transfer response for a long time and
the "send_timeout" was less than "proxy_read_timeout", then nginx
returned the 408 response.
*) Bugfix: the segmentation fault was occurred if the backend sent an
invalid line in response header; the bug had appeared in 0.1.26.
*) Bugfix: the segmentation fault may occurred in FastCGI fault
tolerance configuration.
*) Bugfix: the "expires" directive did not remove the previous
"Expires" and "Cache-Control" headers.
*) Bugfix: nginx did not take into account trailing dot in "Host"
header line.
*) Bugfix: the ngx_http_auth_module did not work under Linux.
*) Bugfix: the rewrite directive worked incorrectly, if the arguments
were in a request.
*) Bugfix: nginx could not be built on MacOS X.
2005-05-12 22:58:06 +08:00
|
|
|
for (i = 0; i < name->len; i++) {
|
|
|
|
key += ngx_tolower(name->data[i]);
|
2005-04-08 23:18:55 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
key %= best;
|
|
|
|
|
|
|
|
if (hash->bucket_limit == 1) {
|
|
|
|
p = (u_char *) hash->buckets + key * hash->bucket_size;
|
nginx-0.1.29-RELEASE import
*) Feature: the ngx_http_ssi_module supports "include virtual" command.
*) Feature: the ngx_http_ssi_module supports the condition command like
'if expr="$NAME"' and "else" and "endif" commands. Only one nested
level is supported.
*) Feature: the ngx_http_ssi_module supports the DATE_LOCAL and
DATE_GMT variables and "config timefmt" command.
*) Feature: the "ssi_ignore_recycled_buffers" directive.
*) Bugfix: the "echo" command did not show the default value for the
empty QUERY_STRING variable.
*) Change: the ngx_http_proxy_module was rewritten.
*) Feature: the "proxy_redirect", "proxy_pass_request_headers",
"proxy_pass_request_body", and "proxy_method" directives.
*) Feature: the "proxy_set_header" directive. The "proxy_x_var" was
canceled and must be replaced with the proxy_set_header directive.
*) Change: the "proxy_preserve_host" is canceled and must be replaced
with the "proxy_set_header Host $host" and the "proxy_redirect off"
directives, the "proxy_set_header Host $host:$proxy_port" directive
and the appropriate proxy_redirect directives.
*) Change: the "proxy_set_x_real_ip" is canceled and must be replaced
with the "proxy_set_header X-Real-IP $remote_addr" directive.
*) Change: the "proxy_add_x_forwarded_for" is canceled and must be
replaced with
the "proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for"
directive.
*) Change: the "proxy_set_x_url" is canceled and must be replaced with
the "proxy_set_header X-URL http://$host:$server_port$request_uri"
directive.
*) Feature: the "fastcgi_param" directive.
*) Change: the "fastcgi_root", "fastcgi_set_var" and "fastcgi_params"
directive are canceled and must be replaced with the fastcgi_param
directives.
*) Feature: the "index" directive can use the variables.
*) Feature: the "index" directive can be used at http and server levels.
*) Change: the last index only in the "index" directive can be absolute.
*) Feature: the "rewrite" directive can use the variables.
*) Feature: the "internal" directive.
*) Feature: the CONTENT_LENGTH, CONTENT_TYPE, REMOTE_PORT, SERVER_ADDR,
SERVER_PORT, SERVER_PROTOCOL, DOCUMENT_ROOT, SERVER_NAME,
REQUEST_METHOD, REQUEST_URI, and REMOTE_USER variables.
*) Change: nginx now passes the invalid lines in a client request
headers or a backend response header.
*) Bugfix: if the backend did not transfer response for a long time and
the "send_timeout" was less than "proxy_read_timeout", then nginx
returned the 408 response.
*) Bugfix: the segmentation fault was occurred if the backend sent an
invalid line in response header; the bug had appeared in 0.1.26.
*) Bugfix: the segmentation fault may occurred in FastCGI fault
tolerance configuration.
*) Bugfix: the "expires" directive did not remove the previous
"Expires" and "Cache-Control" headers.
*) Bugfix: nginx did not take into account trailing dot in "Host"
header line.
*) Bugfix: the ngx_http_auth_module did not work under Linux.
*) Bugfix: the rewrite directive worked incorrectly, if the arguments
were in a request.
*) Bugfix: nginx could not be built on MacOS X.
2005-05-12 22:58:06 +08:00
|
|
|
ngx_memcpy(p, name, hash->bucket_size);
|
2005-04-08 23:18:55 +08:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (bucket = hash->buckets[key];
|
|
|
|
bucket->len;
|
|
|
|
bucket = (ngx_str_t *) ((char *) bucket + hash->bucket_size))
|
|
|
|
{
|
|
|
|
bucket->len &= 0x7fffffff;
|
|
|
|
}
|
|
|
|
|
nginx-0.1.29-RELEASE import
*) Feature: the ngx_http_ssi_module supports "include virtual" command.
*) Feature: the ngx_http_ssi_module supports the condition command like
'if expr="$NAME"' and "else" and "endif" commands. Only one nested
level is supported.
*) Feature: the ngx_http_ssi_module supports the DATE_LOCAL and
DATE_GMT variables and "config timefmt" command.
*) Feature: the "ssi_ignore_recycled_buffers" directive.
*) Bugfix: the "echo" command did not show the default value for the
empty QUERY_STRING variable.
*) Change: the ngx_http_proxy_module was rewritten.
*) Feature: the "proxy_redirect", "proxy_pass_request_headers",
"proxy_pass_request_body", and "proxy_method" directives.
*) Feature: the "proxy_set_header" directive. The "proxy_x_var" was
canceled and must be replaced with the proxy_set_header directive.
*) Change: the "proxy_preserve_host" is canceled and must be replaced
with the "proxy_set_header Host $host" and the "proxy_redirect off"
directives, the "proxy_set_header Host $host:$proxy_port" directive
and the appropriate proxy_redirect directives.
*) Change: the "proxy_set_x_real_ip" is canceled and must be replaced
with the "proxy_set_header X-Real-IP $remote_addr" directive.
*) Change: the "proxy_add_x_forwarded_for" is canceled and must be
replaced with
the "proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for"
directive.
*) Change: the "proxy_set_x_url" is canceled and must be replaced with
the "proxy_set_header X-URL http://$host:$server_port$request_uri"
directive.
*) Feature: the "fastcgi_param" directive.
*) Change: the "fastcgi_root", "fastcgi_set_var" and "fastcgi_params"
directive are canceled and must be replaced with the fastcgi_param
directives.
*) Feature: the "index" directive can use the variables.
*) Feature: the "index" directive can be used at http and server levels.
*) Change: the last index only in the "index" directive can be absolute.
*) Feature: the "rewrite" directive can use the variables.
*) Feature: the "internal" directive.
*) Feature: the CONTENT_LENGTH, CONTENT_TYPE, REMOTE_PORT, SERVER_ADDR,
SERVER_PORT, SERVER_PROTOCOL, DOCUMENT_ROOT, SERVER_NAME,
REQUEST_METHOD, REQUEST_URI, and REMOTE_USER variables.
*) Change: nginx now passes the invalid lines in a client request
headers or a backend response header.
*) Bugfix: if the backend did not transfer response for a long time and
the "send_timeout" was less than "proxy_read_timeout", then nginx
returned the 408 response.
*) Bugfix: the segmentation fault was occurred if the backend sent an
invalid line in response header; the bug had appeared in 0.1.26.
*) Bugfix: the segmentation fault may occurred in FastCGI fault
tolerance configuration.
*) Bugfix: the "expires" directive did not remove the previous
"Expires" and "Cache-Control" headers.
*) Bugfix: nginx did not take into account trailing dot in "Host"
header line.
*) Bugfix: the ngx_http_auth_module did not work under Linux.
*) Bugfix: the rewrite directive worked incorrectly, if the arguments
were in a request.
*) Bugfix: nginx could not be built on MacOS X.
2005-05-12 22:58:06 +08:00
|
|
|
ngx_memcpy(bucket, name, hash->bucket_size);
|
2005-04-08 23:18:55 +08:00
|
|
|
bucket->len |= 0x80000000;
|
|
|
|
}
|
|
|
|
|
|
|
|
ngx_free(test);
|
|
|
|
|
|
|
|
hash->hash_size = best;
|
|
|
|
hash->min_buckets = min_buckets;
|
|
|
|
|
|
|
|
return NGX_OK;
|
|
|
|
}
|
2005-12-27 01:07:48 +08:00
|
|
|
|
|
|
|
|
|
|
|
ngx_int_t
|
|
|
|
ngx_hash_keys_array_init(ngx_hash_keys_arrays_t *ha, ngx_uint_t type)
|
|
|
|
{
|
|
|
|
ngx_uint_t asize;
|
|
|
|
|
|
|
|
if (type == NGX_HASH_SMALL) {
|
|
|
|
asize = 4;
|
|
|
|
ha->hsize = 107;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
asize = NGX_HASH_LARGE_ASIZE;
|
|
|
|
ha->hsize = NGX_HASH_LARGE_HSIZE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ngx_array_init(&ha->keys, ha->temp_pool, asize, sizeof(ngx_hash_key_t))
|
|
|
|
!= NGX_OK)
|
|
|
|
{
|
|
|
|
return NGX_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ngx_array_init(&ha->dns_wildcards, ha->temp_pool, asize,
|
|
|
|
sizeof(ngx_hash_key_t))
|
|
|
|
!= NGX_OK)
|
|
|
|
{
|
|
|
|
return NGX_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
ha->keys_hash = ngx_pcalloc(ha->temp_pool, sizeof(ngx_array_t) * ha->hsize);
|
|
|
|
if (ha->keys_hash == NULL) {
|
|
|
|
return NGX_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
ha->dns_wildcards_hash = ngx_pcalloc(ha->temp_pool,
|
|
|
|
sizeof(ngx_array_t) * ha->hsize);
|
|
|
|
if (ha->dns_wildcards_hash == NULL) {
|
|
|
|
return NGX_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NGX_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ngx_int_t
|
|
|
|
ngx_hash_add_key(ngx_hash_keys_arrays_t *ha, ngx_str_t *key, void *value,
|
|
|
|
ngx_uint_t flags)
|
|
|
|
{
|
|
|
|
size_t len;
|
|
|
|
ngx_str_t *name;
|
|
|
|
ngx_uint_t i, k, n, skip;
|
|
|
|
ngx_hash_key_t *hk;
|
|
|
|
u_char buf[2048];
|
|
|
|
|
|
|
|
if (!(flags & NGX_HASH_WILDCARD_KEY)) {
|
|
|
|
|
|
|
|
/* exact hash */
|
|
|
|
|
|
|
|
k = 0;
|
|
|
|
|
|
|
|
for (i = 0; i < key->len; i++) {
|
2006-01-11 23:26:57 +08:00
|
|
|
if (!(flags & NGX_HASH_READONLY_KEY)) {
|
|
|
|
key->data[i] = ngx_tolower(key->data[i]);
|
|
|
|
}
|
2005-12-27 01:07:48 +08:00
|
|
|
k = ngx_hash(k, key->data[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
k %= ha->hsize;
|
|
|
|
|
|
|
|
/* check conflicts in exact hash */
|
|
|
|
|
|
|
|
name = ha->keys_hash[k].elts;
|
|
|
|
|
|
|
|
if (name) {
|
|
|
|
for (i = 0; i < ha->keys_hash[k].nelts; i++) {
|
|
|
|
if (key->len != name[i].len) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ngx_strncmp(key->data, name[i].data, key->len) == 0) {
|
|
|
|
return NGX_BUSY;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
if (ngx_array_init(&ha->keys_hash[k], ha->temp_pool, 4,
|
|
|
|
sizeof(ngx_str_t))
|
|
|
|
!= NGX_OK)
|
|
|
|
{
|
|
|
|
return NGX_ERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
name = ngx_array_push(&ha->keys_hash[k]);
|
|
|
|
if (name == NULL) {
|
|
|
|
return NGX_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
*name = *key;
|
|
|
|
|
|
|
|
hk = ngx_array_push(&ha->keys);
|
|
|
|
if (hk == NULL) {
|
|
|
|
return NGX_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
hk->key = *key;
|
|
|
|
hk->key_hash = ngx_hash_key(key->data, key->len);
|
|
|
|
hk->value = value;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
/* wildcard hash */
|
|
|
|
|
|
|
|
skip = (key->data[0] == '*') ? 2 : 1;
|
|
|
|
k = 0;
|
|
|
|
|
|
|
|
for (i = skip; i < key->len; i++) {
|
|
|
|
key->data[i] = ngx_tolower(key->data[i]);
|
|
|
|
k = ngx_hash(k, key->data[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
k %= ha->hsize;
|
|
|
|
|
|
|
|
if (skip == 1) {
|
|
|
|
|
|
|
|
/* check conflicts in exact hash for ".example.com" */
|
|
|
|
|
|
|
|
name = ha->keys_hash[k].elts;
|
|
|
|
|
|
|
|
if (name) {
|
|
|
|
len = key->len - skip;
|
|
|
|
|
|
|
|
for (i = 0; i < ha->keys_hash[k].nelts; i++) {
|
|
|
|
if (len != name[i].len) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ngx_strncmp(&key->data[1], name[i].data, len) == 0) {
|
|
|
|
return NGX_BUSY;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
if (ngx_array_init(&ha->keys_hash[k], ha->temp_pool, 4,
|
|
|
|
sizeof(ngx_str_t))
|
|
|
|
!= NGX_OK)
|
|
|
|
{
|
|
|
|
return NGX_ERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
name = ngx_array_push(&ha->keys_hash[k]);
|
|
|
|
if (name == NULL) {
|
|
|
|
return NGX_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
name->len = key->len - 1;
|
|
|
|
name->data = ngx_palloc(ha->temp_pool, name->len);
|
|
|
|
if (name->data == NULL) {
|
|
|
|
return NGX_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
ngx_memcpy(name->data, &key->data[1], name->len);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* convert "*.example.com" to "com.example.\0"
|
|
|
|
* and ".example.com" to "com.example\0"
|
|
|
|
*/
|
|
|
|
|
|
|
|
len = 0;
|
|
|
|
n = 0;
|
|
|
|
|
|
|
|
for (i = key->len - 1; i; i--) {
|
|
|
|
if (key->data[i] == '.') {
|
|
|
|
ngx_memcpy(&buf[n], &key->data[i + 1], len);
|
|
|
|
n += len;
|
|
|
|
buf[n++] = '.';
|
|
|
|
len = 0;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
len++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (len) {
|
|
|
|
ngx_memcpy(&buf[n], &key->data[1], len);
|
|
|
|
n += len;
|
|
|
|
}
|
|
|
|
|
|
|
|
buf[n] = '\0';
|
|
|
|
|
|
|
|
|
|
|
|
/* check conflicts in wildcard hash */
|
|
|
|
|
|
|
|
name = ha->dns_wildcards_hash[k].elts;
|
|
|
|
|
|
|
|
if (name) {
|
|
|
|
len = key->len - skip;
|
|
|
|
|
|
|
|
for (i = 0; i < ha->dns_wildcards_hash[k].nelts; i++) {
|
|
|
|
if (len != name[i].len) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ngx_strncmp(key->data + skip, name[i].data, len) == 0) {
|
|
|
|
return NGX_BUSY;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
if (ngx_array_init(&ha->dns_wildcards_hash[k], ha->temp_pool, 4,
|
|
|
|
sizeof(ngx_str_t))
|
|
|
|
!= NGX_OK)
|
|
|
|
{
|
|
|
|
return NGX_ERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
name = ngx_array_push(&ha->dns_wildcards_hash[k]);
|
|
|
|
if (name == NULL) {
|
|
|
|
return NGX_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
name->len = key->len - skip;
|
|
|
|
name->data = ngx_palloc(ha->temp_pool, name->len);
|
|
|
|
if (name->data == NULL) {
|
|
|
|
return NGX_ERROR;
|
|
|
|
}
|
|
|
|
ngx_memcpy(name->data, key->data + skip, name->len);
|
|
|
|
|
|
|
|
|
|
|
|
ngx_memcpy(key->data, buf, key->len);
|
|
|
|
key->len--;
|
|
|
|
|
|
|
|
hk = ngx_array_push(&ha->dns_wildcards);
|
|
|
|
if (hk == NULL) {
|
|
|
|
return NGX_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
hk->key = *key;
|
|
|
|
hk->key_hash = 0;
|
|
|
|
hk->value = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NGX_OK;
|
|
|
|
}
|