diff src/http/modules/perl/ngx_http_perl_module.c @ 7524:deebe988cbd7

Perl: reworked perl module to pass ctx instead of request. This ensures that correct ctx is always available, including after filter finalization. In particular, this fixes a segmentation fault with the following configuration: location / { image_filter test; perl 'sub { my $r = shift; $r->send_http_header(); $r->print("foo\n"); $r->print("bar\n"); }'; } This also seems to be the only way to correctly handle filter finalization in various complex cases, for example, when embedded perl is used both in the original handler and in an error page called after filter finalization.
author Maxim Dounin <mdounin@mdounin.ru>
date Fri, 12 Jul 2019 11:29:22 +0300
parents 919a5c6c828c
children 575480d3fd01
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
@@ -43,7 +43,8 @@ static PerlInterpreter *ngx_http_perl_cr
 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,
-    HV *nginx, SV *sub, SV **args, ngx_str_t *handler, ngx_str_t *rv);
+    ngx_http_perl_ctx_t *ctx, HV *nginx, SV *sub, SV **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);
@@ -199,6 +200,8 @@ ngx_http_perl_handle_request(ngx_http_re
         }
 
         ngx_http_set_ctx(r, ctx, ngx_http_perl_module);
+
+        ctx->request = r;
     }
 
     pmcf = ngx_http_get_module_main_conf(r, ngx_http_perl_module);
@@ -220,8 +223,8 @@ ngx_http_perl_handle_request(ngx_http_re
         ctx->next = NULL;
     }
 
-    rc = ngx_http_perl_call_handler(aTHX_ r, pmcf->nginx, sub, NULL, handler,
-                                    NULL);
+    rc = ngx_http_perl_call_handler(aTHX_ r, ctx, pmcf->nginx, sub, NULL,
+                                    handler, NULL);
 
     }
 
@@ -309,6 +312,8 @@ ngx_http_perl_variable(ngx_http_request_
         }
 
         ngx_http_set_ctx(r, ctx, ngx_http_perl_module);
+
+        ctx->request = r;
     }
 
     pmcf = ngx_http_get_module_main_conf(r, ngx_http_perl_module);
@@ -321,7 +326,7 @@ ngx_http_perl_variable(ngx_http_request_
     PERL_SET_CONTEXT(pmcf->perl);
     PERL_SET_INTERP(pmcf->perl);
 
-    rc = ngx_http_perl_call_handler(aTHX_ r, pmcf->nginx, pv->sub, NULL,
+    rc = ngx_http_perl_call_handler(aTHX_ r, ctx, pmcf->nginx, pv->sub, NULL,
                                     &pv->handler, &value);
 
     }
@@ -372,6 +377,8 @@ ngx_http_perl_ssi(ngx_http_request_t *r,
         }
 
         ngx_http_set_ctx(r, ctx, ngx_http_perl_module);
+
+        ctx->request = r;
     }
 
     pmcf = ngx_http_get_module_main_conf(r, ngx_http_perl_module);
@@ -430,8 +437,8 @@ ngx_http_perl_ssi(ngx_http_request_t *r,
         asv = NULL;
     }
 
-    rc = ngx_http_perl_call_handler(aTHX_ r, pmcf->nginx, sv, asv, handler,
-                                    NULL);
+    rc = ngx_http_perl_call_handler(aTHX_ r, ctx, pmcf->nginx, sv, asv,
+                                    handler, NULL);
 
     SvREFCNT_dec(sv);
 
@@ -667,8 +674,9 @@ ngx_http_perl_run_requires(pTHX_ ngx_arr
 
 
 static ngx_int_t
-ngx_http_perl_call_handler(pTHX_ ngx_http_request_t *r, HV *nginx, SV *sub,
-    SV **args, ngx_str_t *handler, ngx_str_t *rv)
+ngx_http_perl_call_handler(pTHX_ ngx_http_request_t *r,
+    ngx_http_perl_ctx_t *ctx, HV *nginx, SV *sub, SV **args,
+    ngx_str_t *handler, ngx_str_t *rv)
 {
     SV                *sv;
     int                n, status;
@@ -687,7 +695,7 @@ ngx_http_perl_call_handler(pTHX_ ngx_htt
 
     PUSHMARK(sp);
 
-    sv = sv_2mortal(sv_bless(newRV_noinc(newSViv(PTR2IV(r))), nginx));
+    sv = sv_2mortal(sv_bless(newRV_noinc(newSViv(PTR2IV(ctx))), nginx));
     XPUSHs(sv);
 
     if (args) {