1e18a033bSKonstantin Ananyev
2e18a033bSKonstantin Ananyev/*
3e18a033bSKonstantin Ananyev * Copyright (C) Igor Sysoev
4e18a033bSKonstantin Ananyev * Copyright (C) Nginx, Inc.
5e18a033bSKonstantin Ananyev */
6e18a033bSKonstantin Ananyev
7e18a033bSKonstantin Ananyev
8e18a033bSKonstantin Ananyev#include <ngx_config.h>
9e18a033bSKonstantin Ananyev#include <ngx_core.h>
10e18a033bSKonstantin Ananyev#include <ngx_http.h>
11e18a033bSKonstantin Ananyev#include <nginx.h>
12e18a033bSKonstantin Ananyev
13e18a033bSKonstantin Ananyev
14e18a033bSKonstantin Ananyevstatic ngx_http_variable_t *ngx_http_add_prefix_variable(ngx_conf_t *cf,
15e18a033bSKonstantin Ananyev    ngx_str_t *name, ngx_uint_t flags);
16e18a033bSKonstantin Ananyev
17e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_request(ngx_http_request_t *r,
18e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
19e18a033bSKonstantin Ananyev#if 0
20e18a033bSKonstantin Ananyevstatic void ngx_http_variable_request_set(ngx_http_request_t *r,
21e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
22e18a033bSKonstantin Ananyev#endif
23e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_request_get_size(ngx_http_request_t *r,
24e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
25e18a033bSKonstantin Ananyevstatic void ngx_http_variable_request_set_size(ngx_http_request_t *r,
26e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
27e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_header(ngx_http_request_t *r,
28e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
29e18a033bSKonstantin Ananyev
30e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_cookies(ngx_http_request_t *r,
31e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
32e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_headers(ngx_http_request_t *r,
33e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
34e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_headers_internal(ngx_http_request_t *r,
35e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data, u_char sep);
36e18a033bSKonstantin Ananyev
37e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_unknown_header_in(ngx_http_request_t *r,
38e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
39e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_unknown_header_out(ngx_http_request_t *r,
40e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
41e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_request_line(ngx_http_request_t *r,
42e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
43e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_cookie(ngx_http_request_t *r,
44e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
45e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_argument(ngx_http_request_t *r,
46e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
47e18a033bSKonstantin Ananyev#if (NGX_HAVE_TCP_INFO)
48e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_tcpinfo(ngx_http_request_t *r,
49e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
50e18a033bSKonstantin Ananyev#endif
51e18a033bSKonstantin Ananyev
52e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_content_length(ngx_http_request_t *r,
53e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
54e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_host(ngx_http_request_t *r,
55e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
56e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_binary_remote_addr(ngx_http_request_t *r,
57e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
58e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_remote_addr(ngx_http_request_t *r,
59e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
60e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_remote_port(ngx_http_request_t *r,
61e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
62e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_proxy_protocol_addr(ngx_http_request_t *r,
63e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
64e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_proxy_protocol_port(ngx_http_request_t *r,
65e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
66e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_server_addr(ngx_http_request_t *r,
67e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
68e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_server_port(ngx_http_request_t *r,
69e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
70e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_scheme(ngx_http_request_t *r,
71e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
72e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_https(ngx_http_request_t *r,
73e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
74e18a033bSKonstantin Ananyevstatic void ngx_http_variable_set_args(ngx_http_request_t *r,
75e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
76e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_is_args(ngx_http_request_t *r,
77e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
78e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_document_root(ngx_http_request_t *r,
79e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
80e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_realpath_root(ngx_http_request_t *r,
81e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
82e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_request_filename(ngx_http_request_t *r,
83e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
84e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_server_name(ngx_http_request_t *r,
85e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
86e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_request_method(ngx_http_request_t *r,
87e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
88e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_remote_user(ngx_http_request_t *r,
89e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
90e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_bytes_sent(ngx_http_request_t *r,
91e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
92e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_body_bytes_sent(ngx_http_request_t *r,
93e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
94e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_pipe(ngx_http_request_t *r,
95e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
96e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_request_completion(ngx_http_request_t *r,
97e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
98e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_request_body(ngx_http_request_t *r,
99e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
100e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_request_body_file(ngx_http_request_t *r,
101e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
102e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_request_length(ngx_http_request_t *r,
103e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
104e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_request_time(ngx_http_request_t *r,
105e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
106e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_request_id(ngx_http_request_t *r,
107e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
108e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_status(ngx_http_request_t *r,
109e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
110e18a033bSKonstantin Ananyev
111e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_sent_content_type(ngx_http_request_t *r,
112e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
113e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_sent_content_length(ngx_http_request_t *r,
114e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
115e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_sent_location(ngx_http_request_t *r,
116e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
117e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_sent_last_modified(ngx_http_request_t *r,
118e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
119e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_sent_connection(ngx_http_request_t *r,
120e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
121e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_sent_keep_alive(ngx_http_request_t *r,
122e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
123e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_sent_transfer_encoding(ngx_http_request_t *r,
124e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
125e18a033bSKonstantin Ananyev
126e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_connection(ngx_http_request_t *r,
127e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
128e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_connection_requests(ngx_http_request_t *r,
129e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
130e18a033bSKonstantin Ananyev
131e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_nginx_version(ngx_http_request_t *r,
132e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
133e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_hostname(ngx_http_request_t *r,
134e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
135e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_pid(ngx_http_request_t *r,
136e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
137e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_msec(ngx_http_request_t *r,
138e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
139e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_time_iso8601(ngx_http_request_t *r,
140e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
141e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_http_variable_time_local(ngx_http_request_t *r,
142e18a033bSKonstantin Ananyev    ngx_http_variable_value_t *v, uintptr_t data);
143e18a033bSKonstantin Ananyev
144e18a033bSKonstantin Ananyev/*
145e18a033bSKonstantin Ananyev * TODO:
146e18a033bSKonstantin Ananyev *     Apache CGI: AUTH_TYPE, PATH_INFO (null), PATH_TRANSLATED
147e18a033bSKonstantin Ananyev *                 REMOTE_HOST (null), REMOTE_IDENT (null),
148e18a033bSKonstantin Ananyev *                 SERVER_SOFTWARE
149e18a033bSKonstantin Ananyev *
150e18a033bSKonstantin Ananyev *     Apache SSI: DOCUMENT_NAME, LAST_MODIFIED, USER_NAME (file owner)
151e18a033bSKonstantin Ananyev */
152e18a033bSKonstantin Ananyev
153e18a033bSKonstantin Ananyev/*
154e18a033bSKonstantin Ananyev * the $http_host, $http_user_agent, $http_referer, and $http_via
155e18a033bSKonstantin Ananyev * variables may be handled by generic
156e18a033bSKonstantin Ananyev * ngx_http_variable_unknown_header_in(), but for performance reasons
157e18a033bSKonstantin Ananyev * they are handled using dedicated entries
158e18a033bSKonstantin Ananyev */
159e18a033bSKonstantin Ananyev
160e18a033bSKonstantin Ananyevstatic ngx_http_variable_t  ngx_http_core_variables[] = {
161e18a033bSKonstantin Ananyev
162e18a033bSKonstantin Ananyev    { ngx_string("http_host"), NULL, ngx_http_variable_header,
163e18a033bSKonstantin Ananyev      offsetof(ngx_http_request_t, headers_in.host), 0, 0 },
164e18a033bSKonstantin Ananyev
165e18a033bSKonstantin Ananyev    { ngx_string("http_user_agent"), NULL, ngx_http_variable_header,
166e18a033bSKonstantin Ananyev      offsetof(ngx_http_request_t, headers_in.user_agent), 0, 0 },
167e18a033bSKonstantin Ananyev
168e18a033bSKonstantin Ananyev    { ngx_string("http_referer"), NULL, ngx_http_variable_header,
169e18a033bSKonstantin Ananyev      offsetof(ngx_http_request_t, headers_in.referer), 0, 0 },
170e18a033bSKonstantin Ananyev
171e18a033bSKonstantin Ananyev#if (NGX_HTTP_GZIP)
172e18a033bSKonstantin Ananyev    { ngx_string("http_via"), NULL, ngx_http_variable_header,
173e18a033bSKonstantin Ananyev      offsetof(ngx_http_request_t, headers_in.via), 0, 0 },
174e18a033bSKonstantin Ananyev#endif
175e18a033bSKonstantin Ananyev
176e18a033bSKonstantin Ananyev#if (NGX_HTTP_X_FORWARDED_FOR)
177e18a033bSKonstantin Ananyev    { ngx_string("http_x_forwarded_for"), NULL, ngx_http_variable_headers,
178e18a033bSKonstantin Ananyev      offsetof(ngx_http_request_t, headers_in.x_forwarded_for), 0, 0 },
179e18a033bSKonstantin Ananyev#endif
180e18a033bSKonstantin Ananyev
181e18a033bSKonstantin Ananyev    { ngx_string("http_cookie"), NULL, ngx_http_variable_cookies,
182e18a033bSKonstantin Ananyev      offsetof(ngx_http_request_t, headers_in.cookies), 0, 0 },
183e18a033bSKonstantin Ananyev
184e18a033bSKonstantin Ananyev    { ngx_string("content_length"), NULL, ngx_http_variable_content_length,
185e18a033bSKonstantin Ananyev      0, 0, 0 },
186e18a033bSKonstantin Ananyev
187e18a033bSKonstantin Ananyev    { ngx_string("content_type"), NULL, ngx_http_variable_header,
188e18a033bSKonstantin Ananyev      offsetof(ngx_http_request_t, headers_in.content_type), 0, 0 },
189e18a033bSKonstantin Ananyev
190e18a033bSKonstantin Ananyev    { ngx_string("host"), NULL, ngx_http_variable_host, 0, 0, 0 },
191e18a033bSKonstantin Ananyev
192e18a033bSKonstantin Ananyev    { ngx_string("binary_remote_addr"), NULL,
193e18a033bSKonstantin Ananyev      ngx_http_variable_binary_remote_addr, 0, 0, 0 },
194e18a033bSKonstantin Ananyev
195e18a033bSKonstantin Ananyev    { ngx_string("remote_addr"), NULL, ngx_http_variable_remote_addr, 0, 0, 0 },
196e18a033bSKonstantin Ananyev
197e18a033bSKonstantin Ananyev    { ngx_string("remote_port"), NULL, ngx_http_variable_remote_port, 0, 0, 0 },
198e18a033bSKonstantin Ananyev
199e18a033bSKonstantin Ananyev    { ngx_string("proxy_protocol_addr"), NULL,
200e18a033bSKonstantin Ananyev      ngx_http_variable_proxy_protocol_addr, 0, 0, 0 },
201e18a033bSKonstantin Ananyev
202e18a033bSKonstantin Ananyev    { ngx_string("proxy_protocol_port"), NULL,
203e18a033bSKonstantin Ananyev      ngx_http_variable_proxy_protocol_port, 0, 0, 0 },
204e18a033bSKonstantin Ananyev
205e18a033bSKonstantin Ananyev    { ngx_string("server_addr"), NULL, ngx_http_variable_server_addr, 0, 0, 0 },
206e18a033bSKonstantin Ananyev
207e18a033bSKonstantin Ananyev    { ngx_string("server_port"), NULL, ngx_http_variable_server_port, 0, 0, 0 },
208e18a033bSKonstantin Ananyev
209e18a033bSKonstantin Ananyev    { ngx_string("server_protocol"), NULL, ngx_http_variable_request,
210e18a033bSKonstantin Ananyev      offsetof(ngx_http_request_t, http_protocol), 0, 0 },
211e18a033bSKonstantin Ananyev
212e18a033bSKonstantin Ananyev    { ngx_string("scheme"), NULL, ngx_http_variable_scheme, 0, 0, 0 },
213e18a033bSKonstantin Ananyev
214e18a033bSKonstantin Ananyev    { ngx_string("https"), NULL, ngx_http_variable_https, 0, 0, 0 },
215e18a033bSKonstantin Ananyev
216e18a033bSKonstantin Ananyev    { ngx_string("request_uri"), NULL, ngx_http_variable_request,
217e18a033bSKonstantin Ananyev      offsetof(ngx_http_request_t, unparsed_uri), 0, 0 },
218e18a033bSKonstantin Ananyev
219e18a033bSKonstantin Ananyev    { ngx_string("uri"), NULL, ngx_http_variable_request,
220e18a033bSKonstantin Ananyev      offsetof(ngx_http_request_t, uri),
221e18a033bSKonstantin Ananyev      NGX_HTTP_VAR_NOCACHEABLE, 0 },
222e18a033bSKonstantin Ananyev
223e18a033bSKonstantin Ananyev    { ngx_string("document_uri"), NULL, ngx_http_variable_request,
224e18a033bSKonstantin Ananyev      offsetof(ngx_http_request_t, uri),
225e18a033bSKonstantin Ananyev      NGX_HTTP_VAR_NOCACHEABLE, 0 },
226e18a033bSKonstantin Ananyev
227e18a033bSKonstantin Ananyev    { ngx_string("request"), NULL, ngx_http_variable_request_line, 0, 0, 0 },
228e18a033bSKonstantin Ananyev
229e18a033bSKonstantin Ananyev    { ngx_string("document_root"), NULL,
230e18a033bSKonstantin Ananyev      ngx_http_variable_document_root, 0, NGX_HTTP_VAR_NOCACHEABLE, 0 },
231e18a033bSKonstantin Ananyev
232e18a033bSKonstantin Ananyev    { ngx_string("realpath_root"), NULL,
233e18a033bSKonstantin Ananyev      ngx_http_variable_realpath_root, 0, NGX_HTTP_VAR_NOCACHEABLE, 0 },
234e18a033bSKonstantin Ananyev
235e18a033bSKonstantin Ananyev    { ngx_string("query_string"), NULL, ngx_http_variable_request,
236e18a033bSKonstantin Ananyev      offsetof(ngx_http_request_t, args),
237e18a033bSKonstantin Ananyev      NGX_HTTP_VAR_NOCACHEABLE, 0 },
238e18a033bSKonstantin Ananyev
239e18a033bSKonstantin Ananyev    { ngx_string("args"),
240e18a033bSKonstantin Ananyev      ngx_http_variable_set_args,
241e18a033bSKonstantin Ananyev      ngx_http_variable_request,
242e18a033bSKonstantin Ananyev      offsetof(ngx_http_request_t, args),
243e18a033bSKonstantin Ananyev      NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE, 0 },
244e18a033bSKonstantin Ananyev
245e18a033bSKonstantin Ananyev    { ngx_string("is_args"), NULL, ngx_http_variable_is_args,
246e18a033bSKonstantin Ananyev      0, NGX_HTTP_VAR_NOCACHEABLE, 0 },
247e18a033bSKonstantin Ananyev
248e18a033bSKonstantin Ananyev    { ngx_string("request_filename"), NULL,
249e18a033bSKonstantin Ananyev      ngx_http_variable_request_filename, 0,
250e18a033bSKonstantin Ananyev      NGX_HTTP_VAR_NOCACHEABLE, 0 },
251e18a033bSKonstantin Ananyev
252e18a033bSKonstantin Ananyev    { ngx_string("server_name"), NULL, ngx_http_variable_server_name, 0, 0, 0 },
253e18a033bSKonstantin Ananyev
254e18a033bSKonstantin Ananyev    { ngx_string("request_method"), NULL,
255e18a033bSKonstantin Ananyev      ngx_http_variable_request_method, 0,
256e18a033bSKonstantin Ananyev      NGX_HTTP_VAR_NOCACHEABLE, 0 },
257e18a033bSKonstantin Ananyev
258e18a033bSKonstantin Ananyev    { ngx_string("remote_user"), NULL, ngx_http_variable_remote_user, 0, 0, 0 },
259e18a033bSKonstantin Ananyev
260e18a033bSKonstantin Ananyev    { ngx_string("bytes_sent"), NULL, ngx_http_variable_bytes_sent,
261e18a033bSKonstantin Ananyev      0, 0, 0 },
262e18a033bSKonstantin Ananyev
263e18a033bSKonstantin Ananyev    { ngx_string("body_bytes_sent"), NULL, ngx_http_variable_body_bytes_sent,
264e18a033bSKonstantin Ananyev      0, 0, 0 },
265e18a033bSKonstantin Ananyev
266e18a033bSKonstantin Ananyev    { ngx_string("pipe"), NULL, ngx_http_variable_pipe,
267e18a033bSKonstantin Ananyev      0, 0, 0 },
268e18a033bSKonstantin Ananyev
269e18a033bSKonstantin Ananyev    { ngx_string("request_completion"), NULL,
270e18a033bSKonstantin Ananyev      ngx_http_variable_request_completion,
271e18a033bSKonstantin Ananyev      0, 0, 0 },
272e18a033bSKonstantin Ananyev
273e18a033bSKonstantin Ananyev    { ngx_string("request_body"), NULL,
274e18a033bSKonstantin Ananyev      ngx_http_variable_request_body,
275e18a033bSKonstantin Ananyev      0, 0, 0 },
276e18a033bSKonstantin Ananyev
277e18a033bSKonstantin Ananyev    { ngx_string("request_body_file"), NULL,
278e18a033bSKonstantin Ananyev      ngx_http_variable_request_body_file,
279e18a033bSKonstantin Ananyev      0, 0, 0 },
280e18a033bSKonstantin Ananyev
281e18a033bSKonstantin Ananyev    { ngx_string("request_length"), NULL, ngx_http_variable_request_length,
282e18a033bSKonstantin Ananyev      0, NGX_HTTP_VAR_NOCACHEABLE, 0 },
283e18a033bSKonstantin Ananyev
284e18a033bSKonstantin Ananyev    { ngx_string("request_time"), NULL, ngx_http_variable_request_time,
285e18a033bSKonstantin Ananyev      0, NGX_HTTP_VAR_NOCACHEABLE, 0 },
286e18a033bSKonstantin Ananyev
287e18a033bSKonstantin Ananyev    { ngx_string("request_id"), NULL,
288e18a033bSKonstantin Ananyev      ngx_http_variable_request_id,
289e18a033bSKonstantin Ananyev      0, 0, 0 },
290e18a033bSKonstantin Ananyev
291e18a033bSKonstantin Ananyev    { ngx_string("status"), NULL,
292e18a033bSKonstantin Ananyev      ngx_http_variable_status, 0,
293e18a033bSKonstantin Ananyev      NGX_HTTP_VAR_NOCACHEABLE, 0 },
294e18a033bSKonstantin Ananyev
295e18a033bSKonstantin Ananyev    { ngx_string("sent_http_content_type"), NULL,
296e18a033bSKonstantin Ananyev      ngx_http_variable_sent_content_type, 0, 0, 0 },
297e18a033bSKonstantin Ananyev
298e18a033bSKonstantin Ananyev    { ngx_string("sent_http_content_length"), NULL,
299e18a033bSKonstantin Ananyev      ngx_http_variable_sent_content_length, 0, 0, 0 },
300e18a033bSKonstantin Ananyev
301e18a033bSKonstantin Ananyev    { ngx_string("sent_http_location"), NULL,
302e18a033bSKonstantin Ananyev      ngx_http_variable_sent_location, 0, 0, 0 },
303e18a033bSKonstantin Ananyev
304e18a033bSKonstantin Ananyev    { ngx_string("sent_http_last_modified"), NULL,
305e18a033bSKonstantin Ananyev      ngx_http_variable_sent_last_modified, 0, 0, 0 },
306e18a033bSKonstantin Ananyev
307e18a033bSKonstantin Ananyev    { ngx_string("sent_http_connection"), NULL,
308e18a033bSKonstantin Ananyev      ngx_http_variable_sent_connection, 0, 0, 0 },
309e18a033bSKonstantin Ananyev
310e18a033bSKonstantin Ananyev    { ngx_string("sent_http_keep_alive"), NULL,
311e18a033bSKonstantin Ananyev      ngx_http_variable_sent_keep_alive, 0, 0, 0 },
312e18a033bSKonstantin Ananyev
313e18a033bSKonstantin Ananyev    { ngx_string("sent_http_transfer_encoding"), NULL,
314e18a033bSKonstantin Ananyev      ngx_http_variable_sent_transfer_encoding, 0, 0, 0 },
315e18a033bSKonstantin Ananyev
316e18a033bSKonstantin Ananyev    { ngx_string("sent_http_cache_control"), NULL, ngx_http_variable_headers,
317e18a033bSKonstantin Ananyev      offsetof(ngx_http_request_t, headers_out.cache_control), 0, 0 },
318e18a033bSKonstantin Ananyev
319e18a033bSKonstantin Ananyev    { ngx_string("limit_rate"), ngx_http_variable_request_set_size,
320e18a033bSKonstantin Ananyev      ngx_http_variable_request_get_size,
321e18a033bSKonstantin Ananyev      offsetof(ngx_http_request_t, limit_rate),
322e18a033bSKonstantin Ananyev      NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE, 0 },
323e18a033bSKonstantin Ananyev
324e18a033bSKonstantin Ananyev    { ngx_string("connection"), NULL,
325e18a033bSKonstantin Ananyev      ngx_http_variable_connection, 0, 0, 0 },
326e18a033bSKonstantin Ananyev
327e18a033bSKonstantin Ananyev    { ngx_string("connection_requests"), NULL,
328e18a033bSKonstantin Ananyev      ngx_http_variable_connection_requests, 0, 0, 0 },
329e18a033bSKonstantin Ananyev
330e18a033bSKonstantin Ananyev    { ngx_string("nginx_version"), NULL, ngx_http_variable_nginx_version,
331e18a033bSKonstantin Ananyev      0, 0, 0 },
332e18a033bSKonstantin Ananyev
333e18a033bSKonstantin Ananyev    { ngx_string("hostname"), NULL, ngx_http_variable_hostname,
334e18a033bSKonstantin Ananyev      0, 0, 0 },
335e18a033bSKonstantin Ananyev
336e18a033bSKonstantin Ananyev    { ngx_string("pid"), NULL, ngx_http_variable_pid,
337e18a033bSKonstantin Ananyev      0, 0, 0 },
338e18a033bSKonstantin Ananyev
339e18a033bSKonstantin Ananyev    { ngx_string("msec"), NULL, ngx_http_variable_msec,
340e18a033bSKonstantin Ananyev      0, NGX_HTTP_VAR_NOCACHEABLE, 0 },
341e18a033bSKonstantin Ananyev
342e18a033bSKonstantin Ananyev    { ngx_string("time_iso8601"), NULL, ngx_http_variable_time_iso8601,
343e18a033bSKonstantin Ananyev      0, NGX_HTTP_VAR_NOCACHEABLE, 0 },
344e18a033bSKonstantin Ananyev
345e18a033bSKonstantin Ananyev    { ngx_string("time_local"), NULL, ngx_http_variable_time_local,
346e18a033bSKonstantin Ananyev      0, NGX_HTTP_VAR_NOCACHEABLE, 0 },
347e18a033bSKonstantin Ananyev
348e18a033bSKonstantin Ananyev#if (NGX_HAVE_TCP_INFO)
349e18a033bSKonstantin Ananyev    { ngx_string("tcpinfo_rtt"), NULL, ngx_http_variable_tcpinfo,
350e18a033bSKonstantin Ananyev      0, NGX_HTTP_VAR_NOCACHEABLE, 0 },
351e18a033bSKonstantin Ananyev
352e18a033bSKonstantin Ananyev    { ngx_string("tcpinfo_rttvar"), NULL, ngx_http_variable_tcpinfo,
353e18a033bSKonstantin Ananyev      1, NGX_HTTP_VAR_NOCACHEABLE, 0 },
354e18a033bSKonstantin Ananyev
355e18a033bSKonstantin Ananyev    { ngx_string("tcpinfo_snd_cwnd"), NULL, ngx_http_variable_tcpinfo,
356e18a033bSKonstantin Ananyev      2, NGX_HTTP_VAR_NOCACHEABLE, 0 },
357e18a033bSKonstantin Ananyev
358e18a033bSKonstantin Ananyev    { ngx_string("tcpinfo_rcv_space"), NULL, ngx_http_variable_tcpinfo,
359e18a033bSKonstantin Ananyev      3, NGX_HTTP_VAR_NOCACHEABLE, 0 },
360e18a033bSKonstantin Ananyev#endif
361e18a033bSKonstantin Ananyev
362e18a033bSKonstantin Ananyev    { ngx_string("http_"), NULL, ngx_http_variable_unknown_header_in,
363e18a033bSKonstantin Ananyev      0, NGX_HTTP_VAR_PREFIX, 0 },
364e18a033bSKonstantin Ananyev
365e18a033bSKonstantin Ananyev    { ngx_string("sent_http_"), NULL, ngx_http_variable_unknown_header_out,
366e18a033bSKonstantin Ananyev      0, NGX_HTTP_VAR_PREFIX, 0 },
367e18a033bSKonstantin Ananyev
368e18a033bSKonstantin Ananyev    { ngx_string("cookie_"), NULL, ngx_http_variable_cookie,
369e18a033bSKonstantin Ananyev      0, NGX_HTTP_VAR_PREFIX, 0 },
370e18a033bSKonstantin Ananyev
371e18a033bSKonstantin Ananyev    { ngx_string("arg_"), NULL, ngx_http_variable_argument,
372e18a033bSKonstantin Ananyev      0, NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_PREFIX, 0 },
373e18a033bSKonstantin Ananyev
374e18a033bSKonstantin Ananyev    { ngx_null_string, NULL, NULL, 0, 0, 0 }
375e18a033bSKonstantin Ananyev};
376e18a033bSKonstantin Ananyev
377e18a033bSKonstantin Ananyev
378e18a033bSKonstantin Ananyevngx_http_variable_value_t  ngx_http_variable_null_value =
379e18a033bSKonstantin Ananyev    ngx_http_variable("");
380e18a033bSKonstantin Ananyevngx_http_variable_value_t  ngx_http_variable_true_value =
381e18a033bSKonstantin Ananyev    ngx_http_variable("1");
382e18a033bSKonstantin Ananyev
383e18a033bSKonstantin Ananyev
384e18a033bSKonstantin Ananyevstatic ngx_uint_t  ngx_http_variable_depth = 100;
385e18a033bSKonstantin Ananyev
386e18a033bSKonstantin Ananyev
387e18a033bSKonstantin Ananyevngx_http_variable_t *
388e18a033bSKonstantin Ananyevngx_http_add_variable(ngx_conf_t *cf, ngx_str_t *name, ngx_uint_t flags)
389e18a033bSKonstantin Ananyev{
390e18a033bSKonstantin Ananyev    ngx_int_t                   rc;
391e18a033bSKonstantin Ananyev    ngx_uint_t                  i;
392e18a033bSKonstantin Ananyev    ngx_hash_key_t             *key;
393e18a033bSKonstantin Ananyev    ngx_http_variable_t        *v;
394e18a033bSKonstantin Ananyev    ngx_http_core_main_conf_t  *cmcf;
395e18a033bSKonstantin Ananyev
396e18a033bSKonstantin Ananyev    if (name->len == 0) {
397e18a033bSKonstantin Ananyev        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
398e18a033bSKonstantin Ananyev                           "invalid variable name \"$\"");
399e18a033bSKonstantin Ananyev        return NULL;
400e18a033bSKonstantin Ananyev    }
401e18a033bSKonstantin Ananyev
402e18a033bSKonstantin Ananyev    if (flags & NGX_HTTP_VAR_PREFIX) {
403e18a033bSKonstantin Ananyev        return ngx_http_add_prefix_variable(cf, name, flags);
404e18a033bSKonstantin Ananyev    }
405e18a033bSKonstantin Ananyev
406e18a033bSKonstantin Ananyev    cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
407e18a033bSKonstantin Ananyev
408e18a033bSKonstantin Ananyev    key = cmcf->variables_keys->keys.elts;
409e18a033bSKonstantin Ananyev    for (i = 0; i < cmcf->variables_keys->keys.nelts; i++) {
410e18a033bSKonstantin Ananyev        if (name->len != key[i].key.