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,
200 NGX_HTTP_VAR_NOCACHEABLE
, 0 },
202 { ngx_string("remote_user"), NULL
, ngx_http_variable_remote_user
, 0, 0, 0 },
204 { ngx_string("body_bytes_sent"), NULL
, ngx_http_variable_body_bytes_sent
,
207 { ngx_string("request_completion"), NULL
,
208 ngx_http_variable_request_completion
,
211 { ngx_string("request_body"), NULL
,
212 ngx_http_variable_request_body
,
215 { ngx_string("request_body_file"), NULL
,
216 ngx_http_variable_request_body_file
,
219 { ngx_string("sent_http_content_type"), NULL
,
220 ngx_http_variable_sent_content_type
, 0, 0, 0 },
222 { ngx_string("sent_http_content_length"), NULL
,
223 ngx_http_variable_sent_content_length
, 0, 0, 0 },
225 { ngx_string("sent_http_location"), NULL
,
226 ngx_http_variable_sent_location
, 0, 0, 0 },
228 { ngx_string("sent_http_last_modified"), NULL
,
229 ngx_http_variable_sent_last_modified
, 0, 0, 0 },
231 { ngx_string("sent_http_connection"), NULL
,
232 ngx_http_variable_sent_connection
, 0, 0, 0 },
234 { ngx_string("sent_http_keep_alive"), NULL
,
235 ngx_http_variable_sent_keep_alive
, 0, 0, 0 },
237 { ngx_string("sent_http_transfer_encoding"), NULL
,
238 ngx_http_variable_sent_transfer_encoding
, 0, 0, 0 },
240 { ngx_string("sent_http_cache_control"), NULL
, ngx_http_variable_headers
,
241 offsetof(ngx_http_request_t
, headers_out
.cache_control
), 0, 0 },
243 { ngx_string("limit_rate"), ngx_http_variable_request_set_size
,
244 ngx_http_variable_request_get_size
,
245 offsetof(ngx_http_request_t
, limit_rate
),
246 NGX_HTTP_VAR_CHANGEABLE
|NGX_HTTP_VAR_NOCACHEABLE
, 0 },
248 { ngx_string("nginx_version"), NULL
, ngx_http_variable_nginx_version
,
251 { ngx_string("hostname"), NULL
, ngx_http_variable_hostname
,
254 { ngx_string("pid"), NULL
, ngx_http_variable_pid
,
257 { ngx_null_string
, NULL
, NULL
, 0, 0, 0 }
261 ngx_http_variable_value_t ngx_http_variable_null_value
=
262 ngx_http_variable("");
263 ngx_http_variable_value_t ngx_http_variable_true_value
=
264 ngx_http_variable("1");
267 ngx_http_variable_t
*
268 ngx_http_add_variable(ngx_conf_t
*cf
, ngx_str_t
*name
, ngx_uint_t flags
)
273 ngx_http_variable_t
*v
;
274 ngx_http_core_main_conf_t
*cmcf
;
276 cmcf
= ngx_http_conf_get_module_main_conf(cf
, ngx_http_core_module
);
278 key
= cmcf
->variables_keys
->keys
.elts
;
279 for (i
= 0; i
< cmcf
->variables_keys
->keys
.nelts
; i
++) {
280 if (name
->len
!= key
[i
].key
.len
281 || ngx_strncasecmp(name
->data
, key
[i
].key
.data
, name
->len
) != 0)
288 if (!(v
->flags
& NGX_HTTP_VAR_CHANGEABLE
)) {
289 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, 0,
290 "the duplicate \"%V\" variable", name
);
297 v
= ngx_palloc(cf
->pool
, sizeof(ngx_http_variable_t
));
302 v
->name
.len
= name
->len
;
303 v
->name
.data
= ngx_pnalloc(cf
->pool
, name
->len
);
304 if (v
->name
.data
== NULL
) {
308 ngx_strlow(v
->name
.data
, name
->data
, name
->len
);
310 v
->set_handler
= NULL
;
311 v
->get_handler
= NULL
;
316 rc
= ngx_hash_add_key(cmcf
->variables_keys
, &v
->name
, v
, 0);
318 if (rc
== NGX_ERROR
) {
322 if (rc
== NGX_BUSY
) {
323 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, 0,
324 "conflicting variable name \"%V\"", name
);
333 ngx_http_get_variable_index(ngx_conf_t
*cf
, ngx_str_t
*name
)
336 ngx_http_variable_t
*v
;
337 ngx_http_core_main_conf_t
*cmcf
;
339 cmcf
= ngx_http_conf_get_module_main_conf(cf
, ngx_http_core_module
);
341 v
= cmcf
->variables
.elts
;
344 if (ngx_array_init(&cmcf
->variables
, cf
->pool
, 4,
345 sizeof(ngx_http_variable_t
))
352 for (i
= 0; i
< cmcf
->variables
.nelts
; i
++) {
353 if (name
->len
!= v
[i
].name
.len
354 || ngx_strncasecmp(name
->data
, v
[i
].name
.data
, name
->len
) != 0)
363 v
= ngx_array_push(&cmcf
->variables
);
368 v
->name
.len
= name
->len
;
369 v
->name
.data
= ngx_pnalloc(cf
->pool
, name
->len
);
370 if (v
->name
.data
== NULL
) {
374 ngx_strlow(v
->name
.data
, name
->data
, name
->len
);
376 v
->set_handler
= NULL
;
377 v
->get_handler
= NULL
;
380 v
->index
= cmcf
->variables
.nelts
- 1;
382 return cmcf
->variables
.nelts
- 1;
386 ngx_http_variable_value_t
*
387 ngx_http_get_indexed_variable(ngx_http_request_t
*r
, ngx_uint_t index
)
389 ngx_http_variable_t
*v
;
390 ngx_http_core_main_conf_t
*cmcf
;
392 cmcf
= ngx_http_get_module_main_conf(r
, ngx_http_core_module
);
394 if (cmcf
->variables
.nelts
<= index
) {
395 ngx_log_error(NGX_LOG_ALERT
, r
->connection
->log
, 0,
396 "unknown variable index: %d", index
);
400 if (r
->variables
[index
].not_found
|| r
->variables
[index
].valid
) {
401 return &r
->variables
[index
];
404 v
= cmcf
->variables
.elts
;
406 if (v
[index
].get_handler(r
, &r
->variables
[index
], v
[index
].data
)
409 if (v
[index
].flags
& NGX_HTTP_VAR_NOCACHEABLE
) {
410 r
->variables
[index
].no_cacheable
= 1;
413 return &r
->variables
[index
];
416 r
->variables
[index
].valid
= 0;
417 r
->variables
[index
].not_found
= 1;
423 ngx_http_variable_value_t
*
424 ngx_http_get_flushed_variable(ngx_http_request_t
*r
, ngx_uint_t index
)
426 ngx_http_variable_value_t
*v
;
428 v
= &r
->variables
[index
];
431 if (!v
->no_cacheable
) {
439 return ngx_http_get_indexed_variable(r
, index
);
443 ngx_http_variable_value_t
*
444 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_flushed_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_", 14) == 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
) {
533 ngx_http_variable_request(ngx_http_request_t
*r
, ngx_http_variable_value_t
*v
,
538 s
= (ngx_str_t
*) ((char *) r
+ data
);
556 ngx_http_variable_request_set(ngx_http_request_t
*r
,
557 ngx_http_variable_value_t
*v
, uintptr_t data
)
561 s
= (ngx_str_t
*) ((char *) r
+ data
);
569 ngx_http_variable_request_get_size(ngx_http_request_t
*r
,
570 ngx_http_variable_value_t
*v
, uintptr_t data
)
574 sp
= (size_t *) ((char *) r
+ data
);
576 v
->data
= ngx_pnalloc(r
->pool
, NGX_SIZE_T_LEN
);
577 if (v
->data
== NULL
) {
581 v
->len
= ngx_sprintf(v
->data
, "%uz", *sp
) - v
->data
;
591 ngx_http_variable_request_set_size(ngx_http_request_t
*r
,
592 ngx_http_variable_value_t
*v
, uintptr_t data
)
600 s
= ngx_parse_size(&val
);
602 if (s
== NGX_ERROR
) {
603 ngx_log_error(NGX_LOG_ERR
, r
->connection
->log
, 0,
604 "invalid size \"%V\"", &val
);
608 sp
= (ssize_t
*) ((char *) r
+ data
);
617 ngx_http_variable_header(ngx_http_request_t
*r
, ngx_http_variable_value_t
*v
,
622 h
= *(ngx_table_elt_t
**) ((char *) r
+ data
);
625 v
->len
= h
->value
.len
;
629 v
->data
= h
->value
.data
;
640 ngx_http_variable_headers(ngx_http_request_t
*r
, ngx_http_variable_value_t
*v
,
649 a
= (ngx_array_t
*) ((char *) r
+ data
);
665 v
->len
= (*h
)->value
.len
;
666 v
->data
= (*h
)->value
.data
;
671 len
= - (ssize_t
) (sizeof("; ") - 1);
673 for (i
= 0; i
< n
; i
++) {
674 len
+= h
[i
]->value
.len
+ sizeof("; ") - 1;
677 p
= ngx_pnalloc(r
->pool
, len
);
685 for (i
= 0; /* void */ ; i
++) {
686 p
= ngx_copy(p
, h
[i
]->value
.data
, h
[i
]->value
.len
);
692 *p
++ = ';'; *p
++ = ' ';
700 ngx_http_variable_unknown_header_in(ngx_http_request_t
*r
,
701 ngx_http_variable_value_t
*v
, uintptr_t data
)
703 return ngx_http_variable_unknown_header(v
, (ngx_str_t
*) data
,
704 &r
->headers_in
.headers
.part
,
705 sizeof("http_") - 1);
710 ngx_http_variable_unknown_header_out(ngx_http_request_t
*r
,
711 ngx_http_variable_value_t
*v
, uintptr_t data
)
713 return ngx_http_variable_unknown_header(v
, (ngx_str_t
*) data
,
714 &r
->headers_out
.headers
.part
,
715 sizeof("sent_http_") - 1);
720 ngx_http_variable_unknown_header(ngx_http_variable_value_t
*v
, ngx_str_t
*var
,
721 ngx_list_part_t
*part
, size_t prefix
)
725 ngx_table_elt_t
*header
;
729 for (i
= 0; /* void */ ; i
++) {
731 if (i
>= part
->nelts
) {
732 if (part
->next
== NULL
) {
741 for (n
= 0; n
+ prefix
< var
->len
&& n
< header
[i
].key
.len
; n
++) {
742 ch
= header
[i
].key
.data
[n
];
744 if (ch
>= 'A' && ch
<= 'Z') {
747 } else if (ch
== '-') {
751 if (var
->data
[n
+ prefix
] != ch
) {
756 if (n
+ prefix
== var
->len
&& n
== header
[i
].key
.len
) {
757 v
->len
= header
[i
].value
.len
;
761 v
->data
= header
[i
].value
.data
;
774 ngx_http_variable_request_line(ngx_http_request_t
*r
,
775 ngx_http_variable_value_t
*v
, uintptr_t data
)
779 s
= r
->request_line
.data
;
782 s
= r
->request_start
;
789 for (p
= s
; p
< r
->header_in
->last
; p
++) {
790 if (*p
== CR
|| *p
== LF
) {
795 r
->request_line
.len
= p
- s
;
796 r
->request_line
.data
= s
;
799 v
->len
= r
->request_line
.len
;
810 ngx_http_variable_cookie(ngx_http_request_t
*r
, ngx_http_variable_value_t
*v
,
813 ngx_str_t
*name
= (ngx_str_t
*) data
;
817 s
.len
= name
->len
- (sizeof("cookie_") - 1);
818 s
.data
= name
->data
+ sizeof("cookie_") - 1;
820 if (ngx_http_parse_multi_header_lines(&r
->headers_in
.cookies
, &s
, &cookie
)
831 v
->data
= cookie
.data
;
838 ngx_http_variable_argument(ngx_http_request_t
*r
, ngx_http_variable_value_t
*v
,
841 ngx_str_t
*name
= (ngx_str_t
*) data
;
847 len
= name
->len
- (sizeof("arg_") - 1);
848 arg
= name
->data
+ sizeof("arg_") - 1;
850 if (ngx_http_arg(r
, arg
, len
, &value
) != NGX_OK
) {
855 v
->data
= value
.data
;
866 ngx_http_variable_host(ngx_http_request_t
*r
, ngx_http_variable_value_t
*v
,
869 ngx_http_core_srv_conf_t
*cscf
;
871 if (r
->headers_in
.server
.len
) {
872 v
->len
= r
->headers_in
.server
.len
;
873 v
->data
= r
->headers_in
.server
.data
;
876 cscf
= ngx_http_get_module_srv_conf(r
, ngx_http_core_module
);
878 v
->len
= cscf
->server_name
.len
;
879 v
->data
= cscf
->server_name
.data
;
891 ngx_http_variable_binary_remote_addr(ngx_http_request_t
*r
,
892 ngx_http_variable_value_t
*v
, uintptr_t data
)
894 struct sockaddr_in
*sin
;
896 struct sockaddr_in6
*sin6
;
899 switch (r
->connection
->sockaddr
->sa_family
) {
903 sin6
= (struct sockaddr_in6
*) r
->connection
->sockaddr
;
905 v
->len
= sizeof(struct in6_addr
);
909 v
->data
= sin6
->sin6_addr
.s6_addr
;
914 default: /* AF_INET */
915 sin
= (struct sockaddr_in
*) r
->connection
->sockaddr
;
917 v
->len
= sizeof(in_addr_t
);
921 v
->data
= (u_char
*) &sin
->sin_addr
;
931 ngx_http_variable_remote_addr(ngx_http_request_t
*r
,
932 ngx_http_variable_value_t
*v
, uintptr_t data
)
934 v
->len
= r
->connection
->addr_text
.len
;
938 v
->data
= r
->connection
->addr_text
.data
;
945 ngx_http_variable_remote_port(ngx_http_request_t
*r
,
946 ngx_http_variable_value_t
*v
, uintptr_t data
)
949 struct sockaddr_in
*sin
;
951 struct sockaddr_in6
*sin6
;
959 v
->data
= ngx_pnalloc(r
->pool
, sizeof("65535") - 1);
960 if (v
->data
== NULL
) {
964 switch (r
->connection
->sockaddr
->sa_family
) {
968 sin6
= (struct sockaddr_in6
*) r
->connection
->sockaddr
;
969 port
= ntohs(sin6
->sin6_port
);
973 default: /* AF_INET */
974 sin
= (struct sockaddr_in
*) r
->connection
->sockaddr
;
975 port
= ntohs(sin
->sin_port
);
979 if (port
> 0 && port
< 65536) {
980 v
->len
= ngx_sprintf(v
->data
, "%ui", port
) - v
->data
;
988 ngx_http_variable_server_addr(ngx_http_request_t
*r
,
989 ngx_http_variable_value_t
*v
, uintptr_t data
)
992 u_char addr
[NGX_SOCKADDR_STRLEN
];
994 s
.len
= NGX_SOCKADDR_STRLEN
;
997 if (ngx_connection_local_sockaddr(r
->connection
, &s
, 0) != NGX_OK
) {
1001 s
.data
= ngx_pnalloc(r
->pool
, s
.len
);
1002 if (s
.data
== NULL
) {
1006 ngx_memcpy(s
.data
, addr
, s
.len
);
1010 v
->no_cacheable
= 0;
1019 ngx_http_variable_server_port(ngx_http_request_t
*r
,
1020 ngx_http_variable_value_t
*v
, uintptr_t data
)
1023 struct sockaddr_in
*sin
;
1024 #if (NGX_HAVE_INET6)
1025 struct sockaddr_in6
*sin6
;
1030 v
->no_cacheable
= 0;
1033 if (ngx_connection_local_sockaddr(r
->connection
, NULL
, 0) != NGX_OK
) {
1037 v
->data
= ngx_pnalloc(r
->pool
, sizeof("65535") - 1);
1038 if (v
->data
== NULL
) {
1042 switch (r
->connection
->local_sockaddr
->sa_family
) {
1044 #if (NGX_HAVE_INET6)
1046 sin6
= (struct sockaddr_in6
*) r
->connection
->local_sockaddr
;
1047 port
= ntohs(sin6
->sin6_port
);
1051 default: /* AF_INET */
1052 sin
= (struct sockaddr_in
*) r
->connection
->local_sockaddr
;
1053 port
= ntohs(sin
->sin_port
);
1057 if (port
> 0 && port
< 65536) {
1058 v
->len
= ngx_sprintf(v
->data
, "%ui", port
) - v
->data
;
1066 ngx_http_variable_scheme(ngx_http_request_t
*r
,
1067 ngx_http_variable_value_t
*v
, uintptr_t data
)
1071 if (r
->connection
->ssl
) {
1072 v
->len
= sizeof("https") - 1;
1074 v
->no_cacheable
= 0;
1076 v
->data
= (u_char
*) "https";
1083 v
->len
= sizeof("http") - 1;
1085 v
->no_cacheable
= 0;
1087 v
->data
= (u_char
*) "http";
1094 ngx_http_variable_is_args(ngx_http_request_t
*r
,
1095 ngx_http_variable_value_t
*v
, uintptr_t data
)
1098 v
->no_cacheable
= 0;
1101 if (r
->args
.len
== 0) {
1108 v
->data
= (u_char
*) "?";
1115 ngx_http_variable_document_root(ngx_http_request_t
*r
,
1116 ngx_http_variable_value_t
*v
, uintptr_t data
)
1119 ngx_http_core_loc_conf_t
*clcf
;
1121 clcf
= ngx_http_get_module_loc_conf(r
, ngx_http_core_module
);
1123 if (clcf
->root_lengths
== NULL
) {
1124 v
->len
= clcf
->root
.len
;
1126 v
->no_cacheable
= 0;
1128 v
->data
= clcf
->root
.data
;
1131 if (ngx_http_script_run(r
, &path
, clcf
->root_lengths
->elts
, 0,
1132 clcf
->root_values
->elts
)
1138 if (ngx_conf_full_name((ngx_cycle_t
*) ngx_cycle
, &path
, 0) != NGX_OK
) {
1144 v
->no_cacheable
= 0;
1146 v
->data
= path
.data
;
1154 ngx_http_variable_realpath_root(ngx_http_request_t
*r
,
1155 ngx_http_variable_value_t
*v
, uintptr_t data
)
1159 ngx_http_core_loc_conf_t
*clcf
;
1160 u_char real
[NGX_MAX_PATH
];
1162 clcf
= ngx_http_get_module_loc_conf(r
, ngx_http_core_module
);
1164 if (clcf
->root_lengths
== NULL
) {
1168 if (ngx_http_script_run(r
, &path
, clcf
->root_lengths
->elts
, 1,
1169 clcf
->root_values
->elts
)
1175 path
.data
[path
.len
- 1] = '\0';
1177 if (ngx_conf_full_name((ngx_cycle_t
*) ngx_cycle
, &path
, 0) != NGX_OK
) {
1182 if (ngx_realpath(path
.data
, real
) == NULL
) {
1183 ngx_log_error(NGX_LOG_CRIT
, r
->connection
->log
, ngx_errno
,
1184 ngx_realpath_n
" \"%s\" failed", path
.data
);
1188 len
= ngx_strlen(real
);
1190 v
->data
= ngx_pnalloc(r
->pool
, len
);
1191 if (v
->data
== NULL
) {
1197 v
->no_cacheable
= 0;
1200 ngx_memcpy(v
->data
, real
, len
);
1207 ngx_http_variable_request_filename(ngx_http_request_t
*r
,
1208 ngx_http_variable_value_t
*v
, uintptr_t data
)
1213 if (ngx_http_map_uri_to_path(r
, &path
, &root
, 0) == NULL
) {
1217 /* ngx_http_map_uri_to_path() allocates memory for terminating '\0' */
1219 v
->len
= path
.len
- 1;
1221 v
->no_cacheable
= 0;
1223 v
->data
= path
.data
;
1230 ngx_http_variable_server_name(ngx_http_request_t
*r
,
1231 ngx_http_variable_value_t
*v
, uintptr_t data
)
1233 ngx_http_core_srv_conf_t
*cscf
;
1235 cscf
= ngx_http_get_module_srv_conf(r
, ngx_http_core_module
);
1237 v
->len
= cscf
->server_name
.len
;
1239 v
->no_cacheable
= 0;
1241 v
->data
= cscf
->server_name
.data
;
1248 ngx_http_variable_request_method(ngx_http_request_t
*r
,
1249 ngx_http_variable_value_t
*v
, uintptr_t data
)
1251 if (r
->main
->method_name
.data
) {
1252 v
->len
= r
->main
->method_name
.len
;
1254 v
->no_cacheable
= 0;
1256 v
->data
= r
->main
->method_name
.data
;
1267 ngx_http_variable_remote_user(ngx_http_request_t
*r
,
1268 ngx_http_variable_value_t
*v
, uintptr_t data
)
1272 rc
= ngx_http_auth_basic_user(r
);
1274 if (rc
== NGX_DECLINED
) {
1279 if (rc
== NGX_ERROR
) {
1283 v
->len
= r
->headers_in
.user
.len
;
1285 v
->no_cacheable
= 0;
1287 v
->data
= r
->headers_in
.user
.data
;
1294 ngx_http_variable_body_bytes_sent(ngx_http_request_t
*r
,
1295 ngx_http_variable_value_t
*v
, uintptr_t data
)
1300 sent
= r
->connection
->sent
- r
->header_size
;
1306 p
= ngx_pnalloc(r
->pool
, NGX_OFF_T_LEN
);
1311 v
->len
= ngx_sprintf(p
, "%O", sent
) - p
;
1313 v
->no_cacheable
= 0;
1322 ngx_http_variable_sent_content_type(ngx_http_request_t
*r
,
1323 ngx_http_variable_value_t
*v
, uintptr_t data
)
1325 if (r
->headers_out
.content_type
.len
) {
1326 v
->len
= r
->headers_out
.content_type
.len
;
1328 v
->no_cacheable
= 0;
1330 v
->data
= r
->headers_out
.content_type
.data
;
1341 ngx_http_variable_sent_content_length(ngx_http_request_t
*r
,
1342 ngx_http_variable_value_t
*v
, uintptr_t data
)
1346 if (r
->headers_out
.content_length
) {
1347 v
->len
= r
->headers_out
.content_length
->value
.len
;
1349 v
->no_cacheable
= 0;
1351 v
->data
= r
->headers_out
.content_length
->value
.data
;
1356 if (r
->headers_out
.content_length_n
>= 0) {
1357 p
= ngx_pnalloc(r
->pool
, NGX_OFF_T_LEN
);
1362 v
->len
= ngx_sprintf(p
, "%O", r
->headers_out
.content_length_n
) - p
;
1364 v
->no_cacheable
= 0;
1378 ngx_http_variable_sent_location(ngx_http_request_t
*r
,
1379 ngx_http_variable_value_t
*v
, uintptr_t data
)
1383 if (r
->headers_out
.location
) {
1384 v
->len
= r
->headers_out
.location
->value
.len
;
1386 v
->no_cacheable
= 0;
1388 v
->data
= r
->headers_out
.location
->value
.data
;
1393 name
.len
= sizeof("sent_http_location") - 1;
1394 name
.data
= (u_char
*) "sent_http_location";
1396 return ngx_http_variable_unknown_header(v
, &name
,
1397 &r
->headers_out
.headers
.part
,
1398 sizeof("sent_http_") - 1);
1403 ngx_http_variable_sent_last_modified(ngx_http_request_t
*r
,
1404 ngx_http_variable_value_t
*v
, uintptr_t data
)
1408 if (r
->headers_out
.last_modified
) {
1409 v
->len
= r
->headers_out
.last_modified
->value
.len
;
1411 v
->no_cacheable
= 0;
1413 v
->data
= r
->headers_out
.last_modified
->value
.data
;
1418 if (r
->headers_out
.last_modified_time
>= 0) {
1419 p
= ngx_pnalloc(r
->pool
,
1420 sizeof("Last-Modified: Mon, 28 Sep 1970 06:00:00 GMT") - 1);
1425 v
->len
= ngx_http_time(p
, r
->headers_out
.last_modified_time
) - p
;
1427 v
->no_cacheable
= 0;
1441 ngx_http_variable_sent_connection(ngx_http_request_t
*r
,
1442 ngx_http_variable_value_t
*v
, uintptr_t data
)
1448 len
= sizeof("keep-alive") - 1;
1452 len
= sizeof("close") - 1;
1458 v
->no_cacheable
= 0;
1460 v
->data
= (u_char
*) p
;
1467 ngx_http_variable_sent_keep_alive(ngx_http_request_t
*r
,
1468 ngx_http_variable_value_t
*v
, uintptr_t data
)
1471 ngx_http_core_loc_conf_t
*clcf
;
1474 clcf
= ngx_http_get_module_loc_conf(r
, ngx_http_core_module
);
1476 if (clcf
->keepalive_header
) {
1478 p
= ngx_pnalloc(r
->pool
, sizeof("timeout=") - 1 + NGX_TIME_T_LEN
);
1483 v
->len
= ngx_sprintf(p
, "timeout=%T", clcf
->keepalive_header
) - p
;
1485 v
->no_cacheable
= 0;
1500 ngx_http_variable_sent_transfer_encoding(ngx_http_request_t
*r
,
1501 ngx_http_variable_value_t
*v
, uintptr_t data
)
1504 v
->len
= sizeof("chunked") - 1;
1506 v
->no_cacheable
= 0;
1508 v
->data
= (u_char
*) "chunked";
1519 ngx_http_variable_request_completion(ngx_http_request_t
*r
,
1520 ngx_http_variable_value_t
*v
, uintptr_t data
)
1522 if (r
->request_complete
) {
1525 v
->no_cacheable
= 0;
1527 v
->data
= (u_char
*) "OK";
1534 v
->no_cacheable
= 0;
1536 v
->data
= (u_char
*) "";
1543 ngx_http_variable_request_body(ngx_http_request_t
*r
,
1544 ngx_http_variable_value_t
*v
, uintptr_t data
)
1548 ngx_buf_t
*buf
, *next
;
1551 if (r
->request_body
== NULL
1552 || r
->request_body
->bufs
== NULL
1553 || r
->request_body
->temp_file
)
1560 cl
= r
->request_body
->bufs
;
1563 if (cl
->next
== NULL
) {
1564 v
->len
= buf
->last
- buf
->pos
;
1566 v
->no_cacheable
= 0;
1573 next
= cl
->next
->buf
;
1574 len
= (buf
->last
- buf
->pos
) + (next
->last
- next
->pos
);
1576 p
= ngx_pnalloc(r
->pool
, len
);
1583 p
= ngx_cpymem(p
, buf
->pos
, buf
->last
- buf
->pos
);
1584 ngx_memcpy(p
, next
->pos
, next
->last
- next
->pos
);
1588 v
->no_cacheable
= 0;
1596 ngx_http_variable_request_body_file(ngx_http_request_t
*r
,
1597 ngx_http_variable_value_t
*v
, uintptr_t data
)
1599 if (r
->request_body
== NULL
|| r
->request_body
->temp_file
== NULL
) {
1605 v
->len
= r
->request_body
->temp_file
->file
.name
.len
;
1607 v
->no_cacheable
= 0;
1609 v
->data
= r
->request_body
->temp_file
->file
.name
.data
;
1616 ngx_http_variable_nginx_version(ngx_http_request_t
*r
,
1617 ngx_http_variable_value_t
*v
, uintptr_t data
)
1619 v
->len
= sizeof(NGINX_VERSION
) - 1;
1621 v
->no_cacheable
= 0;
1623 v
->data
= (u_char
*) NGINX_VERSION
;
1630 ngx_http_variable_hostname(ngx_http_request_t
*r
,
1631 ngx_http_variable_value_t
*v
, uintptr_t data
)
1633 v
->len
= ngx_cycle
->hostname
.len
;
1635 v
->no_cacheable
= 0;
1637 v
->data
= ngx_cycle
->hostname
.data
;
1644 ngx_http_variable_pid(ngx_http_request_t
*r
,
1645 ngx_http_variable_value_t
*v
, uintptr_t data
)
1649 p
= ngx_pnalloc(r
->pool
, NGX_INT64_LEN
);
1654 v
->len
= ngx_sprintf(p
, "%P", ngx_pid
) - p
;
1656 v
->no_cacheable
= 0;
1667 ngx_http_variable_not_found(ngx_http_request_t
*r
, ngx_http_variable_value_t
*v
,
1676 ngx_http_regex_compile(ngx_conf_t
*cf
, ngx_regex_compile_t
*rc
)
1682 ngx_http_variable_t
*v
;
1683 ngx_http_regex_t
*re
;
1684 ngx_http_regex_variable_t
*rv
;
1685 ngx_http_core_main_conf_t
*cmcf
;
1687 rc
->pool
= cf
->pool
;
1689 if (ngx_regex_compile(rc
) != NGX_OK
) {
1690 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, 0, "%V", &rc
->err
);
1694 re
= ngx_pcalloc(cf
->pool
, sizeof(ngx_http_regex_t
));
1699 re
->regex
= rc
->regex
;
1700 re
->ncaptures
= rc
->captures
;
1702 cmcf
= ngx_http_conf_get_module_main_conf(cf
, ngx_http_core_module
);
1703 cmcf
->ncaptures
= ngx_max(cmcf
->ncaptures
, re
->ncaptures
);
1705 n
= (ngx_uint_t
) rc
->named_captures
;
1711 rv
= ngx_palloc(rc
->pool
, n
* sizeof(ngx_http_regex_variable_t
));
1718 re
->name
= rc
->pattern
;
1720 size
= rc
->name_size
;
1723 for (i
= 0; i
< n
; i
++) {
1724 rv
[i
].capture
= 2 * ((p
[0] << 8) + p
[1]);
1727 name
.len
= ngx_strlen(name
.data
);
1729 v
= ngx_http_add_variable(cf
, &name
, NGX_HTTP_VAR_CHANGEABLE
);
1734 rv
[i
].index
= ngx_http_get_variable_index(cf
, &name
);
1735 if (rv
[i
].index
== NGX_ERROR
) {
1739 v
->get_handler
= ngx_http_variable_not_found
;
1749 ngx_http_regex_exec(ngx_http_request_t
*r
, ngx_http_regex_t
*re
, ngx_str_t
*s
)
1751 ngx_int_t rc
, index
;
1752 ngx_uint_t i
, n
, len
;
1753 ngx_http_variable_value_t
*vv
;
1754 ngx_http_core_main_conf_t
*cmcf
;
1756 cmcf
= ngx_http_get_module_main_conf(r
, ngx_http_core_module
);
1758 if (re
->ncaptures
) {
1759 len
= cmcf
->ncaptures
;
1761 if (r
->captures
== NULL
) {
1762 r
->captures
= ngx_palloc(r
->pool
, len
* sizeof(int));
1763 if (r
->captures
== NULL
) {
1772 rc
= ngx_regex_exec(re
->regex
, s
, r
->captures
, len
);
1774 if (rc
== NGX_REGEX_NO_MATCHED
) {
1775 return NGX_DECLINED
;
1779 ngx_log_error(NGX_LOG_ALERT
, r
->connection
->log
, 0,
1780 ngx_regex_exec_n
" failed: %i on \"%V\" using \"%V\"",
1785 for (i
= 0; i
< re
->nvariables
; i
++) {
1787 n
= re
->variables
[i
].capture
;
1788 index
= re
->variables
[i
].index
;
1789 vv
= &r
->variables
[index
];
1791 vv
->len
= r
->captures
[n
+ 1] - r
->captures
[n
];
1793 vv
->no_cacheable
= 0;
1795 vv
->data
= &s
->data
[r
->captures
[n
]];
1799 ngx_http_variable_t
*v
;
1801 v
= cmcf
->variables
.elts
;
1803 ngx_log_debug3(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0,
1804 "http regex set $%V to \"%*s\"",
1805 &v
[index
].name
, vv
->len
, vv
->data
);
1810 r
->ncaptures
= rc
* 2;
1811 r
->captures_data
= s
->data
;
1820 ngx_http_variables_add_core_vars(ngx_conf_t
*cf
)
1823 ngx_http_variable_t
*v
;
1824 ngx_http_core_main_conf_t
*cmcf
;
1826 cmcf
= ngx_http_conf_get_module_main_conf(cf
, ngx_http_core_module
);
1828 cmcf
->variables_keys
= ngx_pcalloc(cf
->temp_pool
,
1829 sizeof(ngx_hash_keys_arrays_t
));
1830 if (cmcf
->variables_keys
== NULL
) {
1834 cmcf
->variables_keys
->pool
= cf
->pool
;
1835 cmcf
->variables_keys
->temp_pool
= cf
->pool
;
1837 if (ngx_hash_keys_array_init(cmcf
->variables_keys
, NGX_HASH_SMALL
)
1843 for (v
= ngx_http_core_variables
; v
->name
.len
; v
++) {
1844 rc
= ngx_hash_add_key(cmcf
->variables_keys
, &v
->name
, v
,
1845 NGX_HASH_READONLY_KEY
);
1851 if (rc
== NGX_BUSY
) {
1852 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, 0,
1853 "conflicting variable name \"%V\"", &v
->name
);
1864 ngx_http_variables_init_vars(ngx_conf_t
*cf
)
1867 ngx_hash_key_t
*key
;
1868 ngx_hash_init_t hash
;
1869 ngx_http_variable_t
*v
, *av
;
1870 ngx_http_core_main_conf_t
*cmcf
;
1872 /* set the handlers for the indexed http variables */
1874 cmcf
= ngx_http_conf_get_module_main_conf(cf
, ngx_http_core_module
);
1876 v
= cmcf
->variables
.elts
;
1877 key
= cmcf
->variables_keys
->keys
.elts
;
1879 for (i
= 0; i
< cmcf
->variables
.nelts
; i
++) {
1881 for (n
= 0; n
< cmcf
->variables_keys
->keys
.nelts
; n
++) {
1886 && v
[i
].name
.len
== key
[n
].key
.len
1887 && ngx_strncmp(v
[i
].name
.data
, key
[n
].key
.data
, v
[i
].name
.len
)
1890 v
[i
].get_handler
= av
->get_handler
;
1891 v
[i
].data
= av
->data
;
1893 av
->flags
|= NGX_HTTP_VAR_INDEXED
;
1894 v
[i
].flags
= av
->flags
;
1902 if (ngx_strncmp(v
[i
].name
.data
, "http_", 5) == 0) {
1903 v
[i
].get_handler
= ngx_http_variable_unknown_header_in
;
1904 v
[i
].data
= (uintptr_t) &v
[i
].name
;
1909 if (ngx_strncmp(v
[i
].name
.data
, "sent_http_", 10) == 0) {
1910 v
[i
].get_handler
= ngx_http_variable_unknown_header_out
;
1911 v
[i
].data
= (uintptr_t) &v
[i
].name
;
1916 if (ngx_strncmp(v
[i
].name
.data
, "upstream_http_", 14) == 0) {
1917 v
[i
].get_handler
= ngx_http_upstream_header_variable
;
1918 v
[i
].data
= (uintptr_t) &v
[i
].name
;
1919 v
[i
].flags
= NGX_HTTP_VAR_NOCACHEABLE
;
1924 if (ngx_strncmp(v
[i
].name
.data
, "cookie_", 7) == 0) {
1925 v
[i
].get_handler
= ngx_http_variable_cookie
;
1926 v
[i
].data
= (uintptr_t) &v
[i
].name
;
1931 if (ngx_strncmp(v
[i
].name
.data
, "arg_", 4) == 0) {
1932 v
[i
].get_handler
= ngx_http_variable_argument
;
1933 v
[i
].data
= (uintptr_t) &v
[i
].name
;
1934 v
[i
].flags
= NGX_HTTP_VAR_NOCACHEABLE
;
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
);