Mercurial > hg > nginx-quic
comparison src/http/ngx_http_variables.c @ 501:d4ea69372b94 release-0.1.25
nginx-0.1.25-RELEASE import
*) Bugfix: nginx did run on Linux parisc.
*) Feature: nginx now does not start under FreeBSD if the sysctl
kern.ipc.somaxconn value is too big.
*) Bugfix: if a request was internally redirected by the
ngx_http_index_module module to the ngx_http_proxy_module or
ngx_http_fastcgi_module modules, then the index file was not closed
after request completion.
*) Feature: the "proxy_pass" can be used in location with regular
expression.
*) Feature: the ngx_http_rewrite_filter_module module supports the
condition like "if ($HTTP_USER_AGENT ~ MSIE)".
*) Bugfix: nginx started too slow if the large number of addresses and
text values were used in the "geo" directive.
*) Change: a variable name must be declared as "$name" in the "geo"
directive. The previous variant without "$" is still supported, but
will be removed soon.
*) Feature: the "%{VARIABLE}v" logging parameter.
*) Feature: the "set $name value" directive.
*) Bugfix: gcc 4.0 compatibility.
*) Feature: the --with-openssl-opt=OPTIONS autoconfiguration directive.
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Sat, 19 Mar 2005 12:38:37 +0000 |
parents | 64d9afb209da |
children | 9b8c906f6e63 |
comparison
equal
deleted
inserted
replaced
500:9a0f304470f5 | 501:d4ea69372b94 |
---|---|
23 | 23 |
24 | 24 |
25 static ngx_http_variable_value_t * | 25 static ngx_http_variable_value_t * |
26 ngx_http_variable_header(ngx_http_request_t *r, uintptr_t data); | 26 ngx_http_variable_header(ngx_http_request_t *r, uintptr_t data); |
27 static ngx_http_variable_value_t * | 27 static ngx_http_variable_value_t * |
28 ngx_http_variable_unknown_header(ngx_http_request_t *r, ngx_str_t *var); | 28 ngx_http_variable_unknown_header(ngx_http_request_t *r, uintptr_t data); |
29 static ngx_http_variable_value_t * | 29 static ngx_http_variable_value_t * |
30 ngx_http_variable_remote_addr(ngx_http_request_t *r, uintptr_t data); | 30 ngx_http_variable_remote_addr(ngx_http_request_t *r, uintptr_t data); |
31 static ngx_http_variable_value_t * | 31 static ngx_http_variable_value_t * |
32 ngx_http_variable_uri(ngx_http_request_t *r, uintptr_t data); | 32 ngx_http_variable_uri(ngx_http_request_t *r, uintptr_t data); |
33 static ngx_http_variable_value_t * | 33 static ngx_http_variable_value_t * |
67 { ngx_null_string, NULL, 0 } | 67 { ngx_null_string, NULL, 0 } |
68 }; | 68 }; |
69 | 69 |
70 | 70 |
71 ngx_http_variable_t * | 71 ngx_http_variable_t * |
72 ngx_http_add_variable(ngx_conf_t *cf) | 72 ngx_http_add_variable(ngx_conf_t *cf, ngx_str_t *name, ngx_uint_t set) |
73 { | 73 { |
74 ngx_http_variable_t *var; | 74 ngx_uint_t i; |
75 ngx_http_variable_t *v; | |
75 ngx_http_core_main_conf_t *cmcf; | 76 ngx_http_core_main_conf_t *cmcf; |
76 | 77 |
77 cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); | 78 cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); |
78 | 79 |
79 if (cmcf->variables.elts == NULL) { | 80 v = cmcf->variables.elts; |
81 | |
82 if (v == NULL) { | |
80 if (ngx_array_init(&cmcf->variables, cf->pool, 4, | 83 if (ngx_array_init(&cmcf->variables, cf->pool, 4, |
81 sizeof(ngx_http_variable_t)) == NGX_ERROR) | 84 sizeof(ngx_http_variable_t)) == NGX_ERROR) |
82 { | 85 { |
83 return NULL; | 86 return NULL; |
84 } | 87 } |
85 } | 88 |
86 | 89 } else { |
87 if (!(var = ngx_array_push(&cmcf->variables))) { | 90 for (i = 0; i < cmcf->variables.nelts; i++) { |
88 return NULL; | 91 if (name->len != v[i].name.len |
89 } | 92 || ngx_strncasecmp(name->data, v[i].name.data, name->len) != 0) |
90 | 93 { |
91 var->index = cmcf->variables.nelts - 1; | 94 continue; |
92 | 95 } |
93 return var; | 96 |
97 if (set && v[i].handler) { | |
98 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
99 "the duplicate \"%V\" variable", name); | |
100 return NULL; | |
101 } | |
102 | |
103 return &v[i]; | |
104 } | |
105 } | |
106 | |
107 v = ngx_array_push(&cmcf->variables); | |
108 if (v == NULL) { | |
109 return NULL; | |
110 } | |
111 | |
112 v->name.len = name->len; | |
113 v->name.data = ngx_palloc(cf->pool, name->len); | |
114 if (v->name.data == NULL) { | |
115 return NULL; | |
116 } | |
117 | |
118 for (i = 0; i < name->len; i++) { | |
119 v->name.data[i] = ngx_toupper(name->data[i]); | |
120 } | |
121 | |
122 v->index = cmcf->variables.nelts - 1; | |
123 v->handler = NULL; | |
124 v->data = 0; | |
125 | |
126 return v; | |
94 } | 127 } |
95 | 128 |
96 | 129 |
97 ngx_http_variable_value_t * | 130 ngx_http_variable_value_t * |
98 ngx_http_get_indexed_variable(ngx_http_request_t *r, ngx_uint_t index) | 131 ngx_http_get_indexed_variable(ngx_http_request_t *r, ngx_uint_t index) |
99 { | 132 { |
100 ngx_http_variable_t *var; | 133 ngx_http_variable_t *v; |
134 ngx_http_variable_value_t *vv; | |
101 ngx_http_core_main_conf_t *cmcf; | 135 ngx_http_core_main_conf_t *cmcf; |
102 | |
103 /* TODO: cached variables */ | |
104 | 136 |
105 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); | 137 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); |
106 | 138 |
107 if (cmcf->variables.elts == NULL || cmcf->variables.nelts <= index) { | 139 if (cmcf->variables.elts == NULL || cmcf->variables.nelts <= index) { |
108 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, | 140 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, |
109 "unknown variable index: %d", index); | 141 "unknown variable index: %d", index); |
110 return NULL; | 142 return NULL; |
111 } | 143 } |
112 | 144 |
113 var = cmcf->variables.elts; | 145 if (r->variables && r->variables[index]) { |
114 | 146 return r->variables[index]; |
115 return var[index].handler(r, var[index].data); | 147 } |
116 } | 148 |
117 | 149 v = cmcf->variables.elts; |
118 | 150 |
119 ngx_int_t | 151 vv = v[index].handler(r, v[index].data); |
120 ngx_http_get_variable_index(ngx_http_core_main_conf_t *cmcf, ngx_str_t *name) | 152 |
121 { | 153 if (r->variables == NULL) { |
122 ngx_uint_t i; | 154 r->variables = ngx_pcalloc(r->pool, cmcf->variables.nelts |
123 ngx_http_variable_t *var; | 155 * sizeof(ngx_http_variable_value_t *)); |
124 | 156 if (r->variables == NULL) { |
125 var = cmcf->variables.elts; | 157 return NULL; |
126 for (i = 0; i < cmcf->variables.nelts; i++) { | 158 } |
127 if (var[i].name.len != name->len) { | 159 } |
128 continue; | 160 |
129 } | 161 r->variables[index] = vv; |
130 | 162 |
131 if (ngx_strncasecmp(var[i].name.data, name->data, name->len) == 0) { | 163 return vv; |
132 return var[i].index; | |
133 } | |
134 } | |
135 | |
136 return -1; | |
137 } | 164 } |
138 | 165 |
139 | 166 |
140 ngx_http_variable_value_t * | 167 ngx_http_variable_value_t * |
141 ngx_http_get_variable(ngx_http_request_t *r, ngx_str_t *name) | 168 ngx_http_get_variable(ngx_http_request_t *r, ngx_str_t *name) |
142 { | 169 { |
143 ngx_int_t index; | |
144 ngx_uint_t i, key; | 170 ngx_uint_t i, key; |
145 ngx_http_core_variable_t *var; | 171 ngx_http_variable_t *v; |
172 ngx_http_core_variable_t *cv; | |
146 ngx_http_core_main_conf_t *cmcf; | 173 ngx_http_core_main_conf_t *cmcf; |
147 | 174 |
148 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); | 175 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); |
149 | 176 |
150 index = ngx_http_get_variable_index(cmcf, name); | 177 v = cmcf->variables.elts; |
151 | 178 for (i = 0; i < cmcf->variables.nelts; i++) { |
152 if (index != -1) { | 179 if (v[i].name.len != name->len) { |
153 return ngx_http_get_indexed_variable(r, index); | 180 continue; |
181 } | |
182 | |
183 if (ngx_strncmp(v[i].name.data, name->data, name->len) == 0) { | |
184 return ngx_http_get_indexed_variable(r, v[i].index); | |
185 } | |
154 } | 186 } |
155 | 187 |
156 ngx_http_vars_hash_key(key, name); | 188 ngx_http_vars_hash_key(key, name); |
157 | 189 |
158 var = ngx_http_core_variables_hash[key].elts; | 190 cv = ngx_http_core_variables_hash[key].elts; |
159 for (i = 0; i < ngx_http_core_variables_hash[key].nelts; i++) { | 191 for (i = 0; i < ngx_http_core_variables_hash[key].nelts; i++) { |
160 | 192 if (cv[i].name.len != name->len) { |
161 if (var[i].name.len != name->len | |
162 || ngx_strncasecmp(var[i].name.data, name->data, name->len) != 0) | |
163 { | |
164 continue; | 193 continue; |
165 } | 194 } |
166 | 195 |
167 return var[i].handler(r, var[i].data); | 196 if (ngx_strncmp(cv[i].name.data, name->data, name->len) == 0) { |
168 } | 197 return cv[i].handler(r, cv[i].data); |
169 | 198 } |
170 if (ngx_strncasecmp(name->data, "HTTP_", 5) != 0) { | 199 } |
171 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | 200 |
172 "unknown \"%V\" variable", name); | 201 if (ngx_strncmp(name->data, "HTTP_", 5) == 0) { |
173 return NGX_HTTP_VARIABLE_NOT_FOUND; | 202 return ngx_http_variable_unknown_header(r, (uintptr_t) name); |
174 } | 203 } |
175 | 204 |
176 return ngx_http_variable_unknown_header(r, name); | 205 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
206 "unknown \"%V\" variable", name); | |
207 | |
208 return NGX_HTTP_VARIABLE_NOT_FOUND; | |
177 } | 209 } |
178 | 210 |
179 | 211 |
180 static ngx_http_variable_value_t * | 212 static ngx_http_variable_value_t * |
181 ngx_http_variable_header(ngx_http_request_t *r, uintptr_t data) | 213 ngx_http_variable_header(ngx_http_request_t *r, uintptr_t data) |
182 { | 214 { |
183 ngx_table_elt_t *h; | 215 ngx_table_elt_t *h; |
184 ngx_http_variable_value_t *v; | 216 ngx_http_variable_value_t *vv; |
185 | 217 |
186 h = *(ngx_table_elt_t **) ((char *) &r->headers_in + data); | 218 h = *(ngx_table_elt_t **) ((char *) &r->headers_in + data); |
187 | 219 |
188 if (h == NULL) { | 220 if (h == NULL) { |
189 return NGX_HTTP_VARIABLE_NOT_FOUND; | 221 return NGX_HTTP_VARIABLE_NOT_FOUND; |
190 } | 222 } |
191 | 223 |
192 if (!(v = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)))) { | 224 vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)); |
193 return NULL; | 225 if (vv == NULL) { |
194 } | 226 return NULL; |
195 | 227 } |
196 v->value = 0; | 228 |
197 v->text = h->value; | 229 vv->value = 0; |
198 | 230 vv->text = h->value; |
199 return v; | 231 |
200 } | 232 return vv; |
201 | 233 } |
202 | 234 |
203 static ngx_http_variable_value_t * | 235 |
204 ngx_http_variable_unknown_header(ngx_http_request_t *r, ngx_str_t *var) | 236 static ngx_http_variable_value_t * |
205 { | 237 ngx_http_variable_unknown_header(ngx_http_request_t *r, uintptr_t data) |
238 { | |
239 ngx_str_t *var = (ngx_str_t *) data; | |
240 | |
206 u_char ch; | 241 u_char ch; |
207 ngx_uint_t i, n; | 242 ngx_uint_t i, n; |
208 ngx_list_part_t *part; | 243 ngx_list_part_t *part; |
209 ngx_table_elt_t *header; | 244 ngx_table_elt_t *header; |
210 ngx_http_variable_value_t *v; | 245 ngx_http_variable_value_t *vv; |
211 | 246 |
212 part = &r->headers_in.headers.part; | 247 part = &r->headers_in.headers.part; |
213 header = part->elts; | 248 header = part->elts; |
214 | 249 |
215 for (i = 0; /* void */ ; i++) { | 250 for (i = 0; /* void */ ; i++) { |
239 break; | 274 break; |
240 } | 275 } |
241 } | 276 } |
242 | 277 |
243 if (n + 5 == var->len) { | 278 if (n + 5 == var->len) { |
244 if (!(v = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)))) { | 279 vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)); |
280 if (vv == NULL) { | |
245 return NULL; | 281 return NULL; |
246 } | 282 } |
247 | 283 |
248 v->value = 0; | 284 vv->value = 0; |
249 v->text = header[i].value; | 285 vv->text = header[i].value; |
250 return v; | 286 return vv; |
251 } | 287 } |
252 } | 288 } |
253 | 289 |
254 return NGX_HTTP_VARIABLE_NOT_FOUND; | 290 return NGX_HTTP_VARIABLE_NOT_FOUND; |
255 } | 291 } |
256 | 292 |
257 | 293 |
258 static ngx_http_variable_value_t * | 294 static ngx_http_variable_value_t * |
259 ngx_http_variable_remote_addr(ngx_http_request_t *r, uintptr_t data) | 295 ngx_http_variable_remote_addr(ngx_http_request_t *r, uintptr_t data) |
260 { | 296 { |
261 ngx_http_variable_value_t *v; | 297 ngx_http_variable_value_t *vv; |
262 | 298 |
263 if (!(v = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)))) { | 299 vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)); |
264 return NULL; | 300 if (vv == NULL) { |
265 } | 301 return NULL; |
266 | 302 } |
267 v->value = 0; | 303 |
268 v->text = r->connection->addr_text; | 304 vv->value = 0; |
269 | 305 vv->text = r->connection->addr_text; |
270 return v; | 306 |
307 return vv; | |
271 } | 308 } |
272 | 309 |
273 | 310 |
274 static ngx_http_variable_value_t * | 311 static ngx_http_variable_value_t * |
275 ngx_http_variable_uri(ngx_http_request_t *r, uintptr_t data) | 312 ngx_http_variable_uri(ngx_http_request_t *r, uintptr_t data) |
276 { | 313 { |
277 ngx_http_variable_value_t *v; | 314 ngx_http_variable_value_t *vv; |
278 | 315 |
279 if (!(v = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)))) { | 316 vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)); |
280 return NULL; | 317 if (vv == NULL) { |
281 } | 318 return NULL; |
282 | 319 } |
283 v->value = 0; | 320 |
284 v->text = r->uri; | 321 vv->value = 0; |
285 | 322 vv->text = r->uri; |
286 return v; | 323 |
324 return vv; | |
287 } | 325 } |
288 | 326 |
289 | 327 |
290 static ngx_http_variable_value_t * | 328 static ngx_http_variable_value_t * |
291 ngx_http_variable_query_string(ngx_http_request_t *r, uintptr_t data) | 329 ngx_http_variable_query_string(ngx_http_request_t *r, uintptr_t data) |
292 { | 330 { |
293 ngx_http_variable_value_t *v; | 331 ngx_http_variable_value_t *vv; |
294 | 332 |
295 if (!(v = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)))) { | 333 vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)); |
296 return NULL; | 334 if (vv == NULL) { |
297 } | 335 return NULL; |
298 | 336 } |
299 v->value = 0; | 337 |
300 v->text = r->args; | 338 vv->value = 0; |
301 | 339 vv->text = r->args; |
302 return v; | 340 |
341 return vv; | |
303 } | 342 } |
304 | 343 |
305 | 344 |
306 ngx_int_t | 345 ngx_int_t |
307 ngx_http_core_variables_init(ngx_cycle_t *cycle) | 346 ngx_http_variables_init(ngx_cycle_t *cycle) |
308 { | 347 { |
309 ngx_uint_t i, key; | 348 ngx_uint_t i, j, key; |
310 ngx_http_core_variable_t *var, *v; | 349 ngx_http_variable_t *v; |
350 ngx_http_core_variable_t *cv, *vp; | |
351 ngx_http_core_main_conf_t *cmcf; | |
311 | 352 |
312 ngx_http_core_variables_hash = ngx_palloc(cycle->pool, | 353 ngx_http_core_variables_hash = ngx_palloc(cycle->pool, |
313 NGX_HTTP_VARS_HASH_PRIME | 354 NGX_HTTP_VARS_HASH_PRIME |
314 * sizeof(ngx_array_t)); | 355 * sizeof(ngx_array_t)); |
315 if (ngx_http_core_variables_hash == NULL) { | 356 if (ngx_http_core_variables_hash == NULL) { |
322 { | 363 { |
323 return NGX_ERROR; | 364 return NGX_ERROR; |
324 } | 365 } |
325 } | 366 } |
326 | 367 |
327 for (var = ngx_http_core_variables; var->name.len; var++) { | 368 for (cv = ngx_http_core_variables; cv->name.len; cv++) { |
328 ngx_http_vars_hash_key(key, &var->name); | 369 ngx_http_vars_hash_key(key, &cv->name); |
329 | 370 |
330 if (!(v = ngx_array_push(&ngx_http_core_variables_hash[key]))) { | 371 vp = ngx_array_push(&ngx_http_core_variables_hash[key]); |
372 if (vp == NULL) { | |
331 return NGX_ERROR; | 373 return NGX_ERROR; |
332 } | 374 } |
333 | 375 |
334 *v = *var; | 376 *vp = *cv; |
377 } | |
378 | |
379 | |
380 cmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_core_module); | |
381 | |
382 v = cmcf->variables.elts; | |
383 for (i = 0; i < cmcf->variables.nelts; i++) { | |
384 | |
385 if (v[i].handler) { | |
386 continue; | |
387 } | |
388 | |
389 ngx_http_vars_hash_key(key, &v[i].name); | |
390 | |
391 cv = ngx_http_core_variables_hash[key].elts; | |
392 for (j = 0; j < ngx_http_core_variables_hash[key].nelts; j++) { | |
393 if (cv[j].name.len != v[i].name.len) { | |
394 continue; | |
395 } | |
396 | |
397 if (ngx_strncmp(cv[j].name.data, v[i].name.data, v[i].name.len) | |
398 == 0) | |
399 { | |
400 v[i].handler = cv[j].handler; | |
401 v[i].data = cv[j].data; | |
402 continue; | |
403 } | |
404 } | |
405 | |
406 if (ngx_strncmp(v[i].name.data, "HTTP_", 5) == 0) { | |
407 v[i].handler = ngx_http_variable_unknown_header; | |
408 v[i].data = (uintptr_t) &v[i].name; | |
409 continue; | |
410 } | |
411 | |
412 ngx_log_error(NGX_LOG_ERR, cycle->log, 0, | |
413 "unknown \"%V\" variable", &v[i].name); | |
414 | |
415 return NGX_ERROR; | |
335 } | 416 } |
336 | 417 |
337 return NGX_OK; | 418 return NGX_OK; |
338 } | 419 } |