3 * Copyright (C) Igor Sysoev
7 #include <ngx_config.h>
13 static ngx_int_t
ngx_http_variable_request(ngx_http_request_t
*r
,
14 ngx_http_variable_value_t
*v
, uintptr_t data
);
15 static void ngx_http_variable_request_set(ngx_http_request_t
*r
,
16 ngx_http_variable_value_t
*v
, uintptr_t data
);
17 static ngx_int_t
ngx_http_variable_request_get_size(ngx_http_request_t
*r
,
18 ngx_http_variable_value_t
*v
, uintptr_t data
);
19 static void ngx_http_variable_request_set_size(ngx_http_request_t
*r
,
20 ngx_http_variable_value_t
*v
, uintptr_t data
);
21 static ngx_int_t
ngx_http_variable_header(ngx_http_request_t
*r
,
22 ngx_http_variable_value_t
*v
, uintptr_t data
);
23 static ngx_int_t
ngx_http_variable_headers(ngx_http_request_t
*r
,
24 ngx_http_variable_value_t
*v
, uintptr_t data
);
26 static ngx_int_t
ngx_http_variable_unknown_header_in(ngx_http_request_t
*r
,
27 ngx_http_variable_value_t
*v
, uintptr_t data
);
28 static ngx_int_t
ngx_http_variable_unknown_header_out(ngx_http_request_t
*r
,
29 ngx_http_variable_value_t
*v
, uintptr_t data
);
30 static ngx_int_t
ngx_http_variable_request_line(ngx_http_request_t
*r
,
31 ngx_http_variable_value_t
*v
, uintptr_t data
);
32 static ngx_int_t
ngx_http_variable_cookie(ngx_http_request_t
*r
,
33 ngx_http_variable_value_t
*v
, uintptr_t data
);
34 static ngx_int_t
ngx_http_variable_argument(ngx_http_request_t
*r
,
35 ngx_http_variable_value_t
*v
, uintptr_t data
);
37 static ngx_int_t
ngx_http_variable_host(ngx_http_request_t
*r
,
38 ngx_http_variable_value_t
*v
, uintptr_t data
);
39 static ngx_int_t
ngx_http_variable_binary_remote_addr(ngx_http_request_t
*r
,
40 ngx_http_variable_value_t
*v
, uintptr_t data
);
41 static ngx_int_t
ngx_http_variable_remote_addr(ngx_http_request_t
*r
,
42 ngx_http_variable_value_t
*v
, uintptr_t data
);
43 static ngx_int_t
ngx_http_variable_remote_port(ngx_http_request_t
*r
,
44 ngx_http_variable_value_t
*v
, uintptr_t data
);
45 static ngx_int_t
ngx_http_variable_server_addr(ngx_http_request_t
*r
,
46 ngx_http_variable_value_t
*v
, uintptr_t data
);
47 static ngx_int_t
ngx_http_variable_server_port(ngx_http_request_t
*r
,
48 ngx_http_variable_value_t
*v
, uintptr_t data
);
49 static ngx_int_t
ngx_http_variable_scheme(ngx_http_request_t
*r
,
50 ngx_http_variable_value_t
*v
, uintptr_t data
);
51 static ngx_int_t
ngx_http_variable_is_args(ngx_http_request_t
*r
,
52 ngx_http_variable_value_t
*v
, uintptr_t data
);
53 static ngx_int_t
ngx_http_variable_document_root(ngx_http_request_t
*r
,
54 ngx_http_variable_value_t
*v
, uintptr_t data
);
55 static ngx_int_t
ngx_http_variable_realpath_root(ngx_http_request_t
*r
,
56 ngx_http_variable_value_t
*v
, uintptr_t data
);
57 static ngx_int_t
ngx_http_variable_request_filename(ngx_http_request_t
*r
,
58 ngx_http_variable_value_t
*v
, uintptr_t data
);
59 static ngx_int_t
ngx_http_variable_server_name(ngx_http_request_t
*r
,
60 ngx_http_variable_value_t
*v
, uintptr_t data
);
61 static ngx_int_t
ngx_http_variable_request_method(ngx_http_request_t
*r
,
62 ngx_http_variable_value_t
*v
, uintptr_t data
);
63 static ngx_int_t
ngx_http_variable_remote_user(ngx_http_request_t
*r
,
64 ngx_http_variable_value_t
*v
, uintptr_t data
);
65 static ngx_int_t
ngx_http_variable_body_bytes_sent(ngx_http_request_t
*r
,
66 ngx_http_variable_value_t
*v
, uintptr_t data
);
67 static ngx_int_t
ngx_http_variable_request_completion(ngx_http_request_t
*r
,
68 ngx_http_variable_value_t
*v
, uintptr_t data
);
69 static ngx_int_t
ngx_http_variable_request_body(ngx_http_request_t
*r
,
70 ngx_http_variable_value_t
*v
, uintptr_t data
);
71 static ngx_int_t
ngx_http_variable_request_body_file(ngx_http_request_t
*r
,
72 ngx_http_variable_value_t
*v
, uintptr_t data
);
74 static ngx_int_t
ngx_http_variable_sent_content_type(ngx_http_request_t
*r
,
75 ngx_http_variable_value_t
*v
, uintptr_t data
);
76 static ngx_int_t
ngx_http_variable_sent_content_length(ngx_http_request_t
*r
,
77 ngx_http_variable_value_t
*v
, uintptr_t data
);
78 static ngx_int_t
ngx_http_variable_sent_location(ngx_http_request_t
*r
,
79 ngx_http_variable_value_t
*v
, uintptr_t data
);
80 static ngx_int_t
ngx_http_variable_sent_last_modified(ngx_http_request_t
*r
,
81 ngx_http_variable_value_t
*v
, uintptr_t data
);
82 static ngx_int_t
ngx_http_variable_sent_connection(ngx_http_request_t
*r
,
83 ngx_http_variable_value_t
*v
, uintptr_t data
);
84 static ngx_int_t
ngx_http_variable_sent_keep_alive(ngx_http_request_t
*r
,
85 ngx_http_variable_value_t
*v
, uintptr_t data
);
86 static ngx_int_t
ngx_http_variable_sent_transfer_encoding(ngx_http_request_t
*r
,
87 ngx_http_variable_value_t
*v
, uintptr_t data
);
89 static ngx_int_t
ngx_http_variable_nginx_version(ngx_http_request_t
*r
,
90 ngx_http_variable_value_t
*v
, uintptr_t data
);
91 static ngx_int_t
ngx_http_variable_hostname(ngx_http_request_t
*r
,
92 ngx_http_variable_value_t
*v
, uintptr_t data
);
93 static ngx_int_t
ngx_http_variable_pid(ngx_http_request_t
*r
,
94 ngx_http_variable_value_t
*v
, uintptr_t data
);
98 * Apache CGI: AUTH_TYPE, PATH_INFO (null), PATH_TRANSLATED
99 * REMOTE_HOST (null), REMOTE_IDENT (null),
102 * Apache SSI: DOCUMENT_NAME, LAST_MODIFIED, USER_NAME (file owner)
106 * the $http_host, $http_user_agent, $http_referer, $http_via,
107 * and $http_x_forwarded_for variables may be handled by generic
108 * ngx_http_variable_unknown_header_in(), but for perfomance reasons
109 * they are handled using dedicated entries
112 static ngx_http_variable_t ngx_http_core_variables
[] = {
114 { ngx_string("http_host"), NULL
, ngx_http_variable_header
,
115 offsetof(ngx_http_request_t
, headers_in
.host
), 0, 0 },
117 { ngx_string("http_user_agent"), NULL
, ngx_http_variable_header
,
118 offsetof(ngx_http_request_t
, headers_in
.user_agent
), 0, 0 },
120 { ngx_string("http_referer"), NULL
, ngx_http_variable_header
,
121 offsetof(ngx_http_request_t
, headers_in
.referer
), 0, 0 },
124 { ngx_string("http_via"), NULL
, ngx_http_variable_header
,
125 offsetof(ngx_http_request_t
, headers_in
.via
), 0, 0 },
128 #if (NGX_HTTP_PROXY || NGX_HTTP_REALIP)
129 { ngx_string("http_x_forwarded_for"), NULL
, ngx_http_variable_header
,
130 offsetof(ngx_http_request_t
, headers_in
.x_forwarded_for
), 0, 0 },
133 { ngx_string("http_cookie"), NULL
, ngx_http_variable_headers
,
134 offsetof(ngx_http_request_t
, headers_in
.cookies
), 0, 0 },
136 { ngx_string("content_length"), NULL
, ngx_http_variable_header
,
137 offsetof(ngx_http_request_t
, headers_in
.content_length
), 0, 0 },
139 { ngx_string("content_type"), NULL
, ngx_http_variable_header
,
140 offsetof(ngx_http_request_t
, headers_in
.content_type
), 0, 0 },
142 { ngx_string("host"), NULL
, ngx_http_variable_host
, 0, 0, 0 },
144 { ngx_string("binary_remote_addr"), NULL
,
145 ngx_http_variable_binary_remote_addr
, 0, 0, 0 },
147 { ngx_string("remote_addr"), NULL
, ngx_http_variable_remote_addr
, 0, 0, 0 },
149 { ngx_string("remote_port"), NULL
, ngx_http_variable_remote_port
, 0, 0, 0 },
151 { ngx_string("server_addr"), NULL
, ngx_http_variable_server_addr
, 0, 0, 0 },
153 { ngx_string("server_port"), NULL
, ngx_http_variable_server_port
, 0, 0, 0 },
155 { ngx_string("server_protocol"), NULL
, ngx_http_variable_request
,
156 offsetof(ngx_http_request_t
, http_protocol
), 0, 0 },
158 { ngx_string("scheme"), NULL
, ngx_http_variable_scheme
, 0, 0, 0 },
160 { ngx_string("request_uri"), NULL
, ngx_http_variable_request
,
161 offsetof(ngx_http_request_t
, unparsed_uri
), 0, 0 },
163 { ngx_string("uri"), NULL
, ngx_http_variable_request
,
164 offsetof(ngx_http_request_t
, uri
),
165 NGX_HTTP_VAR_NOCACHEABLE
, 0 },
167 { ngx_string("document_uri"), NULL
, ngx_http_variable_request
,
168 offsetof(ngx_http_request_t
, uri
),
169 NGX_HTTP_VAR_NOCACHEABLE
, 0 },
171 { ngx_string("request"), NULL
, ngx_http_variable_request_line
, 0, 0, 0 },
173 { ngx_string("document_root"), NULL
,
174 ngx_http_variable_document_root
, 0, NGX_HTTP_VAR_NOCACHEABLE
, 0 },
176 { ngx_string("realpath_root"), NULL
,
177 ngx_http_variable_realpath_root
, 0, NGX_HTTP_VAR_NOCACHEABLE
, 0 },
179 { ngx_string("query_string"), NULL
, ngx_http_variable_request
,
180 offsetof(ngx_http_request_t
, args
),
181 NGX_HTTP_VAR_NOCACHEABLE
, 0 },
183 { ngx_string("args"),
184 ngx_http_variable_request_set
,
185 ngx_http_variable_request
,
186 offsetof(ngx_http_request_t
, args
),
187 NGX_HTTP_VAR_CHANGEABLE
|NGX_HTTP_VAR_NOCACHEABLE
, 0 },
189 { ngx_string("is_args"), NULL
, ngx_http_variable_is_args
,
190 0, NGX_HTTP_VAR_NOCACHEABLE
, 0 },
192 { ngx_string("request_filename"), NULL
,
193 ngx_http_variable_request_filename
, 0,
194 NGX_HTTP_VAR_NOCACHEABLE
, 0 },
196 { ngx_string("server_name"), NULL
, ngx_http_variable_server_name
, 0, 0, 0 },
198 { ngx_string("request_method"), NULL
,
199 ngx_http_variable_request_method
, 0, 0, 0 },
201 { ngx_string("remote_user"), NULL
, ngx_http_variable_remote_user
, 0, 0, 0 },
203 { ngx_string("body_bytes_sent"), NULL
, ngx_http_variable_body_bytes_sent
,
206 { ngx_string("request_completion"), NULL
,
207 ngx_http_variable_request_completion
,
210 { ngx_string("request_body"), NULL
,
211 ngx_http_variable_request_body
,
214 { ngx_string("request_body_file"), NULL
,
215 ngx_http_variable_request_body_file
,
218 { ngx_string("sent_http_content_type"), NULL
,
219 ngx_http_variable_sent_content_type
, 0, 0, 0 },
221 { ngx_string("sent_http_content_length"), NULL
,
222 ngx_http_variable_sent_content_length
, 0, 0, 0 },
224 { ngx_string("sent_http_location"), NULL
,
225 ngx_http_variable_sent_location
, 0, 0, 0 },
227 { ngx_string("sent_http_last_modified"), NULL
,
228 ngx_http_variable_sent_last_modified
, 0, 0, 0 },
230 { ngx_string("sent_http_connection"), NULL
,
231 ngx_http_variable_sent_connection
, 0, 0, 0 },
233 { ngx_string("sent_http_keep_alive"), NULL
,
234 ngx_http_variable_sent_keep_alive
, 0, 0, 0 },
236 { ngx_string("sent_http_transfer_encoding"), NULL
,
237 ngx_http_variable_sent_transfer_encoding
, 0, 0, 0 },
239 { ngx_string("sent_http_cache_control"), NULL
, ngx_http_variable_headers
,
240 offsetof(ngx_http_request_t
, headers_out
.cache_control
), 0, 0 },
242 { ngx_string("limit_rate"), ngx_http_variable_request_set_size
,
243 ngx_http_variable_request_get_size
,
244 offsetof(ngx_http_request_t
, limit_rate
),
245 NGX_HTTP_VAR_CHANGEABLE
|NGX_HTTP_VAR_NOCACHEABLE
, 0 },
247 { ngx_string("nginx_version"), NULL
, ngx_http_variable_nginx_version
,
250 { ngx_string("hostname"), NULL
, ngx_http_variable_hostname
,
253 { ngx_string("pid"), NULL
, ngx_http_variable_pid
,
256 { ngx_null_string
, NULL
, NULL
, 0, 0, 0 }
260 ngx_http_variable_value_t ngx_http_variable_null_value
=
261 ngx_http_variable("");
262 ngx_http_variable_value_t ngx_http_variable_true_value
=
263 ngx_http_variable("1");
266 ngx_http_variable_t
*
267 ngx_http_add_variable(ngx_conf_t
*cf
, ngx_str_t
*name
, ngx_uint_t flags
)
272 ngx_http_variable_t
*v
;
273 ngx_http_core_main_conf_t
*cmcf
;
275 cmcf
= ngx_http_conf_get_module_main_conf(cf
, ngx_http_core_module
);
277 key
= cmcf
->variables_keys
->keys
.elts
;
278 for (i
= 0; i
< cmcf
->variables_keys
->keys
.nelts
; i
++) {
279 if (name
->len
!= key
[i
].key
.len
280 || ngx_strncasecmp(name
->data
, key
[i
].key
.data
, name
->len
) != 0)
287 if (!(v
->flags
& NGX_HTTP_VAR_CHANGEABLE
)) {
288 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, 0,
289 "the duplicate \"%V\" variable", name
);
296 v
= ngx_palloc(cf
->pool
, sizeof(ngx_http_variable_t
));
301 v
->name
.len
= name
->len
;
302 v
->name
.data
= ngx_pnalloc(cf
->pool
, name
->len
);
303 if (v
->name
.data
== NULL
) {
307 ngx_strlow(v
->name
.data
, name
->data
, name
->len
);
309 v
->set_handler
= NULL
;
310 v
->get_handler
= NULL
;
315 rc
= ngx_hash_add_key(cmcf
->variables_keys
, &v
->name
, v
, 0);
317 if (rc
== NGX_ERROR
) {
321 if (rc
== NGX_BUSY
) {
322 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, 0,
323 "conflicting variable name \"%V\"", name
);
332 ngx_http_get_variable_index(ngx_conf_t
*cf
, ngx_str_t
*name
)
335 ngx_http_variable_t
*v
;
336 ngx_http_core_main_conf_t
*cmcf
;
338 cmcf
= ngx_http_conf_get_module_main_conf(cf
, ngx_http_core_module
);
340 v
= cmcf
->variables
.elts
;
343 if (ngx_array_init(&cmcf
->variables
, cf
->pool
, 4,
344 sizeof(ngx_http_variable_t
))
351 for (i
= 0; i
< cmcf
->variables
.nelts
; i
++) {
352 if (name
->len
!= v
[i
].name
.len
353 || ngx_strncasecmp(name
->data
, v
[i
].name
.data
, name
->len
) != 0)
362 v
= ngx_array_push(&cmcf
->variables
);
367 v
->name
.len
= name
->len
;
368 v
->name
.data
= ngx_pnalloc(cf
->pool
, name
->len
);
369 if (v
->name
.data
== NULL
) {
373 ngx_strlow(v
->name
.data
, name
->data
, name
->len
);
375 v
->set_handler
= NULL
;
376 v
->get_handler
= NULL
;
379 v
->index
= cmcf
->variables
.nelts
- 1;
381 return cmcf
->variables
.nelts
- 1;
385 ngx_http_variable_value_t
*
386 ngx_http_get_indexed_variable(ngx_http_request_t
*r
, ngx_uint_t index
)
388 ngx_http_variable_t
*v
;
389 ngx_http_core_main_conf_t
*cmcf
;
391 cmcf
= ngx_http_get_module_main_conf(r
, ngx_http_core_module
);
393 if (cmcf
->variables
.nelts
<= index
) {
394 ngx_log_error(NGX_LOG_ALERT
, r
->connection
->log
, 0,
395 "unknown variable index: %d", index
);
399 if (r
->variables
[index
].not_found
|| r
->variables
[index
].valid
) {
400 return &r
->variables
[index
];
403 v
= cmcf
->variables
.elts
;
405 if (v
[index
].get_handler(r
, &r
->variables
[index
], v
[index
].data
)
408 if (v
[index
].flags
& NGX_HTTP_VAR_NOCACHEABLE
) {
409 r
->variables
[index
].no_cacheable
= 1;
412 return &r
->variables
[index
];
415 r
->variables
[index
].valid
= 0;
416 r
->variables
[index
].not_found
= 1;
422 ngx_http_variable_value_t
*
423 ngx_http_get_flushed_variable(ngx_http_request_t
*r
, ngx_uint_t index
)
425 ngx_http_variable_value_t
*v
;
427 v
= &r
->variables
[index
];
430 if (!v
->no_cacheable
) {
438 return ngx_http_get_indexed_variable(r
, index
);
442 ngx_http_variable_value_t
*
443 ngx_http_get_variable(ngx_http_request_t
*r
, ngx_str_t
*name
, ngx_uint_t key
,
446 ngx_http_variable_t
*v
;
447 ngx_http_variable_value_t
*vv
;
448 ngx_http_core_main_conf_t
*cmcf
;
450 cmcf
= ngx_http_get_module_main_conf(r
, ngx_http_core_module
);
452 v
= ngx_hash_find(&cmcf
->variables_hash
, key
, name
->data
, name
->len
);
455 if (v
->flags
& NGX_HTTP_VAR_INDEXED
) {
456 return ngx_http_get_indexed_variable(r
, v
->index
);
460 vv
= ngx_palloc(r
->pool
, sizeof(ngx_http_variable_value_t
));
462 if (vv
&& v
->get_handler(r
, vv
, v
->data
) == NGX_OK
) {
470 vv
= ngx_palloc(r
->pool
, sizeof(ngx_http_variable_value_t
));
475 if (ngx_strncmp(name
->data
, "http_", 5) == 0) {
477 if (ngx_http_variable_unknown_header_in(r
, vv
, (uintptr_t) name
)
486 if (ngx_strncmp(name
->data
, "sent_http_", 10) == 0) {
488 if (ngx_http_variable_unknown_header_out(r
, vv
, (uintptr_t) name
)
497 if (ngx_strncmp(name
->data
, "upstream_http_", 10) == 0) {
499 if (ngx_http_upstream_header_variable(r
, vv
, (uintptr_t) name
)
508 if (ngx_strncmp(name
->data
, "cookie_", 7) == 0) {
510 if (ngx_http_variable_cookie(r
, vv
, (uintptr_t) name
) == NGX_OK
) {
517 if (ngx_strncmp(name
->data
, "arg_", 4) == 0) {
519 if (ngx_http_variable_argument(r
, vv
, (uintptr_t) name
) == NGX_OK
) {
529 ngx_log_error(NGX_LOG_ERR
, r
->connection
->log
, 0,
530 "unknown \"%V\" variable", name
);
538 ngx_http_variable_request(ngx_http_request_t
*r
, ngx_http_variable_value_t
*v
,
543 s
= (ngx_str_t
*) ((char *) r
+ data
);
561 ngx_http_variable_request_set(ngx_http_request_t
*r
,
562 ngx_http_variable_value_t
*v
, uintptr_t data
)
566 s
= (ngx_str_t
*) ((char *) r
+ data
);
574 ngx_http_variable_request_get_size(ngx_http_request_t
*r
,
575 ngx_http_variable_value_t
*v
, uintptr_t data
)
579 sp
= (size_t *) ((char *) r
+ data
);
581 v
->data
= ngx_pnalloc(r
->pool
, NGX_SIZE_T_LEN
);
582 if (v
->data
== NULL
) {
586 v
->len
= ngx_sprintf(v
->data
, "%uz", *sp
) - v
->data
;
596 ngx_http_variable_request_set_size(ngx_http_request_t
*r
,
597 ngx_http_variable_value_t
*v
, uintptr_t data
)
605 s
= ngx_parse_size(&val
);
607 if (s
== NGX_ERROR
) {
608 ngx_log_error(NGX_LOG_ERR
, r
->connection
->log
, 0,
609 "invalid size \"%V\"", &val
);
613 sp
= (ssize_t
*) ((char *) r
+ data
);
622 ngx_http_variable_header(ngx_http_request_t
*r
, ngx_http_variable_value_t
*v
,
627 h
= *(ngx_table_elt_t
**) ((char *) r
+ data
);
630 v
->len
= h
->value
.len
;
634 v
->data
= h
->value
.data
;
645 ngx_http_variable_headers(ngx_http_request_t
*r
, ngx_http_variable_value_t
*v
,
654 a
= (ngx_array_t
*) ((char *) r
+ data
);
670 v
->len
= (*h
)->value
.len
;
671 v
->data
= (*h
)->value
.data
;
676 len
= - (ssize_t
) (sizeof("; ") - 1);
678 for (i
= 0; i
< n
; i
++) {
679 len
+= h
[i
]->value
.len
+ sizeof("; ") - 1;
682 p
= ngx_pnalloc(r
->pool
, len
);
690 for (i
= 0; /* void */ ; i
++) {
691 p
= ngx_copy(p
, h
[i
]->value
.data
, h
[i
]->value
.len
);
697 *p
++ = ';'; *p
++ = ' ';
705 ngx_http_variable_unknown_header_in(ngx_http_request_t
*r
,
706 ngx_http_variable_value_t
*v
, uintptr_t data
)
708 return ngx_http_variable_unknown_header(v
, (ngx_str_t
*) data
,
709 &r
->headers_in
.headers
.part
,
710 sizeof("http_") - 1);
715 ngx_http_variable_unknown_header_out(ngx_http_request_t
*r
,
716 ngx_http_variable_value_t
*v
, uintptr_t data
)
718 return ngx_http_variable_unknown_header(v
, (ngx_str_t
*) data
,
719 &r
->headers_out
.headers
.part
,
720 sizeof("sent_http_") - 1);
725 ngx_http_variable_unknown_header(ngx_http_variable_value_t
*v
, ngx_str_t
*var
,
726 ngx_list_part_t
*part
, size_t prefix
)
730 ngx_table_elt_t
*header
;
734 for (i
= 0; /* void */ ; i
++) {
736 if (i
>= part
->nelts
) {
737 if (part
->next
== NULL
) {
746 for (n
= 0; n
+ prefix
< var
->len
&& n
< header
[i
].key
.len
; n
++) {
747 ch
= header
[i
].key
.data
[n
];
749 if (ch
>= 'A' && ch
<= 'Z') {
752 } else if (ch
== '-') {
756 if (var
->data
[n
+ prefix
] != ch
) {
761 if (n
+ prefix
== var
->len
&& n
== header
[i
].key
.len
) {
762 v
->len
= header
[i
].value
.len
;
766 v
->data
= header
[i
].value
.data
;
779 ngx_http_variable_request_line(ngx_http_request_t
*r
,
780 ngx_http_variable_value_t
*v
, uintptr_t data
)
784 s
= r
->request_line
.data
;
787 s
= r
->request_start
;
794 for (p
= s
; p
< r
->header_in
->last
; p
++) {
795 if (*p
== CR
|| *p
== LF
) {
800 r
->request_line
.len
= p
- s
;
801 r
->request_line
.data
= s
;
804 v
->len
= r
->request_line
.len
;
815 ngx_http_variable_cookie(ngx_http_request_t
*r
, ngx_http_variable_value_t
*v
,
818 ngx_str_t
*name
= (ngx_str_t
*) data
;
822 s
.len
= name
->len
- (sizeof("cookie_") - 1);
823 s
.data
= name
->data
+ sizeof("cookie_") - 1;
825 if (ngx_http_parse_multi_header_lines(&r
->headers_in
.cookies
, &s
, &cookie
)
836 v
->data
= cookie
.data
;
843 ngx_http_variable_argument(ngx_http_request_t
*r
, ngx_http_variable_value_t
*v
,
846 ngx_str_t
*name
= (ngx_str_t
*) data
;
852 len
= name
->len
- (sizeof("arg_") - 1);
853 arg
= name
->data
+ sizeof("arg_") - 1;
855 if (ngx_http_arg(r
, arg
, len
, &value
) != NGX_OK
) {
860 v
->data
= value
.data
;
871 ngx_http_variable_host(ngx_http_request_t
*r
, ngx_http_variable_value_t
*v
,
874 ngx_http_core_srv_conf_t
*cscf
;
876 if (r
->headers_in
.server
.len
) {
877 v
->len
= r
->headers_in
.server
.len
;
878 v
->data
= r
->headers_in
.server
.data
;
881 cscf
= ngx_http_get_module_srv_conf(r
, ngx_http_core_module
);
883 v
->len
= cscf
->server_name
.len
;
884 v
->data
= cscf
->server_name
.data
;
896 ngx_http_variable_binary_remote_addr(ngx_http_request_t
*r
,
897 ngx_http_variable_value_t
*v
, uintptr_t data
)
899 struct sockaddr_in
*sin
;
901 struct sockaddr_in6
*sin6
;
904 switch (r
->connection
->sockaddr
->sa_family
) {
908 sin6
= (struct sockaddr_in6
*) r
->connection
->sockaddr
;
910 v
->len
= sizeof(struct in6_addr
);
914 v
->data
= sin6
->sin6_addr
.s6_addr
;
919 default: /* AF_INET */
920 sin
= (struct sockaddr_in
*) r
->connection
->sockaddr
;
922 v
->len
= sizeof(in_addr_t
);
926 v
->data
= (u_char
*) &sin
->sin_addr
;
936 ngx_http_variable_remote_addr(ngx_http_request_t
*r
,
937 ngx_http_variable_value_t
*v
, uintptr_t data
)
939 v
->len
= r
->connection
->addr_text
.len
;
943 v
->data
= r
->connection
->addr_text
.data
;
950 ngx_http_variable_remote_port(ngx_http_request_t
*r
,
951 ngx_http_variable_value_t
*v
, uintptr_t data
)
954 struct sockaddr_in
*sin
;
956 struct sockaddr_in6
*sin6
;
964 v
->data
= ngx_pnalloc(r
->pool
, sizeof("65535") - 1);
965 if (v
->data
== NULL
) {
969 switch (r
->connection
->sockaddr
->sa_family
) {
973 sin6
= (struct sockaddr_in6
*) r
->connection
->sockaddr
;
974 port
= ntohs(sin6
->sin6_port
);
978 default: /* AF_INET */
979 sin
= (struct sockaddr_in
*) r
->connection
->sockaddr
;
980 port
= ntohs(sin
->sin_port
);
984 if (port
> 0 && port
< 65536) {
985 v
->len
= ngx_sprintf(v
->data
, "%ui", port
) - v
->data
;
993 ngx_http_variable_server_addr(ngx_http_request_t
*r
,
994 ngx_http_variable_value_t
*v
, uintptr_t data
)
997 u_char addr
[NGX_SOCKADDR_STRLEN
];
999 s
.len
= NGX_SOCKADDR_STRLEN
;
1002 if (ngx_connection_local_sockaddr(r
->connection
, &s
, 0) != NGX_OK
) {
1006 s
.data
= ngx_pnalloc(r
->pool
, s
.len
);
1007 if (s
.data
== NULL
) {
1011 ngx_memcpy(s
.data
, addr
, s
.len
);
1015 v
->no_cacheable
= 0;
1024 ngx_http_variable_server_port(ngx_http_request_t
*r
,
1025 ngx_http_variable_value_t
*v
, uintptr_t data
)
1028 struct sockaddr_in
*sin
;
1029 #if (NGX_HAVE_INET6)
1030 struct sockaddr_in6
*sin6
;
1035 v
->no_cacheable
= 0;
1038 if (ngx_connection_local_sockaddr(r
->connection
, NULL
, 0) != NGX_OK
) {
1042 v
->data
= ngx_pnalloc(r
->pool
, sizeof("65535") - 1);
1043 if (v
->data
== NULL
) {
1047 switch (r
->connection
->local_sockaddr
->sa_family
) {
1049 #if (NGX_HAVE_INET6)
1051 sin6
= (struct sockaddr_in6
*) r
->connection
->local_sockaddr
;
1052 port
= ntohs(sin6
->sin6_port
);
1056 default: /* AF_INET */
1057 sin
= (struct sockaddr_in
*) r
->connection
->local_sockaddr
;
1058 port
= ntohs(sin
->sin_port
);
1062 if (port
> 0 && port
< 65536) {
1063 v
->len
= ngx_sprintf(v
->data
, "%ui", port
) - v
->data
;
1071 ngx_http_variable_scheme(ngx_http_request_t
*r
,
1072 ngx_http_variable_value_t
*v
, uintptr_t data
)
1076 if (r
->connection
->ssl
) {
1077 v
->len
= sizeof("https") - 1;
1079 v
->no_cacheable
= 0;
1081 v
->data
= (u_char
*) "https";
1088 v
->len
= sizeof("http") - 1;
1090 v
->no_cacheable
= 0;
1092 v
->data
= (u_char
*) "http";
1099 ngx_http_variable_is_args(ngx_http_request_t
*r
,
1100 ngx_http_variable_value_t
*v
, uintptr_t data
)
1103 v
->no_cacheable
= 0;
1106 if (r
->args
.len
== 0) {
1113 v
->data
= (u_char
*) "?";
1120 ngx_http_variable_document_root(ngx_http_request_t
*r
,
1121 ngx_http_variable_value_t
*v
, uintptr_t data
)
1124 ngx_http_core_loc_conf_t
*clcf
;
1126 clcf
= ngx_http_get_module_loc_conf(r
, ngx_http_core_module
);
1128 if (clcf
->root_lengths
== NULL
) {
1129 v
->len
= clcf
->root
.len
;
1131 v
->no_cacheable
= 0;
1133 v
->data
= clcf
->root
.data
;
1136 if (ngx_http_script_run(r
, &path
, clcf
->root_lengths
->elts
, 0,
1137 clcf
->root_values
->elts
)
1143 if (ngx_conf_full_name((ngx_cycle_t
*) ngx_cycle
, &path
, 0) != NGX_OK
) {
1149 v
->no_cacheable
= 0;
1151 v
->data
= path
.data
;
1159 ngx_http_variable_realpath_root(ngx_http_request_t
*r
,
1160 ngx_http_variable_value_t
*v
, uintptr_t data
)
1164 ngx_http_core_loc_conf_t
*clcf
;
1165 u_char real
[NGX_MAX_PATH
];
1167 clcf
= ngx_http_get_module_loc_conf(r
, ngx_http_core_module
);
1169 if (clcf
->root_lengths
== NULL
) {
1173 if (ngx_http_script_run(r
, &path
, clcf
->root_lengths
->elts
, 1,
1174 clcf
->root_values
->elts
)
1180 path
.data
[path
.len
- 1] = '\0';
1182 if (ngx_conf_full_name((ngx_cycle_t
*) ngx_cycle
, &path
, 0) != NGX_OK
) {
1187 if (ngx_realpath(path
.data
, real
) == NULL
) {
1188 ngx_log_error(NGX_LOG_CRIT
, r
->connection
->log
, ngx_errno
,
1189 ngx_realpath_n
" \"%s\" failed", path
.data
);
1193 len
= ngx_strlen(real
);
1195 v
->data
= ngx_pnalloc(r
->pool
, len
);
1196 if (v
->data
== NULL
) {
1202 v
->no_cacheable
= 0;
1205 ngx_memcpy(v
->data
, real
, len
);
1212 ngx_http_variable_request_filename(ngx_http_request_t
*r
,
1213 ngx_http_variable_value_t
*v
, uintptr_t data
)
1218 if (ngx_http_map_uri_to_path(r
, &path
, &root
, 0) == NULL
) {
1222 /* ngx_http_map_uri_to_path() allocates memory for terminating '\0' */
1224 v
->len
= path
.len
- 1;
1226 v
->no_cacheable
= 0;
1228 v
->data
= path
.data
;
1235 ngx_http_variable_server_name(ngx_http_request_t
*r
,
1236 ngx_http_variable_value_t
*v
, uintptr_t data
)
1238 ngx_http_core_srv_conf_t
*cscf
;
1240 cscf
= ngx_http_get_module_srv_conf(r
, ngx_http_core_module
);
1242 v
->len
= cscf
->server_name
.len
;
1244 v
->no_cacheable
= 0;
1246 v
->data
= cscf
->server_name
.data
;
1253 ngx_http_variable_request_method(ngx_http_request_t
*r
,
1254 ngx_http_variable_value_t
*v
, uintptr_t data
)
1256 if (r
->main
->method_name
.data
) {
1257 v
->len
= r
->main
->method_name
.len
;
1259 v
->no_cacheable
= 0;
1261 v
->data
= r
->main
->method_name
.data
;
1272 ngx_http_variable_remote_user(ngx_http_request_t
*r
,
1273 ngx_http_variable_value_t
*v
, uintptr_t data
)
1277 rc
= ngx_http_auth_basic_user(r
);
1279 if (rc
== NGX_DECLINED
) {
1284 if (rc
== NGX_ERROR
) {
1288 v
->len
= r
->headers_in
.user
.len
;
1290 v
->no_cacheable
= 0;
1292 v
->data
= r
->headers_in
.user
.data
;
1299 ngx_http_variable_body_bytes_sent(ngx_http_request_t
*r
,
1300 ngx_http_variable_value_t
*v
, uintptr_t data
)
1305 sent
= r
->connection
->sent
- r
->header_size
;
1311 p
= ngx_pnalloc(r
->pool
, NGX_OFF_T_LEN
);
1316 v
->len
= ngx_sprintf(p
, "%O", sent
) - p
;
1318 v
->no_cacheable
= 0;
1327 ngx_http_variable_sent_content_type(ngx_http_request_t
*r
,
1328 ngx_http_variable_value_t
*v
, uintptr_t data
)
1330 if (r
->headers_out
.content_type
.len
) {
1331 v
->len
= r
->headers_out
.content_type
.len
;
1333 v
->no_cacheable
= 0;
1335 v
->data
= r
->headers_out
.content_type
.data
;
1346 ngx_http_variable_sent_content_length(ngx_http_request_t
*r
,
1347 ngx_http_variable_value_t
*v
, uintptr_t data
)
1351 if (r
->headers_out
.content_length
) {
1352 v
->len
= r
->headers_out
.content_length
->value
.len
;
1354 v
->no_cacheable
= 0;
1356 v
->data
= r
->headers_out
.content_length
->value
.data
;
1361 if (r
->headers_out
.content_length_n
>= 0) {
1362 p
= ngx_pnalloc(r
->pool
, NGX_OFF_T_LEN
);
1367 v
->len
= ngx_sprintf(p
, "%O", r
->headers_out
.content_length_n
) - p
;
1369 v
->no_cacheable
= 0;
1383 ngx_http_variable_sent_location(ngx_http_request_t
*r
,
1384 ngx_http_variable_value_t
*v
, uintptr_t data
)
1388 if (r
->headers_out
.location
) {
1389 v
->len
= r
->headers_out
.location
->value
.len
;
1391 v
->no_cacheable
= 0;
1393 v
->data
= r
->headers_out
.location
->value
.data
;
1398 name
.len
= sizeof("sent_http_location") - 1;
1399 name
.data
= (u_char
*) "sent_http_location";
1401 return ngx_http_variable_unknown_header(v
, &name
,
1402 &r
->headers_out
.headers
.part
,
1403 sizeof("sent_http_") - 1);
1408 ngx_http_variable_sent_last_modified(ngx_http_request_t
*r
,
1409 ngx_http_variable_value_t
*v
, uintptr_t data
)
1413 if (r
->headers_out
.last_modified
) {
1414 v
->len
= r
->headers_out
.last_modified
->value
.len
;
1416 v
->no_cacheable
= 0;
1418 v
->data
= r
->headers_out
.last_modified
->value
.data
;
1423 if (r
->headers_out
.last_modified_time
>= 0) {
1424 p
= ngx_pnalloc(r
->pool
,
1425 sizeof("Last-Modified: Mon, 28 Sep 1970 06:00:00 GMT") - 1);
1430 v
->len
= ngx_http_time(p
, r
->headers_out
.last_modified_time
) - p
;
1432 v
->no_cacheable
= 0;
1446 ngx_http_variable_sent_connection(ngx_http_request_t
*r
,
1447 ngx_http_variable_value_t
*v
, uintptr_t data
)
1453 len
= sizeof("keep-alive") - 1;
1457 len
= sizeof("close") - 1;
1463 v
->no_cacheable
= 0;
1465 v
->data
= (u_char
*) p
;
1472 ngx_http_variable_sent_keep_alive(ngx_http_request_t
*r
,
1473 ngx_http_variable_value_t
*v
, uintptr_t data
)
1476 ngx_http_core_loc_conf_t
*clcf
;
1479 clcf
= ngx_http_get_module_loc_conf(r
, ngx_http_core_module
);
1481 if (clcf
->keepalive_header
) {
1483 p
= ngx_pnalloc(r
->pool
, sizeof("timeout=") - 1 + NGX_TIME_T_LEN
);
1488 v
->len
= ngx_sprintf(p
, "timeout=%T", clcf
->keepalive_header
) - p
;
1490 v
->no_cacheable
= 0;
1505 ngx_http_variable_sent_transfer_encoding(ngx_http_request_t
*r
,
1506 ngx_http_variable_value_t
*v
, uintptr_t data
)
1509 v
->len
= sizeof("chunked") - 1;
1511 v
->no_cacheable
= 0;
1513 v
->data
= (u_char
*) "chunked";
1524 ngx_http_variable_request_completion(ngx_http_request_t
*r
,
1525 ngx_http_variable_value_t
*v
, uintptr_t data
)
1527 if (r
->request_complete
) {
1530 v
->no_cacheable
= 0;
1532 v
->data
= (u_char
*) "OK";
1539 v
->no_cacheable
= 0;
1541 v
->data
= (u_char
*) "";
1548 ngx_http_variable_request_body(ngx_http_request_t
*r
,
1549 ngx_http_variable_value_t
*v
, uintptr_t data
)
1553 ngx_buf_t
*buf
, *next
;
1556 if (r
->request_body
== NULL
1557 || r
->request_body
->bufs
== NULL
1558 || r
->request_body
->temp_file
)
1565 cl
= r
->request_body
->bufs
;
1568 if (cl
->next
== NULL
) {
1569 v
->len
= buf
->last
- buf
->pos
;
1571 v
->no_cacheable
= 0;
1578 next
= cl
->next
->buf
;
1579 len
= (buf
->last
- buf
->pos
) + (next
->last
- next
->pos
);
1581 p
= ngx_pnalloc(r
->pool
, len
);
1588 p
= ngx_cpymem(p
, buf
->pos
, buf
->last
- buf
->pos
);
1589 ngx_memcpy(p
, next
->pos
, next
->last
- next
->pos
);
1593 v
->no_cacheable
= 0;
1601 ngx_http_variable_request_body_file(ngx_http_request_t
*r
,
1602 ngx_http_variable_value_t
*v
, uintptr_t data
)
1604 if (r
->request_body
== NULL
|| r
->request_body
->temp_file
== NULL
) {
1610 v
->len
= r
->request_body
->temp_file
->file
.name
.len
;
1612 v
->no_cacheable
= 0;
1614 v
->data
= r
->request_body
->temp_file
->file
.name
.data
;
1621 ngx_http_variable_nginx_version(ngx_http_request_t
*r
,
1622 ngx_http_variable_value_t
*v
, uintptr_t data
)
1624 v
->len
= sizeof(NGINX_VERSION
) - 1;
1626 v
->no_cacheable
= 0;
1628 v
->data
= (u_char
*) NGINX_VERSION
;
1635 ngx_http_variable_hostname(ngx_http_request_t
*r
,
1636 ngx_http_variable_value_t
*v
, uintptr_t data
)
1638 v
->len
= ngx_cycle
->hostname
.len
;
1640 v
->no_cacheable
= 0;
1642 v
->data
= ngx_cycle
->hostname
.data
;
1649 ngx_http_variable_pid(ngx_http_request_t
*r
,
1650 ngx_http_variable_value_t
*v
, uintptr_t data
)
1654 p
= ngx_pnalloc(r
->pool
, NGX_INT64_LEN
);
1659 v
->len
= ngx_sprintf(p
, "%P", ngx_pid
) - p
;
1661 v
->no_cacheable
= 0;
1670 ngx_http_variable_not_found(ngx_http_request_t
*r
, ngx_http_variable_value_t
*v
,
1679 ngx_http_regex_compile(ngx_conf_t
*cf
, ngx_regex_compile_t
*rc
)
1685 ngx_http_variable_t
*v
;
1686 ngx_http_regex_t
*re
;
1687 ngx_http_regex_variable_t
*rv
;
1688 ngx_http_core_main_conf_t
*cmcf
;
1690 rc
->pool
= cf
->pool
;
1692 if (ngx_regex_compile(rc
) != NGX_OK
) {
1693 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, 0, "%V", &rc
->err
);
1697 re
= ngx_pcalloc(cf
->pool
, sizeof(ngx_http_regex_t
));
1702 re
->regex
= rc
->regex
;
1703 re
->ncaptures
= rc
->captures
;
1705 cmcf
= ngx_http_conf_get_module_main_conf(cf
, ngx_http_core_module
);
1706 cmcf
->ncaptures
= ngx_max(cmcf
->ncaptures
, re
->ncaptures
);
1708 n
= (ngx_uint_t
) rc
->named_captures
;
1714 rv
= ngx_palloc(rc
->pool
, n
* sizeof(ngx_http_regex_variable_t
));
1721 re
->name
= rc
->pattern
;
1723 size
= rc
->name_size
;
1726 for (i
= 0; i
< n
; i
++) {
1727 rv
[i
].capture
= 2 * ((p
[0] << 8) + p
[1]);
1730 name
.len
= ngx_strlen(name
.data
);
1732 v
= ngx_http_add_variable(cf
, &name
, NGX_HTTP_VAR_CHANGEABLE
);
1737 rv
[i
].index
= ngx_http_get_variable_index(cf
, &name
);
1738 if (rv
[i
].index
== NGX_ERROR
) {
1742 v
->get_handler
= ngx_http_variable_not_found
;
1752 ngx_http_regex_exec(ngx_http_request_t
*r
, ngx_http_regex_t
*re
, ngx_str_t
*s
)
1754 ngx_int_t rc
, index
;
1755 ngx_uint_t i
, n
, len
;
1756 ngx_http_variable_value_t
*vv
;
1757 ngx_http_core_main_conf_t
*cmcf
;
1759 cmcf
= ngx_http_get_module_main_conf(r
, ngx_http_core_module
);
1761 if (re
->ncaptures
) {
1762 len
= cmcf
->ncaptures
;
1764 if (r
->captures
== NULL
) {
1765 r
->captures
= ngx_palloc(r
->pool
, len
* sizeof(int));
1766 if (r
->captures
== NULL
) {
1775 rc
= ngx_regex_exec(re
->regex
, s
, r
->captures
, len
);
1777 if (rc
== NGX_REGEX_NO_MATCHED
) {
1778 return NGX_DECLINED
;
1782 ngx_log_error(NGX_LOG_ALERT
, r
->connection
->log
, 0,
1783 ngx_regex_exec_n
" failed: %i on \"%V\" using \"%V\"",
1788 for (i
= 0; i
< re
->nvariables
; i
++) {
1790 n
= re
->variables
[i
].capture
;
1791 index
= re
->variables
[i
].index
;
1792 vv
= &r
->variables
[index
];
1794 vv
->len
= r
->captures
[n
+ 1] - r
->captures
[n
];
1796 vv
->no_cacheable
= 0;
1798 vv
->data
= &s
->data
[r
->captures
[n
]];
1802 ngx_http_variable_t
*v
;
1804 v
= cmcf
->variables
.elts
;
1806 ngx_log_debug3(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0,
1807 "http regex set $%V to \"%*s\"",
1808 &v
[index
].name
, vv
->len
, vv
->data
);
1813 r
->ncaptures
= rc
* 2;
1814 r
->captures_data
= s
->data
;
1821 ngx_http_variables_add_core_vars(ngx_conf_t
*cf
)
1824 ngx_http_variable_t
*v
;
1825 ngx_http_core_main_conf_t
*cmcf
;
1827 cmcf
= ngx_http_conf_get_module_main_conf(cf
, ngx_http_core_module
);
1829 cmcf
->variables_keys
= ngx_pcalloc(cf
->temp_pool
,
1830 sizeof(ngx_hash_keys_arrays_t
));
1831 if (cmcf
->variables_keys
== NULL
) {
1835 cmcf
->variables_keys
->pool
= cf
->pool
;
1836 cmcf
->variables_keys
->temp_pool
= cf
->pool
;
1838 if (ngx_hash_keys_array_init(cmcf
->variables_keys
, NGX_HASH_SMALL
)
1844 for (v
= ngx_http_core_variables
; v
->name
.len
; v
++) {
1845 rc
= ngx_hash_add_key(cmcf
->variables_keys
, &v
->name
, v
,
1846 NGX_HASH_READONLY_KEY
);
1852 if (rc
== NGX_BUSY
) {
1853 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, 0,
1854 "conflicting variable name \"%V\"", &v
->name
);
1865 ngx_http_variables_init_vars(ngx_conf_t
*cf
)
1868 ngx_hash_key_t
*key
;
1869 ngx_hash_init_t hash
;
1870 ngx_http_variable_t
*v
, *av
;
1871 ngx_http_core_main_conf_t
*cmcf
;
1873 /* set the handlers for the indexed http variables */
1875 cmcf
= ngx_http_conf_get_module_main_conf(cf
, ngx_http_core_module
);
1877 v
= cmcf
->variables
.elts
;
1878 key
= cmcf
->variables_keys
->keys
.elts
;
1880 for (i
= 0; i
< cmcf
->variables
.nelts
; i
++) {
1882 for (n
= 0; n
< cmcf
->variables_keys
->keys
.nelts
; n
++) {
1887 && v
[i
].name
.len
== key
[n
].key
.len
1888 && ngx_strncmp(v
[i
].name
.data
, key
[n
].key
.data
, v
[i
].name
.len
)
1891 v
[i
].get_handler
= av
->get_handler
;
1892 v
[i
].data
= av
->data
;
1894 av
->flags
|= NGX_HTTP_VAR_INDEXED
;
1895 v
[i
].flags
= av
->flags
;
1903 if (ngx_strncmp(v
[i
].name
.data
, "http_", 5) == 0) {
1904 v
[i
].get_handler
= ngx_http_variable_unknown_header_in
;
1905 v
[i
].data
= (uintptr_t) &v
[i
].name
;
1910 if (ngx_strncmp(v
[i
].name
.data
, "sent_http_", 10) == 0) {
1911 v
[i
].get_handler
= ngx_http_variable_unknown_header_out
;
1912 v
[i
].data
= (uintptr_t) &v
[i
].name
;
1917 if (ngx_strncmp(v
[i
].name
.data
, "upstream_http_", 14) == 0) {
1918 v
[i
].get_handler
= ngx_http_upstream_header_variable
;
1919 v
[i
].data
= (uintptr_t) &v
[i
].name
;
1920 v
[i
].flags
= NGX_HTTP_VAR_NOCACHEABLE
;
1925 if (ngx_strncmp(v
[i
].name
.data
, "cookie_", 7) == 0) {
1926 v
[i
].get_handler
= ngx_http_variable_cookie
;
1927 v
[i
].data
= (uintptr_t) &v
[i
].name
;
1932 if (ngx_strncmp(v
[i
].name
.data
, "arg_", 4) == 0) {
1933 v
[i
].get_handler
= ngx_http_variable_argument
;
1934 v
[i
].data
= (uintptr_t) &v
[i
].name
;
1939 ngx_log_error(NGX_LOG_EMERG
, cf
->log
, 0,
1940 "unknown \"%V\" variable", &v
[i
].name
);
1949 for (n
= 0; n
< cmcf
->variables_keys
->keys
.nelts
; n
++) {
1952 if (av
->flags
& NGX_HTTP_VAR_NOHASH
) {
1953 key
[n
].key
.data
= NULL
;
1958 hash
.hash
= &cmcf
->variables_hash
;
1959 hash
.key
= ngx_hash_key
;
1960 hash
.max_size
= cmcf
->variables_hash_max_size
;
1961 hash
.bucket_size
= cmcf
->variables_hash_bucket_size
;
1962 hash
.name
= "variables_hash";
1963 hash
.pool
= cf
->pool
;
1964 hash
.temp_pool
= NULL
;
1966 if (ngx_hash_init(&hash
, cmcf
->variables_keys
->keys
.elts
,
1967 cmcf
->variables_keys
->keys
.nelts
)
1973 cmcf
->variables_keys
= NULL
;
1980 ngx_http_variable_value_rbtree_insert(ngx_rbtree_node_t
*temp
,
1981 ngx_rbtree_node_t
*node
, ngx_rbtree_node_t
*sentinel
)
1983 ngx_rbtree_node_t
**p
;
1984 ngx_http_variable_value_node_t
*vvn
, *vvt
;
1988 vvn
= (ngx_http_variable_value_node_t
*) node
;
1989 vvt
= (ngx_http_variable_value_node_t
*) temp
;
1991 if (node
->key
!= temp
->key
) {
1993 p
= (node
->key
< temp
->key
) ? &temp
->left
: &temp
->right
;
1995 } else if (vvn
->len
!= vvt
->len
) {
1997 p
= (vvn
->len
< vvt
->len
) ? &temp
->left
: &temp
->right
;
2000 p
= (ngx_memcmp(vvn
->value
->data
, vvt
->value
->data
, vvn
->len
) < 0)
2001 ? &temp
->left
: &temp
->right
;
2004 if (*p
== sentinel
) {
2012 node
->parent
= temp
;
2013 node
->left
= sentinel
;
2014 node
->right
= sentinel
;
2019 ngx_http_variable_value_t
*
2020 ngx_http_variable_value_lookup(ngx_rbtree_t
*rbtree
, ngx_str_t
*val
,
2024 ngx_rbtree_node_t
*node
, *sentinel
;
2025 ngx_http_variable_value_node_t
*vvn
;
2027 node
= rbtree
->root
;
2028 sentinel
= rbtree
->sentinel
;
2030 while (node
!= sentinel
) {
2032 vvn
= (ngx_http_variable_value_node_t
*) node
;
2034 if (hash
!= node
->key
) {
2035 node
= (hash
< node
->key
) ? node
->left
: node
->right
;
2039 if (val
->len
!= vvn
->len
) {
2040 node
= (val
->len
< vvn
->len
) ? node
->left
: node
->right
;
2044 rc
= ngx_memcmp(val
->data
, vvn
->value
->data
, val
->len
);