comparison src/http/modules/perl/ngx_http_perl_module.c @ 665:0b460e61bdcd default tip

Merge with nginx 1.0.0.
author Maxim Dounin <mdounin@mdounin.ru>
date Mon, 25 Apr 2011 04:22:17 +0400
parents ff463db0be31
children
comparison
equal deleted inserted replaced
572:06419a2298a9 665:0b460e61bdcd
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;
26 26
27 typedef struct { 27 typedef struct {
28 SV *sub; 28 SV *sub;
29 ngx_str_t handler; 29 ngx_str_t handler;
30 } ngx_http_perl_variable_t; 30 } ngx_http_perl_variable_t;
31
32
33 typedef struct {
34 SV *sv;
35 PerlInterpreter *perl;
36 } ngx_http_perl_cleanup_t;
37 31
38 32
39 #if (NGX_HTTP_SSI) 33 #if (NGX_HTTP_SSI)
40 static ngx_int_t ngx_http_perl_ssi(ngx_http_request_t *r, 34 static ngx_int_t ngx_http_perl_ssi(ngx_http_request_t *r,
41 ngx_http_ssi_ctx_t *ssi_ctx, ngx_str_t **params); 35 ngx_http_ssi_ctx_t *ssi_ctx, ngx_str_t **params);
55 static void *ngx_http_perl_create_main_conf(ngx_conf_t *cf); 49 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); 50 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); 51 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, 52 static char *ngx_http_perl_merge_loc_conf(ngx_conf_t *cf, void *parent,
59 void *child); 53 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); 54 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); 55 static char *ngx_http_perl_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
64 56
65 #if (NGX_HAVE_PERL_MULTIPLICITY) 57 #if (NGX_HAVE_PERL_MULTIPLICITY)
66 static void ngx_http_perl_cleanup_perl(void *data); 58 static void ngx_http_perl_cleanup_perl(void *data);
72 64
73 static ngx_command_t ngx_http_perl_commands[] = { 65 static ngx_command_t ngx_http_perl_commands[] = {
74 66
75 { ngx_string("perl_modules"), 67 { ngx_string("perl_modules"),
76 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1, 68 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
77 ngx_conf_set_str_slot, 69 ngx_conf_set_str_array_slot,
78 NGX_HTTP_MAIN_CONF_OFFSET, 70 NGX_HTTP_MAIN_CONF_OFFSET,
79 offsetof(ngx_http_perl_main_conf_t, modules), 71 offsetof(ngx_http_perl_main_conf_t, modules),
80 NULL }, 72 NULL },
81 73
82 { ngx_string("perl_require"), 74 { ngx_string("perl_require"),
83 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1, 75 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
84 ngx_http_perl_require, 76 ngx_conf_set_str_array_slot,
85 NGX_HTTP_MAIN_CONF_OFFSET, 77 NGX_HTTP_MAIN_CONF_OFFSET,
86 0, 78 offsetof(ngx_http_perl_main_conf_t, requires),
87 NULL }, 79 NULL },
88 80
89 { ngx_string("perl"), 81 { ngx_string("perl"),
90 NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF|NGX_CONF_TAKE1, 82 NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF|NGX_CONF_TAKE1,
91 ngx_http_perl, 83 ngx_http_perl,
152 }; 144 };
153 145
154 #endif 146 #endif
155 147
156 148
157 static ngx_str_t ngx_null_name = ngx_null_string; 149 static ngx_str_t ngx_null_name = ngx_null_string;
158 150 static HV *nginx_stash;
159 static HV *nginx_stash;
160 151
161 #if (NGX_HAVE_PERL_MULTIPLICITY) 152 #if (NGX_HAVE_PERL_MULTIPLICITY)
162 static ngx_uint_t ngx_perl_term; 153 static ngx_uint_t ngx_perl_term;
154 #else
155 static PerlInterpreter *perl;
163 #endif 156 #endif
164 157
165 158
166 static void 159 static void
167 ngx_http_perl_xs_init(pTHX) 160 ngx_http_perl_xs_init(pTHX)
173 166
174 167
175 static ngx_int_t 168 static ngx_int_t
176 ngx_http_perl_handler(ngx_http_request_t *r) 169 ngx_http_perl_handler(ngx_http_request_t *r)
177 { 170 {
178 if (r->zero_in_uri) {
179 return NGX_HTTP_NOT_FOUND;
180 }
181
182 r->main->count++; 171 r->main->count++;
183 172
184 ngx_http_perl_handle_request(r); 173 ngx_http_perl_handle_request(r);
185 174
186 return NGX_DONE; 175 return NGX_DONE;
461 450
462 451
463 static char * 452 static char *
464 ngx_http_perl_init_interpreter(ngx_conf_t *cf, ngx_http_perl_main_conf_t *pmcf) 453 ngx_http_perl_init_interpreter(ngx_conf_t *cf, ngx_http_perl_main_conf_t *pmcf)
465 { 454 {
455 ngx_str_t *m;
456 ngx_uint_t i;
466 #if (NGX_HAVE_PERL_MULTIPLICITY) 457 #if (NGX_HAVE_PERL_MULTIPLICITY)
467 ngx_pool_cleanup_t *cln; 458 ngx_pool_cleanup_t *cln;
468 459
469 cln = ngx_pool_cleanup_add(cf->pool, 0); 460 cln = ngx_pool_cleanup_add(cf->pool, 0);
470 if (cln == NULL) { 461 if (cln == NULL) {
471 return NGX_CONF_ERROR; 462 return NGX_CONF_ERROR;
472 } 463 }
473 464
474 #else
475 static PerlInterpreter *perl;
476 #endif 465 #endif
477 466
478 #ifdef NGX_PERL_MODULES 467 #ifdef NGX_PERL_MODULES
479 if (pmcf->modules.data == NULL) { 468 if (pmcf->modules == NGX_CONF_UNSET_PTR) {
480 pmcf->modules.data = NGX_PERL_MODULES; 469
481 } 470 pmcf->modules = ngx_array_create(cf->pool, 1, sizeof(ngx_str_t));
482 #endif 471 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; 472 return NGX_CONF_ERROR;
473 }
474
475 m = ngx_array_push(pmcf->modules);
476 if (m == NULL) {
477 return NGX_CONF_ERROR;
478 }
479
480 ngx_str_set(m, NGX_PERL_MODULES);
481 }
482 #endif
483
484 if (pmcf->modules != NGX_CONF_UNSET_PTR) {
485 m = pmcf->modules->elts;
486 for (i = 0; i < pmcf->modules->nelts; i++) {
487 if (ngx_conf_full_name(cf->cycle, &m[i], 0) != NGX_OK) {
488 return NGX_CONF_ERROR;
489 }
487 } 490 }
488 } 491 }
489 492
490 #if !(NGX_HAVE_PERL_MULTIPLICITY) 493 #if !(NGX_HAVE_PERL_MULTIPLICITY)
491 494
493 496
494 if (ngx_set_environment(cf->cycle, NULL) == NULL) { 497 if (ngx_set_environment(cf->cycle, NULL) == NULL) {
495 return NGX_CONF_ERROR; 498 return NGX_CONF_ERROR;
496 } 499 }
497 500
498 if (ngx_http_perl_run_requires(aTHX_ &pmcf->requires, cf->log) 501 if (ngx_http_perl_run_requires(aTHX_ pmcf->requires, cf->log)
499 != NGX_OK) 502 != NGX_OK)
500 { 503 {
501 return NGX_CONF_ERROR; 504 return NGX_CONF_ERROR;
502 } 505 }
503 506
541 ngx_http_perl_main_conf_t *pmcf) 544 ngx_http_perl_main_conf_t *pmcf)
542 { 545 {
543 int n; 546 int n;
544 STRLEN len; 547 STRLEN len;
545 SV *sv; 548 SV *sv;
546 char *ver, *embedding[6]; 549 char *ver, **embedding;
550 ngx_str_t *m;
551 ngx_uint_t i;
547 PerlInterpreter *perl; 552 PerlInterpreter *perl;
548 553
549 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, cf->log, 0, "create perl interpreter"); 554 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, cf->log, 0, "create perl interpreter");
550 555
551 if (ngx_set_environment(cf->cycle, NULL) == NULL) { 556 if (ngx_set_environment(cf->cycle, NULL) == NULL) {
567 572
568 #ifdef PERL_EXIT_DESTRUCT_END 573 #ifdef PERL_EXIT_DESTRUCT_END
569 PL_exit_flags |= PERL_EXIT_DESTRUCT_END; 574 PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
570 #endif 575 #endif
571 576
577 n = (pmcf->modules != NGX_CONF_UNSET_PTR) ? pmcf->modules->nelts * 2 : 0;
578
579 embedding = ngx_palloc(cf->pool, (4 + n) * sizeof(char *));
580 if (embedding == NULL) {
581 goto fail;
582 }
583
572 embedding[0] = ""; 584 embedding[0] = "";
573 585
574 if (pmcf->modules.data) { 586 if (n++) {
575 embedding[1] = "-I"; 587 m = pmcf->modules->elts;
576 embedding[2] = (char *) pmcf->modules.data; 588 for (i = 0; i < pmcf->modules->nelts; i++) {
577 n = 3; 589 embedding[2 * i + 1] = "-I";
578 590 embedding[2 * i + 2] = (char *) m[i].data;
579 } else { 591 }
580 n = 1;
581 } 592 }
582 593
583 embedding[n++] = "-Mnginx"; 594 embedding[n++] = "-Mnginx";
584 embedding[n++] = "-e"; 595 embedding[n++] = "-e";
585 embedding[n++] = "0"; 596 embedding[n++] = "0";
599 "version " NGINX_VERSION " of nginx.pm is required, " 610 "version " NGINX_VERSION " of nginx.pm is required, "
600 "but %s was found", ver); 611 "but %s was found", ver);
601 goto fail; 612 goto fail;
602 } 613 }
603 614
604 if (ngx_http_perl_run_requires(aTHX_ &pmcf->requires, cf->log) != NGX_OK) { 615 if (ngx_http_perl_run_requires(aTHX_ pmcf->requires, cf->log) != NGX_OK) {
605 goto fail; 616 goto fail;
606 } 617 }
607 618
608 } 619 }
609 620
620 631
621 632
622 static ngx_int_t 633 static ngx_int_t
623 ngx_http_perl_run_requires(pTHX_ ngx_array_t *requires, ngx_log_t *log) 634 ngx_http_perl_run_requires(pTHX_ ngx_array_t *requires, ngx_log_t *log)
624 { 635 {
625 char **script; 636 u_char *err;
626 STRLEN len; 637 STRLEN len;
627 ngx_str_t err; 638 ngx_str_t *script;
628 ngx_uint_t i; 639 ngx_uint_t i;
640
641 if (requires == NGX_CONF_UNSET_PTR) {
642 return NGX_OK;
643 }
629 644
630 script = requires->elts; 645 script = requires->elts;
631 for (i = 0; i < requires->nelts; i++) { 646 for (i = 0; i < requires->nelts; i++) {
632 647
633 require_pv(script[i]); 648 require_pv((char *) script[i].data);
634 649
635 if (SvTRUE(ERRSV)) { 650 if (SvTRUE(ERRSV)) {
636 651
637 err.data = (u_char *) SvPV(ERRSV, len); 652 err = (u_char *) SvPV(ERRSV, len);
638 for (len--; err.data[len] == LF || err.data[len] == CR; len--) { 653 while (--len && (err[len] == CR || err[len] == LF)) { /* void */ }
639 /* void */
640 }
641 err.len = len + 1;
642 654
643 ngx_log_error(NGX_LOG_EMERG, log, 0, 655 ngx_log_error(NGX_LOG_EMERG, log, 0,
644 "require_pv(\"%s\") failed: \"%V\"", script[i], &err); 656 "require_pv(\"%s\") failed: \"%*s\"",
657 script[i].data, len + 1, err);
645 658
646 return NGX_ERROR; 659 return NGX_ERROR;
647 } 660 }
648 } 661 }
649 662
656 SV **args, ngx_str_t *handler, ngx_str_t *rv) 669 SV **args, ngx_str_t *handler, ngx_str_t *rv)
657 { 670 {
658 SV *sv; 671 SV *sv;
659 int n, status; 672 int n, status;
660 char *line; 673 char *line;
674 u_char *err;
661 STRLEN len, n_a; 675 STRLEN len, n_a;
662 ngx_str_t err;
663 ngx_uint_t i; 676 ngx_uint_t i;
664 ngx_connection_t *c; 677 ngx_connection_t *c;
665 678
666 dSP; 679 dSP;
667 680
718 731
719 /* check $@ */ 732 /* check $@ */
720 733
721 if (SvTRUE(ERRSV)) { 734 if (SvTRUE(ERRSV)) {
722 735
723 err.data = (u_char *) SvPV(ERRSV, len); 736 err = (u_char *) SvPV(ERRSV, len);
724 for (len--; err.data[len] == LF || err.data[len] == CR; len--) { 737 while (--len && (err[len] == CR || err[len] == LF)) { /* void */ }
725 /* void */
726 }
727 err.len = len + 1;
728 738
729 ngx_log_error(NGX_LOG_ERR, c->log, 0, 739 ngx_log_error(NGX_LOG_ERR, c->log, 0,
730 "call_sv(\"%V\") failed: \"%V\"", handler, &err); 740 "call_sv(\"%V\") failed: \"%*s\"", handler, len + 1, err);
731 741
732 if (rv) { 742 if (rv) {
733 return NGX_ERROR; 743 return NGX_ERROR;
734 } 744 }
735 745
784 pmcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_perl_main_conf_t)); 794 pmcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_perl_main_conf_t));
785 if (pmcf == NULL) { 795 if (pmcf == NULL) {
786 return NULL; 796 return NULL;
787 } 797 }
788 798
789 if (ngx_array_init(&pmcf->requires, cf->pool, 1, sizeof(u_char *)) 799 pmcf->modules = NGX_CONF_UNSET_PTR;
790 != NGX_OK) 800 pmcf->requires = NGX_CONF_UNSET_PTR;
791 {
792 return NULL;
793 }
794 801
795 return pmcf; 802 return pmcf;
796 } 803 }
797 804
798 805
895 return NGX_CONF_OK; 902 return NGX_CONF_OK;
896 } 903 }
897 904
898 905
899 static char * 906 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) 907 ngx_http_perl(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
923 { 908 {
924 ngx_http_perl_loc_conf_t *plcf = conf; 909 ngx_http_perl_loc_conf_t *plcf = conf;
925 910
926 ngx_str_t *value; 911 ngx_str_t *value;
1065 static void 1050 static void
1066 ngx_http_perl_exit(ngx_cycle_t *cycle) 1051 ngx_http_perl_exit(ngx_cycle_t *cycle)
1067 { 1052 {
1068 #if (NGX_HAVE_PERL_MULTIPLICITY) 1053 #if (NGX_HAVE_PERL_MULTIPLICITY)
1069 1054
1055 /*
1056 * the master exit hook is run before global pool cleanup,
1057 * therefore just set flag here
1058 */
1059
1070 ngx_perl_term = 1; 1060 ngx_perl_term = 1;
1071 1061
1072 #else 1062 #else
1073 ngx_http_perl_main_conf_t *pmcf; 1063
1074 1064 if (nginx_stash) {
1075 pmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_perl_module);
1076
1077 if (pmcf && nginx_stash) {
1078 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, cycle->log, 0, "perl term"); 1065 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, cycle->log, 0, "perl term");
1079 1066
1080 (void) perl_destruct(pmcf->perl); 1067 (void) perl_destruct(perl);
1081 1068
1082 perl_free(pmcf->perl); 1069 perl_free(perl);
1083 1070
1084 PERL_SYS_TERM(); 1071 PERL_SYS_TERM();
1085 } 1072 }
1086 1073
1087 #endif 1074 #endif