Mercurial > hg > nginx-vendor-0-7
diff src/http/modules/perl/ngx_http_perl_module.c @ 258:6ae1357b7b7c NGINX_0_4_14
nginx 0.4.14
*) Feature: the "proxy_pass_error_message" directive in IMAP/POP3 proxy.
*) Feature: now configure detects system PCRE library on FreeBSD,
Linux, and NetBSD.
*) Bugfix: ngx_http_perl_module did not work with perl built with the
threads support; bug appeared in 0.3.38.
*) Bugfix: ngx_http_perl_module did not work if perl was called
recursively.
*) Bugfix: nginx ignored a host name in an request line.
*) Bugfix: a worker process may got caught in an endless loop, if a
FastCGI server sent too many data to the stderr.
*) Bugfix: the $upstream_response_time variable may be negative if the
system time was changed backward.
*) Bugfix: the "Auth-Login-Attempt" parameter was not sent to IMAP/POP3
proxy authentication server when POP3 was used.
*) Bugfix: a segmentation fault might occur if connect to IMAP/POP3
proxy authentication server failed.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Mon, 27 Nov 2006 00:00:00 +0300 |
parents | acd2ec3541cb |
children | 251bcd11a5b8 |
line wrap: on
line diff
--- a/src/http/modules/perl/ngx_http_perl_module.c +++ b/src/http/modules/perl/ngx_http_perl_module.c @@ -11,12 +11,8 @@ typedef struct { - PerlInterpreter **free_perls; - ngx_uint_t interp; - ngx_uint_t nalloc; - ngx_uint_t interp_max; - PerlInterpreter *perl; + HV *nginx; ngx_str_t modules; ngx_array_t requires; } ngx_http_perl_main_conf_t; @@ -45,12 +41,6 @@ static ngx_int_t ngx_http_perl_ssi(ngx_h ngx_http_ssi_ctx_t *ssi_ctx, ngx_str_t **params); #endif -static ngx_int_t - ngx_http_perl_get_interpreter(ngx_http_perl_main_conf_t *pmcf, - PerlInterpreter **perl, ngx_log_t *log); -static ngx_inline void - ngx_http_perl_free_interpreter(ngx_http_perl_main_conf_t *pmcf, - PerlInterpreter *perl); static char *ngx_http_perl_init_interpreter(ngx_conf_t *cf, ngx_http_perl_main_conf_t *pmcf); static PerlInterpreter * @@ -59,7 +49,7 @@ static PerlInterpreter * static ngx_int_t ngx_http_perl_run_requires(pTHX_ ngx_array_t *requires, ngx_log_t *log); static ngx_int_t ngx_http_perl_call_handler(pTHX_ ngx_http_request_t *r, - SV *sub, ngx_str_t **args, ngx_str_t *handler, ngx_str_t *rv); + HV *nginx, SV *sub, ngx_str_t **args, ngx_str_t *handler, ngx_str_t *rv); static void ngx_http_perl_eval_anon_sub(pTHX_ ngx_str_t *handler, SV **sv); static ngx_int_t ngx_http_perl_preconfiguration(ngx_conf_t *cf); @@ -72,16 +62,11 @@ static char *ngx_http_perl_require(ngx_c void *conf); static char *ngx_http_perl(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static char *ngx_http_perl_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); -static char *ngx_http_perl_interp_max_unsupported(ngx_conf_t *cf, void *post, - void *data); -#if (NGX_HAVE_PERL_CLONE || NGX_HAVE_PERL_MULTIPLICITY) +static void ngx_http_perl_cleanup_sv(void *data); + +#if (NGX_HAVE_PERL_MULTIPLICITY) static void ngx_http_perl_cleanup_perl(void *data); #endif -static void ngx_http_perl_cleanup_sv(void *data); - - -static ngx_conf_post_handler_pt ngx_http_perl_interp_max_p = - ngx_http_perl_interp_max_unsupported; static ngx_command_t ngx_http_perl_commands[] = { @@ -100,13 +85,6 @@ static ngx_command_t ngx_http_perl_comm 0, NULL }, - { ngx_string("perl_interp_max"), - NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1, - ngx_conf_set_num_slot, - NGX_HTTP_MAIN_CONF_OFFSET, - offsetof(ngx_http_perl_main_conf_t, interp_max), - &ngx_http_perl_interp_max_p }, - { ngx_string("perl"), NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_http_perl, @@ -200,24 +178,6 @@ ngx_http_perl_handler(ngx_http_request_t ngx_http_perl_handle_request(r); return NGX_DONE; - -#if 0 - r->request_body_in_single_buf = 1; - r->request_body_in_persistent_file = 1; - r->request_body_delete_incomplete_file = 1; - - if (r->request_body_in_file_only) { - r->request_body_file_log_level = 0; - } - - rc = ngx_http_read_client_request_body(r, ngx_http_perl_handle_request); - - if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { - return rc; - } - - return NGX_DONE; -#endif } @@ -247,16 +207,10 @@ ngx_http_perl_handle_request(ngx_http_re pmcf = ngx_http_get_module_main_conf(r, ngx_http_perl_module); - rc = ngx_http_perl_get_interpreter(pmcf, &ctx->perl, r->connection->log); - - if (rc != NGX_OK) { - ngx_http_finalize_request(r, rc); - return; - } - { - dTHXa(ctx->perl); + dTHXa(pmcf->perl); + PERL_SET_CONTEXT(pmcf->perl); if (ctx->next == NULL) { plcf = ngx_http_get_module_loc_conf(r, ngx_http_perl_module); @@ -269,12 +223,11 @@ ngx_http_perl_handle_request(ngx_http_re ctx->next = NULL; } - rc = ngx_http_perl_call_handler(aTHX_ r, sub, NULL, handler, NULL); + rc = ngx_http_perl_call_handler(aTHX_ r, pmcf->nginx, sub, NULL, handler, + NULL); } - ngx_http_perl_free_interpreter(pmcf, ctx->perl); - if (rc > 600) { rc = NGX_OK; } @@ -338,25 +291,18 @@ ngx_http_perl_variable(ngx_http_request_ pmcf = ngx_http_get_module_main_conf(r, ngx_http_perl_module); - rc = ngx_http_perl_get_interpreter(pmcf, &ctx->perl, r->connection->log); - - if (rc != NGX_OK) { - return rc; - } - value.data = NULL; { - dTHXa(ctx->perl); + dTHXa(pmcf->perl); + PERL_SET_CONTEXT(pmcf->perl); - rc = ngx_http_perl_call_handler(aTHX_ r, pv->sub, NULL, + rc = ngx_http_perl_call_handler(aTHX_ r, pmcf->nginx, pv->sub, NULL, &pv->handler, &value); } - ngx_http_perl_free_interpreter(pmcf, ctx->perl); - if (value.data) { v->len = value.len; v->valid = 1; @@ -371,6 +317,9 @@ ngx_http_perl_variable(ngx_http_request_ ctx->filename.data = NULL; ctx->redirect_uri.len = 0; + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "perl variable done"); + return rc; } @@ -390,8 +339,6 @@ ngx_http_perl_ssi(ngx_http_request_t *r, ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "perl ssi handler"); - pmcf = ngx_http_get_module_main_conf(r, ngx_http_perl_module); - ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module); if (ctx == NULL) { @@ -403,11 +350,7 @@ ngx_http_perl_ssi(ngx_http_request_t *r, ngx_http_set_ctx(r, ctx, ngx_http_perl_module); } - rc = ngx_http_perl_get_interpreter(pmcf, &ctx->perl, r->connection->log); - - if (rc != NGX_OK) { - return rc; - } + pmcf = ngx_http_get_module_main_conf(r, ngx_http_perl_module); ctx->ssi = ssi_ctx; @@ -416,7 +359,8 @@ ngx_http_perl_ssi(ngx_http_request_t *r, { - dTHXa(ctx->perl); + dTHXa(pmcf->perl); + PERL_SET_CONTEXT(pmcf->perl); #if 0 @@ -438,65 +382,30 @@ ngx_http_perl_ssi(ngx_http_request_t *r, sv = newSVpvn((char *) handler->data, handler->len); - rc = ngx_http_perl_call_handler(aTHX_ r, sv, ¶ms[NGX_HTTP_PERL_SSI_ARG], + rc = ngx_http_perl_call_handler(aTHX_ r, pmcf->nginx, sv, + ¶ms[NGX_HTTP_PERL_SSI_ARG], handler, NULL); SvREFCNT_dec(sv); } - ngx_http_perl_free_interpreter(pmcf, ctx->perl); - ctx->filename.data = NULL; ctx->redirect_uri.len = 0; ctx->ssi = NULL; + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "perl ssi done"); + return rc; } #endif -static ngx_int_t -ngx_http_perl_get_interpreter(ngx_http_perl_main_conf_t *pmcf, - PerlInterpreter **perl, ngx_log_t *log) -{ - if (pmcf->interp) { - pmcf->interp--; - - *perl = pmcf->free_perls[pmcf->interp]; - - return NGX_OK; - } - - if (pmcf->nalloc < pmcf->interp_max) { - *perl = ngx_http_perl_create_interpreter(pmcf, log); - - if (*perl) { - return NGX_OK; - } - - return NGX_HTTP_INTERNAL_SERVER_ERROR; - } - - ngx_log_error(NGX_LOG_ALERT, log, 0, "no free perl interpreter"); - - return NGX_HTTP_SERVICE_UNAVAILABLE; -} - - -static ngx_inline void -ngx_http_perl_free_interpreter(ngx_http_perl_main_conf_t *pmcf, - PerlInterpreter *perl) -{ - pmcf->free_perls[pmcf->interp++] = perl; -} - - static char * ngx_http_perl_init_interpreter(ngx_conf_t *cf, ngx_http_perl_main_conf_t *pmcf) { -#if (NGX_HAVE_PERL_CLONE || NGX_HAVE_PERL_MULTIPLICITY) +#if (NGX_HAVE_PERL_MULTIPLICITY) ngx_pool_cleanup_t *cln; cln = ngx_pool_cleanup_add(cf->pool, 0); @@ -520,7 +429,7 @@ ngx_http_perl_init_interpreter(ngx_conf_ } } -#if !(NGX_HAVE_PERL_CLONE || NGX_HAVE_PERL_MULTIPLICITY) +#if !(NGX_HAVE_PERL_MULTIPLICITY) if (perl) { if (ngx_http_perl_run_requires(aTHX_ &pmcf->requires, cf->log) @@ -545,7 +454,9 @@ ngx_http_perl_init_interpreter(ngx_conf_ return NGX_CONF_ERROR; } -#if (NGX_HAVE_PERL_CLONE || NGX_HAVE_PERL_MULTIPLICITY) + pmcf->nginx = nginx_stash; + +#if (NGX_HAVE_PERL_MULTIPLICITY) cln->handler = ngx_http_perl_cleanup_perl; cln->data = pmcf->perl; @@ -572,43 +483,18 @@ ngx_http_perl_create_interpreter(ngx_htt ngx_log_debug0(NGX_LOG_DEBUG_HTTP, log, 0, "create perl interpreter"); -#if (NGX_HAVE_PERL_CLONE) - - if (pmcf->perl) { - - perl = perl_clone(pmcf->perl, CLONEf_KEEP_PTR_TABLE); - if (perl == NULL) { - ngx_log_error(NGX_LOG_ALERT, log, 0, "perl_clone() failed"); - return NULL; - } - - { - - dTHXa(perl); - - ptr_table_free(PL_ptr_table); - PL_ptr_table = NULL; - - } - - pmcf->nalloc++; - - return perl; - } - -#endif - perl = perl_alloc(); if (perl == NULL) { ngx_log_error(NGX_LOG_ALERT, log, 0, "perl_alloc() failed"); return NULL; } - perl_construct(perl); - { dTHXa(perl); + PERL_SET_CONTEXT(perl); + + perl_construct(perl); #ifdef PERL_EXIT_DESTRUCT_END PL_exit_flags |= PERL_EXIT_DESTRUCT_END; @@ -652,8 +538,6 @@ ngx_http_perl_create_interpreter(ngx_htt } - pmcf->nalloc++; - return perl; fail: @@ -699,7 +583,7 @@ ngx_http_perl_run_requires(pTHX_ ngx_arr static ngx_int_t -ngx_http_perl_call_handler(pTHX_ ngx_http_request_t *r, SV *sub, +ngx_http_perl_call_handler(pTHX_ ngx_http_request_t *r, HV *nginx, SV *sub, ngx_str_t **args, ngx_str_t *handler, ngx_str_t *rv) { SV *sv; @@ -718,7 +602,7 @@ ngx_http_perl_call_handler(pTHX_ ngx_htt PUSHMARK(sp); - sv = sv_2mortal(sv_bless(newRV_noinc(newSViv(PTR2IV(r))), nginx_stash)); + sv = sv_2mortal(sv_bless(newRV_noinc(newSViv(PTR2IV(r))), nginx)); XPUSHs(sv); if (args) { @@ -810,6 +694,9 @@ ngx_http_perl_eval_anon_sub(pTHX_ ngx_st if (ngx_strncmp(p, "sub ", 4) == 0 || ngx_strncmp(p, "use ", 4) == 0) { *sv = eval_pv((char *) p, FALSE); + + /* eval_pv() does not set ERRSV on failure */ + return; } @@ -827,8 +714,6 @@ ngx_http_perl_create_main_conf(ngx_conf_ return NGX_CONF_ERROR; } - pmcf->interp_max = NGX_CONF_UNSET_UINT; - if (ngx_array_init(&pmcf->requires, cf->pool, 1, sizeof(u_char *)) != NGX_OK) { @@ -844,39 +729,25 @@ ngx_http_perl_init_main_conf(ngx_conf_t { ngx_http_perl_main_conf_t *pmcf = conf; -#if (NGX_HAVE_PERL_CLONE || NGX_HAVE_PERL_MULTIPLICITY) - ngx_conf_init_uint_value(pmcf->interp_max, 10); -#else - ngx_conf_init_uint_value(pmcf->interp_max, 1); -#endif - - pmcf->free_perls = ngx_pcalloc(cf->pool, - pmcf->interp_max * sizeof(PerlInterpreter *)); - if (pmcf->free_perls == NULL) { - return NGX_CONF_ERROR; - } - if (pmcf->perl == NULL) { if (ngx_http_perl_init_interpreter(cf, pmcf) != NGX_CONF_OK) { return NGX_CONF_ERROR; } } -#if !(NGX_HAVE_PERL_CLONE) - ngx_http_perl_free_interpreter(pmcf, pmcf->perl); -#endif - return NGX_CONF_OK; } -#if (NGX_HAVE_PERL_CLONE || NGX_HAVE_PERL_MULTIPLICITY) +#if (NGX_HAVE_PERL_MULTIPLICITY) static void ngx_http_perl_cleanup_perl(void *data) { PerlInterpreter *perl = data; + PERL_SET_CONTEXT(perl); + (void) perl_destruct(perl); perl_free(perl); @@ -893,6 +764,7 @@ ngx_http_perl_cleanup_sv(void *data) ngx_http_perl_cleanup_t *cln = data; dTHXa(cln->perl); + PERL_SET_CONTEXT(cln->perl); SvREFCNT_dec(cln->sv); } @@ -1019,6 +891,7 @@ ngx_http_perl(ngx_conf_t *cf, ngx_comman { dTHXa(pmcf->perl); + PERL_SET_CONTEXT(pmcf->perl); ngx_http_perl_eval_anon_sub(aTHX_ &value[1], &plcf->sub); @@ -1101,6 +974,7 @@ ngx_http_perl_set(ngx_conf_t *cf, ngx_co { dTHXa(pmcf->perl); + PERL_SET_CONTEXT(pmcf->perl); ngx_http_perl_eval_anon_sub(aTHX_ &value[2], &pv->sub); @@ -1126,19 +1000,3 @@ ngx_http_perl_set(ngx_conf_t *cf, ngx_co return NGX_CONF_OK; } - - -static char * -ngx_http_perl_interp_max_unsupported(ngx_conf_t *cf, void *post, void *data) -{ -#if (NGX_HAVE_PERL_CLONE || NGX_HAVE_PERL_MULTIPLICITY) - - return NGX_CONF_OK; - -#else - - return "to use perl_interp_max you have to build perl with " - "-Dusemultiplicity or -Dusethreads options"; - -#endif -}