Mercurial > hg > nginx-vendor-0-7
comparison src/http/ngx_http_variables.c @ 122:d25a1d6034f1 NGINX_0_3_8
nginx 0.3.8
*) Security: nginx now checks URI got from a backend in
"X-Accel-Redirect" header line or in SSI file for the "/../" paths
and zeroes.
*) Change: nginx now does not treat the empty user name in the
"Authorization" header line as valid one.
*) Feature: the "ssl_session_timeout" directives of the
ngx_http_ssl_module and ngx_imap_ssl_module.
*) Feature: the "auth_http_header" directive of the
ngx_imap_auth_http_module.
*) Feature: the "add_header" directive.
*) Feature: the ngx_http_realip_module.
*) Feature: the new variables to use in the "log_format" directive:
$bytes_sent, $apache_bytes_sent, $status, $time_gmt, $uri,
$request_time, $request_length, $upstream_status,
$upstream_response_time, $gzip_ratio, $uid_got, $uid_set,
$connection, $pipe, and $msec. The parameters in the "%name" form
will be canceled soon.
*) Change: now the false variable values in the "if" directive are the
empty string "" and string starting with "0".
*) Bugfix: while using proxied or FastCGI-server nginx may leave
connections and temporary files with client requests in open state.
*) Bugfix: the worker processes did not flush the buffered logs on
graceful exit.
*) Bugfix: if the request URI was changes by the "rewrite" directive
and the request was proxied in location given by regular expression,
then the incorrect request was transferred to backend; bug appeared
in 0.2.6.
*) Bugfix: the "expires" directive did not remove the previous
"Expires" header.
*) Bugfix: nginx may stop to accept requests if the "rtsig" method and
several worker processes were used.
*) Bugfix: the "\"" and "\'" escape symbols were incorrectly handled in
SSI commands.
*) Bugfix: if the response was ended just after the SSI command and
gzipping was used, then the response did not transferred complete or
did not transferred at all.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Wed, 09 Nov 2005 00:00:00 +0300 |
parents | e85dca77c46a |
children | df17fbafec8f |
comparison
equal
deleted
inserted
replaced
121:737953b238a4 | 122:d25a1d6034f1 |
---|---|
8 #include <ngx_core.h> | 8 #include <ngx_core.h> |
9 #include <ngx_event.h> | 9 #include <ngx_event.h> |
10 #include <ngx_http.h> | 10 #include <ngx_http.h> |
11 | 11 |
12 | 12 |
13 static ngx_http_variable_value_t * | 13 static ngx_int_t ngx_http_variable_request(ngx_http_request_t *r, |
14 ngx_http_variable_request(ngx_http_request_t *r, uintptr_t data); | 14 ngx_http_variable_value_t *v, uintptr_t data); |
15 static ngx_http_variable_value_t * | 15 static ngx_int_t ngx_http_variable_header(ngx_http_request_t *r, |
16 ngx_http_variable_header(ngx_http_request_t *r, uintptr_t data); | 16 ngx_http_variable_value_t *v, uintptr_t data); |
17 static ngx_http_variable_value_t * | 17 static ngx_int_t ngx_http_variable_headers(ngx_http_request_t *r, |
18 ngx_http_variable_headers(ngx_http_request_t *r, uintptr_t data); | 18 ngx_http_variable_value_t *v, uintptr_t data); |
19 static ngx_http_variable_value_t * | 19 static ngx_int_t ngx_http_variable_unknown_header(ngx_http_request_t *r, |
20 ngx_http_variable_unknown_header(ngx_http_request_t *r, uintptr_t data); | 20 ngx_http_variable_value_t *v, uintptr_t data); |
21 static ngx_http_variable_value_t * | 21 static ngx_int_t ngx_http_variable_host(ngx_http_request_t *r, |
22 ngx_http_variable_host(ngx_http_request_t *r, uintptr_t data); | 22 ngx_http_variable_value_t *v, uintptr_t data); |
23 static ngx_http_variable_value_t * | 23 static ngx_int_t ngx_http_variable_remote_addr(ngx_http_request_t *r, |
24 ngx_http_variable_remote_addr(ngx_http_request_t *r, uintptr_t data); | 24 ngx_http_variable_value_t *v, uintptr_t data); |
25 static ngx_http_variable_value_t * | 25 static ngx_int_t ngx_http_variable_remote_port(ngx_http_request_t *r, |
26 ngx_http_variable_remote_port(ngx_http_request_t *r, uintptr_t data); | 26 ngx_http_variable_value_t *v, uintptr_t data); |
27 static ngx_http_variable_value_t * | 27 static ngx_int_t ngx_http_variable_server_addr(ngx_http_request_t *r, |
28 ngx_http_variable_server_addr(ngx_http_request_t *r, uintptr_t data); | 28 ngx_http_variable_value_t *v, uintptr_t data); |
29 static ngx_http_variable_value_t * | 29 static ngx_int_t ngx_http_variable_server_port(ngx_http_request_t *r, |
30 ngx_http_variable_server_port(ngx_http_request_t *r, uintptr_t data); | 30 ngx_http_variable_value_t *v, uintptr_t data); |
31 static ngx_http_variable_value_t * | 31 static ngx_int_t ngx_http_variable_document_root(ngx_http_request_t *r, |
32 ngx_http_variable_document_root(ngx_http_request_t *r, uintptr_t data); | 32 ngx_http_variable_value_t *v, uintptr_t data); |
33 static ngx_http_variable_value_t * | 33 static ngx_int_t ngx_http_variable_request_filename(ngx_http_request_t *r, |
34 ngx_http_variable_request_filename(ngx_http_request_t *r, uintptr_t data); | 34 ngx_http_variable_value_t *v, uintptr_t data); |
35 static ngx_http_variable_value_t * | 35 static ngx_int_t ngx_http_variable_request_method(ngx_http_request_t *r, |
36 ngx_http_variable_request_method(ngx_http_request_t *r, uintptr_t data); | 36 ngx_http_variable_value_t *v, uintptr_t data); |
37 static ngx_http_variable_value_t * | 37 static ngx_int_t ngx_http_variable_remote_user(ngx_http_request_t *r, |
38 ngx_http_variable_remote_user(ngx_http_request_t *r, uintptr_t data); | 38 ngx_http_variable_value_t *v, uintptr_t data); |
39 static ngx_http_variable_value_t * | |
40 ngx_http_variable_sent(ngx_http_request_t *r, uintptr_t data); | |
41 | 39 |
42 | 40 |
43 /* | 41 /* |
44 * TODO: | 42 * TODO: |
45 * Apache CGI: AUTH_TYPE, PATH_INFO (null), PATH_TRANSLATED | 43 * Apache CGI: AUTH_TYPE, PATH_INFO (null), PATH_TRANSLATED |
93 offsetof(ngx_http_request_t, http_protocol), 0, 0 }, | 91 offsetof(ngx_http_request_t, http_protocol), 0, 0 }, |
94 | 92 |
95 { ngx_string("request_uri"), ngx_http_variable_request, | 93 { ngx_string("request_uri"), ngx_http_variable_request, |
96 offsetof(ngx_http_request_t, unparsed_uri), 0, 0 }, | 94 offsetof(ngx_http_request_t, unparsed_uri), 0, 0 }, |
97 | 95 |
96 { ngx_string("uri"), ngx_http_variable_request, | |
97 offsetof(ngx_http_request_t, uri), | |
98 NGX_HTTP_VAR_NOCACHABLE, 0 }, | |
99 | |
98 { ngx_string("document_uri"), ngx_http_variable_request, | 100 { ngx_string("document_uri"), ngx_http_variable_request, |
99 offsetof(ngx_http_request_t, uri), 0, 0 }, | 101 offsetof(ngx_http_request_t, uri), |
102 NGX_HTTP_VAR_NOCACHABLE, 0 }, | |
100 | 103 |
101 { ngx_string("request"), ngx_http_variable_request, | 104 { ngx_string("request"), ngx_http_variable_request, |
102 offsetof(ngx_http_request_t, request_line), 0, 0 }, | 105 offsetof(ngx_http_request_t, request_line), 0, 0 }, |
103 | 106 |
104 { ngx_string("document_root"), ngx_http_variable_document_root, 0, 0, 0 }, | 107 { ngx_string("document_root"), ngx_http_variable_document_root, 0, 0, 0 }, |
114 offsetof(ngx_http_request_t, server_name), 0, 0 }, | 117 offsetof(ngx_http_request_t, server_name), 0, 0 }, |
115 | 118 |
116 { ngx_string("request_method"), ngx_http_variable_request_method, 0, 0, 0 }, | 119 { ngx_string("request_method"), ngx_http_variable_request_method, 0, 0, 0 }, |
117 | 120 |
118 { ngx_string("remote_user"), ngx_http_variable_remote_user, 0, 0, 0 }, | 121 { ngx_string("remote_user"), ngx_http_variable_remote_user, 0, 0, 0 }, |
119 | |
120 { ngx_string("sent"), ngx_http_variable_sent, 0, 0, 0 }, | |
121 | |
122 { ngx_string("apache_sent"), ngx_http_variable_sent, 1, 0, 0 }, | |
123 | 122 |
124 { ngx_null_string, NULL, 0, 0, 0 } | 123 { ngx_null_string, NULL, 0, 0, 0 } |
125 }; | 124 }; |
126 | 125 |
127 | 126 |
231 | 230 |
232 ngx_http_variable_value_t * | 231 ngx_http_variable_value_t * |
233 ngx_http_get_indexed_variable(ngx_http_request_t *r, ngx_uint_t index) | 232 ngx_http_get_indexed_variable(ngx_http_request_t *r, ngx_uint_t index) |
234 { | 233 { |
235 ngx_http_variable_t *v; | 234 ngx_http_variable_t *v; |
236 ngx_http_variable_value_t *vv; | |
237 ngx_http_core_main_conf_t *cmcf; | 235 ngx_http_core_main_conf_t *cmcf; |
238 | 236 |
239 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); | 237 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); |
240 | 238 |
241 if (cmcf->variables.nelts <= index) { | 239 if (cmcf->variables.nelts <= index) { |
242 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, | 240 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, |
243 "unknown variable index: %d", index); | 241 "unknown variable index: %d", index); |
244 return NULL; | 242 return NULL; |
245 } | 243 } |
246 | 244 |
247 if (r->variables && r->variables[index]) { | 245 if (r->variables[index].not_found || r->variables[index].valid) { |
248 return r->variables[index]; | 246 return &r->variables[index]; |
249 } | 247 } |
250 | 248 |
251 v = cmcf->variables.elts; | 249 v = cmcf->variables.elts; |
252 | 250 |
253 vv = v[index].handler(r, v[index].data); | 251 if (v[index].handler(r, &r->variables[index], v[index].data) == NGX_OK) { |
254 | 252 |
255 if (r->variables == NULL) { | 253 if (v[index].flags & NGX_HTTP_VAR_NOCACHABLE) { |
256 r->variables = ngx_pcalloc(r->pool, cmcf->variables.nelts | 254 r->variables[index].no_cachable = 1; |
257 * sizeof(ngx_http_variable_value_t *)); | 255 } |
258 if (r->variables == NULL) { | 256 |
259 return NULL; | 257 return &r->variables[index]; |
260 } | 258 } |
261 } | 259 |
262 | 260 return NULL; |
263 if (!(v[index].flags & NGX_HTTP_VAR_NOCACHABLE)) { | 261 } |
264 r->variables[index] = vv; | 262 |
265 } | 263 |
266 | 264 ngx_http_variable_value_t * |
267 return vv; | 265 ngx_http_get_flushed_variable(ngx_http_request_t *r, ngx_uint_t index) |
266 { | |
267 ngx_http_variable_value_t *v; | |
268 | |
269 v = &r->variables[index]; | |
270 | |
271 if (v->valid) { | |
272 if (!v->no_cachable) { | |
273 return v; | |
274 } | |
275 | |
276 v->valid = 0; | |
277 v->not_found = 0; | |
278 } | |
279 | |
280 return ngx_http_get_indexed_variable(r, index); | |
268 } | 281 } |
269 | 282 |
270 | 283 |
271 ngx_http_variable_value_t * | 284 ngx_http_variable_value_t * |
272 ngx_http_get_variable(ngx_http_request_t *r, ngx_str_t *name) | 285 ngx_http_get_variable(ngx_http_request_t *r, ngx_str_t *name) |
273 { | 286 { |
274 ngx_uint_t i, key; | 287 ngx_uint_t i, key; |
275 ngx_http_variable_t *v; | 288 ngx_http_variable_t *v; |
289 ngx_http_variable_value_t *vv; | |
276 ngx_http_core_main_conf_t *cmcf; | 290 ngx_http_core_main_conf_t *cmcf; |
277 | 291 |
278 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); | 292 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); |
279 | 293 |
280 key = 0; | 294 key = 0; |
290 { | 304 { |
291 if (v[key].flags & NGX_HTTP_VAR_INDEXED) { | 305 if (v[key].flags & NGX_HTTP_VAR_INDEXED) { |
292 return ngx_http_get_indexed_variable(r, v[key].index); | 306 return ngx_http_get_indexed_variable(r, v[key].index); |
293 | 307 |
294 } else { | 308 } else { |
295 return v[key].handler(r, v[key].data); | 309 |
296 } | 310 vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)); |
297 } | 311 |
298 | 312 if (vv && v[key].handler(r, vv, v[key].data) == NGX_OK) { |
299 if (ngx_strncmp(name->data, "http_", 5) == 0) { | 313 return vv; |
300 return ngx_http_variable_unknown_header(r, (uintptr_t) name); | 314 } |
301 } | 315 |
302 | 316 return NULL; |
303 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | 317 } |
304 "unknown \"%V\" variable", name); | |
305 | |
306 return NGX_HTTP_VAR_NOT_FOUND; | |
307 } | |
308 | |
309 | |
310 static ngx_http_variable_value_t * | |
311 ngx_http_variable_request(ngx_http_request_t *r, uintptr_t data) | |
312 { | |
313 ngx_str_t *s; | |
314 ngx_http_variable_value_t *vv; | |
315 | |
316 s = (ngx_str_t *) ((char *) r + data); | |
317 | |
318 if (s->data == NULL) { | |
319 return NGX_HTTP_VAR_NOT_FOUND; | |
320 } | 318 } |
321 | 319 |
322 vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)); | 320 vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)); |
323 if (vv == NULL) { | 321 if (vv == NULL) { |
324 return NULL; | 322 return NULL; |
325 } | 323 } |
326 | 324 |
327 vv->value = 0; | 325 if (ngx_strncmp(name->data, "http_", 5) == 0) { |
328 vv->text = *s; | 326 |
327 if (ngx_http_variable_unknown_header(r, vv, (uintptr_t) name) == NGX_OK) | |
328 { | |
329 return vv; | |
330 } | |
331 | |
332 return NULL; | |
333 } | |
334 | |
335 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
336 "unknown \"%V\" variable", name); | |
337 | |
338 vv->not_found = 1; | |
329 | 339 |
330 return vv; | 340 return vv; |
331 } | 341 } |
332 | 342 |
333 | 343 |
334 static ngx_http_variable_value_t * | 344 static ngx_int_t |
335 ngx_http_variable_header(ngx_http_request_t *r, uintptr_t data) | 345 ngx_http_variable_request(ngx_http_request_t *r, ngx_http_variable_value_t *v, |
336 { | 346 uintptr_t data) |
337 ngx_table_elt_t *h; | 347 { |
338 ngx_http_variable_value_t *vv; | 348 ngx_str_t *s; |
349 | |
350 s = (ngx_str_t *) ((char *) r + data); | |
351 | |
352 if (s->data) { | |
353 v->len = s->len; | |
354 v->valid = 1; | |
355 v->no_cachable = 0; | |
356 v->not_found = 0; | |
357 v->data = s->data; | |
358 | |
359 } else { | |
360 v->not_found = 1; | |
361 } | |
362 | |
363 return NGX_OK; | |
364 } | |
365 | |
366 | |
367 static ngx_int_t | |
368 ngx_http_variable_header(ngx_http_request_t *r, ngx_http_variable_value_t *v, | |
369 uintptr_t data) | |
370 { | |
371 ngx_table_elt_t *h; | |
339 | 372 |
340 h = *(ngx_table_elt_t **) ((char *) r + data); | 373 h = *(ngx_table_elt_t **) ((char *) r + data); |
341 | 374 |
342 if (h == NULL) { | 375 if (h) { |
343 return NGX_HTTP_VAR_NOT_FOUND; | 376 v->len = h->value.len; |
344 } | 377 v->valid = 1; |
345 | 378 v->no_cachable = 0; |
346 vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)); | 379 v->not_found = 0; |
347 if (vv == NULL) { | 380 v->data = h->value.data; |
348 return NULL; | 381 |
349 } | 382 } else { |
350 | 383 v->not_found = 1; |
351 vv->value = 0; | 384 } |
352 vv->text = h->value; | 385 |
353 | 386 return NGX_OK; |
354 return vv; | 387 } |
355 } | 388 |
356 | 389 |
357 | 390 static ngx_int_t |
358 static ngx_http_variable_value_t * | 391 ngx_http_variable_headers(ngx_http_request_t *r, ngx_http_variable_value_t *v, |
359 ngx_http_variable_headers(ngx_http_request_t *r, uintptr_t data) | 392 uintptr_t data) |
360 { | 393 { |
361 u_char *p; | 394 size_t len; |
362 ngx_uint_t i; | 395 u_char *p; |
363 ngx_array_t *a; | 396 ngx_uint_t i; |
364 ngx_table_elt_t **h; | 397 ngx_array_t *a; |
365 ngx_http_variable_value_t *vv; | 398 ngx_table_elt_t **h; |
366 | 399 |
367 a = (ngx_array_t *) ((char *) r + data); | 400 a = (ngx_array_t *) ((char *) r + data); |
368 | 401 |
369 if (a->nelts == 0) { | 402 if (a->nelts == 0) { |
370 return NGX_HTTP_VAR_NOT_FOUND; | 403 v->not_found = 1; |
371 } | 404 return NGX_OK; |
372 | 405 } |
373 vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)); | 406 |
374 if (vv == NULL) { | 407 v->valid = 1; |
375 return NULL; | 408 v->no_cachable = 0; |
376 } | 409 v->not_found = 0; |
377 | |
378 vv->value = 0; | |
379 | 410 |
380 h = a->elts; | 411 h = a->elts; |
381 | 412 |
382 if (a->nelts == 1) { | 413 if (a->nelts == 1) { |
383 vv->text = (*h)->value; | 414 v->len = (*h)->value.len; |
384 return vv; | 415 v->data = (*h)->value.data; |
385 } | 416 |
386 | 417 return NGX_OK; |
387 vv->text.len = (size_t) - (ssize_t) (sizeof("; ") - 1); | 418 } |
419 | |
420 len = (size_t) - (ssize_t) (sizeof("; ") - 1); | |
388 | 421 |
389 for (i = 0; i < a->nelts; i++) { | 422 for (i = 0; i < a->nelts; i++) { |
390 vv->text.len += h[i]->value.len + sizeof("; ") - 1; | 423 len += h[i]->value.len + sizeof("; ") - 1; |
391 } | 424 } |
392 | 425 |
393 vv->text.data = ngx_palloc(r->pool, vv->text.len); | 426 p = ngx_palloc(r->pool, len); |
394 if (vv->text.data == NULL) { | 427 if (p == NULL) { |
395 return NULL; | 428 return NGX_ERROR; |
396 } | 429 } |
397 | 430 |
398 p = vv->text.data; | 431 v->len = len; |
432 v->data = p; | |
399 | 433 |
400 for (i = 0; /* void */ ; i++) { | 434 for (i = 0; /* void */ ; i++) { |
401 p = ngx_cpymem(p, h[i]->value.data, h[i]->value.len); | 435 p = ngx_copy(p, h[i]->value.data, h[i]->value.len); |
402 | 436 |
403 if (i == a->nelts - 1) { | 437 if (i == a->nelts - 1) { |
404 break; | 438 break; |
405 } | 439 } |
406 | 440 |
407 *p++ = ';'; *p++ = ' '; | 441 *p++ = ';'; *p++ = ' '; |
408 } | 442 } |
409 | 443 |
410 return vv; | 444 return NGX_OK; |
411 } | 445 } |
412 | 446 |
413 | 447 |
414 static ngx_http_variable_value_t * | 448 static ngx_int_t |
415 ngx_http_variable_unknown_header(ngx_http_request_t *r, uintptr_t data) | 449 ngx_http_variable_unknown_header(ngx_http_request_t *r, |
450 ngx_http_variable_value_t *v, uintptr_t data) | |
416 { | 451 { |
417 ngx_str_t *var = (ngx_str_t *) data; | 452 ngx_str_t *var = (ngx_str_t *) data; |
418 | 453 |
419 u_char ch; | 454 u_char ch; |
420 ngx_uint_t i, n; | 455 ngx_uint_t i, n; |
421 ngx_list_part_t *part; | 456 ngx_list_part_t *part; |
422 ngx_table_elt_t *header; | 457 ngx_table_elt_t *header; |
423 ngx_http_variable_value_t *vv; | |
424 | 458 |
425 part = &r->headers_in.headers.part; | 459 part = &r->headers_in.headers.part; |
426 header = part->elts; | 460 header = part->elts; |
427 | 461 |
428 for (i = 0; /* void */ ; i++) { | 462 for (i = 0; /* void */ ; i++) { |
451 break; | 485 break; |
452 } | 486 } |
453 } | 487 } |
454 | 488 |
455 if (n + 5 == var->len) { | 489 if (n + 5 == var->len) { |
456 vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)); | 490 v->len = header[i].value.len; |
457 if (vv == NULL) { | 491 v->valid = 1; |
458 return NULL; | 492 v->no_cachable = 0; |
459 } | 493 v->not_found = 0; |
460 | 494 v->data = header[i].value.data; |
461 vv->value = 0; | 495 |
462 vv->text = header[i].value; | 496 return NGX_OK; |
463 return vv; | 497 } |
464 } | 498 } |
465 } | 499 |
466 | 500 v->not_found = 1; |
467 return NGX_HTTP_VAR_NOT_FOUND; | 501 |
468 } | 502 return NGX_OK; |
469 | 503 } |
470 | 504 |
471 static ngx_http_variable_value_t * | 505 |
472 ngx_http_variable_host(ngx_http_request_t *r, uintptr_t data) | 506 static ngx_int_t |
473 { | 507 ngx_http_variable_host(ngx_http_request_t *r, ngx_http_variable_value_t *v, |
474 ngx_http_variable_value_t *vv; | 508 uintptr_t data) |
475 | 509 { |
476 vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)); | |
477 if (vv == NULL) { | |
478 return NULL; | |
479 } | |
480 | |
481 vv->value = 0; | |
482 | |
483 if (r->headers_in.host) { | 510 if (r->headers_in.host) { |
484 vv->text.len = r->headers_in.host_name_len; | 511 v->len = r->headers_in.host_name_len; |
485 vv->text.data = r->headers_in.host->value.data; | 512 v->data = r->headers_in.host->value.data; |
486 | 513 |
487 } else { | 514 } else { |
488 vv->text = r->server_name; | 515 v->len = r->server_name.len; |
489 } | 516 v->data = r->server_name.data; |
490 | 517 } |
491 return vv; | 518 |
492 } | 519 v->valid = 1; |
493 | 520 v->no_cachable = 0; |
494 | 521 v->not_found = 0; |
495 static ngx_http_variable_value_t * | 522 |
496 ngx_http_variable_remote_addr(ngx_http_request_t *r, uintptr_t data) | 523 return NGX_OK; |
497 { | 524 } |
498 ngx_http_variable_value_t *vv; | 525 |
499 | 526 |
500 vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)); | 527 static ngx_int_t |
501 if (vv == NULL) { | 528 ngx_http_variable_remote_addr(ngx_http_request_t *r, |
502 return NULL; | 529 ngx_http_variable_value_t *v, uintptr_t data) |
503 } | 530 { |
504 | 531 v->len = r->connection->addr_text.len; |
505 vv->value = 0; | 532 v->valid = 1; |
506 vv->text = r->connection->addr_text; | 533 v->no_cachable = 0; |
507 | 534 v->not_found = 0; |
508 return vv; | 535 v->data = r->connection->addr_text.data; |
509 } | 536 |
510 | 537 return NGX_OK; |
511 | 538 } |
512 static ngx_http_variable_value_t * | 539 |
513 ngx_http_variable_remote_port(ngx_http_request_t *r, uintptr_t data) | 540 |
514 { | 541 static ngx_int_t |
515 ngx_uint_t port; | 542 ngx_http_variable_remote_port(ngx_http_request_t *r, |
516 struct sockaddr_in *sin; | 543 ngx_http_variable_value_t *v, uintptr_t data) |
517 ngx_http_variable_value_t *vv; | 544 { |
518 | 545 ngx_uint_t port; |
519 vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)); | 546 struct sockaddr_in *sin; |
520 if (vv == NULL) { | 547 |
521 return NULL; | 548 v->len = 0; |
522 } | 549 v->valid = 1; |
523 | 550 v->no_cachable = 0; |
524 vv->value = 0; | 551 v->not_found = 0; |
525 vv->text.len = 0; | 552 |
526 | 553 v->data = ngx_palloc(r->pool, sizeof("65535") - 1); |
527 vv->text.data = ngx_palloc(r->pool, sizeof("65535") - 1); | 554 if (v->data == NULL) { |
528 if (vv->text.data == NULL) { | 555 return NGX_ERROR; |
529 return NULL; | |
530 } | 556 } |
531 | 557 |
532 /* AF_INET only */ | 558 /* AF_INET only */ |
533 | 559 |
534 if (r->connection->sockaddr->sa_family == AF_INET) { | 560 if (r->connection->sockaddr->sa_family == AF_INET) { |
535 sin = (struct sockaddr_in *) r->connection->sockaddr; | 561 sin = (struct sockaddr_in *) r->connection->sockaddr; |
536 | 562 |
537 port = ntohs(sin->sin_port); | 563 port = ntohs(sin->sin_port); |
538 | 564 |
539 if (port > 0 && port < 65536) { | 565 if (port > 0 && port < 65536) { |
540 vv->value = port; | 566 v->len = ngx_sprintf(v->data, "%ui", port) - v->data; |
541 vv->text.len = ngx_sprintf(vv->text.data, "%ui", port) | 567 } |
542 - vv->text.data; | 568 } |
543 } | 569 |
544 } | 570 return NGX_OK; |
545 | 571 } |
546 return vv; | 572 |
547 } | 573 |
548 | 574 static ngx_int_t |
549 | 575 ngx_http_variable_server_addr(ngx_http_request_t *r, |
550 static ngx_http_variable_value_t * | 576 ngx_http_variable_value_t *v, uintptr_t data) |
551 ngx_http_variable_server_addr(ngx_http_request_t *r, uintptr_t data) | 577 { |
552 { | 578 socklen_t len; |
553 socklen_t len; | 579 ngx_connection_t *c; |
554 ngx_connection_t *c; | 580 struct sockaddr_in sin; |
555 struct sockaddr_in sin; | 581 |
556 ngx_http_variable_value_t *vv; | 582 v->data = ngx_palloc(r->pool, INET_ADDRSTRLEN); |
557 | 583 if (v->data == NULL) { |
558 vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)); | 584 return NGX_ERROR; |
559 if (vv == NULL) { | |
560 return NULL; | |
561 } | |
562 | |
563 vv->value = 0; | |
564 | |
565 vv->text.data = ngx_palloc(r->pool, INET_ADDRSTRLEN); | |
566 if (vv->text.data == NULL) { | |
567 return NULL; | |
568 } | 585 } |
569 | 586 |
570 c = r->connection; | 587 c = r->connection; |
571 | 588 |
572 if (r->in_addr == 0) { | 589 if (r->in_addr == 0) { |
573 len = sizeof(struct sockaddr_in); | 590 len = sizeof(struct sockaddr_in); |
574 if (getsockname(c->fd, (struct sockaddr *) &sin, &len) == -1) { | 591 if (getsockname(c->fd, (struct sockaddr *) &sin, &len) == -1) { |
575 ngx_log_error(NGX_LOG_CRIT, c->log, | 592 ngx_log_error(NGX_LOG_CRIT, c->log, |
576 ngx_socket_errno, "getsockname() failed"); | 593 ngx_socket_errno, "getsockname() failed"); |
577 return NULL; | 594 return NGX_ERROR; |
578 } | 595 } |
579 | 596 |
580 r->in_addr = sin.sin_addr.s_addr; | 597 r->in_addr = sin.sin_addr.s_addr; |
581 } | 598 } |
582 | 599 |
583 vv->text.len = ngx_inet_ntop(c->listening->family, &r->in_addr, | 600 v->len = ngx_inet_ntop(c->listening->family, &r->in_addr, |
584 vv->text.data, INET_ADDRSTRLEN); | 601 v->data, INET_ADDRSTRLEN); |
585 | 602 v->valid = 1; |
586 return vv; | 603 v->no_cachable = 0; |
587 } | 604 v->not_found = 0; |
588 | 605 |
589 | 606 return NGX_OK; |
590 static ngx_http_variable_value_t * | 607 } |
591 ngx_http_variable_server_port(ngx_http_request_t *r, uintptr_t data) | 608 |
592 { | 609 |
593 ngx_http_variable_value_t *vv; | 610 static ngx_int_t |
594 | 611 ngx_http_variable_server_port(ngx_http_request_t *r, |
595 vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)); | 612 ngx_http_variable_value_t *v, uintptr_t data) |
596 if (vv == NULL) { | 613 { |
597 return NULL; | 614 v->len = r->port_text->len - 1; |
598 } | 615 v->valid = 1; |
599 | 616 v->no_cachable = 0; |
600 vv->value = r->port; | 617 v->not_found = 0; |
601 vv->text.len = r->port_text->len - 1; | 618 v->data = r->port_text->data + 1; |
602 vv->text.data = r->port_text->data + 1; | 619 |
603 | 620 return NGX_OK; |
604 return vv; | 621 } |
605 } | 622 |
606 | 623 |
607 | 624 static ngx_int_t |
608 static ngx_http_variable_value_t * | 625 ngx_http_variable_document_root(ngx_http_request_t *r, |
609 ngx_http_variable_document_root(ngx_http_request_t *r, uintptr_t data) | 626 ngx_http_variable_value_t *v, uintptr_t data) |
610 { | 627 { |
611 ngx_http_core_loc_conf_t *clcf; | 628 ngx_http_core_loc_conf_t *clcf; |
612 ngx_http_variable_value_t *vv; | |
613 | |
614 vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)); | |
615 if (vv == NULL) { | |
616 return NULL; | |
617 } | |
618 | 629 |
619 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | 630 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
620 | 631 |
621 vv->value = 0; | 632 v->len = clcf->root.len; |
622 vv->text = clcf->root; | 633 v->valid = 1; |
623 | 634 v->no_cachable = 0; |
624 return vv; | 635 v->not_found = 0; |
625 } | 636 v->data = clcf->root.data; |
626 | 637 |
627 | 638 return NGX_OK; |
628 static ngx_http_variable_value_t * | 639 } |
629 ngx_http_variable_request_filename(ngx_http_request_t *r, uintptr_t data) | 640 |
630 { | 641 |
631 ngx_http_variable_value_t *vv; | 642 static ngx_int_t |
632 | 643 ngx_http_variable_request_filename(ngx_http_request_t *r, |
633 vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)); | 644 ngx_http_variable_value_t *v, uintptr_t data) |
634 if (vv == NULL) { | 645 { |
635 return NULL; | 646 ngx_str_t path; |
636 } | 647 |
637 | 648 if (ngx_http_map_uri_to_path(r, &path, 0) == NULL) { |
638 vv->value = 0; | 649 return NGX_ERROR; |
639 | |
640 if (ngx_http_map_uri_to_path(r, &vv->text, 0) == NULL) { | |
641 return NULL; | |
642 } | 650 } |
643 | 651 |
644 /* ngx_http_map_uri_to_path() allocates memory for terminating '\0' */ | 652 /* ngx_http_map_uri_to_path() allocates memory for terminating '\0' */ |
645 | 653 |
646 vv->text.len--; | 654 v->len = path.len - 1; |
647 | 655 v->valid = 1; |
648 return vv; | 656 v->no_cachable = 0; |
649 } | 657 v->not_found = 0; |
650 | 658 v->data = path.data; |
651 | 659 |
652 static ngx_http_variable_value_t * | 660 return NGX_OK; |
653 ngx_http_variable_request_method(ngx_http_request_t *r, uintptr_t data) | 661 } |
654 { | 662 |
655 ngx_http_variable_value_t *vv; | 663 |
656 | 664 static ngx_int_t |
657 if (r->method_name.data == NULL) { | 665 ngx_http_variable_request_method(ngx_http_request_t *r, |
658 return NGX_HTTP_VAR_NOT_FOUND; | 666 ngx_http_variable_value_t *v, uintptr_t data) |
659 } | 667 { |
660 | 668 if (r->method_name.data) { |
661 vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)); | 669 if (r->upstream && r->upstream->method.len) { |
662 if (vv == NULL) { | 670 v->len = r->upstream->method.len; |
663 return NULL; | 671 v->data = r->upstream->method.data; |
664 } | 672 |
665 | 673 } else { |
666 vv->value = 0; | 674 v->len = r->method_name.len; |
667 | 675 v->data = r->method_name.data; |
668 if (r->upstream && r->upstream->method.len) { | 676 } |
669 vv->text = r->upstream->method; | 677 |
678 v->valid = 1; | |
679 v->no_cachable = 0; | |
680 v->not_found = 0; | |
670 | 681 |
671 } else { | 682 } else { |
672 vv->text = r->method_name; | 683 v->not_found = 1; |
673 } | 684 } |
674 | 685 |
675 return vv; | 686 return NGX_OK; |
676 } | 687 } |
677 | 688 |
678 | 689 |
679 static ngx_http_variable_value_t * | 690 static ngx_int_t |
680 ngx_http_variable_remote_user(ngx_http_request_t *r, uintptr_t data) | 691 ngx_http_variable_remote_user(ngx_http_request_t *r, |
681 { | 692 ngx_http_variable_value_t *v, uintptr_t data) |
682 ngx_int_t rc; | 693 { |
683 ngx_http_variable_value_t *vv; | 694 ngx_int_t rc; |
684 | 695 |
685 rc = ngx_http_auth_basic_user(r); | 696 rc = ngx_http_auth_basic_user(r); |
686 | 697 |
687 if (rc == NGX_DECLINED) { | 698 if (rc == NGX_DECLINED) { |
688 return NGX_HTTP_VAR_NOT_FOUND; | 699 v->not_found = 1; |
700 return NGX_OK; | |
689 } | 701 } |
690 | 702 |
691 if (rc == NGX_ERROR) { | 703 if (rc == NGX_ERROR) { |
692 return NULL; | 704 return NGX_ERROR; |
693 } | 705 } |
694 | 706 |
695 vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)); | 707 v->len = r->headers_in.user.len; |
696 if (vv == NULL) { | 708 v->valid = 1; |
697 return NULL; | 709 v->no_cachable = 0; |
698 } | 710 v->not_found = 0; |
699 | 711 v->data = r->headers_in.user.data; |
700 vv->value = 0; | 712 |
701 vv->text = r->headers_in.user; | 713 return NGX_OK; |
702 | |
703 return vv; | |
704 } | |
705 | |
706 | |
707 static ngx_http_variable_value_t * | |
708 ngx_http_variable_sent(ngx_http_request_t *r, uintptr_t data) | |
709 { | |
710 off_t sent; | |
711 u_char *p; | |
712 ngx_http_variable_value_t *vv; | |
713 | |
714 vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)); | |
715 if (vv == NULL) { | |
716 return NULL; | |
717 } | |
718 | |
719 sent = r->connection->sent; | |
720 | |
721 if (data) { | |
722 sent -= r->header_size; | |
723 | |
724 if (sent < 0) { | |
725 sent = 0; | |
726 } | |
727 } | |
728 | |
729 p = ngx_palloc(r->pool, NGX_OFF_T_LEN); | |
730 if (p == NULL) { | |
731 return NULL; | |
732 } | |
733 | |
734 vv->value = 0; | |
735 vv->text.len = ngx_sprintf(p, "%O", sent) - p; | |
736 vv->text.data = p; | |
737 | |
738 return vv; | |
739 } | 714 } |
740 | 715 |
741 | 716 |
742 ngx_int_t | 717 ngx_int_t |
743 ngx_http_variables_add_core_vars(ngx_conf_t *cf) | 718 ngx_http_variables_add_core_vars(ngx_conf_t *cf) |