3 * Copyright (C) Igor Sysoev
4 * Copyright (C) Nginx, Inc.
8 #include <ngx_config.h>
11 #include <ngx_http_perl_module.h>
15 PerlInterpreter
*perl
;
18 ngx_array_t
*requires
;
19 } ngx_http_perl_main_conf_t
;
25 } ngx_http_perl_loc_conf_t
;
31 } ngx_http_perl_variable_t
;
35 static ngx_int_t
ngx_http_perl_ssi(ngx_http_request_t
*r
,
36 ngx_http_ssi_ctx_t
*ssi_ctx
, ngx_str_t
**params
);
39 static char *ngx_http_perl_init_interpreter(ngx_conf_t
*cf
,
40 ngx_http_perl_main_conf_t
*pmcf
);
41 static PerlInterpreter
*ngx_http_perl_create_interpreter(ngx_conf_t
*cf
,
42 ngx_http_perl_main_conf_t
*pmcf
);
43 static ngx_int_t
ngx_http_perl_run_requires(pTHX_ ngx_array_t
*requires
,
45 static ngx_int_t
ngx_http_perl_call_handler(pTHX_ ngx_http_request_t
*r
,
46 HV
*nginx
, SV
*sub
, SV
**args
, ngx_str_t
*handler
, ngx_str_t
*rv
);
47 static void ngx_http_perl_eval_anon_sub(pTHX_ ngx_str_t
*handler
, SV
**sv
);
49 static ngx_int_t
ngx_http_perl_preconfiguration(ngx_conf_t
*cf
);
50 static void *ngx_http_perl_create_main_conf(ngx_conf_t
*cf
);
51 static char *ngx_http_perl_init_main_conf(ngx_conf_t
*cf
, void *conf
);
52 static void *ngx_http_perl_create_loc_conf(ngx_conf_t
*cf
);
53 static char *ngx_http_perl_merge_loc_conf(ngx_conf_t
*cf
, void *parent
,
55 static char *ngx_http_perl(ngx_conf_t
*cf
, ngx_command_t
*cmd
, void *conf
);
56 static char *ngx_http_perl_set(ngx_conf_t
*cf
, ngx_command_t
*cmd
, void *conf
);
58 #if (NGX_HAVE_PERL_MULTIPLICITY)
59 static void ngx_http_perl_cleanup_perl(void *data
);
62 static ngx_int_t
ngx_http_perl_init_worker(ngx_cycle_t
*cycle
);
63 static void ngx_http_perl_exit(ngx_cycle_t
*cycle
);
66 static ngx_command_t ngx_http_perl_commands
[] = {
68 { ngx_string("perl_modules"),
69 NGX_HTTP_MAIN_CONF
|NGX_CONF_TAKE1
,
70 ngx_conf_set_str_array_slot
,
71 NGX_HTTP_MAIN_CONF_OFFSET
,
72 offsetof(ngx_http_perl_main_conf_t
, modules
),
75 { ngx_string("perl_require"),
76 NGX_HTTP_MAIN_CONF
|NGX_CONF_TAKE1
,
77 ngx_conf_set_str_array_slot
,
78 NGX_HTTP_MAIN_CONF_OFFSET
,
79 offsetof(ngx_http_perl_main_conf_t
, requires
),
83 NGX_HTTP_LOC_CONF
|NGX_HTTP_LMT_CONF
|NGX_CONF_TAKE1
,
85 NGX_HTTP_LOC_CONF_OFFSET
,
89 { ngx_string("perl_set"),
90 NGX_HTTP_MAIN_CONF
|NGX_CONF_TAKE2
,
92 NGX_HTTP_LOC_CONF_OFFSET
,
100 static ngx_http_module_t ngx_http_perl_module_ctx
= {
101 ngx_http_perl_preconfiguration
, /* preconfiguration */
102 NULL
, /* postconfiguration */
104 ngx_http_perl_create_main_conf
, /* create main configuration */
105 ngx_http_perl_init_main_conf
, /* init main configuration */
107 NULL
, /* create server configuration */
108 NULL
, /* merge server configuration */
110 ngx_http_perl_create_loc_conf
, /* create location configuration */
111 ngx_http_perl_merge_loc_conf
/* merge location configuration */
115 ngx_module_t ngx_http_perl_module
= {
117 &ngx_http_perl_module_ctx
, /* module context */
118 ngx_http_perl_commands
, /* module directives */
119 NGX_HTTP_MODULE
, /* module type */
120 NULL
, /* init master */
121 NULL
, /* init module */
122 ngx_http_perl_init_worker
, /* init process */
123 NULL
, /* init thread */
124 NULL
, /* exit thread */
125 NULL
, /* exit process */
126 ngx_http_perl_exit
, /* exit master */
127 NGX_MODULE_V1_PADDING
133 #define NGX_HTTP_PERL_SSI_SUB 0
134 #define NGX_HTTP_PERL_SSI_ARG 1
137 static ngx_http_ssi_param_t ngx_http_perl_ssi_params
[] = {
138 { ngx_string("sub"), NGX_HTTP_PERL_SSI_SUB
, 1, 0 },
139 { ngx_string("arg"), NGX_HTTP_PERL_SSI_ARG
, 0, 1 },
140 { ngx_null_string
, 0, 0, 0 }
143 static ngx_http_ssi_command_t ngx_http_perl_ssi_command
= {
144 ngx_string("perl"), ngx_http_perl_ssi
, ngx_http_perl_ssi_params
, 0, 0, 1
150 static ngx_str_t ngx_null_name
= ngx_null_string
;
151 static HV
*nginx_stash
;
153 #if (NGX_HAVE_PERL_MULTIPLICITY)
154 static ngx_uint_t ngx_perl_term
;
156 static PerlInterpreter
*perl
;
161 ngx_http_perl_xs_init(pTHX
)
163 newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader
, __FILE__
);
165 nginx_stash
= gv_stashpv("nginx", TRUE
);
170 ngx_http_perl_handler(ngx_http_request_t
*r
)
174 ngx_http_perl_handle_request(r
);
181 ngx_http_perl_handle_request(ngx_http_request_t
*r
)
185 ngx_str_t uri
, args
, *handler
;
186 ngx_http_perl_ctx_t
*ctx
;
187 ngx_http_perl_loc_conf_t
*plcf
;
188 ngx_http_perl_main_conf_t
*pmcf
;
190 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0, "perl handler");
192 ctx
= ngx_http_get_module_ctx(r
, ngx_http_perl_module
);
195 ctx
= ngx_pcalloc(r
->pool
, sizeof(ngx_http_perl_ctx_t
));
197 ngx_http_finalize_request(r
, NGX_ERROR
);
201 ngx_http_set_ctx(r
, ctx
, ngx_http_perl_module
);
204 pmcf
= ngx_http_get_module_main_conf(r
, ngx_http_perl_module
);
209 PERL_SET_CONTEXT(pmcf
->perl
);
211 if (ctx
->next
== NULL
) {
212 plcf
= ngx_http_get_module_loc_conf(r
, ngx_http_perl_module
);
214 handler
= &plcf
->handler
;
218 handler
= &ngx_null_name
;
222 rc
= ngx_http_perl_call_handler(aTHX_ r
, pmcf
->nginx
, sub
, NULL
, handler
,
227 ngx_log_debug1(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0,
228 "perl handler done: %i", rc
);
230 if (rc
== NGX_DONE
) {
231 ngx_http_finalize_request(r
, rc
);
239 if (ctx
->redirect_uri
.len
) {
240 uri
= ctx
->redirect_uri
;
241 args
= ctx
->redirect_args
;
247 ctx
->filename
.data
= NULL
;
248 ctx
->redirect_uri
.len
= 0;
250 if (ctx
->done
|| ctx
->next
) {
251 ngx_http_finalize_request(r
, NGX_DONE
);
256 ngx_http_internal_redirect(r
, &uri
, &args
);
257 ngx_http_finalize_request(r
, NGX_DONE
);
261 if (rc
== NGX_OK
|| rc
== NGX_HTTP_OK
) {
262 ngx_http_send_special(r
, NGX_HTTP_LAST
);
266 ngx_http_finalize_request(r
, rc
);
271 ngx_http_perl_sleep_handler(ngx_http_request_t
*r
)
275 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0,
276 "perl sleep handler");
278 wev
= r
->connection
->write
;
282 ngx_http_perl_handle_request(r
);
286 if (ngx_handle_write_event(wev
, 0) != NGX_OK
) {
287 ngx_http_finalize_request(r
, NGX_HTTP_INTERNAL_SERVER_ERROR
);
293 ngx_http_perl_variable(ngx_http_request_t
*r
, ngx_http_variable_value_t
*v
,
296 ngx_http_perl_variable_t
*pv
= (ngx_http_perl_variable_t
*) data
;
300 ngx_http_perl_ctx_t
*ctx
;
301 ngx_http_perl_main_conf_t
*pmcf
;
303 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0,
304 "perl variable handler");
306 ctx
= ngx_http_get_module_ctx(r
, ngx_http_perl_module
);
309 ctx
= ngx_pcalloc(r
->pool
, sizeof(ngx_http_perl_ctx_t
));
314 ngx_http_set_ctx(r
, ctx
, ngx_http_perl_module
);
317 pmcf
= ngx_http_get_module_main_conf(r
, ngx_http_perl_module
);
324 PERL_SET_CONTEXT(pmcf
->perl
);
326 rc
= ngx_http_perl_call_handler(aTHX_ r
, pmcf
->nginx
, pv
->sub
, NULL
,
327 &pv
->handler
, &value
);
336 v
->data
= value
.data
;
342 ctx
->filename
.data
= NULL
;
343 ctx
->redirect_uri
.len
= 0;
345 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0,
346 "perl variable done");
355 ngx_http_perl_ssi(ngx_http_request_t
*r
, ngx_http_ssi_ctx_t
*ssi_ctx
,
360 ngx_str_t
*handler
, **args
;
362 ngx_http_perl_ctx_t
*ctx
;
363 ngx_http_perl_main_conf_t
*pmcf
;
365 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0,
368 ctx
= ngx_http_get_module_ctx(r
, ngx_http_perl_module
);
371 ctx
= ngx_pcalloc(r
->pool
, sizeof(ngx_http_perl_ctx_t
));
376 ngx_http_set_ctx(r
, ctx
, ngx_http_perl_module
);
379 pmcf
= ngx_http_get_module_main_conf(r
, ngx_http_perl_module
);
383 handler
= params
[NGX_HTTP_PERL_SSI_SUB
];
384 handler
->data
[handler
->len
] = '\0';
389 PERL_SET_CONTEXT(pmcf
->perl
);
393 /* the code is disabled to force the precompiled perl code using only */
395 ngx_http_perl_eval_anon_sub(aTHX_ handler
, &sv
);
397 if (sv
== &PL_sv_undef
) {
398 ngx_log_error(NGX_LOG_ERR
, r
->connection
->log
, 0,
399 "eval_pv(\"%V\") failed", handler
);
404 sv
= newSVpvn((char *) handler
->data
, handler
->len
);
409 sv
= newSVpvn((char *) handler
->data
, handler
->len
);
411 args
= ¶ms
[NGX_HTTP_PERL_SSI_ARG
];
415 for (i
= 0; args
[i
]; i
++) { /* void */ }
417 asv
= ngx_pcalloc(r
->pool
, (i
+ 1) * sizeof(SV
*));
426 for (i
= 0; args
[i
]; i
++) {
427 asv
[i
+ 1] = newSVpvn((char *) args
[i
]->data
, args
[i
]->len
);
434 rc
= ngx_http_perl_call_handler(aTHX_ r
, pmcf
->nginx
, sv
, asv
, handler
,
441 ctx
->filename
.data
= NULL
;
442 ctx
->redirect_uri
.len
= 0;
445 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0, "perl ssi done");
454 ngx_http_perl_init_interpreter(ngx_conf_t
*cf
, ngx_http_perl_main_conf_t
*pmcf
)
458 #if (NGX_HAVE_PERL_MULTIPLICITY)
459 ngx_pool_cleanup_t
*cln
;
461 cln
= ngx_pool_cleanup_add(cf
->pool
, 0);
463 return NGX_CONF_ERROR
;
468 #ifdef NGX_PERL_MODULES
469 if (pmcf
->modules
== NGX_CONF_UNSET_PTR
) {
471 pmcf
->modules
= ngx_array_create(cf
->pool
, 1, sizeof(ngx_str_t
));
472 if (pmcf
->modules
== NULL
) {
473 return NGX_CONF_ERROR
;
476 m
= ngx_array_push(pmcf
->modules
);
478 return NGX_CONF_ERROR
;
481 ngx_str_set(m
, NGX_PERL_MODULES
);
485 if (pmcf
->modules
!= NGX_CONF_UNSET_PTR
) {
486 m
= pmcf
->modules
->elts
;
487 for (i
= 0; i
< pmcf
->modules
->nelts
; i
++) {
488 if (ngx_conf_full_name(cf
->cycle
, &m
[i
], 0) != NGX_OK
) {
489 return NGX_CONF_ERROR
;
494 #if !(NGX_HAVE_PERL_MULTIPLICITY)
498 if (ngx_set_environment(cf
->cycle
, NULL
) == NULL
) {
499 return NGX_CONF_ERROR
;
502 if (ngx_http_perl_run_requires(aTHX_ pmcf
->requires
, cf
->log
)
505 return NGX_CONF_ERROR
;
509 pmcf
->nginx
= nginx_stash
;
516 if (nginx_stash
== NULL
) {
517 PERL_SYS_INIT(&ngx_argc
, &ngx_argv
);
520 pmcf
->perl
= ngx_http_perl_create_interpreter(cf
, pmcf
);
522 if (pmcf
->perl
== NULL
) {
523 return NGX_CONF_ERROR
;
526 pmcf
->nginx
= nginx_stash
;
528 #if (NGX_HAVE_PERL_MULTIPLICITY)
530 cln
->handler
= ngx_http_perl_cleanup_perl
;
531 cln
->data
= pmcf
->perl
;
543 static PerlInterpreter
*
544 ngx_http_perl_create_interpreter(ngx_conf_t
*cf
,
545 ngx_http_perl_main_conf_t
*pmcf
)
550 char *ver
, **embedding
;
553 PerlInterpreter
*perl
;
555 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, cf
->log
, 0, "create perl interpreter");
557 if (ngx_set_environment(cf
->cycle
, NULL
) == NULL
) {
563 ngx_log_error(NGX_LOG_ALERT
, cf
->log
, 0, "perl_alloc() failed");
570 PERL_SET_CONTEXT(perl
);
572 perl_construct(perl
);
574 #ifdef PERL_EXIT_DESTRUCT_END
575 PL_exit_flags
|= PERL_EXIT_DESTRUCT_END
;
578 n
= (pmcf
->modules
!= NGX_CONF_UNSET_PTR
) ? pmcf
->modules
->nelts
* 2 : 0;
580 embedding
= ngx_palloc(cf
->pool
, (4 + n
) * sizeof(char *));
581 if (embedding
== NULL
) {
588 m
= pmcf
->modules
->elts
;
589 for (i
= 0; i
< pmcf
->modules
->nelts
; i
++) {
590 embedding
[2 * i
+ 1] = "-I";
591 embedding
[2 * i
+ 2] = (char *) m
[i
].data
;
595 embedding
[n
++] = "-Mnginx";
596 embedding
[n
++] = "-e";
597 embedding
[n
++] = "0";
599 n
= perl_parse(perl
, ngx_http_perl_xs_init
, n
, embedding
, NULL
);
602 ngx_log_error(NGX_LOG_ALERT
, cf
->log
, 0, "perl_parse() failed: %d", n
);
606 sv
= get_sv("nginx::VERSION", FALSE
);
609 if (ngx_strcmp(ver
, NGINX_VERSION
) != 0) {
610 ngx_log_error(NGX_LOG_ALERT
, cf
->log
, 0,
611 "version " NGINX_VERSION
" of nginx.pm is required, "
612 "but %s was found", ver
);
616 if (ngx_http_perl_run_requires(aTHX_ pmcf
->requires
, cf
->log
) != NGX_OK
) {
626 (void) perl_destruct(perl
);
635 ngx_http_perl_run_requires(pTHX_ ngx_array_t
*requires
, ngx_log_t
*log
)
642 if (requires
== NGX_CONF_UNSET_PTR
) {
646 script
= requires
->elts
;
647 for (i
= 0; i
< requires
->nelts
; i
++) {
649 require_pv((char *) script
[i
].data
);
653 err
= (u_char
*) SvPV(ERRSV
, len
);
654 while (--len
&& (err
[len
] == CR
|| err
[len
] == LF
)) { /* void */ }
656 ngx_log_error(NGX_LOG_EMERG
, log
, 0,
657 "require_pv(\"%s\") failed: \"%*s\"",
658 script
[i
].data
, len
+ 1, err
);
669 ngx_http_perl_call_handler(pTHX_ ngx_http_request_t
*r
, HV
*nginx
, SV
*sub
,
670 SV
**args
, ngx_str_t
*handler
, ngx_str_t
*rv
)
689 sv
= sv_2mortal(sv_bless(newRV_noinc(newSViv(PTR2IV(r
))), nginx
));
693 EXTEND(sp
, (intptr_t) args
[0]);
695 for (i
= 1; i
<= (ngx_uint_t
) args
[0]; i
++) {
696 PUSHs(sv_2mortal(args
[i
]));
704 n
= call_sv(sub
, G_EVAL
);
712 ngx_log_debug1(NGX_LOG_DEBUG_HTTP
, c
->log
, 0,
713 "call_sv: %d", status
);
716 line
= SvPVx(POPs
, n_a
);
719 rv
->data
= ngx_pnalloc(r
->pool
, n_a
);
720 if (rv
->data
== NULL
) {
724 ngx_memcpy(rv
->data
, line
, n_a
);
737 err
= (u_char
*) SvPV(ERRSV
, len
);
738 while (--len
&& (err
[len
] == CR
|| err
[len
] == LF
)) { /* void */ }
740 ngx_log_error(NGX_LOG_ERR
, c
->log
, 0,
741 "call_sv(\"%V\") failed: \"%*s\"", handler
, len
+ 1, err
);
747 return NGX_HTTP_INTERNAL_SERVER_ERROR
;
751 ngx_log_error(NGX_LOG_ALERT
, c
->log
, 0,
752 "call_sv(\"%V\") returned %d results", handler
, n
);
760 return (ngx_int_t
) status
;
765 ngx_http_perl_eval_anon_sub(pTHX_ ngx_str_t
*handler
, SV
**sv
)
769 for (p
= handler
->data
; *p
; p
++) {
770 if (*p
!= ' ' && *p
!= '\t' && *p
!= CR
&& *p
!= LF
) {
775 if (ngx_strncmp(p
, "sub ", 4) == 0
776 || ngx_strncmp(p
, "sub{", 4) == 0
777 || ngx_strncmp(p
, "use ", 4) == 0)
779 *sv
= eval_pv((char *) p
, FALSE
);
781 /* eval_pv() does not set ERRSV on failure */
791 ngx_http_perl_create_main_conf(ngx_conf_t
*cf
)
793 ngx_http_perl_main_conf_t
*pmcf
;
795 pmcf
= ngx_pcalloc(cf
->pool
, sizeof(ngx_http_perl_main_conf_t
));
800 pmcf
->modules
= NGX_CONF_UNSET_PTR
;
801 pmcf
->requires
= NGX_CONF_UNSET_PTR
;
808 ngx_http_perl_init_main_conf(ngx_conf_t
*cf
, void *conf
)
810 ngx_http_perl_main_conf_t
*pmcf
= conf
;
812 if (pmcf
->perl
== NULL
) {
813 if (ngx_http_perl_init_interpreter(cf
, pmcf
) != NGX_CONF_OK
) {
814 return NGX_CONF_ERROR
;
822 #if (NGX_HAVE_PERL_MULTIPLICITY)
825 ngx_http_perl_cleanup_perl(void *data
)
827 PerlInterpreter
*perl
= data
;
829 PERL_SET_CONTEXT(perl
);
831 (void) perl_destruct(perl
);
836 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, ngx_cycle
->log
, 0, "perl term");
846 ngx_http_perl_preconfiguration(ngx_conf_t
*cf
)
850 ngx_http_ssi_main_conf_t
*smcf
;
852 smcf
= ngx_http_conf_get_module_main_conf(cf
, ngx_http_ssi_filter_module
);
854 rc
= ngx_hash_add_key(&smcf
->commands
, &ngx_http_perl_ssi_command
.name
,
855 &ngx_http_perl_ssi_command
, NGX_HASH_READONLY_KEY
);
858 if (rc
== NGX_BUSY
) {
859 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, 0,
860 "conflicting SSI command \"%V\"",
861 &ngx_http_perl_ssi_command
.name
);
873 ngx_http_perl_create_loc_conf(ngx_conf_t
*cf
)
875 ngx_http_perl_loc_conf_t
*plcf
;
877 plcf
= ngx_pcalloc(cf
->pool
, sizeof(ngx_http_perl_loc_conf_t
));
883 * set by ngx_pcalloc():
885 * plcf->handler = { 0, NULL };
893 ngx_http_perl_merge_loc_conf(ngx_conf_t
*cf
, void *parent
, void *child
)
895 ngx_http_perl_loc_conf_t
*prev
= parent
;
896 ngx_http_perl_loc_conf_t
*conf
= child
;
898 if (conf
->sub
== NULL
) {
899 conf
->sub
= prev
->sub
;
900 conf
->handler
= prev
->handler
;
908 ngx_http_perl(ngx_conf_t
*cf
, ngx_command_t
*cmd
, void *conf
)
910 ngx_http_perl_loc_conf_t
*plcf
= conf
;
913 ngx_http_core_loc_conf_t
*clcf
;
914 ngx_http_perl_main_conf_t
*pmcf
;
916 value
= cf
->args
->elts
;
918 if (plcf
->handler
.data
) {
919 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, 0,
920 "duplicate perl handler \"%V\"", &value
[1]);
921 return NGX_CONF_ERROR
;
924 pmcf
= ngx_http_conf_get_module_main_conf(cf
, ngx_http_perl_module
);
926 if (pmcf
->perl
== NULL
) {
927 if (ngx_http_perl_init_interpreter(cf
, pmcf
) != NGX_CONF_OK
) {
928 return NGX_CONF_ERROR
;
932 plcf
->handler
= value
[1];
937 PERL_SET_CONTEXT(pmcf
->perl
);
939 ngx_http_perl_eval_anon_sub(aTHX_
&value
[1], &plcf
->sub
);
941 if (plcf
->sub
== &PL_sv_undef
) {
942 ngx_conf_log_error(NGX_LOG_ERR
, cf
, 0,
943 "eval_pv(\"%V\") failed", &value
[1]);
944 return NGX_CONF_ERROR
;
947 if (plcf
->sub
== NULL
) {
948 plcf
->sub
= newSVpvn((char *) value
[1].data
, value
[1].len
);
953 clcf
= ngx_http_conf_get_module_loc_conf(cf
, ngx_http_core_module
);
954 clcf
->handler
= ngx_http_perl_handler
;
961 ngx_http_perl_set(ngx_conf_t
*cf
, ngx_command_t
*cmd
, void *conf
)
965 ngx_http_variable_t
*v
;
966 ngx_http_perl_variable_t
*pv
;
967 ngx_http_perl_main_conf_t
*pmcf
;
969 value
= cf
->args
->elts
;
971 if (value
[1].data
[0] != '$') {
972 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, 0,
973 "invalid variable name \"%V\"", &value
[1]);
974 return NGX_CONF_ERROR
;
980 v
= ngx_http_add_variable(cf
, &value
[1], NGX_HTTP_VAR_CHANGEABLE
);
982 return NGX_CONF_ERROR
;
985 pv
= ngx_palloc(cf
->pool
, sizeof(ngx_http_perl_variable_t
));
987 return NGX_CONF_ERROR
;
990 index
= ngx_http_get_variable_index(cf
, &value
[1]);
991 if (index
== NGX_ERROR
) {
992 return NGX_CONF_ERROR
;
995 pmcf
= ngx_http_conf_get_module_main_conf(cf
, ngx_http_perl_module
);
997 if (pmcf
->perl
== NULL
) {
998 if (ngx_http_perl_init_interpreter(cf
, pmcf
) != NGX_CONF_OK
) {
999 return NGX_CONF_ERROR
;
1003 pv
->handler
= value
[2];
1008 PERL_SET_CONTEXT(pmcf
->perl
);
1010 ngx_http_perl_eval_anon_sub(aTHX_
&value
[2], &pv
->sub
);
1012 if (pv
->sub
== &PL_sv_undef
) {
1013 ngx_conf_log_error(NGX_LOG_ERR
, cf
, 0,
1014 "eval_pv(\"%V\") failed", &value
[2]);
1015 return NGX_CONF_ERROR
;
1018 if (pv
->sub
== NULL
) {
1019 pv
->sub
= newSVpvn((char *) value
[2].data
, value
[2].len
);
1024 v
->get_handler
= ngx_http_perl_variable
;
1025 v
->data
= (uintptr_t) pv
;
1032 ngx_http_perl_init_worker(ngx_cycle_t
*cycle
)
1034 ngx_http_perl_main_conf_t
*pmcf
;
1036 pmcf
= ngx_http_cycle_get_module_main_conf(cycle
, ngx_http_perl_module
);
1040 PERL_SET_CONTEXT(pmcf
->perl
);
1042 /* set worker's $$ */
1044 sv_setiv(GvSV(gv_fetchpv("$", TRUE
, SVt_PV
)), (I32
) ngx_pid
);
1052 ngx_http_perl_exit(ngx_cycle_t
*cycle
)
1054 #if (NGX_HAVE_PERL_MULTIPLICITY)
1057 * the master exit hook is run before global pool cleanup,
1058 * therefore just set flag here
1066 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, cycle
->log
, 0, "perl term");
1068 (void) perl_destruct(perl
);