Mercurial > hg > nginx-quic
annotate src/core/ngx_hash.c @ 4664:356c91151658 stable-1.2
Merge of r4618: rewrite escaping fix (ticket #162).
The following code resulted in incorrect escaping of uri and possible
segfault:
location / {
rewrite ^(.*) $1?c=$1;
return 200 "$uri";
}
If there were arguments in a rewrite's replacement string, and length was
actually calculated (due to duplicate captures as in the example above,
or variables present), the is_args flag was set and incorrectly copied
after length calculation. This resulted in escaping applied to the uri part
of the replacement, resulting in incorrect escaping. Additionally, buffer
was allocated without escaping expected, thus this also resulted in buffer
overrun and possible segfault.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Mon, 04 Jun 2012 11:07:19 +0000 |
parents | d620f497c50f |
children | d2ed9fee092b |
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 | |
260 for (n = 0; n < nelts; n++) { | |
261 if (hinit->bucket_size < NGX_HASH_ELT_SIZE(&names[n]) + sizeof(void *)) | |
262 { | |
263 ngx_log_error(NGX_LOG_EMERG, hinit->pool->log, 0, | |
595 | 264 "could not build the %s, you should " |
589 | 265 "increase %s_bucket_size: %i", |
266 hinit->name, hinit->name, hinit->bucket_size); | |
267 return NGX_ERROR; | |
268 } | |
269 } | |
270 | |
595 | 271 test = ngx_alloc(hinit->max_size * sizeof(u_short), hinit->pool->log); |
589 | 272 if (test == NULL) { |
273 return NGX_ERROR; | |
274 } | |
275 | |
631 | 276 bucket_size = hinit->bucket_size - sizeof(void *); |
277 | |
746 | 278 start = nelts / (bucket_size / (2 * sizeof(void *))); |
589 | 279 start = start ? start : 1; |
280 | |
4404
840f3e768ef8
Fixed division by zero exception in ngx_hash_init().
Valentin Bartenev <vbart@nginx.com>
parents:
3510
diff
changeset
|
281 if (hinit->max_size > 10000 && nelts && hinit->max_size / nelts < 100) { |
631 | 282 start = hinit->max_size - 1000; |
283 } | |
589 | 284 |
285 for (size = start; size < hinit->max_size; size++) { | |
286 | |
595 | 287 ngx_memzero(test, size * sizeof(u_short)); |
589 | 288 |
289 for (n = 0; n < nelts; n++) { | |
290 if (names[n].key.data == NULL) { | |
291 continue; | |
292 } | |
293 | |
294 key = names[n].key_hash % size; | |
595 | 295 test[key] = (u_short) (test[key] + NGX_HASH_ELT_SIZE(&names[n])); |
589 | 296 |
297 #if 0 | |
298 ngx_log_error(NGX_LOG_ALERT, hinit->pool->log, 0, | |
299 "%ui: %ui %ui \"%V\"", | |
300 size, key, test[key], &names[n].key); | |
301 #endif | |
302 | |
595 | 303 if (test[key] > (u_short) bucket_size) { |
589 | 304 goto next; |
305 } | |
306 } | |
307 | |
308 goto found; | |
309 | |
310 next: | |
311 | |
312 continue; | |
313 } | |
314 | |
315 ngx_log_error(NGX_LOG_EMERG, hinit->pool->log, 0, | |
595 | 316 "could not build the %s, you should increase " |
589 | 317 "either %s_max_size: %i or %s_bucket_size: %i", |
318 hinit->name, hinit->name, hinit->max_size, | |
319 hinit->name, hinit->bucket_size); | |
320 | |
321 ngx_free(test); | |
322 | |
323 return NGX_ERROR; | |
324 | |
325 found: | |
326 | |
327 for (i = 0; i < size; i++) { | |
328 test[i] = sizeof(void *); | |
329 } | |
330 | |
331 for (n = 0; n < nelts; n++) { | |
332 if (names[n].key.data == NULL) { | |
333 continue; | |
334 } | |
335 | |
336 key = names[n].key_hash % size; | |
595 | 337 test[key] = (u_short) (test[key] + NGX_HASH_ELT_SIZE(&names[n])); |
589 | 338 } |
339 | |
340 len = 0; | |
341 | |
342 for (i = 0; i < size; i++) { | |
343 if (test[i] == sizeof(void *)) { | |
344 continue; | |
345 } | |
346 | |
595 | 347 test[i] = (u_short) (ngx_align(test[i], ngx_cacheline_size)); |
589 | 348 |
349 len += test[i]; | |
350 } | |
351 | |
352 if (hinit->hash == NULL) { | |
353 hinit->hash = ngx_pcalloc(hinit->pool, sizeof(ngx_hash_wildcard_t) | |
354 + size * sizeof(ngx_hash_elt_t *)); | |
355 if (hinit->hash == NULL) { | |
356 ngx_free(test); | |
357 return NGX_ERROR; | |
358 } | |
359 | |
360 buckets = (ngx_hash_elt_t **) | |
361 ((u_char *) hinit->hash + sizeof(ngx_hash_wildcard_t)); | |
362 | |
363 } else { | |
364 buckets = ngx_pcalloc(hinit->pool, size * sizeof(ngx_hash_elt_t *)); | |
365 if (buckets == NULL) { | |
366 ngx_free(test); | |
367 return NGX_ERROR; | |
368 } | |
369 } | |
370 | |
371 elts = ngx_palloc(hinit->pool, len + ngx_cacheline_size); | |
372 if (elts == NULL) { | |
373 ngx_free(test); | |
374 return NGX_ERROR; | |
375 } | |
376 | |
377 elts = ngx_align_ptr(elts, ngx_cacheline_size); | |
378 | |
379 for (i = 0; i < size; i++) { | |
380 if (test[i] == sizeof(void *)) { | |
381 continue; | |
382 } | |
383 | |
384 buckets[i] = (ngx_hash_elt_t *) elts; | |
385 elts += test[i]; | |
386 | |
387 } | |
388 | |
389 for (i = 0; i < size; i++) { | |
390 test[i] = 0; | |
391 } | |
392 | |
393 for (n = 0; n < nelts; n++) { | |
394 if (names[n].key.data == NULL) { | |
395 continue; | |
396 } | |
397 | |
398 key = names[n].key_hash % size; | |
399 elt = (ngx_hash_elt_t *) ((u_char *) buckets[key] + test[key]); | |
400 | |
401 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
|
402 elt->len = (u_short) names[n].key.len; |
589 | 403 |
2135 | 404 ngx_strlow(elt->name, names[n].key.data, names[n].key.len); |
589 | 405 |
595 | 406 test[key] = (u_short) (test[key] + NGX_HASH_ELT_SIZE(&names[n])); |
589 | 407 } |
408 | |
409 for (i = 0; i < size; i++) { | |
410 if (buckets[i] == NULL) { | |
411 continue; | |
412 } | |
413 | |
414 elt = (ngx_hash_elt_t *) ((u_char *) buckets[i] + test[i]); | |
415 | |
416 elt->value = NULL; | |
417 } | |
418 | |
419 ngx_free(test); | |
420 | |
421 hinit->hash->buckets = buckets; | |
422 hinit->hash->size = size; | |
423 | |
424 #if 0 | |
425 | |
426 for (i = 0; i < size; i++) { | |
427 ngx_str_t val; | |
428 ngx_uint_t key; | |
429 | |
430 elt = buckets[i]; | |
431 | |
432 if (elt == NULL) { | |
433 ngx_log_error(NGX_LOG_ALERT, hinit->pool->log, 0, | |
434 "%ui: NULL", i); | |
435 continue; | |
436 } | |
437 | |
438 while (elt->value) { | |
439 val.len = elt->len; | |
440 val.data = &elt->name[0]; | |
441 | |
442 key = hinit->key(val.data, val.len); | |
443 | |
444 ngx_log_error(NGX_LOG_ALERT, hinit->pool->log, 0, | |
445 "%ui: %p \"%V\" %ui", i, elt, &val, key); | |
446 | |
447 elt = (ngx_hash_elt_t *) ngx_align_ptr(&elt->name[0] + elt->len, | |
448 sizeof(void *)); | |
449 } | |
450 } | |
451 | |
452 #endif | |
453 | |
454 return NGX_OK; | |
455 } | |
456 | |
457 | |
458 ngx_int_t | |
459 ngx_hash_wildcard_init(ngx_hash_init_t *hinit, ngx_hash_key_t *names, | |
460 ngx_uint_t nelts) | |
461 { | |
593 | 462 size_t len, dot_len; |
591 | 463 ngx_uint_t i, n, dot; |
589 | 464 ngx_array_t curr_names, next_names; |
465 ngx_hash_key_t *name, *next_name; | |
466 ngx_hash_init_t h; | |
467 ngx_hash_wildcard_t *wdc; | |
468 | |
469 if (ngx_array_init(&curr_names, hinit->temp_pool, nelts, | |
470 sizeof(ngx_hash_key_t)) | |
471 != NGX_OK) | |
472 { | |
473 return NGX_ERROR; | |
474 } | |
475 | |
476 if (ngx_array_init(&next_names, hinit->temp_pool, nelts, | |
477 sizeof(ngx_hash_key_t)) | |
478 != NGX_OK) | |
479 { | |
480 return NGX_ERROR; | |
481 } | |
482 | |
483 for (n = 0; n < nelts; n = i) { | |
484 | |
485 #if 0 | |
486 ngx_log_error(NGX_LOG_ALERT, hinit->pool->log, 0, | |
487 "wc0: \"%V\"", &names[n].key); | |
488 #endif | |
489 | |
591 | 490 dot = 0; |
491 | |
589 | 492 for (len = 0; len < names[n].key.len; len++) { |
493 if (names[n].key.data[len] == '.') { | |
591 | 494 dot = 1; |
589 | 495 break; |
496 } | |
497 } | |
498 | |
499 name = ngx_array_push(&curr_names); | |
500 if (name == NULL) { | |
501 return NGX_ERROR; | |
502 } | |
503 | |
591 | 504 name->key.len = len; |
589 | 505 name->key.data = names[n].key.data; |
506 name->key_hash = hinit->key(name->key.data, name->key.len); | |
507 name->value = names[n].value; | |
508 | |
509 #if 0 | |
510 ngx_log_error(NGX_LOG_ALERT, hinit->pool->log, 0, | |
593 | 511 "wc1: \"%V\" %ui", &name->key, dot); |
589 | 512 #endif |
513 | |
593 | 514 dot_len = len + 1; |
515 | |
591 | 516 if (dot) { |
517 len++; | |
518 } | |
519 | |
589 | 520 next_names.nelts = 0; |
521 | |
522 if (names[n].key.len != len) { | |
523 next_name = ngx_array_push(&next_names); | |
524 if (next_name == NULL) { | |
525 return NGX_ERROR; | |
526 } | |
527 | |
528 next_name->key.len = names[n].key.len - len; | |
529 next_name->key.data = names[n].key.data + len; | |
3118 | 530 next_name->key_hash = 0; |
589 | 531 next_name->value = names[n].value; |
532 | |
533 #if 0 | |
534 ngx_log_error(NGX_LOG_ALERT, hinit->pool->log, 0, | |
535 "wc2: \"%V\"", &next_name->key); | |
536 #endif | |
537 } | |
538 | |
539 for (i = n + 1; i < nelts; i++) { | |
540 if (ngx_strncmp(names[n].key.data, names[i].key.data, len) != 0) { | |
541 break; | |
542 } | |
543 | |
593 | 544 if (!dot |
545 && names[i].key.len > len | |
546 && names[i].key.data[len] != '.') | |
547 { | |
548 break; | |
549 } | |
550 | |
589 | 551 next_name = ngx_array_push(&next_names); |
552 if (next_name == NULL) { | |
553 return NGX_ERROR; | |
554 } | |
555 | |
593 | 556 next_name->key.len = names[i].key.len - dot_len; |
557 next_name->key.data = names[i].key.data + dot_len; | |
3118 | 558 next_name->key_hash = 0; |
589 | 559 next_name->value = names[i].value; |
560 | |
561 #if 0 | |
562 ngx_log_error(NGX_LOG_ALERT, hinit->pool->log, 0, | |
591 | 563 "wc3: \"%V\"", &next_name->key); |
589 | 564 #endif |
565 } | |
566 | |
567 if (next_names.nelts) { | |
593 | 568 |
589 | 569 h = *hinit; |
570 h.hash = NULL; | |
571 | |
572 if (ngx_hash_wildcard_init(&h, (ngx_hash_key_t *) next_names.elts, | |
573 next_names.nelts) | |
574 != NGX_OK) | |
575 { | |
576 return NGX_ERROR; | |
577 } | |
578 | |
579 wdc = (ngx_hash_wildcard_t *) h.hash; | |
580 | |
581 if (names[n].key.len == len) { | |
582 wdc->value = names[n].value; | |
583 } | |
584 | |
2502
23706c19fab8
fix r2169 for .def.com and .abc.def.com case
Igor Sysoev <igor@sysoev.ru>
parents:
2195
diff
changeset
|
585 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
|
586 |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
587 } 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
|
588 name->value = (void *) ((uintptr_t) name->value | 1); |
589 | 589 } |
590 } | |
591 | |
592 if (ngx_hash_init(hinit, (ngx_hash_key_t *) curr_names.elts, | |
593 curr_names.nelts) | |
594 != NGX_OK) | |
595 { | |
596 return NGX_ERROR; | |
597 } | |
598 | |
599 return NGX_OK; | |
600 } | |
601 | |
602 | |
603 ngx_uint_t | |
604 ngx_hash_key(u_char *data, size_t len) | |
605 { | |
606 ngx_uint_t i, key; | |
607 | |
608 key = 0; | |
609 | |
610 for (i = 0; i < len; i++) { | |
611 key = ngx_hash(key, data[i]); | |
612 } | |
613 | |
614 return key; | |
615 } | |
616 | |
617 | |
618 ngx_uint_t | |
619 ngx_hash_key_lc(u_char *data, size_t len) | |
620 { | |
621 ngx_uint_t i, key; | |
622 | |
623 key = 0; | |
624 | |
625 for (i = 0; i < len; i++) { | |
626 key = ngx_hash(key, ngx_tolower(data[i])); | |
627 } | |
628 | |
629 return key; | |
630 } | |
631 | |
632 | |
2136 | 633 ngx_uint_t |
634 ngx_hash_strlow(u_char *dst, u_char *src, size_t n) | |
635 { | |
636 ngx_uint_t key; | |
637 | |
638 key = 0; | |
639 | |
640 while (n--) { | |
641 *dst = ngx_tolower(*src); | |
642 key = ngx_hash(key, *dst); | |
643 dst++; | |
644 src++; | |
645 } | |
646 | |
647 return key; | |
648 } | |
649 | |
650 | |
589 | 651 ngx_int_t |
593 | 652 ngx_hash_keys_array_init(ngx_hash_keys_arrays_t *ha, ngx_uint_t type) |
653 { | |
654 ngx_uint_t asize; | |
655 | |
656 if (type == NGX_HASH_SMALL) { | |
657 asize = 4; | |
658 ha->hsize = 107; | |
659 | |
660 } else { | |
661 asize = NGX_HASH_LARGE_ASIZE; | |
662 ha->hsize = NGX_HASH_LARGE_HSIZE; | |
663 } | |
664 | |
665 if (ngx_array_init(&ha->keys, ha->temp_pool, asize, sizeof(ngx_hash_key_t)) | |
666 != NGX_OK) | |
667 { | |
668 return NGX_ERROR; | |
669 } | |
670 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
671 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
|
672 sizeof(ngx_hash_key_t)) |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
673 != NGX_OK) |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
674 { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
675 return NGX_ERROR; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
676 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
677 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
678 if (ngx_array_init(&ha->dns_wc_tail, ha->temp_pool, asize, |
593 | 679 sizeof(ngx_hash_key_t)) |
680 != NGX_OK) | |
681 { | |
682 return NGX_ERROR; | |
683 } | |
684 | |
685 ha->keys_hash = ngx_pcalloc(ha->temp_pool, sizeof(ngx_array_t) * ha->hsize); | |
686 if (ha->keys_hash == NULL) { | |
687 return NGX_ERROR; | |
688 } | |
689 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
690 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
|
691 sizeof(ngx_array_t) * ha->hsize); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
692 if (ha->dns_wc_head_hash == NULL) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
693 return NGX_ERROR; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
694 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
695 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
696 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
|
697 sizeof(ngx_array_t) * ha->hsize); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
698 if (ha->dns_wc_tail_hash == NULL) { |
593 | 699 return NGX_ERROR; |
700 } | |
701 | |
702 return NGX_OK; | |
703 } | |
704 | |
705 | |
706 ngx_int_t | |
707 ngx_hash_add_key(ngx_hash_keys_arrays_t *ha, ngx_str_t *key, void *value, | |
708 ngx_uint_t flags) | |
709 { | |
710 size_t len; | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
711 u_char *p; |
593 | 712 ngx_str_t *name; |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
713 ngx_uint_t i, k, n, skip, last; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
714 ngx_array_t *keys, *hwc; |
593 | 715 ngx_hash_key_t *hk; |
716 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
717 last = key->len; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
718 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
719 if (flags & NGX_HASH_WILDCARD_KEY) { |
593 | 720 |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
721 /* |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
722 * supported wildcards: |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
723 * "*.example.com", ".example.com", and "www.example.*" |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
724 */ |
593 | 725 |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
726 n = 0; |
593 | 727 |
728 for (i = 0; i < key->len; i++) { | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
729 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
730 if (key->data[i] == '*') { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
731 if (++n > 1) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
732 return NGX_DECLINED; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
733 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
734 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
735 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
736 if (key->data[i] == '.' && key->data[i + 1] == '.') { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
737 return NGX_DECLINED; |
597 | 738 } |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
739 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
740 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
741 if (key->len > 1 && key->data[0] == '.') { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
742 skip = 1; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
743 goto wildcard; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
744 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
745 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
746 if (key->len > 2) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
747 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
748 if (key->data[0] == '*' && key->data[1] == '.') { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
749 skip = 2; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
750 goto wildcard; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
751 } |
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 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
|
754 skip = 0; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
755 last -= 2; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
756 goto wildcard; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
757 } |
593 | 758 } |
759 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
760 if (n) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
761 return NGX_DECLINED; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
762 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
763 } |
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 /* exact hash */ |
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 k = 0; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
768 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
769 for (i = 0; i < last; i++) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
770 if (!(flags & NGX_HASH_READONLY_KEY)) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
771 key->data[i] = ngx_tolower(key->data[i]); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
772 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
773 k = ngx_hash(k, key->data[i]); |
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 k %= ha->hsize; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
777 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
778 /* check conflicts in exact hash */ |
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 name = ha->keys_hash[k].elts; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
781 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
782 if (name) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
783 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
|
784 if (last != name[i].len) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
785 continue; |
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 (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
|
789 return NGX_BUSY; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
790 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
791 } |
593 | 792 |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
793 } else { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
794 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
|
795 sizeof(ngx_str_t)) |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
796 != NGX_OK) |
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 return NGX_ERROR; |
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 } |
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 name = ngx_array_push(&ha->keys_hash[k]); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
803 if (name == NULL) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
804 return NGX_ERROR; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
805 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
806 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
807 *name = *key; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
808 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
809 hk = ngx_array_push(&ha->keys); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
810 if (hk == NULL) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
811 return NGX_ERROR; |
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 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
814 hk->key = *key; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
815 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
|
816 hk->value = value; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
817 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
818 return NGX_OK; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
819 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
820 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
821 wildcard: |
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 /* wildcard hash */ |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
824 |
2136 | 825 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
|
826 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
827 k %= ha->hsize; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
828 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
829 if (skip == 1) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
830 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
831 /* check conflicts in exact hash for ".example.com" */ |
593 | 832 |
833 name = ha->keys_hash[k].elts; | |
834 | |
835 if (name) { | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
836 len = last - skip; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
837 |
593 | 838 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
|
839 if (len != name[i].len) { |
593 | 840 continue; |
841 } | |
842 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
843 if (ngx_strncmp(&key->data[1], name[i].data, len) == 0) { |
593 | 844 return NGX_BUSY; |
845 } | |
846 } | |
847 | |
848 } else { | |
849 if (ngx_array_init(&ha->keys_hash[k], ha->temp_pool, 4, | |
850 sizeof(ngx_str_t)) | |
851 != NGX_OK) | |
852 { | |
853 return NGX_ERROR; | |
854 } | |
855 } | |
856 | |
857 name = ngx_array_push(&ha->keys_hash[k]); | |
858 if (name == NULL) { | |
859 return NGX_ERROR; | |
860 } | |
861 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
862 name->len = last - 1; |
2049 | 863 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
|
864 if (name->data == NULL) { |
593 | 865 return NGX_ERROR; |
866 } | |
867 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
868 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
|
869 } |
593 | 870 |
871 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
872 if (skip) { |
593 | 873 |
874 /* | |
875 * convert "*.example.com" to "com.example.\0" | |
876 * and ".example.com" to "com.example\0" | |
877 */ | |
878 | |
2049 | 879 p = ngx_pnalloc(ha->temp_pool, last); |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
880 if (p == NULL) { |
619 | 881 return NGX_ERROR; |
882 } | |
883 | |
593 | 884 len = 0; |
885 n = 0; | |
886 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
887 for (i = last - 1; i; i--) { |
593 | 888 if (key->data[i] == '.') { |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
889 ngx_memcpy(&p[n], &key->data[i + 1], len); |
593 | 890 n += len; |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
891 p[n++] = '.'; |
593 | 892 len = 0; |
893 continue; | |
894 } | |
895 | |
896 len++; | |
897 } | |
898 | |
899 if (len) { | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
900 ngx_memcpy(&p[n], &key->data[1], len); |
593 | 901 n += len; |
902 } | |
903 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
904 p[n] = '\0'; |
619 | 905 |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
906 hwc = &ha->dns_wc_head; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
907 keys = &ha->dns_wc_head_hash[k]; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
908 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
909 } else { |
619 | 910 |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
911 /* convert "www.example.*" to "www.example\0" */ |
619 | 912 |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
913 last++; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
914 |
2049 | 915 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
|
916 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
|
917 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
|
918 } |
d83687d29853
fix trailing wildcard when two or more listen used in one server
Igor Sysoev <igor@sysoev.ru>
parents:
1253
diff
changeset
|
919 |
1492 | 920 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
|
921 |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
922 hwc = &ha->dns_wc_tail; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
923 keys = &ha->dns_wc_tail_hash[k]; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
924 } |
593 | 925 |
926 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
927 hk = ngx_array_push(hwc); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
928 if (hk == NULL) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
929 return NGX_ERROR; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
930 } |
593 | 931 |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
932 hk->key.len = last - 1; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
933 hk->key.data = p; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
934 hk->key_hash = 0; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
935 hk->value = value; |
593 | 936 |
937 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
938 /* check conflicts in wildcard hash */ |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
939 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
940 name = keys->elts; |
593 | 941 |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
942 if (name) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
943 len = last - skip; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
944 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
945 for (i = 0; i < keys->nelts; i++) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
946 if (len != name[i].len) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
947 continue; |
593 | 948 } |
949 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
950 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
|
951 return NGX_BUSY; |
593 | 952 } |
953 } | |
954 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
955 } else { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
956 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
|
957 { |
593 | 958 return NGX_ERROR; |
959 } | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
960 } |
593 | 961 |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
962 name = ngx_array_push(keys); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
963 if (name == NULL) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
964 return NGX_ERROR; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
965 } |
619 | 966 |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
967 name->len = last - skip; |
2049 | 968 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
|
969 if (name->data == NULL) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
970 return NGX_ERROR; |
593 | 971 } |
972 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
973 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
|
974 |
593 | 975 return NGX_OK; |
976 } |