Mercurial > hg > nginx-quic
annotate src/http/modules/perl/nginx.xs @ 6986:0cdee26605f3
Cleaned up r->headers_out.headers allocation error handling.
If initialization of a header failed for some reason after ngx_list_push(),
leaving the header as is can result in uninitialized memory access by
the header filter or the log module. The fix is to clear partially
initialized headers in case of errors.
For the Cache-Control header, the fix is to postpone pushing
r->headers_out.cache_control until its value is completed.
author | Sergey Kandaurov <pluknet@nginx.com> |
---|---|
date | Thu, 20 Apr 2017 18:26:37 +0300 |
parents | 1c5e5e5b008d |
children | 36c52a0f6ded |
rev | line source |
---|---|
599 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4412 | 4 * Copyright (C) Nginx, Inc. |
599 | 5 */ |
6 | |
7 | |
882
26c3e48b9996
the PERL_NO_GET_CONTEXT is actually required, see perlguts
Igor Sysoev <igor@sysoev.ru>
parents:
869
diff
changeset
|
8 #define PERL_NO_GET_CONTEXT |
26c3e48b9996
the PERL_NO_GET_CONTEXT is actually required, see perlguts
Igor Sysoev <igor@sysoev.ru>
parents:
869
diff
changeset
|
9 |
599 | 10 #include <ngx_config.h> |
11 #include <ngx_core.h> | |
12 #include <ngx_http.h> | |
13 #include <ngx_http_perl_module.h> | |
14 | |
603 | 15 #include "XSUB.h" |
16 | |
1739
5b7baef2e11e
copy return values to perl's allocated memory
Igor Sysoev <igor@sysoev.ru>
parents:
1703
diff
changeset
|
17 |
633 | 18 #define ngx_http_perl_set_request(r) \ |
19 r = INT2PTR(ngx_http_request_t *, SvIV((SV *) SvRV(ST(0)))) | |
20 | |
21 | |
1739
5b7baef2e11e
copy return values to perl's allocated memory
Igor Sysoev <igor@sysoev.ru>
parents:
1703
diff
changeset
|
22 #define ngx_http_perl_set_targ(p, len) \ |
633 | 23 \ |
1739
5b7baef2e11e
copy return values to perl's allocated memory
Igor Sysoev <igor@sysoev.ru>
parents:
1703
diff
changeset
|
24 SvUPGRADE(TARG, SVt_PV); \ |
633 | 25 SvPOK_on(TARG); \ |
1739
5b7baef2e11e
copy return values to perl's allocated memory
Igor Sysoev <igor@sysoev.ru>
parents:
1703
diff
changeset
|
26 sv_setpvn(TARG, (char *) p, len) |
633 | 27 |
599 | 28 |
29 static ngx_int_t | |
30 ngx_http_perl_sv2str(pTHX_ ngx_http_request_t *r, ngx_str_t *s, SV *sv) | |
31 { | |
32 u_char *p; | |
33 STRLEN len; | |
34 | |
35 if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PV) { | |
36 sv = SvRV(sv); | |
37 } | |
38 | |
39 p = (u_char *) SvPV(sv, len); | |
40 | |
41 s->len = len; | |
42 | |
1703
43747661804d
*) copy regex captures $1, $2, etc.
Igor Sysoev <igor@sysoev.ru>
parents:
1565
diff
changeset
|
43 if (SvREADONLY(sv) && SvPOK(sv)) { |
599 | 44 s->data = p; |
1703
43747661804d
*) copy regex captures $1, $2, etc.
Igor Sysoev <igor@sysoev.ru>
parents:
1565
diff
changeset
|
45 |
43747661804d
*) copy regex captures $1, $2, etc.
Igor Sysoev <igor@sysoev.ru>
parents:
1565
diff
changeset
|
46 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
43747661804d
*) copy regex captures $1, $2, etc.
Igor Sysoev <igor@sysoev.ru>
parents:
1565
diff
changeset
|
47 "perl sv2str: %08XD \"%V\"", sv->sv_flags, s); |
43747661804d
*) copy regex captures $1, $2, etc.
Igor Sysoev <igor@sysoev.ru>
parents:
1565
diff
changeset
|
48 |
599 | 49 return NGX_OK; |
50 } | |
51 | |
2049 | 52 s->data = ngx_pnalloc(r->pool, len); |
599 | 53 if (s->data == NULL) { |
54 return NGX_ERROR; | |
55 } | |
56 | |
57 ngx_memcpy(s->data, p, len); | |
58 | |
1703
43747661804d
*) copy regex captures $1, $2, etc.
Igor Sysoev <igor@sysoev.ru>
parents:
1565
diff
changeset
|
59 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
43747661804d
*) copy regex captures $1, $2, etc.
Igor Sysoev <igor@sysoev.ru>
parents:
1565
diff
changeset
|
60 "perl sv2str: %08XD \"%V\"", sv->sv_flags, s); |
43747661804d
*) copy regex captures $1, $2, etc.
Igor Sysoev <igor@sysoev.ru>
parents:
1565
diff
changeset
|
61 |
599 | 62 return NGX_OK; |
63 } | |
64 | |
65 | |
66 static ngx_int_t | |
67 ngx_http_perl_output(ngx_http_request_t *r, ngx_buf_t *b) | |
68 { | |
617 | 69 ngx_chain_t out; |
70 #if (NGX_HTTP_SSI) | |
71 ngx_chain_t *cl; | |
599 | 72 ngx_http_perl_ctx_t *ctx; |
73 | |
74 ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module); | |
75 | |
76 if (ctx->ssi) { | |
77 cl = ngx_alloc_chain_link(r->pool); | |
78 if (cl == NULL) { | |
79 return NGX_ERROR; | |
80 } | |
81 | |
82 cl->buf = b; | |
83 cl->next = NULL; | |
84 *ctx->ssi->last_out = cl; | |
85 ctx->ssi->last_out = &cl->next; | |
86 | |
87 return NGX_OK; | |
88 } | |
617 | 89 #endif |
599 | 90 |
91 out.buf = b; | |
92 out.next = NULL; | |
93 | |
94 return ngx_http_output_filter(r, &out); | |
95 } | |
96 | |
97 | |
98 MODULE = nginx PACKAGE = nginx | |
99 | |
100 | |
6233
c6cc0b79a43d
Perl: prototyping behavior explicitly specified.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6232
diff
changeset
|
101 PROTOTYPES: DISABLE |
c6cc0b79a43d
Perl: prototyping behavior explicitly specified.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6232
diff
changeset
|
102 |
c6cc0b79a43d
Perl: prototyping behavior explicitly specified.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6232
diff
changeset
|
103 |
633 | 104 void |
915 | 105 status(r, code) |
106 CODE: | |
107 | |
108 ngx_http_request_t *r; | |
109 | |
110 ngx_http_perl_set_request(r); | |
111 | |
112 r->headers_out.status = SvIV(ST(1)); | |
113 | |
114 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
115 "perl status: %d", r->headers_out.status); | |
116 | |
117 XSRETURN_UNDEF; | |
118 | |
119 | |
120 void | |
599 | 121 send_http_header(r, ...) |
633 | 122 CODE: |
599 | 123 |
633 | 124 ngx_http_request_t *r; |
125 SV *sv; | |
599 | 126 |
633 | 127 ngx_http_perl_set_request(r); |
599 | 128 |
129 if (r->headers_out.status == 0) { | |
130 r->headers_out.status = NGX_HTTP_OK; | |
131 } | |
132 | |
133 if (items != 1) { | |
134 sv = ST(1); | |
135 | |
136 if (ngx_http_perl_sv2str(aTHX_ r, &r->headers_out.content_type, sv) | |
137 != NGX_OK) | |
138 { | |
633 | 139 XSRETURN_EMPTY; |
599 | 140 } |
141 | |
1444
37938e68910b
allow to append charset to the "Content-Type" header
Igor Sysoev <igor@sysoev.ru>
parents:
1372
diff
changeset
|
142 r->headers_out.content_type_len = r->headers_out.content_type.len; |
37938e68910b
allow to append charset to the "Content-Type" header
Igor Sysoev <igor@sysoev.ru>
parents:
1372
diff
changeset
|
143 |
599 | 144 } else { |
673 | 145 if (ngx_http_set_content_type(r) != NGX_OK) { |
146 XSRETURN_EMPTY; | |
599 | 147 } |
148 } | |
149 | |
633 | 150 (void) ngx_http_send_header(r); |
599 | 151 |
152 | |
633 | 153 void |
154 header_only(r) | |
599 | 155 CODE: |
156 | |
633 | 157 dXSTARG; |
158 ngx_http_request_t *r; | |
159 | |
160 ngx_http_perl_set_request(r); | |
599 | 161 |
633 | 162 sv_upgrade(TARG, SVt_IV); |
163 sv_setiv(TARG, r->header_only); | |
599 | 164 |
633 | 165 ST(0) = TARG; |
599 | 166 |
167 | |
633 | 168 void |
169 uri(r) | |
170 CODE: | |
171 | |
172 dXSTARG; | |
173 ngx_http_request_t *r; | |
599 | 174 |
633 | 175 ngx_http_perl_set_request(r); |
1739
5b7baef2e11e
copy return values to perl's allocated memory
Igor Sysoev <igor@sysoev.ru>
parents:
1703
diff
changeset
|
176 ngx_http_perl_set_targ(r->uri.data, r->uri.len); |
633 | 177 |
178 ST(0) = TARG; | |
179 | |
180 | |
181 void | |
182 args(r) | |
599 | 183 CODE: |
184 | |
633 | 185 dXSTARG; |
186 ngx_http_request_t *r; | |
599 | 187 |
633 | 188 ngx_http_perl_set_request(r); |
1739
5b7baef2e11e
copy return values to perl's allocated memory
Igor Sysoev <igor@sysoev.ru>
parents:
1703
diff
changeset
|
189 ngx_http_perl_set_targ(r->args.data, r->args.len); |
599 | 190 |
633 | 191 ST(0) = TARG; |
599 | 192 |
193 | |
633 | 194 void |
629 | 195 request_method(r) |
633 | 196 CODE: |
197 | |
198 dXSTARG; | |
199 ngx_http_request_t *r; | |
629 | 200 |
633 | 201 ngx_http_perl_set_request(r); |
1739
5b7baef2e11e
copy return values to perl's allocated memory
Igor Sysoev <igor@sysoev.ru>
parents:
1703
diff
changeset
|
202 ngx_http_perl_set_targ(r->method_name.data, r->method_name.len); |
633 | 203 |
204 ST(0) = TARG; | |
205 | |
206 | |
207 void | |
208 remote_addr(r) | |
629 | 209 CODE: |
210 | |
633 | 211 dXSTARG; |
212 ngx_http_request_t *r; | |
629 | 213 |
633 | 214 ngx_http_perl_set_request(r); |
215 ngx_http_perl_set_targ(r->connection->addr_text.data, | |
1739
5b7baef2e11e
copy return values to perl's allocated memory
Igor Sysoev <igor@sysoev.ru>
parents:
1703
diff
changeset
|
216 r->connection->addr_text.len); |
629 | 217 |
633 | 218 ST(0) = TARG; |
629 | 219 |
220 | |
633 | 221 void |
222 header_in(r, key) | |
629 | 223 CODE: |
224 | |
633 | 225 dXSTARG; |
667 | 226 ngx_http_request_t *r; |
227 SV *key; | |
5248
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
228 u_char *p, *lowcase_key, *value, sep; |
667 | 229 STRLEN len; |
230 ssize_t size; | |
231 ngx_uint_t i, n, hash; | |
5248
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
232 ngx_array_t *a; |
667 | 233 ngx_list_part_t *part; |
234 ngx_table_elt_t *h, **ph; | |
235 ngx_http_header_t *hh; | |
236 ngx_http_core_main_conf_t *cmcf; | |
629 | 237 |
633 | 238 ngx_http_perl_set_request(r); |
599 | 239 |
633 | 240 key = ST(1); |
599 | 241 |
242 if (SvROK(key) && SvTYPE(SvRV(key)) == SVt_PV) { | |
243 key = SvRV(key); | |
244 } | |
245 | |
246 p = (u_char *) SvPV(key, len); | |
247 | |
667 | 248 /* look up hashed headers */ |
249 | |
2049 | 250 lowcase_key = ngx_pnalloc(r->pool, len); |
667 | 251 if (lowcase_key == NULL) { |
252 XSRETURN_UNDEF; | |
253 } | |
254 | |
2136 | 255 hash = ngx_hash_strlow(lowcase_key, p, len); |
667 | 256 |
257 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); | |
258 | |
259 hh = ngx_hash_find(&cmcf->headers_in_hash, hash, lowcase_key, len); | |
260 | |
261 if (hh) { | |
5248
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
262 |
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
263 if (hh->offset == offsetof(ngx_http_headers_in_t, cookies)) { |
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
264 sep = ';'; |
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
265 goto multi; |
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
266 } |
5306
43900b822890
Perl: fixed syntax usage for C preprocessor directives.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5248
diff
changeset
|
267 #if (NGX_HTTP_X_FORWARDED_FOR) |
5248
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
268 if (hh->offset == offsetof(ngx_http_headers_in_t, x_forwarded_for)) { |
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
269 sep = ','; |
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
270 goto multi; |
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
271 } |
5306
43900b822890
Perl: fixed syntax usage for C preprocessor directives.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5248
diff
changeset
|
272 #endif |
5248
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
273 |
6232
5f2a0739da19
Perl: fixed warning about "sep" may be used uninitialized.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5306
diff
changeset
|
274 ph = (ngx_table_elt_t **) ((char *) &r->headers_in + hh->offset); |
667 | 275 |
6232
5f2a0739da19
Perl: fixed warning about "sep" may be used uninitialized.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5306
diff
changeset
|
276 if (*ph) { |
5f2a0739da19
Perl: fixed warning about "sep" may be used uninitialized.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5306
diff
changeset
|
277 ngx_http_perl_set_targ((*ph)->value.data, (*ph)->value.len); |
667 | 278 |
6232
5f2a0739da19
Perl: fixed warning about "sep" may be used uninitialized.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5306
diff
changeset
|
279 goto done; |
5f2a0739da19
Perl: fixed warning about "sep" may be used uninitialized.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5306
diff
changeset
|
280 } |
667 | 281 |
6232
5f2a0739da19
Perl: fixed warning about "sep" may be used uninitialized.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5306
diff
changeset
|
282 XSRETURN_UNDEF; |
667 | 283 |
5248
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
284 multi: |
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
285 |
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
286 /* Cookie, X-Forwarded-For */ |
667 | 287 |
5248
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
288 a = (ngx_array_t *) ((char *) &r->headers_in + hh->offset); |
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
289 |
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
290 n = a->nelts; |
667 | 291 |
292 if (n == 0) { | |
293 XSRETURN_UNDEF; | |
294 } | |
295 | |
5248
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
296 ph = a->elts; |
667 | 297 |
298 if (n == 1) { | |
1739
5b7baef2e11e
copy return values to perl's allocated memory
Igor Sysoev <igor@sysoev.ru>
parents:
1703
diff
changeset
|
299 ngx_http_perl_set_targ((*ph)->value.data, (*ph)->value.len); |
667 | 300 |
301 goto done; | |
302 } | |
303 | |
304 size = - (ssize_t) (sizeof("; ") - 1); | |
305 | |
306 for (i = 0; i < n; i++) { | |
307 size += ph[i]->value.len + sizeof("; ") - 1; | |
308 } | |
309 | |
5248
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
310 value = ngx_pnalloc(r->pool, size); |
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
311 if (value == NULL) { |
667 | 312 XSRETURN_UNDEF; |
313 } | |
314 | |
5248
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
315 p = value; |
667 | 316 |
317 for (i = 0; /* void */ ; i++) { | |
318 p = ngx_copy(p, ph[i]->value.data, ph[i]->value.len); | |
319 | |
320 if (i == n - 1) { | |
321 break; | |
322 } | |
323 | |
5248
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
324 *p++ = sep; *p++ = ' '; |
667 | 325 } |
326 | |
5248
f5626ab8cb87
Perl: fixed r->header_in("Cookie") (ticket #351).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5198
diff
changeset
|
327 ngx_http_perl_set_targ(value, size); |
667 | 328 |
329 goto done; | |
330 } | |
331 | |
332 /* iterate over all headers */ | |
333 | |
599 | 334 part = &r->headers_in.headers.part; |
667 | 335 h = part->elts; |
599 | 336 |
337 for (i = 0; /* void */ ; i++) { | |
338 | |
339 if (i >= part->nelts) { | |
340 if (part->next == NULL) { | |
341 break; | |
342 } | |
343 | |
344 part = part->next; | |
667 | 345 h = part->elts; |
599 | 346 i = 0; |
347 } | |
348 | |
667 | 349 if (len != h[i].key.len |
350 || ngx_strcasecmp(p, h[i].key.data) != 0) | |
599 | 351 { |
352 continue; | |
353 } | |
354 | |
1739
5b7baef2e11e
copy return values to perl's allocated memory
Igor Sysoev <igor@sysoev.ru>
parents:
1703
diff
changeset
|
355 ngx_http_perl_set_targ(h[i].value.data, h[i].value.len); |
599 | 356 |
357 goto done; | |
358 } | |
359 | |
360 XSRETURN_UNDEF; | |
361 | |
362 done: | |
363 | |
633 | 364 ST(0) = TARG; |
599 | 365 |
366 | |
633 | 367 void |
681 | 368 has_request_body(r, next) |
369 CODE: | |
370 | |
371 dXSTARG; | |
372 ngx_http_request_t *r; | |
373 ngx_http_perl_ctx_t *ctx; | |
374 | |
375 ngx_http_perl_set_request(r); | |
376 | |
5181
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
377 if (r->headers_in.content_length_n <= 0 && !r->headers_in.chunked) { |
681 | 378 XSRETURN_UNDEF; |
379 } | |
380 | |
381 ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module); | |
909 | 382 ctx->next = SvRV(ST(1)); |
681 | 383 |
384 r->request_body_in_single_buf = 1; | |
385 r->request_body_in_persistent_file = 1; | |
1075
4d203f76b757
undo "client_body_in_file_only any"
Igor Sysoev <igor@sysoev.ru>
parents:
1056
diff
changeset
|
386 r->request_body_in_clean_file = 1; |
681 | 387 |
388 if (r->request_body_in_file_only) { | |
389 r->request_body_file_log_level = 0; | |
390 } | |
391 | |
392 ngx_http_read_client_request_body(r, ngx_http_perl_handle_request); | |
393 | |
394 sv_upgrade(TARG, SVt_IV); | |
395 sv_setiv(TARG, 1); | |
396 | |
397 ST(0) = TARG; | |
398 | |
399 | |
400 void | |
631 | 401 request_body(r) |
402 CODE: | |
403 | |
633 | 404 dXSTARG; |
405 ngx_http_request_t *r; | |
5181
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
406 u_char *p, *data; |
633 | 407 size_t len; |
5181
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
408 ngx_buf_t *buf; |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
409 ngx_chain_t *cl; |
633 | 410 |
411 ngx_http_perl_set_request(r); | |
631 | 412 |
941 | 413 if (r->request_body == NULL |
414 || r->request_body->temp_file | |
415 || r->request_body->bufs == NULL) | |
416 { | |
633 | 417 XSRETURN_UNDEF; |
418 } | |
631 | 419 |
5181
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
420 cl = r->request_body->bufs; |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
421 buf = cl->buf; |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
422 |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
423 if (cl->next == NULL) { |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
424 len = buf->last - buf->pos; |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
425 data = buf->pos; |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
426 goto done; |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
427 } |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
428 |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
429 len = buf->last - buf->pos; |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
430 cl = cl->next; |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
431 |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
432 for ( /* void */ ; cl; cl = cl->next) { |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
433 buf = cl->buf; |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
434 len += buf->last - buf->pos; |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
435 } |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
436 |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
437 p = ngx_pnalloc(r->pool, len); |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
438 if (p == NULL) { |
5198
e530b88b088b
Perl: extra "return" removed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5181
diff
changeset
|
439 XSRETURN_UNDEF; |
5181
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
440 } |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
441 |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
442 data = p; |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
443 cl = r->request_body->bufs; |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
444 |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
445 for ( /* void */ ; cl; cl = cl->next) { |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
446 buf = cl->buf; |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
447 p = ngx_cpymem(p, buf->pos, buf->last - buf->pos); |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
448 } |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
449 |
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
450 done: |
631 | 451 |
452 if (len == 0) { | |
453 XSRETURN_UNDEF; | |
454 } | |
455 | |
5181
4d0ac175f6e4
Perl: request body handling fixed.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4644
diff
changeset
|
456 ngx_http_perl_set_targ(data, len); |
631 | 457 |
633 | 458 ST(0) = TARG; |
631 | 459 |
460 | |
633 | 461 void |
462 request_body_file(r) | |
463 CODE: | |
464 | |
465 dXSTARG; | |
466 ngx_http_request_t *r; | |
467 | |
468 ngx_http_perl_set_request(r); | |
469 | |
941 | 470 if (r->request_body == NULL || r->request_body->temp_file == NULL) { |
633 | 471 XSRETURN_UNDEF; |
472 } | |
473 | |
474 ngx_http_perl_set_targ(r->request_body->temp_file->file.name.data, | |
1739
5b7baef2e11e
copy return values to perl's allocated memory
Igor Sysoev <igor@sysoev.ru>
parents:
1703
diff
changeset
|
475 r->request_body->temp_file->file.name.len); |
599 | 476 |
633 | 477 ST(0) = TARG; |
478 | |
479 | |
480 void | |
1371 | 481 discard_request_body(r) |
482 CODE: | |
483 | |
484 ngx_http_request_t *r; | |
485 | |
486 ngx_http_perl_set_request(r); | |
487 | |
488 ngx_http_discard_request_body(r); | |
489 | |
490 | |
491 void | |
633 | 492 header_out(r, key, value) |
493 CODE: | |
599 | 494 |
633 | 495 ngx_http_request_t *r; |
496 SV *key; | |
497 SV *value; | |
498 ngx_table_elt_t *header; | |
599 | 499 |
633 | 500 ngx_http_perl_set_request(r); |
501 | |
502 key = ST(1); | |
503 value = ST(2); | |
599 | 504 |
505 header = ngx_list_push(&r->headers_out.headers); | |
506 if (header == NULL) { | |
633 | 507 XSRETURN_EMPTY; |
599 | 508 } |
509 | |
510 header->hash = 1; | |
511 | |
512 if (ngx_http_perl_sv2str(aTHX_ r, &header->key, key) != NGX_OK) { | |
6986
0cdee26605f3
Cleaned up r->headers_out.headers allocation error handling.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6960
diff
changeset
|
513 header->hash = 0; |
633 | 514 XSRETURN_EMPTY; |
599 | 515 } |
516 | |
517 if (ngx_http_perl_sv2str(aTHX_ r, &header->value, value) != NGX_OK) { | |
6986
0cdee26605f3
Cleaned up r->headers_out.headers allocation error handling.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6960
diff
changeset
|
518 header->hash = 0; |
633 | 519 XSRETURN_EMPTY; |
599 | 520 } |
521 | |
522 if (header->key.len == sizeof("Content-Length") - 1 | |
3870 | 523 && ngx_strncasecmp(header->key.data, (u_char *) "Content-Length", |
741
63a08390a8a2
$r->headers_out("Content-Length", "NNN") did not work
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
524 sizeof("Content-Length") - 1) == 0) |
599 | 525 { |
741
63a08390a8a2
$r->headers_out("Content-Length", "NNN") did not work
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
526 r->headers_out.content_length_n = (off_t) SvIV(value); |
599 | 527 r->headers_out.content_length = header; |
528 } | |
529 | |
4196
190ae1a7f917
Handling of Content-Encoding set from perl.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4188
diff
changeset
|
530 if (header->key.len == sizeof("Content-Encoding") - 1 |
4644
95763fce86a8
Fixed warning during nginx.xs compilation.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4494
diff
changeset
|
531 && ngx_strncasecmp(header->key.data, (u_char *) "Content-Encoding", |
4196
190ae1a7f917
Handling of Content-Encoding set from perl.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4188
diff
changeset
|
532 sizeof("Content-Encoding") - 1) == 0) |
190ae1a7f917
Handling of Content-Encoding set from perl.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4188
diff
changeset
|
533 { |
190ae1a7f917
Handling of Content-Encoding set from perl.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4188
diff
changeset
|
534 r->headers_out.content_encoding = header; |
190ae1a7f917
Handling of Content-Encoding set from perl.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4188
diff
changeset
|
535 } |
190ae1a7f917
Handling of Content-Encoding set from perl.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4188
diff
changeset
|
536 |
599 | 537 |
633 | 538 void |
599 | 539 filename(r) |
633 | 540 CODE: |
599 | 541 |
633 | 542 dXSTARG; |
774
589841f06b87
previous commit broke two modules
Igor Sysoev <igor@sysoev.ru>
parents:
741
diff
changeset
|
543 size_t root; |
633 | 544 ngx_http_request_t *r; |
599 | 545 ngx_http_perl_ctx_t *ctx; |
546 | |
633 | 547 ngx_http_perl_set_request(r); |
599 | 548 |
549 ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module); | |
633 | 550 if (ctx->filename.data) { |
599 | 551 goto done; |
552 } | |
553 | |
774
589841f06b87
previous commit broke two modules
Igor Sysoev <igor@sysoev.ru>
parents:
741
diff
changeset
|
554 if (ngx_http_map_uri_to_path(r, &ctx->filename, &root, 0) == NULL) { |
599 | 555 XSRETURN_UNDEF; |
556 } | |
557 | |
633 | 558 ctx->filename.len--; |
559 sv_setpv(PL_statname, (char *) ctx->filename.data); | |
599 | 560 |
561 done: | |
562 | |
1739
5b7baef2e11e
copy return values to perl's allocated memory
Igor Sysoev <igor@sysoev.ru>
parents:
1703
diff
changeset
|
563 ngx_http_perl_set_targ(ctx->filename.data, ctx->filename.len); |
599 | 564 |
633 | 565 ST(0) = TARG; |
599 | 566 |
567 | |
633 | 568 void |
599 | 569 print(r, ...) |
570 CODE: | |
571 | |
633 | 572 ngx_http_request_t *r; |
573 SV *sv; | |
574 int i; | |
575 u_char *p; | |
576 size_t size; | |
577 STRLEN len; | |
578 ngx_buf_t *b; | |
579 | |
580 ngx_http_perl_set_request(r); | |
599 | 581 |
582 if (items == 2) { | |
583 | |
584 /* | |
585 * do zero copy for prolate single read-only SV: | |
586 * $r->print("some text\n"); | |
587 */ | |
588 | |
589 sv = ST(1); | |
590 | |
591 if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PV) { | |
592 sv = SvRV(sv); | |
593 } | |
594 | |
1703
43747661804d
*) copy regex captures $1, $2, etc.
Igor Sysoev <igor@sysoev.ru>
parents:
1565
diff
changeset
|
595 if (SvREADONLY(sv) && SvPOK(sv)) { |
599 | 596 |
597 p = (u_char *) SvPV(sv, len); | |
598 | |
599 if (len == 0) { | |
633 | 600 XSRETURN_EMPTY; |
599 | 601 } |
602 | |
603 b = ngx_calloc_buf(r->pool); | |
604 if (b == NULL) { | |
633 | 605 XSRETURN_EMPTY; |
599 | 606 } |
607 | |
608 b->memory = 1; | |
609 b->pos = p; | |
610 b->last = p + len; | |
611 b->start = p; | |
612 b->end = b->last; | |
613 | |
601 | 614 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
615 "$r->print: read-only SV: %z", len); | |
616 | |
599 | 617 goto out; |
618 } | |
619 } | |
620 | |
621 size = 0; | |
622 | |
623 for (i = 1; i < items; i++) { | |
624 | |
625 sv = ST(i); | |
626 | |
627 if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PV) { | |
628 sv = SvRV(sv); | |
629 } | |
630 | |
601 | 631 (void) SvPV(sv, len); |
599 | 632 |
601 | 633 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
634 "$r->print: copy SV: %z", len); | |
599 | 635 |
636 size += len; | |
637 } | |
638 | |
639 if (size == 0) { | |
633 | 640 XSRETURN_EMPTY; |
599 | 641 } |
642 | |
643 b = ngx_create_temp_buf(r->pool, size); | |
644 if (b == NULL) { | |
633 | 645 XSRETURN_EMPTY; |
599 | 646 } |
647 | |
648 for (i = 1; i < items; i++) { | |
649 sv = ST(i); | |
650 | |
651 if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PV) { | |
652 sv = SvRV(sv); | |
653 } | |
654 | |
655 p = (u_char *) SvPV(sv, len); | |
656 b->last = ngx_cpymem(b->last, p, len); | |
657 } | |
658 | |
659 out: | |
660 | |
633 | 661 (void) ngx_http_perl_output(r, b); |
599 | 662 |
663 | |
633 | 664 void |
613 | 665 sendfile(r, filename, offset = -1, bytes = 0) |
633 | 666 CODE: |
667 | |
1454 | 668 ngx_http_request_t *r; |
669 char *filename; | |
2794
92bd6afe8d9c
use off_t in $r->sendfile(), this allows to use 64-bit off_t on platforms
Igor Sysoev <igor@sysoev.ru>
parents:
2756
diff
changeset
|
670 off_t offset; |
1454 | 671 size_t bytes; |
672 ngx_str_t path; | |
673 ngx_buf_t *b; | |
674 ngx_open_file_info_t of; | |
675 ngx_http_core_loc_conf_t *clcf; | |
599 | 676 |
633 | 677 ngx_http_perl_set_request(r); |
678 | |
679 filename = SvPV_nolen(ST(1)); | |
599 | 680 |
681 if (filename == NULL) { | |
682 croak("sendfile(): NULL filename"); | |
683 } | |
684 | |
633 | 685 offset = items < 3 ? -1 : SvIV(ST(2)); |
686 bytes = items < 4 ? 0 : SvIV(ST(3)); | |
687 | |
599 | 688 b = ngx_calloc_buf(r->pool); |
689 if (b == NULL) { | |
633 | 690 XSRETURN_EMPTY; |
599 | 691 } |
692 | |
693 b->file = ngx_pcalloc(r->pool, sizeof(ngx_file_t)); | |
694 if (b->file == NULL) { | |
633 | 695 XSRETURN_EMPTY; |
599 | 696 } |
697 | |
1454 | 698 path.len = ngx_strlen(filename); |
699 | |
2061
b0a1c84725cf
change useless ngx_pcalloc() to ngx_pnalloc()
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
700 path.data = ngx_pnalloc(r->pool, path.len + 1); |
1454 | 701 if (path.data == NULL) { |
633 | 702 XSRETURN_EMPTY; |
599 | 703 } |
704 | |
3870 | 705 (void) ngx_cpystrn(path.data, (u_char *) filename, path.len + 1); |
1560
25ee6eee7573
style fix: remove trailing spaces
Igor Sysoev <igor@sysoev.ru>
parents:
1457
diff
changeset
|
706 |
2063
67a29af877ed
initialize of.uniq in ngx_open_cached_file()
Igor Sysoev <igor@sysoev.ru>
parents:
2061
diff
changeset
|
707 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
67a29af877ed
initialize of.uniq in ngx_open_cached_file()
Igor Sysoev <igor@sysoev.ru>
parents:
2061
diff
changeset
|
708 |
2068
75a8d34459c5
ngx_memzero() ngx_open_file_info_t
Igor Sysoev <igor@sysoev.ru>
parents:
2063
diff
changeset
|
709 ngx_memzero(&of, sizeof(ngx_open_file_info_t)); |
75a8d34459c5
ngx_memzero() ngx_open_file_info_t
Igor Sysoev <igor@sysoev.ru>
parents:
2063
diff
changeset
|
710 |
3178 | 711 of.read_ahead = clcf->read_ahead; |
2129 | 712 of.directio = clcf->directio; |
2063
67a29af877ed
initialize of.uniq in ngx_open_cached_file()
Igor Sysoev <igor@sysoev.ru>
parents:
2061
diff
changeset
|
713 of.valid = clcf->open_file_cache_valid; |
67a29af877ed
initialize of.uniq in ngx_open_cached_file()
Igor Sysoev <igor@sysoev.ru>
parents:
2061
diff
changeset
|
714 of.min_uses = clcf->open_file_cache_min_uses; |
67a29af877ed
initialize of.uniq in ngx_open_cached_file()
Igor Sysoev <igor@sysoev.ru>
parents:
2061
diff
changeset
|
715 of.errors = clcf->open_file_cache_errors; |
67a29af877ed
initialize of.uniq in ngx_open_cached_file()
Igor Sysoev <igor@sysoev.ru>
parents:
2061
diff
changeset
|
716 of.events = clcf->open_file_cache_events; |
4494
13e09cf11d4e
Disable symlinks: initialization of the "disable_symlinks" field in
Valentin Bartenev <vbart@nginx.com>
parents:
4478
diff
changeset
|
717 |
13e09cf11d4e
Disable symlinks: initialization of the "disable_symlinks" field in
Valentin Bartenev <vbart@nginx.com>
parents:
4478
diff
changeset
|
718 if (ngx_http_set_disable_symlinks(r, clcf, &path, &of) != NGX_OK) { |
13e09cf11d4e
Disable symlinks: initialization of the "disable_symlinks" field in
Valentin Bartenev <vbart@nginx.com>
parents:
4478
diff
changeset
|
719 XSRETURN_EMPTY; |
13e09cf11d4e
Disable symlinks: initialization of the "disable_symlinks" field in
Valentin Bartenev <vbart@nginx.com>
parents:
4478
diff
changeset
|
720 } |
2063
67a29af877ed
initialize of.uniq in ngx_open_cached_file()
Igor Sysoev <igor@sysoev.ru>
parents:
2061
diff
changeset
|
721 |
1799 | 722 if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool) |
723 != NGX_OK) | |
724 { | |
1454 | 725 if (of.err == 0) { |
726 XSRETURN_EMPTY; | |
727 } | |
728 | |
599 | 729 ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno, |
2756
09cab3f8d92e
*) of.test_only to not open file if only stat() is enough
Igor Sysoev <igor@sysoev.ru>
parents:
2231
diff
changeset
|
730 "%s \"%s\" failed", of.failed, filename); |
633 | 731 XSRETURN_EMPTY; |
599 | 732 } |
733 | |
613 | 734 if (offset == -1) { |
735 offset = 0; | |
736 } | |
737 | |
738 if (bytes == 0) { | |
1454 | 739 bytes = of.size - offset; |
599 | 740 } |
741 | |
742 b->in_file = 1; | |
613 | 743 |
744 b->file_pos = offset; | |
745 b->file_last = offset + bytes; | |
599 | 746 |
1454 | 747 b->file->fd = of.fd; |
599 | 748 b->file->log = r->connection->log; |
2231
8564129d49b6
*) handle unaligned file part for directio
Igor Sysoev <igor@sysoev.ru>
parents:
2136
diff
changeset
|
749 b->file->directio = of.is_directio; |
599 | 750 |
633 | 751 (void) ngx_http_perl_output(r, b); |
599 | 752 |
753 | |
633 | 754 void |
1178
a77f6980de50
rename $r->rflush to $r->flush
Igor Sysoev <igor@sysoev.ru>
parents:
1075
diff
changeset
|
755 flush(r) |
633 | 756 CODE: |
599 | 757 |
633 | 758 ngx_http_request_t *r; |
759 ngx_buf_t *b; | |
599 | 760 |
633 | 761 ngx_http_perl_set_request(r); |
599 | 762 |
763 b = ngx_calloc_buf(r->pool); | |
764 if (b == NULL) { | |
633 | 765 XSRETURN_EMPTY; |
599 | 766 } |
767 | |
768 b->flush = 1; | |
769 | |
1178
a77f6980de50
rename $r->rflush to $r->flush
Igor Sysoev <igor@sysoev.ru>
parents:
1075
diff
changeset
|
770 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "$r->flush"); |
601 | 771 |
633 | 772 (void) ngx_http_perl_output(r, b); |
599 | 773 |
633 | 774 XSRETURN_EMPTY; |
599 | 775 |
776 | |
777 void | |
778 internal_redirect(r, uri) | |
633 | 779 CODE: |
599 | 780 |
633 | 781 ngx_http_request_t *r; |
782 SV *uri; | |
599 | 783 ngx_uint_t i; |
784 ngx_http_perl_ctx_t *ctx; | |
785 | |
633 | 786 ngx_http_perl_set_request(r); |
787 | |
788 uri = ST(1); | |
599 | 789 |
790 ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module); | |
791 | |
792 if (ngx_http_perl_sv2str(aTHX_ r, &ctx->redirect_uri, uri) != NGX_OK) { | |
793 XSRETURN_EMPTY; | |
794 } | |
795 | |
796 for (i = 0; i < ctx->redirect_uri.len; i++) { | |
797 if (ctx->redirect_uri.data[i] == '?') { | |
798 | |
799 ctx->redirect_args.len = ctx->redirect_uri.len - (i + 1); | |
800 ctx->redirect_args.data = &ctx->redirect_uri.data[i + 1]; | |
801 ctx->redirect_uri.len = i; | |
802 | |
803 XSRETURN_EMPTY; | |
804 } | |
805 } | |
601 | 806 |
807 | |
633 | 808 void |
811 | 809 allow_ranges(r) |
810 CODE: | |
811 | |
812 ngx_http_request_t *r; | |
813 | |
814 ngx_http_perl_set_request(r); | |
815 | |
816 r->allow_ranges = 1; | |
817 | |
818 | |
819 void | |
601 | 820 unescape(r, text, type = 0) |
821 CODE: | |
822 | |
633 | 823 dXSTARG; |
824 ngx_http_request_t *r; | |
825 SV *text; | |
826 int type; | |
827 u_char *p, *dst, *src; | |
828 STRLEN len; | |
601 | 829 |
633 | 830 ngx_http_perl_set_request(r); |
831 | |
832 text = ST(1); | |
833 | |
834 src = (u_char *) SvPV(text, len); | |
835 | |
2049 | 836 p = ngx_pnalloc(r->pool, len + 1); |
601 | 837 if (p == NULL) { |
838 XSRETURN_UNDEF; | |
839 } | |
840 | |
841 dst = p; | |
842 | |
633 | 843 type = items < 3 ? 0 : SvIV(ST(2)); |
844 | |
845 ngx_unescape_uri(&dst, &src, len, (ngx_uint_t) type); | |
601 | 846 *dst = '\0'; |
847 | |
1739
5b7baef2e11e
copy return values to perl's allocated memory
Igor Sysoev <igor@sysoev.ru>
parents:
1703
diff
changeset
|
848 ngx_http_perl_set_targ(p, dst - p); |
601 | 849 |
633 | 850 ST(0) = TARG; |
833 | 851 |
852 | |
853 void | |
854 variable(r, name, value = NULL) | |
855 CODE: | |
856 | |
857 dXSTARG; | |
858 ngx_http_request_t *r; | |
859 SV *name, *value; | |
860 u_char *p, *lowcase; | |
861 STRLEN len; | |
862 ngx_str_t var, val; | |
863 ngx_uint_t i, hash; | |
912
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
864 ngx_http_perl_var_t *v; |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
865 ngx_http_perl_ctx_t *ctx; |
833 | 866 ngx_http_variable_value_t *vv; |
867 | |
868 ngx_http_perl_set_request(r); | |
869 | |
870 name = ST(1); | |
871 | |
872 if (SvROK(name) && SvTYPE(SvRV(name)) == SVt_PV) { | |
873 name = SvRV(name); | |
874 } | |
875 | |
876 if (items == 2) { | |
877 value = NULL; | |
878 | |
879 } else { | |
880 value = ST(2); | |
881 | |
882 if (SvROK(value) && SvTYPE(SvRV(value)) == SVt_PV) { | |
883 value = SvRV(value); | |
884 } | |
885 | |
886 if (ngx_http_perl_sv2str(aTHX_ r, &val, value) != NGX_OK) { | |
887 XSRETURN_UNDEF; | |
888 } | |
889 } | |
890 | |
891 p = (u_char *) SvPV(name, len); | |
892 | |
2049 | 893 lowcase = ngx_pnalloc(r->pool, len); |
833 | 894 if (lowcase == NULL) { |
895 XSRETURN_UNDEF; | |
896 } | |
897 | |
2136 | 898 hash = ngx_hash_strlow(lowcase, p, len); |
833 | 899 |
900 var.len = len; | |
901 var.data = lowcase; | |
5306
43900b822890
Perl: fixed syntax usage for C preprocessor directives.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5248
diff
changeset
|
902 #if (NGX_DEBUG) |
912
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
903 |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
904 if (value) { |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
905 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
906 "perl variable: \"%V\"=\"%V\"", &var, &val); |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
907 } else { |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
908 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
909 "perl variable: \"%V\"", &var); |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
910 } |
5306
43900b822890
Perl: fixed syntax usage for C preprocessor directives.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5248
diff
changeset
|
911 #endif |
912
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
912 |
3500
0eb46e3c5c02
change processing variables accessed by SSI and perl module:
Igor Sysoev <igor@sysoev.ru>
parents:
3447
diff
changeset
|
913 vv = ngx_http_get_variable(r, &var, hash); |
833 | 914 if (vv == NULL) { |
915 XSRETURN_UNDEF; | |
916 } | |
917 | |
918 if (vv->not_found) { | |
912
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
919 |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
920 ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module); |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
921 |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
922 if (ctx->variables) { |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
923 |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
924 v = ctx->variables->elts; |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
925 for (i = 0; i < ctx->variables->nelts; i++) { |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
926 |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
927 if (hash != v[i].hash |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
928 || len != v[i].name.len |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
929 || ngx_strncmp(lowcase, v[i].name.data, len) != 0) |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
930 { |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
931 continue; |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
932 } |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
933 |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
934 if (value) { |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
935 v[i].value = val; |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
936 XSRETURN_UNDEF; |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
937 } |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
938 |
1739
5b7baef2e11e
copy return values to perl's allocated memory
Igor Sysoev <igor@sysoev.ru>
parents:
1703
diff
changeset
|
939 ngx_http_perl_set_targ(v[i].value.data, v[i].value.len); |
912
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
940 |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
941 goto done; |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
942 } |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
943 } |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
944 |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
945 if (value) { |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
946 if (ctx->variables == NULL) { |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
947 ctx->variables = ngx_array_create(r->pool, 1, |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
948 sizeof(ngx_http_perl_var_t)); |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
949 if (ctx->variables == NULL) { |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
950 XSRETURN_UNDEF; |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
951 } |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
952 } |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
953 |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
954 v = ngx_array_push(ctx->variables); |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
955 if (v == NULL) { |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
956 XSRETURN_UNDEF; |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
957 } |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
958 |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
959 v->hash = hash; |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
960 v->name.len = len; |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
961 v->name.data = lowcase; |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
962 v->value = val; |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
963 |
833 | 964 XSRETURN_UNDEF; |
965 } | |
966 | |
967 XSRETURN_UNDEF; | |
968 } | |
969 | |
970 if (value) { | |
971 vv->len = val.len; | |
972 vv->valid = 1; | |
1565 | 973 vv->no_cacheable = 0; |
833 | 974 vv->not_found = 0; |
975 vv->data = val.data; | |
976 | |
977 XSRETURN_UNDEF; | |
978 } | |
979 | |
1739
5b7baef2e11e
copy return values to perl's allocated memory
Igor Sysoev <igor@sysoev.ru>
parents:
1703
diff
changeset
|
980 ngx_http_perl_set_targ(vv->data, vv->len); |
833 | 981 |
912
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
982 done: |
7fa926a7926d
$r->variable() supports perl only variables
Igor Sysoev <igor@sysoev.ru>
parents:
911
diff
changeset
|
983 |
833 | 984 ST(0) = TARG; |
907 | 985 |
986 | |
987 void | |
911 | 988 sleep(r, sleep, next) |
989 CODE: | |
990 | |
991 ngx_http_request_t *r; | |
1897 | 992 ngx_msec_t sleep; |
911 | 993 ngx_http_perl_ctx_t *ctx; |
994 | |
995 ngx_http_perl_set_request(r); | |
996 | |
1898 | 997 sleep = (ngx_msec_t) SvIV(ST(1)); |
1897 | 998 |
999 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
1000 "perl sleep: %M", sleep); | |
1001 | |
911 | 1002 ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module); |
1003 | |
1004 ctx->next = SvRV(ST(2)); | |
1005 | |
6960
1c5e5e5b008d
Perl: fixed delaying subrequests.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6233
diff
changeset
|
1006 r->connection->write->delayed = 1; |
1897 | 1007 ngx_add_timer(r->connection->write, sleep); |
1008 | |
1009 r->write_event_handler = ngx_http_perl_sleep_handler; | |
3447
de70f912ad58
fix request counter for $r->sleep(), the bug was introduced in r3050
Igor Sysoev <igor@sysoev.ru>
parents:
3317
diff
changeset
|
1010 r->main->count++; |
911 | 1011 |
1012 | |
1013 void | |
907 | 1014 log_error(r, err, msg) |
1015 CODE: | |
1016 | |
1017 ngx_http_request_t *r; | |
1018 SV *err, *msg; | |
1019 u_char *p; | |
1020 STRLEN len; | |
1021 ngx_err_t e; | |
1022 | |
1023 ngx_http_perl_set_request(r); | |
1024 | |
1025 err = ST(1); | |
1026 | |
1027 if (SvROK(err) && SvTYPE(SvRV(err)) == SVt_PV) { | |
1028 err = SvRV(err); | |
1029 } | |
1030 | |
1031 e = SvIV(err); | |
1032 | |
1033 msg = ST(2); | |
1034 | |
1035 if (SvROK(msg) && SvTYPE(SvRV(msg)) == SVt_PV) { | |
1036 msg = SvRV(msg); | |
1037 } | |
1038 | |
1039 p = (u_char *) SvPV(msg, len); | |
1040 | |
910 | 1041 ngx_log_error(NGX_LOG_ERR, r->connection->log, e, "perl: %s", p); |