Mercurial > hg > nginx-vendor-current
comparison src/http/modules/perl/ngx_http_perl_module.c @ 532:f7ec98e3caeb NGINX_0_8_18
nginx 0.8.18
*) Feature: the "read_ahead" directive.
*) Feature: now several "perl_modules" directive may be used.
*) 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: nginx did not work on Linux/sparc.
Thanks to Marcus Ramberg.
*) Bugfix: nginx sent '\0' in a "Location" response header line on
MKCOL request.
Thanks to Xie Zhenye.
*) Bugfix: zero status code was logged instead of 499 status code; the
bug had appeared in 0.8.11.
*) Bugfix: socket leak; the bug had appeared in 0.8.11.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Tue, 06 Oct 2009 00:00:00 +0400 |
parents | 005a70f9573b |
children | 697030d79811 |
comparison
equal
deleted
inserted
replaced
531:7688992d2abb | 532:f7ec98e3caeb |
---|---|
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, |
461 | 459 |
462 | 460 |
463 static char * | 461 static char * |
464 ngx_http_perl_init_interpreter(ngx_conf_t *cf, ngx_http_perl_main_conf_t *pmcf) | 462 ngx_http_perl_init_interpreter(ngx_conf_t *cf, ngx_http_perl_main_conf_t *pmcf) |
465 { | 463 { |
464 ngx_str_t *m; | |
465 ngx_uint_t i; | |
466 #if (NGX_HAVE_PERL_MULTIPLICITY) | 466 #if (NGX_HAVE_PERL_MULTIPLICITY) |
467 ngx_pool_cleanup_t *cln; | 467 ngx_pool_cleanup_t *cln; |
468 | 468 |
469 cln = ngx_pool_cleanup_add(cf->pool, 0); | 469 cln = ngx_pool_cleanup_add(cf->pool, 0); |
470 if (cln == NULL) { | 470 if (cln == NULL) { |
471 return NGX_CONF_ERROR; | 471 return NGX_CONF_ERROR; |
472 } | 472 } |
474 #else | 474 #else |
475 static PerlInterpreter *perl; | 475 static PerlInterpreter *perl; |
476 #endif | 476 #endif |
477 | 477 |
478 #ifdef NGX_PERL_MODULES | 478 #ifdef NGX_PERL_MODULES |
479 if (pmcf->modules.data == NULL) { | 479 if (pmcf->modules == NGX_CONF_UNSET_PTR) { |
480 pmcf->modules.data = NGX_PERL_MODULES; | 480 |
481 } | 481 pmcf->modules = ngx_array_create(cf->pool, 1, sizeof(ngx_str_t)); |
482 #endif | 482 if (pmcf->modules == NULL) { |
483 | |
484 if (pmcf->modules.data) { | |
485 if (ngx_conf_full_name(cf->cycle, &pmcf->modules, 0) != NGX_OK) { | |
486 return NGX_CONF_ERROR; | 483 return NGX_CONF_ERROR; |
484 } | |
485 | |
486 m = ngx_array_push(pmcf->modules); | |
487 if (m == NULL) { | |
488 return NGX_CONF_ERROR; | |
489 } | |
490 | |
491 m->len = sizeof(NGX_PERL_MODULES) - 1; | |
492 m->data = NGX_PERL_MODULES; | |
493 } | |
494 #endif | |
495 | |
496 if (pmcf->modules != NGX_CONF_UNSET_PTR) { | |
497 m = pmcf->modules->elts; | |
498 for (i = 0; i < pmcf->modules->nelts; i++) { | |
499 if (ngx_conf_full_name(cf->cycle, &m[i], 0) != NGX_OK) { | |
500 return NGX_CONF_ERROR; | |
501 } | |
487 } | 502 } |
488 } | 503 } |
489 | 504 |
490 #if !(NGX_HAVE_PERL_MULTIPLICITY) | 505 #if !(NGX_HAVE_PERL_MULTIPLICITY) |
491 | 506 |
493 | 508 |
494 if (ngx_set_environment(cf->cycle, NULL) == NULL) { | 509 if (ngx_set_environment(cf->cycle, NULL) == NULL) { |
495 return NGX_CONF_ERROR; | 510 return NGX_CONF_ERROR; |
496 } | 511 } |
497 | 512 |
498 if (ngx_http_perl_run_requires(aTHX_ &pmcf->requires, cf->log) | 513 if (ngx_http_perl_run_requires(aTHX_ pmcf->requires, cf->log) |
499 != NGX_OK) | 514 != NGX_OK) |
500 { | 515 { |
501 return NGX_CONF_ERROR; | 516 return NGX_CONF_ERROR; |
502 } | 517 } |
503 | 518 |
541 ngx_http_perl_main_conf_t *pmcf) | 556 ngx_http_perl_main_conf_t *pmcf) |
542 { | 557 { |
543 int n; | 558 int n; |
544 STRLEN len; | 559 STRLEN len; |
545 SV *sv; | 560 SV *sv; |
546 char *ver, *embedding[6]; | 561 char *ver, **embedding; |
562 ngx_str_t *m; | |
563 ngx_uint_t i; | |
547 PerlInterpreter *perl; | 564 PerlInterpreter *perl; |
548 | 565 |
549 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, cf->log, 0, "create perl interpreter"); | 566 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, cf->log, 0, "create perl interpreter"); |
550 | 567 |
551 if (ngx_set_environment(cf->cycle, NULL) == NULL) { | 568 if (ngx_set_environment(cf->cycle, NULL) == NULL) { |
567 | 584 |
568 #ifdef PERL_EXIT_DESTRUCT_END | 585 #ifdef PERL_EXIT_DESTRUCT_END |
569 PL_exit_flags |= PERL_EXIT_DESTRUCT_END; | 586 PL_exit_flags |= PERL_EXIT_DESTRUCT_END; |
570 #endif | 587 #endif |
571 | 588 |
589 n = (pmcf->modules != NGX_CONF_UNSET_PTR) ? pmcf->modules->nelts * 2 : 0; | |
590 | |
591 embedding = ngx_palloc(cf->pool, (4 + n) * sizeof(char *)); | |
592 if (embedding == NULL) { | |
593 goto fail; | |
594 } | |
595 | |
572 embedding[0] = ""; | 596 embedding[0] = ""; |
573 | 597 |
574 if (pmcf->modules.data) { | 598 if (n++) { |
575 embedding[1] = "-I"; | 599 m = pmcf->modules->elts; |
576 embedding[2] = (char *) pmcf->modules.data; | 600 for (i = 0; i < pmcf->modules->nelts; i++) { |
577 n = 3; | 601 embedding[2 * i + 1] = "-I"; |
578 | 602 embedding[2 * i + 2] = (char *) m[i].data; |
579 } else { | 603 } |
580 n = 1; | |
581 } | 604 } |
582 | 605 |
583 embedding[n++] = "-Mnginx"; | 606 embedding[n++] = "-Mnginx"; |
584 embedding[n++] = "-e"; | 607 embedding[n++] = "-e"; |
585 embedding[n++] = "0"; | 608 embedding[n++] = "0"; |
599 "version " NGINX_VERSION " of nginx.pm is required, " | 622 "version " NGINX_VERSION " of nginx.pm is required, " |
600 "but %s was found", ver); | 623 "but %s was found", ver); |
601 goto fail; | 624 goto fail; |
602 } | 625 } |
603 | 626 |
604 if (ngx_http_perl_run_requires(aTHX_ &pmcf->requires, cf->log) != NGX_OK) { | 627 if (ngx_http_perl_run_requires(aTHX_ pmcf->requires, cf->log) != NGX_OK) { |
605 goto fail; | 628 goto fail; |
606 } | 629 } |
607 | 630 |
608 } | 631 } |
609 | 632 |
620 | 643 |
621 | 644 |
622 static ngx_int_t | 645 static ngx_int_t |
623 ngx_http_perl_run_requires(pTHX_ ngx_array_t *requires, ngx_log_t *log) | 646 ngx_http_perl_run_requires(pTHX_ ngx_array_t *requires, ngx_log_t *log) |
624 { | 647 { |
625 char **script; | 648 u_char *err; |
626 STRLEN len; | 649 STRLEN len; |
627 ngx_str_t err; | 650 ngx_str_t *script; |
628 ngx_uint_t i; | 651 ngx_uint_t i; |
652 | |
653 if (requires == NGX_CONF_UNSET_PTR) { | |
654 return NGX_OK; | |
655 } | |
629 | 656 |
630 script = requires->elts; | 657 script = requires->elts; |
631 for (i = 0; i < requires->nelts; i++) { | 658 for (i = 0; i < requires->nelts; i++) { |
632 | 659 |
633 require_pv(script[i]); | 660 require_pv((char *) script[i].data); |
634 | 661 |
635 if (SvTRUE(ERRSV)) { | 662 if (SvTRUE(ERRSV)) { |
636 | 663 |
637 err.data = (u_char *) SvPV(ERRSV, len); | 664 err = (u_char *) SvPV(ERRSV, len); |
638 for (len--; err.data[len] == LF || err.data[len] == CR; len--) { | 665 while (--len && (err[len] == CR || err[len] == LF)) { /* void */ } |
639 /* void */ | |
640 } | |
641 err.len = len + 1; | |
642 | 666 |
643 ngx_log_error(NGX_LOG_EMERG, log, 0, | 667 ngx_log_error(NGX_LOG_EMERG, log, 0, |
644 "require_pv(\"%s\") failed: \"%V\"", script[i], &err); | 668 "require_pv(\"%s\") failed: \"%*s\"", |
669 script[i].data, len + 1, err); | |
645 | 670 |
646 return NGX_ERROR; | 671 return NGX_ERROR; |
647 } | 672 } |
648 } | 673 } |
649 | 674 |
656 SV **args, ngx_str_t *handler, ngx_str_t *rv) | 681 SV **args, ngx_str_t *handler, ngx_str_t *rv) |
657 { | 682 { |
658 SV *sv; | 683 SV *sv; |
659 int n, status; | 684 int n, status; |
660 char *line; | 685 char *line; |
686 u_char *err; | |
661 STRLEN len, n_a; | 687 STRLEN len, n_a; |
662 ngx_str_t err; | |
663 ngx_uint_t i; | 688 ngx_uint_t i; |
664 ngx_connection_t *c; | 689 ngx_connection_t *c; |
665 | 690 |
666 dSP; | 691 dSP; |
667 | 692 |
718 | 743 |
719 /* check $@ */ | 744 /* check $@ */ |
720 | 745 |
721 if (SvTRUE(ERRSV)) { | 746 if (SvTRUE(ERRSV)) { |
722 | 747 |
723 err.data = (u_char *) SvPV(ERRSV, len); | 748 err = (u_char *) SvPV(ERRSV, len); |
724 for (len--; err.data[len] == LF || err.data[len] == CR; len--) { | 749 while (--len && (err[len] == CR || err[len] == LF)) { /* void */ } |
725 /* void */ | |
726 } | |
727 err.len = len + 1; | |
728 | 750 |
729 ngx_log_error(NGX_LOG_ERR, c->log, 0, | 751 ngx_log_error(NGX_LOG_ERR, c->log, 0, |
730 "call_sv(\"%V\") failed: \"%V\"", handler, &err); | 752 "call_sv(\"%V\") failed: \"%*s\"", handler, len + 1, err); |
731 | 753 |
732 if (rv) { | 754 if (rv) { |
733 return NGX_ERROR; | 755 return NGX_ERROR; |
734 } | 756 } |
735 | 757 |
784 pmcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_perl_main_conf_t)); | 806 pmcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_perl_main_conf_t)); |
785 if (pmcf == NULL) { | 807 if (pmcf == NULL) { |
786 return NULL; | 808 return NULL; |
787 } | 809 } |
788 | 810 |
789 if (ngx_array_init(&pmcf->requires, cf->pool, 1, sizeof(u_char *)) | 811 pmcf->modules = NGX_CONF_UNSET_PTR; |
790 != NGX_OK) | 812 pmcf->requires = NGX_CONF_UNSET_PTR; |
791 { | |
792 return NULL; | |
793 } | |
794 | 813 |
795 return pmcf; | 814 return pmcf; |
796 } | 815 } |
797 | 816 |
798 | 817 |
895 return NGX_CONF_OK; | 914 return NGX_CONF_OK; |
896 } | 915 } |
897 | 916 |
898 | 917 |
899 static char * | 918 static char * |
900 ngx_http_perl_require(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
901 { | |
902 ngx_http_perl_main_conf_t *pmcf = conf; | |
903 | |
904 u_char **p; | |
905 ngx_str_t *value; | |
906 | |
907 value = cf->args->elts; | |
908 | |
909 p = ngx_array_push(&pmcf->requires); | |
910 | |
911 if (p == NULL) { | |
912 return NGX_CONF_ERROR; | |
913 } | |
914 | |
915 *p = value[1].data; | |
916 | |
917 return NGX_CONF_OK; | |
918 } | |
919 | |
920 | |
921 static char * | |
922 ngx_http_perl(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | 919 ngx_http_perl(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
923 { | 920 { |
924 ngx_http_perl_loc_conf_t *plcf = conf; | 921 ngx_http_perl_loc_conf_t *plcf = conf; |
925 | 922 |
926 ngx_str_t *value; | 923 ngx_str_t *value; |