Mercurial > hg > nginx-quic
annotate src/http/modules/perl/ngx_http_perl_module.c @ 5324:8ef1722143dc
SPDY: do not reject headers with empty value (ticket #396).
A quote from SPDY draft 2 specification: "The length of each name and
value must be greater than zero. A receiver of a zero-length name or
value must send a RST_STREAM with code PROTOCOL error."
But it appears that Chrome browser allows sending requests over SPDY/2
connection using JavaScript that contain headers with empty values.
For better compatibility across SPDY clients and to be compliant with
HTTP, such headers are no longer rejected.
Also, it is worth noting that in SPDY draft 3 the statement has been
changed so that it permits empty values for headers.
author | Valentin Bartenev <vbart@nginx.com> |
---|---|
date | Thu, 15 Aug 2013 19:16:09 +0400 |
parents | f1a91825730a |
children | 314c3d7cc3a5 |
rev | line source |
---|---|
599 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4412 | 4 * Copyright (C) Nginx, Inc. |
599 | 5 */ |
6 | |
7 | |
8 #include <ngx_config.h> | |
9 #include <ngx_core.h> | |
10 #include <ngx_http.h> | |
11 #include <ngx_http_perl_module.h> | |
12 | |
13 | |
14 typedef struct { | |
15 PerlInterpreter *perl; | |
873
f92ad15c2db1
fix segfaults in future workers those will use old configuration,
Igor Sysoev <igor@sysoev.ru>
parents:
872
diff
changeset
|
16 HV *nginx; |
3175 | 17 ngx_array_t *modules; |
3174
479fd46cd1c4
use ngx_conf_set_str_array_slot() for perl_require
Igor Sysoev <igor@sysoev.ru>
parents:
3173
diff
changeset
|
18 ngx_array_t *requires; |
599 | 19 } ngx_http_perl_main_conf_t; |
20 | |
21 | |
22 typedef struct { | |
23 SV *sub; | |
24 ngx_str_t handler; | |
25 } ngx_http_perl_loc_conf_t; | |
26 | |
27 | |
28 typedef struct { | |
29 SV *sub; | |
30 ngx_str_t handler; | |
31 } ngx_http_perl_variable_t; | |
32 | |
33 | |
617 | 34 #if (NGX_HTTP_SSI) |
599 | 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); | |
617 | 37 #endif |
38 | |
599 | 39 static char *ngx_http_perl_init_interpreter(ngx_conf_t *cf, |
40 ngx_http_perl_main_conf_t *pmcf); | |
1069 | 41 static PerlInterpreter *ngx_http_perl_create_interpreter(ngx_conf_t *cf, |
42 ngx_http_perl_main_conf_t *pmcf); | |
653 | 43 static ngx_int_t ngx_http_perl_run_requires(pTHX_ ngx_array_t *requires, |
649 | 44 ngx_log_t *log); |
599 | 45 static ngx_int_t ngx_http_perl_call_handler(pTHX_ ngx_http_request_t *r, |
1899
d24ef26f1205
pass additional arguments in ngx_http_perl_call_handler() as SV
Igor Sysoev <igor@sysoev.ru>
parents:
1897
diff
changeset
|
46 HV *nginx, SV *sub, SV **args, ngx_str_t *handler, ngx_str_t *rv); |
599 | 47 static void ngx_http_perl_eval_anon_sub(pTHX_ ngx_str_t *handler, SV **sv); |
48 | |
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, | |
54 void *child); | |
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); | |
872
1c4a5b3f9110
Axe several perl interpreter instances: they may be useful in currently
Igor Sysoev <igor@sysoev.ru>
parents:
871
diff
changeset
|
57 |
1c4a5b3f9110
Axe several perl interpreter instances: they may be useful in currently
Igor Sysoev <igor@sysoev.ru>
parents:
871
diff
changeset
|
58 #if (NGX_HAVE_PERL_MULTIPLICITY) |
599 | 59 static void ngx_http_perl_cleanup_perl(void *data); |
649 | 60 #endif |
599 | 61 |
1257 | 62 static ngx_int_t ngx_http_perl_init_worker(ngx_cycle_t *cycle); |
1221
aa653367028e
PERL_SYS_TERM() should be called once on exit only, this fixes the message
Igor Sysoev <igor@sysoev.ru>
parents:
1165
diff
changeset
|
63 static void ngx_http_perl_exit(ngx_cycle_t *cycle); |
aa653367028e
PERL_SYS_TERM() should be called once on exit only, this fixes the message
Igor Sysoev <igor@sysoev.ru>
parents:
1165
diff
changeset
|
64 |
599 | 65 |
66 static ngx_command_t ngx_http_perl_commands[] = { | |
67 | |
68 { ngx_string("perl_modules"), | |
69 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1, | |
3175 | 70 ngx_conf_set_str_array_slot, |
599 | 71 NGX_HTTP_MAIN_CONF_OFFSET, |
72 offsetof(ngx_http_perl_main_conf_t, modules), | |
73 NULL }, | |
74 | |
75 { ngx_string("perl_require"), | |
76 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1, | |
3174
479fd46cd1c4
use ngx_conf_set_str_array_slot() for perl_require
Igor Sysoev <igor@sysoev.ru>
parents:
3173
diff
changeset
|
77 ngx_conf_set_str_array_slot, |
599 | 78 NGX_HTTP_MAIN_CONF_OFFSET, |
3174
479fd46cd1c4
use ngx_conf_set_str_array_slot() for perl_require
Igor Sysoev <igor@sysoev.ru>
parents:
3173
diff
changeset
|
79 offsetof(ngx_http_perl_main_conf_t, requires), |
599 | 80 NULL }, |
81 | |
82 { ngx_string("perl"), | |
922
a5b9cdfe3e19
allow "perl" inside "limit_except"
Igor Sysoev <igor@sysoev.ru>
parents:
913
diff
changeset
|
83 NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF|NGX_CONF_TAKE1, |
599 | 84 ngx_http_perl, |
85 NGX_HTTP_LOC_CONF_OFFSET, | |
86 0, | |
87 NULL }, | |
88 | |
89 { ngx_string("perl_set"), | |
90 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE2, | |
91 ngx_http_perl_set, | |
92 NGX_HTTP_LOC_CONF_OFFSET, | |
93 0, | |
94 NULL }, | |
95 | |
96 ngx_null_command | |
97 }; | |
98 | |
99 | |
100 static ngx_http_module_t ngx_http_perl_module_ctx = { | |
101 ngx_http_perl_preconfiguration, /* preconfiguration */ | |
102 NULL, /* postconfiguration */ | |
103 | |
104 ngx_http_perl_create_main_conf, /* create main configuration */ | |
105 ngx_http_perl_init_main_conf, /* init main configuration */ | |
106 | |
107 NULL, /* create server configuration */ | |
108 NULL, /* merge server configuration */ | |
109 | |
110 ngx_http_perl_create_loc_conf, /* create location configuration */ | |
111 ngx_http_perl_merge_loc_conf /* merge location configuration */ | |
112 }; | |
113 | |
114 | |
115 ngx_module_t ngx_http_perl_module = { | |
116 NGX_MODULE_V1, | |
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 */ | |
1257 | 122 ngx_http_perl_init_worker, /* init process */ |
599 | 123 NULL, /* init thread */ |
124 NULL, /* exit thread */ | |
125 NULL, /* exit process */ | |
1221
aa653367028e
PERL_SYS_TERM() should be called once on exit only, this fixes the message
Igor Sysoev <igor@sysoev.ru>
parents:
1165
diff
changeset
|
126 ngx_http_perl_exit, /* exit master */ |
599 | 127 NGX_MODULE_V1_PADDING |
128 }; | |
129 | |
130 | |
617 | 131 #if (NGX_HTTP_SSI) |
132 | |
599 | 133 #define NGX_HTTP_PERL_SSI_SUB 0 |
134 #define NGX_HTTP_PERL_SSI_ARG 1 | |
135 | |
136 | |
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 } | |
141 }; | |
142 | |
143 static ngx_http_ssi_command_t ngx_http_perl_ssi_command = { | |
667 | 144 ngx_string("perl"), ngx_http_perl_ssi, ngx_http_perl_ssi_params, 0, 0, 1 |
599 | 145 }; |
146 | |
617 | 147 #endif |
148 | |
599 | 149 |
3350
67da53a19e02
use global perl variable in perl_destruct()/perl_free()
Igor Sysoev <igor@sysoev.ru>
parents:
3175
diff
changeset
|
150 static ngx_str_t ngx_null_name = ngx_null_string; |
67da53a19e02
use global perl variable in perl_destruct()/perl_free()
Igor Sysoev <igor@sysoev.ru>
parents:
3175
diff
changeset
|
151 static HV *nginx_stash; |
681 | 152 |
2715 | 153 #if (NGX_HAVE_PERL_MULTIPLICITY) |
3350
67da53a19e02
use global perl variable in perl_destruct()/perl_free()
Igor Sysoev <igor@sysoev.ru>
parents:
3175
diff
changeset
|
154 static ngx_uint_t ngx_perl_term; |
67da53a19e02
use global perl variable in perl_destruct()/perl_free()
Igor Sysoev <igor@sysoev.ru>
parents:
3175
diff
changeset
|
155 #else |
67da53a19e02
use global perl variable in perl_destruct()/perl_free()
Igor Sysoev <igor@sysoev.ru>
parents:
3175
diff
changeset
|
156 static PerlInterpreter *perl; |
2715 | 157 #endif |
681 | 158 |
633 | 159 |
599 | 160 static void |
161 ngx_http_perl_xs_init(pTHX) | |
162 { | |
163 newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, __FILE__); | |
633 | 164 |
165 nginx_stash = gv_stashpv("nginx", TRUE); | |
599 | 166 } |
167 | |
168 | |
169 static ngx_int_t | |
170 ngx_http_perl_handler(ngx_http_request_t *r) | |
171 { | |
3082
5e8bf3e983d2
fix request counter handling for perl handler, introduced in r3050
Igor Sysoev <igor@sysoev.ru>
parents:
3050
diff
changeset
|
172 r->main->count++; |
5e8bf3e983d2
fix request counter handling for perl handler, introduced in r3050
Igor Sysoev <igor@sysoev.ru>
parents:
3050
diff
changeset
|
173 |
681 | 174 ngx_http_perl_handle_request(r); |
175 | |
176 return NGX_DONE; | |
629 | 177 } |
178 | |
179 | |
681 | 180 void |
629 | 181 ngx_http_perl_handle_request(ngx_http_request_t *r) |
182 { | |
681 | 183 SV *sub; |
599 | 184 ngx_int_t rc; |
681 | 185 ngx_str_t uri, args, *handler; |
599 | 186 ngx_http_perl_ctx_t *ctx; |
187 ngx_http_perl_loc_conf_t *plcf; | |
188 ngx_http_perl_main_conf_t *pmcf; | |
189 | |
190 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "perl handler"); | |
191 | |
192 ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module); | |
193 | |
194 if (ctx == NULL) { | |
195 ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_perl_ctx_t)); | |
196 if (ctx == NULL) { | |
681 | 197 ngx_http_finalize_request(r, NGX_ERROR); |
1025 | 198 return; |
599 | 199 } |
200 | |
201 ngx_http_set_ctx(r, ctx, ngx_http_perl_module); | |
202 } | |
203 | |
204 pmcf = ngx_http_get_module_main_conf(r, ngx_http_perl_module); | |
205 | |
206 { | |
207 | |
872
1c4a5b3f9110
Axe several perl interpreter instances: they may be useful in currently
Igor Sysoev <igor@sysoev.ru>
parents:
871
diff
changeset
|
208 dTHXa(pmcf->perl); |
873
f92ad15c2db1
fix segfaults in future workers those will use old configuration,
Igor Sysoev <igor@sysoev.ru>
parents:
872
diff
changeset
|
209 PERL_SET_CONTEXT(pmcf->perl); |
599 | 210 |
681 | 211 if (ctx->next == NULL) { |
212 plcf = ngx_http_get_module_loc_conf(r, ngx_http_perl_module); | |
213 sub = plcf->sub; | |
214 handler = &plcf->handler; | |
599 | 215 |
681 | 216 } else { |
217 sub = ctx->next; | |
218 handler = &ngx_null_name; | |
219 ctx->next = NULL; | |
220 } | |
221 | |
873
f92ad15c2db1
fix segfaults in future workers those will use old configuration,
Igor Sysoev <igor@sysoev.ru>
parents:
872
diff
changeset
|
222 rc = ngx_http_perl_call_handler(aTHX_ r, pmcf->nginx, sub, NULL, handler, |
f92ad15c2db1
fix segfaults in future workers those will use old configuration,
Igor Sysoev <igor@sysoev.ru>
parents:
872
diff
changeset
|
223 NULL); |
599 | 224 |
225 } | |
226 | |
3082
5e8bf3e983d2
fix request counter handling for perl handler, introduced in r3050
Igor Sysoev <igor@sysoev.ru>
parents:
3050
diff
changeset
|
227 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
5e8bf3e983d2
fix request counter handling for perl handler, introduced in r3050
Igor Sysoev <igor@sysoev.ru>
parents:
3050
diff
changeset
|
228 "perl handler done: %i", rc); |
5e8bf3e983d2
fix request counter handling for perl handler, introduced in r3050
Igor Sysoev <igor@sysoev.ru>
parents:
3050
diff
changeset
|
229 |
1702
86bb52e28ce0
fix segfault when $r->has_request_body() is called with ready body
Igor Sysoev <igor@sysoev.ru>
parents:
1565
diff
changeset
|
230 if (rc == NGX_DONE) { |
3111
4a2d3f571de6
fix request counter handling in perl module for $r->internal_redirect()
Igor Sysoev <igor@sysoev.ru>
parents:
3082
diff
changeset
|
231 ngx_http_finalize_request(r, rc); |
1702
86bb52e28ce0
fix segfault when $r->has_request_body() is called with ready body
Igor Sysoev <igor@sysoev.ru>
parents:
1565
diff
changeset
|
232 return; |
86bb52e28ce0
fix segfault when $r->has_request_body() is called with ready body
Igor Sysoev <igor@sysoev.ru>
parents:
1565
diff
changeset
|
233 } |
86bb52e28ce0
fix segfault when $r->has_request_body() is called with ready body
Igor Sysoev <igor@sysoev.ru>
parents:
1565
diff
changeset
|
234 |
599 | 235 if (rc > 600) { |
236 rc = NGX_OK; | |
237 } | |
238 | |
239 if (ctx->redirect_uri.len) { | |
240 uri = ctx->redirect_uri; | |
241 args = ctx->redirect_args; | |
629 | 242 |
243 } else { | |
244 uri.len = 0; | |
599 | 245 } |
246 | |
633 | 247 ctx->filename.data = NULL; |
599 | 248 ctx->redirect_uri.len = 0; |
249 | |
681 | 250 if (ctx->done || ctx->next) { |
3111
4a2d3f571de6
fix request counter handling in perl module for $r->internal_redirect()
Igor Sysoev <igor@sysoev.ru>
parents:
3082
diff
changeset
|
251 ngx_http_finalize_request(r, NGX_DONE); |
681 | 252 return; |
253 } | |
254 | |
599 | 255 if (uri.len) { |
629 | 256 ngx_http_internal_redirect(r, &uri, &args); |
3111
4a2d3f571de6
fix request counter handling in perl module for $r->internal_redirect()
Igor Sysoev <igor@sysoev.ru>
parents:
3082
diff
changeset
|
257 ngx_http_finalize_request(r, NGX_DONE); |
629 | 258 return; |
599 | 259 } |
260 | |
261 if (rc == NGX_OK || rc == NGX_HTTP_OK) { | |
629 | 262 ngx_http_send_special(r, NGX_HTTP_LAST); |
681 | 263 ctx->done = 1; |
599 | 264 } |
265 | |
629 | 266 ngx_http_finalize_request(r, rc); |
599 | 267 } |
268 | |
269 | |
1897 | 270 void |
911 | 271 ngx_http_perl_sleep_handler(ngx_http_request_t *r) |
272 { | |
913
90ce4d0e3241
fix ngx_http_perl_sleep_handler()
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
273 ngx_event_t *wev; |
90ce4d0e3241
fix ngx_http_perl_sleep_handler()
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
274 |
911 | 275 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
276 "perl sleep handler"); | |
277 | |
913
90ce4d0e3241
fix ngx_http_perl_sleep_handler()
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
278 wev = r->connection->write; |
90ce4d0e3241
fix ngx_http_perl_sleep_handler()
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
279 |
90ce4d0e3241
fix ngx_http_perl_sleep_handler()
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
280 if (wev->timedout) { |
90ce4d0e3241
fix ngx_http_perl_sleep_handler()
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
281 wev->timedout = 0; |
90ce4d0e3241
fix ngx_http_perl_sleep_handler()
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
282 ngx_http_perl_handle_request(r); |
90ce4d0e3241
fix ngx_http_perl_sleep_handler()
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
283 return; |
90ce4d0e3241
fix ngx_http_perl_sleep_handler()
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
284 } |
90ce4d0e3241
fix ngx_http_perl_sleep_handler()
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
285 |
2388
722b5aff05ae
use "!= NGX_OK" instead of "== NGX_ERROR"
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
286 if (ngx_handle_write_event(wev, 0) != NGX_OK) { |
913
90ce4d0e3241
fix ngx_http_perl_sleep_handler()
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
287 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); |
90ce4d0e3241
fix ngx_http_perl_sleep_handler()
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
288 } |
911 | 289 } |
290 | |
291 | |
599 | 292 static ngx_int_t |
293 ngx_http_perl_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, | |
294 uintptr_t data) | |
295 { | |
296 ngx_http_perl_variable_t *pv = (ngx_http_perl_variable_t *) data; | |
297 | |
298 ngx_int_t rc; | |
299 ngx_str_t value; | |
300 ngx_http_perl_ctx_t *ctx; | |
301 ngx_http_perl_main_conf_t *pmcf; | |
302 | |
303 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
304 "perl variable handler"); | |
305 | |
306 ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module); | |
307 | |
308 if (ctx == NULL) { | |
309 ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_perl_ctx_t)); | |
310 if (ctx == NULL) { | |
311 return NGX_ERROR; | |
312 } | |
313 | |
314 ngx_http_set_ctx(r, ctx, ngx_http_perl_module); | |
872
1c4a5b3f9110
Axe several perl interpreter instances: they may be useful in currently
Igor Sysoev <igor@sysoev.ru>
parents:
871
diff
changeset
|
315 } |
599 | 316 |
872
1c4a5b3f9110
Axe several perl interpreter instances: they may be useful in currently
Igor Sysoev <igor@sysoev.ru>
parents:
871
diff
changeset
|
317 pmcf = ngx_http_get_module_main_conf(r, ngx_http_perl_module); |
599 | 318 |
319 value.data = NULL; | |
320 | |
321 { | |
322 | |
872
1c4a5b3f9110
Axe several perl interpreter instances: they may be useful in currently
Igor Sysoev <igor@sysoev.ru>
parents:
871
diff
changeset
|
323 dTHXa(pmcf->perl); |
873
f92ad15c2db1
fix segfaults in future workers those will use old configuration,
Igor Sysoev <igor@sysoev.ru>
parents:
872
diff
changeset
|
324 PERL_SET_CONTEXT(pmcf->perl); |
599 | 325 |
873
f92ad15c2db1
fix segfaults in future workers those will use old configuration,
Igor Sysoev <igor@sysoev.ru>
parents:
872
diff
changeset
|
326 rc = ngx_http_perl_call_handler(aTHX_ r, pmcf->nginx, pv->sub, NULL, |
599 | 327 &pv->handler, &value); |
328 | |
329 } | |
330 | |
331 if (value.data) { | |
332 v->len = value.len; | |
333 v->valid = 1; | |
1565 | 334 v->no_cacheable = 0; |
599 | 335 v->not_found = 0; |
336 v->data = value.data; | |
337 | |
338 } else { | |
339 v->not_found = 1; | |
340 } | |
341 | |
633 | 342 ctx->filename.data = NULL; |
599 | 343 ctx->redirect_uri.len = 0; |
344 | |
871 | 345 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
346 "perl variable done"); | |
347 | |
599 | 348 return rc; |
349 } | |
350 | |
351 | |
617 | 352 #if (NGX_HTTP_SSI) |
353 | |
599 | 354 static ngx_int_t |
355 ngx_http_perl_ssi(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ssi_ctx, | |
356 ngx_str_t **params) | |
357 { | |
1899
d24ef26f1205
pass additional arguments in ngx_http_perl_call_handler() as SV
Igor Sysoev <igor@sysoev.ru>
parents:
1897
diff
changeset
|
358 SV *sv, **asv; |
599 | 359 ngx_int_t rc; |
1899
d24ef26f1205
pass additional arguments in ngx_http_perl_call_handler() as SV
Igor Sysoev <igor@sysoev.ru>
parents:
1897
diff
changeset
|
360 ngx_str_t *handler, **args; |
d24ef26f1205
pass additional arguments in ngx_http_perl_call_handler() as SV
Igor Sysoev <igor@sysoev.ru>
parents:
1897
diff
changeset
|
361 ngx_uint_t i; |
599 | 362 ngx_http_perl_ctx_t *ctx; |
363 ngx_http_perl_main_conf_t *pmcf; | |
364 | |
365 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
366 "perl ssi handler"); | |
367 | |
368 ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module); | |
369 | |
370 if (ctx == NULL) { | |
371 ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_perl_ctx_t)); | |
372 if (ctx == NULL) { | |
373 return NGX_ERROR; | |
374 } | |
375 | |
376 ngx_http_set_ctx(r, ctx, ngx_http_perl_module); | |
377 } | |
378 | |
872
1c4a5b3f9110
Axe several perl interpreter instances: they may be useful in currently
Igor Sysoev <igor@sysoev.ru>
parents:
871
diff
changeset
|
379 pmcf = ngx_http_get_module_main_conf(r, ngx_http_perl_module); |
599 | 380 |
381 ctx->ssi = ssi_ctx; | |
382 | |
383 handler = params[NGX_HTTP_PERL_SSI_SUB]; | |
384 handler->data[handler->len] = '\0'; | |
385 | |
386 { | |
387 | |
872
1c4a5b3f9110
Axe several perl interpreter instances: they may be useful in currently
Igor Sysoev <igor@sysoev.ru>
parents:
871
diff
changeset
|
388 dTHXa(pmcf->perl); |
873
f92ad15c2db1
fix segfaults in future workers those will use old configuration,
Igor Sysoev <igor@sysoev.ru>
parents:
872
diff
changeset
|
389 PERL_SET_CONTEXT(pmcf->perl); |
599 | 390 |
651 | 391 #if 0 |
392 | |
393 /* the code is disabled to force the precompiled perl code using only */ | |
394 | |
395 ngx_http_perl_eval_anon_sub(aTHX_ handler, &sv); | |
396 | |
397 if (sv == &PL_sv_undef) { | |
398 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
399 "eval_pv(\"%V\") failed", handler); | |
400 return NGX_ERROR; | |
401 } | |
402 | |
403 if (sv == NULL) { | |
404 sv = newSVpvn((char *) handler->data, handler->len); | |
405 } | |
406 | |
407 #endif | |
408 | |
599 | 409 sv = newSVpvn((char *) handler->data, handler->len); |
410 | |
1899
d24ef26f1205
pass additional arguments in ngx_http_perl_call_handler() as SV
Igor Sysoev <igor@sysoev.ru>
parents:
1897
diff
changeset
|
411 args = ¶ms[NGX_HTTP_PERL_SSI_ARG]; |
d24ef26f1205
pass additional arguments in ngx_http_perl_call_handler() as SV
Igor Sysoev <igor@sysoev.ru>
parents:
1897
diff
changeset
|
412 |
d24ef26f1205
pass additional arguments in ngx_http_perl_call_handler() as SV
Igor Sysoev <igor@sysoev.ru>
parents:
1897
diff
changeset
|
413 if (args) { |
d24ef26f1205
pass additional arguments in ngx_http_perl_call_handler() as SV
Igor Sysoev <igor@sysoev.ru>
parents:
1897
diff
changeset
|
414 |
d24ef26f1205
pass additional arguments in ngx_http_perl_call_handler() as SV
Igor Sysoev <igor@sysoev.ru>
parents:
1897
diff
changeset
|
415 for (i = 0; args[i]; i++) { /* void */ } |
d24ef26f1205
pass additional arguments in ngx_http_perl_call_handler() as SV
Igor Sysoev <igor@sysoev.ru>
parents:
1897
diff
changeset
|
416 |
d24ef26f1205
pass additional arguments in ngx_http_perl_call_handler() as SV
Igor Sysoev <igor@sysoev.ru>
parents:
1897
diff
changeset
|
417 asv = ngx_pcalloc(r->pool, (i + 1) * sizeof(SV *)); |
d24ef26f1205
pass additional arguments in ngx_http_perl_call_handler() as SV
Igor Sysoev <igor@sysoev.ru>
parents:
1897
diff
changeset
|
418 |
d24ef26f1205
pass additional arguments in ngx_http_perl_call_handler() as SV
Igor Sysoev <igor@sysoev.ru>
parents:
1897
diff
changeset
|
419 if (asv == NULL) { |
d24ef26f1205
pass additional arguments in ngx_http_perl_call_handler() as SV
Igor Sysoev <igor@sysoev.ru>
parents:
1897
diff
changeset
|
420 SvREFCNT_dec(sv); |
d24ef26f1205
pass additional arguments in ngx_http_perl_call_handler() as SV
Igor Sysoev <igor@sysoev.ru>
parents:
1897
diff
changeset
|
421 return NGX_ERROR; |
d24ef26f1205
pass additional arguments in ngx_http_perl_call_handler() as SV
Igor Sysoev <igor@sysoev.ru>
parents:
1897
diff
changeset
|
422 } |
d24ef26f1205
pass additional arguments in ngx_http_perl_call_handler() as SV
Igor Sysoev <igor@sysoev.ru>
parents:
1897
diff
changeset
|
423 |
d24ef26f1205
pass additional arguments in ngx_http_perl_call_handler() as SV
Igor Sysoev <igor@sysoev.ru>
parents:
1897
diff
changeset
|
424 asv[0] = (SV *) i; |
d24ef26f1205
pass additional arguments in ngx_http_perl_call_handler() as SV
Igor Sysoev <igor@sysoev.ru>
parents:
1897
diff
changeset
|
425 |
d24ef26f1205
pass additional arguments in ngx_http_perl_call_handler() as SV
Igor Sysoev <igor@sysoev.ru>
parents:
1897
diff
changeset
|
426 for (i = 0; args[i]; i++) { |
d24ef26f1205
pass additional arguments in ngx_http_perl_call_handler() as SV
Igor Sysoev <igor@sysoev.ru>
parents:
1897
diff
changeset
|
427 asv[i + 1] = newSVpvn((char *) args[i]->data, args[i]->len); |
d24ef26f1205
pass additional arguments in ngx_http_perl_call_handler() as SV
Igor Sysoev <igor@sysoev.ru>
parents:
1897
diff
changeset
|
428 } |
d24ef26f1205
pass additional arguments in ngx_http_perl_call_handler() as SV
Igor Sysoev <igor@sysoev.ru>
parents:
1897
diff
changeset
|
429 |
d24ef26f1205
pass additional arguments in ngx_http_perl_call_handler() as SV
Igor Sysoev <igor@sysoev.ru>
parents:
1897
diff
changeset
|
430 } else { |
d24ef26f1205
pass additional arguments in ngx_http_perl_call_handler() as SV
Igor Sysoev <igor@sysoev.ru>
parents:
1897
diff
changeset
|
431 asv = NULL; |
d24ef26f1205
pass additional arguments in ngx_http_perl_call_handler() as SV
Igor Sysoev <igor@sysoev.ru>
parents:
1897
diff
changeset
|
432 } |
d24ef26f1205
pass additional arguments in ngx_http_perl_call_handler() as SV
Igor Sysoev <igor@sysoev.ru>
parents:
1897
diff
changeset
|
433 |
d24ef26f1205
pass additional arguments in ngx_http_perl_call_handler() as SV
Igor Sysoev <igor@sysoev.ru>
parents:
1897
diff
changeset
|
434 rc = ngx_http_perl_call_handler(aTHX_ r, pmcf->nginx, sv, asv, handler, |
d24ef26f1205
pass additional arguments in ngx_http_perl_call_handler() as SV
Igor Sysoev <igor@sysoev.ru>
parents:
1897
diff
changeset
|
435 NULL); |
599 | 436 |
437 SvREFCNT_dec(sv); | |
438 | |
439 } | |
440 | |
633 | 441 ctx->filename.data = NULL; |
599 | 442 ctx->redirect_uri.len = 0; |
443 ctx->ssi = NULL; | |
444 | |
871 | 445 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "perl ssi done"); |
446 | |
599 | 447 return rc; |
448 } | |
449 | |
617 | 450 #endif |
451 | |
599 | 452 |
453 static char * | |
454 ngx_http_perl_init_interpreter(ngx_conf_t *cf, ngx_http_perl_main_conf_t *pmcf) | |
455 { | |
3350
67da53a19e02
use global perl variable in perl_destruct()/perl_free()
Igor Sysoev <igor@sysoev.ru>
parents:
3175
diff
changeset
|
456 ngx_str_t *m; |
67da53a19e02
use global perl variable in perl_destruct()/perl_free()
Igor Sysoev <igor@sysoev.ru>
parents:
3175
diff
changeset
|
457 ngx_uint_t i; |
872
1c4a5b3f9110
Axe several perl interpreter instances: they may be useful in currently
Igor Sysoev <igor@sysoev.ru>
parents:
871
diff
changeset
|
458 #if (NGX_HAVE_PERL_MULTIPLICITY) |
3350
67da53a19e02
use global perl variable in perl_destruct()/perl_free()
Igor Sysoev <igor@sysoev.ru>
parents:
3175
diff
changeset
|
459 ngx_pool_cleanup_t *cln; |
599 | 460 |
461 cln = ngx_pool_cleanup_add(cf->pool, 0); | |
462 if (cln == NULL) { | |
463 return NGX_CONF_ERROR; | |
464 } | |
465 | |
649 | 466 #endif |
467 | |
599 | 468 #ifdef NGX_PERL_MODULES |
3175 | 469 if (pmcf->modules == NGX_CONF_UNSET_PTR) { |
470 | |
471 pmcf->modules = ngx_array_create(cf->pool, 1, sizeof(ngx_str_t)); | |
472 if (pmcf->modules == NULL) { | |
473 return NGX_CONF_ERROR; | |
474 } | |
475 | |
476 m = ngx_array_push(pmcf->modules); | |
477 if (m == NULL) { | |
478 return NGX_CONF_ERROR; | |
479 } | |
480 | |
3516
dd1570b6f237
ngx_str_set() and ngx_str_null()
Igor Sysoev <igor@sysoev.ru>
parents:
3448
diff
changeset
|
481 ngx_str_set(m, NGX_PERL_MODULES); |
599 | 482 } |
483 #endif | |
484 | |
3175 | 485 if (pmcf->modules != NGX_CONF_UNSET_PTR) { |
486 m = pmcf->modules->elts; | |
487 for (i = 0; i < pmcf->modules->nelts; i++) { | |
5317
f1a91825730a
Replaced ngx_conf_full_name() with ngx_get_full_name().
Valentin Bartenev <vbart@nginx.com>
parents:
4972
diff
changeset
|
488 if (ngx_get_full_name(cf->pool, &cf->cycle->prefix, &m[i]) |
f1a91825730a
Replaced ngx_conf_full_name() with ngx_get_full_name().
Valentin Bartenev <vbart@nginx.com>
parents:
4972
diff
changeset
|
489 != NGX_OK) |
f1a91825730a
Replaced ngx_conf_full_name() with ngx_get_full_name().
Valentin Bartenev <vbart@nginx.com>
parents:
4972
diff
changeset
|
490 { |
3175 | 491 return NGX_CONF_ERROR; |
492 } | |
639 | 493 } |
629 | 494 } |
495 | |
872
1c4a5b3f9110
Axe several perl interpreter instances: they may be useful in currently
Igor Sysoev <igor@sysoev.ru>
parents:
871
diff
changeset
|
496 #if !(NGX_HAVE_PERL_MULTIPLICITY) |
649 | 497 |
498 if (perl) { | |
1165 | 499 |
500 if (ngx_set_environment(cf->cycle, NULL) == NULL) { | |
501 return NGX_CONF_ERROR; | |
502 } | |
503 | |
3174
479fd46cd1c4
use ngx_conf_set_str_array_slot() for perl_require
Igor Sysoev <igor@sysoev.ru>
parents:
3173
diff
changeset
|
504 if (ngx_http_perl_run_requires(aTHX_ pmcf->requires, cf->log) |
653 | 505 != NGX_OK) |
506 { | |
649 | 507 return NGX_CONF_ERROR; |
508 } | |
509 | |
510 pmcf->perl = perl; | |
1163
8288459f15c9
set nginx_stash after reconfiguration in single interpreter perl
Igor Sysoev <igor@sysoev.ru>
parents:
1069
diff
changeset
|
511 pmcf->nginx = nginx_stash; |
649 | 512 |
513 return NGX_CONF_OK; | |
514 } | |
515 | |
516 #endif | |
517 | |
1221
aa653367028e
PERL_SYS_TERM() should be called once on exit only, this fixes the message
Igor Sysoev <igor@sysoev.ru>
parents:
1165
diff
changeset
|
518 if (nginx_stash == NULL) { |
aa653367028e
PERL_SYS_TERM() should be called once on exit only, this fixes the message
Igor Sysoev <igor@sysoev.ru>
parents:
1165
diff
changeset
|
519 PERL_SYS_INIT(&ngx_argc, &ngx_argv); |
aa653367028e
PERL_SYS_TERM() should be called once on exit only, this fixes the message
Igor Sysoev <igor@sysoev.ru>
parents:
1165
diff
changeset
|
520 } |
599 | 521 |
1069 | 522 pmcf->perl = ngx_http_perl_create_interpreter(cf, pmcf); |
599 | 523 |
524 if (pmcf->perl == NULL) { | |
525 return NGX_CONF_ERROR; | |
526 } | |
527 | |
873
f92ad15c2db1
fix segfaults in future workers those will use old configuration,
Igor Sysoev <igor@sysoev.ru>
parents:
872
diff
changeset
|
528 pmcf->nginx = nginx_stash; |
f92ad15c2db1
fix segfaults in future workers those will use old configuration,
Igor Sysoev <igor@sysoev.ru>
parents:
872
diff
changeset
|
529 |
872
1c4a5b3f9110
Axe several perl interpreter instances: they may be useful in currently
Igor Sysoev <igor@sysoev.ru>
parents:
871
diff
changeset
|
530 #if (NGX_HAVE_PERL_MULTIPLICITY) |
649 | 531 |
599 | 532 cln->handler = ngx_http_perl_cleanup_perl; |
533 cln->data = pmcf->perl; | |
534 | |
649 | 535 #else |
536 | |
537 perl = pmcf->perl; | |
538 | |
539 #endif | |
540 | |
599 | 541 return NGX_CONF_OK; |
542 } | |
543 | |
544 | |
545 static PerlInterpreter * | |
1069 | 546 ngx_http_perl_create_interpreter(ngx_conf_t *cf, |
547 ngx_http_perl_main_conf_t *pmcf) | |
599 | 548 { |
549 int n; | |
775 | 550 STRLEN len; |
551 SV *sv; | |
3175 | 552 char *ver, **embedding; |
553 ngx_str_t *m; | |
554 ngx_uint_t i; | |
599 | 555 PerlInterpreter *perl; |
556 | |
1069 | 557 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, cf->log, 0, "create perl interpreter"); |
558 | |
559 if (ngx_set_environment(cf->cycle, NULL) == NULL) { | |
560 return NULL; | |
561 } | |
599 | 562 |
563 perl = perl_alloc(); | |
564 if (perl == NULL) { | |
1069 | 565 ngx_log_error(NGX_LOG_ALERT, cf->log, 0, "perl_alloc() failed"); |
599 | 566 return NULL; |
567 } | |
568 | |
569 { | |
570 | |
571 dTHXa(perl); | |
873
f92ad15c2db1
fix segfaults in future workers those will use old configuration,
Igor Sysoev <igor@sysoev.ru>
parents:
872
diff
changeset
|
572 PERL_SET_CONTEXT(perl); |
f92ad15c2db1
fix segfaults in future workers those will use old configuration,
Igor Sysoev <igor@sysoev.ru>
parents:
872
diff
changeset
|
573 |
f92ad15c2db1
fix segfaults in future workers those will use old configuration,
Igor Sysoev <igor@sysoev.ru>
parents:
872
diff
changeset
|
574 perl_construct(perl); |
599 | 575 |
576 #ifdef PERL_EXIT_DESTRUCT_END | |
577 PL_exit_flags |= PERL_EXIT_DESTRUCT_END; | |
578 #endif | |
579 | |
3175 | 580 n = (pmcf->modules != NGX_CONF_UNSET_PTR) ? pmcf->modules->nelts * 2 : 0; |
581 | |
582 embedding = ngx_palloc(cf->pool, (4 + n) * sizeof(char *)); | |
583 if (embedding == NULL) { | |
584 goto fail; | |
585 } | |
586 | |
599 | 587 embedding[0] = ""; |
588 | |
3175 | 589 if (n++) { |
590 m = pmcf->modules->elts; | |
591 for (i = 0; i < pmcf->modules->nelts; i++) { | |
592 embedding[2 * i + 1] = "-I"; | |
593 embedding[2 * i + 2] = (char *) m[i].data; | |
594 } | |
599 | 595 } |
596 | |
597 embedding[n++] = "-Mnginx"; | |
598 embedding[n++] = "-e"; | |
599 embedding[n++] = "0"; | |
600 | |
601 n = perl_parse(perl, ngx_http_perl_xs_init, n, embedding, NULL); | |
602 | |
603 if (n != 0) { | |
1069 | 604 ngx_log_error(NGX_LOG_ALERT, cf->log, 0, "perl_parse() failed: %d", n); |
599 | 605 goto fail; |
606 } | |
607 | |
775 | 608 sv = get_sv("nginx::VERSION", FALSE); |
609 ver = SvPV(sv, len); | |
610 | |
611 if (ngx_strcmp(ver, NGINX_VERSION) != 0) { | |
1069 | 612 ngx_log_error(NGX_LOG_ALERT, cf->log, 0, |
775 | 613 "version " NGINX_VERSION " of nginx.pm is required, " |
614 "but %s was found", ver); | |
615 goto fail; | |
616 } | |
617 | |
3174
479fd46cd1c4
use ngx_conf_set_str_array_slot() for perl_require
Igor Sysoev <igor@sysoev.ru>
parents:
3173
diff
changeset
|
618 if (ngx_http_perl_run_requires(aTHX_ pmcf->requires, cf->log) != NGX_OK) { |
649 | 619 goto fail; |
599 | 620 } |
621 | |
622 } | |
623 | |
624 return perl; | |
625 | |
626 fail: | |
627 | |
628 (void) perl_destruct(perl); | |
629 | |
630 perl_free(perl); | |
631 | |
632 return NULL; | |
633 } | |
634 | |
635 | |
649 | 636 static ngx_int_t |
653 | 637 ngx_http_perl_run_requires(pTHX_ ngx_array_t *requires, ngx_log_t *log) |
649 | 638 { |
3173 | 639 u_char *err; |
649 | 640 STRLEN len; |
3174
479fd46cd1c4
use ngx_conf_set_str_array_slot() for perl_require
Igor Sysoev <igor@sysoev.ru>
parents:
3173
diff
changeset
|
641 ngx_str_t *script; |
649 | 642 ngx_uint_t i; |
643 | |
3174
479fd46cd1c4
use ngx_conf_set_str_array_slot() for perl_require
Igor Sysoev <igor@sysoev.ru>
parents:
3173
diff
changeset
|
644 if (requires == NGX_CONF_UNSET_PTR) { |
479fd46cd1c4
use ngx_conf_set_str_array_slot() for perl_require
Igor Sysoev <igor@sysoev.ru>
parents:
3173
diff
changeset
|
645 return NGX_OK; |
479fd46cd1c4
use ngx_conf_set_str_array_slot() for perl_require
Igor Sysoev <igor@sysoev.ru>
parents:
3173
diff
changeset
|
646 } |
479fd46cd1c4
use ngx_conf_set_str_array_slot() for perl_require
Igor Sysoev <igor@sysoev.ru>
parents:
3173
diff
changeset
|
647 |
649 | 648 script = requires->elts; |
649 for (i = 0; i < requires->nelts; i++) { | |
650 | |
3174
479fd46cd1c4
use ngx_conf_set_str_array_slot() for perl_require
Igor Sysoev <igor@sysoev.ru>
parents:
3173
diff
changeset
|
651 require_pv((char *) script[i].data); |
649 | 652 |
653 if (SvTRUE(ERRSV)) { | |
654 | |
3173 | 655 err = (u_char *) SvPV(ERRSV, len); |
656 while (--len && (err[len] == CR || err[len] == LF)) { /* void */ } | |
649 | 657 |
658 ngx_log_error(NGX_LOG_EMERG, log, 0, | |
3173 | 659 "require_pv(\"%s\") failed: \"%*s\"", |
3174
479fd46cd1c4
use ngx_conf_set_str_array_slot() for perl_require
Igor Sysoev <igor@sysoev.ru>
parents:
3173
diff
changeset
|
660 script[i].data, len + 1, err); |
649 | 661 |
662 return NGX_ERROR; | |
663 } | |
664 } | |
665 | |
666 return NGX_OK; | |
667 } | |
668 | |
669 | |
599 | 670 static ngx_int_t |
873
f92ad15c2db1
fix segfaults in future workers those will use old configuration,
Igor Sysoev <igor@sysoev.ru>
parents:
872
diff
changeset
|
671 ngx_http_perl_call_handler(pTHX_ ngx_http_request_t *r, HV *nginx, SV *sub, |
1899
d24ef26f1205
pass additional arguments in ngx_http_perl_call_handler() as SV
Igor Sysoev <igor@sysoev.ru>
parents:
1897
diff
changeset
|
672 SV **args, ngx_str_t *handler, ngx_str_t *rv) |
599 | 673 { |
1702
86bb52e28ce0
fix segfault when $r->has_request_body() is called with ready body
Igor Sysoev <igor@sysoev.ru>
parents:
1565
diff
changeset
|
674 SV *sv; |
86bb52e28ce0
fix segfault when $r->has_request_body() is called with ready body
Igor Sysoev <igor@sysoev.ru>
parents:
1565
diff
changeset
|
675 int n, status; |
86bb52e28ce0
fix segfault when $r->has_request_body() is called with ready body
Igor Sysoev <igor@sysoev.ru>
parents:
1565
diff
changeset
|
676 char *line; |
3173 | 677 u_char *err; |
1702
86bb52e28ce0
fix segfault when $r->has_request_body() is called with ready body
Igor Sysoev <igor@sysoev.ru>
parents:
1565
diff
changeset
|
678 STRLEN len, n_a; |
86bb52e28ce0
fix segfault when $r->has_request_body() is called with ready body
Igor Sysoev <igor@sysoev.ru>
parents:
1565
diff
changeset
|
679 ngx_uint_t i; |
86bb52e28ce0
fix segfault when $r->has_request_body() is called with ready body
Igor Sysoev <igor@sysoev.ru>
parents:
1565
diff
changeset
|
680 ngx_connection_t *c; |
599 | 681 |
682 dSP; | |
683 | |
684 status = 0; | |
685 | |
686 ENTER; | |
687 SAVETMPS; | |
688 | |
689 PUSHMARK(sp); | |
690 | |
873
f92ad15c2db1
fix segfaults in future workers those will use old configuration,
Igor Sysoev <igor@sysoev.ru>
parents:
872
diff
changeset
|
691 sv = sv_2mortal(sv_bless(newRV_noinc(newSViv(PTR2IV(r))), nginx)); |
599 | 692 XPUSHs(sv); |
693 | |
694 if (args) { | |
1940
6a4c74bea81c
fix building on 64-bit platforms broken in r1900
Igor Sysoev <igor@sysoev.ru>
parents:
1899
diff
changeset
|
695 EXTEND(sp, (intptr_t) args[0]); |
599 | 696 |
1899
d24ef26f1205
pass additional arguments in ngx_http_perl_call_handler() as SV
Igor Sysoev <igor@sysoev.ru>
parents:
1897
diff
changeset
|
697 for (i = 1; i <= (ngx_uint_t) args[0]; i++) { |
d24ef26f1205
pass additional arguments in ngx_http_perl_call_handler() as SV
Igor Sysoev <igor@sysoev.ru>
parents:
1897
diff
changeset
|
698 PUSHs(sv_2mortal(args[i])); |
599 | 699 } |
700 } | |
701 | |
702 PUTBACK; | |
703 | |
1702
86bb52e28ce0
fix segfault when $r->has_request_body() is called with ready body
Igor Sysoev <igor@sysoev.ru>
parents:
1565
diff
changeset
|
704 c = r->connection; |
86bb52e28ce0
fix segfault when $r->has_request_body() is called with ready body
Igor Sysoev <igor@sysoev.ru>
parents:
1565
diff
changeset
|
705 |
599 | 706 n = call_sv(sub, G_EVAL); |
707 | |
708 SPAGAIN; | |
709 | |
710 if (n) { | |
711 if (rv == NULL) { | |
712 status = POPi; | |
713 | |
1702
86bb52e28ce0
fix segfault when $r->has_request_body() is called with ready body
Igor Sysoev <igor@sysoev.ru>
parents:
1565
diff
changeset
|
714 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, |
599 | 715 "call_sv: %d", status); |
716 | |
717 } else { | |
619 | 718 line = SvPVx(POPs, n_a); |
599 | 719 rv->len = n_a; |
720 | |
2049 | 721 rv->data = ngx_pnalloc(r->pool, n_a); |
599 | 722 if (rv->data == NULL) { |
723 return NGX_ERROR; | |
724 } | |
725 | |
726 ngx_memcpy(rv->data, line, n_a); | |
727 } | |
728 } | |
729 | |
730 PUTBACK; | |
731 | |
732 FREETMPS; | |
733 LEAVE; | |
734 | |
735 /* check $@ */ | |
736 | |
737 if (SvTRUE(ERRSV)) { | |
738 | |
3173 | 739 err = (u_char *) SvPV(ERRSV, len); |
740 while (--len && (err[len] == CR || err[len] == LF)) { /* void */ } | |
599 | 741 |
1702
86bb52e28ce0
fix segfault when $r->has_request_body() is called with ready body
Igor Sysoev <igor@sysoev.ru>
parents:
1565
diff
changeset
|
742 ngx_log_error(NGX_LOG_ERR, c->log, 0, |
3173 | 743 "call_sv(\"%V\") failed: \"%*s\"", handler, len + 1, err); |
599 | 744 |
745 if (rv) { | |
746 return NGX_ERROR; | |
747 } | |
748 | |
749 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
750 } | |
751 | |
752 if (n != 1) { | |
1702
86bb52e28ce0
fix segfault when $r->has_request_body() is called with ready body
Igor Sysoev <igor@sysoev.ru>
parents:
1565
diff
changeset
|
753 ngx_log_error(NGX_LOG_ALERT, c->log, 0, |
599 | 754 "call_sv(\"%V\") returned %d results", handler, n); |
755 status = NGX_OK; | |
756 } | |
757 | |
758 if (rv) { | |
759 return NGX_OK; | |
760 } | |
761 | |
762 return (ngx_int_t) status; | |
763 } | |
764 | |
765 | |
766 static void | |
767 ngx_http_perl_eval_anon_sub(pTHX_ ngx_str_t *handler, SV **sv) | |
768 { | |
623 | 769 u_char *p; |
770 | |
771 for (p = handler->data; *p; p++) { | |
772 if (*p != ' ' && *p != '\t' && *p != CR && *p != LF) { | |
773 break; | |
774 } | |
775 } | |
776 | |
3132 | 777 if (ngx_strncmp(p, "sub ", 4) == 0 |
778 || ngx_strncmp(p, "sub{", 4) == 0 | |
779 || ngx_strncmp(p, "use ", 4) == 0) | |
780 { | |
623 | 781 *sv = eval_pv((char *) p, FALSE); |
874 | 782 |
783 /* eval_pv() does not set ERRSV on failure */ | |
784 | |
599 | 785 return; |
786 } | |
787 | |
788 *sv = NULL; | |
789 } | |
790 | |
791 | |
792 static void * | |
793 ngx_http_perl_create_main_conf(ngx_conf_t *cf) | |
794 { | |
795 ngx_http_perl_main_conf_t *pmcf; | |
796 | |
797 pmcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_perl_main_conf_t)); | |
798 if (pmcf == NULL) { | |
2912
c7d57b539248
return NULL instead of NGX_CONF_ERROR on a create conf failure
Igor Sysoev <igor@sysoev.ru>
parents:
2721
diff
changeset
|
799 return NULL; |
599 | 800 } |
801 | |
3175 | 802 pmcf->modules = NGX_CONF_UNSET_PTR; |
3174
479fd46cd1c4
use ngx_conf_set_str_array_slot() for perl_require
Igor Sysoev <igor@sysoev.ru>
parents:
3173
diff
changeset
|
803 pmcf->requires = NGX_CONF_UNSET_PTR; |
599 | 804 |
805 return pmcf; | |
806 } | |
807 | |
808 | |
809 static char * | |
810 ngx_http_perl_init_main_conf(ngx_conf_t *cf, void *conf) | |
811 { | |
812 ngx_http_perl_main_conf_t *pmcf = conf; | |
813 | |
814 if (pmcf->perl == NULL) { | |
815 if (ngx_http_perl_init_interpreter(cf, pmcf) != NGX_CONF_OK) { | |
816 return NGX_CONF_ERROR; | |
817 } | |
818 } | |
819 | |
820 return NGX_CONF_OK; | |
821 } | |
822 | |
823 | |
872
1c4a5b3f9110
Axe several perl interpreter instances: they may be useful in currently
Igor Sysoev <igor@sysoev.ru>
parents:
871
diff
changeset
|
824 #if (NGX_HAVE_PERL_MULTIPLICITY) |
649 | 825 |
599 | 826 static void |
827 ngx_http_perl_cleanup_perl(void *data) | |
828 { | |
649 | 829 PerlInterpreter *perl = data; |
599 | 830 |
873
f92ad15c2db1
fix segfaults in future workers those will use old configuration,
Igor Sysoev <igor@sysoev.ru>
parents:
872
diff
changeset
|
831 PERL_SET_CONTEXT(perl); |
f92ad15c2db1
fix segfaults in future workers those will use old configuration,
Igor Sysoev <igor@sysoev.ru>
parents:
872
diff
changeset
|
832 |
599 | 833 (void) perl_destruct(perl); |
834 | |
835 perl_free(perl); | |
2715 | 836 |
837 if (ngx_perl_term) { | |
838 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, "perl term"); | |
839 | |
840 PERL_SYS_TERM(); | |
841 } | |
599 | 842 } |
843 | |
649 | 844 #endif |
845 | |
846 | |
599 | 847 static ngx_int_t |
848 ngx_http_perl_preconfiguration(ngx_conf_t *cf) | |
849 { | |
617 | 850 #if (NGX_HTTP_SSI) |
599 | 851 ngx_int_t rc; |
852 ngx_http_ssi_main_conf_t *smcf; | |
853 | |
854 smcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_ssi_filter_module); | |
855 | |
856 rc = ngx_hash_add_key(&smcf->commands, &ngx_http_perl_ssi_command.name, | |
857 &ngx_http_perl_ssi_command, NGX_HASH_READONLY_KEY); | |
858 | |
859 if (rc != NGX_OK) { | |
860 if (rc == NGX_BUSY) { | |
861 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
862 "conflicting SSI command \"%V\"", | |
863 &ngx_http_perl_ssi_command.name); | |
864 } | |
865 | |
866 return NGX_ERROR; | |
867 } | |
617 | 868 #endif |
599 | 869 |
870 return NGX_OK; | |
871 } | |
872 | |
873 | |
874 static void * | |
875 ngx_http_perl_create_loc_conf(ngx_conf_t *cf) | |
876 { | |
877 ngx_http_perl_loc_conf_t *plcf; | |
878 | |
879 plcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_perl_loc_conf_t)); | |
880 if (plcf == NULL) { | |
2912
c7d57b539248
return NULL instead of NGX_CONF_ERROR on a create conf failure
Igor Sysoev <igor@sysoev.ru>
parents:
2721
diff
changeset
|
881 return NULL; |
599 | 882 } |
883 | |
884 /* | |
885 * set by ngx_pcalloc(): | |
886 * | |
887 * plcf->handler = { 0, NULL }; | |
888 */ | |
889 | |
890 return plcf; | |
891 } | |
892 | |
893 | |
894 static char * | |
895 ngx_http_perl_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) | |
896 { | |
897 ngx_http_perl_loc_conf_t *prev = parent; | |
898 ngx_http_perl_loc_conf_t *conf = child; | |
899 | |
900 if (conf->sub == NULL) { | |
901 conf->sub = prev->sub; | |
902 conf->handler = prev->handler; | |
903 } | |
904 | |
905 return NGX_CONF_OK; | |
906 } | |
907 | |
908 | |
909 static char * | |
910 ngx_http_perl(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
911 { | |
912 ngx_http_perl_loc_conf_t *plcf = conf; | |
913 | |
914 ngx_str_t *value; | |
915 ngx_http_core_loc_conf_t *clcf; | |
916 ngx_http_perl_main_conf_t *pmcf; | |
917 | |
918 value = cf->args->elts; | |
919 | |
920 if (plcf->handler.data) { | |
921 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
922 "duplicate perl handler \"%V\"", &value[1]); | |
923 return NGX_CONF_ERROR; | |
924 } | |
925 | |
926 pmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_perl_module); | |
927 | |
928 if (pmcf->perl == NULL) { | |
929 if (ngx_http_perl_init_interpreter(cf, pmcf) != NGX_CONF_OK) { | |
930 return NGX_CONF_ERROR; | |
931 } | |
932 } | |
933 | |
934 plcf->handler = value[1]; | |
935 | |
936 { | |
937 | |
938 dTHXa(pmcf->perl); | |
873
f92ad15c2db1
fix segfaults in future workers those will use old configuration,
Igor Sysoev <igor@sysoev.ru>
parents:
872
diff
changeset
|
939 PERL_SET_CONTEXT(pmcf->perl); |
599 | 940 |
941 ngx_http_perl_eval_anon_sub(aTHX_ &value[1], &plcf->sub); | |
942 | |
943 if (plcf->sub == &PL_sv_undef) { | |
944 ngx_conf_log_error(NGX_LOG_ERR, cf, 0, | |
945 "eval_pv(\"%V\") failed", &value[1]); | |
946 return NGX_CONF_ERROR; | |
947 } | |
948 | |
949 if (plcf->sub == NULL) { | |
950 plcf->sub = newSVpvn((char *) value[1].data, value[1].len); | |
951 } | |
952 | |
953 } | |
954 | |
955 clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); | |
956 clcf->handler = ngx_http_perl_handler; | |
957 | |
958 return NGX_CONF_OK; | |
959 } | |
960 | |
961 | |
962 static char * | |
963 ngx_http_perl_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
964 { | |
965 ngx_int_t index; | |
966 ngx_str_t *value; | |
967 ngx_http_variable_t *v; | |
968 ngx_http_perl_variable_t *pv; | |
969 ngx_http_perl_main_conf_t *pmcf; | |
970 | |
971 value = cf->args->elts; | |
972 | |
4972
8b635cf36ccc
Added checks that disallow adding a variable with an empty name.
Ruslan Ermilov <ru@nginx.com>
parents:
4963
diff
changeset
|
973 if (value[1].data[0] != '$') { |
599 | 974 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
975 "invalid variable name \"%V\"", &value[1]); | |
976 return NGX_CONF_ERROR; | |
977 } | |
978 | |
979 value[1].len--; | |
980 value[1].data++; | |
981 | |
1565 | 982 v = ngx_http_add_variable(cf, &value[1], NGX_HTTP_VAR_CHANGEABLE); |
599 | 983 if (v == NULL) { |
984 return NGX_CONF_ERROR; | |
985 } | |
986 | |
987 pv = ngx_palloc(cf->pool, sizeof(ngx_http_perl_variable_t)); | |
988 if (pv == NULL) { | |
989 return NGX_CONF_ERROR; | |
990 } | |
991 | |
992 index = ngx_http_get_variable_index(cf, &value[1]); | |
993 if (index == NGX_ERROR) { | |
994 return NGX_CONF_ERROR; | |
995 } | |
996 | |
997 pmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_perl_module); | |
998 | |
999 if (pmcf->perl == NULL) { | |
1000 if (ngx_http_perl_init_interpreter(cf, pmcf) != NGX_CONF_OK) { | |
1001 return NGX_CONF_ERROR; | |
1002 } | |
1003 } | |
1004 | |
1005 pv->handler = value[2]; | |
1006 | |
1007 { | |
1008 | |
1009 dTHXa(pmcf->perl); | |
873
f92ad15c2db1
fix segfaults in future workers those will use old configuration,
Igor Sysoev <igor@sysoev.ru>
parents:
872
diff
changeset
|
1010 PERL_SET_CONTEXT(pmcf->perl); |
599 | 1011 |
1012 ngx_http_perl_eval_anon_sub(aTHX_ &value[2], &pv->sub); | |
1013 | |
1014 if (pv->sub == &PL_sv_undef) { | |
1015 ngx_conf_log_error(NGX_LOG_ERR, cf, 0, | |
1016 "eval_pv(\"%V\") failed", &value[2]); | |
1017 return NGX_CONF_ERROR; | |
1018 } | |
1019 | |
1020 if (pv->sub == NULL) { | |
1021 pv->sub = newSVpvn((char *) value[2].data, value[2].len); | |
1022 } | |
1023 | |
1024 } | |
1025 | |
637 | 1026 v->get_handler = ngx_http_perl_variable; |
599 | 1027 v->data = (uintptr_t) pv; |
1028 | |
1029 return NGX_CONF_OK; | |
1030 } | |
1221
aa653367028e
PERL_SYS_TERM() should be called once on exit only, this fixes the message
Igor Sysoev <igor@sysoev.ru>
parents:
1165
diff
changeset
|
1031 |
aa653367028e
PERL_SYS_TERM() should be called once on exit only, this fixes the message
Igor Sysoev <igor@sysoev.ru>
parents:
1165
diff
changeset
|
1032 |
1257 | 1033 static ngx_int_t |
1034 ngx_http_perl_init_worker(ngx_cycle_t *cycle) | |
1035 { | |
1258
5076d97b9cf0
fix building on threaded or multiplicity interpreter perl,
Igor Sysoev <igor@sysoev.ru>
parents:
1257
diff
changeset
|
1036 ngx_http_perl_main_conf_t *pmcf; |
5076d97b9cf0
fix building on threaded or multiplicity interpreter perl,
Igor Sysoev <igor@sysoev.ru>
parents:
1257
diff
changeset
|
1037 |
5076d97b9cf0
fix building on threaded or multiplicity interpreter perl,
Igor Sysoev <igor@sysoev.ru>
parents:
1257
diff
changeset
|
1038 pmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_perl_module); |
5076d97b9cf0
fix building on threaded or multiplicity interpreter perl,
Igor Sysoev <igor@sysoev.ru>
parents:
1257
diff
changeset
|
1039 |
2713
b4d8aef4a1ad
fix segfault if no http section is defined in confguraiton,
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
1040 if (pmcf) { |
b4d8aef4a1ad
fix segfault if no http section is defined in confguraiton,
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
1041 dTHXa(pmcf->perl); |
b4d8aef4a1ad
fix segfault if no http section is defined in confguraiton,
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
1042 PERL_SET_CONTEXT(pmcf->perl); |
1258
5076d97b9cf0
fix building on threaded or multiplicity interpreter perl,
Igor Sysoev <igor@sysoev.ru>
parents:
1257
diff
changeset
|
1043 |
2713
b4d8aef4a1ad
fix segfault if no http section is defined in confguraiton,
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
1044 /* set worker's $$ */ |
1257 | 1045 |
2713
b4d8aef4a1ad
fix segfault if no http section is defined in confguraiton,
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
1046 sv_setiv(GvSV(gv_fetchpv("$", TRUE, SVt_PV)), (I32) ngx_pid); |
1258
5076d97b9cf0
fix building on threaded or multiplicity interpreter perl,
Igor Sysoev <igor@sysoev.ru>
parents:
1257
diff
changeset
|
1047 } |
5076d97b9cf0
fix building on threaded or multiplicity interpreter perl,
Igor Sysoev <igor@sysoev.ru>
parents:
1257
diff
changeset
|
1048 |
1257 | 1049 return NGX_OK; |
1050 } | |
1051 | |
1941 | 1052 |
1221
aa653367028e
PERL_SYS_TERM() should be called once on exit only, this fixes the message
Igor Sysoev <igor@sysoev.ru>
parents:
1165
diff
changeset
|
1053 static void |
aa653367028e
PERL_SYS_TERM() should be called once on exit only, this fixes the message
Igor Sysoev <igor@sysoev.ru>
parents:
1165
diff
changeset
|
1054 ngx_http_perl_exit(ngx_cycle_t *cycle) |
aa653367028e
PERL_SYS_TERM() should be called once on exit only, this fixes the message
Igor Sysoev <igor@sysoev.ru>
parents:
1165
diff
changeset
|
1055 { |
2715 | 1056 #if (NGX_HAVE_PERL_MULTIPLICITY) |
1057 | |
3351
b759cf8f6000
add comment from r2716 commit message
Igor Sysoev <igor@sysoev.ru>
parents:
3350
diff
changeset
|
1058 /* |
b759cf8f6000
add comment from r2716 commit message
Igor Sysoev <igor@sysoev.ru>
parents:
3350
diff
changeset
|
1059 * the master exit hook is run before global pool cleanup, |
b759cf8f6000
add comment from r2716 commit message
Igor Sysoev <igor@sysoev.ru>
parents:
3350
diff
changeset
|
1060 * therefore just set flag here |
b759cf8f6000
add comment from r2716 commit message
Igor Sysoev <igor@sysoev.ru>
parents:
3350
diff
changeset
|
1061 */ |
b759cf8f6000
add comment from r2716 commit message
Igor Sysoev <igor@sysoev.ru>
parents:
3350
diff
changeset
|
1062 |
2715 | 1063 ngx_perl_term = 1; |
1064 | |
1065 #else | |
3351
b759cf8f6000
add comment from r2716 commit message
Igor Sysoev <igor@sysoev.ru>
parents:
3350
diff
changeset
|
1066 |
3350
67da53a19e02
use global perl variable in perl_destruct()/perl_free()
Igor Sysoev <igor@sysoev.ru>
parents:
3175
diff
changeset
|
1067 if (nginx_stash) { |
2715 | 1068 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, cycle->log, 0, "perl term"); |
1069 | |
3350
67da53a19e02
use global perl variable in perl_destruct()/perl_free()
Igor Sysoev <igor@sysoev.ru>
parents:
3175
diff
changeset
|
1070 (void) perl_destruct(perl); |
2715 | 1071 |
3350
67da53a19e02
use global perl variable in perl_destruct()/perl_free()
Igor Sysoev <igor@sysoev.ru>
parents:
3175
diff
changeset
|
1072 perl_free(perl); |
1946
171a283af56b
some perl builds require my_perl for PERL_SYS_TERM()
Igor Sysoev <igor@sysoev.ru>
parents:
1941
diff
changeset
|
1073 |
2714
4dd1773990db
fix segfault on exit if no http section is defined in confguraiton,
Igor Sysoev <igor@sysoev.ru>
parents:
2713
diff
changeset
|
1074 PERL_SYS_TERM(); |
1946
171a283af56b
some perl builds require my_perl for PERL_SYS_TERM()
Igor Sysoev <igor@sysoev.ru>
parents:
1941
diff
changeset
|
1075 } |
2715 | 1076 |
1077 #endif | |
1221
aa653367028e
PERL_SYS_TERM() should be called once on exit only, this fixes the message
Igor Sysoev <igor@sysoev.ru>
parents:
1165
diff
changeset
|
1078 } |