Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nginx/nginx.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/http/ngx_http_config.c')
-rw-r--r--src/http/ngx_http_config.c214
1 files changed, 214 insertions, 0 deletions
diff --git a/src/http/ngx_http_config.c b/src/http/ngx_http_config.c
new file mode 100644
index 000000000..965625d64
--- /dev/null
+++ b/src/http/ngx_http_config.c
@@ -0,0 +1,214 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_event.h>
+#include <ngx_http.h>
+
+
+ngx_int_t
+ngx_http_config_add_hash(ngx_http_hash_conf_t *h, 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_HTTP_WILDCARD_HASH)) {
+
+ /* exact hash */
+
+ k = 0;
+
+ for (i = 0; i < key->len; i++) {
+ key->data[i] = ngx_tolower(key->data[i]);
+ k = ngx_hash(k, key->data[i]);
+ }
+
+ k %= NGX_HTTP_CONFIG_HASH;
+
+ /* check conflicts in exact hash */
+
+ name = h->keys_hash[k].elts;
+
+ if (name) {
+ for (i = 0; i < h->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(&h->keys_hash[k], h->temp_pool, 4,
+ sizeof(ngx_str_t))
+ != NGX_OK)
+ {
+ return NGX_ERROR;
+ }
+ }
+
+ name = ngx_array_push(&h->keys_hash[k]);
+ if (name == NULL) {
+ return NGX_ERROR;
+ }
+
+ *name = *key;
+
+ hk = ngx_array_push(&h->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 %= NGX_HTTP_CONFIG_HASH;
+
+ if (skip == 1) {
+
+ /* check conflicts in exact hash for ".example.com" */
+
+ name = h->keys_hash[k].elts;
+
+ if (name) {
+ len = key->len - skip;
+
+ for (i = 0; i < h->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(&h->keys_hash[k], h->temp_pool, 4,
+ sizeof(ngx_str_t))
+ != NGX_OK)
+ {
+ return NGX_ERROR;
+ }
+ }
+
+ name = ngx_array_push(&h->keys_hash[k]);
+ if (name == NULL) {
+ return NGX_ERROR;
+ }
+
+ name->len = key->len - 1;
+ name->data = ngx_palloc(h->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 = h->dns_hash[k].elts;
+
+ if (name) {
+ len = key->len - skip;
+
+ for (i = 0; i < h->dns_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(&h->dns_hash[k], h->temp_pool, 4,
+ sizeof(ngx_str_t))
+ != NGX_OK)
+ {
+ return NGX_ERROR;
+ }
+ }
+
+ name = ngx_array_push(&h->dns_hash[k]);
+ if (name == NULL) {
+ return NGX_ERROR;
+ }
+
+ name->len = key->len - skip;
+ name->data = ngx_palloc(h->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(&h->dns_wildcards);
+ if (hk == NULL) {
+ return NGX_ERROR;
+ }
+
+ hk->key = *key;
+ hk->key_hash = 0;
+ hk->value = value;
+ }
+
+ return NGX_OK;
+}