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