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