Mercurial > hg > nginx
annotate src/core/ngx_hash.c @ 9320:cf73b65983c2 default tip
release-1.27.3 tag
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Tue, 13 Aug 2024 17:26:33 +0300 |
parents | 2a7155733855 |
children |
rev | line source |
---|---|
507 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4412 | 4 * Copyright (C) Nginx, Inc. |
507 | 5 */ |
6 | |
7 | |
8 #include <ngx_config.h> | |
9 #include <ngx_core.h> | |
10 | |
11 | |
589 | 12 void * |
13 ngx_hash_find(ngx_hash_t *hash, ngx_uint_t key, u_char *name, size_t len) | |
14 { | |
15 ngx_uint_t i; | |
16 ngx_hash_elt_t *elt; | |
17 | |
18 #if 0 | |
2155 | 19 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "hf:\"%*s\"", len, name); |
589 | 20 #endif |
21 | |
22 elt = hash->buckets[key % hash->size]; | |
23 | |
24 if (elt == NULL) { | |
25 return NULL; | |
26 } | |
27 | |
28 while (elt->value) { | |
29 if (len != (size_t) elt->len) { | |
30 goto next; | |
31 } | |
32 | |
33 for (i = 0; i < len; i++) { | |
34 if (name[i] != elt->name[i]) { | |
35 goto next; | |
36 } | |
37 } | |
38 | |
39 return elt->value; | |
40 | |
41 next: | |
42 | |
43 elt = (ngx_hash_elt_t *) ngx_align_ptr(&elt->name[0] + elt->len, | |
44 sizeof(void *)); | |
45 continue; | |
46 } | |
47 | |
48 return NULL; | |
49 } | |
50 | |
51 | |
52 void * | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
53 ngx_hash_find_wc_head(ngx_hash_wildcard_t *hwc, u_char *name, size_t len) |
589 | 54 { |
55 void *value; | |
56 ngx_uint_t i, n, key; | |
57 | |
58 #if 0 | |
2155 | 59 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "wch:\"%*s\"", len, name); |
589 | 60 #endif |
61 | |
62 n = len; | |
63 | |
64 while (n) { | |
65 if (name[n - 1] == '.') { | |
66 break; | |
67 } | |
68 | |
69 n--; | |
70 } | |
71 | |
72 key = 0; | |
73 | |
74 for (i = n; i < len; i++) { | |
75 key = ngx_hash(key, name[i]); | |
76 } | |
77 | |
78 #if 0 | |
79 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "key:\"%ui\"", key); | |
80 #endif | |
81 | |
82 value = ngx_hash_find(&hwc->hash, key, &name[n], len - n); | |
83 | |
2149 | 84 #if 0 |
85 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "value:\"%p\"", value); | |
86 #endif | |
87 | |
589 | 88 if (value) { |
591 | 89 |
90 /* | |
91 * the 2 low bits of value have the special meaning: | |
2168
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
92 * 00 - value is data pointer for both "example.com" |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
93 * and "*.example.com"; |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
94 * 01 - value is data pointer for "*.example.com" only; |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
95 * 10 - value is pointer to wildcard hash allowing |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
96 * both "example.com" and "*.example.com"; |
591 | 97 * 11 - value is pointer to wildcard hash allowing |
2168
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
98 * "*.example.com" only. |
591 | 99 */ |
100 | |
2168
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
101 if ((uintptr_t) value & 2) { |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
102 |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
103 if (n == 0) { |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
104 |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
105 /* "example.com" */ |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
106 |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
107 if ((uintptr_t) value & 1) { |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
108 return NULL; |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
109 } |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
110 |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
111 hwc = (ngx_hash_wildcard_t *) |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
112 ((uintptr_t) value & (uintptr_t) ~3); |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
113 return hwc->value; |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
114 } |
591 | 115 |
116 hwc = (ngx_hash_wildcard_t *) ((uintptr_t) value & (uintptr_t) ~3); | |
117 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
118 value = ngx_hash_find_wc_head(hwc, name, n - 1); |
589 | 119 |
120 if (value) { | |
121 return value; | |
122 } | |
123 | |
124 return hwc->value; | |
125 } | |
126 | |
2168
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
127 if ((uintptr_t) value & 1) { |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
128 |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
129 if (n == 0) { |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
130 |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
131 /* "example.com" */ |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
132 |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
133 return NULL; |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
134 } |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
135 |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
136 return (void *) ((uintptr_t) value & (uintptr_t) ~3); |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
137 } |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
138 |
589 | 139 return value; |
140 } | |
141 | |
142 return hwc->value; | |
143 } | |
144 | |
145 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
146 void * |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
147 ngx_hash_find_wc_tail(ngx_hash_wildcard_t *hwc, u_char *name, size_t len) |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
148 { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
149 void *value; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
150 ngx_uint_t i, key; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
151 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
152 #if 0 |
2155 | 153 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "wct:\"%*s\"", len, name); |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
154 #endif |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
155 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
156 key = 0; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
157 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
158 for (i = 0; i < len; i++) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
159 if (name[i] == '.') { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
160 break; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
161 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
162 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
163 key = ngx_hash(key, name[i]); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
164 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
165 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
166 if (i == len) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
167 return NULL; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
168 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
169 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
170 #if 0 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
171 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "key:\"%ui\"", key); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
172 #endif |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
173 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
174 value = ngx_hash_find(&hwc->hash, key, name, i); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
175 |
2155 | 176 #if 0 |
177 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "value:\"%p\"", value); | |
178 #endif | |
179 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
180 if (value) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
181 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
182 /* |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
183 * the 2 low bits of value have the special meaning: |
2168
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
184 * 00 - value is data pointer; |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
185 * 11 - value is pointer to wildcard hash allowing "example.*". |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
186 */ |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
187 |
2168
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
188 if ((uintptr_t) value & 2) { |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
189 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
190 i++; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
191 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
192 hwc = (ngx_hash_wildcard_t *) ((uintptr_t) value & (uintptr_t) ~3); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
193 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
194 value = ngx_hash_find_wc_tail(hwc, &name[i], len - i); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
195 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
196 if (value) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
197 return value; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
198 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
199 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
200 return hwc->value; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
201 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
202 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
203 return value; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
204 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
205 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
206 return hwc->value; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
207 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
208 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
209 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
210 void * |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
211 ngx_hash_find_combined(ngx_hash_combined_t *hash, ngx_uint_t key, u_char *name, |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
212 size_t len) |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
213 { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
214 void *value; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
215 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
216 if (hash->hash.buckets) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
217 value = ngx_hash_find(&hash->hash, key, name, len); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
218 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
219 if (value) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
220 return value; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
221 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
222 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
223 |
2195 | 224 if (len == 0) { |
225 return NULL; | |
226 } | |
227 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
228 if (hash->wc_head && hash->wc_head->hash.buckets) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
229 value = ngx_hash_find_wc_head(hash->wc_head, name, len); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
230 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
231 if (value) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
232 return value; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
233 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
234 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
235 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
236 if (hash->wc_tail && hash->wc_tail->hash.buckets) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
237 value = ngx_hash_find_wc_tail(hash->wc_tail, name, len); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
238 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
239 if (value) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
240 return value; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
241 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
242 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
243 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
244 return NULL; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
245 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
246 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
247 |
589 | 248 #define NGX_HASH_ELT_SIZE(name) \ |
3510
4c70bbdfd076
allow hash key values more than 255 bytes, it does not actually increase mean
Igor Sysoev <igor@sysoev.ru>
parents:
3118
diff
changeset
|
249 (sizeof(void *) + ngx_align((name)->key.len + 2, sizeof(void *))) |
589 | 250 |
507 | 251 ngx_int_t |
589 | 252 ngx_hash_init(ngx_hash_init_t *hinit, ngx_hash_key_t *names, ngx_uint_t nelts) |
253 { | |
254 u_char *elts; | |
595 | 255 size_t len; |
256 u_short *test; | |
589 | 257 ngx_uint_t i, n, key, size, start, bucket_size; |
258 ngx_hash_elt_t *elt, **buckets; | |
259 | |
6225
3b6d69857de2
Core: fixed potential division by zero when initializing hash.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6224
diff
changeset
|
260 if (hinit->max_size == 0) { |
3b6d69857de2
Core: fixed potential division by zero when initializing hash.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6224
diff
changeset
|
261 ngx_log_error(NGX_LOG_EMERG, hinit->pool->log, 0, |
3b6d69857de2
Core: fixed potential division by zero when initializing hash.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6224
diff
changeset
|
262 "could not build %s, you should " |
3b6d69857de2
Core: fixed potential division by zero when initializing hash.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6224
diff
changeset
|
263 "increase %s_max_size: %i", |
3b6d69857de2
Core: fixed potential division by zero when initializing hash.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6224
diff
changeset
|
264 hinit->name, hinit->name, hinit->max_size); |
3b6d69857de2
Core: fixed potential division by zero when initializing hash.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6224
diff
changeset
|
265 return NGX_ERROR; |
3b6d69857de2
Core: fixed potential division by zero when initializing hash.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6224
diff
changeset
|
266 } |
3b6d69857de2
Core: fixed potential division by zero when initializing hash.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6224
diff
changeset
|
267 |
7536
c3f60d618c17
Core: fixed segfault with too large bucket sizes (ticket #1806).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6743
diff
changeset
|
268 if (hinit->bucket_size > 65536 - ngx_cacheline_size) { |
c3f60d618c17
Core: fixed segfault with too large bucket sizes (ticket #1806).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6743
diff
changeset
|
269 ngx_log_error(NGX_LOG_EMERG, hinit->pool->log, 0, |
c3f60d618c17
Core: fixed segfault with too large bucket sizes (ticket #1806).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6743
diff
changeset
|
270 "could not build %s, too large " |
c3f60d618c17
Core: fixed segfault with too large bucket sizes (ticket #1806).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6743
diff
changeset
|
271 "%s_bucket_size: %i", |
c3f60d618c17
Core: fixed segfault with too large bucket sizes (ticket #1806).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6743
diff
changeset
|
272 hinit->name, hinit->name, hinit->bucket_size); |
c3f60d618c17
Core: fixed segfault with too large bucket sizes (ticket #1806).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6743
diff
changeset
|
273 return NGX_ERROR; |
c3f60d618c17
Core: fixed segfault with too large bucket sizes (ticket #1806).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6743
diff
changeset
|
274 } |
c3f60d618c17
Core: fixed segfault with too large bucket sizes (ticket #1806).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6743
diff
changeset
|
275 |
589 | 276 for (n = 0; n < nelts; n++) { |
7943
2a7155733855
Core: removed unnecessary restriction in hash initialization.
Alexey Radkov <alexey.radkov@gmail.com>
parents:
7541
diff
changeset
|
277 if (names[n].key.data == NULL) { |
2a7155733855
Core: removed unnecessary restriction in hash initialization.
Alexey Radkov <alexey.radkov@gmail.com>
parents:
7541
diff
changeset
|
278 continue; |
2a7155733855
Core: removed unnecessary restriction in hash initialization.
Alexey Radkov <alexey.radkov@gmail.com>
parents:
7541
diff
changeset
|
279 } |
2a7155733855
Core: removed unnecessary restriction in hash initialization.
Alexey Radkov <alexey.radkov@gmail.com>
parents:
7541
diff
changeset
|
280 |
589 | 281 if (hinit->bucket_size < NGX_HASH_ELT_SIZE(&names[n]) + sizeof(void *)) |
282 { | |
283 ngx_log_error(NGX_LOG_EMERG, hinit->pool->log, 0, | |
6224
ddf35e019a80
Core: fixed style in the error message.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5985
diff
changeset
|
284 "could not build %s, you should " |
589 | 285 "increase %s_bucket_size: %i", |
286 hinit->name, hinit->name, hinit->bucket_size); | |
287 return NGX_ERROR; | |
288 } | |
289 } | |
290 | |
595 | 291 test = ngx_alloc(hinit->max_size * sizeof(u_short), hinit->pool->log); |
589 | 292 if (test == NULL) { |
293 return NGX_ERROR; | |
294 } | |
295 | |
631 | 296 bucket_size = hinit->bucket_size - sizeof(void *); |
297 | |
746 | 298 start = nelts / (bucket_size / (2 * sizeof(void *))); |
589 | 299 start = start ? start : 1; |
300 | |
4404
840f3e768ef8
Fixed division by zero exception in ngx_hash_init().
Valentin Bartenev <vbart@nginx.com>
parents:
3510
diff
changeset
|
301 if (hinit->max_size > 10000 && nelts && hinit->max_size / nelts < 100) { |
631 | 302 start = hinit->max_size - 1000; |
303 } | |
589 | 304 |
5636
54f847c88cf7
Core: fixed hash to actually try max_size.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5635
diff
changeset
|
305 for (size = start; size <= hinit->max_size; size++) { |
589 | 306 |
595 | 307 ngx_memzero(test, size * sizeof(u_short)); |
589 | 308 |
309 for (n = 0; n < nelts; n++) { | |
310 if (names[n].key.data == NULL) { | |
311 continue; | |
312 } | |
313 | |
314 key = names[n].key_hash % size; | |
7536
c3f60d618c17
Core: fixed segfault with too large bucket sizes (ticket #1806).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6743
diff
changeset
|
315 len = test[key] + NGX_HASH_ELT_SIZE(&names[n]); |
589 | 316 |
317 #if 0 | |
318 ngx_log_error(NGX_LOG_ALERT, hinit->pool->log, 0, | |
7536
c3f60d618c17
Core: fixed segfault with too large bucket sizes (ticket #1806).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6743
diff
changeset
|
319 "%ui: %ui %uz \"%V\"", |
c3f60d618c17
Core: fixed segfault with too large bucket sizes (ticket #1806).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6743
diff
changeset
|
320 size, key, len, &names[n].key); |
589 | 321 #endif |
322 | |
7536
c3f60d618c17
Core: fixed segfault with too large bucket sizes (ticket #1806).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6743
diff
changeset
|
323 if (len > bucket_size) { |
589 | 324 goto next; |
325 } | |
7536
c3f60d618c17
Core: fixed segfault with too large bucket sizes (ticket #1806).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6743
diff
changeset
|
326 |
c3f60d618c17
Core: fixed segfault with too large bucket sizes (ticket #1806).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6743
diff
changeset
|
327 test[key] = (u_short) len; |
589 | 328 } |
329 | |
330 goto found; | |
331 | |
332 next: | |
333 | |
334 continue; | |
335 } | |
336 | |
5985
f961c719fb09
Core: fixed potential buffer overrun when initializing hash.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5870
diff
changeset
|
337 size = hinit->max_size; |
5870
5e72578e6503
Core: fixed buffer overrun when hash max_size reached.
Yichun Zhang <agentzh@gmail.com>
parents:
5636
diff
changeset
|
338 |
5635
c348dea081fb
Core: hash now ignores bucket_size if it hits max_size limit.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4689
diff
changeset
|
339 ngx_log_error(NGX_LOG_WARN, hinit->pool->log, 0, |
c348dea081fb
Core: hash now ignores bucket_size if it hits max_size limit.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4689
diff
changeset
|
340 "could not build optimal %s, you should increase " |
c348dea081fb
Core: hash now ignores bucket_size if it hits max_size limit.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4689
diff
changeset
|
341 "either %s_max_size: %i or %s_bucket_size: %i; " |
c348dea081fb
Core: hash now ignores bucket_size if it hits max_size limit.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4689
diff
changeset
|
342 "ignoring %s_bucket_size", |
589 | 343 hinit->name, hinit->name, hinit->max_size, |
5635
c348dea081fb
Core: hash now ignores bucket_size if it hits max_size limit.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4689
diff
changeset
|
344 hinit->name, hinit->bucket_size, hinit->name); |
589 | 345 |
346 found: | |
347 | |
348 for (i = 0; i < size; i++) { | |
349 test[i] = sizeof(void *); | |
350 } | |
351 | |
352 for (n = 0; n < nelts; n++) { | |
353 if (names[n].key.data == NULL) { | |
354 continue; | |
355 } | |
356 | |
357 key = names[n].key_hash % size; | |
7536
c3f60d618c17
Core: fixed segfault with too large bucket sizes (ticket #1806).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6743
diff
changeset
|
358 len = test[key] + NGX_HASH_ELT_SIZE(&names[n]); |
c3f60d618c17
Core: fixed segfault with too large bucket sizes (ticket #1806).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6743
diff
changeset
|
359 |
c3f60d618c17
Core: fixed segfault with too large bucket sizes (ticket #1806).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6743
diff
changeset
|
360 if (len > 65536 - ngx_cacheline_size) { |
c3f60d618c17
Core: fixed segfault with too large bucket sizes (ticket #1806).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6743
diff
changeset
|
361 ngx_log_error(NGX_LOG_EMERG, hinit->pool->log, 0, |
c3f60d618c17
Core: fixed segfault with too large bucket sizes (ticket #1806).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6743
diff
changeset
|
362 "could not build %s, you should " |
c3f60d618c17
Core: fixed segfault with too large bucket sizes (ticket #1806).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6743
diff
changeset
|
363 "increase %s_max_size: %i", |
c3f60d618c17
Core: fixed segfault with too large bucket sizes (ticket #1806).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6743
diff
changeset
|
364 hinit->name, hinit->name, hinit->max_size); |
7541
eb9c7fb796d5
Core: fixed memory leak on error, missed in c3f60d618c17.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7536
diff
changeset
|
365 ngx_free(test); |
7536
c3f60d618c17
Core: fixed segfault with too large bucket sizes (ticket #1806).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6743
diff
changeset
|
366 return NGX_ERROR; |
c3f60d618c17
Core: fixed segfault with too large bucket sizes (ticket #1806).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6743
diff
changeset
|
367 } |
c3f60d618c17
Core: fixed segfault with too large bucket sizes (ticket #1806).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6743
diff
changeset
|
368 |
c3f60d618c17
Core: fixed segfault with too large bucket sizes (ticket #1806).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6743
diff
changeset
|
369 test[key] = (u_short) len; |
589 | 370 } |
371 | |
372 len = 0; | |
373 | |
374 for (i = 0; i < size; i++) { | |
375 if (test[i] == sizeof(void *)) { | |
376 continue; | |
377 } | |
378 | |
595 | 379 test[i] = (u_short) (ngx_align(test[i], ngx_cacheline_size)); |
589 | 380 |
381 len += test[i]; | |
382 } | |
383 | |
384 if (hinit->hash == NULL) { | |
385 hinit->hash = ngx_pcalloc(hinit->pool, sizeof(ngx_hash_wildcard_t) | |
386 + size * sizeof(ngx_hash_elt_t *)); | |
387 if (hinit->hash == NULL) { | |
388 ngx_free(test); | |
389 return NGX_ERROR; | |
390 } | |
391 | |
392 buckets = (ngx_hash_elt_t **) | |
393 ((u_char *) hinit->hash + sizeof(ngx_hash_wildcard_t)); | |
394 | |
395 } else { | |
396 buckets = ngx_pcalloc(hinit->pool, size * sizeof(ngx_hash_elt_t *)); | |
397 if (buckets == NULL) { | |
398 ngx_free(test); | |
399 return NGX_ERROR; | |
400 } | |
401 } | |
402 | |
403 elts = ngx_palloc(hinit->pool, len + ngx_cacheline_size); | |
404 if (elts == NULL) { | |
405 ngx_free(test); | |
406 return NGX_ERROR; | |
407 } | |
408 | |
409 elts = ngx_align_ptr(elts, ngx_cacheline_size); | |
410 | |
411 for (i = 0; i < size; i++) { | |
412 if (test[i] == sizeof(void *)) { | |
413 continue; | |
414 } | |
415 | |
416 buckets[i] = (ngx_hash_elt_t *) elts; | |
417 elts += test[i]; | |
418 } | |
419 | |
420 for (i = 0; i < size; i++) { | |
421 test[i] = 0; | |
422 } | |
423 | |
424 for (n = 0; n < nelts; n++) { | |
425 if (names[n].key.data == NULL) { | |
426 continue; | |
427 } | |
428 | |
429 key = names[n].key_hash % size; | |
430 elt = (ngx_hash_elt_t *) ((u_char *) buckets[key] + test[key]); | |
431 | |
432 elt->value = names[n].value; | |
3510
4c70bbdfd076
allow hash key values more than 255 bytes, it does not actually increase mean
Igor Sysoev <igor@sysoev.ru>
parents:
3118
diff
changeset
|
433 elt->len = (u_short) names[n].key.len; |
589 | 434 |
2135 | 435 ngx_strlow(elt->name, names[n].key.data, names[n].key.len); |
589 | 436 |
595 | 437 test[key] = (u_short) (test[key] + NGX_HASH_ELT_SIZE(&names[n])); |
589 | 438 } |
439 | |
440 for (i = 0; i < size; i++) { | |
441 if (buckets[i] == NULL) { | |
442 continue; | |
443 } | |
444 | |
445 elt = (ngx_hash_elt_t *) ((u_char *) buckets[i] + test[i]); | |
446 | |
447 elt->value = NULL; | |
448 } | |
449 | |
450 ngx_free(test); | |
451 | |
452 hinit->hash->buckets = buckets; | |
453 hinit->hash->size = size; | |
454 | |
455 #if 0 | |
456 | |
457 for (i = 0; i < size; i++) { | |
458 ngx_str_t val; | |
459 ngx_uint_t key; | |
460 | |
461 elt = buckets[i]; | |
462 | |
463 if (elt == NULL) { | |
464 ngx_log_error(NGX_LOG_ALERT, hinit->pool->log, 0, | |
465 "%ui: NULL", i); | |
466 continue; | |
467 } | |
468 | |
469 while (elt->value) { | |
470 val.len = elt->len; | |
471 val.data = &elt->name[0]; | |
472 | |
473 key = hinit->key(val.data, val.len); | |
474 | |
475 ngx_log_error(NGX_LOG_ALERT, hinit->pool->log, 0, | |
476 "%ui: %p \"%V\" %ui", i, elt, &val, key); | |
477 | |
478 elt = (ngx_hash_elt_t *) ngx_align_ptr(&elt->name[0] + elt->len, | |
479 sizeof(void *)); | |
480 } | |
481 } | |
482 | |
483 #endif | |
484 | |
485 return NGX_OK; | |
486 } | |
487 | |
488 | |
489 ngx_int_t | |
490 ngx_hash_wildcard_init(ngx_hash_init_t *hinit, ngx_hash_key_t *names, | |
491 ngx_uint_t nelts) | |
492 { | |
593 | 493 size_t len, dot_len; |
591 | 494 ngx_uint_t i, n, dot; |
589 | 495 ngx_array_t curr_names, next_names; |
496 ngx_hash_key_t *name, *next_name; | |
497 ngx_hash_init_t h; | |
498 ngx_hash_wildcard_t *wdc; | |
499 | |
500 if (ngx_array_init(&curr_names, hinit->temp_pool, nelts, | |
501 sizeof(ngx_hash_key_t)) | |
502 != NGX_OK) | |
503 { | |
504 return NGX_ERROR; | |
505 } | |
506 | |
507 if (ngx_array_init(&next_names, hinit->temp_pool, nelts, | |
508 sizeof(ngx_hash_key_t)) | |
509 != NGX_OK) | |
510 { | |
511 return NGX_ERROR; | |
512 } | |
513 | |
514 for (n = 0; n < nelts; n = i) { | |
515 | |
516 #if 0 | |
517 ngx_log_error(NGX_LOG_ALERT, hinit->pool->log, 0, | |
518 "wc0: \"%V\"", &names[n].key); | |
519 #endif | |
520 | |
591 | 521 dot = 0; |
522 | |
589 | 523 for (len = 0; len < names[n].key.len; len++) { |
524 if (names[n].key.data[len] == '.') { | |
591 | 525 dot = 1; |
589 | 526 break; |
527 } | |
528 } | |
529 | |
530 name = ngx_array_push(&curr_names); | |
531 if (name == NULL) { | |
532 return NGX_ERROR; | |
533 } | |
534 | |
591 | 535 name->key.len = len; |
589 | 536 name->key.data = names[n].key.data; |
537 name->key_hash = hinit->key(name->key.data, name->key.len); | |
538 name->value = names[n].value; | |
539 | |
540 #if 0 | |
541 ngx_log_error(NGX_LOG_ALERT, hinit->pool->log, 0, | |
593 | 542 "wc1: \"%V\" %ui", &name->key, dot); |
589 | 543 #endif |
544 | |
593 | 545 dot_len = len + 1; |
546 | |
591 | 547 if (dot) { |
548 len++; | |
549 } | |
550 | |
589 | 551 next_names.nelts = 0; |
552 | |
553 if (names[n].key.len != len) { | |
554 next_name = ngx_array_push(&next_names); | |
555 if (next_name == NULL) { | |
556 return NGX_ERROR; | |
557 } | |
558 | |
559 next_name->key.len = names[n].key.len - len; | |
560 next_name->key.data = names[n].key.data + len; | |
3118 | 561 next_name->key_hash = 0; |
589 | 562 next_name->value = names[n].value; |
563 | |
564 #if 0 | |
565 ngx_log_error(NGX_LOG_ALERT, hinit->pool->log, 0, | |
566 "wc2: \"%V\"", &next_name->key); | |
567 #endif | |
568 } | |
569 | |
570 for (i = n + 1; i < nelts; i++) { | |
571 if (ngx_strncmp(names[n].key.data, names[i].key.data, len) != 0) { | |
572 break; | |
573 } | |
574 | |
593 | 575 if (!dot |
576 && names[i].key.len > len | |
577 && names[i].key.data[len] != '.') | |
578 { | |
579 break; | |
580 } | |
581 | |
589 | 582 next_name = ngx_array_push(&next_names); |
583 if (next_name == NULL) { | |
584 return NGX_ERROR; | |
585 } | |
586 | |
593 | 587 next_name->key.len = names[i].key.len - dot_len; |
588 next_name->key.data = names[i].key.data + dot_len; | |
3118 | 589 next_name->key_hash = 0; |
589 | 590 next_name->value = names[i].value; |
591 | |
592 #if 0 | |
593 ngx_log_error(NGX_LOG_ALERT, hinit->pool->log, 0, | |
591 | 594 "wc3: \"%V\"", &next_name->key); |
589 | 595 #endif |
596 } | |
597 | |
598 if (next_names.nelts) { | |
593 | 599 |
589 | 600 h = *hinit; |
601 h.hash = NULL; | |
602 | |
603 if (ngx_hash_wildcard_init(&h, (ngx_hash_key_t *) next_names.elts, | |
604 next_names.nelts) | |
605 != NGX_OK) | |
606 { | |
607 return NGX_ERROR; | |
608 } | |
609 | |
610 wdc = (ngx_hash_wildcard_t *) h.hash; | |
611 | |
612 if (names[n].key.len == len) { | |
613 wdc->value = names[n].value; | |
614 } | |
615 | |
2502
23706c19fab8
fix r2169 for .def.com and .abc.def.com case
Igor Sysoev <igor@sysoev.ru>
parents:
2195
diff
changeset
|
616 name->value = (void *) ((uintptr_t) wdc | (dot ? 3 : 2)); |
2168
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
617 |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
618 } else if (dot) { |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
619 name->value = (void *) ((uintptr_t) name->value | 1); |
589 | 620 } |
621 } | |
622 | |
623 if (ngx_hash_init(hinit, (ngx_hash_key_t *) curr_names.elts, | |
624 curr_names.nelts) | |
625 != NGX_OK) | |
626 { | |
627 return NGX_ERROR; | |
628 } | |
629 | |
630 return NGX_OK; | |
631 } | |
632 | |
633 | |
634 ngx_uint_t | |
635 ngx_hash_key(u_char *data, size_t len) | |
636 { | |
637 ngx_uint_t i, key; | |
638 | |
639 key = 0; | |
640 | |
641 for (i = 0; i < len; i++) { | |
642 key = ngx_hash(key, data[i]); | |
643 } | |
644 | |
645 return key; | |
646 } | |
647 | |
648 | |
649 ngx_uint_t | |
650 ngx_hash_key_lc(u_char *data, size_t len) | |
651 { | |
652 ngx_uint_t i, key; | |
653 | |
654 key = 0; | |
655 | |
656 for (i = 0; i < len; i++) { | |
657 key = ngx_hash(key, ngx_tolower(data[i])); | |
658 } | |
659 | |
660 return key; | |
661 } | |
662 | |
663 | |
2136 | 664 ngx_uint_t |
665 ngx_hash_strlow(u_char *dst, u_char *src, size_t n) | |
666 { | |
667 ngx_uint_t key; | |
668 | |
669 key = 0; | |
670 | |
671 while (n--) { | |
672 *dst = ngx_tolower(*src); | |
673 key = ngx_hash(key, *dst); | |
674 dst++; | |
675 src++; | |
676 } | |
677 | |
678 return key; | |
679 } | |
680 | |
681 | |
589 | 682 ngx_int_t |
593 | 683 ngx_hash_keys_array_init(ngx_hash_keys_arrays_t *ha, ngx_uint_t type) |
684 { | |
685 ngx_uint_t asize; | |
686 | |
687 if (type == NGX_HASH_SMALL) { | |
688 asize = 4; | |
689 ha->hsize = 107; | |
690 | |
691 } else { | |
692 asize = NGX_HASH_LARGE_ASIZE; | |
693 ha->hsize = NGX_HASH_LARGE_HSIZE; | |
694 } | |
695 | |
696 if (ngx_array_init(&ha->keys, ha->temp_pool, asize, sizeof(ngx_hash_key_t)) | |
697 != NGX_OK) | |
698 { | |
699 return NGX_ERROR; | |
700 } | |
701 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
702 if (ngx_array_init(&ha->dns_wc_head, ha->temp_pool, asize, |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
703 sizeof(ngx_hash_key_t)) |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
704 != NGX_OK) |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
705 { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
706 return NGX_ERROR; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
707 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
708 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
709 if (ngx_array_init(&ha->dns_wc_tail, ha->temp_pool, asize, |
593 | 710 sizeof(ngx_hash_key_t)) |
711 != NGX_OK) | |
712 { | |
713 return NGX_ERROR; | |
714 } | |
715 | |
716 ha->keys_hash = ngx_pcalloc(ha->temp_pool, sizeof(ngx_array_t) * ha->hsize); | |
717 if (ha->keys_hash == NULL) { | |
718 return NGX_ERROR; | |
719 } | |
720 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
721 ha->dns_wc_head_hash = ngx_pcalloc(ha->temp_pool, |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
722 sizeof(ngx_array_t) * ha->hsize); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
723 if (ha->dns_wc_head_hash == NULL) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
724 return NGX_ERROR; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
725 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
726 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
727 ha->dns_wc_tail_hash = ngx_pcalloc(ha->temp_pool, |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
728 sizeof(ngx_array_t) * ha->hsize); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
729 if (ha->dns_wc_tail_hash == NULL) { |
593 | 730 return NGX_ERROR; |
731 } | |
732 | |
733 return NGX_OK; | |
734 } | |
735 | |
736 | |
737 ngx_int_t | |
738 ngx_hash_add_key(ngx_hash_keys_arrays_t *ha, ngx_str_t *key, void *value, | |
739 ngx_uint_t flags) | |
740 { | |
741 size_t len; | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
742 u_char *p; |
593 | 743 ngx_str_t *name; |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
744 ngx_uint_t i, k, n, skip, last; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
745 ngx_array_t *keys, *hwc; |
593 | 746 ngx_hash_key_t *hk; |
747 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
748 last = key->len; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
749 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
750 if (flags & NGX_HASH_WILDCARD_KEY) { |
593 | 751 |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
752 /* |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
753 * supported wildcards: |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
754 * "*.example.com", ".example.com", and "www.example.*" |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
755 */ |
593 | 756 |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
757 n = 0; |
593 | 758 |
759 for (i = 0; i < key->len; i++) { | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
760 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
761 if (key->data[i] == '*') { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
762 if (++n > 1) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
763 return NGX_DECLINED; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
764 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
765 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
766 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
767 if (key->data[i] == '.' && key->data[i + 1] == '.') { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
768 return NGX_DECLINED; |
597 | 769 } |
6245
3cf25d33886a
Core: fixed segfault with null in wildcard hash names.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6225
diff
changeset
|
770 |
3cf25d33886a
Core: fixed segfault with null in wildcard hash names.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6225
diff
changeset
|
771 if (key->data[i] == '\0') { |
3cf25d33886a
Core: fixed segfault with null in wildcard hash names.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6225
diff
changeset
|
772 return NGX_DECLINED; |
3cf25d33886a
Core: fixed segfault with null in wildcard hash names.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6225
diff
changeset
|
773 } |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
774 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
775 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
776 if (key->len > 1 && key->data[0] == '.') { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
777 skip = 1; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
778 goto wildcard; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
779 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
780 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
781 if (key->len > 2) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
782 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
783 if (key->data[0] == '*' && key->data[1] == '.') { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
784 skip = 2; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
785 goto wildcard; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
786 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
787 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
788 if (key->data[i - 2] == '.' && key->data[i - 1] == '*') { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
789 skip = 0; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
790 last -= 2; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
791 goto wildcard; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
792 } |
593 | 793 } |
794 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
795 if (n) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
796 return NGX_DECLINED; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
797 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
798 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
799 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
800 /* exact hash */ |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
801 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
802 k = 0; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
803 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
804 for (i = 0; i < last; i++) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
805 if (!(flags & NGX_HASH_READONLY_KEY)) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
806 key->data[i] = ngx_tolower(key->data[i]); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
807 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
808 k = ngx_hash(k, key->data[i]); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
809 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
810 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
811 k %= ha->hsize; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
812 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
813 /* check conflicts in exact hash */ |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
814 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
815 name = ha->keys_hash[k].elts; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
816 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
817 if (name) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
818 for (i = 0; i < ha->keys_hash[k].nelts; i++) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
819 if (last != name[i].len) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
820 continue; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
821 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
822 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
823 if (ngx_strncmp(key->data, name[i].data, last) == 0) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
824 return NGX_BUSY; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
825 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
826 } |
593 | 827 |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
828 } else { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
829 if (ngx_array_init(&ha->keys_hash[k], ha->temp_pool, 4, |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
830 sizeof(ngx_str_t)) |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
831 != NGX_OK) |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
832 { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
833 return NGX_ERROR; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
834 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
835 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
836 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
837 name = ngx_array_push(&ha->keys_hash[k]); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
838 if (name == NULL) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
839 return NGX_ERROR; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
840 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
841 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
842 *name = *key; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
843 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
844 hk = ngx_array_push(&ha->keys); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
845 if (hk == NULL) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
846 return NGX_ERROR; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
847 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
848 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
849 hk->key = *key; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
850 hk->key_hash = ngx_hash_key(key->data, last); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
851 hk->value = value; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
852 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
853 return NGX_OK; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
854 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
855 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
856 wildcard: |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
857 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
858 /* wildcard hash */ |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
859 |
2136 | 860 k = ngx_hash_strlow(&key->data[skip], &key->data[skip], last - skip); |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
861 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
862 k %= ha->hsize; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
863 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
864 if (skip == 1) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
865 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
866 /* check conflicts in exact hash for ".example.com" */ |
593 | 867 |
868 name = ha->keys_hash[k].elts; | |
869 | |
870 if (name) { | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
871 len = last - skip; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
872 |
593 | 873 for (i = 0; i < ha->keys_hash[k].nelts; i++) { |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
874 if (len != name[i].len) { |
593 | 875 continue; |
876 } | |
877 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
878 if (ngx_strncmp(&key->data[1], name[i].data, len) == 0) { |
593 | 879 return NGX_BUSY; |
880 } | |
881 } | |
882 | |
883 } else { | |
884 if (ngx_array_init(&ha->keys_hash[k], ha->temp_pool, 4, | |
885 sizeof(ngx_str_t)) | |
886 != NGX_OK) | |
887 { | |
888 return NGX_ERROR; | |
889 } | |
890 } | |
891 | |
892 name = ngx_array_push(&ha->keys_hash[k]); | |
893 if (name == NULL) { | |
894 return NGX_ERROR; | |
895 } | |
896 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
897 name->len = last - 1; |
2049 | 898 name->data = ngx_pnalloc(ha->temp_pool, name->len); |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
899 if (name->data == NULL) { |
593 | 900 return NGX_ERROR; |
901 } | |
902 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
903 ngx_memcpy(name->data, &key->data[1], name->len); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
904 } |
593 | 905 |
906 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
907 if (skip) { |
593 | 908 |
909 /* | |
910 * convert "*.example.com" to "com.example.\0" | |
911 * and ".example.com" to "com.example\0" | |
912 */ | |
913 | |
2049 | 914 p = ngx_pnalloc(ha->temp_pool, last); |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
915 if (p == NULL) { |
619 | 916 return NGX_ERROR; |
917 } | |
918 | |
593 | 919 len = 0; |
920 n = 0; | |
921 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
922 for (i = last - 1; i; i--) { |
593 | 923 if (key->data[i] == '.') { |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
924 ngx_memcpy(&p[n], &key->data[i + 1], len); |
593 | 925 n += len; |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
926 p[n++] = '.'; |
593 | 927 len = 0; |
928 continue; | |
929 } | |
930 | |
931 len++; | |
932 } | |
933 | |
934 if (len) { | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
935 ngx_memcpy(&p[n], &key->data[1], len); |
593 | 936 n += len; |
937 } | |
938 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
939 p[n] = '\0'; |
619 | 940 |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
941 hwc = &ha->dns_wc_head; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
942 keys = &ha->dns_wc_head_hash[k]; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
943 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
944 } else { |
619 | 945 |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
946 /* convert "www.example.*" to "www.example\0" */ |
619 | 947 |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
948 last++; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
949 |
2049 | 950 p = ngx_pnalloc(ha->temp_pool, last); |
1415
d83687d29853
fix trailing wildcard when two or more listen used in one server
Igor Sysoev <igor@sysoev.ru>
parents:
1253
diff
changeset
|
951 if (p == NULL) { |
d83687d29853
fix trailing wildcard when two or more listen used in one server
Igor Sysoev <igor@sysoev.ru>
parents:
1253
diff
changeset
|
952 return NGX_ERROR; |
d83687d29853
fix trailing wildcard when two or more listen used in one server
Igor Sysoev <igor@sysoev.ru>
parents:
1253
diff
changeset
|
953 } |
d83687d29853
fix trailing wildcard when two or more listen used in one server
Igor Sysoev <igor@sysoev.ru>
parents:
1253
diff
changeset
|
954 |
1492 | 955 ngx_cpystrn(p, key->data, last); |
1415
d83687d29853
fix trailing wildcard when two or more listen used in one server
Igor Sysoev <igor@sysoev.ru>
parents:
1253
diff
changeset
|
956 |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
957 hwc = &ha->dns_wc_tail; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
958 keys = &ha->dns_wc_tail_hash[k]; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
959 } |
593 | 960 |
961 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
962 /* check conflicts in wildcard hash */ |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
963 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
964 name = keys->elts; |
593 | 965 |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
966 if (name) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
967 len = last - skip; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
968 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
969 for (i = 0; i < keys->nelts; i++) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
970 if (len != name[i].len) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
971 continue; |
593 | 972 } |
973 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
974 if (ngx_strncmp(key->data + skip, name[i].data, len) == 0) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
975 return NGX_BUSY; |
593 | 976 } |
977 } | |
978 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
979 } else { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
980 if (ngx_array_init(keys, ha->temp_pool, 4, sizeof(ngx_str_t)) != NGX_OK) |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
981 { |
593 | 982 return NGX_ERROR; |
983 } | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
984 } |
593 | 985 |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
986 name = ngx_array_push(keys); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
987 if (name == NULL) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
988 return NGX_ERROR; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
989 } |
619 | 990 |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
991 name->len = last - skip; |
2049 | 992 name->data = ngx_pnalloc(ha->temp_pool, name->len); |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
993 if (name->data == NULL) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
994 return NGX_ERROR; |
593 | 995 } |
996 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
997 ngx_memcpy(name->data, key->data + skip, name->len); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
998 |
4689
d2ed9fee092b
Fixed handling of conflicting wildcard server names.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
999 |
d2ed9fee092b
Fixed handling of conflicting wildcard server names.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
1000 /* add to wildcard hash */ |
d2ed9fee092b
Fixed handling of conflicting wildcard server names.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
1001 |
d2ed9fee092b
Fixed handling of conflicting wildcard server names.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
1002 hk = ngx_array_push(hwc); |
d2ed9fee092b
Fixed handling of conflicting wildcard server names.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
1003 if (hk == NULL) { |
d2ed9fee092b
Fixed handling of conflicting wildcard server names.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
1004 return NGX_ERROR; |
d2ed9fee092b
Fixed handling of conflicting wildcard server names.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
1005 } |
d2ed9fee092b
Fixed handling of conflicting wildcard server names.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
1006 |
d2ed9fee092b
Fixed handling of conflicting wildcard server names.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
1007 hk->key.len = last - 1; |
d2ed9fee092b
Fixed handling of conflicting wildcard server names.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
1008 hk->key.data = p; |
d2ed9fee092b
Fixed handling of conflicting wildcard server names.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
1009 hk->key_hash = 0; |
d2ed9fee092b
Fixed handling of conflicting wildcard server names.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
1010 hk->value = value; |
d2ed9fee092b
Fixed handling of conflicting wildcard server names.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
1011 |
593 | 1012 return NGX_OK; |
1013 } |