comparison src/http/modules/perl/ngx_http_perl_module.c @ 502:89dc5654117c NGINX_0_7_63

nginx 0.7.63 *) Security: now "/../" are disabled in "Destination" request header line. *) Change: minimum supported OpenSSL version is 0.9.7. *) Change: the "ask" parameter of the "ssl_verify_client" directive was changed to the "optional" parameter and now it checks a client certificate if it was offered. Thanks to Brice Figureau. *) Feature: now the "-V" switch shows TLS SNI support. *) Feature: the $ssl_client_verify variable. Thanks to Brice Figureau. *) Feature: the "ssl_crl" directive. Thanks to Brice Figureau. *) Bugfix: the $ssl_client_cert variable usage corrupted memory; the bug had appeared in 0.7.7. Thanks to Sergey Zhuravlev. *) Feature: now the start cache loader runs in a separate process; this should improve large caches handling. *) Feature: now temporary files and permanent storage area may reside at different file systems. *) Bugfix: nginx counted incorrectly disk cache size. *) Change: now directive "gzip_disable msie6" does not disable gzipping for MSIE 6.0 SV1. *) Bugfix: nginx always added "Vary: Accept-Encoding" response header line, if both "gzip_static" and "gzip_vary" were on. *) Feature: the "proxy" parameter of the "geo" directive. *) Feature: the ngx_http_geoip_module. *) Feature: the "limit_rate_after" directive. Thanks to Ivan Debnar. *) Feature: the "limit_req_log_level" and "limit_conn_log_level" directives. *) Bugfix: now "limit_req" directive conforms to the leaky bucket algorithm. Thanks to Maxim Dounin. *) Bugfix: in ngx_http_limit_req_module. Thanks to Maxim Dounin. *) Bugfix: now nginx allows underscores in a request method. *) Bugfix: "proxy_pass_header" and "fastcgi_pass_header" directives did not pass to a client the "X-Accel-Redirect", "X-Accel-Limit-Rate", "X-Accel-Buffering", and "X-Accel-Charset" lines from backend response header. Thanks to Maxim Dounin. *) Bugfix: in handling "Last-Modified" and "Accept-Ranges" backend response header lines; the bug had appeared in 0.7.44. Thanks to Maxim Dounin. *) Feature: the "image_filter_transparency" directive. *) Feature: the "image_filter" directive supports variables for setting size. *) Bugfix: in PNG alpha-channel support in the ngx_http_image_filter_module. *) Bugfix: in transparency support in the ngx_http_image_filter_module. *) Feature: now several "perl_modules" directives may be used. *) Bugfix: ngx_http_perl_module responses did not work in subrequests. *) Bugfix: nginx sent '\0' in a "Location" response header line on MKCOL request. Thanks to Xie Zhenye. *) Bugfix: an "error_page" directive did not redirect a 413 error; the bug had appeared in 0.6.10. *) Bugfix: in memory allocation error handling. Thanks to Maxim Dounin and Kirill A. Korinskiy.
author Igor Sysoev <http://sysoev.ru>
date Mon, 26 Oct 2009 00:00:00 +0300
parents 549994537f15
children b9fdcaf2062b
comparison
equal deleted inserted replaced
501:dc87c92181c7 502:89dc5654117c
11 11
12 12
13 typedef struct { 13 typedef struct {
14 PerlInterpreter *perl; 14 PerlInterpreter *perl;
15 HV *nginx; 15 HV *nginx;
16 ngx_str_t modules; 16 ngx_array_t *modules;
17 ngx_array_t requires; 17 ngx_array_t *requires;
18 } ngx_http_perl_main_conf_t; 18 } ngx_http_perl_main_conf_t;
19 19
20 20
21 typedef struct { 21 typedef struct {
22 SV *sub; 22 SV *sub;
55 static void *ngx_http_perl_create_main_conf(ngx_conf_t *cf); 55 static void *ngx_http_perl_create_main_conf(ngx_conf_t *cf);
56 static char *ngx_http_perl_init_main_conf(ngx_conf_t *cf, void *conf); 56 static char *ngx_http_perl_init_main_conf(ngx_conf_t *cf, void *conf);
57 static void *ngx_http_perl_create_loc_conf(ngx_conf_t *cf); 57 static void *ngx_http_perl_create_loc_conf(ngx_conf_t *cf);
58 static char *ngx_http_perl_merge_loc_conf(ngx_conf_t *cf, void *parent, 58 static char *ngx_http_perl_merge_loc_conf(ngx_conf_t *cf, void *parent,
59 void *child); 59 void *child);
60 static char *ngx_http_perl_require(ngx_conf_t *cf, ngx_command_t *cmd,
61 void *conf);
62 static char *ngx_http_perl(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); 60 static char *ngx_http_perl(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
63 static char *ngx_http_perl_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); 61 static char *ngx_http_perl_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
64 62
65 #if (NGX_HAVE_PERL_MULTIPLICITY) 63 #if (NGX_HAVE_PERL_MULTIPLICITY)
66 static void ngx_http_perl_cleanup_perl(void *data); 64 static void ngx_http_perl_cleanup_perl(void *data);
72 70
73 static ngx_command_t ngx_http_perl_commands[] = { 71 static ngx_command_t ngx_http_perl_commands[] = {
74 72
75 { ngx_string("perl_modules"), 73 { ngx_string("perl_modules"),
76 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1, 74 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
77 ngx_conf_set_str_slot, 75 ngx_conf_set_str_array_slot,
78 NGX_HTTP_MAIN_CONF_OFFSET, 76 NGX_HTTP_MAIN_CONF_OFFSET,
79 offsetof(ngx_http_perl_main_conf_t, modules), 77 offsetof(ngx_http_perl_main_conf_t, modules),
80 NULL }, 78 NULL },
81 79
82 { ngx_string("perl_require"), 80 { ngx_string("perl_require"),
83 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1, 81 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
84 ngx_http_perl_require, 82 ngx_conf_set_str_array_slot,
85 NGX_HTTP_MAIN_CONF_OFFSET, 83 NGX_HTTP_MAIN_CONF_OFFSET,
86 0, 84 offsetof(ngx_http_perl_main_conf_t, requires),
87 NULL }, 85 NULL },
88 86
89 { ngx_string("perl"), 87 { ngx_string("perl"),
90 NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF|NGX_CONF_TAKE1, 88 NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF|NGX_CONF_TAKE1,
91 ngx_http_perl, 89 ngx_http_perl,
456 454
457 455
458 static char * 456 static char *
459 ngx_http_perl_init_interpreter(ngx_conf_t *cf, ngx_http_perl_main_conf_t *pmcf) 457 ngx_http_perl_init_interpreter(ngx_conf_t *cf, ngx_http_perl_main_conf_t *pmcf)
460 { 458 {
459 ngx_str_t *m;
460 ngx_uint_t i;
461 #if (NGX_HAVE_PERL_MULTIPLICITY) 461 #if (NGX_HAVE_PERL_MULTIPLICITY)
462 ngx_pool_cleanup_t *cln; 462 ngx_pool_cleanup_t *cln;
463 463
464 cln = ngx_pool_cleanup_add(cf->pool, 0); 464 cln = ngx_pool_cleanup_add(cf->pool, 0);
465 if (cln == NULL) { 465 if (cln == NULL) {
466 return NGX_CONF_ERROR; 466 return NGX_CONF_ERROR;
467 } 467 }
469 #else 469 #else
470 static PerlInterpreter *perl; 470 static PerlInterpreter *perl;
471 #endif 471 #endif
472 472
473 #ifdef NGX_PERL_MODULES 473 #ifdef NGX_PERL_MODULES
474 if (pmcf->modules.data == NULL) { 474 if (pmcf->modules == NGX_CONF_UNSET_PTR) {
475 pmcf->modules.data = NGX_PERL_MODULES; 475
476 } 476 pmcf->modules = ngx_array_create(cf->pool, 1, sizeof(ngx_str_t));
477 #endif 477 if (pmcf->modules == NULL) {
478
479 if (pmcf->modules.data) {
480 if (ngx_conf_full_name(cf->cycle, &pmcf->modules, 0) != NGX_OK) {
481 return NGX_CONF_ERROR; 478 return NGX_CONF_ERROR;
479 }
480
481 m = ngx_array_push(pmcf->modules);
482 if (m == NULL) {
483 return NGX_CONF_ERROR;
484 }
485
486 m->len = sizeof(NGX_PERL_MODULES) - 1;
487 m->data = NGX_PERL_MODULES;
488 }
489 #endif
490
491 if (pmcf->modules != NGX_CONF_UNSET_PTR) {
492 m = pmcf->modules->elts;
493 for (i = 0; i < pmcf->modules->nelts; i++) {
494 if (ngx_conf_full_name(cf->cycle, &m[i], 0) != NGX_OK) {
495 return NGX_CONF_ERROR;
496 }
482 } 497 }
483 } 498 }
484 499
485 #if !(NGX_HAVE_PERL_MULTIPLICITY) 500 #if !(NGX_HAVE_PERL_MULTIPLICITY)
486 501
488 503
489 if (ngx_set_environment(cf->cycle, NULL) == NULL) { 504 if (ngx_set_environment(cf->cycle, NULL) == NULL) {
490 return NGX_CONF_ERROR; 505 return NGX_CONF_ERROR;
491 } 506 }
492 507
493 if (ngx_http_perl_run_requires(aTHX_ &pmcf->requires, cf->log) 508 if (ngx_http_perl_run_requires(aTHX_ pmcf->requires, cf->log)
494 != NGX_OK) 509 != NGX_OK)
495 { 510 {
496 return NGX_CONF_ERROR; 511 return NGX_CONF_ERROR;
497 } 512 }
498 513
536 ngx_http_perl_main_conf_t *pmcf) 551 ngx_http_perl_main_conf_t *pmcf)
537 { 552 {
538 int n; 553 int n;
539 STRLEN len; 554 STRLEN len;
540 SV *sv; 555 SV *sv;
541 char *ver, *embedding[6]; 556 char *ver, **embedding;
557 ngx_str_t *m;
558 ngx_uint_t i;
542 PerlInterpreter *perl; 559 PerlInterpreter *perl;
543 560
544 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, cf->log, 0, "create perl interpreter"); 561 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, cf->log, 0, "create perl interpreter");
545 562
546 if (ngx_set_environment(cf->cycle, NULL) == NULL) { 563 if (ngx_set_environment(cf->cycle, NULL) == NULL) {
562 579
563 #ifdef PERL_EXIT_DESTRUCT_END 580 #ifdef PERL_EXIT_DESTRUCT_END
564 PL_exit_flags |= PERL_EXIT_DESTRUCT_END; 581 PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
565 #endif 582 #endif
566 583
584 n = (pmcf->modules != NGX_CONF_UNSET_PTR) ? pmcf->modules->nelts * 2 : 0;
585
586 embedding = ngx_palloc(cf->pool, (4 + n) * sizeof(char *));
587 if (embedding == NULL) {
588 goto fail;
589 }
590
567 embedding[0] = ""; 591 embedding[0] = "";
568 592
569 if (pmcf->modules.data) { 593 if (n++) {
570 embedding[1] = "-I"; 594 m = pmcf->modules->elts;
571 embedding[2] = (char *) pmcf->modules.data; 595 for (i = 0; i < pmcf->modules->nelts; i++) {
572 n = 3; 596 embedding[2 * i + 1] = "-I";
573 597 embedding[2 * i + 2] = (char *) m[i].data;
574 } else { 598 }
575 n = 1;
576 } 599 }
577 600
578 embedding[n++] = "-Mnginx"; 601 embedding[n++] = "-Mnginx";
579 embedding[n++] = "-e"; 602 embedding[n++] = "-e";
580 embedding[n++] = "0"; 603 embedding[n++] = "0";
594 "version " NGINX_VERSION " of nginx.pm is required, " 617 "version " NGINX_VERSION " of nginx.pm is required, "
595 "but %s was found", ver); 618 "but %s was found", ver);
596 goto fail; 619 goto fail;
597 } 620 }
598 621
599 if (ngx_http_perl_run_requires(aTHX_ &pmcf->requires, cf->log) != NGX_OK) { 622 if (ngx_http_perl_run_requires(aTHX_ pmcf->requires, cf->log) != NGX_OK) {
600 goto fail; 623 goto fail;
601 } 624 }
602 625
603 } 626 }
604 627
615 638
616 639
617 static ngx_int_t 640 static ngx_int_t
618 ngx_http_perl_run_requires(pTHX_ ngx_array_t *requires, ngx_log_t *log) 641 ngx_http_perl_run_requires(pTHX_ ngx_array_t *requires, ngx_log_t *log)
619 { 642 {
620 char **script; 643 u_char *err;
621 STRLEN len; 644 STRLEN len;
622 ngx_str_t err; 645 ngx_str_t *script;
623 ngx_uint_t i; 646 ngx_uint_t i;
647
648 if (requires == NGX_CONF_UNSET_PTR) {
649 return NGX_OK;
650 }
624 651
625 script = requires->elts; 652 script = requires->elts;
626 for (i = 0; i < requires->nelts; i++) { 653 for (i = 0; i < requires->nelts; i++) {
627 654
628 require_pv(script[i]); 655 require_pv((char *) script[i].data);
629 656
630 if (SvTRUE(ERRSV)) { 657 if (SvTRUE(ERRSV)) {
631 658
632 err.data = (u_char *) SvPV(ERRSV, len); 659 err = (u_char *) SvPV(ERRSV, len);
633 for (len--; err.data[len] == LF || err.data[len] == CR; len--) { 660 while (--len && (err[len] == CR || err[len] == LF)) { /* void */ }
634 /* void */
635 }
636 err.len = len + 1;
637 661
638 ngx_log_error(NGX_LOG_EMERG, log, 0, 662 ngx_log_error(NGX_LOG_EMERG, log, 0,
639 "require_pv(\"%s\") failed: \"%V\"", script[i], &err); 663 "require_pv(\"%s\") failed: \"%*s\"",
664 script[i].data, len + 1, err);
640 665
641 return NGX_ERROR; 666 return NGX_ERROR;
642 } 667 }
643 } 668 }
644 669
651 SV **args, ngx_str_t *handler, ngx_str_t *rv) 676 SV **args, ngx_str_t *handler, ngx_str_t *rv)
652 { 677 {
653 SV *sv; 678 SV *sv;
654 int n, status; 679 int n, status;
655 char *line; 680 char *line;
681 u_char *err;
656 STRLEN len, n_a; 682 STRLEN len, n_a;
657 ngx_str_t err;
658 ngx_uint_t i; 683 ngx_uint_t i;
659 ngx_connection_t *c; 684 ngx_connection_t *c;
660 685
661 dSP; 686 dSP;
662 687
722 747
723 /* check $@ */ 748 /* check $@ */
724 749
725 if (SvTRUE(ERRSV)) { 750 if (SvTRUE(ERRSV)) {
726 751
727 err.data = (u_char *) SvPV(ERRSV, len); 752 err = (u_char *) SvPV(ERRSV, len);
728 for (len--; err.data[len] == LF || err.data[len] == CR; len--) { 753 while (--len && (err[len] == CR || err[len] == LF)) { /* void */ }
729 /* void */
730 }
731 err.len = len + 1;
732 754
733 ngx_log_error(NGX_LOG_ERR, c->log, 0, 755 ngx_log_error(NGX_LOG_ERR, c->log, 0,
734 "call_sv(\"%V\") failed: \"%V\"", handler, &err); 756 "call_sv(\"%V\") failed: \"%*s\"", handler, len + 1, err);
735 757
736 if (rv) { 758 if (rv) {
737 return NGX_ERROR; 759 return NGX_ERROR;
738 } 760 }
739 761
763 if (*p != ' ' && *p != '\t' && *p != CR && *p != LF) { 785 if (*p != ' ' && *p != '\t' && *p != CR && *p != LF) {
764 break; 786 break;
765 } 787 }
766 } 788 }
767 789
768 if (ngx_strncmp(p, "sub ", 4) == 0 || ngx_strncmp(p, "use ", 4) == 0) { 790 if (ngx_strncmp(p, "sub ", 4) == 0
791 || ngx_strncmp(p, "sub{", 4) == 0
792 || ngx_strncmp(p, "use ", 4) == 0)
793 {
769 *sv = eval_pv((char *) p, FALSE); 794 *sv = eval_pv((char *) p, FALSE);
770 795
771 /* eval_pv() does not set ERRSV on failure */ 796 /* eval_pv() does not set ERRSV on failure */
772 797
773 return; 798 return;
782 { 807 {
783 ngx_http_perl_main_conf_t *pmcf; 808 ngx_http_perl_main_conf_t *pmcf;
784 809
785 pmcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_perl_main_conf_t)); 810 pmcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_perl_main_conf_t));
786 if (pmcf == NULL) { 811 if (pmcf == NULL) {
787 return NGX_CONF_ERROR;
788 }
789
790 if (ngx_array_init(&pmcf->requires, cf->pool, 1, sizeof(u_char *))
791 != NGX_OK)
792 {
793 return NULL; 812 return NULL;
794 } 813 }
814
815 pmcf->modules = NGX_CONF_UNSET_PTR;
816 pmcf->requires = NGX_CONF_UNSET_PTR;
795 817
796 return pmcf; 818 return pmcf;
797 } 819 }
798 820
799 821
867 { 889 {
868 ngx_http_perl_loc_conf_t *plcf; 890 ngx_http_perl_loc_conf_t *plcf;
869 891
870 plcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_perl_loc_conf_t)); 892 plcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_perl_loc_conf_t));
871 if (plcf == NULL) { 893 if (plcf == NULL) {
872 return NGX_CONF_ERROR; 894 return NULL;
873 } 895 }
874 896
875 /* 897 /*
876 * set by ngx_pcalloc(): 898 * set by ngx_pcalloc():
877 * 899 *
896 return NGX_CONF_OK; 918 return NGX_CONF_OK;
897 } 919 }
898 920
899 921
900 static char * 922 static char *
901 ngx_http_perl_require(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
902 {
903 ngx_http_perl_main_conf_t *pmcf = conf;
904
905 u_char **p;
906 ngx_str_t *value;
907
908 value = cf->args->elts;
909
910 p = ngx_array_push(&pmcf->requires);
911
912 if (p == NULL) {
913 return NGX_CONF_ERROR;
914 }
915
916 *p = value[1].data;
917
918 return NGX_CONF_OK;
919 }
920
921
922 static char *
923 ngx_http_perl(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) 923 ngx_http_perl(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
924 { 924 {
925 ngx_http_perl_loc_conf_t *plcf = conf; 925 ngx_http_perl_loc_conf_t *plcf = conf;
926 926
927 ngx_str_t *value; 927 ngx_str_t *value;