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