Mercurial > hg > nginx
comparison src/http/modules/perl/ngx_http_perl_module.c @ 649:1e720b0be7ec release-0.3.46
nginx-0.3.46-RELEASE import
*) Feature: the "proxy_hide_header", "proxy_pass_header",
"fastcgi_hide_header", and "fastcgi_pass_header" directives.
*) Change: the "proxy_pass_x_powered_by", "fastcgi_x_powered_by", and
"proxy_pass_server" directives were canceled.
*) Feature: the "X-Accel-Buffering" response header line is supported
in proxy mode.
*) Bugfix: the reconfiguration bug and memory leaks in the
ngx_http_perl_module.
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Thu, 11 May 2006 14:43:47 +0000 |
parents | 715d24327080 |
children | 39b7d7b33c91 |
comparison
equal
deleted
inserted
replaced
648:e60de1d1cdb2 | 649:1e720b0be7ec |
---|---|
49 static char *ngx_http_perl_init_interpreter(ngx_conf_t *cf, | 49 static char *ngx_http_perl_init_interpreter(ngx_conf_t *cf, |
50 ngx_http_perl_main_conf_t *pmcf); | 50 ngx_http_perl_main_conf_t *pmcf); |
51 static PerlInterpreter * | 51 static PerlInterpreter * |
52 ngx_http_perl_create_interpreter(ngx_http_perl_main_conf_t *pmcf, | 52 ngx_http_perl_create_interpreter(ngx_http_perl_main_conf_t *pmcf, |
53 ngx_log_t *log); | 53 ngx_log_t *log); |
54 static ngx_int_t ngx_http_perl_run_requires(ngx_array_t *requires, | |
55 ngx_log_t *log); | |
54 static ngx_int_t ngx_http_perl_call_handler(pTHX_ ngx_http_request_t *r, | 56 static ngx_int_t ngx_http_perl_call_handler(pTHX_ ngx_http_request_t *r, |
55 SV *sub, ngx_str_t **args, ngx_str_t *handler, ngx_str_t *rv); | 57 SV *sub, ngx_str_t **args, ngx_str_t *handler, ngx_str_t *rv); |
56 static void ngx_http_perl_eval_anon_sub(pTHX_ ngx_str_t *handler, SV **sv); | 58 static void ngx_http_perl_eval_anon_sub(pTHX_ ngx_str_t *handler, SV **sv); |
57 | 59 |
58 static ngx_int_t ngx_http_perl_preconfiguration(ngx_conf_t *cf); | 60 static ngx_int_t ngx_http_perl_preconfiguration(ngx_conf_t *cf); |
65 void *conf); | 67 void *conf); |
66 static char *ngx_http_perl(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); | 68 static char *ngx_http_perl(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); |
67 static char *ngx_http_perl_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); | 69 static char *ngx_http_perl_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); |
68 static char *ngx_http_perl_interp_max_unsupported(ngx_conf_t *cf, void *post, | 70 static char *ngx_http_perl_interp_max_unsupported(ngx_conf_t *cf, void *post, |
69 void *data); | 71 void *data); |
72 #if (NGX_HAVE_PERL_CLONE || NGX_HAVE_PERL_MULTIPLICITY) | |
70 static void ngx_http_perl_cleanup_perl(void *data); | 73 static void ngx_http_perl_cleanup_perl(void *data); |
74 #endif | |
75 static void ngx_http_perl_cleanup_sv(void *data); | |
71 | 76 |
72 | 77 |
73 static ngx_conf_post_handler_pt ngx_http_perl_interp_max_p = | 78 static ngx_conf_post_handler_pt ngx_http_perl_interp_max_p = |
74 ngx_http_perl_interp_max_unsupported; | 79 ngx_http_perl_interp_max_unsupported; |
75 | 80 |
392 | 397 |
393 { | 398 { |
394 | 399 |
395 dTHXa(ctx->perl); | 400 dTHXa(ctx->perl); |
396 | 401 |
397 #if 0 | |
398 | |
399 ngx_http_perl_eval_anon_sub(aTHX_ handler, &sv); | |
400 | |
401 if (sv == &PL_sv_undef) { | |
402 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
403 "eval_pv(\"%V\") failed", handler); | |
404 return NGX_ERROR; | |
405 } | |
406 | |
407 if (sv == NULL) { | |
408 sv = newSVpvn((char *) handler->data, handler->len); | |
409 } | |
410 | |
411 #endif | |
412 | |
413 sv = newSVpvn((char *) handler->data, handler->len); | 402 sv = newSVpvn((char *) handler->data, handler->len); |
414 | 403 |
415 rc = ngx_http_perl_call_handler(aTHX_ r, sv, ¶ms[NGX_HTTP_PERL_SSI_ARG], | 404 rc = ngx_http_perl_call_handler(aTHX_ r, sv, ¶ms[NGX_HTTP_PERL_SSI_ARG], |
416 handler, NULL); | 405 handler, NULL); |
417 | 406 |
468 | 457 |
469 | 458 |
470 static char * | 459 static char * |
471 ngx_http_perl_init_interpreter(ngx_conf_t *cf, ngx_http_perl_main_conf_t *pmcf) | 460 ngx_http_perl_init_interpreter(ngx_conf_t *cf, ngx_http_perl_main_conf_t *pmcf) |
472 { | 461 { |
473 ngx_pool_cleanup_t *cln; | 462 #if (NGX_HAVE_PERL_CLONE || NGX_HAVE_PERL_MULTIPLICITY) |
463 ngx_pool_cleanup_t *cln; | |
474 | 464 |
475 cln = ngx_pool_cleanup_add(cf->pool, 0); | 465 cln = ngx_pool_cleanup_add(cf->pool, 0); |
476 if (cln == NULL) { | 466 if (cln == NULL) { |
477 return NGX_CONF_ERROR; | 467 return NGX_CONF_ERROR; |
478 } | 468 } |
469 | |
470 #else | |
471 static PerlInterpreter *perl; | |
472 #endif | |
479 | 473 |
480 #ifdef NGX_PERL_MODULES | 474 #ifdef NGX_PERL_MODULES |
481 if (pmcf->modules.data == NULL) { | 475 if (pmcf->modules.data == NULL) { |
482 pmcf->modules.data = NGX_PERL_MODULES; | 476 pmcf->modules.data = NGX_PERL_MODULES; |
483 } | 477 } |
487 if (ngx_conf_full_name(cf->cycle, &pmcf->modules) != NGX_OK) { | 481 if (ngx_conf_full_name(cf->cycle, &pmcf->modules) != NGX_OK) { |
488 return NGX_CONF_ERROR; | 482 return NGX_CONF_ERROR; |
489 } | 483 } |
490 } | 484 } |
491 | 485 |
486 #if !(NGX_HAVE_PERL_CLONE || NGX_HAVE_PERL_MULTIPLICITY) | |
487 | |
488 if (perl) { | |
489 if (ngx_http_perl_run_requires(&pmcf->requires, cf->log) != NGX_OK) { | |
490 return NGX_CONF_ERROR; | |
491 } | |
492 | |
493 pmcf->perl = perl; | |
494 | |
495 return NGX_CONF_OK; | |
496 } | |
497 | |
498 #endif | |
499 | |
492 PERL_SYS_INIT(&ngx_argc, &ngx_argv); | 500 PERL_SYS_INIT(&ngx_argc, &ngx_argv); |
493 | 501 |
494 pmcf->perl = ngx_http_perl_create_interpreter(pmcf, cf->log); | 502 pmcf->perl = ngx_http_perl_create_interpreter(pmcf, cf->log); |
495 | 503 |
496 if (pmcf->perl == NULL) { | 504 if (pmcf->perl == NULL) { |
497 PERL_SYS_TERM(); | 505 PERL_SYS_TERM(); |
498 return NGX_CONF_ERROR; | 506 return NGX_CONF_ERROR; |
499 } | 507 } |
500 | 508 |
509 #if (NGX_HAVE_PERL_CLONE || NGX_HAVE_PERL_MULTIPLICITY) | |
510 | |
501 cln->handler = ngx_http_perl_cleanup_perl; | 511 cln->handler = ngx_http_perl_cleanup_perl; |
502 cln->data = pmcf->perl; | 512 cln->data = pmcf->perl; |
513 | |
514 #else | |
515 | |
516 perl = pmcf->perl; | |
517 | |
518 #endif | |
503 | 519 |
504 return NGX_CONF_OK; | 520 return NGX_CONF_OK; |
505 } | 521 } |
506 | 522 |
507 | 523 |
509 ngx_http_perl_create_interpreter(ngx_http_perl_main_conf_t *pmcf, | 525 ngx_http_perl_create_interpreter(ngx_http_perl_main_conf_t *pmcf, |
510 ngx_log_t *log) | 526 ngx_log_t *log) |
511 { | 527 { |
512 int n; | 528 int n; |
513 char *embedding[6]; | 529 char *embedding[6]; |
514 char **script; | |
515 STRLEN len; | |
516 ngx_str_t err; | |
517 ngx_uint_t i; | |
518 PerlInterpreter *perl; | 530 PerlInterpreter *perl; |
519 | 531 |
520 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, log, 0, "create perl interpreter"); | 532 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, log, 0, "create perl interpreter"); |
521 | 533 |
522 #if (NGX_HAVE_PERL_CLONE) | 534 #if (NGX_HAVE_PERL_CLONE) |
581 if (n != 0) { | 593 if (n != 0) { |
582 ngx_log_error(NGX_LOG_ALERT, log, 0, "perl_parse() failed: %d", n); | 594 ngx_log_error(NGX_LOG_ALERT, log, 0, "perl_parse() failed: %d", n); |
583 goto fail; | 595 goto fail; |
584 } | 596 } |
585 | 597 |
586 script = pmcf->requires.elts; | 598 if (ngx_http_perl_run_requires(&pmcf->requires, log) != NGX_OK) { |
587 for (i = 0; i < pmcf->requires.nelts; i++) { | 599 goto fail; |
600 } | |
601 | |
602 } | |
603 | |
604 pmcf->nalloc++; | |
605 | |
606 return perl; | |
607 | |
608 fail: | |
609 | |
610 (void) perl_destruct(perl); | |
611 | |
612 perl_free(perl); | |
613 | |
614 return NULL; | |
615 } | |
616 | |
617 | |
618 static ngx_int_t | |
619 ngx_http_perl_run_requires(ngx_array_t *requires, ngx_log_t *log) | |
620 { | |
621 char **script; | |
622 STRLEN len; | |
623 ngx_str_t err; | |
624 ngx_uint_t i; | |
625 | |
626 script = requires->elts; | |
627 for (i = 0; i < requires->nelts; i++) { | |
628 | |
588 require_pv(script[i]); | 629 require_pv(script[i]); |
589 | 630 |
590 if (SvTRUE(ERRSV)) { | 631 if (SvTRUE(ERRSV)) { |
591 | 632 |
592 err.data = (u_char *) SvPV(ERRSV, len); | 633 err.data = (u_char *) SvPV(ERRSV, len); |
595 } | 636 } |
596 err.len = len + 1; | 637 err.len = len + 1; |
597 | 638 |
598 ngx_log_error(NGX_LOG_EMERG, log, 0, | 639 ngx_log_error(NGX_LOG_EMERG, log, 0, |
599 "require_pv(\"%s\") failed: \"%V\"", script[i], &err); | 640 "require_pv(\"%s\") failed: \"%V\"", script[i], &err); |
600 goto fail; | 641 |
601 } | 642 return NGX_ERROR; |
602 } | 643 } |
603 | 644 } |
604 } | 645 |
605 | 646 return NGX_OK; |
606 pmcf->nalloc++; | |
607 | |
608 return perl; | |
609 | |
610 fail: | |
611 | |
612 (void) perl_destruct(perl); | |
613 | |
614 perl_free(perl); | |
615 | |
616 return NULL; | |
617 } | 647 } |
618 | 648 |
619 | 649 |
620 #if (__INTEL_COMPILER) | 650 #if (__INTEL_COMPILER) |
621 /* | 651 /* |
738 if (*p != ' ' && *p != '\t' && *p != CR && *p != LF) { | 768 if (*p != ' ' && *p != '\t' && *p != CR && *p != LF) { |
739 break; | 769 break; |
740 } | 770 } |
741 } | 771 } |
742 | 772 |
743 if (ngx_strncmp(p, "sub ", 4) == 0 | 773 if (ngx_strncmp(p, "sub ", 4) == 0 || ngx_strncmp(p, "use ", 4) == 0) { |
744 || ngx_strncmp(p, "use ", 4) == 0) | |
745 { | |
746 *sv = eval_pv((char *) p, FALSE); | 774 *sv = eval_pv((char *) p, FALSE); |
747 | |
748 return; | 775 return; |
749 } | 776 } |
750 | 777 |
751 *sv = NULL; | 778 *sv = NULL; |
752 } | 779 } |
803 | 830 |
804 return NGX_CONF_OK; | 831 return NGX_CONF_OK; |
805 } | 832 } |
806 | 833 |
807 | 834 |
835 #if (NGX_HAVE_PERL_CLONE || NGX_HAVE_PERL_MULTIPLICITY) | |
836 | |
808 static void | 837 static void |
809 ngx_http_perl_cleanup_perl(void *data) | 838 ngx_http_perl_cleanup_perl(void *data) |
810 { | 839 { |
811 PerlInterpreter *perl = data; | 840 PerlInterpreter *perl = data; |
812 | 841 |
813 (void) perl_destruct(perl); | 842 (void) perl_destruct(perl); |
814 | 843 |
815 perl_free(perl); | 844 perl_free(perl); |
816 | 845 |
817 PERL_SYS_TERM(); | 846 PERL_SYS_TERM(); |
847 } | |
848 | |
849 #endif | |
850 | |
851 | |
852 static void | |
853 ngx_http_perl_cleanup_sv(void *data) | |
854 { | |
855 SV *sv = data; | |
856 | |
857 SvREFCNT_dec(sv); | |
818 } | 858 } |
819 | 859 |
820 | 860 |
821 static ngx_int_t | 861 static ngx_int_t |
822 ngx_http_perl_preconfiguration(ngx_conf_t *cf) | 862 ngx_http_perl_preconfiguration(ngx_conf_t *cf) |
906 ngx_http_perl(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | 946 ngx_http_perl(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
907 { | 947 { |
908 ngx_http_perl_loc_conf_t *plcf = conf; | 948 ngx_http_perl_loc_conf_t *plcf = conf; |
909 | 949 |
910 ngx_str_t *value; | 950 ngx_str_t *value; |
951 ngx_pool_cleanup_t *cln; | |
911 ngx_http_core_loc_conf_t *clcf; | 952 ngx_http_core_loc_conf_t *clcf; |
912 ngx_http_perl_main_conf_t *pmcf; | 953 ngx_http_perl_main_conf_t *pmcf; |
913 | 954 |
914 value = cf->args->elts; | 955 value = cf->args->elts; |
915 | 956 |
925 if (ngx_http_perl_init_interpreter(cf, pmcf) != NGX_CONF_OK) { | 966 if (ngx_http_perl_init_interpreter(cf, pmcf) != NGX_CONF_OK) { |
926 return NGX_CONF_ERROR; | 967 return NGX_CONF_ERROR; |
927 } | 968 } |
928 } | 969 } |
929 | 970 |
971 cln = ngx_pool_cleanup_add(cf->pool, 0); | |
972 if (cln == NULL) { | |
973 return NGX_CONF_ERROR; | |
974 } | |
975 | |
930 plcf->handler = value[1]; | 976 plcf->handler = value[1]; |
931 | 977 |
932 { | 978 { |
933 | 979 |
934 dTHXa(pmcf->perl); | 980 dTHXa(pmcf->perl); |
945 plcf->sub = newSVpvn((char *) value[1].data, value[1].len); | 991 plcf->sub = newSVpvn((char *) value[1].data, value[1].len); |
946 } | 992 } |
947 | 993 |
948 } | 994 } |
949 | 995 |
996 cln->handler = ngx_http_perl_cleanup_sv; | |
997 cln->data = plcf->sub; | |
998 | |
950 clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); | 999 clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); |
951 clcf->handler = ngx_http_perl_handler; | 1000 clcf->handler = ngx_http_perl_handler; |
952 | 1001 |
953 return NGX_CONF_OK; | 1002 return NGX_CONF_OK; |
954 } | 1003 } |
957 static char * | 1006 static char * |
958 ngx_http_perl_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | 1007 ngx_http_perl_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
959 { | 1008 { |
960 ngx_int_t index; | 1009 ngx_int_t index; |
961 ngx_str_t *value; | 1010 ngx_str_t *value; |
1011 ngx_pool_cleanup_t *cln; | |
962 ngx_http_variable_t *v; | 1012 ngx_http_variable_t *v; |
963 ngx_http_perl_variable_t *pv; | 1013 ngx_http_perl_variable_t *pv; |
964 ngx_http_perl_main_conf_t *pmcf; | 1014 ngx_http_perl_main_conf_t *pmcf; |
965 | 1015 |
966 value = cf->args->elts; | 1016 value = cf->args->elts; |
995 if (ngx_http_perl_init_interpreter(cf, pmcf) != NGX_CONF_OK) { | 1045 if (ngx_http_perl_init_interpreter(cf, pmcf) != NGX_CONF_OK) { |
996 return NGX_CONF_ERROR; | 1046 return NGX_CONF_ERROR; |
997 } | 1047 } |
998 } | 1048 } |
999 | 1049 |
1050 cln = ngx_pool_cleanup_add(cf->pool, 0); | |
1051 if (cln == NULL) { | |
1052 return NGX_CONF_ERROR; | |
1053 } | |
1054 | |
1000 pv->handler = value[2]; | 1055 pv->handler = value[2]; |
1001 | 1056 |
1002 { | 1057 { |
1003 | 1058 |
1004 dTHXa(pmcf->perl); | 1059 dTHXa(pmcf->perl); |
1015 pv->sub = newSVpvn((char *) value[2].data, value[2].len); | 1070 pv->sub = newSVpvn((char *) value[2].data, value[2].len); |
1016 } | 1071 } |
1017 | 1072 |
1018 } | 1073 } |
1019 | 1074 |
1075 cln->handler = ngx_http_perl_cleanup_sv; | |
1076 cln->data = pv->sub; | |
1077 | |
1020 v->get_handler = ngx_http_perl_variable; | 1078 v->get_handler = ngx_http_perl_variable; |
1021 v->data = (uintptr_t) pv; | 1079 v->data = (uintptr_t) pv; |
1022 | 1080 |
1023 return NGX_CONF_OK; | 1081 return NGX_CONF_OK; |
1024 } | 1082 } |