Mercurial > hg > nginx-ranges
comparison src/http/ngx_http_script.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 | f63280c59dd5 |
children | df17fbafec8f |
comparison
equal
deleted
inserted
replaced
121:737953b238a4 | 122:d25a1d6034f1 |
---|---|
32 ngx_int_t | 32 ngx_int_t |
33 ngx_http_script_compile(ngx_http_script_compile_t *sc) | 33 ngx_http_script_compile(ngx_http_script_compile_t *sc) |
34 { | 34 { |
35 u_char ch; | 35 u_char ch; |
36 size_t size; | 36 size_t size; |
37 ngx_int_t index; | 37 ngx_int_t index, *p; |
38 ngx_str_t name; | 38 ngx_str_t name; |
39 uintptr_t *code; | 39 uintptr_t *code; |
40 ngx_uint_t i, n, bracket; | 40 ngx_uint_t i, n, bracket; |
41 ngx_http_script_var_code_t *var_code; | 41 ngx_http_script_var_code_t *var_code; |
42 ngx_http_script_copy_code_t *copy; | 42 ngx_http_script_copy_code_t *copy; |
43 ngx_http_script_copy_capture_code_t *copy_capture; | 43 ngx_http_script_copy_capture_code_t *copy_capture; |
44 | |
45 if (sc->flushes && *sc->flushes == NULL) { | |
46 n = sc->variables ? sc->variables : 1; | |
47 *sc->flushes = ngx_array_create(sc->cf->pool, n, sizeof(ngx_uint_t)); | |
48 if (*sc->flushes == NULL) { | |
49 return NGX_ERROR; | |
50 } | |
51 } | |
52 | |
44 | 53 |
45 if (*sc->lengths == NULL) { | 54 if (*sc->lengths == NULL) { |
46 n = sc->variables * (2 * sizeof(ngx_http_script_copy_code_t) | 55 n = sc->variables * (2 * sizeof(ngx_http_script_copy_code_t) |
47 + sizeof(ngx_http_script_var_code_t)) | 56 + sizeof(ngx_http_script_var_code_t)) |
48 + sizeof(uintptr_t); | 57 + sizeof(uintptr_t); |
165 | 174 |
166 if (index == NGX_ERROR) { | 175 if (index == NGX_ERROR) { |
167 return NGX_ERROR; | 176 return NGX_ERROR; |
168 } | 177 } |
169 | 178 |
179 if (sc->flushes) { | |
180 p = ngx_array_push(*sc->flushes); | |
181 if (p == NULL) { | |
182 return NGX_ERROR; | |
183 } | |
184 | |
185 *p = index; | |
186 } | |
187 | |
170 var_code = ngx_http_script_add_code(*sc->lengths, | 188 var_code = ngx_http_script_add_code(*sc->lengths, |
171 sizeof(ngx_http_script_var_code_t), | 189 sizeof(ngx_http_script_var_code_t), |
172 NULL); | 190 NULL); |
173 if (var_code == NULL) { | 191 if (var_code == NULL) { |
174 return NGX_ERROR; | 192 return NGX_ERROR; |
274 | 292 |
275 return NGX_ERROR; | 293 return NGX_ERROR; |
276 } | 294 } |
277 | 295 |
278 | 296 |
297 void | |
298 ngx_http_script_flush_no_cachable_variables(ngx_http_request_t *r, | |
299 ngx_array_t *indices) | |
300 { | |
301 ngx_uint_t n, *index; | |
302 | |
303 if (indices) { | |
304 index = indices->elts; | |
305 for (n = 0; n < indices->nelts; n++) { | |
306 if (r->variables[index[n]].no_cachable) { | |
307 r->variables[index[n]].valid = 0; | |
308 r->variables[index[n]].not_found = 0; | |
309 } | |
310 } | |
311 } | |
312 } | |
313 | |
314 | |
279 void * | 315 void * |
280 ngx_http_script_start_code(ngx_pool_t *pool, ngx_array_t **codes, size_t size) | 316 ngx_http_script_start_code(ngx_pool_t *pool, ngx_array_t **codes, size_t size) |
281 { | 317 { |
282 if (*codes == NULL) { | 318 if (*codes == NULL) { |
283 *codes = ngx_array_create(pool, 256, 1); | 319 *codes = ngx_array_create(pool, 256, 1); |
333 ngx_http_script_copy_code_t *code; | 369 ngx_http_script_copy_code_t *code; |
334 | 370 |
335 code = (ngx_http_script_copy_code_t *) e->ip; | 371 code = (ngx_http_script_copy_code_t *) e->ip; |
336 | 372 |
337 if (!e->skip) { | 373 if (!e->skip) { |
338 e->pos = ngx_cpymem(e->pos, e->ip + sizeof(ngx_http_script_copy_code_t), | 374 e->pos = ngx_copy(e->pos, e->ip + sizeof(ngx_http_script_copy_code_t), |
339 code->len); | 375 code->len); |
340 } | 376 } |
341 | 377 |
342 e->ip += sizeof(ngx_http_script_copy_code_t) | 378 e->ip += sizeof(ngx_http_script_copy_code_t) |
343 + ((code->len + sizeof(uintptr_t) - 1) & ~(sizeof(uintptr_t) - 1)); | 379 + ((code->len + sizeof(uintptr_t) - 1) & ~(sizeof(uintptr_t) - 1)); |
344 | 380 |
357 | 393 |
358 code = (ngx_http_script_var_code_t *) e->ip; | 394 code = (ngx_http_script_var_code_t *) e->ip; |
359 | 395 |
360 e->ip += sizeof(ngx_http_script_var_code_t); | 396 e->ip += sizeof(ngx_http_script_var_code_t); |
361 | 397 |
362 value = ngx_http_get_indexed_variable(e->request, code->index); | 398 if (e->flushed) { |
363 | 399 value = ngx_http_get_indexed_variable(e->request, code->index); |
364 if (value && value != NGX_HTTP_VAR_NOT_FOUND) { | 400 |
365 return value->text.len; | 401 } else { |
402 value = ngx_http_get_flushed_variable(e->request, code->index); | |
403 } | |
404 | |
405 if (value && !value->not_found) { | |
406 return value->len; | |
366 } | 407 } |
367 | 408 |
368 return 0; | 409 return 0; |
369 } | 410 } |
370 | 411 |
378 code = (ngx_http_script_var_code_t *) e->ip; | 419 code = (ngx_http_script_var_code_t *) e->ip; |
379 | 420 |
380 e->ip += sizeof(ngx_http_script_var_code_t); | 421 e->ip += sizeof(ngx_http_script_var_code_t); |
381 | 422 |
382 if (!e->skip) { | 423 if (!e->skip) { |
383 value = ngx_http_get_indexed_variable(e->request, code->index); | 424 |
384 | 425 if (e->flushed) { |
385 if (value && value != NGX_HTTP_VAR_NOT_FOUND) { | 426 value = ngx_http_get_indexed_variable(e->request, code->index); |
386 e->pos = ngx_cpymem(e->pos, value->text.data, value->text.len); | 427 |
428 } else { | |
429 value = ngx_http_get_flushed_variable(e->request, code->index); | |
430 } | |
431 | |
432 if (value && !value->not_found) { | |
433 e->pos = ngx_copy(e->pos, value->data, value->len); | |
387 | 434 |
388 if (e->log) { | 435 if (e->log) { |
389 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, | 436 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, |
390 e->request->connection->log, 0, | 437 e->request->connection->log, 0, |
391 "http script var: \"%V\"", &e->buf); | 438 "http script var: \"%V\"", &e->buf); |
438 e->pos = (u_char *) ngx_escape_uri(e->pos, | 485 e->pos = (u_char *) ngx_escape_uri(e->pos, |
439 &e->line.data[e->captures[code->n]], | 486 &e->line.data[e->captures[code->n]], |
440 e->captures[code->n + 1] - e->captures[code->n], | 487 e->captures[code->n + 1] - e->captures[code->n], |
441 NGX_ESCAPE_ARGS); | 488 NGX_ESCAPE_ARGS); |
442 } else { | 489 } else { |
443 e->pos = ngx_cpymem(e->pos, | 490 e->pos = ngx_copy(e->pos, |
444 &e->line.data[e->captures[code->n]], | 491 &e->line.data[e->captures[code->n]], |
445 e->captures[code->n + 1] - e->captures[code->n]); | 492 e->captures[code->n + 1] - e->captures[code->n]); |
446 } | 493 } |
447 } | 494 } |
448 | 495 |
449 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, | 496 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, |
450 "http script capture: \"%V\"", &e->buf); | 497 "http script capture: \"%V\"", &e->buf); |
485 | 532 |
486 if (code->uri) { | 533 if (code->uri) { |
487 e->line = r->uri; | 534 e->line = r->uri; |
488 } else { | 535 } else { |
489 e->sp--; | 536 e->sp--; |
490 e->line = e->sp->text; | 537 e->line.len = e->sp->len; |
538 e->line.data = e->sp->data; | |
491 } | 539 } |
492 | 540 |
493 rc = ngx_regex_exec(code->regex, &e->line, e->captures, code->ncaptures); | 541 rc = ngx_regex_exec(code->regex, &e->line, e->captures, code->ncaptures); |
494 | 542 |
495 if (rc == NGX_REGEX_NO_MATCHED) { | 543 if (rc == NGX_REGEX_NO_MATCHED) { |
500 } | 548 } |
501 | 549 |
502 e->ncaptures = 0; | 550 e->ncaptures = 0; |
503 | 551 |
504 if (code->test) { | 552 if (code->test) { |
505 e->sp->value = 0; | 553 e->sp->len = 0; |
506 e->sp->text.len = 0; | 554 e->sp->data = (u_char *) ""; |
507 e->sp->text.data = (u_char *) ""; | |
508 e->sp++; | 555 e->sp++; |
509 | 556 |
510 e->ip += sizeof(ngx_http_script_regex_code_t); | 557 e->ip += sizeof(ngx_http_script_regex_code_t); |
511 return; | 558 return; |
512 } | 559 } |
531 } | 578 } |
532 | 579 |
533 e->ncaptures = code->ncaptures; | 580 e->ncaptures = code->ncaptures; |
534 | 581 |
535 if (code->test) { | 582 if (code->test) { |
536 e->sp->value = 1; | 583 e->sp->len = 1; |
537 e->sp->text.len = 1; | 584 e->sp->data = (u_char *) "1"; |
538 e->sp->text.data = (u_char *) "1"; | |
539 e->sp++; | 585 e->sp++; |
540 | 586 |
541 e->ip += sizeof(ngx_http_script_regex_code_t); | 587 e->ip += sizeof(ngx_http_script_regex_code_t); |
542 return; | 588 return; |
543 } | 589 } |
632 | 678 |
633 if (code->redirect) { | 679 if (code->redirect) { |
634 | 680 |
635 if (code->add_args && r->args.len) { | 681 if (code->add_args && r->args.len) { |
636 *e->pos++ = (u_char) (code->args ? '&' : '?'); | 682 *e->pos++ = (u_char) (code->args ? '&' : '?'); |
637 e->pos = ngx_cpymem(e->pos, r->args.data, r->args.len); | 683 e->pos = ngx_copy(e->pos, r->args.data, r->args.len); |
638 } | 684 } |
639 | 685 |
640 e->buf.len = e->pos - e->buf.data; | 686 e->buf.len = e->pos - e->buf.data; |
641 | 687 |
642 if (e->log) { | 688 if (e->log) { |
663 if (e->args) { | 709 if (e->args) { |
664 e->buf.len = e->args - e->buf.data; | 710 e->buf.len = e->args - e->buf.data; |
665 | 711 |
666 if (code->add_args && r->args.len) { | 712 if (code->add_args && r->args.len) { |
667 *e->pos++ = '&'; | 713 *e->pos++ = '&'; |
668 e->pos = ngx_cpymem(e->pos, r->args.data, r->args.len); | 714 e->pos = ngx_copy(e->pos, r->args.data, r->args.len); |
669 } | 715 } |
670 | 716 |
671 r->args.len = e->pos - e->args; | 717 r->args.len = e->pos - e->args; |
672 r->args.data = e->args; | 718 r->args.data = e->args; |
673 | 719 |
739 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, | 785 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, |
740 "http script if"); | 786 "http script if"); |
741 | 787 |
742 e->sp--; | 788 e->sp--; |
743 | 789 |
744 if (e->sp->value) { | 790 if (e->sp->len && e->sp->data[0] != '0') { |
745 if (code->loc_conf) { | 791 if (code->loc_conf) { |
746 e->request->loc_conf = code->loc_conf; | 792 e->request->loc_conf = code->loc_conf; |
747 ngx_http_update_location_config(e->request); | 793 ngx_http_update_location_config(e->request); |
748 } | 794 } |
749 | 795 |
792 return; | 838 return; |
793 } | 839 } |
794 | 840 |
795 e->pos = e->buf.data; | 841 e->pos = e->buf.data; |
796 | 842 |
797 e->sp->value = 0; | 843 e->sp->data = e->buf.data; |
798 e->sp->text = e->buf; | 844 e->sp->len = e->buf.len; |
799 e->sp++; | 845 e->sp++; |
800 } | 846 } |
801 | 847 |
802 | 848 |
803 void | 849 void |
810 e->ip += sizeof(ngx_http_script_value_code_t); | 856 e->ip += sizeof(ngx_http_script_value_code_t); |
811 | 857 |
812 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, | 858 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, |
813 "http script value"); | 859 "http script value"); |
814 | 860 |
815 e->sp->value = (ngx_uint_t) code->value; | 861 e->sp->len = code->text_len; |
816 e->sp->text.len = (size_t) code->text_len; | 862 e->sp->data = (u_char *) code->text_data; |
817 e->sp->text.data = (u_char *) code->text_data; | |
818 e->sp++; | 863 e->sp++; |
819 } | 864 } |
820 | 865 |
821 | 866 |
822 void | 867 void |
823 ngx_http_script_set_var_code(ngx_http_script_engine_t *e) | 868 ngx_http_script_set_var_code(ngx_http_script_engine_t *e) |
824 { | 869 { |
825 ngx_http_request_t *r; | 870 ngx_http_request_t *r; |
826 ngx_http_variable_value_t *value; | |
827 ngx_http_core_main_conf_t *cmcf; | |
828 ngx_http_script_var_code_t *code; | 871 ngx_http_script_var_code_t *code; |
829 | 872 |
830 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, | 873 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, |
831 "http script set var"); | 874 "http script set var"); |
832 | 875 |
834 | 877 |
835 e->ip += sizeof(ngx_http_script_var_code_t); | 878 e->ip += sizeof(ngx_http_script_var_code_t); |
836 | 879 |
837 r = e->request; | 880 r = e->request; |
838 | 881 |
839 if (r->variables == NULL) { | |
840 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); | |
841 | |
842 r->variables = ngx_pcalloc(r->pool, cmcf->variables.nelts | |
843 * sizeof(ngx_http_variable_value_t *)); | |
844 if (r->variables == NULL) { | |
845 e->ip = ngx_http_script_exit; | |
846 e->status = NGX_HTTP_INTERNAL_SERVER_ERROR; | |
847 return; | |
848 } | |
849 } | |
850 | |
851 value = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)); | |
852 if (value == NULL) { | |
853 e->ip = ngx_http_script_exit; | |
854 e->status = NGX_HTTP_INTERNAL_SERVER_ERROR; | |
855 return; | |
856 } | |
857 | |
858 e->sp--; | 882 e->sp--; |
859 | 883 |
860 *value = *e->sp; | 884 r->variables[code->index].len = e->sp->len; |
861 | 885 r->variables[code->index].valid = 1; |
862 r->variables[code->index] = value; | 886 r->variables[code->index].no_cachable = 0; |
887 r->variables[code->index].not_found = 0; | |
888 r->variables[code->index].data = e->sp->data; | |
863 } | 889 } |
864 | 890 |
865 | 891 |
866 void | 892 void |
867 ngx_http_script_var_code(ngx_http_script_engine_t *e) | 893 ngx_http_script_var_code(ngx_http_script_engine_t *e) |
874 | 900 |
875 code = (ngx_http_script_var_code_t *) e->ip; | 901 code = (ngx_http_script_var_code_t *) e->ip; |
876 | 902 |
877 e->ip += sizeof(ngx_http_script_var_code_t); | 903 e->ip += sizeof(ngx_http_script_var_code_t); |
878 | 904 |
879 value = ngx_http_get_indexed_variable(e->request, code->index); | 905 value = ngx_http_get_flushed_variable(e->request, code->index); |
880 | 906 |
881 if (value && value != NGX_HTTP_VAR_NOT_FOUND) { | 907 if (value && !value->not_found) { |
882 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, | 908 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, |
883 "http script var: %ui, \"%V\"", value->value, &value->text); | 909 "http script var: \"%V\"", value); |
910 | |
884 *e->sp = *value; | 911 *e->sp = *value; |
885 e->sp++; | 912 e->sp++; |
886 | 913 |
887 return; | 914 return; |
888 } | 915 } |
889 | 916 |
890 e->sp->value = 0; | 917 e->sp->data = (u_char *) ""; |
891 e->sp->text.len = 0; | 918 e->sp->len = 0; |
892 e->sp->text.data = (u_char *) ""; | |
893 e->sp++; | 919 e->sp++; |
894 } | 920 } |
895 | 921 |
896 | 922 |
897 void | 923 void |