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