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;