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