Mercurial > hg > nginx
annotate src/http/ngx_http_variables.c @ 2724:9fd2f12fee0a
fix Win32 ngx_gettimezone()
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Sun, 19 Apr 2009 19:08:49 +0000 |
parents | 051e9b12428e |
children | 2f3c80ff2123 |
rev | line source |
---|---|
499 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4 */ | |
5 | |
6 | |
7 #include <ngx_config.h> | |
8 #include <ngx_core.h> | |
9 #include <ngx_http.h> | |
1329 | 10 #include <nginx.h> |
499 | 11 |
12 | |
573 | 13 static ngx_int_t ngx_http_variable_request(ngx_http_request_t *r, |
14 ngx_http_variable_value_t *v, uintptr_t data); | |
1350 | 15 static void ngx_http_variable_request_set(ngx_http_request_t *r, |
16 ngx_http_variable_value_t *v, uintptr_t data); | |
637 | 17 static void ngx_http_variable_request_set_size(ngx_http_request_t *r, |
18 ngx_http_variable_value_t *v, uintptr_t data); | |
573 | 19 static ngx_int_t ngx_http_variable_header(ngx_http_request_t *r, |
20 ngx_http_variable_value_t *v, uintptr_t data); | |
21 static ngx_int_t ngx_http_variable_headers(ngx_http_request_t *r, | |
22 ngx_http_variable_value_t *v, uintptr_t data); | |
577 | 23 |
24 static ngx_int_t ngx_http_variable_unknown_header_in(ngx_http_request_t *r, | |
573 | 25 ngx_http_variable_value_t *v, uintptr_t data); |
577 | 26 static ngx_int_t ngx_http_variable_unknown_header_out(ngx_http_request_t *r, |
27 ngx_http_variable_value_t *v, uintptr_t data); | |
2359
4fee4ebbfb0b
$cookie_... variable did not for SSI and perl
Igor Sysoev <igor@sysoev.ru>
parents:
2333
diff
changeset
|
28 static ngx_int_t ngx_http_variable_cookie(ngx_http_request_t *r, |
4fee4ebbfb0b
$cookie_... variable did not for SSI and perl
Igor Sysoev <igor@sysoev.ru>
parents:
2333
diff
changeset
|
29 ngx_http_variable_value_t *v, uintptr_t data); |
2137 | 30 static ngx_int_t ngx_http_variable_argument(ngx_http_request_t *r, |
31 ngx_http_variable_value_t *v, uintptr_t data); | |
577 | 32 |
573 | 33 static ngx_int_t ngx_http_variable_host(ngx_http_request_t *r, |
34 ngx_http_variable_value_t *v, uintptr_t data); | |
983
7a8ca436d611
ngx_http_variable_binary_remote_addr()
Igor Sysoev <igor@sysoev.ru>
parents:
982
diff
changeset
|
35 static ngx_int_t ngx_http_variable_binary_remote_addr(ngx_http_request_t *r, |
7a8ca436d611
ngx_http_variable_binary_remote_addr()
Igor Sysoev <igor@sysoev.ru>
parents:
982
diff
changeset
|
36 ngx_http_variable_value_t *v, uintptr_t data); |
573 | 37 static ngx_int_t ngx_http_variable_remote_addr(ngx_http_request_t *r, |
38 ngx_http_variable_value_t *v, uintptr_t data); | |
39 static ngx_int_t ngx_http_variable_remote_port(ngx_http_request_t *r, | |
40 ngx_http_variable_value_t *v, uintptr_t data); | |
41 static ngx_int_t ngx_http_variable_server_addr(ngx_http_request_t *r, | |
42 ngx_http_variable_value_t *v, uintptr_t data); | |
43 static ngx_int_t ngx_http_variable_server_port(ngx_http_request_t *r, | |
44 ngx_http_variable_value_t *v, uintptr_t data); | |
731 | 45 static ngx_int_t ngx_http_variable_scheme(ngx_http_request_t *r, |
46 ngx_http_variable_value_t *v, uintptr_t data); | |
1351 | 47 static ngx_int_t ngx_http_variable_is_args(ngx_http_request_t *r, |
48 ngx_http_variable_value_t *v, uintptr_t data); | |
573 | 49 static ngx_int_t ngx_http_variable_document_root(ngx_http_request_t *r, |
50 ngx_http_variable_value_t *v, uintptr_t data); | |
2259 | 51 static ngx_int_t ngx_http_variable_realpath_root(ngx_http_request_t *r, |
52 ngx_http_variable_value_t *v, uintptr_t data); | |
573 | 53 static ngx_int_t ngx_http_variable_request_filename(ngx_http_request_t *r, |
54 ngx_http_variable_value_t *v, uintptr_t data); | |
1811 | 55 static ngx_int_t ngx_http_variable_server_name(ngx_http_request_t *r, |
56 ngx_http_variable_value_t *v, uintptr_t data); | |
573 | 57 static ngx_int_t ngx_http_variable_request_method(ngx_http_request_t *r, |
58 ngx_http_variable_value_t *v, uintptr_t data); | |
59 static ngx_int_t ngx_http_variable_remote_user(ngx_http_request_t *r, | |
60 ngx_http_variable_value_t *v, uintptr_t data); | |
611 | 61 static ngx_int_t ngx_http_variable_body_bytes_sent(ngx_http_request_t *r, |
62 ngx_http_variable_value_t *v, uintptr_t data); | |
629 | 63 static ngx_int_t ngx_http_variable_request_completion(ngx_http_request_t *r, |
64 ngx_http_variable_value_t *v, uintptr_t data); | |
759 | 65 static ngx_int_t ngx_http_variable_request_body_file(ngx_http_request_t *r, |
66 ngx_http_variable_value_t *v, uintptr_t data); | |
499 | 67 |
641 | 68 static ngx_int_t ngx_http_variable_sent_content_type(ngx_http_request_t *r, |
69 ngx_http_variable_value_t *v, uintptr_t data); | |
70 static ngx_int_t ngx_http_variable_sent_content_length(ngx_http_request_t *r, | |
71 ngx_http_variable_value_t *v, uintptr_t data); | |
2485
51b1097dbb67
fix $sent_http_location for local redirects
Igor Sysoev <igor@sysoev.ru>
parents:
2415
diff
changeset
|
72 static ngx_int_t ngx_http_variable_sent_location(ngx_http_request_t *r, |
51b1097dbb67
fix $sent_http_location for local redirects
Igor Sysoev <igor@sysoev.ru>
parents:
2415
diff
changeset
|
73 ngx_http_variable_value_t *v, uintptr_t data); |
641 | 74 static ngx_int_t ngx_http_variable_sent_last_modified(ngx_http_request_t *r, |
75 ngx_http_variable_value_t *v, uintptr_t data); | |
76 static ngx_int_t ngx_http_variable_sent_connection(ngx_http_request_t *r, | |
77 ngx_http_variable_value_t *v, uintptr_t data); | |
78 static ngx_int_t ngx_http_variable_sent_keep_alive(ngx_http_request_t *r, | |
79 ngx_http_variable_value_t *v, uintptr_t data); | |
80 static ngx_int_t ngx_http_variable_sent_transfer_encoding(ngx_http_request_t *r, | |
81 ngx_http_variable_value_t *v, uintptr_t data); | |
82 | |
1329 | 83 static ngx_int_t ngx_http_variable_nginx_version(ngx_http_request_t *r, |
84 ngx_http_variable_value_t *v, uintptr_t data); | |
2011 | 85 static ngx_int_t ngx_http_variable_hostname(ngx_http_request_t *r, |
86 ngx_http_variable_value_t *v, uintptr_t data); | |
2249 | 87 static ngx_int_t ngx_http_variable_pid(ngx_http_request_t *r, |
88 ngx_http_variable_value_t *v, uintptr_t data); | |
499 | 89 |
509 | 90 /* |
91 * TODO: | |
92 * Apache CGI: AUTH_TYPE, PATH_INFO (null), PATH_TRANSLATED | |
93 * REMOTE_HOST (null), REMOTE_IDENT (null), | |
94 * SERVER_SOFTWARE | |
95 * | |
571 | 96 * Apache SSI: DOCUMENT_NAME, LAST_MODIFIED, USER_NAME (file owner) |
509 | 97 */ |
499 | 98 |
641 | 99 /* |
100 * the $http_host, $http_user_agent, $http_referer, $http_via, | |
101 * and $http_x_forwarded_for variables may be handled by generic | |
102 * ngx_http_variable_unknown_header_in(), but for perfomance reasons | |
103 * they are handled using dedicated entries | |
104 */ | |
105 | |
509 | 106 static ngx_http_variable_t ngx_http_core_variables[] = { |
107 | |
637 | 108 { ngx_string("http_host"), NULL, ngx_http_variable_header, |
533 | 109 offsetof(ngx_http_request_t, headers_in.host), 0, 0 }, |
499 | 110 |
637 | 111 { ngx_string("http_user_agent"), NULL, ngx_http_variable_header, |
533 | 112 offsetof(ngx_http_request_t, headers_in.user_agent), 0, 0 }, |
509 | 113 |
637 | 114 { ngx_string("http_referer"), NULL, ngx_http_variable_header, |
533 | 115 offsetof(ngx_http_request_t, headers_in.referer), 0, 0 }, |
499 | 116 |
117 #if (NGX_HTTP_GZIP) | |
637 | 118 { ngx_string("http_via"), NULL, ngx_http_variable_header, |
533 | 119 offsetof(ngx_http_request_t, headers_in.via), 0, 0 }, |
499 | 120 #endif |
121 | |
1113
f1d7cf0f68e3
optimize $http_x_forwarded_for
Igor Sysoev <igor@sysoev.ru>
parents:
983
diff
changeset
|
122 #if (NGX_HTTP_PROXY || NGX_HTTP_REALIP) |
637 | 123 { ngx_string("http_x_forwarded_for"), NULL, ngx_http_variable_header, |
533 | 124 offsetof(ngx_http_request_t, headers_in.x_forwarded_for), 0, 0 }, |
499 | 125 #endif |
126 | |
637 | 127 { ngx_string("http_cookie"), NULL, ngx_http_variable_headers, |
533 | 128 offsetof(ngx_http_request_t, headers_in.cookies), 0, 0 }, |
515 | 129 |
637 | 130 { ngx_string("content_length"), NULL, ngx_http_variable_header, |
533 | 131 offsetof(ngx_http_request_t, headers_in.content_length), 0, 0 }, |
509 | 132 |
637 | 133 { ngx_string("content_type"), NULL, ngx_http_variable_header, |
533 | 134 offsetof(ngx_http_request_t, headers_in.content_type), 0, 0 }, |
509 | 135 |
637 | 136 { ngx_string("host"), NULL, ngx_http_variable_host, 0, 0, 0 }, |
509 | 137 |
982 | 138 { ngx_string("binary_remote_addr"), NULL, |
983
7a8ca436d611
ngx_http_variable_binary_remote_addr()
Igor Sysoev <igor@sysoev.ru>
parents:
982
diff
changeset
|
139 ngx_http_variable_binary_remote_addr, 0, 0, 0 }, |
982 | 140 |
637 | 141 { ngx_string("remote_addr"), NULL, ngx_http_variable_remote_addr, 0, 0, 0 }, |
499 | 142 |
637 | 143 { ngx_string("remote_port"), NULL, ngx_http_variable_remote_port, 0, 0, 0 }, |
509 | 144 |
637 | 145 { ngx_string("server_addr"), NULL, ngx_http_variable_server_addr, 0, 0, 0 }, |
509 | 146 |
637 | 147 { ngx_string("server_port"), NULL, ngx_http_variable_server_port, 0, 0, 0 }, |
509 | 148 |
637 | 149 { ngx_string("server_protocol"), NULL, ngx_http_variable_request, |
533 | 150 offsetof(ngx_http_request_t, http_protocol), 0, 0 }, |
509 | 151 |
731 | 152 { ngx_string("scheme"), NULL, ngx_http_variable_scheme, 0, 0, 0 }, |
153 | |
637 | 154 { ngx_string("request_uri"), NULL, ngx_http_variable_request, |
533 | 155 offsetof(ngx_http_request_t, unparsed_uri), 0, 0 }, |
499 | 156 |
637 | 157 { ngx_string("uri"), NULL, ngx_http_variable_request, |
158 offsetof(ngx_http_request_t, uri), | |
1565 | 159 NGX_HTTP_VAR_NOCACHEABLE, 0 }, |
637 | 160 |
161 { ngx_string("document_uri"), NULL, ngx_http_variable_request, | |
573 | 162 offsetof(ngx_http_request_t, uri), |
1565 | 163 NGX_HTTP_VAR_NOCACHEABLE, 0 }, |
573 | 164 |
637 | 165 { ngx_string("request"), NULL, ngx_http_variable_request, |
569 | 166 offsetof(ngx_http_request_t, request_line), 0, 0 }, |
167 | |
637 | 168 { ngx_string("document_root"), NULL, |
1565 | 169 ngx_http_variable_document_root, 0, NGX_HTTP_VAR_NOCACHEABLE, 0 }, |
509 | 170 |
2259 | 171 { ngx_string("realpath_root"), NULL, |
172 ngx_http_variable_realpath_root, 0, NGX_HTTP_VAR_NOCACHEABLE, 0 }, | |
173 | |
637 | 174 { ngx_string("query_string"), NULL, ngx_http_variable_request, |
509 | 175 offsetof(ngx_http_request_t, args), |
1565 | 176 NGX_HTTP_VAR_NOCACHEABLE, 0 }, |
499 | 177 |
1350 | 178 { ngx_string("args"), |
179 ngx_http_variable_request_set, | |
180 ngx_http_variable_request, | |
589 | 181 offsetof(ngx_http_request_t, args), |
1565 | 182 NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE, 0 }, |
589 | 183 |
1351 | 184 { ngx_string("is_args"), NULL, ngx_http_variable_is_args, |
1565 | 185 0, NGX_HTTP_VAR_NOCACHEABLE, 0 }, |
1351 | 186 |
637 | 187 { ngx_string("request_filename"), NULL, |
188 ngx_http_variable_request_filename, 0, | |
1565 | 189 NGX_HTTP_VAR_NOCACHEABLE, 0 }, |
509 | 190 |
1811 | 191 { ngx_string("server_name"), NULL, ngx_http_variable_server_name, 0, 0, 0 }, |
509 | 192 |
637 | 193 { ngx_string("request_method"), NULL, |
194 ngx_http_variable_request_method, 0, 0, 0 }, | |
509 | 195 |
637 | 196 { ngx_string("remote_user"), NULL, ngx_http_variable_remote_user, 0, 0, 0 }, |
509 | 197 |
637 | 198 { ngx_string("body_bytes_sent"), NULL, ngx_http_variable_body_bytes_sent, |
611 | 199 0, 0, 0 }, |
200 | |
637 | 201 { ngx_string("request_completion"), NULL, |
202 ngx_http_variable_request_completion, | |
629 | 203 0, 0, 0 }, |
204 | |
759 | 205 { ngx_string("request_body_file"), NULL, |
206 ngx_http_variable_request_body_file, | |
207 0, 0, 0 }, | |
208 | |
641 | 209 { ngx_string("sent_http_content_type"), NULL, |
210 ngx_http_variable_sent_content_type, 0, 0, 0 }, | |
211 | |
212 { ngx_string("sent_http_content_length"), NULL, | |
213 ngx_http_variable_sent_content_length, 0, 0, 0 }, | |
214 | |
2485
51b1097dbb67
fix $sent_http_location for local redirects
Igor Sysoev <igor@sysoev.ru>
parents:
2415
diff
changeset
|
215 { ngx_string("sent_http_location"), NULL, |
51b1097dbb67
fix $sent_http_location for local redirects
Igor Sysoev <igor@sysoev.ru>
parents:
2415
diff
changeset
|
216 ngx_http_variable_sent_location, 0, 0, 0 }, |
51b1097dbb67
fix $sent_http_location for local redirects
Igor Sysoev <igor@sysoev.ru>
parents:
2415
diff
changeset
|
217 |
641 | 218 { ngx_string("sent_http_last_modified"), NULL, |
219 ngx_http_variable_sent_last_modified, 0, 0, 0 }, | |
220 | |
221 { ngx_string("sent_http_connection"), NULL, | |
222 ngx_http_variable_sent_connection, 0, 0, 0 }, | |
223 | |
224 { ngx_string("sent_http_keep_alive"), NULL, | |
225 ngx_http_variable_sent_keep_alive, 0, 0, 0 }, | |
226 | |
227 { ngx_string("sent_http_transfer_encoding"), NULL, | |
228 ngx_http_variable_sent_transfer_encoding, 0, 0, 0 }, | |
229 | |
230 { ngx_string("sent_http_cache_control"), NULL, ngx_http_variable_headers, | |
231 offsetof(ngx_http_request_t, headers_out.cache_control), 0, 0 }, | |
232 | |
637 | 233 { ngx_string("limit_rate"), ngx_http_variable_request_set_size, |
234 ngx_http_variable_request, | |
235 offsetof(ngx_http_request_t, limit_rate), | |
1565 | 236 NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE, 0 }, |
637 | 237 |
1329 | 238 { ngx_string("nginx_version"), NULL, ngx_http_variable_nginx_version, |
239 0, 0, 0 }, | |
240 | |
2011 | 241 { ngx_string("hostname"), NULL, ngx_http_variable_hostname, |
242 0, 0, 0 }, | |
243 | |
2249 | 244 { ngx_string("pid"), NULL, ngx_http_variable_pid, |
245 0, 0, 0 }, | |
246 | |
637 | 247 { ngx_null_string, NULL, NULL, 0, 0, 0 } |
499 | 248 }; |
249 | |
250 | |
577 | 251 ngx_http_variable_value_t ngx_http_variable_null_value = |
252 ngx_http_variable(""); | |
253 ngx_http_variable_value_t ngx_http_variable_true_value = | |
254 ngx_http_variable("1"); | |
255 | |
256 | |
499 | 257 ngx_http_variable_t * |
509 | 258 ngx_http_add_variable(ngx_conf_t *cf, ngx_str_t *name, ngx_uint_t flags) |
259 { | |
611 | 260 ngx_int_t rc; |
509 | 261 ngx_uint_t i; |
611 | 262 ngx_hash_key_t *key; |
509 | 263 ngx_http_variable_t *v; |
264 ngx_http_core_main_conf_t *cmcf; | |
265 | |
266 cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); | |
267 | |
611 | 268 key = cmcf->variables_keys->keys.elts; |
269 for (i = 0; i < cmcf->variables_keys->keys.nelts; i++) { | |
270 if (name->len != key[i].key.len | |
271 || ngx_strncasecmp(name->data, key[i].key.data, name->len) != 0) | |
509 | 272 { |
273 continue; | |
274 } | |
275 | |
611 | 276 v = key[i].value; |
277 | |
1565 | 278 if (!(v->flags & NGX_HTTP_VAR_CHANGEABLE)) { |
509 | 279 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
280 "the duplicate \"%V\" variable", name); | |
281 return NULL; | |
282 } | |
283 | |
611 | 284 return v; |
509 | 285 } |
286 | |
611 | 287 v = ngx_palloc(cf->pool, sizeof(ngx_http_variable_t)); |
509 | 288 if (v == NULL) { |
289 return NULL; | |
290 } | |
291 | |
292 v->name.len = name->len; | |
2049 | 293 v->name.data = ngx_pnalloc(cf->pool, name->len); |
509 | 294 if (v->name.data == NULL) { |
295 return NULL; | |
296 } | |
297 | |
2135 | 298 ngx_strlow(v->name.data, name->data, name->len); |
509 | 299 |
637 | 300 v->set_handler = NULL; |
301 v->get_handler = NULL; | |
509 | 302 v->data = 0; |
303 v->flags = flags; | |
533 | 304 v->index = 0; |
509 | 305 |
611 | 306 rc = ngx_hash_add_key(cmcf->variables_keys, &v->name, v, 0); |
307 | |
308 if (rc == NGX_ERROR) { | |
309 return NULL; | |
310 } | |
311 | |
312 if (rc == NGX_BUSY) { | |
313 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
314 "conflicting variable name \"%V\"", name); | |
315 return NULL; | |
316 } | |
317 | |
509 | 318 return v; |
319 } | |
320 | |
321 | |
322 ngx_int_t | |
323 ngx_http_get_variable_index(ngx_conf_t *cf, ngx_str_t *name) | |
499 | 324 { |
501 | 325 ngx_uint_t i; |
326 ngx_http_variable_t *v; | |
499 | 327 ngx_http_core_main_conf_t *cmcf; |
328 | |
329 cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); | |
330 | |
501 | 331 v = cmcf->variables.elts; |
332 | |
333 if (v == NULL) { | |
499 | 334 if (ngx_array_init(&cmcf->variables, cf->pool, 4, |
2536
a6d6d762c554
small optimization: " == NGX_ERROR" > " != NGX_OK"
Igor Sysoev <igor@sysoev.ru>
parents:
2533
diff
changeset
|
335 sizeof(ngx_http_variable_t)) |
a6d6d762c554
small optimization: " == NGX_ERROR" > " != NGX_OK"
Igor Sysoev <igor@sysoev.ru>
parents:
2533
diff
changeset
|
336 != NGX_OK) |
499 | 337 { |
509 | 338 return NGX_ERROR; |
499 | 339 } |
501 | 340 |
341 } else { | |
342 for (i = 0; i < cmcf->variables.nelts; i++) { | |
343 if (name->len != v[i].name.len | |
344 || ngx_strncasecmp(name->data, v[i].name.data, name->len) != 0) | |
345 { | |
346 continue; | |
347 } | |
348 | |
509 | 349 return i; |
501 | 350 } |
499 | 351 } |
352 | |
501 | 353 v = ngx_array_push(&cmcf->variables); |
354 if (v == NULL) { | |
509 | 355 return NGX_ERROR; |
499 | 356 } |
357 | |
501 | 358 v->name.len = name->len; |
2049 | 359 v->name.data = ngx_pnalloc(cf->pool, name->len); |
501 | 360 if (v->name.data == NULL) { |
509 | 361 return NGX_ERROR; |
501 | 362 } |
499 | 363 |
2135 | 364 ngx_strlow(v->name.data, name->data, name->len); |
501 | 365 |
637 | 366 v->set_handler = NULL; |
367 v->get_handler = NULL; | |
501 | 368 v->data = 0; |
509 | 369 v->flags = 0; |
533 | 370 v->index = cmcf->variables.nelts - 1; |
501 | 371 |
509 | 372 return cmcf->variables.nelts - 1; |
499 | 373 } |
374 | |
375 | |
376 ngx_http_variable_value_t * | |
377 ngx_http_get_indexed_variable(ngx_http_request_t *r, ngx_uint_t index) | |
378 { | |
501 | 379 ngx_http_variable_t *v; |
499 | 380 ngx_http_core_main_conf_t *cmcf; |
381 | |
382 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); | |
383 | |
553 | 384 if (cmcf->variables.nelts <= index) { |
499 | 385 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, |
386 "unknown variable index: %d", index); | |
387 return NULL; | |
388 } | |
389 | |
573 | 390 if (r->variables[index].not_found || r->variables[index].valid) { |
391 return &r->variables[index]; | |
501 | 392 } |
499 | 393 |
501 | 394 v = cmcf->variables.elts; |
499 | 395 |
637 | 396 if (v[index].get_handler(r, &r->variables[index], v[index].data) |
397 == NGX_OK) | |
398 { | |
1565 | 399 if (v[index].flags & NGX_HTTP_VAR_NOCACHEABLE) { |
400 r->variables[index].no_cacheable = 1; | |
499 | 401 } |
573 | 402 |
403 return &r->variables[index]; | |
499 | 404 } |
405 | |
657 | 406 r->variables[index].valid = 0; |
407 r->variables[index].not_found = 1; | |
408 | |
798 | 409 return NULL; |
573 | 410 } |
411 | |
412 | |
413 ngx_http_variable_value_t * | |
414 ngx_http_get_flushed_variable(ngx_http_request_t *r, ngx_uint_t index) | |
415 { | |
1150 | 416 ngx_http_variable_value_t *v; |
573 | 417 |
418 v = &r->variables[index]; | |
419 | |
420 if (v->valid) { | |
1565 | 421 if (!v->no_cacheable) { |
573 | 422 return v; |
423 } | |
424 | |
425 v->valid = 0; | |
426 v->not_found = 0; | |
509 | 427 } |
501 | 428 |
573 | 429 return ngx_http_get_indexed_variable(r, index); |
499 | 430 } |
431 | |
432 | |
433 ngx_http_variable_value_t * | |
635 | 434 ngx_http_get_variable(ngx_http_request_t *r, ngx_str_t *name, ngx_uint_t key, |
435 ngx_uint_t nowarn) | |
499 | 436 { |
501 | 437 ngx_http_variable_t *v; |
573 | 438 ngx_http_variable_value_t *vv; |
499 | 439 ngx_http_core_main_conf_t *cmcf; |
440 | |
441 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); | |
442 | |
611 | 443 v = ngx_hash_find(&cmcf->variables_hash, key, name->data, name->len); |
499 | 444 |
611 | 445 if (v) { |
446 if (v->flags & NGX_HTTP_VAR_INDEXED) { | |
447 return ngx_http_get_indexed_variable(r, v->index); | |
519 | 448 |
449 } else { | |
499 | 450 |
573 | 451 vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)); |
501 | 452 |
637 | 453 if (vv && v->get_handler(r, vv, v->data) == NGX_OK) { |
573 | 454 return vv; |
455 } | |
509 | 456 |
573 | 457 return NULL; |
458 } | |
509 | 459 } |
460 | |
461 vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)); | |
462 if (vv == NULL) { | |
463 return NULL; | |
464 } | |
465 | |
573 | 466 if (ngx_strncmp(name->data, "http_", 5) == 0) { |
499 | 467 |
577 | 468 if (ngx_http_variable_unknown_header_in(r, vv, (uintptr_t) name) |
469 == NGX_OK) | |
470 { | |
471 return vv; | |
472 } | |
473 | |
474 return NULL; | |
475 } | |
476 | |
477 if (ngx_strncmp(name->data, "sent_http_", 10) == 0) { | |
478 | |
479 if (ngx_http_variable_unknown_header_out(r, vv, (uintptr_t) name) | |
480 == NGX_OK) | |
573 | 481 { |
482 return vv; | |
483 } | |
499 | 484 |
485 return NULL; | |
486 } | |
487 | |
1162 | 488 if (ngx_strncmp(name->data, "upstream_http_", 10) == 0) { |
489 | |
490 if (ngx_http_upstream_header_variable(r, vv, (uintptr_t) name) | |
491 == NGX_OK) | |
492 { | |
493 return vv; | |
494 } | |
495 | |
496 return NULL; | |
497 } | |
498 | |
2307 | 499 if (ngx_strncmp(name->data, "cookie_", 7) == 0) { |
500 | |
2359
4fee4ebbfb0b
$cookie_... variable did not for SSI and perl
Igor Sysoev <igor@sysoev.ru>
parents:
2333
diff
changeset
|
501 if (ngx_http_variable_cookie(r, vv, (uintptr_t) name) == NGX_OK) { |
2307 | 502 return vv; |
503 } | |
504 | |
505 return NULL; | |
506 } | |
507 | |
2137 | 508 if (ngx_strncmp(name->data, "arg_", 4) == 0) { |
509 | |
510 if (ngx_http_variable_argument(r, vv, (uintptr_t) name) == NGX_OK) { | |
511 return vv; | |
512 } | |
513 | |
514 return NULL; | |
515 } | |
516 | |
635 | 517 vv->not_found = 1; |
573 | 518 |
635 | 519 if (nowarn == 0) { |
520 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
521 "unknown \"%V\" variable", name); | |
522 } | |
499 | 523 |
501 | 524 return vv; |
499 | 525 } |
526 | |
527 | |
573 | 528 static ngx_int_t |
529 ngx_http_variable_request(ngx_http_request_t *r, ngx_http_variable_value_t *v, | |
530 uintptr_t data) | |
531 { | |
532 ngx_str_t *s; | |
533 | |
534 s = (ngx_str_t *) ((char *) r + data); | |
535 | |
536 if (s->data) { | |
537 v->len = s->len; | |
538 v->valid = 1; | |
1565 | 539 v->no_cacheable = 0; |
573 | 540 v->not_found = 0; |
541 v->data = s->data; | |
542 | |
543 } else { | |
544 v->not_found = 1; | |
545 } | |
546 | |
547 return NGX_OK; | |
548 } | |
549 | |
550 | |
637 | 551 static void |
1350 | 552 ngx_http_variable_request_set(ngx_http_request_t *r, |
553 ngx_http_variable_value_t *v, uintptr_t data) | |
554 { | |
555 ngx_str_t *s; | |
556 | |
557 s = (ngx_str_t *) ((char *) r + data); | |
558 | |
559 s->len = v->len; | |
560 s->data = v->data; | |
561 } | |
562 | |
563 | |
564 static void | |
637 | 565 ngx_http_variable_request_set_size(ngx_http_request_t *r, |
566 ngx_http_variable_value_t *v, uintptr_t data) | |
567 { | |
568 ssize_t s, *sp; | |
569 ngx_str_t val; | |
570 | |
1310
33d6c994a0b2
Sun Studio on sparc uses different bit order
Igor Sysoev <igor@sysoev.ru>
parents:
1191
diff
changeset
|
571 val.len = v->len; |
637 | 572 val.data = v->data; |
573 | |
574 s = ngx_parse_size(&val); | |
575 | |
576 if (s == NGX_ERROR) { | |
577 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
578 "invalid size \"%V\"", &val); | |
579 return; | |
580 } | |
581 | |
582 sp = (ssize_t *) ((char *) r + data); | |
583 | |
584 *sp = s; | |
585 | |
586 return; | |
587 } | |
588 | |
589 | |
573 | 590 static ngx_int_t |
591 ngx_http_variable_header(ngx_http_request_t *r, ngx_http_variable_value_t *v, | |
592 uintptr_t data) | |
515 | 593 { |
573 | 594 ngx_table_elt_t *h; |
595 | |
596 h = *(ngx_table_elt_t **) ((char *) r + data); | |
597 | |
598 if (h) { | |
599 v->len = h->value.len; | |
600 v->valid = 1; | |
1565 | 601 v->no_cacheable = 0; |
573 | 602 v->not_found = 0; |
603 v->data = h->value.data; | |
604 | |
605 } else { | |
606 v->not_found = 1; | |
607 } | |
608 | |
609 return NGX_OK; | |
610 } | |
611 | |
612 | |
613 static ngx_int_t | |
614 ngx_http_variable_headers(ngx_http_request_t *r, ngx_http_variable_value_t *v, | |
615 uintptr_t data) | |
616 { | |
667 | 617 ssize_t len; |
573 | 618 u_char *p; |
667 | 619 ngx_uint_t i, n; |
573 | 620 ngx_array_t *a; |
621 ngx_table_elt_t **h; | |
515 | 622 |
623 a = (ngx_array_t *) ((char *) r + data); | |
624 | |
667 | 625 n = a->nelts; |
626 | |
627 if (n == 0) { | |
573 | 628 v->not_found = 1; |
629 return NGX_OK; | |
515 | 630 } |
631 | |
573 | 632 v->valid = 1; |
1565 | 633 v->no_cacheable = 0; |
573 | 634 v->not_found = 0; |
515 | 635 |
636 h = a->elts; | |
637 | |
667 | 638 if (n == 1) { |
573 | 639 v->len = (*h)->value.len; |
640 v->data = (*h)->value.data; | |
515 | 641 |
573 | 642 return NGX_OK; |
515 | 643 } |
644 | |
667 | 645 len = - (ssize_t) (sizeof("; ") - 1); |
573 | 646 |
667 | 647 for (i = 0; i < n; i++) { |
573 | 648 len += h[i]->value.len + sizeof("; ") - 1; |
515 | 649 } |
650 | |
2049 | 651 p = ngx_pnalloc(r->pool, len); |
573 | 652 if (p == NULL) { |
653 return NGX_ERROR; | |
654 } | |
655 | |
656 v->len = len; | |
657 v->data = p; | |
515 | 658 |
659 for (i = 0; /* void */ ; i++) { | |
573 | 660 p = ngx_copy(p, h[i]->value.data, h[i]->value.len); |
515 | 661 |
667 | 662 if (i == n - 1) { |
515 | 663 break; |
664 } | |
665 | |
666 *p++ = ';'; *p++ = ' '; | |
667 } | |
668 | |
573 | 669 return NGX_OK; |
515 | 670 } |
671 | |
672 | |
573 | 673 static ngx_int_t |
577 | 674 ngx_http_variable_unknown_header_in(ngx_http_request_t *r, |
675 ngx_http_variable_value_t *v, uintptr_t data) | |
676 { | |
677 return ngx_http_variable_unknown_header(v, (ngx_str_t *) data, | |
678 &r->headers_in.headers.part, | |
679 sizeof("http_") - 1); | |
680 } | |
681 | |
682 | |
683 static ngx_int_t | |
684 ngx_http_variable_unknown_header_out(ngx_http_request_t *r, | |
573 | 685 ngx_http_variable_value_t *v, uintptr_t data) |
499 | 686 { |
577 | 687 return ngx_http_variable_unknown_header(v, (ngx_str_t *) data, |
688 &r->headers_out.headers.part, | |
689 sizeof("sent_http_") - 1); | |
690 } | |
501 | 691 |
577 | 692 |
1162 | 693 ngx_int_t |
577 | 694 ngx_http_variable_unknown_header(ngx_http_variable_value_t *v, ngx_str_t *var, |
695 ngx_list_part_t *part, size_t prefix) | |
696 { | |
573 | 697 u_char ch; |
698 ngx_uint_t i, n; | |
699 ngx_table_elt_t *header; | |
499 | 700 |
701 header = part->elts; | |
702 | |
703 for (i = 0; /* void */ ; i++) { | |
704 | |
705 if (i >= part->nelts) { | |
706 if (part->next == NULL) { | |
707 break; | |
708 } | |
709 | |
710 part = part->next; | |
711 header = part->elts; | |
712 i = 0; | |
713 } | |
714 | |
577 | 715 for (n = 0; n + prefix < var->len && n < header[i].key.len; n++) { |
499 | 716 ch = header[i].key.data[n]; |
717 | |
509 | 718 if (ch >= 'A' && ch <= 'Z') { |
719 ch |= 0x20; | |
499 | 720 |
721 } else if (ch == '-') { | |
722 ch = '_'; | |
723 } | |
724 | |
577 | 725 if (var->data[n + prefix] != ch) { |
499 | 726 break; |
727 } | |
728 } | |
729 | |
742
75d767d32624
nonexistent $sent_http_content has value of $sent_http_content_length or so
Igor Sysoev <igor@sysoev.ru>
parents:
732
diff
changeset
|
730 if (n + prefix == var->len && n == header[i].key.len) { |
573 | 731 v->len = header[i].value.len; |
732 v->valid = 1; | |
1565 | 733 v->no_cacheable = 0; |
573 | 734 v->not_found = 0; |
735 v->data = header[i].value.data; | |
499 | 736 |
573 | 737 return NGX_OK; |
499 | 738 } |
739 } | |
740 | |
573 | 741 v->not_found = 1; |
742 | |
743 return NGX_OK; | |
509 | 744 } |
745 | |
746 | |
573 | 747 static ngx_int_t |
2307 | 748 ngx_http_variable_cookie(ngx_http_request_t *r, ngx_http_variable_value_t *v, |
749 uintptr_t data) | |
750 { | |
751 ngx_str_t *name = (ngx_str_t *) data; | |
752 | |
753 ngx_str_t cookie, s; | |
754 | |
755 s.len = name->len - (sizeof("cookie_") - 1); | |
756 s.data = name->data + sizeof("cookie_") - 1; | |
757 | |
758 if (ngx_http_parse_multi_header_lines(&r->headers_in.cookies, &s, &cookie) | |
759 == NGX_DECLINED) | |
760 { | |
761 v->not_found = 1; | |
762 return NGX_OK; | |
763 } | |
764 | |
765 v->len = cookie.len; | |
766 v->valid = 1; | |
767 v->no_cacheable = 0; | |
768 v->not_found = 0; | |
769 v->data = cookie.data; | |
770 | |
771 return NGX_OK; | |
772 } | |
773 | |
774 | |
775 static ngx_int_t | |
2137 | 776 ngx_http_variable_argument(ngx_http_request_t *r, ngx_http_variable_value_t *v, |
777 uintptr_t data) | |
778 { | |
779 ngx_str_t *name = (ngx_str_t *) data; | |
780 | |
2415 | 781 u_char *arg; |
782 size_t len; | |
783 ngx_str_t value; | |
2137 | 784 |
2415 | 785 len = name->len - (sizeof("arg_") - 1); |
786 arg = name->data + sizeof("arg_") - 1; | |
787 | |
788 if (ngx_http_arg(r, arg, len, &value) != NGX_OK) { | |
2137 | 789 v->not_found = 1; |
790 return NGX_OK; | |
791 } | |
792 | |
2415 | 793 v->data = value.data; |
794 v->len = value.len; | |
795 v->valid = 1; | |
796 v->no_cacheable = 0; | |
797 v->not_found = 0; | |
2137 | 798 |
799 return NGX_OK; | |
800 } | |
801 | |
802 | |
803 static ngx_int_t | |
573 | 804 ngx_http_variable_host(ngx_http_request_t *r, ngx_http_variable_value_t *v, |
805 uintptr_t data) | |
509 | 806 { |
1811 | 807 ngx_http_core_srv_conf_t *cscf; |
808 | |
2007
b9de93d804ea
*) host in request line has priority
Igor Sysoev <igor@sysoev.ru>
parents:
1811
diff
changeset
|
809 if (r->headers_in.server.len) { |
b9de93d804ea
*) host in request line has priority
Igor Sysoev <igor@sysoev.ru>
parents:
1811
diff
changeset
|
810 v->len = r->headers_in.server.len; |
b9de93d804ea
*) host in request line has priority
Igor Sysoev <igor@sysoev.ru>
parents:
1811
diff
changeset
|
811 v->data = r->headers_in.server.data; |
928
a6fe6bedb9e3
fix segfault when $host is used and
Igor Sysoev <igor@sysoev.ru>
parents:
864
diff
changeset
|
812 |
a6fe6bedb9e3
fix segfault when $host is used and
Igor Sysoev <igor@sysoev.ru>
parents:
864
diff
changeset
|
813 } else { |
2007
b9de93d804ea
*) host in request line has priority
Igor Sysoev <igor@sysoev.ru>
parents:
1811
diff
changeset
|
814 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); |
b9de93d804ea
*) host in request line has priority
Igor Sysoev <igor@sysoev.ru>
parents:
1811
diff
changeset
|
815 |
b9de93d804ea
*) host in request line has priority
Igor Sysoev <igor@sysoev.ru>
parents:
1811
diff
changeset
|
816 v->len = cscf->server_name.len; |
b9de93d804ea
*) host in request line has priority
Igor Sysoev <igor@sysoev.ru>
parents:
1811
diff
changeset
|
817 v->data = cscf->server_name.data; |
509 | 818 } |
819 | |
573 | 820 v->valid = 1; |
1565 | 821 v->no_cacheable = 0; |
573 | 822 v->not_found = 0; |
509 | 823 |
573 | 824 return NGX_OK; |
499 | 825 } |
826 | |
827 | |
573 | 828 static ngx_int_t |
983
7a8ca436d611
ngx_http_variable_binary_remote_addr()
Igor Sysoev <igor@sysoev.ru>
parents:
982
diff
changeset
|
829 ngx_http_variable_binary_remote_addr(ngx_http_request_t *r, |
573 | 830 ngx_http_variable_value_t *v, uintptr_t data) |
499 | 831 { |
2512
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
832 struct sockaddr_in *sin; |
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
833 #if (NGX_HAVE_INET6) |
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
834 struct sockaddr_in6 *sin6; |
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
835 #endif |
982 | 836 |
2512
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
837 switch (r->connection->sockaddr->sa_family) { |
983
7a8ca436d611
ngx_http_variable_binary_remote_addr()
Igor Sysoev <igor@sysoev.ru>
parents:
982
diff
changeset
|
838 |
2512
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
839 #if (NGX_HAVE_INET6) |
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
840 case AF_INET6: |
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
841 sin6 = (struct sockaddr_in6 *) r->connection->sockaddr; |
982 | 842 |
2512
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
843 v->len = sizeof(struct in6_addr); |
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
844 v->valid = 1; |
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
845 v->no_cacheable = 0; |
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
846 v->not_found = 0; |
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
847 v->data = (u_char *) &sin6->sin6_addr; |
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
848 |
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
849 break; |
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
850 #endif |
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
851 |
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
852 default: /* AF_INET */ |
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
853 sin = (struct sockaddr_in *) r->connection->sockaddr; |
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
854 |
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
855 v->len = sizeof(in_addr_t); |
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
856 v->valid = 1; |
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
857 v->no_cacheable = 0; |
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
858 v->not_found = 0; |
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
859 v->data = (u_char *) &sin->sin_addr; |
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
860 |
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
861 break; |
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
862 } |
982 | 863 |
983
7a8ca436d611
ngx_http_variable_binary_remote_addr()
Igor Sysoev <igor@sysoev.ru>
parents:
982
diff
changeset
|
864 return NGX_OK; |
7a8ca436d611
ngx_http_variable_binary_remote_addr()
Igor Sysoev <igor@sysoev.ru>
parents:
982
diff
changeset
|
865 } |
982 | 866 |
867 | |
983
7a8ca436d611
ngx_http_variable_binary_remote_addr()
Igor Sysoev <igor@sysoev.ru>
parents:
982
diff
changeset
|
868 static ngx_int_t |
7a8ca436d611
ngx_http_variable_binary_remote_addr()
Igor Sysoev <igor@sysoev.ru>
parents:
982
diff
changeset
|
869 ngx_http_variable_remote_addr(ngx_http_request_t *r, |
7a8ca436d611
ngx_http_variable_binary_remote_addr()
Igor Sysoev <igor@sysoev.ru>
parents:
982
diff
changeset
|
870 ngx_http_variable_value_t *v, uintptr_t data) |
7a8ca436d611
ngx_http_variable_binary_remote_addr()
Igor Sysoev <igor@sysoev.ru>
parents:
982
diff
changeset
|
871 { |
7a8ca436d611
ngx_http_variable_binary_remote_addr()
Igor Sysoev <igor@sysoev.ru>
parents:
982
diff
changeset
|
872 v->len = r->connection->addr_text.len; |
7a8ca436d611
ngx_http_variable_binary_remote_addr()
Igor Sysoev <igor@sysoev.ru>
parents:
982
diff
changeset
|
873 v->valid = 1; |
1565 | 874 v->no_cacheable = 0; |
983
7a8ca436d611
ngx_http_variable_binary_remote_addr()
Igor Sysoev <igor@sysoev.ru>
parents:
982
diff
changeset
|
875 v->not_found = 0; |
7a8ca436d611
ngx_http_variable_binary_remote_addr()
Igor Sysoev <igor@sysoev.ru>
parents:
982
diff
changeset
|
876 v->data = r->connection->addr_text.data; |
499 | 877 |
573 | 878 return NGX_OK; |
499 | 879 } |
880 | |
881 | |
573 | 882 static ngx_int_t |
883 ngx_http_variable_remote_port(ngx_http_request_t *r, | |
884 ngx_http_variable_value_t *v, uintptr_t data) | |
499 | 885 { |
2512
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
886 ngx_uint_t port; |
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
887 struct sockaddr_in *sin; |
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
888 #if (NGX_HAVE_INET6) |
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
889 struct sockaddr_in6 *sin6; |
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
890 #endif |
509 | 891 |
573 | 892 v->len = 0; |
893 v->valid = 1; | |
1565 | 894 v->no_cacheable = 0; |
573 | 895 v->not_found = 0; |
509 | 896 |
2049 | 897 v->data = ngx_pnalloc(r->pool, sizeof("65535") - 1); |
573 | 898 if (v->data == NULL) { |
899 return NGX_ERROR; | |
509 | 900 } |
901 | |
2512
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
902 switch (r->connection->sockaddr->sa_family) { |
577 | 903 |
2512
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
904 #if (NGX_HAVE_INET6) |
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
905 case AF_INET6: |
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
906 sin6 = (struct sockaddr_in6 *) r->connection->sockaddr; |
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
907 port = ntohs(sin6->sin6_port); |
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
908 break; |
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
909 #endif |
577 | 910 |
2512
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
911 default: /* AF_INET */ |
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
912 sin = (struct sockaddr_in *) r->connection->sockaddr; |
509 | 913 port = ntohs(sin->sin_port); |
2512
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
914 break; |
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
915 } |
577 | 916 |
2512
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
917 if (port > 0 && port < 65536) { |
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
918 v->len = ngx_sprintf(v->data, "%ui", port) - v->data; |
509 | 919 } |
920 | |
573 | 921 return NGX_OK; |
509 | 922 } |
923 | |
924 | |
573 | 925 static ngx_int_t |
926 ngx_http_variable_server_addr(ngx_http_request_t *r, | |
927 ngx_http_variable_value_t *v, uintptr_t data) | |
509 | 928 { |
1805 | 929 ngx_str_t s; |
2512
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
930 u_char addr[NGX_SOCKADDR_STRLEN]; |
499 | 931 |
2512
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
932 s.len = NGX_SOCKADDR_STRLEN; |
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
933 s.data = addr; |
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
934 |
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
935 if (ngx_http_server_addr(r, &s) != NGX_OK) { |
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
936 return NGX_ERROR; |
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
937 } |
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
938 |
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
939 s.data = ngx_pnalloc(r->pool, s.len); |
1805 | 940 if (s.data == NULL) { |
573 | 941 return NGX_ERROR; |
509 | 942 } |
943 | |
2512
2e91aecb9e57
a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents:
2485
diff
changeset
|
944 ngx_memcpy(s.data, addr, s.len); |
509 | 945 |
1805 | 946 v->len = s.len; |
573 | 947 v->valid = 1; |
1565 | 948 v->no_cacheable = 0; |
573 | 949 v->not_found = 0; |
1805 | 950 v->data = s.data; |
499 | 951 |
573 | 952 return NGX_OK; |
499 | 953 } |
954 | |
955 | |
573 | 956 static ngx_int_t |
957 ngx_http_variable_server_port(ngx_http_request_t *r, | |
958 ngx_http_variable_value_t *v, uintptr_t data) | |
509 | 959 { |
2533 | 960 ngx_uint_t port; |
961 struct sockaddr_in *sin; | |
962 #if (NGX_HAVE_INET6) | |
963 struct sockaddr_in6 *sin6; | |
964 #endif | |
965 | |
966 v->len = 0; | |
573 | 967 v->valid = 1; |
1565 | 968 v->no_cacheable = 0; |
573 | 969 v->not_found = 0; |
2533 | 970 |
971 if (ngx_http_server_addr(r, NULL) != NGX_OK) { | |
972 return NGX_ERROR; | |
973 } | |
974 | |
975 v->data = ngx_pnalloc(r->pool, sizeof("65535") - 1); | |
976 if (v->data == NULL) { | |
977 return NGX_ERROR; | |
978 } | |
979 | |
980 switch (r->connection->local_sockaddr->sa_family) { | |
981 | |
982 #if (NGX_HAVE_INET6) | |
983 case AF_INET6: | |
984 sin6 = (struct sockaddr_in6 *) r->connection->local_sockaddr; | |
985 port = ntohs(sin6->sin6_port); | |
986 break; | |
987 #endif | |
988 | |
989 default: /* AF_INET */ | |
990 sin = (struct sockaddr_in *) r->connection->local_sockaddr; | |
991 port = ntohs(sin->sin_port); | |
992 break; | |
993 } | |
994 | |
995 if (port > 0 && port < 65536) { | |
996 v->len = ngx_sprintf(v->data, "%ui", port) - v->data; | |
997 } | |
509 | 998 |
573 | 999 return NGX_OK; |
509 | 1000 } |
1001 | |
1002 | |
573 | 1003 static ngx_int_t |
731 | 1004 ngx_http_variable_scheme(ngx_http_request_t *r, |
1005 ngx_http_variable_value_t *v, uintptr_t data) | |
1006 { | |
1007 #if (NGX_HTTP_SSL) | |
1008 | |
1009 if (r->connection->ssl) { | |
1010 v->len = sizeof("https") - 1; | |
1011 v->valid = 1; | |
1565 | 1012 v->no_cacheable = 0; |
731 | 1013 v->not_found = 0; |
732 | 1014 v->data = (u_char *) "https"; |
731 | 1015 |
1016 return NGX_OK; | |
1017 } | |
1018 | |
1019 #endif | |
1020 | |
1021 v->len = sizeof("http") - 1; | |
1022 v->valid = 1; | |
1565 | 1023 v->no_cacheable = 0; |
731 | 1024 v->not_found = 0; |
732 | 1025 v->data = (u_char *) "http"; |
731 | 1026 |
1027 return NGX_OK; | |
1028 } | |
1029 | |
1030 | |
1031 static ngx_int_t | |
1351 | 1032 ngx_http_variable_is_args(ngx_http_request_t *r, |
1033 ngx_http_variable_value_t *v, uintptr_t data) | |
1034 { | |
1035 v->valid = 1; | |
1565 | 1036 v->no_cacheable = 0; |
1351 | 1037 v->not_found = 0; |
1038 | |
1039 if (r->args.len == 0) { | |
1040 v->len = 0; | |
1041 v->data = NULL; | |
1042 return NGX_OK; | |
1043 } | |
1044 | |
1045 v->len = 1; | |
1046 v->data = (u_char *) "?"; | |
1047 | |
1048 return NGX_OK; | |
1049 } | |
1050 | |
1051 | |
1052 static ngx_int_t | |
573 | 1053 ngx_http_variable_document_root(ngx_http_request_t *r, |
1054 ngx_http_variable_value_t *v, uintptr_t data) | |
499 | 1055 { |
671 | 1056 ngx_str_t path; |
573 | 1057 ngx_http_core_loc_conf_t *clcf; |
509 | 1058 |
1059 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | |
1060 | |
671 | 1061 if (clcf->root_lengths == NULL) { |
1062 v->len = clcf->root.len; | |
1063 v->valid = 1; | |
1565 | 1064 v->no_cacheable = 0; |
671 | 1065 v->not_found = 0; |
1066 v->data = clcf->root.data; | |
1067 | |
1068 } else { | |
1069 if (ngx_http_script_run(r, &path, clcf->root_lengths->elts, 0, | |
1070 clcf->root_values->elts) | |
1071 == NULL) | |
1072 { | |
1073 return NGX_ERROR; | |
1074 } | |
1075 | |
2536
a6d6d762c554
small optimization: " == NGX_ERROR" > " != NGX_OK"
Igor Sysoev <igor@sysoev.ru>
parents:
2533
diff
changeset
|
1076 if (ngx_conf_full_name((ngx_cycle_t *) ngx_cycle, &path, 0) != NGX_OK) { |
671 | 1077 return NGX_ERROR; |
1078 } | |
1079 | |
1080 v->len = path.len; | |
1081 v->valid = 1; | |
1565 | 1082 v->no_cacheable = 0; |
671 | 1083 v->not_found = 0; |
1084 v->data = path.data; | |
1085 } | |
509 | 1086 |
573 | 1087 return NGX_OK; |
509 | 1088 } |
1089 | |
1090 | |
573 | 1091 static ngx_int_t |
2259 | 1092 ngx_http_variable_realpath_root(ngx_http_request_t *r, |
1093 ngx_http_variable_value_t *v, uintptr_t data) | |
1094 { | |
1095 size_t len; | |
1096 ngx_str_t path; | |
1097 ngx_http_core_loc_conf_t *clcf; | |
1098 u_char real[NGX_MAX_PATH]; | |
1099 | |
1100 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | |
1101 | |
1102 if (clcf->root_lengths == NULL) { | |
1103 path = clcf->root; | |
1104 | |
1105 } else { | |
1106 if (ngx_http_script_run(r, &path, clcf->root_lengths->elts, 1, | |
1107 clcf->root_values->elts) | |
1108 == NULL) | |
1109 { | |
1110 return NGX_ERROR; | |
1111 } | |
1112 | |
1113 path.data[path.len - 1] = '\0'; | |
1114 | |
2536
a6d6d762c554
small optimization: " == NGX_ERROR" > " != NGX_OK"
Igor Sysoev <igor@sysoev.ru>
parents:
2533
diff
changeset
|
1115 if (ngx_conf_full_name((ngx_cycle_t *) ngx_cycle, &path, 0) != NGX_OK) { |
2259 | 1116 return NGX_ERROR; |
1117 } | |
1118 } | |
1119 | |
1120 if (ngx_realpath(path.data, real) == NULL) { | |
1121 ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno, | |
1122 ngx_realpath_n " \"%s\" failed", path.data); | |
1123 return NGX_ERROR; | |
1124 } | |
1125 | |
1126 len = ngx_strlen(real); | |
1127 | |
1128 v->data = ngx_pnalloc(r->pool, len); | |
1129 if (v->data == NULL) { | |
1130 return NGX_ERROR; | |
1131 } | |
1132 | |
1133 v->len = len; | |
1134 v->valid = 1; | |
1135 v->no_cacheable = 0; | |
1136 v->not_found = 0; | |
1137 | |
1138 ngx_memcpy(v->data, real, len); | |
1139 | |
1140 return NGX_OK; | |
1141 } | |
1142 | |
1143 | |
1144 static ngx_int_t | |
573 | 1145 ngx_http_variable_request_filename(ngx_http_request_t *r, |
1146 ngx_http_variable_value_t *v, uintptr_t data) | |
509 | 1147 { |
773 | 1148 size_t root; |
573 | 1149 ngx_str_t path; |
499 | 1150 |
773 | 1151 if (ngx_http_map_uri_to_path(r, &path, &root, 0) == NULL) { |
573 | 1152 return NGX_ERROR; |
557 | 1153 } |
509 | 1154 |
557 | 1155 /* ngx_http_map_uri_to_path() allocates memory for terminating '\0' */ |
509 | 1156 |
573 | 1157 v->len = path.len - 1; |
1158 v->valid = 1; | |
1565 | 1159 v->no_cacheable = 0; |
573 | 1160 v->not_found = 0; |
1161 v->data = path.data; | |
499 | 1162 |
573 | 1163 return NGX_OK; |
499 | 1164 } |
1165 | |
1166 | |
573 | 1167 static ngx_int_t |
1811 | 1168 ngx_http_variable_server_name(ngx_http_request_t *r, |
1169 ngx_http_variable_value_t *v, uintptr_t data) | |
1170 { | |
1171 ngx_http_core_srv_conf_t *cscf; | |
1172 | |
1173 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); | |
1174 | |
1175 v->len = cscf->server_name.len; | |
1176 v->valid = 1; | |
1177 v->no_cacheable = 0; | |
1178 v->not_found = 0; | |
1179 v->data = cscf->server_name.data; | |
1180 | |
1181 return NGX_OK; | |
1182 } | |
1183 | |
1184 | |
1185 static ngx_int_t | |
573 | 1186 ngx_http_variable_request_method(ngx_http_request_t *r, |
1187 ngx_http_variable_value_t *v, uintptr_t data) | |
561 | 1188 { |
647 | 1189 if (r->main->method_name.data) { |
1190 v->len = r->main->method_name.len; | |
573 | 1191 v->valid = 1; |
1565 | 1192 v->no_cacheable = 0; |
573 | 1193 v->not_found = 0; |
647 | 1194 v->data = r->main->method_name.data; |
573 | 1195 |
1196 } else { | |
1197 v->not_found = 1; | |
561 | 1198 } |
1199 | |
573 | 1200 return NGX_OK; |
561 | 1201 } |
1202 | |
1203 | |
573 | 1204 static ngx_int_t |
1205 ngx_http_variable_remote_user(ngx_http_request_t *r, | |
1206 ngx_http_variable_value_t *v, uintptr_t data) | |
539 | 1207 { |
573 | 1208 ngx_int_t rc; |
539 | 1209 |
1210 rc = ngx_http_auth_basic_user(r); | |
1211 | |
1212 if (rc == NGX_DECLINED) { | |
573 | 1213 v->not_found = 1; |
1214 return NGX_OK; | |
539 | 1215 } |
1216 | |
1217 if (rc == NGX_ERROR) { | |
573 | 1218 return NGX_ERROR; |
539 | 1219 } |
1220 | |
573 | 1221 v->len = r->headers_in.user.len; |
1222 v->valid = 1; | |
1565 | 1223 v->no_cacheable = 0; |
573 | 1224 v->not_found = 0; |
1225 v->data = r->headers_in.user.data; | |
571 | 1226 |
573 | 1227 return NGX_OK; |
571 | 1228 } |
1229 | |
1230 | |
611 | 1231 static ngx_int_t |
1232 ngx_http_variable_body_bytes_sent(ngx_http_request_t *r, | |
1233 ngx_http_variable_value_t *v, uintptr_t data) | |
1234 { | |
1235 off_t sent; | |
1236 u_char *p; | |
1237 | |
1238 sent = r->connection->sent - r->header_size; | |
1239 | |
1240 if (sent < 0) { | |
1241 sent = 0; | |
1242 } | |
1243 | |
2049 | 1244 p = ngx_pnalloc(r->pool, NGX_OFF_T_LEN); |
611 | 1245 if (p == NULL) { |
1246 return NGX_ERROR; | |
1247 } | |
1248 | |
1249 v->len = ngx_sprintf(p, "%O", sent) - p; | |
1250 v->valid = 1; | |
1565 | 1251 v->no_cacheable = 0; |
611 | 1252 v->not_found = 0; |
1253 v->data = p; | |
1254 | |
1255 return NGX_OK; | |
1256 } | |
1257 | |
1258 | |
629 | 1259 static ngx_int_t |
641 | 1260 ngx_http_variable_sent_content_type(ngx_http_request_t *r, |
1261 ngx_http_variable_value_t *v, uintptr_t data) | |
1262 { | |
1263 if (r->headers_out.content_type.len) { | |
1264 v->len = r->headers_out.content_type.len; | |
1265 v->valid = 1; | |
1565 | 1266 v->no_cacheable = 0; |
641 | 1267 v->not_found = 0; |
1268 v->data = r->headers_out.content_type.data; | |
1269 | |
1270 } else { | |
1271 v->not_found = 1; | |
1272 } | |
1273 | |
1274 return NGX_OK; | |
1275 } | |
1276 | |
1277 | |
1278 static ngx_int_t | |
1279 ngx_http_variable_sent_content_length(ngx_http_request_t *r, | |
1280 ngx_http_variable_value_t *v, uintptr_t data) | |
1281 { | |
1282 u_char *p; | |
1283 | |
1284 if (r->headers_out.content_length) { | |
1285 v->len = r->headers_out.content_length->value.len; | |
1286 v->valid = 1; | |
1565 | 1287 v->no_cacheable = 0; |
641 | 1288 v->not_found = 0; |
1289 v->data = r->headers_out.content_length->value.data; | |
1290 | |
1291 return NGX_OK; | |
1292 } | |
1293 | |
1294 if (r->headers_out.content_length_n >= 0) { | |
2049 | 1295 p = ngx_pnalloc(r->pool, NGX_OFF_T_LEN); |
641 | 1296 if (p == NULL) { |
1297 return NGX_ERROR; | |
1298 } | |
1299 | |
1300 v->len = ngx_sprintf(p, "%O", r->headers_out.content_length_n) - p; | |
1301 v->valid = 1; | |
1565 | 1302 v->no_cacheable = 0; |
641 | 1303 v->not_found = 0; |
1304 v->data = p; | |
1305 | |
1306 return NGX_OK; | |
1307 } | |
1308 | |
1309 v->not_found = 1; | |
1310 | |
1311 return NGX_OK; | |
1312 } | |
1313 | |
1314 | |
1315 static ngx_int_t | |
2485
51b1097dbb67
fix $sent_http_location for local redirects
Igor Sysoev <igor@sysoev.ru>
parents:
2415
diff
changeset
|
1316 ngx_http_variable_sent_location(ngx_http_request_t *r, |
51b1097dbb67
fix $sent_http_location for local redirects
Igor Sysoev <igor@sysoev.ru>
parents:
2415
diff
changeset
|
1317 ngx_http_variable_value_t *v, uintptr_t data) |
51b1097dbb67
fix $sent_http_location for local redirects
Igor Sysoev <igor@sysoev.ru>
parents:
2415
diff
changeset
|
1318 { |
2539
051e9b12428e
fix segfault introduced in r2486 in $sent_http_location processing
Igor Sysoev <igor@sysoev.ru>
parents:
2536
diff
changeset
|
1319 ngx_str_t name; |
051e9b12428e
fix segfault introduced in r2486 in $sent_http_location processing
Igor Sysoev <igor@sysoev.ru>
parents:
2536
diff
changeset
|
1320 |
2485
51b1097dbb67
fix $sent_http_location for local redirects
Igor Sysoev <igor@sysoev.ru>
parents:
2415
diff
changeset
|
1321 if (r->headers_out.location) { |
51b1097dbb67
fix $sent_http_location for local redirects
Igor Sysoev <igor@sysoev.ru>
parents:
2415
diff
changeset
|
1322 v->len = r->headers_out.location->value.len; |
51b1097dbb67
fix $sent_http_location for local redirects
Igor Sysoev <igor@sysoev.ru>
parents:
2415
diff
changeset
|
1323 v->valid = 1; |
51b1097dbb67
fix $sent_http_location for local redirects
Igor Sysoev <igor@sysoev.ru>
parents:
2415
diff
changeset
|
1324 v->no_cacheable = 0; |
51b1097dbb67
fix $sent_http_location for local redirects
Igor Sysoev <igor@sysoev.ru>
parents:
2415
diff
changeset
|
1325 v->not_found = 0; |
51b1097dbb67
fix $sent_http_location for local redirects
Igor Sysoev <igor@sysoev.ru>
parents:
2415
diff
changeset
|
1326 v->data = r->headers_out.location->value.data; |
51b1097dbb67
fix $sent_http_location for local redirects
Igor Sysoev <igor@sysoev.ru>
parents:
2415
diff
changeset
|
1327 |
51b1097dbb67
fix $sent_http_location for local redirects
Igor Sysoev <igor@sysoev.ru>
parents:
2415
diff
changeset
|
1328 return NGX_OK; |
51b1097dbb67
fix $sent_http_location for local redirects
Igor Sysoev <igor@sysoev.ru>
parents:
2415
diff
changeset
|
1329 } |
51b1097dbb67
fix $sent_http_location for local redirects
Igor Sysoev <igor@sysoev.ru>
parents:
2415
diff
changeset
|
1330 |
2539
051e9b12428e
fix segfault introduced in r2486 in $sent_http_location processing
Igor Sysoev <igor@sysoev.ru>
parents:
2536
diff
changeset
|
1331 name.len = sizeof("sent_http_location") - 1; |
051e9b12428e
fix segfault introduced in r2486 in $sent_http_location processing
Igor Sysoev <igor@sysoev.ru>
parents:
2536
diff
changeset
|
1332 name.data = (u_char *) "sent_http_location"; |
051e9b12428e
fix segfault introduced in r2486 in $sent_http_location processing
Igor Sysoev <igor@sysoev.ru>
parents:
2536
diff
changeset
|
1333 |
051e9b12428e
fix segfault introduced in r2486 in $sent_http_location processing
Igor Sysoev <igor@sysoev.ru>
parents:
2536
diff
changeset
|
1334 return ngx_http_variable_unknown_header(v, &name, |
2485
51b1097dbb67
fix $sent_http_location for local redirects
Igor Sysoev <igor@sysoev.ru>
parents:
2415
diff
changeset
|
1335 &r->headers_out.headers.part, |
51b1097dbb67
fix $sent_http_location for local redirects
Igor Sysoev <igor@sysoev.ru>
parents:
2415
diff
changeset
|
1336 sizeof("sent_http_") - 1); |
51b1097dbb67
fix $sent_http_location for local redirects
Igor Sysoev <igor@sysoev.ru>
parents:
2415
diff
changeset
|
1337 } |
51b1097dbb67
fix $sent_http_location for local redirects
Igor Sysoev <igor@sysoev.ru>
parents:
2415
diff
changeset
|
1338 |
51b1097dbb67
fix $sent_http_location for local redirects
Igor Sysoev <igor@sysoev.ru>
parents:
2415
diff
changeset
|
1339 |
51b1097dbb67
fix $sent_http_location for local redirects
Igor Sysoev <igor@sysoev.ru>
parents:
2415
diff
changeset
|
1340 static ngx_int_t |
641 | 1341 ngx_http_variable_sent_last_modified(ngx_http_request_t *r, |
1342 ngx_http_variable_value_t *v, uintptr_t data) | |
1343 { | |
1344 u_char *p; | |
1345 | |
1346 if (r->headers_out.last_modified) { | |
1347 v->len = r->headers_out.last_modified->value.len; | |
1348 v->valid = 1; | |
1565 | 1349 v->no_cacheable = 0; |
641 | 1350 v->not_found = 0; |
1351 v->data = r->headers_out.last_modified->value.data; | |
1352 | |
1353 return NGX_OK; | |
1354 } | |
1355 | |
1356 if (r->headers_out.last_modified_time >= 0) { | |
2049 | 1357 p = ngx_pnalloc(r->pool, |
641 | 1358 sizeof("Last-Modified: Mon, 28 Sep 1970 06:00:00 GMT") - 1); |
1359 if (p == NULL) { | |
1360 return NGX_ERROR; | |
1361 } | |
1362 | |
1363 v->len = ngx_http_time(p, r->headers_out.last_modified_time) - p; | |
1364 v->valid = 1; | |
1565 | 1365 v->no_cacheable = 0; |
641 | 1366 v->not_found = 0; |
1367 v->data = p; | |
1368 | |
1369 return NGX_OK; | |
1370 } | |
1371 | |
1372 v->not_found = 1; | |
1373 | |
1374 return NGX_OK; | |
1375 } | |
1376 | |
1377 | |
1378 static ngx_int_t | |
1379 ngx_http_variable_sent_connection(ngx_http_request_t *r, | |
1380 ngx_http_variable_value_t *v, uintptr_t data) | |
1381 { | |
1382 size_t len; | |
1383 char *p; | |
1384 | |
1385 if (r->keepalive) { | |
1386 len = sizeof("keep-alive") - 1; | |
1387 p = "keep-alive"; | |
1388 | |
1389 } else { | |
1390 len = sizeof("close") - 1; | |
1391 p = "close"; | |
1392 } | |
1393 | |
1394 v->len = len; | |
1395 v->valid = 1; | |
1565 | 1396 v->no_cacheable = 0; |
641 | 1397 v->not_found = 0; |
1398 v->data = (u_char *) p; | |
1399 | |
1400 return NGX_OK; | |
1401 } | |
1402 | |
1403 | |
1404 static ngx_int_t | |
1405 ngx_http_variable_sent_keep_alive(ngx_http_request_t *r, | |
1406 ngx_http_variable_value_t *v, uintptr_t data) | |
1407 { | |
1408 u_char *p; | |
1409 ngx_http_core_loc_conf_t *clcf; | |
1410 | |
1411 if (r->keepalive) { | |
1412 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | |
1413 | |
1414 if (clcf->keepalive_header) { | |
1415 | |
2049 | 1416 p = ngx_pnalloc(r->pool, sizeof("timeout=") - 1 + NGX_TIME_T_LEN); |
641 | 1417 if (p == NULL) { |
1418 return NGX_ERROR; | |
1419 } | |
1420 | |
1421 v->len = ngx_sprintf(p, "timeout=%T", clcf->keepalive_header) - p; | |
1422 v->valid = 1; | |
1565 | 1423 v->no_cacheable = 0; |
641 | 1424 v->not_found = 0; |
1425 v->data = p; | |
1426 | |
1427 return NGX_OK; | |
1428 } | |
1429 } | |
1430 | |
1431 v->not_found = 1; | |
1432 | |
1433 return NGX_OK; | |
1434 } | |
1435 | |
1436 | |
1437 static ngx_int_t | |
1438 ngx_http_variable_sent_transfer_encoding(ngx_http_request_t *r, | |
1439 ngx_http_variable_value_t *v, uintptr_t data) | |
1440 { | |
1441 if (r->chunked) { | |
1442 v->len = sizeof("chunked") - 1; | |
1443 v->valid = 1; | |
1565 | 1444 v->no_cacheable = 0; |
641 | 1445 v->not_found = 0; |
1446 v->data = (u_char *) "chunked"; | |
1447 | |
1448 } else { | |
1449 v->not_found = 1; | |
1450 } | |
1451 | |
1452 return NGX_OK; | |
1453 } | |
1454 | |
1455 | |
1456 static ngx_int_t | |
629 | 1457 ngx_http_variable_request_completion(ngx_http_request_t *r, |
1458 ngx_http_variable_value_t *v, uintptr_t data) | |
1459 { | |
1460 if (r->request_complete) { | |
1461 v->len = 2; | |
1462 v->valid = 1; | |
1565 | 1463 v->no_cacheable = 0; |
629 | 1464 v->not_found = 0; |
1465 v->data = (u_char *) "OK"; | |
1466 | |
1467 return NGX_OK; | |
1468 } | |
1469 | |
1470 v->len = 0; | |
1471 v->valid = 1; | |
1565 | 1472 v->no_cacheable = 0; |
629 | 1473 v->not_found = 0; |
1474 v->data = (u_char *) ""; | |
1475 | |
1476 return NGX_OK; | |
1477 } | |
1478 | |
1479 | |
759 | 1480 static ngx_int_t |
1481 ngx_http_variable_request_body_file(ngx_http_request_t *r, | |
1482 ngx_http_variable_value_t *v, uintptr_t data) | |
1483 { | |
1484 if (r->request_body == NULL || r->request_body->temp_file == NULL) { | |
763
0b0f3d4854c0
variable should not be found if no request body file
Igor Sysoev <igor@sysoev.ru>
parents:
759
diff
changeset
|
1485 v->not_found = 1; |
759 | 1486 |
1487 return NGX_OK; | |
1488 } | |
1489 | |
1490 v->len = r->request_body->temp_file->file.name.len; | |
1491 v->valid = 1; | |
1565 | 1492 v->no_cacheable = 0; |
759 | 1493 v->not_found = 0; |
1494 v->data = r->request_body->temp_file->file.name.data; | |
1495 | |
1496 return NGX_OK; | |
1497 } | |
1498 | |
1499 | |
1329 | 1500 static ngx_int_t |
1501 ngx_http_variable_nginx_version(ngx_http_request_t *r, | |
1502 ngx_http_variable_value_t *v, uintptr_t data) | |
1503 { | |
1504 v->len = sizeof(NGINX_VERSION) - 1; | |
1505 v->valid = 1; | |
1565 | 1506 v->no_cacheable = 0; |
1329 | 1507 v->not_found = 0; |
1508 v->data = (u_char *) NGINX_VERSION; | |
1509 | |
1510 return NGX_OK; | |
1511 } | |
1512 | |
1513 | |
2011 | 1514 static ngx_int_t |
1515 ngx_http_variable_hostname(ngx_http_request_t *r, | |
1516 ngx_http_variable_value_t *v, uintptr_t data) | |
1517 { | |
1518 v->len = ngx_cycle->hostname.len; | |
1519 v->valid = 1; | |
1520 v->no_cacheable = 0; | |
1521 v->not_found = 0; | |
1522 v->data = ngx_cycle->hostname.data; | |
1523 | |
1524 return NGX_OK; | |
1525 } | |
1526 | |
1527 | |
2249 | 1528 static ngx_int_t |
1529 ngx_http_variable_pid(ngx_http_request_t *r, | |
1530 ngx_http_variable_value_t *v, uintptr_t data) | |
1531 { | |
1532 u_char *p; | |
1533 | |
1534 p = ngx_pnalloc(r->pool, NGX_INT64_LEN); | |
1535 if (p == NULL) { | |
1536 return NGX_ERROR; | |
1537 } | |
1538 | |
1539 v->len = ngx_sprintf(p, "%P", ngx_pid) - p; | |
1540 v->valid = 1; | |
1541 v->no_cacheable = 0; | |
1542 v->not_found = 0; | |
1543 v->data = p; | |
1544 | |
1545 return NGX_OK; | |
1546 } | |
1547 | |
1548 | |
499 | 1549 ngx_int_t |
509 | 1550 ngx_http_variables_add_core_vars(ngx_conf_t *cf) |
499 | 1551 { |
611 | 1552 ngx_int_t rc; |
1553 ngx_http_variable_t *v; | |
501 | 1554 ngx_http_core_main_conf_t *cmcf; |
499 | 1555 |
509 | 1556 cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); |
1557 | |
611 | 1558 cmcf->variables_keys = ngx_pcalloc(cf->temp_pool, |
1559 sizeof(ngx_hash_keys_arrays_t)); | |
1560 if (cmcf->variables_keys == NULL) { | |
1561 return NGX_ERROR; | |
1562 } | |
1563 | |
1564 cmcf->variables_keys->pool = cf->pool; | |
1565 cmcf->variables_keys->temp_pool = cf->pool; | |
1566 | |
1567 if (ngx_hash_keys_array_init(cmcf->variables_keys, NGX_HASH_SMALL) | |
1568 != NGX_OK) | |
509 | 1569 { |
499 | 1570 return NGX_ERROR; |
1571 } | |
1572 | |
611 | 1573 for (v = ngx_http_core_variables; v->name.len; v++) { |
1574 rc = ngx_hash_add_key(cmcf->variables_keys, &v->name, v, | |
1575 NGX_HASH_READONLY_KEY); | |
1576 | |
1577 if (rc == NGX_OK) { | |
1578 continue; | |
499 | 1579 } |
1580 | |
611 | 1581 if (rc == NGX_BUSY) { |
1582 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1583 "conflicting variable name \"%V\"", &v->name); | |
1584 } | |
1585 | |
1586 return NGX_ERROR; | |
499 | 1587 } |
1588 | |
1589 return NGX_OK; | |
1590 } | |
509 | 1591 |
1592 | |
1593 ngx_int_t | |
1594 ngx_http_variables_init_vars(ngx_conf_t *cf) | |
1595 { | |
1596 ngx_uint_t i, n; | |
611 | 1597 ngx_hash_key_t *key; |
1598 ngx_hash_init_t hash; | |
509 | 1599 ngx_http_variable_t *v, *av; |
1600 ngx_http_core_main_conf_t *cmcf; | |
1601 | |
1602 /* set the handlers for the indexed http variables */ | |
1603 | |
1604 cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); | |
1605 | |
1606 v = cmcf->variables.elts; | |
611 | 1607 key = cmcf->variables_keys->keys.elts; |
509 | 1608 |
1609 for (i = 0; i < cmcf->variables.nelts; i++) { | |
1610 | |
611 | 1611 for (n = 0; n < cmcf->variables_keys->keys.nelts; n++) { |
509 | 1612 |
1191
0eb2dc4fdea8
fix segfault introduced in r1190
Igor Sysoev <igor@sysoev.ru>
parents:
1173
diff
changeset
|
1613 av = key[n].value; |
0eb2dc4fdea8
fix segfault introduced in r1190
Igor Sysoev <igor@sysoev.ru>
parents:
1173
diff
changeset
|
1614 |
0eb2dc4fdea8
fix segfault introduced in r1190
Igor Sysoev <igor@sysoev.ru>
parents:
1173
diff
changeset
|
1615 if (av->get_handler |
0eb2dc4fdea8
fix segfault introduced in r1190
Igor Sysoev <igor@sysoev.ru>
parents:
1173
diff
changeset
|
1616 && v[i].name.len == key[n].key.len |
611 | 1617 && ngx_strncmp(v[i].name.data, key[n].key.data, v[i].name.len) |
509 | 1618 == 0) |
1619 { | |
637 | 1620 v[i].get_handler = av->get_handler; |
611 | 1621 v[i].data = av->data; |
527 | 1622 |
611 | 1623 av->flags |= NGX_HTTP_VAR_INDEXED; |
1624 v[i].flags = av->flags; | |
509 | 1625 |
611 | 1626 av->index = i; |
533 | 1627 |
509 | 1628 goto next; |
1629 } | |
1630 } | |
1631 | |
1632 if (ngx_strncmp(v[i].name.data, "http_", 5) == 0) { | |
637 | 1633 v[i].get_handler = ngx_http_variable_unknown_header_in; |
577 | 1634 v[i].data = (uintptr_t) &v[i].name; |
1635 | |
1636 continue; | |
1637 } | |
1638 | |
1639 if (ngx_strncmp(v[i].name.data, "sent_http_", 10) == 0) { | |
637 | 1640 v[i].get_handler = ngx_http_variable_unknown_header_out; |
509 | 1641 v[i].data = (uintptr_t) &v[i].name; |
1642 | |
1643 continue; | |
1644 } | |
1645 | |
1162 | 1646 if (ngx_strncmp(v[i].name.data, "upstream_http_", 14) == 0) { |
1647 v[i].get_handler = ngx_http_upstream_header_variable; | |
1648 v[i].data = (uintptr_t) &v[i].name; | |
1565 | 1649 v[i].flags = NGX_HTTP_VAR_NOCACHEABLE; |
1162 | 1650 |
1651 continue; | |
1652 } | |
1653 | |
2307 | 1654 if (ngx_strncmp(v[i].name.data, "cookie_", 7) == 0) { |
1655 v[i].get_handler = ngx_http_variable_cookie; | |
1656 v[i].data = (uintptr_t) &v[i].name; | |
1657 | |
1658 continue; | |
1659 } | |
1660 | |
2137 | 1661 if (ngx_strncmp(v[i].name.data, "arg_", 4) == 0) { |
1662 v[i].get_handler = ngx_http_variable_argument; | |
1663 v[i].data = (uintptr_t) &v[i].name; | |
1664 | |
1665 continue; | |
1666 } | |
1667 | |
509 | 1668 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, |
1669 "unknown \"%V\" variable", &v[i].name); | |
1670 | |
1671 return NGX_ERROR; | |
1672 | |
1673 next: | |
1674 continue; | |
1675 } | |
1676 | |
1677 | |
611 | 1678 for (n = 0; n < cmcf->variables_keys->keys.nelts; n++) { |
1679 av = key[n].value; | |
1680 | |
1681 if (av->flags & NGX_HTTP_VAR_NOHASH) { | |
1682 key[n].key.data = NULL; | |
583 | 1683 } |
1684 } | |
1685 | |
1686 | |
611 | 1687 hash.hash = &cmcf->variables_hash; |
1688 hash.key = ngx_hash_key; | |
1689 hash.max_size = cmcf->variables_hash_max_size; | |
1690 hash.bucket_size = cmcf->variables_hash_bucket_size; | |
1691 hash.name = "variables_hash"; | |
1692 hash.pool = cf->pool; | |
1693 hash.temp_pool = NULL; | |
509 | 1694 |
611 | 1695 if (ngx_hash_init(&hash, cmcf->variables_keys->keys.elts, |
1696 cmcf->variables_keys->keys.nelts) | |
581 | 1697 != NGX_OK) |
509 | 1698 { |
1699 return NGX_ERROR; | |
1700 } | |
1701 | |
611 | 1702 cmcf->variables_keys = NULL; |
509 | 1703 |
1704 return NGX_OK; | |
1705 } | |
2333
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1706 |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1707 |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1708 void |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1709 ngx_http_variable_value_rbtree_insert(ngx_rbtree_node_t *temp, |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1710 ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel) |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1711 { |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1712 ngx_rbtree_node_t **p; |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1713 ngx_http_variable_value_node_t *vvn, *vvt; |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1714 |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1715 for ( ;; ) { |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1716 |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1717 vvn = (ngx_http_variable_value_node_t *) node; |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1718 vvt = (ngx_http_variable_value_node_t *) temp; |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1719 |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1720 if (node->key != temp->key) { |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1721 |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1722 p = (node->key < temp->key) ? &temp->left : &temp->right; |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1723 |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1724 } else if (vvn->len != vvt->len) { |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1725 |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1726 p = (vvn->len < vvt->len) ? &temp->left : &temp->right; |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1727 |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1728 } else { |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1729 p = (ngx_memcmp(vvn->value->data, vvt->value->data, vvn->len) < 0) |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1730 ? &temp->left : &temp->right; |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1731 } |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1732 |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1733 if (*p == sentinel) { |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1734 break; |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1735 } |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1736 |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1737 temp = *p; |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1738 } |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1739 |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1740 *p = node; |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1741 node->parent = temp; |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1742 node->left = sentinel; |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1743 node->right = sentinel; |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1744 ngx_rbt_red(node); |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1745 } |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1746 |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1747 |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1748 ngx_http_variable_value_t * |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1749 ngx_http_variable_value_lookup(ngx_rbtree_t *rbtree, ngx_str_t *val, |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1750 uint32_t hash) |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1751 { |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1752 ngx_int_t rc; |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1753 ngx_rbtree_node_t *node, *sentinel; |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1754 ngx_http_variable_value_node_t *vvn; |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1755 |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1756 node = rbtree->root; |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1757 sentinel = rbtree->sentinel; |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1758 |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1759 while (node != sentinel) { |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1760 |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1761 vvn = (ngx_http_variable_value_node_t *) node; |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1762 |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1763 if (hash != node->key) { |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1764 node = (hash < node->key) ? node->left : node->right; |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1765 continue; |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1766 } |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1767 |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1768 if (val->len != vvn->len) { |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1769 node = (val->len < vvn->len) ? node->left : node->right; |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1770 continue; |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1771 } |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1772 |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1773 rc = ngx_memcmp(val->data, vvn->value->data, val->len); |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1774 |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1775 if (rc < 0) { |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1776 node = node->left; |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1777 continue; |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1778 } |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1779 |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1780 if (rc > 0) { |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1781 node = node->right; |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1782 continue; |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1783 } |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1784 |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1785 return vvn->value; |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1786 } |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1787 |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1788 return NULL; |
f267d23868fc
variable value rbtree support
Igor Sysoev <igor@sysoev.ru>
parents:
2307
diff
changeset
|
1789 } |