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