Mercurial > hg > nginx-ranges
comparison src/http/ngx_http_script.c @ 465:ca8f7f6cab16 NGINX_0_7_40
nginx 0.7.40
*) Feature: the "location" directive supports captures in regular
expressions.
*) Feature: an "alias" directive with capture references may be used
inside a location given by a regular expression with captures.
*) Feature: the "server_name" directive supports captures in regular
expressions.
*) Workaround: the ngx_http_autoindex_module did not show the trailing
slash in directories on XFS filesystem; the issue had appeared in
0.7.15.
Thanks to Dmitry Kuzmenko.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Mon, 09 Mar 2009 00:00:00 +0300 |
parents | 33394d1255b0 |
children | c8cfb6c462ef |
comparison
equal
deleted
inserted
replaced
464:ead634c4b006 | 465:ca8f7f6cab16 |
---|---|
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 #if (NGX_PCRE) | |
43 ngx_http_script_copy_capture_code_t *copy_capture; | 44 ngx_http_script_copy_capture_code_t *copy_capture; |
45 #endif | |
44 | 46 |
45 if (sc->flushes && *sc->flushes == NULL) { | 47 if (sc->flushes && *sc->flushes == NULL) { |
46 n = sc->variables ? sc->variables : 1; | 48 n = sc->variables ? sc->variables : 1; |
47 *sc->flushes = ngx_array_create(sc->cf->pool, n, sizeof(ngx_uint_t)); | 49 *sc->flushes = ngx_array_create(sc->cf->pool, n, sizeof(ngx_uint_t)); |
48 if (*sc->flushes == NULL) { | 50 if (*sc->flushes == NULL) { |
87 | 89 |
88 if (++i == sc->source->len) { | 90 if (++i == sc->source->len) { |
89 goto invalid_variable; | 91 goto invalid_variable; |
90 } | 92 } |
91 | 93 |
94 #if (NGX_PCRE) | |
95 | |
96 /* NGX_HTTP_MAX_CAPTURES is 9 */ | |
97 | |
92 if (sc->source->data[i] >= '1' && sc->source->data[i] <= '9') { | 98 if (sc->source->data[i] >= '1' && sc->source->data[i] <= '9') { |
93 | 99 |
94 n = sc->source->data[i] - '0'; | 100 n = sc->source->data[i] - '0'; |
95 | 101 |
96 if (sc->captures_mask & (1 << n)) { | 102 if (sc->captures_mask & (1 << n)) { |
127 | 133 |
128 i++; | 134 i++; |
129 | 135 |
130 continue; | 136 continue; |
131 } | 137 } |
138 | |
139 #endif | |
132 | 140 |
133 if (sc->source->data[i] == '{') { | 141 if (sc->source->data[i] == '{') { |
134 bracket = 1; | 142 bracket = 1; |
135 | 143 |
136 if (++i == sc->source->len) { | 144 if (++i == sc->source->len) { |
517 } | 525 } |
518 } | 526 } |
519 | 527 |
520 | 528 |
521 size_t | 529 size_t |
522 ngx_http_script_copy_capture_len_code(ngx_http_script_engine_t *e) | |
523 { | |
524 ngx_http_script_copy_capture_code_t *code; | |
525 | |
526 code = (ngx_http_script_copy_capture_code_t *) e->ip; | |
527 | |
528 e->ip += sizeof(ngx_http_script_copy_capture_code_t); | |
529 | |
530 if (code->n < e->ncaptures) { | |
531 if ((e->is_args || e->quote) | |
532 && (e->request->quoted_uri || e->request->plus_in_uri)) | |
533 { | |
534 return e->captures[code->n + 1] - e->captures[code->n] | |
535 + 2 * ngx_escape_uri(NULL, | |
536 &e->line.data[e->captures[code->n]], | |
537 e->captures[code->n + 1] - e->captures[code->n], | |
538 NGX_ESCAPE_ARGS); | |
539 } else { | |
540 return e->captures[code->n + 1] - e->captures[code->n]; | |
541 } | |
542 } | |
543 | |
544 return 0; | |
545 } | |
546 | |
547 | |
548 void | |
549 ngx_http_script_copy_capture_code(ngx_http_script_engine_t *e) | |
550 { | |
551 u_char *p; | |
552 ngx_http_script_copy_capture_code_t *code; | |
553 | |
554 code = (ngx_http_script_copy_capture_code_t *) e->ip; | |
555 | |
556 e->ip += sizeof(ngx_http_script_copy_capture_code_t); | |
557 | |
558 p = e->pos; | |
559 | |
560 if (code->n < e->ncaptures) { | |
561 if ((e->is_args || e->quote) | |
562 && (e->request->quoted_uri || e->request->plus_in_uri)) | |
563 { | |
564 e->pos = (u_char *) ngx_escape_uri(p, | |
565 &e->line.data[e->captures[code->n]], | |
566 e->captures[code->n + 1] - e->captures[code->n], | |
567 NGX_ESCAPE_ARGS); | |
568 } else { | |
569 e->pos = ngx_copy(p, | |
570 &e->line.data[e->captures[code->n]], | |
571 e->captures[code->n + 1] - e->captures[code->n]); | |
572 } | |
573 } | |
574 | |
575 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, | |
576 "http script capture: \"%*s\"", e->pos - p, p); | |
577 } | |
578 | |
579 | |
580 size_t | |
581 ngx_http_script_mark_args_code(ngx_http_script_engine_t *e) | 530 ngx_http_script_mark_args_code(ngx_http_script_engine_t *e) |
582 { | 531 { |
583 e->is_args = 1; | 532 e->is_args = 1; |
584 e->ip += sizeof(uintptr_t); | 533 e->ip += sizeof(uintptr_t); |
585 | 534 |
595 | 544 |
596 e->is_args = 1; | 545 e->is_args = 1; |
597 e->args = e->pos; | 546 e->args = e->pos; |
598 e->ip += sizeof(uintptr_t); | 547 e->ip += sizeof(uintptr_t); |
599 } | 548 } |
600 | |
601 | 549 |
602 | 550 |
603 #if (NGX_PCRE) | 551 #if (NGX_PCRE) |
604 | 552 |
605 void | 553 void |
626 e->sp--; | 574 e->sp--; |
627 e->line.len = e->sp->len; | 575 e->line.len = e->sp->len; |
628 e->line.data = e->sp->data; | 576 e->line.data = e->sp->data; |
629 } | 577 } |
630 | 578 |
631 rc = ngx_regex_exec(code->regex, &e->line, e->captures, code->ncaptures); | 579 if (code->ncaptures && r->captures == NULL) { |
580 | |
581 r->captures = ngx_palloc(r->pool, | |
582 (NGX_HTTP_MAX_CAPTURES + 1) * 3 * sizeof(int)); | |
583 if (r->captures == NULL) { | |
584 e->ip = ngx_http_script_exit; | |
585 e->status = NGX_HTTP_INTERNAL_SERVER_ERROR; | |
586 return; | |
587 } | |
588 } | |
589 | |
590 rc = ngx_regex_exec(code->regex, &e->line, r->captures, code->ncaptures); | |
632 | 591 |
633 if (rc == NGX_REGEX_NO_MATCHED) { | 592 if (rc == NGX_REGEX_NO_MATCHED) { |
634 if (e->log || (r->connection->log->log_level & NGX_LOG_DEBUG_HTTP)) { | 593 if (e->log || (r->connection->log->log_level & NGX_LOG_DEBUG_HTTP)) { |
635 ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0, | 594 ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0, |
636 "\"%V\" does not match \"%V\"", | 595 "\"%V\" does not match \"%V\"", |
637 &code->name, &e->line); | 596 &code->name, &e->line); |
638 } | 597 } |
639 | 598 |
640 e->ncaptures = 0; | 599 r->ncaptures = 0; |
641 | 600 |
642 if (code->test) { | 601 if (code->test) { |
643 if (code->negative_test) { | 602 if (code->negative_test) { |
644 e->sp->len = 1; | 603 e->sp->len = 1; |
645 e->sp->data = (u_char *) "1"; | 604 e->sp->data = (u_char *) "1"; |
672 if (e->log || (r->connection->log->log_level & NGX_LOG_DEBUG_HTTP)) { | 631 if (e->log || (r->connection->log->log_level & NGX_LOG_DEBUG_HTTP)) { |
673 ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0, | 632 ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0, |
674 "\"%V\" matches \"%V\"", &code->name, &e->line); | 633 "\"%V\" matches \"%V\"", &code->name, &e->line); |
675 } | 634 } |
676 | 635 |
677 e->ncaptures = code->ncaptures; | 636 r->ncaptures = code->ncaptures; |
637 r->captures_data = e->line.data; | |
678 | 638 |
679 if (code->test) { | 639 if (code->test) { |
680 if (code->negative_test) { | 640 if (code->negative_test) { |
681 e->sp->len = 0; | 641 e->sp->len = 0; |
682 e->sp->data = (u_char *) ""; | 642 e->sp->data = (u_char *) ""; |
723 NGX_ESCAPE_ARGS); | 683 NGX_ESCAPE_ARGS); |
724 } | 684 } |
725 } | 685 } |
726 | 686 |
727 for (n = 1; n < (ngx_uint_t) rc; n++) { | 687 for (n = 1; n < (ngx_uint_t) rc; n++) { |
728 e->buf.len += e->captures[2 * n + 1] - e->captures[2 * n]; | 688 e->buf.len += r->captures[2 * n + 1] - r->captures[2 * n]; |
729 } | 689 } |
730 | 690 |
731 } else { | 691 } else { |
732 ngx_memzero(&le, sizeof(ngx_http_script_engine_t)); | 692 ngx_memzero(&le, sizeof(ngx_http_script_engine_t)); |
733 | 693 |
734 le.ip = code->lengths->elts; | 694 le.ip = code->lengths->elts; |
735 le.line = e->line; | 695 le.line = e->line; |
736 le.request = r; | 696 le.request = r; |
737 le.captures = e->captures; | |
738 le.ncaptures = e->ncaptures; | |
739 le.quote = code->redirect; | 697 le.quote = code->redirect; |
740 | 698 |
741 len = 0; | 699 len = 0; |
742 | 700 |
743 while (*(uintptr_t *) le.ip) { | 701 while (*(uintptr_t *) le.ip) { |
872 } | 830 } |
873 | 831 |
874 e->ip += sizeof(ngx_http_script_regex_end_code_t); | 832 e->ip += sizeof(ngx_http_script_regex_end_code_t); |
875 } | 833 } |
876 | 834 |
835 | |
836 size_t | |
837 ngx_http_script_copy_capture_len_code(ngx_http_script_engine_t *e) | |
838 { | |
839 int *cap; | |
840 u_char *p; | |
841 ngx_uint_t n; | |
842 ngx_http_request_t *r; | |
843 ngx_http_script_copy_capture_code_t *code; | |
844 | |
845 r = e->request; | |
846 | |
847 code = (ngx_http_script_copy_capture_code_t *) e->ip; | |
848 | |
849 e->ip += sizeof(ngx_http_script_copy_capture_code_t); | |
850 | |
851 n = code->n; | |
852 | |
853 if (n < r->ncaptures) { | |
854 | |
855 cap = r->captures; | |
856 | |
857 if ((e->is_args || e->quote) | |
858 && (e->request->quoted_uri || e->request->plus_in_uri)) | |
859 { | |
860 p = r->captures_data; | |
861 | |
862 return cap[n + 1] - cap[n] | |
863 + 2 * ngx_escape_uri(NULL, &p[cap[n]], cap[n + 1] - cap[n], | |
864 NGX_ESCAPE_ARGS); | |
865 } else { | |
866 return cap[n + 1] - cap[n]; | |
867 } | |
868 } | |
869 | |
870 return 0; | |
871 } | |
872 | |
873 | |
874 void | |
875 ngx_http_script_copy_capture_code(ngx_http_script_engine_t *e) | |
876 { | |
877 int *cap; | |
878 u_char *p, *pos; | |
879 ngx_uint_t n; | |
880 ngx_http_request_t *r; | |
881 ngx_http_script_copy_capture_code_t *code; | |
882 | |
883 r = e->request; | |
884 | |
885 code = (ngx_http_script_copy_capture_code_t *) e->ip; | |
886 | |
887 e->ip += sizeof(ngx_http_script_copy_capture_code_t); | |
888 | |
889 n = code->n; | |
890 | |
891 pos = e->pos; | |
892 | |
893 if (n < r->ncaptures) { | |
894 | |
895 cap = r->captures; | |
896 p = r->captures_data; | |
897 | |
898 if ((e->is_args || e->quote) | |
899 && (e->request->quoted_uri || e->request->plus_in_uri)) | |
900 { | |
901 e->pos = (u_char *) ngx_escape_uri(pos, &p[cap[n]], | |
902 cap[n + 1] - cap[n], | |
903 NGX_ESCAPE_ARGS); | |
904 } else { | |
905 e->pos = ngx_copy(pos, &p[cap[n]], cap[n + 1] - cap[n]); | |
906 } | |
907 } | |
908 | |
909 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, | |
910 "http script capture: \"%*s\"", e->pos - pos, pos); | |
911 } | |
912 | |
877 #endif | 913 #endif |
878 | 914 |
879 | 915 |
880 void | 916 void |
881 ngx_http_script_return_code(ngx_http_script_engine_t *e) | 917 ngx_http_script_return_code(ngx_http_script_engine_t *e) |
1131 ngx_memzero(&le, sizeof(ngx_http_script_engine_t)); | 1167 ngx_memzero(&le, sizeof(ngx_http_script_engine_t)); |
1132 | 1168 |
1133 le.ip = code->lengths->elts; | 1169 le.ip = code->lengths->elts; |
1134 le.line = e->line; | 1170 le.line = e->line; |
1135 le.request = e->request; | 1171 le.request = e->request; |
1136 le.captures = e->captures; | |
1137 le.ncaptures = e->ncaptures; | |
1138 le.quote = e->quote; | 1172 le.quote = e->quote; |
1139 | 1173 |
1140 for (len = 0; *(uintptr_t *) le.ip; len += lcode(&le)) { | 1174 for (len = 0; *(uintptr_t *) le.ip; len += lcode(&le)) { |
1141 lcode = *(ngx_http_script_len_code_pt *) le.ip; | 1175 lcode = *(ngx_http_script_len_code_pt *) le.ip; |
1142 } | 1176 } |